1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-06-30 22:07:11 -07:00

add fpu registers and basic moves

This commit is contained in:
Connor Olding 2015-11-20 13:28:10 -08:00
parent 8407c4e016
commit 301bfc99f8

View File

@ -14,7 +14,13 @@ local registers = {
'T8', 'T9', 'K0', 'K1', 'GP', 'SP', 'S8', 'RA', 'T8', 'T9', 'K0', 'K1', 'GP', 'SP', 'S8', 'RA',
} }
local all_registers = registers -- TODO local fpu_registers = {
[0]=
'F0', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7',
'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15',
'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23',
'F24', 'F25', 'F26', 'F27', 'F28', 'F29', 'F30', 'F31',
}
local all_instructions = { local all_instructions = {
'ADD', 'ADDI', 'ADDIU', 'ADDU', 'ADD', 'ADDI', 'ADDIU', 'ADDU',
@ -168,6 +174,14 @@ local all_tokens = {
'SEP', 'SEP',
} }
local all_registers = {}
for k, v in pairs(registers) do
all_registers[k] = v
end
for k, v in pairs(fpu_registers) do
all_registers[k + 32] = v
end
-- set up reverse table lookups -- set up reverse table lookups
local function revtable(t) local function revtable(t)
for k, v in pairs(t) do for k, v in pairs(t) do
@ -176,12 +190,13 @@ local function revtable(t)
end end
revtable(registers) revtable(registers)
revtable(fpu_registers)
revtable(all_registers) revtable(all_registers)
revtable(all_instructions) revtable(all_instructions)
revtable(all_tokens) revtable(all_tokens)
local argtypes = { local argtypes = {
bro = 'base rt offset', bto = 'base rt offset',
sti = 'rs rt immediate', sti = 'rs rt immediate',
std = 'rs rt rd', -- ending with 5 unset bits and a const std = 'rs rt rd', -- ending with 5 unset bits and a const
st = 'rs rt', -- ending with 10 unset bits and a const st = 'rs rt', -- ending with 10 unset bits and a const
@ -197,11 +212,27 @@ local argtypes = {
mf = 'rd', -- 10 unset bits on left, 5 on right, ending with a const mf = 'rd', -- 10 unset bits on left, 5 on right, ending with a const
jalr= 'rs rd', -- 5 unset bits inbetween, 5 on right, ending with a const jalr= 'rs rd', -- 5 unset bits inbetween, 5 on right, ending with a const
code= 'code', -- ending with a const code= 'code', -- ending with a const
movf= 'rd fs', -- starting with const, ending with 11 unset bits
bfo = 'base fs offset',
} }
local at = argtypes -- temporary shorthand local at = argtypes -- temporary shorthand
local instruction_handlers = { local instruction_handlers = {
CFC1 = {17, at.movf, 2},
CTC1 = {17, at.movf, 6},
DMFC1 = {17, at.movf, 1},
DMTC1 = {17, at.movf, 5},
MFC0 = {16, at.movf, 0},
MFC1 = {16, at.movf, 0},
MTC0 = {17, at.movf, 4},
MTC1 = {17, at.movf, 4},
LDC1 = {53, at.bfo},
LWC1 = {49, at.bfo},
SDC1 = {61, at.bfo},
SWC1 = {57, at.bfo},
-- --
@ -253,29 +284,29 @@ local instruction_handlers = {
NOP = { 0, at.code, 0}, NOP = { 0, at.code, 0},
LB = {32, at.bro}, LB = {32, at.bto},
LBU = {36, at.bro}, LBU = {36, at.bto},
LD = {55, at.bro}, LD = {55, at.bto},
LDL = {26, at.bro}, LDL = {26, at.bto},
LDR = {27, at.bro}, LDR = {27, at.bto},
LH = {33, at.bro}, LH = {33, at.bto},
LHU = {37, at.bro}, LHU = {37, at.bto},
LL = {48, at.bro}, LL = {48, at.bto},
LLD = {52, at.bro}, LLD = {52, at.bto},
LW = {35, at.bro}, LW = {35, at.bto},
LWL = {34, at.bro}, LWL = {34, at.bto},
LWR = {38, at.bro}, LWR = {38, at.bto},
LWU = {39, at.bro}, LWU = {39, at.bto},
SB = {40, at.bro}, SB = {40, at.bto},
SC = {56, at.bro}, SC = {56, at.bto},
SCD = {60, at.bro}, SCD = {60, at.bto},
SD = {63, at.bro}, SD = {63, at.bto},
SDL = {44, at.bro}, SDL = {44, at.bto},
SDR = {45, at.bro}, SDR = {45, at.bto},
SH = {41, at.bro}, SH = {41, at.bto},
SW = {43, at.bro}, SW = {43, at.bto},
SWL = {42, at.bro}, SWL = {42, at.bto},
SWR = {46, at.bro}, SWR = {46, at.bto},
ADDI = { 8, at.sti}, ADDI = { 8, at.sti},
ADDIU = { 9, at.sti}, ADDIU = { 9, at.sti},
@ -625,7 +656,8 @@ function Parser:directive()
end end
end end
function Parser:register() function Parser:register(t)
t = t or registers
if self.tt ~= 'REG' then if self.tt ~= 'REG' then
if self.tt == 'NUM' and self.tok == '0' then if self.tt == 'NUM' and self.tok == '0' then
-- i don't think cajeasm actually does this -- i don't think cajeasm actually does this
@ -636,6 +668,9 @@ function Parser:register()
end end
end end
local reg = self.tok local reg = self.tok
if not t[reg] then
self:error('wrong type of register')
end
self:advance() self:advance()
return reg return reg
end end
@ -665,16 +700,20 @@ function Parser:instruction()
if h == nil then if h == nil then
self:error('undefined instruction') self:error('undefined instruction')
elseif h[2] == nil then elseif h[2] == argtypes.bto then
-- OP
Dumper:add_instruction_26(h[1])
elseif h[2] == argtypes.bro then
-- OP rt, offset(base) -- OP rt, offset(base)
local rt = self:register() local rt = self:register()
self:optional_comma() self:optional_comma()
local offset = {'LOWER', self:const()} local offset = {'LOWER', self:const()}
local base = self:deref() local base = self:deref()
Dumper:add_instruction_5_5_16(h[1], base, rt, offset) Dumper:add_instruction_5_5_16(h[1], base, rt, offset)
elseif h[2] == argtypes.bfo then
-- OP ft, offset(base)
local ft = self:register(fpu_registers)
self:optional_comma()
local offset = {'LOWER', self:const()}
local base = self:deref()
Dumper:add_instruction_5_5_16(h[1], base, rt, offset)
elseif h[2] == argtypes.sti then elseif h[2] == argtypes.sti then
-- OP rt, rs, immediate -- OP rt, rs, immediate
local rs = self:register() local rs = self:register()
@ -743,6 +782,7 @@ function Parser:instruction()
self:optional_comma() self:optional_comma()
local offset = self:const() local offset = self:const()
local const = h[3] or self:error('internal error: expected const') local const = h[3] or self:error('internal error: expected const')
-- FIXME: branches are relative
Dumper:add_instruction_5_5_16(h[1], rs, const, offset) Dumper:add_instruction_5_5_16(h[1], rs, const, offset)
elseif h[2] == argtypes.sync then elseif h[2] == argtypes.sync then
-- OP -- OP
@ -775,6 +815,19 @@ function Parser:instruction()
-- OP -- OP
local const = h[3] or self:error('internal error: expected const') local const = h[3] or self:error('internal error: expected const')
Dumper:add_instruction_26(h[1], const) Dumper:add_instruction_26(h[1], const)
elseif h[2] == argtypes.movf then
local rt = self:register()
self:optional_comma()
local rd
if name == 'MFC0' or name == 'MTC0' then
-- OP rt, rd
rd = self:register()
else
-- OP rt, fs
rd = self:register(fpu_registers)
end
local const = h[3] or self:error('internal error: expected const')
Dumper:add_instruction_5_5_5_5_6(h[1], const, rt, rd, 0, 0)
else else
self:error('TODO') self:error('TODO')
end end