1
0
Fork 0
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:
Connor Olding 2016-04-10 02:59:39 -07:00
parent 356aee5e9f
commit 311b1e362f
5 changed files with 33 additions and 10 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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')

View file

@ -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)