]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Cleaning up the x86 back end: get rid of instruction variants which
authorJulian Seward <jseward@acm.org>
Wed, 23 Feb 2005 13:31:25 +0000 (13:31 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 23 Feb 2005 13:31:25 +0000 (13:31 +0000)
the instruction selector will never generate.  I guess this
demonstrates that the majority of operations are sufficiently rare
that it is not worth going to much effort to generate good code for
them.

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

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

index 0fd7454cfa3f7c0ef06603eae21261b0fba1c443..b608fba440b27a2604318518b6de59e7822ce68f 100644 (file)
@@ -430,14 +430,6 @@ static void mapRegs_X86RM ( HRegRemap* m, X86RM* op )
 
 /* --------- Instructions. --------- */
 
-HChar* showX86ScalarSz ( X86ScalarSz sz ) {
-   switch (sz) {
-      case Xss_16: return "w";
-      case Xss_32: return "l";
-      default: vpanic("showX86ScalarSz");
-   }
-}
-
 HChar* showX86UnaryOp ( X86UnaryOp op ) {
    switch (op) {
       case Xun_NOT: return "not";
@@ -587,7 +579,7 @@ X86Instr* X86Instr_Alu32M ( X86AluOp op, X86RI* src, X86AMode* dst ) {
    vassert(op != Xalu_MUL);
    return i;
 }
-X86Instr* X86Instr_Sh32 ( X86ShiftOp op, UInt src, X86RM* dst ) {
+X86Instr* X86Instr_Sh32 ( X86ShiftOp op, UInt src, HReg dst ) {
    X86Instr* i     = LibVEX_Alloc(sizeof(X86Instr));
    i->tag          = Xin_Sh32;
    i->Xin.Sh32.op  = op;
@@ -595,34 +587,32 @@ X86Instr* X86Instr_Sh32 ( X86ShiftOp op, UInt src, X86RM* dst ) {
    i->Xin.Sh32.dst = dst;
    return i;
 }
-X86Instr* X86Instr_Test32  ( X86RI* src, X86RM* dst ) {
-   X86Instr* i       = LibVEX_Alloc(sizeof(X86Instr));
-   i->tag            = Xin_Test32;
-   i->Xin.Test32.src = src;
-   i->Xin.Test32.dst = dst;
+X86Instr* X86Instr_Test32 ( UInt imm32, HReg dst ) {
+   X86Instr* i         = LibVEX_Alloc(sizeof(X86Instr));
+   i->tag              = Xin_Test32;
+   i->Xin.Test32.imm32 = imm32;
+   i->Xin.Test32.dst   = dst;
    return i;
 }
-X86Instr* X86Instr_Unary32  ( X86UnaryOp op, X86RM* dst ) {
+X86Instr* X86Instr_Unary32 ( X86UnaryOp op, HReg dst ) {
    X86Instr* i        = LibVEX_Alloc(sizeof(X86Instr));
    i->tag             = Xin_Unary32;
    i->Xin.Unary32.op  = op;
    i->Xin.Unary32.dst = dst;
    return i;
 }
-X86Instr* X86Instr_MulL ( Bool syned, X86ScalarSz ssz , X86RM* src ) {
+X86Instr* X86Instr_MulL ( Bool syned, 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;
 }
-X86Instr* X86Instr_Div ( Bool syned, X86ScalarSz ssz, X86RM* src ) {
-   X86Instr* i        = LibVEX_Alloc(sizeof(X86Instr));
-   i->tag             = Xin_Div;
-   i->Xin.Div.syned   = syned;
-   i->Xin.Div.ssz     = ssz;
-   i->Xin.Div.src     = src;
+X86Instr* X86Instr_Div ( Bool syned, X86RM* src ) {
+   X86Instr* i      = LibVEX_Alloc(sizeof(X86Instr));
+   i->tag           = Xin_Div;
+   i->Xin.Div.syned = syned;
+   i->Xin.Div.src   = src;
    return i;
 }
 X86Instr* X86Instr_Sh3232  ( X86ShiftOp op, UInt amt, HReg src, HReg dst ) {
@@ -767,11 +757,10 @@ X86Instr* X86Instr_FpCMov ( X86CondCode cond, HReg src, HReg dst ) {
    vassert(cond != Xcc_ALWAYS);
    return i;
 }
-X86Instr* X86Instr_FpLdStCW ( Bool isLoad, X86AMode* addr ) {
-   X86Instr* i            = LibVEX_Alloc(sizeof(X86Instr));
-   i->tag                 = Xin_FpLdStCW;
-   i->Xin.FpLdStCW.isLoad = isLoad;
-   i->Xin.FpLdStCW.addr   = addr;
+X86Instr* X86Instr_FpLdCW ( X86AMode* addr ) {
+   X86Instr* i          = LibVEX_Alloc(sizeof(X86Instr));
+   i->tag               = Xin_FpLdCW;
+   i->Xin.FpLdCW.addr   = addr;
    return i;
 }
 X86Instr* X86Instr_FpStSW_AX ( void ) {
@@ -897,28 +886,22 @@ void ppX86Instr ( X86Instr* i ) {
            vex_printf("%%cl,"); 
          else 
             vex_printf("$%d,", i->Xin.Sh32.src);
-         ppX86RM(i->Xin.Sh32.dst);
+         ppHRegX86(i->Xin.Sh32.dst);
          return;
       case Xin_Test32:
-         vex_printf("testl ");
-         ppX86RI(i->Xin.Test32.src);
-         vex_printf(",");
-         ppX86RM(i->Xin.Test32.dst);
+         vex_printf("testl $%d,", i->Xin.Test32.imm32);
+         ppHRegX86(i->Xin.Test32.dst);
          return;
       case Xin_Unary32:
          vex_printf("%sl ", showX86UnaryOp(i->Xin.Unary32.op));
-         ppX86RM(i->Xin.Unary32.dst);
+         ppHRegX86(i->Xin.Unary32.dst);
          return;
       case Xin_MulL:
-         vex_printf("%cmul%s ",
-                    i->Xin.MulL.syned ? 's' : 'u',
-                    showX86ScalarSz(i->Xin.MulL.ssz));
+         vex_printf("%cmull ", i->Xin.MulL.syned ? 's' : 'u');
          ppX86RM(i->Xin.MulL.src);
          return;
       case Xin_Div:
-         vex_printf("%cdiv%s ",
-                    i->Xin.Div.syned ? 's' : 'u',
-                    showX86ScalarSz(i->Xin.Div.ssz));
+         vex_printf("%cdivl ", i->Xin.Div.syned ? 's' : 'u');
          ppX86RM(i->Xin.Div.src);
          return;
       case Xin_Sh3232:
@@ -1047,9 +1030,9 @@ void ppX86Instr ( X86Instr* i ) {
          vex_printf(",");
          ppHRegX86(i->Xin.FpCMov.dst);
          return;
-      case Xin_FpLdStCW:
-         vex_printf(i->Xin.FpLdStCW.isLoad ? "fldcw " : "fstcw ");
-         ppX86AMode(i->Xin.FpLdStCW.addr);
+      case Xin_FpLdCW:
+         vex_printf("fldcw ");
+         ppX86AMode(i->Xin.FpLdCW.addr);
          return;
       case Xin_FpStSW_AX:
          vex_printf("fstsw %%ax");
@@ -1142,11 +1125,11 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
       case Xin_Alu32R:
          addRegUsage_X86RMI(u, i->Xin.Alu32R.src);
          if (i->Xin.Alu32R.op == Xalu_MOV) {
-            addHRegUse(u, HRmWrite,  i->Xin.Alu32R.dst);
+            addHRegUse(u, HRmWrite, i->Xin.Alu32R.dst);
             return;
          }
          if (i->Xin.Alu32R.op == Xalu_CMP) { 
-            addHRegUse(u, HRmRead,  i->Xin.Alu32R.dst);
+            addHRegUse(u, HRmRead, i->Xin.Alu32R.dst);
             return;
          }
          addHRegUse(u, HRmModify, i->Xin.Alu32R.dst);
@@ -1156,16 +1139,15 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
          addRegUsage_X86AMode(u, i->Xin.Alu32M.dst);
          return;
       case Xin_Sh32:
-         addRegUsage_X86RM(u, i->Xin.Sh32.dst, HRmModify);
+         addHRegUse(u, HRmModify, i->Xin.Sh32.dst);
          if (i->Xin.Sh32.src == 0)
             addHRegUse(u, HRmRead, hregX86_ECX());
          return;
       case Xin_Test32:
-         addRegUsage_X86RI(u, i->Xin.Test32.src);
-         addRegUsage_X86RM(u, i->Xin.Test32.dst, HRmRead);
+         addHRegUse(u, HRmRead, i->Xin.Test32.dst);
          return;
       case Xin_Unary32:
-         addRegUsage_X86RM(u, i->Xin.Unary32.dst, HRmModify);
+         addHRegUse(u, HRmModify, i->Xin.Unary32.dst);
          return;
       case Xin_MulL:
          addRegUsage_X86RM(u, i->Xin.MulL.src, HRmRead);
@@ -1273,8 +1255,8 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
          addHRegUse(u, HRmRead,   i->Xin.FpCMov.src);
          addHRegUse(u, HRmModify, i->Xin.FpCMov.dst);
          return;
-      case Xin_FpLdStCW:
-         addRegUsage_X86AMode(u, i->Xin.FpLdStCW.addr);
+      case Xin_FpLdCW:
+         addRegUsage_X86AMode(u, i->Xin.FpLdCW.addr);
          return;
       case Xin_FpStSW_AX:
          addHRegUse(u, HRmWrite, hregX86_EAX());
@@ -1378,14 +1360,13 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i)
          mapRegs_X86AMode(m, i->Xin.Alu32M.dst);
          return;
       case Xin_Sh32:
-         mapRegs_X86RM(m, i->Xin.Sh32.dst);
+         mapReg(m, &i->Xin.Sh32.dst);
          return;
       case Xin_Test32:
-         mapRegs_X86RI(m, i->Xin.Test32.src);
-         mapRegs_X86RM(m, i->Xin.Test32.dst);
+         mapReg(m, &i->Xin.Test32.dst);
          return;
       case Xin_Unary32:
-         mapRegs_X86RM(m, i->Xin.Unary32.dst);
+         mapReg(m, &i->Xin.Unary32.dst);
          return;
       case Xin_MulL:
          mapRegs_X86RM(m, i->Xin.MulL.src);
@@ -1451,8 +1432,8 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i)
          mapReg(m, &i->Xin.FpCMov.src);
          mapReg(m, &i->Xin.FpCMov.dst);
          return;
-      case Xin_FpLdStCW:
-         mapRegs_X86AMode(m, i->Xin.FpLdStCW.addr);
+      case Xin_FpLdCW:
+         mapRegs_X86AMode(m, i->Xin.FpLdCW.addr);
          return;
       case Xin_FpStSW_AX:
          return;
@@ -2013,95 +1994,65 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
       }
       if (i->Xin.Sh32.src == 0) {
          *p++ = opc_cl;
-         switch (i->Xin.Sh32.dst->tag) {
-            case Xrm_Reg:
-               p = doAMode_R(p, fake(subopc), 
-                                i->Xin.Sh32.dst->Xrm.Reg.reg);
-               goto done;
-            default:
-               goto bad;
-         }
+         p = doAMode_R(p, fake(subopc), i->Xin.Sh32.dst);
       } else {
          *p++ = opc_imm;
-         switch (i->Xin.Sh32.dst->tag) {
-            case Xrm_Reg:
-               p = doAMode_R(p, fake(subopc), 
-                                i->Xin.Sh32.dst->Xrm.Reg.reg);
-               *p++ = (UChar)(i->Xin.Sh32.src);
-               goto done;
-            default:
-               goto bad;
-         }
+         p = doAMode_R(p, fake(subopc), i->Xin.Sh32.dst);
+         *p++ = (UChar)(i->Xin.Sh32.src);
       }
-      break;
+      goto done;
 
    case Xin_Test32:
-      if (i->Xin.Test32.src->tag == Xri_Imm
-          && i->Xin.Test32.dst->tag == Xrm_Reg) {
-         /* testl $imm32, %reg */
-         *p++ = 0xF7;
-         p = doAMode_R(p, fake(0), i->Xin.Test32.dst->Xrm.Reg.reg);
-         p = emit32(p, i->Xin.Test32.src->Xri.Imm.imm32);
-         goto done;
-      }
-      break;
+      /* testl $imm32, %reg */
+      *p++ = 0xF7;
+      p = doAMode_R(p, fake(0), i->Xin.Test32.dst);
+      p = emit32(p, i->Xin.Test32.imm32);
+      goto done;
 
    case Xin_Unary32:
       if (i->Xin.Unary32.op == Xun_NOT) {
          *p++ = 0xF7;
-         if (i->Xin.Unary32.dst->tag == Xrm_Reg) {
-            p = doAMode_R(p, fake(2), i->Xin.Unary32.dst->Xrm.Reg.reg);
-            goto done;
-         } else {
-            goto bad;
-         }
+         p = doAMode_R(p, fake(2), i->Xin.Unary32.dst);
+         goto done;
       }
       if (i->Xin.Unary32.op == Xun_NEG) {
          *p++ = 0xF7;
-         if (i->Xin.Unary32.dst->tag == Xrm_Reg) {
-            p = doAMode_R(p, fake(3), i->Xin.Unary32.dst->Xrm.Reg.reg);
-            goto done;
-         } else {
-            goto bad;
-         }
+         p = doAMode_R(p, fake(3), i->Xin.Unary32.dst);
+         goto done;
       }
       break;
 
    case Xin_MulL:
       subopc = i->Xin.MulL.syned ? 5 : 4;
-      if (i->Xin.MulL.ssz == Xss_32) {
-         *p++ = 0xF7;
-         switch (i->Xin.MulL.src->tag)  {
-            case Xrm_Mem:
-               p = doAMode_M(p, fake(subopc),
-                                i->Xin.MulL.src->Xrm.Mem.am);
-               goto done;
-            case Xrm_Reg:
-               p = doAMode_R(p, fake(subopc), 
-                                i->Xin.MulL.src->Xrm.Reg.reg);
-               goto done;
-            default:
-               goto bad;
-         }
+      *p++ = 0xF7;
+      switch (i->Xin.MulL.src->tag)  {
+         case Xrm_Mem:
+            p = doAMode_M(p, fake(subopc),
+                             i->Xin.MulL.src->Xrm.Mem.am);
+            goto done;
+         case Xrm_Reg:
+            p = doAMode_R(p, fake(subopc), 
+                             i->Xin.MulL.src->Xrm.Reg.reg);
+            goto done;
+         default:
+            goto bad;
       }
       break;
 
    case Xin_Div:
       subopc = i->Xin.Div.syned ? 7 : 6;
-      if (i->Xin.Div.ssz == Xss_32) {
-         *p++ = 0xF7;
-         switch (i->Xin.Div.src->tag)  {
-            case Xrm_Mem:
-               p = doAMode_M(p, fake(subopc),
-                                i->Xin.Div.src->Xrm.Mem.am);
-               goto done;
-            case Xrm_Reg:
-               p = doAMode_R(p, fake(subopc), 
-                                i->Xin.Div.src->Xrm.Reg.reg);
-               goto done;
-            default:
-               goto bad;
-         }
+      *p++ = 0xF7;
+      switch (i->Xin.Div.src->tag)  {
+         case Xrm_Mem:
+            p = doAMode_M(p, fake(subopc),
+                             i->Xin.Div.src->Xrm.Mem.am);
+            goto done;
+         case Xrm_Reg:
+            p = doAMode_R(p, fake(subopc), 
+                             i->Xin.Div.src->Xrm.Reg.reg);
+            goto done;
+         default:
+            goto bad;
       }
       break;
 
@@ -2232,7 +2183,6 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
 
    case Xin_CMov32:
       vassert(i->Xin.CMov32.cond != Xcc_ALWAYS);
-#if 0
       /* This generates cmov, which is illegal on P54/P55. */
       *p++ = 0x0F;
       *p++ = 0x40 + i->Xin.CMov32.cond;
@@ -2244,37 +2194,6 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
          p = doAMode_M(p, i->Xin.CMov32.dst, i->Xin.CMov32.src->Xrm.Mem.am);
          goto done;
       }
-#else
-      /* P5 friendly version: conditional jump over an unconditional
-         move. */
-      /* jmp fwds if !condition */
-      *p++ = 0x70 + (i->Xin.CMov32.cond ^ 1);
-      *p++ = 0; /* # of bytes in the next bit, which we don't know yet */
-      ptmp = p;
-
-      switch (i->Xin.CMov32.src->tag) {
-         case Xrm_Reg:
-            /* Big sigh.  This is movl E -> G ... */
-            *p++ = 0x89;
-            p = doAMode_R(p, i->Xin.CMov32.src->Xrm.Reg.reg,
-                             i->Xin.CMov32.dst);
-                             
-            break;
-         case Xrm_Mem:
-            /* ... whereas this is movl G -> E.  That's why the args
-               to doAMode_R appear to be the wrong way round in the
-               Xrm_Reg case. */
-            *p++ = 0x8B;
-            p = doAMode_M(p, i->Xin.CMov32.dst, 
-                             i->Xin.CMov32.src->Xrm.Mem.am);
-            break;
-         default:
-            goto bad;
-      }
-      /* Fill in the jump offset. */
-      *(ptmp-1) = p - ptmp;
-      goto done;
-#endif
       break;
 
    case Xin_LoadEX:
@@ -2581,13 +2500,9 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
       *(ptmp-1) = p - ptmp;
       goto done;
 
-   case Xin_FpLdStCW:
-      if (i->Xin.FpLdStCW.isLoad) {
-         *p++ = 0xD9;
-         p = doAMode_M(p, fake(5)/*subopcode*/, i->Xin.FpLdStCW.addr);
-      } else {
-         vassert(0);
-      }
+   case Xin_FpLdCW:
+      *p++ = 0xD9;
+      p = doAMode_M(p, fake(5)/*subopcode*/, i->Xin.FpLdCW.addr);
       goto done;
 
    case Xin_FpStSW_AX:
index 8d7b557c900372c9d80dbb0df2abfa6369623392..64c5140b5fb6d8788f50f96bb55bcb08a323c7c8 100644 (file)
@@ -238,17 +238,6 @@ extern void ppX86RM ( X86RM* );
 
 /* --------- Instructions. --------- */
 
-/* --------- */
-typedef
-   enum {
-      Xss_16,
-      Xss_32
-   }
-   X86ScalarSz;
-
-extern HChar* showX86ScalarSz ( X86ScalarSz );
-
-
 /* --------- */
 typedef
    enum {
@@ -350,11 +339,12 @@ typedef
    enum {
       Xin_Alu32R,    /* 32-bit mov/arith/logical, dst=REG */
       Xin_Alu32M,    /* 32-bit mov/arith/logical, dst=MEM */
-      Xin_Sh32,      /* 32-bit shift/rotate, dst=REG or MEM */
-      Xin_Test32,    /* 32-bit test (AND, set flags, discard result) */
+      Xin_Sh32,      /* 32-bit shift/rotate, dst=REG */
+      Xin_Test32,    /* 32-bit test of REG against imm32 (AND, set
+                        flags, discard result) */
       Xin_Unary32,   /* 32-bit not and neg */
-      Xin_MulL,      /* widening multiply */
-      Xin_Div,       /* div and mod */
+      Xin_MulL,      /* 32 x 32 -> 64 multiply */
+      Xin_Div,       /* 64/32 -> (32,32) div and mod */
       Xin_Sh3232,    /* shldl or shrdl */
       Xin_Push,      /* push (32-bit?) value on stack */
       Xin_Call,      /* call to address in register */
@@ -372,7 +362,7 @@ typedef
       Xin_FpLdStI,   /* FP fake load/store, converting to/from Int */
       Xin_Fp64to32,  /* FP round IEEE754 double to IEEE754 single */
       Xin_FpCMov,    /* FP fake floating point conditional move */
-      Xin_FpLdStCW,  /* fldcw / fstcw */
+      Xin_FpLdCW,    /* fldcw */
       Xin_FpStSW_AX, /* fstsw %ax */
       Xin_FpCmp,     /* FP compare, generating a C320 value into int reg */
 
@@ -407,29 +397,27 @@ typedef
          } Alu32M;
          struct {
             X86ShiftOp op;
-            UInt       src;  /* shift amount, or 0 means %cl */
-            X86RM*     dst;
+            UInt  src;  /* shift amount, or 0 means %cl */
+            HReg  dst;
          } Sh32;
          struct {
-            X86RI* src;
-            X86RM* dst;
+            UInt imm32;
+            HReg dst; /* not written, only read */
          } Test32;
          /* Not and Neg */
          struct {
             X86UnaryOp op;
-            X86RM*     dst;
+            HReg       dst;
          } Unary32;
-         /* DX:AX = AX *s/u r/m16,  or EDX:EAX = EAX *s/u r/m32 */
+         /* EDX:EAX = EAX *s/u r/m32 */
          struct {
-            Bool        syned;
-            X86ScalarSz ssz;
-            X86RM*      src;
+            Bool   syned;
+            X86RM* src;
          } MulL;
          /* x86 div/idiv instruction.  Modifies EDX and EAX and reads src. */
          struct {
-            Bool        syned;
-            X86ScalarSz ssz;
-            X86RM*      src;
+            Bool   syned;
+            X86RM* src;
          } Div;
          /* shld/shrd.  op may only be Xsh_SHL or Xsh_SHR */
          struct {
@@ -539,12 +527,11 @@ typedef
             HReg        src;
             HReg        dst;
          } FpCMov;
-         /* Load/store the FPU's 16-bit control word (fldcw/fstcw) */
+         /* Load the FPU's 16-bit control word (fldcw) */
          struct {
-            Bool      isLoad;
             X86AMode* addr;
          }
-         FpLdStCW;
+         FpLdCW;
          /* fstsw %ax */
          struct {
             /* no fields */
@@ -568,7 +555,7 @@ typedef
             X86AMode* addr;
          } SseLdSt;
          struct {
-            Int       sz; /* 4 or 8 only */
+            UChar     sz; /* 4 or 8 only */
             HReg      reg;
             X86AMode* addr;
          } SseLdzLO;
@@ -616,11 +603,11 @@ typedef
 
 extern X86Instr* X86Instr_Alu32R    ( X86AluOp, X86RMI*, HReg );
 extern X86Instr* X86Instr_Alu32M    ( X86AluOp, X86RI*,  X86AMode* );
-extern X86Instr* X86Instr_Unary32   ( X86UnaryOp op, X86RM* dst );
-extern X86Instr* X86Instr_Sh32      ( X86ShiftOp, UInt, X86RM* );
-extern X86Instr* X86Instr_Test32    ( X86RI* src, X86RM* dst );
-extern X86Instr* X86Instr_MulL      ( Bool syned, X86ScalarSz, X86RM* );
-extern X86Instr* X86Instr_Div       ( Bool syned, X86ScalarSz, X86RM* );
+extern X86Instr* X86Instr_Unary32   ( X86UnaryOp op, HReg dst );
+extern X86Instr* X86Instr_Sh32      ( X86ShiftOp, UInt, HReg );
+extern X86Instr* X86Instr_Test32    ( UInt imm32, HReg dst );
+extern X86Instr* X86Instr_MulL      ( Bool syned, X86RM* );
+extern X86Instr* X86Instr_Div       ( Bool syned, X86RM* );
 extern X86Instr* X86Instr_Sh3232    ( X86ShiftOp, UInt amt, HReg src, HReg dst );
 extern X86Instr* X86Instr_Push      ( X86RMI* );
 extern X86Instr* X86Instr_Call      ( X86CondCode, Addr32, Int );
@@ -639,7 +626,7 @@ extern X86Instr* X86Instr_FpLdSt    ( Bool isLoad, UChar sz, HReg reg, X86AMode*
 extern X86Instr* X86Instr_FpLdStI   ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
 extern X86Instr* X86Instr_Fp64to32  ( HReg src, HReg dst );
 extern X86Instr* X86Instr_FpCMov    ( X86CondCode, HReg src, HReg dst );
-extern X86Instr* X86Instr_FpLdStCW  ( Bool isLoad, X86AMode* );
+extern X86Instr* X86Instr_FpLdCW    ( X86AMode* );
 extern X86Instr* X86Instr_FpStSW_AX ( void );
 extern X86Instr* X86Instr_FpCmp     ( HReg srcL, HReg srcR, HReg dst );
 
index a431ed89a406fd2c0492c7e17aa86efac2912708..eaa78b332caf47bdb1a08f3ca4238a8b929d0327 100644 (file)
@@ -619,7 +619,7 @@ void set_FPU_rounding_default ( ISelEnv* env )
    */
    X86AMode* zero_esp = X86AMode_IR(0, hregX86_ESP());
    addInstr(env, X86Instr_Push(X86RMI_Imm(DEFAULT_FPUCW)));
-   addInstr(env, X86Instr_FpLdStCW(True/*load*/, zero_esp));
+   addInstr(env, X86Instr_FpLdCW(zero_esp));
    add_to_esp(env, 4);
 }
 
@@ -646,10 +646,10 @@ void set_FPU_rounding_mode ( ISelEnv* env, IRExpr* mode )
    */
    addInstr(env, mk_iMOVsd_RR(rrm, rrm2));
    addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(3), rrm2));
-   addInstr(env, X86Instr_Sh32(Xsh_SHL, 10, X86RM_Reg(rrm2)));
+   addInstr(env, X86Instr_Sh32(Xsh_SHL, 10, rrm2));
    addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Imm(DEFAULT_FPUCW), rrm2));
    addInstr(env, X86Instr_Push(X86RMI_Reg(rrm2)));
-   addInstr(env, X86Instr_FpLdStCW(True/*load*/, zero_esp));
+   addInstr(env, X86Instr_FpLdCW(zero_esp));
    add_to_esp(env, 4);
 }
 
@@ -766,7 +766,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          HReg dst = newVRegI(env);
          HReg reg = iselIntExpr_R(env, e->Iex.Binop.arg2);
          addInstr(env, mk_iMOVsd_RR(reg,dst));
-         addInstr(env, X86Instr_Unary32(Xun_NEG,X86RM_Reg(dst)));
+         addInstr(env, X86Instr_Unary32(Xun_NEG,dst));
          return dst;
       }
 
@@ -844,12 +844,12 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
                                 Xalu_AND, X86RMI_Imm(0xFFFF), dst));
                break;
             case Iop_Sar8:
-               addInstr(env, X86Instr_Sh32(Xsh_SHL, 24, X86RM_Reg(dst)));
-               addInstr(env, X86Instr_Sh32(Xsh_SAR, 24, X86RM_Reg(dst)));
+               addInstr(env, X86Instr_Sh32(Xsh_SHL, 24, dst));
+               addInstr(env, X86Instr_Sh32(Xsh_SAR, 24, dst));
                break;
             case Iop_Sar16:
-               addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, X86RM_Reg(dst)));
-               addInstr(env, X86Instr_Sh32(Xsh_SAR, 16, X86RM_Reg(dst)));
+               addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, dst));
+               addInstr(env, X86Instr_Sh32(Xsh_SAR, 16, dst));
                break;
             default: break;
          }
