diff options
author | Mike Pall <mike> | 2011-01-03 02:58:31 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-01-03 02:58:31 +0100 |
commit | 44a22b9889b7366f0313f4f98b64bc142f2d2fed (patch) | |
tree | c9483dbf1b292b99b429ccdfefcc657dc80cfe39 /src | |
parent | 593821f7d9a70208105e878e615d1e67eb7b0c16 (diff) | |
download | luajit-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.c | 40 | ||||
-rw-r--r-- | src/lj_target_x86.h | 4 |
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); | |
2727 | static 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 | ||
280 | typedef enum { | 281 | typedef 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 | ||
284 | typedef enum { | 286 | typedef enum { |