1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-05-17 16:03:24 -07: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 s1, (s0)
lw s2, 256(s0) lw s2, 256(s0)
lw s3, label(s0) lw s3, label(s0)
; this is currently unsupported however
sw s2, label+4 sw s2, label+4
sw s3, label+4(s0) sw s3, label+4(s0)

View File

@ -138,21 +138,25 @@ function Dumper:desym(t)
end end
return rel % 0x10000 return rel % 0x10000
elseif type(t.tok) == 'number' then elseif type(t.tok) == 'number' then
if t.offset then
return t.tok + t.offset
end
return t.tok return t.tok
elseif t.tt == 'REG' then elseif t.tt == 'REG' then
assert(data.all_registers[t.tok], 'Internal Error: unknown register') 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] 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] local label = self.labels[t.tok]
if label == nil then if label == nil then
self:error('undefined label') self:error('undefined label')
end end
return label if t.offset then
elseif t.tt == 'LABELREL' then label = label + t.offset
local label = self.labels[t.tok]
if label == nil then
self:error('undefined label')
end end
if t.tt == 'LABELSYM' then
return label
end
label = label % 0x80000000 label = label % 0x80000000
local pos = self.pos % 0x80000000 local pos = self.pos % 0x80000000
local rel = floor(label/4) - 1 - floor(pos/4) local rel = floor(label/4) - 1 - floor(pos/4)

View File

@ -379,6 +379,10 @@ function Lexer:lex(_yield)
local n = self:read_number() local n = self:read_number()
if n then if n then
yield('NUM', sign*n) 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 else
yield('RELLABELSYM', sign*#buff) yield('RELLABELSYM', sign*#buff)
end end

View File

@ -179,6 +179,7 @@ function Parser:instruction()
elseif overrides[name] then elseif overrides[name] then
overrides[name](self, name) overrides[name](self, name)
elseif h[2] == 'tob' then -- TODO: or h[2] == 'Tob' then 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 lui = data.instructions['LUI']
local addu = data.instructions['ADDU'] local addu = data.instructions['ADDU']
local args = {} local args = {}
@ -191,6 +192,9 @@ function Parser:instruction()
local lui_args = {} local lui_args = {}
local addu_args = {} local addu_args = {}
local o = self:const() local o = self:const()
if self.tt == 'NUM' then
o:set('offset', self:const().tok)
end
args.offset = self:token(o) args.offset = self:token(o)
if not o.portion then if not o.portion then
args.offset:set('portion', 'lower') args.offset:set('portion', 'lower')

View File

@ -17,11 +17,24 @@ function Preproc:process(tokens)
local plus_labels = {} -- constructed forwards local plus_labels = {} -- constructed forwards
local minus_labels = {} -- constructed backwards 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 = {} local new_tokens = {}
self.i = 0 self.i = 0
while self.i < #self.tokens do while self.i < #self.tokens do
local t = self:advance() 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 if t.tt == nil then
error('Internal Error: missing token') error('Internal Error: missing token')
elseif t.tt == 'DEF' then elseif t.tt == 'DEF' then
@ -36,7 +49,7 @@ function Preproc:process(tokens)
if tok == nil then if tok == nil then
self:error('undefined define') -- uhhh nice wording self:error('undefined define') -- uhhh nice wording
end end
insert(new_tokens, self:token(tt, tok)) insert(new_tokens, self:token(tt, tok * sign))
elseif t.tt == 'RELLABEL' then elseif t.tt == 'RELLABEL' then
if t.tok == '+' then if t.tok == '+' then
insert(plus_labels, #new_tokens + 1) insert(plus_labels, #new_tokens + 1)