@@ -864,15 +864,12 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
            vassert(nshift >= 0);
            if (nshift > 0)
                /* Can't allow nshift==0 since that means %cl */
-               addInstr(env, X86Instr_Sh32(
-                                shOp, 
-                                nshift,
-                                X86RM_Reg(dst)));
+               addInstr(env, X86Instr_Sh32( shOp, nshift, dst ));
          } else {
             /* General case; we have to force the amount into %cl. */
             HReg regR = iselIntExpr_R(env, e->Iex.Binop.arg2);
             addInstr(env, mk_iMOVsd_RR(regR,hregX86_ECX()));
-            addInstr(env, X86Instr_Sh32(shOp, 0/* %cl */, X86RM_Reg(dst)));
+            addInstr(env, X86Instr_Sh32(shOp, 0/* %cl */, dst));
          }
          return dst;
       }
@@ -885,7 +882,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          HReg lo8s = iselIntExpr_R(env, e->Iex.Binop.arg2);
          addInstr(env, mk_iMOVsd_RR(hi8s, hi8));
          addInstr(env, mk_iMOVsd_RR(lo8s, lo8));
-         addInstr(env, X86Instr_Sh32(Xsh_SHL, 8, X86RM_Reg(hi8)));
+         addInstr(env, X86Instr_Sh32(Xsh_SHL, 8, hi8));
          addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(0xFF), lo8));
          addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(lo8), hi8));
          return hi8;
