iropt: implement flattening (into SSA form).  This caused various
primops to become exposed when previously they were treated as part
of a pattern, hence the changes to host-x86/*.c to handle them.



git-svn-id: svn://svn.valgrind.org/vex/trunk@173 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/host-x86/hdefs.c b/priv/host-x86/hdefs.c
index 451bf9b..ccc6b5f 100644
--- a/priv/host-x86/hdefs.c
+++ b/priv/host-x86/hdefs.c
@@ -537,6 +537,13 @@
    vassert(sz == 1 || sz == 2);
    return i;
 }
+X86Instr* X86Instr_Set32 ( X86CondCode cond, HReg dst ) {
+   X86Instr* i       = LibVEX_Alloc(sizeof(X86Instr));
+   i->tag            = Xin_Set32;
+   i->Xin.Set32.cond = cond;
+   i->Xin.Set32.dst  = dst;
+   return i;
+}
 X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst ) {
    X86Instr* i        = LibVEX_Alloc(sizeof(X86Instr));
    i->tag             = Xin_FpUnary;
@@ -675,6 +682,10 @@
          vex_printf(",");
          ppX86AMode(i->Xin.Store.dst);
          return;
+      case Xin_Set32:
+         vex_printf("setl%s ", showX86CondCode(i->Xin.Set32.cond));
+         ppHRegX86(i->Xin.Set32.dst);
+         return;
       case Xin_FpUnary:
          vex_printf("g%sD ", showX86FpOp(i->Xin.FpUnary.op));
          ppHRegX86(i->Xin.FpUnary.src);
@@ -800,6 +811,9 @@
          addHRegUse(u, HRmRead, i->Xin.Store.src);
          addRegUsage_X86AMode(u, i->Xin.Store.dst);
          return;
+      case Xin_Set32:
+         addHRegUse(u, HRmWrite, i->Xin.Set32.dst);
+         return;
       case Xin_FpUnary:
          addHRegUse(u, HRmRead, i->Xin.FpUnary.src);
          addHRegUse(u, HRmWrite, i->Xin.FpUnary.dst);
@@ -887,6 +901,9 @@
          mapReg(m, &i->Xin.Store.src);
          mapRegs_X86AMode(m, i->Xin.Store.dst);
          return;
+      case Xin_Set32:
+         mapReg(m, &i->Xin.Set32.dst);
+         return;
       case Xin_FpBinary:
          mapReg(m, &i->Xin.FpBinary.srcL);
          mapReg(m, &i->Xin.FpBinary.srcR);
@@ -1425,6 +1442,9 @@
             *p++ = 0x68;
             p = emit32(p, i->Xin.Push.src->Xrmi.Imm.imm32);
             goto done;
+         case Xrmi_Reg:
+            *p++ = 0x50 + iregNo(i->Xin.Push.src->Xrmi.Reg.reg);
+            goto done;
         default: 
             goto bad;
       }
@@ -1550,6 +1570,36 @@
       }
       break;
 
+   case Xin_Set32:
+      /* Make the destination register be 1 or 0, depending on whether
+         the relevant condition holds.  We have to dodge and weave
+         when the destination is %esi or %edi as we cannot directly
+         emit the native 'setb %reg' for those.  Further complication:
+         the top 24 bits of the destination should be forced to zero,
+         but doing 'xor %r,%r' kills the flag(s) we are about to read.
+         Sigh. */
+      /* First: movl $0, %dst */
+      *p++ = 0xB8 + iregNo(i->Xin.Set32.dst);
+      p = emit32(p, 0);
+      /* Do we need to swap in %eax? */
+
+      if (iregNo(i->Xin.Set32.dst) >= 4) {
+         /* xchg %eax, %dst */
+         *p++ = 0x90 + iregNo(i->Xin.Set32.dst);
+         /* setb lo8(%reg) */
+         *p++ = 0x0F; 
+         *p++ = 0x90 + (UChar)(i->Xin.Set32.cond);
+         p = doAMode_R(p, fake(0), hregX86_EAX());
+         /* xchg %eax, %dst */
+         *p++ = 0x90 + iregNo(i->Xin.Set32.dst);
+      } else {
+         /* setb lo8(%reg) */
+         *p++ = 0x0F; 
+         *p++ = 0x90 + (UChar)(i->Xin.Set32.cond);
+         p = doAMode_R(p, fake(0), i->Xin.Set32.dst);
+      }
+      goto done;
+
    case Xin_Store:
       if (i->Xin.Store.sz == 2) {
          /* This case, at least, is simple, given that we can
@@ -1652,13 +1702,13 @@
         /* ffree %st(7) */
         p = do_ffree_st7(p);
         /* pushl %hi ; pushl %lo */
-        *p++ = 0x50 + hregNumber(i->Xin.FpI64.iregHi);
-        *p++ = 0x50 + hregNumber(i->Xin.FpI64.iregLo);
+        *p++ = 0x50 + iregNo(i->Xin.FpI64.iregHi);
+        *p++ = 0x50 + iregNo(i->Xin.FpI64.iregLo);
         /* fildll 0(%esp) */
         *p++ = 0xDF; *p++ = 0x6C; *p++ = 0x24; *p++ = 0x00; 
         /* addl $8, %esp */
         *p++ = 0x83; *p++ = 0xC4; *p++ = 0x08; 
-        p = do_fstp_st(p, 1+hregNumber(i->Xin.FpI64.freg));
+        p = do_fstp_st(p, 1+iregNo(i->Xin.FpI64.freg));
         goto done;
      }