1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-11-14 14:39:04 -08:00

assemble some arguments that aren't registers again

This commit is contained in:
Connor Olding 2016-04-20 21:23:32 -07:00
parent 027485543c
commit acb5a3a6df
3 changed files with 84 additions and 53 deletions

View file

@ -135,6 +135,10 @@ function Dumper:desym(t)
end
function Dumper:toval(t)
if type(t) == 'number' then
return t
end
assert(type(t) == 'table', 'Internal Error: invalid value')
local val = self:desym(t)
@ -248,36 +252,61 @@ function Dumper:register(registers)
if not numeric then
self:error('wrong type of register')
end
--self:advance()
return numeric
return Token(t)
end
function Dumper:const(relative, no_label)
if no_label then
self:expect{'NUM'}
else
self:expect{'NUM', 'LABELSYM'}
end
local t = self.s[self.i]
local new = Token(t)
if relative then
if t.tt == 'LABELSYM' then
new.t = 'LABELREL'
else
new.t = 'REL'
end
end
return new
end
function Dumper:deref()
self:expect{'DEREF'}
local t = self.s[self.i]
local new = Token(t)
new.tt = 'REG'
return new
end
function Dumper:assemble_j(first, out)
local w = 0
w = w + self:validate(first, 6) * 0x04000000
w = w + self:validate(out[1], 26) * 0x00000001
w = w + self:valvar(first, 6) * 0x04000000
w = w + self:valvar(out[1], 26) * 0x00000001
local t = Token(self.fn, self.line, 'WORDS', {w})
local s = Statement(self.fn, self.line, '!DATA', t)
return s
end
function Dumper:assemble_i(first, out)
local w = 0
w = w + self:validate(first, 6) * 0x04000000
w = w + self:validate(out[1], 5) * 0x00200000
w = w + self:validate(out[2], 5) * 0x00010000
w = w + self:validate(out[3], 16) * 0x00000001
w = w + self:valvar(first, 6) * 0x04000000
w = w + self:valvar(out[1], 5) * 0x00200000
w = w + self:valvar(out[2], 5) * 0x00010000
w = w + self:valvar(out[3], 16) * 0x00000001
local t = Token(self.fn, self.line, 'WORDS', {w})
local s = Statement(self.fn, self.line, '!DATA', t)
return s
end
function Dumper:assemble_r(first, out)
local w = 0
w = w + self:validate(first, 6) * 0x04000000
w = w + self:validate(out[1], 5) * 0x00200000
w = w + self:validate(out[2], 5) * 0x00010000
w = w + self:validate(out[3], 5) * 0x00000800
w = w + self:validate(out[4], 5) * 0x00000040
w = w + self:validate(out[5], 6) * 0x00000001
w = w + self:valvar(first, 6) * 0x04000000
w = w + self:valvar(out[1], 5) * 0x00200000
w = w + self:valvar(out[2], 5) * 0x00010000
w = w + self:valvar(out[3], 5) * 0x00000800
w = w + self:valvar(out[4], 5) * 0x00000040
w = w + self:valvar(out[5], 6) * 0x00000001
local t = Token(self.fn, self.line, 'WORDS', {w})
local s = Statement(self.fn, self.line, '!DATA', t)
return s
@ -310,19 +339,19 @@ function Dumper:format_in(informat)
elseif c == 'Z' and not args.rt then
args.rt = self:register(data.sys_registers)
elseif c == 'o' and not args.offset then
args.offset = 0 --Token(self:const()):set('signed')
args.offset = Token(self:const()):set('signed')
elseif c == 'r' and not args.offset then
args.offset = 0 --Token(self:const('relative')):set('signed')
args.offset = Token(self:const('relative')):set('signed')
elseif c == 'i' and not args.immediate then
args.immediate = 0 --self:const(nil, 'no label')
args.immediate = self:const(nil, 'no label')
elseif c == 'I' and not args.index then
args.index = 0 --Token(self:const()):set('index')
args.index = Token(self:const()):set('index')
elseif c == 'k' and not args.immediate then
args.immediate = 0 --Token(self:const(nil, 'no label')):set('negate')
args.immediate = Token(self:const(nil, 'no label')):set('negate')
elseif c == 'K' and not args.immediate then
args.immediate = 0 --Token(self:const(nil, 'no label')):set('signed')
args.immediate = Token(self:const(nil, 'no label')):set('signed')
elseif c == 'b' and not args.base then
args.base = 0 --self:deref()
args.base = self:deref()
else
error('Internal Error: invalid input formatting string')
end
@ -338,34 +367,21 @@ function Dumper:format_out_raw(outformat, first, args, const, formatconst)
[5]=self.assemble_r,
}
local out = {}
for i=1,#outformat do
for i=1, #outformat do
local c = outformat:sub(i, i)
if c == 'd' then
out[#out+1] = args.rd
elseif c == 's' then
out[#out+1] = args.rs
elseif c == 't' then
out[#out+1] = args.rt
elseif c == 'D' then
out[#out+1] = args.fd
elseif c == 'S' then
out[#out+1] = args.fs
elseif c == 'T' then
out[#out+1] = args.ft
elseif c == 'o' then
out[#out+1] = args.offset
elseif c == 'i' then
out[#out+1] = args.immediate
elseif c == 'I' then
out[#out+1] = args.index
elseif c == 'b' then
out[#out+1] = args.base
elseif c == '0' then
out[#out+1] = 0
elseif c == 'C' then
out[#out+1] = const
elseif c == 'F' then
out[#out+1] = formatconst
if c == 'd' then out[#out+1] = args.rd
elseif c == 's' then insert(out, args.rs)
elseif c == 't' then insert(out, args.rt)
elseif c == 'D' then insert(out, args.fd)
elseif c == 'S' then insert(out, args.fs)
elseif c == 'T' then insert(out, args.ft)
elseif c == 'o' then insert(out, args.offset)
elseif c == 'i' then insert(out, args.immediate)
elseif c == 'I' then insert(out, args.index)
elseif c == 'b' then insert(out, args.base)
elseif c == '0' then insert(out, 0)
elseif c == 'C' then insert(out, const)
elseif c == 'F' then insert(out, formatconst)
end
end
local f = lookup[#outformat]
@ -385,6 +401,9 @@ function Dumper:assemble(s)
--overrides[name](self, name)
local s = Statement(self.fn, self.line, '!DATA') -- FIXME: dummy
return s
elseif h[2] == 'tob' then -- TODO: or h[2] == 'Tob' then
local s = Statement(self.fn, self.line, '!DATA') -- FIXME: dummy
return s
elseif h[2] ~= nil then
local args = self:format_in(h[2])
return self:format_out(h, args)
@ -418,17 +437,24 @@ function Dumper:load(statements)
end
end
-- TODO: keep track of self.pos and lengths here
-- TODO: keep track of lengths here?
self.pos = 0
for i=1, #statements do
local s = statements[i]
self.fn = s.fn
self.line = s.line
if s.type:sub(1, 1) ~= '!' then
insert(new_statements, self:assemble(s))
s = self:assemble(s)
insert(new_statements, s)
elseif assembled_directives[s.type] then
-- FIXME: check for LABELs in !DATA
-- TODO: reimplement ALIGN and SKIP here
insert(new_statements, s)
elseif s.type == '!LABEL' then
-- noop
else
print(s.type)
error('Internal Error: unknown statement found in Dumper')
end
end

View file

@ -110,9 +110,6 @@ function Parser:parse(asm)
- assemble? dumper gets passed .org .base
--]]
local dumper = Dumper(self.writer, self.options)
self.statements = dumper:load(self.statements)
-- DEBUG
for i, s in ipairs(self.statements) do
local values = ''
@ -123,6 +120,9 @@ function Parser:parse(asm)
print(i, s.type, values)
end
local dumper = Dumper(self.writer, self.options)
self.statements = dumper:load(self.statements)
--if self.options.labels then
-- dumper:export_labels(self.options.labels)
--end

View file

@ -50,4 +50,9 @@ function Statement:validate(n)
end
end
-- TODO: just move push_data into Statement too
function Statement:length()
assert(self.type == '!DATA', 'Statement:length only works on !DATA types')
end
return Statement