@@ -898,7 +895,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          HReg lo16s = iselIntExpr_R(env, e->Iex.Binop.arg2);
          addInstr(env, mk_iMOVsd_RR(hi16s, hi16));
          addInstr(env, mk_iMOVsd_RR(lo16s, lo16));
-         addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, X86RM_Reg(hi16)));
+         addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, hi16));
          addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(0xFFFF), lo16));
          addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(lo16), hi16));
          return hi16;
@@ -919,10 +916,10 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
 
          addInstr(env, mk_iMOVsd_RR(a16s, a16));
          addInstr(env, mk_iMOVsd_RR(b16s, b16));
-         addInstr(env, X86Instr_Sh32(Xsh_SHL, shift, X86RM_Reg(a16)));
-         addInstr(env, X86Instr_Sh32(Xsh_SHL, shift, X86RM_Reg(b16)));
-         addInstr(env, X86Instr_Sh32(shr_op,  shift, X86RM_Reg(a16)));
-         addInstr(env, X86Instr_Sh32(shr_op,  shift, X86RM_Reg(b16)));
+         addInstr(env, X86Instr_Sh32(Xsh_SHL, shift, a16));
+         addInstr(env, X86Instr_Sh32(Xsh_SHL, shift, b16));
+         addInstr(env, X86Instr_Sh32(shr_op,  shift, a16));
+         addInstr(env, X86Instr_Sh32(shr_op,  shift, b16));
          addInstr(env, X86Instr_Alu32R(Xalu_MUL, X86RMI_Reg(a16), b16));
          return b16;
       }
