1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-11-14 18:19:03 -08:00

allow 1 register in place of 2, pseudo stuff…

allow CL to take more than one argument.
implement pseudo-instructions NEGU, SGT, and SGTU.
This commit is contained in:
Connor Olding 2016-04-26 01:30:55 -07:00
parent f3765a0300
commit 6b0d27ba6d
3 changed files with 120 additions and 22 deletions

View file

@ -211,7 +211,7 @@ function Preproc:pop(kind)
end end
function Preproc:expand(statements) function Preproc:expand(statements)
-- third pass: expand pseudo-instructions -- third pass: expand pseudo-instructions and register arguments
self.statements = {} self.statements = {}
for i=1, #statements do for i=1, #statements do
local s = statements[i] local s = statements[i]
@ -227,6 +227,23 @@ function Preproc:expand(statements)
error('Internal Error: unknown instruction') error('Internal Error: unknown instruction')
end end
if data.one_register_variants[name] then
self.i = 1
local a = self:register(data.all_registers)
local b = s[2]
if b == nil or b.tt ~= 'REG' then
insert(s, 2, self:token(a))
end
elseif data.two_register_variants[name] then
self.i = 1
local a = self:register(data.all_registers)
local b = self:register(data.all_registers)
local c = s[3]
if c == nil or c.tt ~= 'REG' then
insert(s, 2, self:token(a))
end
end
if overrides[name] then if overrides[name] then
self.i = 1 self.i = 1
overrides[name](self, name) overrides[name](self, name)

View file

