DynASM/PPC: Add sub/shift/rotate/clear instruction aliases.

This commit is contained in:
Mike Pall 2015-04-12 01:27:17 +02:00
parent b2a5cc8233
commit 1c968d5b63
2 changed files with 88 additions and 12 deletions

View File

@ -230,8 +230,18 @@ local map_cond = {
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
local map_op, op_template
local function op_alias(opname, f)
return function(params, nparams)
if not params then return "-> "..opname:sub(1, -3) end
f(params, nparams)
op_template(params, map_op[opname], nparams)
end
end
-- Template strings for PPC instructions. -- Template strings for PPC instructions.
local map_op = { map_op = {
tdi_3 = "08000000ARI", tdi_3 = "08000000ARI",
twi_3 = "0c000000ARI", twi_3 = "0c000000ARI",
mulli_3 = "1c000000RRI", mulli_3 = "1c000000RRI",
@ -299,6 +309,33 @@ local map_op = {
std_2 = "f8000000RD", std_2 = "f8000000RD",
stdu_2 = "f8000001RD", stdu_2 = "f8000001RD",
subi_3 = op_alias("addi_3", function(p) p[3] = "-("..p[3]..")" end),
subis_3 = op_alias("addis_3", function(p) p[3] = "-("..p[3]..")" end),
subic_3 = op_alias("addic_3", function(p) p[3] = "-("..p[3]..")" end),
["subic._3"] = op_alias("addic._3", function(p) p[3] = "-("..p[3]..")" end),
rotlwi_3 = op_alias("rlwinm_5", function(p)
p[4] = "0"; p[5] = "31"
end),
rotrwi_3 = op_alias("rlwinm_5", function(p)
p[3] = "32-("..p[3]..")"; p[4] = "0"; p[5] = "31"
end),
rotlw_3 = op_alias("rlwnm_5", function(p)
p[4] = "0"; p[5] = "31"
end),
slwi_3 = op_alias("rlwinm_5", function(p)
p[5] = "31-("..p[3]..")"; p[4] = "0"
end),
srwi_3 = op_alias("rlwinm_5", function(p)
p[4] = p[3]; p[3] = "32-("..p[3]..")"; p[5] = "31"
end),
clrlwi_3 = op_alias("rlwinm_5", function(p)
p[4] = p[3]; p[3] = "0"; p[5] = "31"
end),
clrrwi_3 = op_alias("rlwinm_5", function(p)
p[5] = "31-("..p[3]..")"; p[3] = "0"; p[4] = "0"
end),
-- Primary opcode 4: -- Primary opcode 4:
mulhhwu_3 = "10000010RRR.", mulhhwu_3 = "10000010RRR.",
machhwu_3 = "10000018RRR.", machhwu_3 = "10000018RRR.",
@ -790,6 +827,28 @@ local map_op = {
rldcl_4 = "78000010RR~RM.", rldcl_4 = "78000010RR~RM.",
rldcr_4 = "78000012RR~RM.", rldcr_4 = "78000012RR~RM.",
rotldi_3 = op_alias("rldicl_4", function(p)
p[4] = "0"
end),
rotrdi_3 = op_alias("rldicl_4", function(p)
p[3] = "64-("..p[3]..")"; p[4] = "0"
end),
rotld_3 = op_alias("rldcl_4", function(p)
p[4] = "0"
end),
sldi_3 = op_alias("rldicr_4", function(p)
p[4] = "63-("..p[3]..")"
end),
srdi_3 = op_alias("rldicl_4", function(p)
p[4] = p[3]; p[3] = "64-("..p[3]..")"
end),
clrldi_3 = op_alias("rldicl_4", function(p)
p[4] = p[3]; p[3] = "0"
end),
clrrdi_3 = op_alias("rldicr_4", function(p)
p[4] = "63-("..p[3]..")"; p[3] = "0"
end),
-- Primary opcode 56: -- Primary opcode 56:
lq_2 = "e0000000R:D", -- NYI: displacement must be divisible by 8. lq_2 = "e0000000R:D", -- NYI: displacement must be divisible by 8.
@ -1358,7 +1417,7 @@ local map_op = {
do do
local t = {} local t = {}
for k,v in pairs(map_op) do for k,v in pairs(map_op) do
if sub(v, -1) == "." then if type(v) == "string" and sub(v, -1) == "." then
local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2) local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2)
t[sub(k, 1, -3).."."..sub(k, -2)] = v2 t[sub(k, 1, -3).."."..sub(k, -2)] = v2
end end
@ -1454,8 +1513,30 @@ local function parse_cond(expr)
werror("bad condition bit name `"..expr.."'") werror("bad condition bit name `"..expr.."'")
end end
local parse_ctx = {}
local loadenv = setfenv and function(s)
local code = loadstring(s, "")
if code then setfenv(code, parse_ctx) end
return code
end or function(s)
return load(s, "", nil, parse_ctx)
end
-- Try to parse simple arithmetic, too, since some basic ops are aliases.
local function parse_number(n)
local x = tonumber(n)
if x then return x end
local code = loadenv("return "..n)
if code then
local ok, y = pcall(code)
if ok then return y end
end
return nil
end
local function parse_imm(imm, bits, shift, scale, signed) local function parse_imm(imm, bits, shift, scale, signed)
local n = tonumber(imm) local n = parse_number(imm)
if n then if n then
local m = sar(n, scale) local m = sar(n, scale)
if shl(m, scale) == n then if shl(m, scale) == n then
@ -1479,7 +1560,7 @@ local function parse_imm(imm, bits, shift, scale, signed)
end end
local function parse_shiftmask(imm, isshift) local function parse_shiftmask(imm, isshift)
local n = tonumber(imm) local n = parse_number(imm)
if n then if n then
if shr(n, 6) == 0 then if shr(n, 6) == 0 then
local lsb = band(n, 31) local lsb = band(n, 31)
@ -1567,7 +1648,7 @@ end
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- Handle opcodes defined with template strings. -- Handle opcodes defined with template strings.
map_op[".template__"] = function(params, template, nparams) op_template = function(params, template, nparams)
if not params then return sub(template, 9) end if not params then return sub(template, 9) end
local op = tonumber(sub(template, 1, 8), 16) local op = tonumber(sub(template, 1, 8), 16)
local n, rs = 1, 26 local n, rs = 1, 26
@ -1669,6 +1750,8 @@ map_op[".template__"] = function(params, template, nparams)
wputpos(pos, op) wputpos(pos, op)
end end
map_op[".template__"] = op_template
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- Pseudo-opcode to mark the position where the action list is to be emitted. -- Pseudo-opcode to mark the position where the action list is to be emitted.

View File

@ -320,13 +320,6 @@
| |
|//----------------------------------------------------------------------- |//-----------------------------------------------------------------------
| |
|// These basic macros should really be part of DynASM.
|.macro srwi, rx, ry, n; rlwinm rx, ry, 32-n, n, 31; .endmacro
|.macro slwi, rx, ry, n; rlwinm rx, ry, n, 0, 31-n; .endmacro
|.macro rotlwi, rx, ry, n; rlwinm rx, ry, n, 0, 31; .endmacro
|.macro rotlw, rx, ry, rn; rlwnm rx, ry, rn, 0, 31; .endmacro
|.macro subi, rx, ry, i; addi rx, ry, -i; .endmacro
|
|// Trap for not-yet-implemented parts. |// Trap for not-yet-implemented parts.
|.macro NYI; tw 4, sp, sp; .endmacro |.macro NYI; tw 4, sp, sp; .endmacro
| |