mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 15:34:09 +00:00
Add support for SS-a instructions.
I've also changed the template parser so that it can handle suffixes which are longer than 1 character. The suffix for SS-a instructions is "SS-a". We could change this again later.
This commit is contained in:
parent
8281c33747
commit
106718249e
@ -258,6 +258,39 @@ static void load_test(dasm_State *state)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void ssa(dasm_State *state) {
|
||||||
|
dasm_State **Dst = &state;
|
||||||
|
|
||||||
|
| lay sp, -16(sp)
|
||||||
|
| lay r0, -1(r0)
|
||||||
|
| stg r0, 8(sp)
|
||||||
|
| xc 8(8, sp), 8(sp)
|
||||||
|
| stg r2, 0(sp)
|
||||||
|
| mvc 13(2, sp), 6(sp)
|
||||||
|
| lg r2, 8(sp)
|
||||||
|
| la sp, 16(sp)
|
||||||
|
| br r14
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ssa_act(dasm_State *state) {
|
||||||
|
dasm_State **Dst = &state;
|
||||||
|
|
||||||
|
int xl = 8;
|
||||||
|
int d1 = 13;
|
||||||
|
int l1 = 2;
|
||||||
|
int d2 = 6;
|
||||||
|
|
||||||
|
| lay sp, -16(sp)
|
||||||
|
| lay r0, -1(r0)
|
||||||
|
| stg r0, 8(sp)
|
||||||
|
| xc 8(xl, sp), 8(sp)
|
||||||
|
| stg r2, 0(sp)
|
||||||
|
| mvc d1(l1, sp), d2(sp)
|
||||||
|
| lg r2, 8(sp)
|
||||||
|
| la sp, 16(sp)
|
||||||
|
| br r14
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t arg1;
|
int64_t arg1;
|
||||||
int64_t arg2;
|
int64_t arg2;
|
||||||
@ -267,22 +300,24 @@ typedef struct {
|
|||||||
} test_table;
|
} test_table;
|
||||||
|
|
||||||
test_table test[] = {
|
test_table test[] = {
|
||||||
{ 1, 2, add, 3, "add"},
|
{ 1, 2, add, 3, "add"},
|
||||||
{10, 5, sub, 5, "sub"},
|
{10, 5, sub, 5, "sub"},
|
||||||
{ 2, 3, mul, 6, "mul"},
|
{ 2, 3, mul, 6, "mul"},
|
||||||
{ 5, 7, rx, 12298, "rx"},
|
{ 5, 7, rx, 12298, "rx"},
|
||||||
{ 5, 7, rxy, 10, "rxy"},
|
{ 5, 7, rxy, 10, "rxy"},
|
||||||
{ 2, 4, lab, 32, "lab"},
|
{ 2, 4, lab, 32, "lab"},
|
||||||
{ 2, 4, labg, 32, "labg"},
|
{ 2, 4, labg, 32, "labg"},
|
||||||
{ 2, 0, add_imm16, 17, "imm16"},
|
{ 2, 0, add_imm16, 17, "imm16"},
|
||||||
{ 2, 0, add_imm32, 16, "imm32"},
|
{ 2, 0, add_imm32, 16, "imm32"},
|
||||||
{ 7, 3, save, 480, "save"},
|
{ 7, 3, save, 480, "save"},
|
||||||
{ 7, 3, labmul, 21, "labmul0"},
|
{ 7, 3, labmul, 21, "labmul0"},
|
||||||
{ 7, 0, labmul, 0, "labmul1"},
|
{ 7, 0, labmul, 0, "labmul1"},
|
||||||
{ 0, 0, pc, 55, "pc"},
|
{ 0, 0, pc, 55, "pc"},
|
||||||
{ 2,12, jmp_fwd, 12, "jmp_fwd"}
|
{ 2,12, jmp_fwd, 12, "jmp_fwd"},
|
||||||
// { 9,8, add_rrd, 25, "add_rrd"},
|
// { 9,8, add_rrd, 25, "add_rrd"},
|
||||||
// { 2,4, load_test, 4,"load_test"}
|
// { 2,4, load_test, 4,"load_test"},
|
||||||
|
{-1, 0, ssa, 65535<<8, "ssa"},
|
||||||
|
{-1, 0, ssa_act, 65535<<8, "ssa_act"}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *jitcode(dasm_State **state, size_t *size)
|
static void *jitcode(dasm_State **state, size_t *size)
|
||||||
|
@ -24,6 +24,7 @@ enum {
|
|||||||
DASM_REL_PC, DASM_LABEL_PC,
|
DASM_REL_PC, DASM_LABEL_PC,
|
||||||
DASM_DISP12, DASM_DISP20,
|
DASM_DISP12, DASM_DISP20,
|
||||||
DASM_IMM16, DASM_IMM32,
|
DASM_IMM16, DASM_IMM32,
|
||||||
|
DASM_LEN8R,
|
||||||
DASM__MAX
|
DASM__MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -284,6 +285,10 @@ void dasm_put(Dst_DECL, int start, ...)
|
|||||||
CK((n >> 12) == 0, RANGE_I);
|
CK((n >> 12) == 0, RANGE_I);
|
||||||
b[pos++] = n;
|
b[pos++] = n;
|
||||||
break;
|
break;
|
||||||
|
case DASM_LEN8R:
|
||||||
|
CK(n >= 1 && n <= 256, RANGE_I);
|
||||||
|
b[pos++] = n;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stop:
|
stop:
|
||||||
@ -364,6 +369,7 @@ int dasm_link(Dst_DECL, size_t * szp)
|
|||||||
case DASM_IMM32:
|
case DASM_IMM32:
|
||||||
case DASM_DISP20:
|
case DASM_DISP20:
|
||||||
case DASM_DISP12:
|
case DASM_DISP12:
|
||||||
|
case DASM_LEN8R:
|
||||||
pos++;
|
pos++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -458,6 +464,9 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||||||
case DASM_DISP12:
|
case DASM_DISP12:
|
||||||
cp[-1] |= n & 0xfff;
|
cp[-1] |= n & 0xfff;
|
||||||
break;
|
break;
|
||||||
|
case DASM_LEN8R:
|
||||||
|
cp[-1] |= (n - 1) & 0xff;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
*cp++ = ins;
|
*cp++ = ins;
|
||||||
break;
|
break;
|
||||||
|
@ -39,7 +39,7 @@ local wline, werror, wfatal, wwarn
|
|||||||
local action_names = {
|
local action_names = {
|
||||||
"STOP", "SECTION", "ESC", "REL_EXT",
|
"STOP", "SECTION", "ESC", "REL_EXT",
|
||||||
"ALIGN", "REL_LG", "LABEL_LG",
|
"ALIGN", "REL_LG", "LABEL_LG",
|
||||||
"REL_PC", "LABEL_PC", "DISP12", "DISP20", "IMM16", "IMM32",
|
"REL_PC", "LABEL_PC", "DISP12", "DISP20", "IMM16", "IMM32", "LEN8R",
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Maximum number of section buffer positions for dasm_put().
|
-- Maximum number of section buffer positions for dasm_put().
|
||||||
@ -370,6 +370,41 @@ local function parse_mem_by(arg)
|
|||||||
return d, b, a
|
return d, b, a
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Parse memory operand of the form d(l, b) where 0 <= d < 4096, 1 <= l <= 256,
|
||||||
|
-- and b is a GPR.
|
||||||
|
local function parse_mem_lb(arg)
|
||||||
|
local reg = "r1?[0-9]"
|
||||||
|
local d, l, b = match(arg, "^(.*)%s*%(%s*(.*)%s*,%s*("..reg..")%s*%)$")
|
||||||
|
if not d then
|
||||||
|
-- TODO: handle values without registers?
|
||||||
|
-- TODO: handle registers without a displacement?
|
||||||
|
werror("bad memory operand: "..arg)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local dval = tonumber(d)
|
||||||
|
local dact = nil
|
||||||
|
if dval then
|
||||||
|
if not is_uint12(dval) then
|
||||||
|
werror("displacement out of range: ", dval)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
dval = 0
|
||||||
|
dact = function() waction("DISP12", nil, d) end
|
||||||
|
end
|
||||||
|
local lval = tonumber(l)
|
||||||
|
local lact = nil
|
||||||
|
if lval then
|
||||||
|
if lval < 1 or lval > 256 then
|
||||||
|
werror("length out of range: ", dval)
|
||||||
|
end
|
||||||
|
lval = lval - 1
|
||||||
|
else
|
||||||
|
lval = 0
|
||||||
|
lact = function() waction("LEN8R", nil, l) end
|
||||||
|
end
|
||||||
|
return dval, lval, parse_reg(b), dact, lact
|
||||||
|
end
|
||||||
|
|
||||||
local function parse_imm(arg)
|
local function parse_imm(arg)
|
||||||
local imm_val = tonumber(arg,16)
|
local imm_val = tonumber(arg,16)
|
||||||
if imm_val then
|
if imm_val then
|
||||||
@ -1014,6 +1049,23 @@ map_op = {
|
|||||||
trace_3 = "000099000000q",
|
trace_3 = "000099000000q",
|
||||||
tracg_3 = "eb000000000fs",
|
tracg_3 = "eb000000000fs",
|
||||||
tre_2 = "0000b2a50000h",
|
tre_2 = "0000b2a50000h",
|
||||||
|
|
||||||
|
-- SS-a instructions
|
||||||
|
clc_2 = "d50000000000SS-a",
|
||||||
|
ed_2 = "de0000000000SS-a",
|
||||||
|
edmk_2 = "df0000000000SS-a",
|
||||||
|
mvc_2 = "d20000000000SS-a",
|
||||||
|
mvcin_2 = "e80000000000SS-a",
|
||||||
|
mvn_2 = "d10000000000SS-a",
|
||||||
|
mvz_2 = "d30000000000SS-a",
|
||||||
|
nc_2 = "d40000000000SS-a",
|
||||||
|
oc_2 = "d60000000000SS-a",
|
||||||
|
tr_2 = "dc0000000000SS-a",
|
||||||
|
trt_2 = "dd0000000000SS-a",
|
||||||
|
trtr_2 = "d00000000000SS-a",
|
||||||
|
unpka_2 = "ea0000000000SS-a",
|
||||||
|
unpku_2 = "e20000000000SS-a",
|
||||||
|
xc_2 = "d70000000000SS-a",
|
||||||
}
|
}
|
||||||
for cond,c in pairs(map_cond) do
|
for cond,c in pairs(map_cond) do
|
||||||
-- Extended mnemonics for branches.
|
-- Extended mnemonics for branches.
|
||||||
@ -1037,85 +1089,94 @@ local function parse_template(params, template, nparams, pos)
|
|||||||
local op2 = tonumber(sub(template, 9, 12), 16)
|
local op2 = tonumber(sub(template, 9, 12), 16)
|
||||||
|
|
||||||
-- Process each character.
|
-- Process each character.
|
||||||
for p in gmatch(sub(template, 13), ".") do
|
local p = sub(template, 13)
|
||||||
local pr1,pr2,pr3
|
if p == "g" then
|
||||||
if p == "g" then
|
op2 = op2 + shl(parse_reg(params[1]),4) + parse_reg(params[2])
|
||||||
op2 = op2 + shl(parse_reg(params[1]),4) + parse_reg(params[2])
|
wputhw(op2)
|
||||||
wputhw(op2)
|
elseif p == "h" then
|
||||||
elseif p == "h" then
|
op2 = op2 + shl(parse_reg(params[1]),4) + parse_reg(params[2])
|
||||||
op2 = op2 + shl(parse_reg(params[1]),4) + parse_reg(params[2])
|
wputhw(op1); wputhw(op2)
|
||||||
wputhw(op1); wputhw(op2)
|
elseif p == "i" then
|
||||||
elseif p == "i" then
|
op1 = op1 + shl(parse_reg(params[1]),4)
|
||||||
op1 = op1 + shl(parse_reg(params[1]),4)
|
wputhw(op1);
|
||||||
wputhw(op1);
|
parse_imm16(params[2])
|
||||||
parse_imm16(params[2])
|
elseif p == "j" then
|
||||||
elseif p == "j" then
|
local d, x, b, a = parse_mem_bx(params[2])
|
||||||
local d, x, b, a = parse_mem_bx(params[2])
|
op1 = op1 + shl(parse_reg(params[1]), 4) + x
|
||||||
op1 = op1 + shl(parse_reg(params[1]), 4) + x
|
op2 = op2 + shl(b, 12) + d
|
||||||
op2 = op2 + shl(b, 12) + d
|
wputhw(op1); wputhw(op2);
|
||||||
wputhw(op1); wputhw(op2);
|
if a then a() end
|
||||||
if a then a() end
|
elseif p == "k" then
|
||||||
elseif p == "k" then
|
elseif p == "l" then
|
||||||
|
local d, x, b, a = parse_mem_bxy(params[2])
|
||||||
|
op0 = op0 + shl(parse_reg(params[1]), 4) + x
|
||||||
|
op1 = op1 + shl(b, 12) + band(d, 0xfff)
|
||||||
|
op2 = op2 + band(shr(d, 4), 0xff00)
|
||||||
|
wputhw(op0); wputhw(op1); wputhw(op2)
|
||||||
|
if a then a() end
|
||||||
|
elseif p == "m" then
|
||||||
|
|
||||||
elseif p == "l" then
|
elseif p == "n" then
|
||||||
local d, x, b, a = parse_mem_bxy(params[2])
|
op0 = op0 + shl(parse_reg(params[1]), 4)
|
||||||
op0 = op0 + shl(parse_reg(params[1]), 4) + x
|
wputhw(op0);
|
||||||
op1 = op1 + shl(b, 12) + band(d, 0xfff)
|
parse_imm(params[2])
|
||||||
op2 = op2 + band(shr(d, 4), 0xff00)
|
elseif p == "o" then
|
||||||
wputhw(op0); wputhw(op1); wputhw(op2)
|
op0 = op0 + shl(parse_reg(params[1]), 4)
|
||||||
if a then a() end
|
wputhw(op0);
|
||||||
elseif p == "m" then
|
local mode, n, s = parse_label(params[2])
|
||||||
|
waction("REL_"..mode, n, s)
|
||||||
elseif p == "n" then
|
elseif p == "q" then
|
||||||
op0 = op0 + shl(parse_reg(params[1]), 4)
|
local d, b, a = parse_mem_b(params[3])
|
||||||
wputhw(op0);
|
op1 = op1 + shl(parse_reg(params[1]), 4) + parse_reg(params[2])
|
||||||
parse_imm(params[2])
|
op2 = op2 + shl(b, 12) + d
|
||||||
elseif p == "o" then
|
wputhw(op1); wputhw(op2)
|
||||||
op0 = op0 + shl(parse_reg(params[1]), 4)
|
if a then a() end -- a() emits action.
|
||||||
wputhw(op0);
|
elseif p == "r" then
|
||||||
local mode, n, s = parse_label(params[2])
|
op2 = op2 + shl(parse_reg(params[1]),12) + shl(parse_reg(params[2]),4) + parse_reg(params[3])
|
||||||
waction("REL_"..mode, n, s)
|
wputhw(op1); wputhw(op2)
|
||||||
elseif p == "q" then
|
elseif p == "s" then
|
||||||
local d, b, a = parse_mem_b(params[3])
|
local d, b, a = parse_mem_by(params[3])
|
||||||
op1 = op1 + shl(parse_reg(params[1]), 4) + parse_reg(params[2])
|
op0 = op0 + shl(parse_reg(params[1]), 4) + parse_reg(params[2])
|
||||||
op2 = op2 + shl(b, 12) + d
|
op1 = op1 + shl(b, 12) + band(d, 0xfff)
|
||||||
wputhw(op1); wputhw(op2)
|
op2 = op2 + band(shr(d, 4), 0xff00)
|
||||||
if a then a() end -- a() emits action.
|
wputhw(op0); wputhw(op1); wputhw(op2)
|
||||||
elseif p == "r" then
|
if a then a() end -- a() emits action.
|
||||||
op2 = op2 + shl(parse_reg(params[1]),12) + shl(parse_reg(params[2]),4) + parse_reg(params[3])
|
elseif p == "SS-a" then
|
||||||
wputhw(op1); wputhw(op2)
|
local d1, l1, b1, d1a, l1a = parse_mem_lb(params[1])
|
||||||
elseif p == "s" then
|
local d2, b2, d2a = parse_mem_b(params[2])
|
||||||
local d, b, a = parse_mem_by(params[3])
|
op0 = op0 + l1
|
||||||
op0 = op0 + shl(parse_reg(params[1]), 4) + parse_reg(params[2])
|
op1 = op1 + shl(b1, 12) + d1
|
||||||
op1 = op1 + shl(b, 12) + band(d, 0xfff)
|
op2 = op2 + shl(b2, 12) + d2
|
||||||
op2 = op2 + band(shr(d, 4), 0xff00)
|
wputhw(op0)
|
||||||
wputhw(op0); wputhw(op1); wputhw(op2)
|
if l1a then l1a() end
|
||||||
if a then a() end -- a() emits action.
|
wputhw(op1)
|
||||||
elseif p == "w" then
|
if d1a then d1a() end
|
||||||
local mode, n, s = parse_label(params[1])
|
wputhw(op2)
|
||||||
wputhw(op1)
|
if d2a then d2a() end
|
||||||
waction("REL_"..mode, n, s)
|
elseif p == "w" then
|
||||||
elseif p == "x" then
|
local mode, n, s = parse_label(params[1])
|
||||||
local mode, n, s = parse_label(params[1])
|
wputhw(op1)
|
||||||
wputhw(op0)
|
waction("REL_"..mode, n, s)
|
||||||
waction("REL_"..mode, n, s)
|
elseif p == "x" then
|
||||||
elseif p == "y" then
|
local mode, n, s = parse_label(params[1])
|
||||||
local d, x, b, a = parse_mem_bx(params[1])
|
wputhw(op0)
|
||||||
op1 = op1 + x
|
waction("REL_"..mode, n, s)
|
||||||
op2 = op2 + shl(b, 12) + d
|
elseif p == "y" then
|
||||||
wputhw(op1); wputhw(op2);
|
local d, x, b, a = parse_mem_bx(params[1])
|
||||||
if a then a() end -- a() emits action.
|
op1 = op1 + x
|
||||||
elseif p == "z" then
|
op2 = op2 + shl(b, 12) + d
|
||||||
op2 = op2 + parse_reg(params[1])
|
wputhw(op1); wputhw(op2);
|
||||||
wputhw(op2)
|
if a then a() end -- a() emits action.
|
||||||
else
|
elseif p == "z" then
|
||||||
werror("unrecognized encoding")
|
op2 = op2 + parse_reg(params[1])
|
||||||
end
|
wputhw(op2)
|
||||||
|
else
|
||||||
|
werror("unrecognized encoding")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function op_template(params, template, nparams)
|
function op_template(params, template, nparams)
|
||||||
if not params then return template:gsub("%x%x%x%x%x%x%x%x", "") end
|
if not params then return template:gsub("%x%x%x%x%x%x%x%x%x%x%x%x", "") end
|
||||||
-- Limit number of section buffer positions used by a single dasm_put().
|
-- Limit number of section buffer positions used by a single dasm_put().
|
||||||
-- A single opcode needs a maximum of 5 positions.
|
-- A single opcode needs a maximum of 5 positions.
|
||||||
if secpos+5 > maxsecpos then wflush() end
|
if secpos+5 > maxsecpos then wflush() end
|
||||||
|
Loading…
Reference in New Issue
Block a user