mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Add support for non-constant integer IR_MUL to backend.
This commit is contained in:
parent
593821f7d9
commit
44a22b9889
40
src/lj_asm.c
40
src/lj_asm.c
@ -2713,40 +2713,26 @@ static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa)
|
|||||||
IRRef tmp = lref; lref = rref; rref = tmp;
|
IRRef tmp = lref; lref = rref; rref = tmp;
|
||||||
}
|
}
|
||||||
right = asm_fuseload(as, rref, rset_clear(allow, dest));
|
right = asm_fuseload(as, rref, rset_clear(allow, dest));
|
||||||
/* Note: fuses only with IR_FLOAD for now. */
|
|
||||||
}
|
}
|
||||||
if (irt_isguard(ir->t)) /* For IR_ADDOV etc. */
|
if (irt_isguard(ir->t)) /* For IR_ADDOV etc. */
|
||||||
asm_guardcc(as, CC_O);
|
asm_guardcc(as, CC_O);
|
||||||
if (ra_hasreg(right))
|
if (xa != XOg_X_IMUL) {
|
||||||
emit_mrm(as, XO_ARITH(xa), REX_64IR(ir, dest), right);
|
if (ra_hasreg(right))
|
||||||
else
|
emit_mrm(as, XO_ARITH(xa), REX_64IR(ir, dest), right);
|
||||||
emit_gri(as, XG_ARITHi(xa), REX_64IR(ir, dest), k);
|
else
|
||||||
ra_left(as, dest, lref);
|
emit_gri(as, XG_ARITHi(xa), REX_64IR(ir, dest), k);
|
||||||
}
|
} else if (ra_hasreg(right)) { /* IMUL r, mrm. */
|
||||||
|
emit_mrm(as, XO_IMUL, REX_64IR(ir, dest), right);
|
||||||
static void asm_intmul(ASMState *as, IRIns *ir)
|
} else { /* IMUL r, r, k. */
|
||||||
{
|
|
||||||
IRRef lref = ir->op1;
|
|
||||||
IRRef rref = ir->op2;
|
|
||||||
int32_t k = 0;
|
|
||||||
if (asm_isk32(as, rref, &k)) {
|
|
||||||
/* NYI: use lea/shl/add/sub (FOLD only does 2^k) depending on CPU. */
|
/* NYI: use lea/shl/add/sub (FOLD only does 2^k) depending on CPU. */
|
||||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
|
||||||
Reg left = asm_fuseload(as, lref, RSET_GPR);
|
Reg left = asm_fuseload(as, lref, RSET_GPR);
|
||||||
x86Op xo;
|
x86Op xo;
|
||||||
if (checki8(k)) {
|
if (checki8(k)) { emit_i8(as, k); xo = XO_IMULi8;
|
||||||
emit_i8(as, k);
|
} else { emit_i32(as, k); xo = XO_IMULi; }
|
||||||
xo = XO_IMULi8;
|
|
||||||
} else {
|
|
||||||
emit_i32(as, k);
|
|
||||||
xo = XO_IMULi;
|
|
||||||
}
|
|
||||||
emit_rr(as, xo, REX_64IR(ir, dest), left);
|
emit_rr(as, xo, REX_64IR(ir, dest), left);
|
||||||
} else {
|
return;
|
||||||
/* NYI: integer multiply of non-constant operands. */
|
|
||||||
setintV(&as->J->errinfo, ir->o);
|
|
||||||
lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
|
|
||||||
}
|
}
|
||||||
|
ra_left(as, dest, lref);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LEA is really a 4-operand ADD with an independent destination register,
|
/* LEA is really a 4-operand ADD with an independent destination register,
|
||||||
@ -3716,7 +3702,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
|
|||||||
if (irt_isnum(ir->t))
|
if (irt_isnum(ir->t))
|
||||||
asm_fparith(as, ir, XO_MULSD);
|
asm_fparith(as, ir, XO_MULSD);
|
||||||
else
|
else
|
||||||
asm_intmul(as, ir);
|
asm_intarith(as, ir, XOg_X_IMUL);
|
||||||
break;
|
break;
|
||||||
case IR_DIV: asm_fparith(as, ir, XO_DIVSD); break;
|
case IR_DIV: asm_fparith(as, ir, XO_DIVSD); break;
|
||||||
|
|
||||||
|
@ -218,6 +218,7 @@ typedef enum {
|
|||||||
XO_SHIFTi = XO_(c1),
|
XO_SHIFTi = XO_(c1),
|
||||||
XO_SHIFT1 = XO_(d1),
|
XO_SHIFT1 = XO_(d1),
|
||||||
XO_SHIFTcl = XO_(d3),
|
XO_SHIFTcl = XO_(d3),
|
||||||
|
XO_IMUL = XO_0f(af),
|
||||||
XO_IMULi = XO_(69),
|
XO_IMULi = XO_(69),
|
||||||
XO_IMULi8 = XO_(6b),
|
XO_IMULi8 = XO_(6b),
|
||||||
XO_CMP = XO_(3b),
|
XO_CMP = XO_(3b),
|
||||||
@ -278,7 +279,8 @@ typedef uint32_t x86Group;
|
|||||||
#define XO_ARITH(a) ((x86Op)(0x030000fe + ((a)<<27)))
|
#define XO_ARITH(a) ((x86Op)(0x030000fe + ((a)<<27)))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP
|
XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP,
|
||||||
|
XOg_X_IMUL
|
||||||
} x86Arith;
|
} x86Arith;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
Loading…
Reference in New Issue
Block a user