@ -86,7 +86,13 @@ data.fmt_double = 17
data.fmt_word = 20 data.fmt_word = 20
data.fmt_long = 21 data.fmt_long = 21
-- set up dummy values for pseudo-instructions later
local __ = {} local __ = {}
-- instructions with the first two arguments as registers, but not the third
local o1 = {}
-- instructions with all three arguments as registers
local o2 = {}
data.instructions = { data.instructions = {
--[[ --[[
data guide: data guide:
@ -248,6 +254,7 @@ data.instructions = {
-- coprocessor-related instructions -- coprocessor-related instructions
-- TODO: these can take a code value
TEQ = {0, 'st', 'st00C', 52}, TEQ = {0, 'st', 'st00C', 52},
TGE = {0, 'st', 'st00C', 48}, TGE = {0, 'st', 'st00C', 48},
TGEU = {0, 'st', 'st00C', 49}, TGEU = {0, 'st', 'st00C', 49},
@ -280,6 +287,7 @@ data.instructions = {
CACHE = {47, 'iob', 'bio'}, CACHE = {47, 'iob', 'bio'},
-- misuses 'F' to write the initial bit -- misuses 'F' to write the initial bit
-- RFE = {16, '', 'F000C', 16, 16},
ERET = {16, '', 'F000C', 24, 16}, ERET = {16, '', 'F000C', 24, 16},
TLBP = {16, '', 'F000C', 8, 16}, TLBP = {16, '', 'F000C', 8, 16},
TLBR = {16, '', 'F000C', 1, 16}, TLBR = {16, '', 'F000C', 1, 16},
@ -381,8 +389,11 @@ data.instructions = {
CL = { 0, 'd', '00d0C', 37}, -- OR RD, R0, R0 CL = { 0, 'd', '00d0C', 37}, -- OR RD, R0, R0
MOV = { 0, 'ds', 's0d0C', 37}, -- OR RD, RS, R0 MOV = { 0, 'ds', 's0d0C', 37}, -- OR RD, RS, R0
NEG = { 0, 'dt', '0td0C', 34}, -- SUB RD, R0, RT NEG = { 0, 'dt', '0td0C', 34}, -- SUB RD, R0, RT
NEGU = { 0, 'dt', '0td0C', 35}, -- SUBU RD, R0, RT
NOP = { 0, '', '0'}, -- SLL R0, R0, 0 NOP = { 0, '', '0'}, -- SLL R0, R0, 0
NOT = { 0, 'ds', 's0d0C', 39}, -- NOR RD, RS, R0 NOT = { 0, 'ds', 's0d0C', 39}, -- NOR RD, RS, R0
SGT = { 0, 'dst', 'tsd0C', 42}, -- SLT RD, RT, RS
SGTU = { 0, 'dst', 'tsd0C', 43}, -- SLTU RD, RT, RS
SUBI = { 8, 'tsk', 'sti'}, -- ADDI RT, RS, -immediate SUBI = { 8, 'tsk', 'sti'}, -- ADDI RT, RS, -immediate
SUBIU = { 9, 'tsk', 'sti'}, -- ADDIU RT, RS, -immediate SUBIU = { 9, 'tsk', 'sti'}, -- ADDIU RT, RS, -immediate
@ -394,41 +405,95 @@ data.instructions = {
PUSH = __, PUSH = __,
POP = __, POP = __,
JPOP = __, JPOP = __,
-- CL = __, overridden to take varargs
ABS = __, -- BGEZ NOP SUBU? ABS = o1, -- SRA XOR SUBU
MUL = __, -- MULT MFLO MUL = o2, -- MULT MFLO
--DIV = __, -- 3 arguments -- DIV = o2, -- 3 arguments
REM = __, -- 3 arguments REM = o2, -- 3 arguments
NAND = __, -- AND, NOT NAND = o2, -- AND, NOT
NANDI = __, -- ANDI, NOT NANDI = o1, -- ANDI, NOT
NORI = __, -- ORI, NOT NORI = o1, -- ORI, NOT
ROL = __, -- SLL, SRL, OR ROL = o1, -- SLL, SRL, OR
ROR = __, -- SRL, SLL, OR ROR = o1, -- SRL, SLL, OR
SEQ = __, SEQI = __, SEQIU = __, SEQU = __, SEQ = o2,
SGE = __, SGEI = __, SGEIU = __, SGEU = __, SGE = o2, SGEU = o2,
SGT = __, SGTI = __, SGTIU = __, SGTU = __, SLE = o2, SLEU = o2,
SLE = __, SLEI = __, SLEIU = __, SLEU = __, SNE = o2,
SNE = __, SNEI = __, SNEIU = __, SNEU = __,
BGE = __, SEQI = o1, SEQIU = o1,
BLE = __, SGEI = o1, SGEIU = o1,
BLT = __, SGTI = o1, SGTIU = o1,
BGT = __, SLEI = o1, SLEIU = o1,
SNEI = o1, SNEIU = o1,
BGE = o1, BGEU = o1,
BLE = o1, BLEU = o1,
BLT = o1, BLTU = o1,
BGT = o1, BGTU = o1,
BEQI = __, BEQIL = __, BEQI = __, BEQIL = __,
BNEI = __, BNEIL = __,
BGEI = __, BGEIL = __, BGEI = __, BGEIL = __,
BGTI = __, BGTIL = __,
BLEI = __, BLEIL = __, BLEI = __, BLEIL = __,
BLTI = __, BLTIL = __, BLTI = __, BLTIL = __,
BGTI = __, BGTIL = __, BNEI = __, BNEIL = __,
BGEL = o1, BGEUL = o1,
BGTL = o1, BGTUL = o1,
BLEL = o1, BLEUL = o1,
BLTL = o1, BLTUL = o1,
} }
local register_types = {
d = 0,
s = 0,
t = 0,
D = 1,
S = 1,
T = 1,
X = 2,
Y = 2,
Z = 2,
}
data.one_register_variants = {}
data.two_register_variants = {}
data.all_instructions = {} data.all_instructions = {}
local i = 1 local i = 1
for k, v in pairs(data.instructions) do for k, v in pairs(data.instructions) do
data.all_instructions[k:gsub('_', '.')] = i local name = k:gsub('_', '.')
-- if the first two args of an instructions are the same register type,
-- allow it to be used with just one argument to cover both.
-- likewise, if all three arguments are registers of the same type,
-- allow just two to be used.
local fmt = v[2]
if fmt then
local a = fmt:sub(1, 1)
local b = fmt:sub(2, 2)
local c = fmt:sub(3, 3)
a = register_types[a]
b = register_types[b]
c = register_types[c]
if a ~= nil and b ~= nil and a == b then
if c == nil then
data.one_register_variants[name] = true
elseif c == a then
data.two_register_variants[name] = true
end
end
elseif v == o1 then
data.one_register_variants[name] = true
elseif v == o2 then
data.two_register_variants[name] = true
end
data.all_instructions[name] = i
i = i + 1 i = i + 1
end end
revtable(data.all_instructions) revtable(data.all_instructions)

View file

@ -177,6 +177,22 @@ function overrides:ROL(name)
end end
overrides.ROR = overrides.ROL overrides.ROR = overrides.ROL
function overrides:ABS(name)
local dest = self:pop('CPU')
local src = self:pop('CPU')
self:push_new('SRA', 'AT', src, 31)
self:push_new('XOR', dest, src, 'AT')
self:push_new('SUBU', dest, dest, 'AT')
end
function overrides:CL(name)
self:expect{'REG'} -- assert there's at least one argument
for i=1, #self.s do
local reg = self:pop('CPU')
self:push_new('CL', reg)
end
end
function overrides:JR(name) function overrides:JR(name)
local src = self:peek() and self:pop('CPU') or 'RA' local src = self:peek() and self:pop('CPU') or 'RA'
self:push_new('JR', src) self:push_new('JR', src)