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 {
|
||||
int64_t arg1;
|
||||
int64_t arg2;
|
||||
@ -280,9 +313,11 @@ test_table test[] = {
|
||||
{ 7, 3, labmul, 21, "labmul0"},
|
||||
{ 7, 0, labmul, 0, "labmul1"},
|
||||
{ 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"},
|
||||
// { 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)
|
||||
|
@ -24,6 +24,7 @@ enum {
|
||||
DASM_REL_PC, DASM_LABEL_PC,
|
||||
DASM_DISP12, DASM_DISP20,
|
||||
DASM_IMM16, DASM_IMM32,
|
||||
DASM_LEN8R,
|
||||
DASM__MAX
|
||||
};
|
||||
|
||||
@ -284,6 +285,10 @@ void dasm_put(Dst_DECL, int start, ...)
|
||||
CK((n >> 12) == 0, RANGE_I);
|
||||
b[pos++] = n;
|
||||
break;
|
||||
case DASM_LEN8R:
|
||||
CK(n >= 1 && n <= 256, RANGE_I);
|
||||
b[pos++] = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
stop:
|
||||
@ -364,6 +369,7 @@ int dasm_link(Dst_DECL, size_t * szp)
|
||||
case DASM_IMM32:
|
||||
case DASM_DISP20:
|
||||
case DASM_DISP12:
|
||||
case DASM_LEN8R:
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
@ -458,6 +464,9 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
case DASM_DISP12:
|
||||
cp[-1] |= n & 0xfff;
|
||||
break;
|
||||
case DASM_LEN8R:
|
||||
cp[-1] |= (n - 1) & 0xff;
|
||||
break;
|
||||
default:
|
||||
*cp++ = ins;
|
||||
break;
|
||||
|
@ -39,7 +39,7 @@ local wline, werror, wfatal, wwarn
|
||||
local action_names = {
|
||||
"STOP", "SECTION", "ESC", "REL_EXT",
|
||||
"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().
|
||||
@ -370,6 +370,41 @@ local function parse_mem_by(arg)
|
||||
return d, b, a
|
||||
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 imm_val = tonumber(arg,16)
|
||||
if imm_val then
|
||||
@ -1014,6 +1049,23 @@ map_op = {
|
||||
trace_3 = "000099000000q",
|
||||
tracg_3 = "eb000000000fs",
|
||||
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
|
||||
-- Extended mnemonics for branches.
|
||||
@ -1037,8 +1089,7 @@ local function parse_template(params, template, nparams, pos)
|
||||
local op2 = tonumber(sub(template, 9, 12), 16)
|
||||
|
||||
-- Process each character.
|
||||
for p in gmatch(sub(template, 13), ".") do
|
||||
local pr1,pr2,pr3
|
||||
local p = sub(template, 13)
|
||||
if p == "g" then
|
||||
op2 = op2 + shl(parse_reg(params[1]),4) + parse_reg(params[2])
|
||||
wputhw(op2)
|
||||
@ -1056,7 +1107,6 @@ local function parse_template(params, template, nparams, pos)
|
||||
wputhw(op1); wputhw(op2);
|
||||
if a then a() end
|
||||
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
|
||||
@ -1091,6 +1141,18 @@ local function parse_template(params, template, nparams, pos)
|
||||
op2 = op2 + band(shr(d, 4), 0xff00)
|
||||
wputhw(op0); wputhw(op1); wputhw(op2)
|
||||
if a then a() end -- a() emits action.
|
||||
elseif p == "SS-a" then
|
||||
local d1, l1, b1, d1a, l1a = parse_mem_lb(params[1])
|
||||
local d2, b2, d2a = parse_mem_b(params[2])
|
||||
op0 = op0 + l1
|
||||
op1 = op1 + shl(b1, 12) + d1
|
||||
op2 = op2 + shl(b2, 12) + d2
|
||||
wputhw(op0)
|
||||
if l1a then l1a() end
|
||||
wputhw(op1)
|
||||
if d1a then d1a() end
|
||||
wputhw(op2)
|
||||
if d2a then d2a() end
|
||||
elseif p == "w" then
|
||||
local mode, n, s = parse_label(params[1])
|
||||
wputhw(op1)
|
||||
@ -1113,9 +1175,8 @@ local function parse_template(params, template, nparams, pos)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
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().
|
||||
-- A single opcode needs a maximum of 5 positions.
|
||||
if secpos+5 > maxsecpos then wflush() end
|
||||
|
Loading…
Reference in New Issue
Block a user