]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
hdefs: MulL, MFence
authorCerion Armour-Brown <cerion@valgrind.org>
Thu, 10 Feb 2005 16:11:35 +0000 (16:11 +0000)
committerCerion Armour-Brown <cerion@valgrind.org>
Thu, 10 Feb 2005 16:11:35 +0000 (16:11 +0000)
isel:
  Iop_64HIto32
  Iop_64to32
  iselInt64Expr:
    Iop_MullU32
    Iop_MullS32
  Ist_MFence

Had a go at implementing long multiplies (last shortcut was wrong)

git-svn-id: svn://svn.valgrind.org/vex/trunk@882

VEX/priv/host-ppc32/hdefs.c
VEX/priv/host-ppc32/hdefs.h
VEX/priv/host-ppc32/isel.c

index 7439f4d54033c222a991e519ea7b9483b7465347..643f25bac788f96aa78dc07b41a3755a2dc9ddfd 100644 (file)
@@ -471,14 +471,17 @@ PPC32Instr* PPC32Instr_Unary32  ( PPC32UnaryOp op, HReg dst ) {
    i->Pin.Unary32.dst = dst;
    return i;
 }
-//.. X86Instr* X86Instr_MulL ( Bool syned, X86ScalarSz ssz , X86RM* src ) {
-//..    X86Instr* i        = LibVEX_Alloc(sizeof(X86Instr));
-//..    i->tag             = Xin_MulL;
-//..    i->Xin.MulL.syned  = syned;
-//..    i->Xin.MulL.ssz    = ssz;
-//..    i->Xin.MulL.src    = src;
-//..    return i;
-//.. }
+PPC32Instr* PPC32Instr_MulL ( Bool syned, Bool word, HReg dst,
+                             HReg src1, PPC32RI* src2 ) {
+   PPC32Instr* i     = LibVEX_Alloc(sizeof(PPC32Instr));
+   i->tag            = Pin_MulL;
+   i->Pin.MulL.syned = syned;
+   i->Pin.MulL.word  = word;
+   i->Pin.MulL.dst  = dst;
+   i->Pin.MulL.src1  = src1;
+   i->Pin.MulL.src2  = src2;
+   return i;
+}
 //.. X86Instr* X86Instr_Div ( Bool syned, X86ScalarSz ssz, X86RM* src ) {
 //..    X86Instr* i        = LibVEX_Alloc(sizeof(X86Instr));
 //..    i->tag             = Xin_Div;