@@ -934,7 +931,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          addInstr(env, X86Instr_FpCmp(fL,fR,dst));
          /* shift this right 8 bits so as to conform to CmpF64
             definition. */
-         addInstr(env, X86Instr_Sh32(Xsh_SHR, 8, X86RM_Reg(dst)));
+         addInstr(env, X86Instr_Sh32(Xsh_SHR, 8, dst));
          return dst;
       }
 
@@ -1050,8 +1047,8 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
             HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
             UInt amt = e->Iex.Unop.op==Iop_16Sto32 ? 16 : 24;
             addInstr(env, mk_iMOVsd_RR(src,dst) );
-            addInstr(env, X86Instr_Sh32(Xsh_SHL, amt, X86RM_Reg(dst)));
-            addInstr(env, X86Instr_Sh32(Xsh_SAR, amt, X86RM_Reg(dst)));
+            addInstr(env, X86Instr_Sh32(Xsh_SHL, amt, dst));
+            addInstr(env, X86Instr_Sh32(Xsh_SAR, amt, dst));
             return dst;
          }
         case Iop_Not8:
@@ -1060,7 +1057,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
             HReg dst = newVRegI(env);
             HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
             addInstr(env, mk_iMOVsd_RR(src,dst) );
-            addInstr(env, X86Instr_Unary32(Xun_NOT,X86RM_Reg(dst)));
+            addInstr(env, X86Instr_Unary32(Xun_NOT,dst));
             return dst;
          }
          case Iop_64HIto32: {
@@ -1079,7 +1076,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
             HReg src  = iselIntExpr_R(env, e->Iex.Unop.arg);
             Int shift = e->Iex.Unop.op == Iop_16HIto8 ? 8 : 16;
             addInstr(env, mk_iMOVsd_RR(src,dst) );
-            addInstr(env, X86Instr_Sh32(Xsh_SHR, shift, X86RM_Reg(dst)));
+            addInstr(env, X86Instr_Sh32(Xsh_SHR, shift, dst));
             return dst;
          }
          case Iop_1Uto32:
