mirror of
https://github.com/notwa/lips
synced 2024-05-03 10:03:23 -07:00
implement all branch pseudo-instructions
This commit is contained in:
parent
8375eaff08
commit
e4e8e16ea5
|
@ -165,7 +165,7 @@ Whether or not they output the proper machine code is another thing.
|
||||||
|
|
||||||
* MUL, DIV, REM
|
* MUL, DIV, REM
|
||||||
|
|
||||||
* many Set/Branch pseudo-instructions
|
* many Set [Condition] pseudo-instructions
|
||||||
|
|
||||||
## Registers
|
## Registers
|
||||||
|
|
||||||
|
|
|
@ -443,12 +443,13 @@ data.instructions = {
|
||||||
BLT = o1, BLTU = o1,
|
BLT = o1, BLTU = o1,
|
||||||
BGT = o1, BGTU = o1,
|
BGT = o1, BGTU = o1,
|
||||||
|
|
||||||
BEQI = __, BEQIL = __,
|
-- note: signedness of BEQI/BNEI determines how the immediate is loaded
|
||||||
BGEI = __, BGEIL = __,
|
BEQI = __, BEQIU = __, BEQIL = __, BEQIUL = __,
|
||||||
BGTI = __, BGTIL = __,
|
BGEI = __, BGEIU = __, BGEIL = __, BGEIUL = __,
|
||||||
BLEI = __, BLEIL = __,
|
BGTI = __, BGTIU = __, BGTIL = __, BGTIUL = __,
|
||||||
BLTI = __, BLTIL = __,
|
BLEI = __, BLEIU = __, BLEIL = __, BLEIUL = __,
|
||||||
BNEI = __, BNEIL = __,
|
BLTI = __, BLTIU = __, BLTIL = __, BLTIUL = __,
|
||||||
|
BNEI = __, BNEIU = __, BNEIL = __, BNEIUL = __,
|
||||||
|
|
||||||
BGEL = o1, BGEUL = o1,
|
BGEL = o1, BGEUL = o1,
|
||||||
BGTL = o1, BGTUL = o1,
|
BGTL = o1, BGTUL = o1,
|
||||||
|
|
|
@ -3,6 +3,14 @@ local insert = table.insert
|
||||||
local path = string.gsub(..., "[^.]+$", "")
|
local path = string.gsub(..., "[^.]+$", "")
|
||||||
local data = require(path.."data")
|
local data = require(path.."data")
|
||||||
|
|
||||||
|
local function name_pop(name, character)
|
||||||
|
if name:sub(#name) == character then
|
||||||
|
return name:sub(1, #name - 1), character
|
||||||
|
else
|
||||||
|
return name, ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local overrides = {}
|
local overrides = {}
|
||||||
-- note: "self" is an instance of Preproc
|
-- note: "self" is an instance of Preproc
|
||||||
|
|
||||||
|
@ -163,6 +171,8 @@ function overrides:NORI(name)
|
||||||
self:push_new('NOR', dest, dest, 'R0') -- NOT
|
self:push_new('NOR', dest, dest, 'R0') -- NOT
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- TODO: ROLV/RORV-like versions of this
|
||||||
|
-- maybe give the same auto-register treatment to SLL/SRL/SRA too
|
||||||
function overrides:ROL(name)
|
function overrides:ROL(name)
|
||||||
local first = name == 'ROL' and 'SLL' or 'SRL'
|
local first = name == 'ROL' and 'SLL' or 'SRL'
|
||||||
local second = name == 'ROL' and 'SRL' or 'SLL'
|
local second = name == 'ROL' and 'SRL' or 'SLL'
|
||||||
|
@ -205,65 +215,107 @@ function overrides:JR(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
local branch_basics = {
|
local branch_basics = {
|
||||||
|
BEQ = 'BEQ',
|
||||||
BGE = 'BEQ',
|
BGE = 'BEQ',
|
||||||
|
BGT = 'BNE',
|
||||||
BLE = 'BEQ',
|
BLE = 'BEQ',
|
||||||
BLT = 'BNE',
|
BLT = 'BNE',
|
||||||
BGT = 'BNE',
|
BNE = 'BNE',
|
||||||
BGEL = 'BEQL',
|
|
||||||
BLEL = 'BEQL',
|
|
||||||
BLTL = 'BNEL',
|
|
||||||
BGTL = 'BNEL',
|
|
||||||
|
|
||||||
BEQI = 'BEQ',
|
|
||||||
BGEI = 'BEQ',
|
|
||||||
BGTI = 'BEQ',
|
|
||||||
BLEI = 'BNE',
|
|
||||||
BLTI = 'BNE',
|
|
||||||
BNEI = 'BNE',
|
|
||||||
BEQIL = 'BEQL',
|
|
||||||
BGEIL = 'BEQL',
|
|
||||||
BGTIL = 'BEQL',
|
|
||||||
BLEIL = 'BNEL',
|
|
||||||
BLTIL = 'BNEL',
|
|
||||||
BNEIL = 'BNEL',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function overrides:BLT(name)
|
function overrides:BLT(name)
|
||||||
local slt = name:sub(#name) == 'U' and 'SLTU' or 'SLT'
|
local likely, unsigned
|
||||||
local branch = branch_basics[name:sub(1, 3)]
|
name, likely = name_pop(name, 'L')
|
||||||
|
name, unsigned = name_pop(name, 'U')
|
||||||
|
local branch = branch_basics[name]
|
||||||
local a = self:pop('CPU')
|
local a = self:pop('CPU')
|
||||||
local b = self:pop('CPU')
|
local b = self:pop('CPU')
|
||||||
local offset = self:pop('CONST')
|
local offset = self:pop('CONST')
|
||||||
self:push_new(slt, 'AT', a, b)
|
self:push_new('SLT'..unsigned, 'AT', a, b)
|
||||||
self:push_new(branch, 'AT', 'R0', offset)
|
self:push_new(branch..likely, 'AT', 'R0', offset)
|
||||||
end
|
end
|
||||||
|
|
||||||
function overrides:BLE(name)
|
function overrides:BLE(name)
|
||||||
local slt = name:sub(#name) == 'U' and 'SLTU' or 'SLT'
|
local likely, unsigned
|
||||||
local branch = branch_basics[name:sub(1, 3)]
|
name, likely = name_pop(name, 'L')
|
||||||
|
name, unsigned = name_pop(name, 'U')
|
||||||
|
local branch = branch_basics[name]
|
||||||
local a = self:pop('CPU')
|
local a = self:pop('CPU')
|
||||||
local b = self:pop('CPU')
|
local b = self:pop('CPU')
|
||||||
local offset = self:pop('CONST')
|
local offset = self:pop('CONST')
|
||||||
self:push_new(slt, 'AT', b, a)
|
self:push_new('SLT'..unsigned, 'AT', b, a)
|
||||||
self:push_new(branch, 'AT', 'R0', offset)
|
self:push_new(branch..likely, 'AT', 'R0', offset)
|
||||||
end
|
end
|
||||||
|
|
||||||
overrides.BGE = overrides.BLT
|
function overrides:BLTI(name)
|
||||||
overrides.BGT = overrides.BLE
|
local likely, unsigned
|
||||||
|
name, likely = name_pop(name, 'L')
|
||||||
|
name, unsigned = name_pop(name, 'U')
|
||||||
|
local branch = branch_basics[name:sub(1, #name - 1)]
|
||||||
|
local reg = self:pop('CPU')
|
||||||
|
local im = self:pop('CONST')
|
||||||
|
local offset = self:pop('CONST')
|
||||||
|
self:push_new('SLTI'..unsigned, 'AT', reg, im)
|
||||||
|
self:push_new(branch..likely, 'AT', 'R0', offset)
|
||||||
|
end
|
||||||
|
|
||||||
overrides.BGEL = overrides.BLT
|
function overrides:BLEI(name)
|
||||||
overrides.BGTL = overrides.BLE
|
local likely, unsigned
|
||||||
overrides.BLEL = overrides.BLE
|
name, likely = name_pop(name, 'L')
|
||||||
overrides.BLTL = overrides.BLT
|
name, unsigned = name_pop(name, 'U')
|
||||||
|
local branch = branch_basics[name:sub(1, #name - 1)]
|
||||||
|
local loadi = unsigned == 'U' and 'ORI' or 'ADDIU'
|
||||||
|
local reg = self:pop('CPU')
|
||||||
|
local im = self:pop('CONST')
|
||||||
|
local offset = self:pop('CONST')
|
||||||
|
self:push_new(loadi, 'AT', 'R0', im)
|
||||||
|
self:push_new('SLT'..unsigned, 'AT', 'AT', reg)
|
||||||
|
self:push_new(branch..likely, 'AT', 'R0', offset)
|
||||||
|
end
|
||||||
|
|
||||||
overrides.BGEU = overrides.BLT
|
function overrides:BEQI(name)
|
||||||
overrides.BGTU = overrides.BLE
|
local likely, unsigned
|
||||||
overrides.BLEU = overrides.BLE
|
name, likely = name_pop(name, 'L')
|
||||||
overrides.BLTU = overrides.BLT
|
name, unsigned = name_pop(name, 'U')
|
||||||
|
local branch = name:sub(1, #name - 1)
|
||||||
|
local loadi = unsigned == 'U' and 'ORI' or 'ADDIU'
|
||||||
|
local reg = self:pop('CPU')
|
||||||
|
local im = self:pop('CONST')
|
||||||
|
local offset = self:pop('CONST')
|
||||||
|
self:push_new(loadi, 'AT', 'R0', im)
|
||||||
|
self:push_new(branch..likely, reg, 'AT', offset)
|
||||||
|
end
|
||||||
|
|
||||||
overrides.BGEUL = overrides.BLT
|
local BLT = overrides.BLT
|
||||||
overrides.BGTUL = overrides.BLE
|
local BLE = overrides.BLE
|
||||||
overrides.BLEUL = overrides.BLE
|
local BLTI = overrides.BLTI
|
||||||
overrides.BLTUL = overrides.BLT
|
local BLEI = overrides.BLEI
|
||||||
|
local BEQI = overrides.BEQI
|
||||||
|
for k, v in pairs{
|
||||||
|
BGE = BLT, BGEI = BLTI,
|
||||||
|
BGT = BLE, BGTI = BLEI,
|
||||||
|
|
||||||
|
BGEL = BLT, BGEIL = BLTI,
|
||||||
|
BGTL = BLE, BGTIL = BLEI,
|
||||||
|
BLEL = BLE, BLEIL = BLEI,
|
||||||
|
BLTL = BLT, BLTIL = BLTI,
|
||||||
|
|
||||||
|
BGEU = BLT, BGEIU = BLTI,
|
||||||
|
BGTU = BLE, BGTIU = BLEI,
|
||||||
|
BLEU = BLE, BLEIU = BLEI,
|
||||||
|
BLTU = BLT, BLTIU = BLTI,
|
||||||
|
|
||||||
|
BGEUL = BLT, BGEIUL = BLTI,
|
||||||
|
BGTUL = BLE, BGTIUL = BLEI,
|
||||||
|
BLEUL = BLE, BLEIUL = BLEI,
|
||||||
|
BLTUL = BLT, BLTIUL = BLTI,
|
||||||
|
|
||||||
|
BEQI = BEQI, BEQIU = BEQI,
|
||||||
|
BEQIL = BEQI, BEQIUL = BEQI,
|
||||||
|
BNEI = BEQI, BNEIU = BEQI,
|
||||||
|
BNEIL = BEQI, BNEIUL = BEQI,
|
||||||
|
} do
|
||||||
|
overrides[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
return overrides
|
return overrides
|
||||||
|
|
Loading…
Reference in New Issue
Block a user