@@ -564,16 +567,15 @@ PPC32Instr* PPC32Instr_Set32 ( PPC32CondCode cond, HReg dst ) {
 //..    i->Xin.Bsfr32.dst    = dst;
 //..    return i;
 //.. }
-//.. X86Instr* X86Instr_MFence ( VexSubArch subarch )
-//.. {
-//..    X86Instr* i           = LibVEX_Alloc(sizeof(X86Instr));
-//..    i->tag                = Xin_MFence;
-//..    i->Xin.MFence.subarch = subarch;
-//..    vassert(subarch == VexSubArchX86_sse0
-//..            || subarch == VexSubArchX86_sse1
-//..            || subarch == VexSubArchX86_sse2);
-//..    return i;
-//.. }
+PPC32Instr* PPC32Instr_MFence ( VexSubArch subarch )
+{
+   PPC32Instr* i         = LibVEX_Alloc(sizeof(PPC32Instr));
+   i->tag                = Pin_MFence;
+   i->Pin.MFence.subarch = subarch;
+   vassert(subarch == VexSubArchPPC32_AV
+           || subarch == VexSubArchPPC32_noAV);
+   return i;
+}
 
 //.. X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst ) {
 //..    X86Instr* i        = LibVEX_Alloc(sizeof(X86Instr));
@@ -697,12 +699,20 @@ void ppPPC32Instr ( PPC32Instr* i )
          vex_printf("%sl ", showPPC32UnaryOp(i->Pin.Unary32.op));
          ppHRegPPC32(i->Pin.Unary32.dst);
          return;
-//..       case Xin_MulL:
-//..          vex_printf("%cmul%s ",
-//..                     i->Xin.MulL.syned ? 's' : 'u',
-//..                     showX86ScalarSz(i->Xin.MulL.ssz));
-//..          ppX86RM(i->Xin.MulL.src);
-//..          return;
+      case Pin_MulL:
+         if (i->Pin.MulL.src2->tag == Pri_Imm) {
+             vex_printf("mulli ");
+         } else {
+             vex_printf("mul%s%c ",
+                        i->Pin.MulL.word ? "hw" : "lw",
+                        i->Pin.MulL.syned ? 's' : 'u');
+         }
+         ppHRegPPC32(i->Pin.MulL.dst);
+         vex_printf(",");
+         ppHRegPPC32(i->Pin.MulL.src1);
+         vex_printf(",");
+         ppPPC32RI(i->Pin.MulL.src2);
+         return;
 //..       case Xin_Div:
 //..          vex_printf("%cdiv%s ",
 //..                     i->Xin.Div.syned ? 's' : 'u',
@@ -797,10 +807,10 @@ void ppPPC32Instr ( PPC32Instr* i )
 //..          vex_printf(",");
 //..          ppHRegX86(i->Xin.Bsfr32.dst);
 //..          return;
-//..       case Xin_MFence:
-//..          vex_printf("mfence(%s)",
-//..                     LibVEX_ppVexSubArch(i->Xin.MFence.subarch));
-//..          return;
+      case Pin_MFence:
+         vex_printf("mfence(%s)",
+                    LibVEX_ppVexSubArch(i->Pin.MFence.subarch));
+         return;
 //..       case Xin_FpUnary:
 //..          vex_printf("g%sD ", showX86FpOp(i->Xin.FpUnary.op));
 //..          ppHRegX86(i->Xin.FpUnary.src);
@@ -973,11 +983,11 @@ void getRegUsage_PPC32Instr ( HRegUsage* u, PPC32Instr* i )
       case Pin_Unary32:
         addHRegUse(u, HRmModify, i->Pin.Unary32.dst);
          return;
-//..       case Xin_MulL:
-//..          addRegUsage_X86RM(u, i->Xin.MulL.src, HRmRead);
-//..          addHRegUse(u, HRmModify, hregX86_EAX());
-//..          addHRegUse(u, HRmWrite, hregX86_EDX());
-//..          return;
+      case Pin_MulL:
+        addHRegUse(u, HRmWrite, i->Pin.MulL.dst);
+        addHRegUse(u, HRmRead, i->Pin.MulL.src1);
+         addRegUsage_PPC32RI(u, i->Pin.MulL.src2);
+         return;
 //..       case Xin_Div:
 //..          addRegUsage_X86RM(u, i->Xin.Div.src, HRmRead);
 //..          addHRegUse(u, HRmModify, hregX86_EAX());
@@ -1058,8 +1068,8 @@ void getRegUsage_PPC32Instr ( HRegUsage* u, PPC32Instr* i )
 //..          addHRegUse(u, HRmRead, i->Xin.Bsfr32.src);
 //..          addHRegUse(u, HRmWrite, i->Xin.Bsfr32.dst);
 //..          return;
-//..       case Xin_MFence:
-//..          return;
+      case Pin_MFence:
+         return;
 //..       case Xin_FpUnary:
 //..          addHRegUse(u, HRmRead, i->Xin.FpUnary.src);
 //..          addHRegUse(u, HRmWrite, i->Xin.FpUnary.dst);
@@ -1200,9 +1210,11 @@ void mapRegs_PPC32Instr (HRegRemap* m, PPC32Instr* i)
       case Pin_Unary32:
          mapReg(m, &i->Pin.Unary32.dst);
          return;
-//..       case Xin_MulL:
-//..          mapRegs_X86RM(m, i->Xin.MulL.src);
-//..          return;
+      case Pin_MulL:
+         mapReg(m, &i->Pin.MulL.dst);
+         mapReg(m, &i->Pin.MulL.src1);
+         mapRegs_PPC32RI(m, i->Pin.MulL.src2);
+         return;
 //..       case Xin_Div:
 //..          mapRegs_X86RM(m, i->Xin.Div.src);
 //..          return;
@@ -1237,8 +1249,8 @@ void mapRegs_PPC32Instr (HRegRemap* m, PPC32Instr* i)
 //..          mapReg(m, &i->Xin.Bsfr32.src);
 //..          mapReg(m, &i->Xin.Bsfr32.dst);
 //..          return;
-//..       case Xin_MFence:
-//..          return;
+      case Pin_MFence:
+         return;
 //..       case Xin_FpUnary:
 //..          mapReg(m, &i->Xin.FpUnary.src);
 //..          mapReg(m, &i->Xin.FpUnary.dst);
index e5b552f96946211126d897ddda008aa158894929..918ec7e66912f9971ae66a9372527a09f1e96719 100644 (file)
@@ -290,7 +290,7 @@ typedef
       Pin_Sh32,      /* 32-bit shift/rotate */
       Pin_Test32,    /* 32-bit test (AND, set flags, discard result) */
       Pin_Unary32,   /* 32-bit not and neg */
-//..       Xin_MulL,      /* widening multiply */
+      Pin_MulL,      /* widening multiply */
 //..       Xin_Div,       /* div and mod */
 //..       Xin_Sh3232,    /* shldl or shrdl */
 //..       Xin_Push,      /* push (32-bit?) value on stack */
@@ -301,7 +301,7 @@ typedef
       Pin_Store,     /* store a 8|16|32 bit value to mem */
       Pin_Set32,     /* convert condition code to 32-bit value */
 //..       Xin_Bsfr32,    /* 32-bit bsf/bsr */
-//..       Xin_MFence,    /* mem fence (not just sse2, but sse0 and 1 too) */
+      Pin_MFence,    /* mem fence (not just sse2, but sse0 and 1 too) */
 
 //..       Xin_FpUnary,   /* FP fake unary op */
 //..       Xin_FpBinary,  /* FP fake binary op */
@@ -343,12 +343,14 @@ typedef
             PPC32UnaryOp op;
             HReg         dst;
          } Unary32;
