mirror of
https://github.com/notwa/lips
synced 2024-11-14 09:49:02 -08:00
implement offsets for constants
This commit is contained in:
parent
356aee5e9f
commit
311b1e362f
5 changed files with 33 additions and 10 deletions
|
@ -91,8 +91,6 @@ my_label:
|
|||
lw s1, (s0)
|
||||
lw s2, 256(s0)
|
||||
lw s3, label(s0)
|
||||
|
||||
; this is currently unsupported however
|
||||
sw s2, label+4
|
||||
sw s3, label+4(s0)
|
||||
|
||||
|
|
|
@ -138,21 +138,25 @@ function Dumper:desym(t)
|
|||
end
|
||||
return rel % 0x10000
|
||||
elseif type(t.tok) == 'number' then
|
||||
if t.offset then
|
||||
return t.tok + t.offset
|
||||
end
|
||||
return t.tok
|
||||
elseif t.tt == 'REG' then
|
||||
assert(data.all_registers[t.tok], 'Internal Error: unknown register')
|
||||
return data.registers[t.tok] or data.fpu_registers[t.tok] or data.sys_registers[t.tok]
|
||||
elseif t.tt == 'LABELSYM' then
|
||||
elseif t.tt == 'LABELSYM' or t.tt == 'LABELREL' then
|
||||
local label = self.labels[t.tok]
|
||||
if label == nil then
|
||||
self:error('undefined label')
|
||||
end
|
||||
return label
|
||||
elseif t.tt == 'LABELREL' then
|
||||
local label = self.labels[t.tok]
|
||||
if label == nil then
|
||||
self:error('undefined label')
|
||||
if t.offset then
|
||||
label = label + t.offset
|
||||
end
|
||||
if t.tt == 'LABELSYM' then
|
||||
return label
|
||||
end
|
||||
|
||||
label = label % 0x80000000
|
||||
local pos = self.pos % 0x80000000
|
||||
local rel = floor(label/4) - 1 - floor(pos/4)
|
||||
|
|
|
@ -379,6 +379,10 @@ function Lexer:lex(_yield)
|
|||
local n = self:read_number()
|
||||
if n then
|
||||
yield('NUM', sign*n)
|
||||
elseif #buff == 1 then
|
||||
-- this could be a RELLABELSYM
|
||||
-- we'll have to let the preproc figure it out
|
||||
yield('UNARY', sign)
|
||||
else
|
||||
yield('RELLABELSYM', sign*#buff)
|
||||
end
|
||||
|
|
|
@ -179,6 +179,7 @@ function Parser:instruction()
|
|||
elseif overrides[name] then
|
||||
overrides[name](self, name)
|
||||
elseif h[2] == 'tob' then -- TODO: or h[2] == 'Tob' then
|
||||
-- handle all the addressing modes for lw/sw-like instructions
|
||||
local lui = data.instructions['LUI']
|
||||
local addu = data.instructions['ADDU']
|
||||
local args = {}
|
||||
|
@ -191,6 +192,9 @@ function Parser:instruction()
|
|||
local lui_args = {}
|
||||
local addu_args = {}
|
||||
local o = self:const()
|
||||
if self.tt == 'NUM' then
|
||||
o:set('offset', self:const().tok)
|
||||
end
|
||||
args.offset = self:token(o)
|
||||
if not o.portion then
|
||||
args.offset:set('portion', 'lower')
|
||||
|
|
|
@ -17,11 +17,24 @@ function Preproc:process(tokens)
|
|||
local plus_labels = {} -- constructed forwards
|
||||
local minus_labels = {} -- constructed backwards
|
||||
|
||||
-- first pass: resolve defines, collect relative labels
|
||||
-- first pass: resolve unary ops, defines, and collect relative labels
|
||||
local new_tokens = {}
|
||||
self.i = 0
|
||||
while self.i < #self.tokens do
|
||||
local t = self:advance()
|
||||
local sign = 1
|
||||
if t.tt == 'UNARY' then
|
||||
local peek = self.tokens[self.i + 1]
|
||||
if peek.tt == 'UNARY' then
|
||||
self:error('unary operators cannot be chained')
|
||||
elseif peek.tt == 'EOL' or peek.tt == 'SEP' then
|
||||
t.tt = 'RELLABEL'
|
||||
elseif peek.tt == 'DEFSYM' then
|
||||
sign = t.tok
|
||||
else
|
||||
self:error('expected a symbolic constant after unary operator')
|
||||
end
|
||||
end
|
||||
if t.tt == nil then
|
||||
error('Internal Error: missing token')
|
||||
elseif t.tt == 'DEF' then
|
||||
|
@ -36,7 +49,7 @@ function Preproc:process(tokens)
|
|||
if tok == nil then
|
||||
self:error('undefined define') -- uhhh nice wording
|
||||
end
|
||||
insert(new_tokens, self:token(tt, tok))
|
||||
insert(new_tokens, self:token(tt, tok * sign))
|
||||
elseif t.tt == 'RELLABEL' then
|
||||
if t.tok == '+' then
|
||||
insert(plus_labels, #new_tokens + 1)
|
||||
|
|
Loading…
Reference in a new issue