@@ -1096,8 +1093,8 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
             HReg dst         = newVRegI(env);
             X86CondCode cond = iselCondCode(env, e->Iex.Unop.arg);
             addInstr(env, X86Instr_Set32(cond,dst));
-            addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, X86RM_Reg(dst)));
-            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(dst)));
+            addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, dst));
+            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, dst));
             return dst;
          }
          case Iop_Ctz32: {
@@ -1217,7 +1214,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
         HReg dst = newVRegI(env);
         addInstr(env, mk_iMOVsd_RR(rX,dst));
         r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond);
-        addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8)));
+        addInstr(env, X86Instr_Test32(0xFF, r8));
         addInstr(env, X86Instr_CMov32(Xcc_Z,r0,dst));
         return dst;
       }
@@ -1357,7 +1354,11 @@ static X86RMI* iselIntExpr_RMI_wrk ( ISelEnv* env, IRExpr* e )
                                     hregX86_EBP()));
    }
 
-   /* special case: load from memory */
+   /* special case: 32-bit load from memory */
+   if (e->tag == Iex_LDle && ty == Ity_I32) {
+      X86AMode* am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+      return X86RMI_Mem(am);
+   }
 
    /* default case: calculate into a register and return that */
    {
@@ -1518,8 +1519,8 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e )
       unop(Iop_32to1,bind(0))
    );
    if (matchIRExpr(&mi,p_32to1,e)) {
-      X86RM* rm = iselIntExpr_RM(env, mi.bindee[0]);
-      addInstr(env, X86Instr_Test32(X86RI_Imm(1),rm));
+      HReg r = iselIntExpr_R(env, mi.bindee[0]);
+      addInstr(env, X86Instr_Test32(1,r));
       return Xcc_NZ;
    }
 
