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:
parent
f3765a0300
commit
6b0d27ba6d
3 changed files with 120 additions and 22 deletions
|
@ -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)
|
||||||
|
|
107
lips/data.lua
107
lips/data.lua
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue