1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-05-02 17:43:23 -07:00
fix jump and branch destinations.
note: branching is no longer compatible with CajeASM.

make LUI dumb: only use 'UPPER' with LI/LA.
note: this is very incompatible with CajeASM.
add LUUI pseudo-instruction to use 'UPPER' instead of 'LOWER'.

fix SUBI/SUBIU parsing.

fix LI for values under 0x10000.

pass filename through main().
tell Lexer our filename.
don't print filename in Dumper since it's irrelevant.
This commit is contained in:
Connor Olding 2015-11-21 17:35:43 -08:00
parent 327f38cbbc
commit 57ca41d414

View File

@ -126,7 +126,7 @@ local instruction_handlers = {
SWL = {42, 'tob', 'bto'},
SWR = {46, 'tob', 'bto'},
LUI = {15, 'tJ', '0ti'},
LUI = {15, 'tj', '0ti'},
MFHI = {0, 'd', '00d0C', 16},
MFLO = {0, 'd', '00d0C', 18},
@ -336,6 +336,10 @@ local instruction_handlers = {
SUBI = {8, 'tsk', 'sti'},
SUBIU = {9, 'tsk', 'sti'},
-- LUI only loads the lower 16 bits of its constant.
-- if you need the upper 16, use this instead.
LUUI = {15, 'tJ', '0ti'},
-- ...that expand to multiple instructions
LI = 'LI', -- only one instruction for values < 0x10000
LA = 'LA',
@ -767,7 +771,7 @@ function Parser:format_in(informat)
else
error('Internal Error: invalid input formatting string', 1)
end
if c2:find('[dstDSToiIjJr]') then
if c2:find('[dstDSToiIjJkr]') then
self:optional_comma()
end
end
@ -826,7 +830,9 @@ function Parser:instruction()
if h == nil then
self:error('undefined instruction')
elseif h == 'LI' or h == 'LA' then
-- FIXME: this fails horribly with labels
local lui = instruction_handlers['LUI']
local addi = instruction_handlers['ADDI']
local ori = instruction_handlers['ORI']
local args = {}
args.rt = self:register()
@ -836,11 +842,13 @@ function Parser:instruction()
args.rs = args.rt
args.immediate = {'UPPER', im}
self:format_out(lui[3], lui[1], args, lui[4], lui[5])
args.immediate = {'LOWER', im}
self:format_out(ori[3], ori[1], args, ori[4], ori[5])
else
args.rs = 'R0'
args.immediate = {'LOWER', im}
self:format_out(addi[3], addi[1], args, addi[4], addi[5])
end
args.immediate = {'LOWER', im}
self:format_out(ori[3], ori[1], args, ori[4], ori[5])
elseif h[2] ~= nil then
args = self:format_in(h[2])
self:format_out(h[3], h[1], args, h[4], h[5])
@ -852,7 +860,7 @@ end
function Parser:parse(asm)
self.asm = asm
self.lexer = Lexer(asm)
self.lexer = Lexer(asm, self.fn)
self:advance()
while self.tt ~= 'EOF' do
@ -880,7 +888,7 @@ end
function Dumper:error(msg)
-- TOOD: we should pass line numbers down to add_instruction.
error(string.format('%s:%d: Dumper Error: %s', self.fn, self.pos, msg), 2)
error(string.format('%s:%d: Dumper Error: %s', '(code)', self.pos, msg), 2)
end
function Dumper:advance(by)
@ -985,7 +993,7 @@ function Dumper:desym(tok)
return self.labels[tok[2]]
elseif tok[1] == 'LABELREL' then
local rel = math.floor(self.labels[tok[2]]/4)
rel = rel - 2 - math.floor(self.pos/4)
rel = rel - 1 - math.floor(self.pos/4)
if rel > 0x8000 or rel <= -0x8000 then
self:error('branch too far')
end
@ -1015,8 +1023,7 @@ function Dumper:toval(tok)
end
if tok[1] == 'UPPER' then
local val = self:desym(tok[2])
val = math.floor(val/0x10000)
return val
return math.floor(val/0x10000)
elseif tok[1] == 'LOWER' then
local val = self:desym(tok[2])
return val % 0x10000
@ -1024,13 +1031,8 @@ function Dumper:toval(tok)
local val = -self:desym(tok[2])
return val % 0x10000
elseif tok[1] == 'INDEX' then
local val = self:desym(tok[2])
if type(tok[2]) == 'table' and tok[2][1] == 'LABELSYM' then
-- don't multiply by 4 twice
else
val = val*4
end
--print('(index)', val)
local val = self:desym(tok[2]) % 0x80000000
val = math.floor(val/4)
return val
else
return self:desym(tok)
@ -1149,11 +1151,13 @@ local function assemble(fn_or_asm, writer)
writer = writer or io.write
function main()
local fn = nil
local asm = ''
if fn_or_asm:find('[\r\n]') then
asm = fn_or_asm
else
local f = io.open(fn_or_asm, 'r')
fn = fn_or_asm
local f = io.open(fn, 'r')
if not f then
error('could not read assembly file', 1)
end
@ -1161,7 +1165,7 @@ local function assemble(fn_or_asm, writer)
f:close()
end
local parser = Parser(writer)
local parser = Parser(writer, fn)
return parser:parse(asm)
end