@@ -1754,7 +1755,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
       addInstr(env, mk_iMOVsd_RR(eXHi, tHi));
       addInstr(env, mk_iMOVsd_RR(eXLo, tLo));
       r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond);
-      addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8)));
+      addInstr(env, X86Instr_Test32(0xFF, r8));
       /* This assumes the first cmov32 doesn't trash the condition
          codes, so they are still available for the second cmov32 */
       addInstr(env, X86Instr_CMov32(Xcc_Z,X86RM_Reg(e0Hi),tHi));
@@ -1779,7 +1780,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
             X86RM* rmLeft = iselIntExpr_RM(env, e->Iex.Binop.arg1);
             HReg   rRight = iselIntExpr_R(env, e->Iex.Binop.arg2);
             addInstr(env, mk_iMOVsd_RR(rRight, hregX86_EAX()));
-            addInstr(env, X86Instr_MulL(syned, Xss_32, rmLeft));
+            addInstr(env, X86Instr_MulL(syned, rmLeft));
             /* Result is now in EDX:EAX.  Tell the caller. */
             addInstr(env, mk_iMOVsd_RR(hregX86_EDX(), tHi));
             addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), tLo));
@@ -1801,7 +1802,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
             iselInt64Expr(&sHi,&sLo, env, e->Iex.Binop.arg1);
             addInstr(env, mk_iMOVsd_RR(sHi, hregX86_EDX()));
             addInstr(env, mk_iMOVsd_RR(sLo, hregX86_EAX()));
