aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-03 02:58:31 +0100
committerMike Pall <mike>2011-01-03 02:58:31 +0100
commit44a22b9889b7366f0313f4f98b64bc142f2d2fed (patch)
treec9483dbf1b292b99b429ccdfefcc657dc80cfe39 /src
parent593821f7d9a70208105e878e615d1e67eb7b0c16 (diff)
downloadluajit-44a22b9889b7366f0313f4f98b64bc142f2d2fed.tar.gz
luajit-44a22b9889b7366f0313f4f98b64bc142f2d2fed.tar.bz2
luajit-44a22b9889b7366f0313f4f98b64bc142f2d2fed.zip
Add support for non-constant integer IR_MUL to backend.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c40
-rw-r--r--src/lj_target_x86.h4
2 files changed, 16 insertions, 28 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index b2459e59..f8bd388c 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -2713,40 +2713,26 @@ static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa)
2713 IRRef tmp = lref; lref = rref; rref = tmp; 2713 IRRef tmp = lref; lref = rref; rref = tmp;
2714 } 2714 }
2715 right = asm_fuseload(as, rref, rset_clear(allow, dest)); 2715 right = asm_fuseload(as, rref, rset_clear(allow, dest));
2716 /* Note: fuses only with IR_FLOAD for now. */
2717 } 2716 }
2718 if (irt_isguard(ir->t)) /* For IR_ADDOV etc. */ 2717 if (irt_isguard(ir->t)) /* For IR_ADDOV etc. */
2719 asm_guardcc(as, CC_O); 2718 asm_guardcc(as, CC_O);
2720 if (ra_hasreg(right)) 2719 if (xa != XOg_X_IMUL) {
2721 emit_mrm(as, XO_ARITH(xa), REX_64IR(ir, dest), right); 2720 if (ra_hasreg(right))
2722 else 2721 emit_mrm(as, XO_ARITH(xa), REX_64IR(ir, dest), right);
2723 emit_gri(as, XG_ARITHi(xa), REX_64IR(ir, dest), k); 2722 else
2724 ra_left(as, dest, lref); 2723 emit_gri(as, XG_ARITHi(xa), REX_64IR(ir, dest), k);
2725} 2724 } else if (ra_hasreg(right)) { /* IMUL r, mrm. */
2726 2725 emit_mrm(as, XO_IMUL, REX_64IR(ir, dest), right);
2727static void asm_intmul(ASMState *as, IRIns *ir) 2726 } else { /* IMUL r, r, k. */
2728{
2729 IRRef lref = ir->op1;
2730 IRRef rref = ir->op2;
2731 int32_t k = 0;
2732 if (asm_isk32(as, rref, &k)) {
2733 /* NYI: use lea/shl/add/sub (FOLD only does 2^k) depending on CPU. */ 2727 /* NYI: use lea/shl/add/sub (FOLD only does 2^k) depending on CPU. */
2734 Reg dest = ra_dest(as, ir, RSET_GPR);
2735 Reg left = asm_fuseload(as, lref, RSET_GPR); 2728 Reg left = asm_fuseload(as, lref, RSET_GPR);
2736 x86Op xo; 2729 x86Op xo;
2737 if (checki8(k)) { 2730 if (checki8(k)) { emit_i8(as, k); xo = XO_IMULi8;
2738 emit_i8(as, k); 2731 } else { emit_i32(as, k); xo = XO_IMULi; }
2739 xo = XO_IMULi8;
2740 } else {
2741 emit_i32(as, k);
2742 xo = XO_IMULi;
2743 }
2744 emit_rr(as, xo, REX_64IR(ir, dest), left); 2732 emit_rr(as, xo, REX_64IR(ir, dest), left);
2745 } else { 2733 return;
2746 /* NYI: integer multiply of non-constant operands. */
2747 setintV(&as->J->errinfo, ir->o);
2748 lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
2749 } 2734 }
2735 ra_left(as, dest, lref);
2750} 2736}
2751 2737
2752/* LEA is really a 4-operand ADD with an independent destination register, 2738/* LEA is really a 4-operand ADD with an independent destination register,
@@ -3716,7 +3702,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
3716 if (irt_isnum(ir->t)) 3702 if (irt_isnum(ir->t))
3717 asm_fparith(as, ir, XO_MULSD); 3703 asm_fparith(as, ir, XO_MULSD);
3718 else 3704 else
3719 asm_intmul(as, ir); 3705 asm_intarith(as, ir, XOg_X_IMUL);
3720 break; 3706 break;
3721 case IR_DIV: asm_fparith(as, ir, XO_DIVSD); break; 3707 case IR_DIV: asm_fparith(as, ir, XO_DIVSD); break;
3722 3708
diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h
index eb287f03..5909c905 100644
--- a/src/lj_target_x86.h
+++ b/src/lj_target_x86.h
@@ -218,6 +218,7 @@ typedef enum {
218 XO_SHIFTi = XO_(c1), 218 XO_SHIFTi = XO_(c1),
219 XO_SHIFT1 = XO_(d1), 219 XO_SHIFT1 = XO_(d1),
220 XO_SHIFTcl = XO_(d3), 220 XO_SHIFTcl = XO_(d3),
221 XO_IMUL = XO_0f(af),
221 XO_IMULi = XO_(69), 222 XO_IMULi = XO_(69),
222 XO_IMULi8 = XO_(6b), 223 XO_IMULi8 = XO_(6b),
223 XO_CMP = XO_(3b), 224 XO_CMP = XO_(3b),
@@ -278,7 +279,8 @@ typedef uint32_t x86Group;
278#define XO_ARITH(a) ((x86Op)(0x030000fe + ((a)<<27))) 279#define XO_ARITH(a) ((x86Op)(0x030000fe + ((a)<<27)))
279 280
280typedef enum { 281typedef enum {
281 XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP 282 XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP,
283 XOg_X_IMUL
282} x86Arith; 284} x86Arith;
283 285
284typedef enum { 286typedef enum {