-//..          /* DX:AX = AX *s/u r/m16,  or EDX:EAX = EAX *s/u r/m32 */
-//..          struct {
-//..             Bool        syned;
-//..             X86ScalarSz ssz;
-//..             X86RM*      src;
-//..          } MulL;
+         /* DX:AX = AX *s/u r/m16,  or EDX:EAX = EAX *s/u r/m32 */
+         struct {
+            Bool     syned;
+           Bool     word;   /* low=0, hi=1 */
+            HReg     dst;
+            HReg     src1;
+            PPC32RI* src2;
+         } MulL;
 //..          /* x86 div/idiv instruction.  Modifies EDX and EAX and reads src. */
 //..          struct {
 //..             Bool        syned;
@@ -413,16 +415,16 @@ typedef
 //..             HReg src;
 //..             HReg dst;
 //..          } Bsfr32;
-//..          /* Mem fence (not just sse2, but sse0 and 1 too).  In short,
-//..             an insn which flushes all preceding loads and stores as
-//..             much as possible before continuing.  On SSE2 we emit a
-//..             real "mfence", on SSE1 "sfence ; lock addl $0,0(%esp)" and
-//..             on SSE0 "lock addl $0,0(%esp)".  This insn therefore
-//..             carries the subarch so the assembler knows what to
-//..             emit. */
-//..          struct {
-//..             VexSubArch subarch;
-//..          } MFence;
+         /* Mem fence (not just sse2, but sse0 and 1 too).  In short,
+            an insn which flushes all preceding loads and stores as
+            much as possible before continuing.  On SSE2 we emit a
+            real "mfence", on SSE1 "sfence ; lock addl $0,0(%esp)" and
+            on SSE0 "lock addl $0,0(%esp)".  This insn therefore
+            carries the subarch so the assembler knows what to
+            emit. */
+         struct {
+            VexSubArch subarch;
+         } MFence;
 
 //..          /* X86 Floating point (fake 3-operand, "flat reg file" insns) */
 //..          struct {