-            addInstr(env, X86Instr_Div(syned, Xss_32, rmRight));
+            addInstr(env, X86Instr_Div(syned, rmRight));
             addInstr(env, mk_iMOVsd_RR(hregX86_EDX(), tHi));
             addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), tLo));
             *rHi = tHi;
@@ -1891,9 +1892,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
             /* Ok.  Now shift amt is in %ecx, and value is in tHi/tLo
                and those regs are legitimately modifiable. */
             addInstr(env, X86Instr_Sh3232(Xsh_SHL, 0/*%cl*/, tLo, tHi));
-            addInstr(env, X86Instr_Sh32(Xsh_SHL, 0/*%cl*/, X86RM_Reg(tLo)));
-            addInstr(env, X86Instr_Test32(X86RI_Imm(32), 
-                          X86RM_Reg(hregX86_ECX())));
+            addInstr(env, X86Instr_Sh32(Xsh_SHL, 0/*%cl*/, tLo));
+            addInstr(env, X86Instr_Test32(32, hregX86_ECX()));
             addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tLo), tHi));
             addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(0), tTemp));
             addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tTemp), tLo));
@@ -1934,9 +1934,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
             /* Ok.  Now shift amt is in %ecx, and value is in tHi/tLo
                and those regs are legitimately modifiable. */
             addInstr(env, X86Instr_Sh3232(Xsh_SHR, 0/*%cl*/, tHi, tLo));
