1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-11-14 09:19:02 -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
function Preproc:expand(statements)
-- third pass: expand pseudo-instructions
-- third pass: expand pseudo-instructions and register arguments
self.statements = {}
for i=1, #statements do
local s = statements[i]
@ -227,6 +227,23 @@ function Preproc:expand(statements)
error('Internal Error: unknown instruction')
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
self.i = 1
overrides[name](self, name)

View file

@ -86,7 +86,13 @@ data.fmt_double = 17
data.fmt_word = 20
data.fmt_long = 21
-- set up dummy values for pseudo-instructions later
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 guide:
@ -248,6 +254,7 @@ data.instructions = {
-- coprocessor-related instructions
-- TODO: these can take a code value
TEQ = {0, 'st', 'st00C', 52},
TGE = {0, 'st', 'st00C', 48},
TGEU = {0, 'st', 'st00C', 49},
@ -280,6 +287,7 @@ data.instructions = {
CACHE = {47, 'iob', 'bio'},
-- misuses 'F' to write the initial bit
-- RFE = {16, '', 'F000C', 16, 16},
ERET = {16, '', 'F000C', 24, 16},
TLBP = {16, '', 'F000C', 8, 16},
TLBR = {16, '', 'F000C', 1, 16},
@ -381,8 +389,11 @@ data.instructions = {
CL = { 0, 'd', '00d0C', 37}, -- OR RD, R0, R0
MOV = { 0, 'ds', 's0d0C', 37}, -- OR RD, RS, R0
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
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
SUBIU = { 9, 'tsk', 'sti'}, -- ADDIU RT, RS, -immediate
@ -394,41 +405,95 @@ data.instructions = {
PUSH = __,
POP = __,
JPOP = __,
-- CL = __, overridden to take varargs
ABS = __, -- BGEZ NOP SUBU?
MUL = __, -- MULT MFLO
--DIV = __, -- 3 arguments
REM = __, -- 3 arguments
ABS = o1, -- SRA XOR SUBU
MUL = o2, -- MULT MFLO
-- DIV = o2, -- 3 arguments
REM = o2, -- 3 arguments
NAND = __, -- AND, NOT
NANDI = __, -- ANDI, NOT
NORI = __, -- ORI, NOT
ROL = __, -- SLL, SRL, OR
ROR = __, -- SRL, SLL, OR
NAND = o2, -- AND, NOT
NANDI = o1, -- ANDI, NOT
NORI = o1, -- ORI, NOT
ROL = o1, -- SLL, SRL, OR
ROR = o1, -- SRL, SLL, OR
SEQ = __, SEQI = __, SEQIU = __, SEQU = __,
SGE = __, SGEI = __, SGEIU = __, SGEU = __,
SGT = __, SGTI = __, SGTIU = __, SGTU = __,
SLE = __, SLEI = __, SLEIU = __, SLEU = __,
SNE = __, SNEI = __, SNEIU = __, SNEU = __,
SEQ = o2,
SGE = o2, SGEU = o2,
SLE = o2, SLEU = o2,
SNE = o2,
BGE = __,
BLE = __,
BLT = __,
BGT = __,
SEQI = o1, SEQIU = o1,
SGEI = o1, SGEIU = o1,
SGTI = o1, SGTIU = o1,
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 = __,
BNEI = __, BNEIL = __,
BGEI = __, BGEIL = __,
BGTI = __, BGTIL = __,
BLEI = __, BLEIL = __,
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 = {}
local i = 1
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
end
revtable(data.all_instructions)

View file

@ -177,6 +177,22 @@ function overrides:ROL(name)
end
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)
local src = self:peek() and self:pop('CPU') or 'RA'
self:push_new('JR', src)