Procházet zdrojové kódy

Add support for non-constant integer IR_MUL to backend.

Mike Pall před 14 roky
rodič
revize
44a22b9889
2 změnil soubory, kde provedl 16 přidání a 28 odebrání
  1. 13 27
      src/lj_asm.c
  2. 3 1
      src/lj_target_x86.h

+ 13 - 27
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;
     }
     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. */
     asm_guardcc(as, CC_O);
-  if (ra_hasreg(right))
-    emit_mrm(as, XO_ARITH(xa), REX_64IR(ir, dest), right);
-  else
-    emit_gri(as, XG_ARITHi(xa), REX_64IR(ir, dest), k);
-  ra_left(as, dest, lref);
-}
-
-static void asm_intmul(ASMState *as, IRIns *ir)
-{
-  IRRef lref = ir->op1;
-  IRRef rref = ir->op2;
-  int32_t k = 0;
-  if (asm_isk32(as, rref, &k)) {
+  if (xa != XOg_X_IMUL) {
+    if (ra_hasreg(right))
+      emit_mrm(as, XO_ARITH(xa), REX_64IR(ir, dest), right);
+    else
+      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);
+  } else {  /* IMUL r, r, k. */
     /* 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);
     x86Op xo;
-    if (checki8(k)) {
-      emit_i8(as, k);
-      xo = XO_IMULi8;
-    } else {
-      emit_i32(as, k);
-      xo = XO_IMULi;
-    }
+    if (checki8(k)) { emit_i8(as, k); xo = XO_IMULi8;
+    } else { emit_i32(as, k); xo = XO_IMULi; }
     emit_rr(as, xo, REX_64IR(ir, dest), left);
-  } else {
-    /* NYI: integer multiply of non-constant operands. */
-    setintV(&as->J->errinfo, ir->o);
-    lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
+    return;
   }
+  ra_left(as, dest, lref);
 }
 
 /* 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))
       asm_fparith(as, ir, XO_MULSD);
     else
-      asm_intmul(as, ir);
+      asm_intarith(as, ir, XOg_X_IMUL);
     break;
   case IR_DIV: asm_fparith(as, ir, XO_DIVSD); break;
 

+ 3 - 1
src/lj_target_x86.h

@@ -218,6 +218,7 @@ typedef enum {
   XO_SHIFTi =	XO_(c1),
   XO_SHIFT1 =	XO_(d1),
   XO_SHIFTcl =	XO_(d3),
+  XO_IMUL =	XO_0f(af),
   XO_IMULi =	XO_(69),
   XO_IMULi8 =	XO_(6b),
   XO_CMP =	XO_(3b),
@@ -278,7 +279,8 @@ typedef uint32_t x86Group;
 #define XO_ARITH(a)	((x86Op)(0x030000fe + ((a)<<27)))
 
 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;
 
 typedef enum {