-            addInstr(env, X86Instr_Sh32(Xsh_SHR, 0/*%cl*/, X86RM_Reg(tHi)));
-            addInstr(env, X86Instr_Test32(X86RI_Imm(32), 
-                          X86RM_Reg(hregX86_ECX())));
+            addInstr(env, X86Instr_Sh32(Xsh_SHR, 0/*%cl*/, tHi));
+            addInstr(env, X86Instr_Test32(32, hregX86_ECX()));
             addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tHi), tLo));
             addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(0), tTemp));
             addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tTemp), tHi));
@@ -2157,7 +2156,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
             HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
             addInstr(env, mk_iMOVsd_RR(src,tHi));
             addInstr(env, mk_iMOVsd_RR(src,tLo));
-            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(tHi)));
+            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, tHi));
             *rHi = tHi;
             *rLo = tLo;
             return;
@@ -2203,8 +2202,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
             HReg tHi = newVRegI(env);
             X86CondCode cond = iselCondCode(env, e->Iex.Unop.arg);
             addInstr(env, X86Instr_Set32(cond,tLo));
-            addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, X86RM_Reg(tLo)));
-            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(tLo)));
+            addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, tLo));
+            addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, tLo));
             addInstr(env, mk_iMOVsd_RR(tLo, tHi));
             *rHi = tHi;
             *rLo = tLo;
@@ -2219,8 +2218,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
             iselInt64Expr(&sHi, &sLo, env, e->Iex.Unop.arg);
             addInstr(env, mk_iMOVsd_RR(sHi, tHi));
             addInstr(env, mk_iMOVsd_RR(sLo, tLo));
-            addInstr(env, X86Instr_Unary32(Xun_NOT,X86RM_Reg(tHi)));
-            addInstr(env, X86Instr_Unary32(Xun_NOT,X86RM_Reg(tLo)));
+            addInstr(env, X86Instr_Unary32(Xun_NOT,tHi));
+            addInstr(env, X86Instr_Unary32(Xun_NOT,tLo));
             *rHi = tHi;
             *rLo = tLo;
             return;
@@ -2625,7 +2624,7 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e )
         HReg r0  = iselDblExpr(env, e->Iex.Mux0X.expr0);
         HReg dst = newVRegF(env);
         addInstr(env, X86Instr_FpUnary(Xfp_MOV,rX,dst));
-        addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8)));
+        addInstr(env, X86Instr_Test32(0xFF, r8));
         addInstr(env, X86Instr_FpCMov(Xcc_Z,r0,dst));
         return dst;
       }
@@ -2759,7 +2758,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
          for (i = 0; i < 4; i++) {
             am = X86AMode_IR(i*4, hregX86_ESP());
             addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Mem(am), r32));
-            addInstr(env, X86Instr_Unary32(Xun_NEG, X86RM_Reg(r32)));
+            addInstr(env, X86Instr_Unary32(Xun_NEG, r32));
             addInstr(env, X86Instr_Alu32R(Xalu_SBB, X86RMI_Reg(r32), r32));
             addInstr(env, X86Instr_Alu32M(Xalu_MOV, X86RI_Reg(r32), am));
          }
@@ -3124,7 +3123,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
       HReg r0  = iselVecExpr(env, e->Iex.Mux0X.expr0);
       HReg dst = newVRegV(env);
       addInstr(env, mk_vMOVsd_RR(rX,dst));
-      addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8)));
+      addInstr(env, X86Instr_Test32(0xFF, r8));
       addInstr(env, X86Instr_SseCMov(Xcc_Z,r0,dst));
       return dst;
    }