mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 15:34:09 +00:00
Support floating point register arguments.
It would be nice to verify that floating-point/general-purpose registers are indeed expected by the instruction, but for now treat them both the same so we can use floating-point instructions.
This commit is contained in:
parent
53b627b21c
commit
3ae1c4fd6b
@ -101,7 +101,6 @@ static void add_imm16(dasm_State *state)
|
|||||||
| br r14
|
| br r14
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void add_imm32(dasm_State *state)
|
static void add_imm32(dasm_State *state)
|
||||||
{
|
{
|
||||||
dasm_State **Dst = &state;
|
dasm_State **Dst = &state;
|
||||||
@ -110,6 +109,67 @@ static void add_imm32(dasm_State *state)
|
|||||||
| br r14
|
| br r14
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void save(dasm_State *state)
|
||||||
|
{
|
||||||
|
dasm_State **Dst = &state;
|
||||||
|
|
||||||
|
|.define CFRAME_SPACE, 224 // Delta for sp, 8 byte aligned.
|
||||||
|
|
|
||||||
|
|// Register save area.
|
||||||
|
|.define SAVE_GPRS, 264(sp) // Save area for r6-r15 (10*8 bytes).
|
||||||
|
|
|
||||||
|
|// Argument save area, each slot is 8-bytes (32-bit types are sign/zero extended).
|
||||||
|
|.define RESERVED, 232(sp) // Reserved for compiler use.
|
||||||
|
|.define BACKCHAIN, 224(sp)
|
||||||
|
|
|
||||||
|
|// Current stack frame.
|
||||||
|
|.define SAVE_FPR15, 216(sp)
|
||||||
|
|.define SAVE_FPR14, 208(sp)
|
||||||
|
|.define SAVE_FPR13, 200(sp)
|
||||||
|
|.define SAVE_FPR12, 192(sp)
|
||||||
|
|.define SAVE_FPR11, 184(sp)
|
||||||
|
|.define SAVE_FPR10, 176(sp)
|
||||||
|
|.define SAVE_FPR9, 168(sp)
|
||||||
|
|.define SAVE_FPR8, 160(sp)
|
||||||
|
|
|
||||||
|
|// Callee save area.
|
||||||
|
|.define CALLEESAVE, 000(sp)
|
||||||
|
|
|
||||||
|
|.macro saveregs
|
||||||
|
| lay sp, -CFRAME_SPACE(sp) // Allocate stack frame.
|
||||||
|
| stmg r6, r15, SAVE_GPRS // Technically we restore r15 regardless.
|
||||||
|
| std f8, SAVE_FPR8 // f8-f15 are callee-saved.
|
||||||
|
| std f9, SAVE_FPR9
|
||||||
|
| std f10, SAVE_FPR10
|
||||||
|
| std f11, SAVE_FPR11
|
||||||
|
| std f12, SAVE_FPR12
|
||||||
|
| std f13, SAVE_FPR13
|
||||||
|
| std f14, SAVE_FPR14
|
||||||
|
| std f15, SAVE_FPR15
|
||||||
|
|.endmacro
|
||||||
|
|
|
||||||
|
|.macro restoreregs
|
||||||
|
| ld f8, SAVE_FPR8 // f8-f15 are callee-saved.
|
||||||
|
| ld f9, SAVE_FPR9
|
||||||
|
| ld f10, SAVE_FPR10
|
||||||
|
| ld f11, SAVE_FPR11
|
||||||
|
| ld f12, SAVE_FPR12
|
||||||
|
| ld f13, SAVE_FPR13
|
||||||
|
| ld f14, SAVE_FPR14
|
||||||
|
| ld f15, SAVE_FPR15
|
||||||
|
| lmg r6, r15, SAVE_GPRS // Restores the stack pointer.
|
||||||
|
|.endmacro
|
||||||
|
|
|
||||||
|
| saveregs
|
||||||
|
| lgfi r7, 10 // 16
|
||||||
|
| lgfi r8, 20 // 32
|
||||||
|
| agr r2, r3
|
||||||
|
| agr r7, r8
|
||||||
|
| msgr r2, r7
|
||||||
|
| restoreregs
|
||||||
|
| br r14
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t arg1;
|
int64_t arg1;
|
||||||
int64_t arg2;
|
int64_t arg2;
|
||||||
@ -127,7 +187,8 @@ test_table test[] = {
|
|||||||
{ 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"}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *jitcode(dasm_State **state, size_t *size)
|
static void *jitcode(dasm_State **state, size_t *size)
|
||||||
|
@ -246,8 +246,8 @@ local map_cond = {
|
|||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
local function parse_gpr(expr)
|
local function parse_reg(expr)
|
||||||
local r = match(expr, "^r(1?[0-9])$")
|
local r = match(expr, "^[r|f](1?[0-9])$")
|
||||||
if r then
|
if r then
|
||||||
r = tonumber(r)
|
r = tonumber(r)
|
||||||
if r <= 15 then return r, tp end
|
if r <= 15 then return r, tp end
|
||||||
@ -255,15 +255,6 @@ local function parse_gpr(expr)
|
|||||||
werror("bad register name `"..expr.."'")
|
werror("bad register name `"..expr.."'")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function parse_fpr(expr)
|
|
||||||
local r = match(expr, "^f(1?[0-9])$")
|
|
||||||
if r then
|
|
||||||
r = tonumber(r)
|
|
||||||
if r <= 15 then return r end
|
|
||||||
end
|
|
||||||
werror("bad register name `"..expr.."'")
|
|
||||||
end
|
|
||||||
|
|
||||||
local parse_ctx = {}
|
local parse_ctx = {}
|
||||||
|
|
||||||
local loadenv = setfenv and function(s)
|
local loadenv = setfenv and function(s)
|
||||||
@ -308,11 +299,11 @@ local function split_memop(arg)
|
|||||||
local reg = "r1?[0-9]"
|
local reg = "r1?[0-9]"
|
||||||
local d, x, b = match(arg, "^(.*)%(("..reg.."), ("..reg..")%)$")
|
local d, x, b = match(arg, "^(.*)%(("..reg.."), ("..reg..")%)$")
|
||||||
if d then
|
if d then
|
||||||
return d, parse_gpr(x), parse_gpr(b)
|
return d, parse_reg(x), parse_reg(b)
|
||||||
end
|
end
|
||||||
local d, b = match(arg, "^(.*)%(("..reg..")%)$")
|
local d, b = match(arg, "^(.*)%(("..reg..")%)$")
|
||||||
if d then
|
if d then
|
||||||
return d, 0, parse_gpr(b)
|
return d, 0, parse_reg(b)
|
||||||
end
|
end
|
||||||
-- TODO: handle values without registers?
|
-- TODO: handle values without registers?
|
||||||
-- TODO: handle registers without a displacement?
|
-- TODO: handle registers without a displacement?
|
||||||
@ -1047,18 +1038,18 @@ local function parse_template(params, template, nparams, pos)
|
|||||||
for p in gmatch(sub(template, 13), ".") do
|
for p in gmatch(sub(template, 13), ".") do
|
||||||
local pr1,pr2,pr3
|
local pr1,pr2,pr3
|
||||||
if p == "g" then
|
if p == "g" then
|
||||||
op2 = op2 + shl(parse_gpr(params[1]),4) + parse_gpr(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_gpr(params[1]),4) + parse_gpr(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_gpr(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_gpr(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
|
||||||
@ -1066,7 +1057,7 @@ local function parse_template(params, template, nparams, pos)
|
|||||||
|
|
||||||
elseif p == "l" then
|
elseif p == "l" then
|
||||||
local d, x, b, a = parse_mem_bxy(params[2])
|
local d, x, b, a = parse_mem_bxy(params[2])
|
||||||
op0 = op0 + shl(parse_gpr(params[1]), 4) + x
|
op0 = op0 + shl(parse_reg(params[1]), 4) + x
|
||||||
op1 = op1 + shl(b, 12) + band(d, 0xfff)
|
op1 = op1 + shl(b, 12) + band(d, 0xfff)
|
||||||
op2 = op2 + band(shr(d, 4), 0xff00)
|
op2 = op2 + band(shr(d, 4), 0xff00)
|
||||||
wputhw(op0); wputhw(op1); wputhw(op2)
|
wputhw(op0); wputhw(op1); wputhw(op2)
|
||||||
@ -1074,18 +1065,18 @@ local function parse_template(params, template, nparams, pos)
|
|||||||
elseif p == "m" then
|
elseif p == "m" then
|
||||||
|
|
||||||
elseif p == "n" then
|
elseif p == "n" then
|
||||||
op0 = op0 + shl(parse_gpr(params[1]), 4)
|
op0 = op0 + shl(parse_reg(params[1]), 4)
|
||||||
wputhw(op0);
|
wputhw(op0);
|
||||||
parse_imm(params[2])
|
parse_imm(params[2])
|
||||||
elseif p == "q" then
|
elseif p == "q" then
|
||||||
local d, b, a = parse_mem_b(params[3])
|
local d, b, a = parse_mem_b(params[3])
|
||||||
op1 = op1 + shl(parse_gpr(params[1]), 4) + parse_gpr(params[2])
|
op1 = op1 + shl(parse_reg(params[1]), 4) + parse_reg(params[2])
|
||||||
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 -- a() emits action.
|
if a then a() end -- a() emits action.
|
||||||
elseif p == "s" then
|
elseif p == "s" then
|
||||||
local d, b, a = parse_mem_by(params[3])
|
local d, b, a = parse_mem_by(params[3])
|
||||||
op0 = op0 + shl(parse_gpr(params[1]), 4) + parse_gpr(params[2])
|
op0 = op0 + shl(parse_reg(params[1]), 4) + parse_reg(params[2])
|
||||||
op1 = op1 + shl(b, 12) + band(d, 0xfff)
|
op1 = op1 + shl(b, 12) + band(d, 0xfff)
|
||||||
op2 = op2 + band(shr(d, 4), 0xff00)
|
op2 = op2 + band(shr(d, 4), 0xff00)
|
||||||
wputhw(op0); wputhw(op1); wputhw(op2)
|
wputhw(op0); wputhw(op1); wputhw(op2)
|
||||||
@ -1105,7 +1096,7 @@ local function parse_template(params, template, nparams, pos)
|
|||||||
wputhw(op1); wputhw(op2);
|
wputhw(op1); wputhw(op2);
|
||||||
if a then a() end -- a() emits action.
|
if a then a() end -- a() emits action.
|
||||||
elseif p == "z" then
|
elseif p == "z" then
|
||||||
op2 = op2 + parse_gpr(params[1])
|
op2 = op2 + parse_reg(params[1])
|
||||||
wputhw(op2)
|
wputhw(op2)
|
||||||
else
|
else
|
||||||
werror("unrecognized encoding")
|
werror("unrecognized encoding")
|
||||||
|
Loading…
Reference in New Issue
Block a user