@@ -492,7 +494,7 @@ extern PPC32Instr* PPC32Instr_Alu32     ( PPC32AluOp, HReg, HReg, PPC32RI* );
 extern PPC32Instr* PPC32Instr_Sh32      ( PPC32ShiftOp, HReg, HReg, PPC32RI* );
 extern PPC32Instr* PPC32Instr_Test32    ( HReg dst, PPC32RI* src );
 extern PPC32Instr* PPC32Instr_Unary32   ( PPC32UnaryOp op, HReg dst );
-//.. extern X86Instr* X86Instr_MulL      ( Bool syned, X86ScalarSz, X86RM* );
+extern PPC32Instr* PPC32Instr_MulL      ( Bool syned, Bool word, HReg, HReg, PPC32RI* );
 //.. extern X86Instr* X86Instr_Div       ( Bool syned, X86ScalarSz, X86RM* );
 //.. extern X86Instr* X86Instr_Sh3232    ( X86ShiftOp, UInt amt, HReg src, HReg dst );
 //.. extern X86Instr* X86Instr_Push      ( X86RMI* );
@@ -504,7 +506,7 @@ extern PPC32Instr* PPC32Instr_LoadEX    ( UChar sz, Bool syned,
 extern PPC32Instr* PPC32Instr_Store     ( UChar sz, PPC32AMode* dst, HReg src );
 extern PPC32Instr* PPC32Instr_Set32     ( PPC32CondCode cond, HReg dst );
 //.. extern X86Instr* X86Instr_Bsfr32    ( Bool isFwds, HReg src, HReg dst );
-//.. extern X86Instr* X86Instr_MFence    ( VexSubArch );
+extern PPC32Instr* PPC32Instr_MFence    ( VexSubArch );
 //.. 
 //.. extern X86Instr* X86Instr_FpUnary   ( X86FpOp op, HReg src, HReg dst );
 //.. extern X86Instr* X86Instr_FpBinary  ( X86FpOp op, HReg srcL, HReg srcR, HReg dst );
index e97710b6d3ad4d55d425aa59af023b4ffcde75da..b2dfbf7334d520ad4639219c70126db4b4c0ecfa 100644 (file)
@@ -185,7 +185,6 @@ static HReg lookupIRTemp ( ISelEnv* env, IRTemp tmp )
    return env->vregmap[tmp];
 }
 
-#if 0
 static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp )
 {
    vassert(tmp >= 0);
@@ -194,7 +193,6 @@ static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp )
    *vrLO = env->vregmap[tmp];
    *vrHI = env->vregmapHI[tmp];
 }
-#endif
 
 static void addInstr ( ISelEnv* env, PPC32Instr* instr )
 {
@@ -246,12 +244,10 @@ static HReg          iselIntExpr_R     ( ISelEnv* env, IRExpr* e );
 static PPC32AMode*   iselIntExpr_AMode_wrk ( ISelEnv* env, IRExpr* e );
 static PPC32AMode*   iselIntExpr_AMode     ( ISelEnv* env, IRExpr* e );
 
-#if 0
 static void          iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, 
                                         ISelEnv* env, IRExpr* e );
 static void          iselInt64Expr     ( HReg* rHi, HReg* rLo, 
                                         ISelEnv* env, IRExpr* e );
-#endif
 
 static PPC32CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e );
 static PPC32CondCode iselCondCode     ( ISelEnv* env, IRExpr* e );
@@ -1055,14 +1051,20 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
             return dst;
          }
          case Iop_64HIto32: {
-
-           /* 64HIto32(MullU32(expr,expr)) */
+            HReg rHi, rLo;
+            iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg);
+            return rHi; /* and abandon rLo .. poor wee thing :-) */
+         }
+         case Iop_64to32: {
+#if 1
+// CAB: This right?
+           /* 64to32(MullS32(expr,expr)) */
            {
-               DECLARE_PATTERN(p_MullU32_then_64HIto32);
-               DEFINE_PATTERN(p_MullU32_then_64HIto32,
-                              unop(Iop_64HIto32,
-                                   binop(Iop_MullU32, bind(0), bind(1))));
-               if (matchIRExpr(&mi,p_MullU32_then_64HIto32,e)) {
+               DECLARE_PATTERN(p_MullS32_then_64to32);
+               DEFINE_PATTERN(p_MullS32_then_64to32,
+                              unop(Iop_64to32,
+                                   binop(Iop_MullS32, bind(0), bind(1))));
+               if (matchIRExpr(&mi,p_MullS32_then_64to32,e)) {
                    HReg dst = newVRegI(env);
                    HReg     src1 = iselIntExpr_R( env, mi.bindee[0] );
                    PPC32RI* src2 = iselIntExpr_RI( env, mi.bindee[1] );
@@ -1070,20 +1072,12 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
                    return dst;
                }
            }
-
-#if 0
-            HReg rHi, rLo;
-            iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg);
-            return rHi; /* and abandon rLo .. poor wee thing :-) */
-#endif
-         }
-#if 0
-         case Iop_64to32: {
+#else
             HReg rHi, rLo;
             iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg);
             return rLo; /* similar stupid comment to the above ... */
