diff options
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 40 |
1 files changed, 13 insertions, 27 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 | ||