-         }
 #endif
+         }
          case Iop_16HIto8:
          case Iop_32HIto16: {
             HReg dst   = newVRegI(env);
@@ -1548,7 +1542,6 @@ static PPC32CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e )
 }
 
 
-#if 0
 /*---------------------------------------------------------*/
 /*--- ISEL: Integer expressions (64 bit)                ---*/
 /*---------------------------------------------------------*/
@@ -1577,7 +1570,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
    vassert(e);
    vassert(typeOfIRExpr(env->type_env,e) == Ity_I64);
 
-   vex_printf("@iselInt64Expr_wrk: tag=%d\n", e->tag);
+//   vex_printf("@iselInt64Expr_wrk: tag=%d\n", e->tag);
 
 //..    /* 64-bit literal */
 //..    if (e->tag == Iex_Const) {
@@ -1670,26 +1663,19 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
          /* 32 x 32 -> 64 multiply */
          case Iop_MullU32:
          case Iop_MullS32: {
-#if 0
             /* get one operand into %r3, and the other into a R/I.
                Need to make an educated guess about which is better in
                which. */
-            HReg     tLo    = newVRegI(env);
-            HReg     tHi    = newVRegI(env);
-            Bool     syned  = e->Iex.Binop.op == Iop_MullS32;
-            PPC32RI* rmLeft = iselIntExpr_RI(env, e->Iex.Binop.arg1);
-            HReg     rRight = iselIntExpr_R(env, e->Iex.Binop.arg2);
-            addInstr(env, mk_iMOVsd_RR(rRight, hregPPC32_GPR3()));
-
-            addInstr(env, PPC32Instr_MulL(syned, Pss_32, rmLeft));
-
-            /* Result is now in EDX:EAX.  Tell the caller. */
-            addInstr(env, mk_iMOVds_RR(tHi, hregPPC32_EDX()));
-            addInstr(env, mk_iMOVds_RR(tLo, hregPPC32_EAX()));
+            HReg     tLo     = newVRegI(env);
+            HReg     tHi     = newVRegI(env);
+            Bool     syned   = e->Iex.Binop.op == Iop_MullS32;
+            HReg     rLeft   = iselIntExpr_R(env, e->Iex.Binop.arg1);
+            PPC32RI* riRight = iselIntExpr_RI(env, e->Iex.Binop.arg2);
+            addInstr(env, PPC32Instr_MulL(syned, 0, tLo, rLeft, riRight));
+            addInstr(env, PPC32Instr_MulL(syned, 1, tHi, rLeft, riRight));
             *rHi = tHi;
             *rLo = tLo;
             return;
-#endif
          }
 
 //..          /* 64 x 32 -> (32(rem),32(div)) division */
@@ -2212,7 +2198,6 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
    ppIRExpr(e);
    vpanic("iselInt64Expr(ppc32)");
 }
-#endif
 
 
 //.. /*---------------------------------------------------------*/
@@ -3251,10 +3236,10 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
 //..       break;
 //..    }
 
-//..    /* --------- MEM FENCE --------- */
-//..    case Ist_MFence:
-//..       addInstr(env, X86Instr_MFence(env->subarch));
-//..       return;
+   /* --------- MEM FENCE --------- */
+   case Ist_MFence:
+      addInstr(env, PPC32Instr_MFence(env->subarch));
+      return;
 
    /* --------- EXIT --------- */
    case Ist_Exit: {