]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
More x86 FP stuff, including conversion stuff to/from Ints.
authorJulian Seward <jseward@acm.org>
Sat, 14 Aug 2004 11:50:01 +0000 (11:50 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 14 Aug 2004 11:50:01 +0000 (11:50 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@167

VEX/priv/guest-x86/toIR.c
VEX/priv/host-x86/hdefs.c
VEX/priv/host-x86/hdefs.h
VEX/priv/host-x86/isel.c
VEX/priv/ir/irdefs.c
VEX/pub/libvex_ir.h

index 43f90447925f38e55e5a8839eb453080a6bdc5e2..1b15922143f588b77769a3f0f1bad0d11b8f833b 100644 (file)
@@ -3142,8 +3142,9 @@ static
 UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
 {
    Int  len;
+   UInt src;
    Char dis_buf[32];
-   UInt opc_aux;
+   IRTemp t1;
 
    /* On entry, delta points at the second byte of the insn (the modrm
       byte).*/
@@ -3159,13 +3160,56 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
    /* -+-+-+-+-+-+-+-+-+-+-+-+ 0xD9 opcodes +-+-+-+-+-+-+-+ */
    else
    if (first_opcode == 0xD9) {
-      goto decode_fail;
+      if (modrm < 0xC0) {
+         goto decode_fail;
+      } else {
+         delta++;
+         switch (modrm) {
+            case 0xC0 ... 0xC7: /* FLD %st(?) */
+               src = (UInt)modrm - 0xC0;
+               DIP("fld %%st(%d)\n", src);
+              t1 = newTemp(Ity_F64);
+              assign(t1, get_ST(src));
+              stmt( do_push() );
+              stmt( put_ST(0, mkexpr(t1)) );
+               break;
+
+            default:
+               goto decode_fail;
+         }
+      }
    }
 
    /* -+-+-+-+-+-+-+-+-+-+-+-+ 0xDA opcodes +-+-+-+-+-+-+-+ */
    else
    if (first_opcode == 0xDA) {
-      goto decode_fail;
+
+      if (modrm < 0xC0) {
+
+          /* bits 5,4,3 are an opcode extension, and the modRM also
+            specifies an address. */
+         IRTemp addr = disAMode( &len, sorb, delta, dis_buf );
+         delta += len;
+
+         switch (gregOfRM(modrm)) {
+            case 1: /* FIMUL m32int */
+               DIP("fimull %s", dis_buf);
+               stmt( put_ST(0, 
+                        binop(Iop_MulF64, 
+                              get_ST(0),
+                              unop(Iop_I64toF64,
+                                   unop(Iop_32Sto64,
+                                        loadLE(Ity_I32, mkexpr(addr)))))));
+               break;
+
+            default:
+               vex_printf("unhandled opc_aux = 0x%2x\n", gregOfRM(modrm));
+               vex_printf("first_opcode == 0xDA\n");
+               goto decode_fail;
+         }
+      } else {
+         goto decode_fail;
+      }
    }
 
    /* -+-+-+-+-+-+-+-+-+-+-+-+ 0xDB opcodes +-+-+-+-+-+-+-+ */
@@ -3186,18 +3230,18 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
 
       if (modrm < 0xC0) {
 
-        /* bits 5,4,3 are an opcode extension, and the modRM also
+          /* bits 5,4,3 are an opcode extension, and the modRM also
             specifies an address. */
-        IRTemp addr = disAMode( &len, sorb, delta, dis_buf );
-        delta += len;
+         IRTemp addr = disAMode( &len, sorb, delta, dis_buf );
+         delta += len;
 
          switch (gregOfRM(modrm)) {
 
             case 0: /* FLD double-real */
                DIP("fldD %s\n", dis_buf);
-              stmt( do_push() );
-              stmt( put_ST(0, IRExpr_LDle(Ity_F64, mkexpr(addr))) );
-              break;
+               stmt( do_push() );
+               stmt( put_ST(0, IRExpr_LDle(Ity_F64, mkexpr(addr))) );
+               break;
 
 #if 0
             case 2: /* FST double-real */
@@ -3225,10 +3269,10 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
 #endif
 
             default:
-               vex_printf("unhandled opc_aux = 0x%2x\n", opc_aux);
-               vex_printf("first_opcode == 0xDD");
+               vex_printf("unhandled opc_aux = 0x%2x\n", gregOfRM(modrm));
+               vex_printf("first_opcode == 0xDD\n");
                goto decode_fail;
-        }
+         }
       } else {
          goto decode_fail;
       }
@@ -3653,7 +3697,7 @@ UInt dis_SHLRD_Gv_Ev ( UChar sorb,
                             mask))) );
 
    setFlags_DSTus_DST1 ( left_shift ? Iop_Shl32 : Iop_Sar32,
-                        tmpSubSh, tmpRes, ty, tmpSH );
+                         tmpSubSh, tmpRes, ty, tmpSH );
 
    /* Put result back. */
 
@@ -4359,7 +4403,7 @@ void codegen_xchg_eAX_Reg ( Int sz, Int reg )
 //-- static
 //-- Addr dis_SSE3_reg_or_mem ( UCodeBlock* cb, 
 //--                            UChar sorb, 
-//--                      Addr eip,
+//--                      Addr eip,
 //--                      Int sz,
 //--                            Char* name, 
 //--                            UChar opc1, 
index dff3c8a037f5a55d7708047f6396cf301b0c9350..9ae499ffbcf09ef98e00544c0e3e99139d916f27 100644 (file)
@@ -410,12 +410,13 @@ Char* showX86ShiftOp ( X86ShiftOp op ) {
 
 Char* showX86FpOp ( X86FpOp op ) {
    switch (op) {
-      case Xfp_Add:    return "add";
-      case Xfp_Sub:    return "sub";
-      case Xfp_Mul:    return "mul";
-      case Xfp_Div:    return "div";
-      case Xfp_Sqrt:   return "sqrt";
-      case Xfp_Negate: return "chs";
+      case Xfp_ADD:    return "add";
+      case Xfp_SUB:    return "sub";
+      case Xfp_MUL:    return "mul";
+      case Xfp_DIV:    return "div";
+      case Xfp_SQRT:   return "sqrt";
+      case Xfp_NEGATE: return "chs";
+      case Xfp_MOV:    return "mov";
       default: vpanic("ppX86FpOp");
    }
 }
@@ -591,9 +592,9 @@ void ppX86Instr ( X86Instr* i ) {
       case Xin_Sh32:
          vex_printf("%sl ", showX86ShiftOp(i->Xin.Sh32.op));
          if (i->Xin.Sh32.src == 0)
-           vex_printf(" %%cl,"); 
+           vex_printf("%%cl,"); 
          else 
-            vex_printf(" $%d,", i->Xin.Sh32.src);
+            vex_printf("$%d,", i->Xin.Sh32.src);
          ppX86RM(i->Xin.Sh32.dst);
          return;
       case Xin_Test32:
@@ -674,6 +675,20 @@ void ppX86Instr ( X86Instr* i ) {
          vex_printf(",");
          ppX86AMode(i->Xin.Store.dst);
          return;
+      case Xin_FpUnary:
+         vex_printf("g%sD ", showX86FpOp(i->Xin.FpUnary.op));
+         ppHRegX86(i->Xin.FpUnary.src);
+         vex_printf(",");
+         ppHRegX86(i->Xin.FpUnary.dst);
+         break;
+      case Xin_FpBinary:
+         vex_printf("g%sD ", showX86FpOp(i->Xin.FpBinary.op));
+         ppHRegX86(i->Xin.FpBinary.srcL);
+         vex_printf(",");
+         ppHRegX86(i->Xin.FpBinary.srcR);
+         vex_printf(",");
+         ppHRegX86(i->Xin.FpBinary.dst);
+         break;
       case Xin_FpLdSt:
          if (i->Xin.FpLdSt.isLoad) {
             vex_printf("gld%c " , i->Xin.FpLdSt.sz==8 ? 'D' : 'F');
@@ -687,6 +702,18 @@ void ppX86Instr ( X86Instr* i ) {
             ppX86AMode(i->Xin.FpLdSt.addr);
          }
          return;
+      case Xin_FpI64:
+         if (i->Xin.FpI64.toInt) {
+            vassert(0);
+         } else {
+            vex_printf("gi64tof64 ");
+            ppHRegX86(i->Xin.FpI64.iregHi);
+            vex_printf(":");
+            ppHRegX86(i->Xin.FpI64.iregLo);
+            vex_printf(", ");
+            ppHRegX86(i->Xin.FpI64.freg);
+         }
+         return;
       default:
          vpanic("ppX86Instr");
    }
@@ -773,11 +800,29 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
          addHRegUse(u, HRmRead, i->Xin.Store.src);
          addRegUsage_X86AMode(u, i->Xin.Store.dst);
          return;
+      case Xin_FpUnary:
+         addHRegUse(u, HRmRead, i->Xin.FpUnary.src);
+         addHRegUse(u, HRmWrite, i->Xin.FpUnary.dst);
+         return;
+      case Xin_FpBinary:
+         addHRegUse(u, HRmRead, i->Xin.FpBinary.srcL);
+         addHRegUse(u, HRmRead, i->Xin.FpBinary.srcR);
+         addHRegUse(u, HRmWrite, i->Xin.FpBinary.dst);
+         return;
       case Xin_FpLdSt:
          addRegUsage_X86AMode(u, i->Xin.FpLdSt.addr);
          addHRegUse(u, i->Xin.FpLdSt.isLoad ? HRmWrite : HRmRead,
                        i->Xin.FpLdSt.reg);
          return;
+      case Xin_FpI64:
+         if (i->Xin.FpI64.toInt) {
+            vassert(0);
+         } else {
+            addHRegUse(u, HRmWrite, i->Xin.FpI64.freg);
+            addHRegUse(u, HRmRead, i->Xin.FpI64.iregHi);
+            addHRegUse(u, HRmRead, i->Xin.FpI64.iregLo);
+         }
+         return;
       default:
          ppX86Instr(i);
          vpanic("getRegUsage_X86Instr");
@@ -842,29 +887,54 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i)
          mapReg(m, &i->Xin.Store.src);
          mapRegs_X86AMode(m, i->Xin.Store.dst);
          return;
+      case Xin_FpBinary:
+         mapReg(m, &i->Xin.FpBinary.srcL);
+         mapReg(m, &i->Xin.FpBinary.srcR);
+         mapReg(m, &i->Xin.FpBinary.dst);
+         return;
       case Xin_FpLdSt:
          mapRegs_X86AMode(m, i->Xin.FpLdSt.addr);
          mapReg(m, &i->Xin.FpLdSt.reg);
          return;
+      case Xin_FpI64:
+         mapReg(m, &i->Xin.FpI64.freg);
+         mapReg(m, &i->Xin.FpI64.iregHi);
+         mapReg(m, &i->Xin.FpI64.iregLo);
+         return;
       default:
          ppX86Instr(i);
          vpanic("mapRegs_X86Instr");
    }
 }
 
+/* Figure out if i represents a reg-reg move, and if so assign the
+   source and destination to *src and *dst.  If in doubt say No.  Used
+   by the register allocator to do move coalescing. 
+*/
 Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst )
 {
-   if (i->tag != Xin_Alu32R)
-      return False;
-   if (i->Xin.Alu32R.op != Xalu_MOV)
-      return False;
-   if (i->Xin.Alu32R.src->tag != Xrmi_Reg)
-      return False;
-   *src = i->Xin.Alu32R.src->Xrmi.Reg.reg;
-   *dst = i->Xin.Alu32R.dst;
-   return True;
+   /* Moves between integer regs */
+   if (i->tag == Xin_Alu32R) {
+      if (i->Xin.Alu32R.op != Xalu_MOV)
+         return False;
+      if (i->Xin.Alu32R.src->tag != Xrmi_Reg)
+         return False;
+      *src = i->Xin.Alu32R.src->Xrmi.Reg.reg;
+      *dst = i->Xin.Alu32R.dst;
+      return True;
+   }
+   /* Moves between FP regs */
+   if (i->tag == Xin_FpUnary) {
+      if (i->Xin.FpUnary.op != Xfp_MOV)
+         return False;
+      *src = i->Xin.FpUnary.src;
+      *dst = i->Xin.FpUnary.dst;
+      return True;
+   }
+   return False;
 }
 
+
 /* x86 spill/reload using the hacked104 testbed.  Spill slots
    start at word 51, and there are 24 in total. 
 */
@@ -1051,6 +1121,20 @@ static UChar* do_fld_st ( UChar* p, Int i )
    return p;
 }
 
+/* Emit f<op> %st(i), 1 <= i <= 5 */
+static UChar* do_fop_st ( UChar* p, X86FpOp op, Int i )
+{
+#  define fake(_n) mkHReg((_n), HRcInt, False)
+   Int subopc;
+   switch (op) {
+      case Xfp_MUL: subopc = 1; break;
+      default: vpanic("do_fop_st: unknown op");
+   }
+   *p++ = 0xD8;
+   p    = doAMode_R(p, fake(subopc), fake(i));
+   return p;
+#  undef fake
+}
 
 /* Emit an instruction into buf and return the number of bytes used.
    Note that buf is not the insn's final place, and therefore it is
@@ -1511,10 +1595,20 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
       } /* if (i->Xin.Store.sz == 1) */
       break;
 
+   case Xin_FpBinary:
+      /* gop %srcL, %srcR, %dst
+         --> ffree %st7 ; fld %st(srcL) ; fop %st(1+srcR) ; fstp %st(1+dst)
+      */
+      p = do_ffree_st7(p);
+      p = do_fld_st(p, 0+hregNumber(i->Xin.FpBinary.srcL));
+      p = do_fop_st(p, i->Xin.FpBinary.op, 1+hregNumber(i->Xin.FpBinary.srcR));
+      p = do_fstp_st(p, 1+hregNumber(i->Xin.FpBinary.dst));
+      goto done;
+
    case Xin_FpLdSt:
       if (i->Xin.FpLdSt.isLoad) {
          /* Load from memory into %fakeN.  
-            --> ffree %st(7) ; fld{s/l} amode ; fstp st(I+1) 
+            --> ffree %st(7) ; fld{s/l} amode ; fstp st(N+1) 
          */
          p = do_ffree_st7(p);
          *p++ = i->Xin.FpLdSt.sz==4 ? 0xD9 : 0xDD;
@@ -1523,7 +1617,7 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
          goto done;
       } else {
          /* Store from %fakeN into memory.
-            --> ffree %st(7) ; fld st(I) ; fstp{l|s} amode
+            --> ffree %st(7) ; fld st(N) ; fstp{l|s} amode
         */
          p = do_ffree_st7(p);
          p = do_fld_st(p, 0+hregNumber(i->Xin.FpLdSt.reg));
@@ -1533,6 +1627,27 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
       }
       break;
 
+   case Xin_FpI64:
+     if (i->Xin.FpI64.toInt) {
+       vassert(0);
+     } else {
+        /* gi64tof64 %hi:%lo %fakeN
+           --> ffree %st7; pushl hi ; pushl lo ; fildll 0(%esp) ; 
+               addl $8,%esp ; fstpl %st(N+1) 
+        */
+        /* 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);
+        /* 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));
+        goto done;
+     }
+
    default: 
       goto bad;
    }
index 32afc1acd0e64c4628db2ba6355091e45c1f6303..5e698f703fa66a0da02b93400d2eb9599c3138fd 100644 (file)
@@ -245,8 +245,11 @@ extern Char* showX86ShiftOp ( X86ShiftOp );
 /* --------- */
 typedef
    enum {
-      Xfp_Add, Xfp_Sub, Xfp_Mul, Xfp_Div, 
-      Xfp_Sqrt, Xfp_Negate
+      Xfp_INVALID,
+      /* Binary */
+      Xfp_ADD, Xfp_SUB, Xfp_MUL, Xfp_DIV, 
+      /* Unary */
+      Xfp_SQRT, Xfp_NEGATE, Xfp_MOV
    }
    X86FpOp;
 
index d5b892a792addcc459719f0289f1120527ea06a8..622241e970f49400d3cc4c9005d0dcfa1a1273f5 100644 (file)
@@ -841,6 +841,20 @@ static void iselIntExpr64 ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
       return;
    }
 
+   /* 32Sto64(e) */
+   if (e->tag == Iex_Unop
+       && e->Iex.Unop.op == Iop_32Sto64) {
+      HReg tLo = newVRegI(env);
+      HReg tHi = newVRegI(env);
+      HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
+      addInstr(env, mk_MOVsd_RR(src,tHi));
+      addInstr(env, mk_MOVsd_RR(src,tLo));
+      addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(tHi)));
+      *rHi = tHi;
+      *rLo = tLo;
+      return;
+   }
+
    /* 64-bit shifts */
    if (e->tag == Iex_Binop
        && e->Iex.Binop.op == Iop_Shl64) {
@@ -949,6 +963,10 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
    vassert(e);
    vassert(typeOfIRExpr(env->type_env,e) == Ity_F64);
 
+   if (e->tag == Iex_Tmp) {
+      return lookupIRTemp(env, e->Iex.Tmp.tmp);
+   }
+
    if (e->tag == Iex_LDle) {
       X86AMode* am;
       HReg res = newVRegF(env);
@@ -958,8 +976,45 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
       return res;
    }
 
+   if (e->tag == Iex_GetI) {
+      /* First off, compute the index expression into an integer reg.
+         The written address will then be 0 + ebp + reg*1, that is, an
+         X86AMode_IRRS. */
+      HReg idx = iselIntExpr_R(env, e->Iex.GetI.offset);
+      HReg res = newVRegF(env);
+      addInstr(env, 
+               X86Instr_FpLdSt( True/*load*/, 8, res,
+                                X86AMode_IRRS(0, hregX86_EBP(), idx, 0)) );
+      return res;
+   }
+
+   if (e->tag == Iex_Binop) {
+      X86FpOp fpop = Xfp_INVALID;
+      switch (e->Iex.Binop.op) {
+         case Iop_MulF64: fpop = Xfp_MUL; break;
+         default: break;
+      }
+      if (fpop != Xfp_INVALID) {
+         HReg res  = newVRegF(env);
+         HReg srcL = iselDblExpr(env, e->Iex.Binop.arg1);
+         HReg srcR = iselDblExpr(env, e->Iex.Binop.arg2);
+         addInstr(env, X86Instr_FpBinary(fpop,srcL,srcR,res));
+         return res;
+      }
+   }
+
+   if (e->tag == Iex_Unop) {
+      if (e->Iex.Unop.op == Iop_I64toF64) {
+         HReg iHi, iLo;
+         HReg dst = newVRegF(env);
+         iselIntExpr64(&iHi, &iLo, env, e->Iex.Unop.arg);
+         addInstr(env, X86Instr_FpI64(False/*i->f*/,dst,iHi,iLo));
+         return dst;
+      }
+   }
+
    ppIRExpr(e);
-   vpanic("iselIntExpr64");
+   vpanic("iselDblExpr");
 }
 
 
@@ -1015,9 +1070,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
          return;
       }
       if (ty == Ity_I8 || ty == Ity_I16) {
-         /* We're going to write to memory, so compute the RHS into an
-            X86RI. */
-         HReg r  = iselIntExpr_R(env, stmt->Ist.Put.expr);
+         HReg r = iselIntExpr_R(env, stmt->Ist.Put.expr);
          addInstr(env, X86Instr_Store(
                           ty==Ity_I8 ? 1 : 2,
                           r,
@@ -1064,6 +1117,12 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
          addInstr(env, mk_MOVsd_RR(rLo,dstLo) );
          return;
       }
+      if (ty == Ity_F64) {
+         HReg dst = lookupIRTemp(env, tmp);
+         HReg src = iselDblExpr(env, stmt->Ist.Tmp.expr);
+         addInstr(env, X86Instr_FpUnary(Xfp_MOV,src,dst));
+         return;
+      }
       break;
    }
 
@@ -1148,6 +1207,7 @@ HInstrArray* iselBB_X86 ( IRBB* bb, Addr64(*find_helper)(Char*) )
          case Ity_I32: hreg   = mkHReg(j++, HRcInt, True); break;
          case Ity_I64: hreg   = mkHReg(j++, HRcInt, True);
                        hregHI = mkHReg(j++, HRcInt, True); break;
+         case Ity_F64: hreg   = mkHReg(j++, HRcFloat, True); break;
          default: ppIRType(bb->tyenv->types[i]);
                   vpanic("iselBB: IRTemp type");
       }
index c28d12ae147ae26d1de9d91c5021bf5091764401..2ce5bd97e7eb0517d2ec36a93e8b77370c2117fc 100644 (file)
@@ -90,6 +90,7 @@ void ppIROp ( IROp op )
       case Iop_8Sto16:   vex_printf("8Sto16");  return;
       case Iop_8Sto32:   vex_printf("8Sto32");  return;
       case Iop_16Sto32:  vex_printf("16Sto32"); return;
+      case Iop_32Sto64:  vex_printf("32Sto64"); return;
       case Iop_32to8:    vex_printf("32to8");   return;
       case Iop_32to1:    vex_printf("32to1");   return;
       case Iop_1Uto8:    vex_printf("1Uto8");   return;
@@ -116,6 +117,9 @@ void ppIROp ( IROp op )
       case Iop_64to32:   vex_printf("64to32");   return;
       case Iop_32HLto64: vex_printf("32HLto64"); return;
 
+      case Iop_MulF64:   vex_printf("MulF64"); return;
+      case Iop_I64toF64: vex_printf("I64toF64"); return;
+
       default:           vpanic("ppIROp(1)");
    }
   
@@ -140,6 +144,12 @@ void ppIRExpr ( IRExpr* e )
       ppIRType(e->Iex.Get.ty);
       vex_printf(")");
       break;
+    case Iex_GetI:
+      vex_printf( "GETI[%d,%d](", e->Iex.GetI.minoff, e->Iex.GetI.maxoff);
+      ppIRExpr(e->Iex.GetI.offset);
+      vex_printf("):");
+      ppIRType(e->Iex.GetI.ty);
+      break;
     case Iex_Tmp:
       ppIRTemp(e->Iex.Tmp.tmp);
       break;
@@ -542,8 +552,12 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 )
       case Iop_8Sto32:  UNARY(Ity_I32,Ity_I8);
       case Iop_16Uto32: UNARY(Ity_I32,Ity_I16);
       case Iop_16Sto32: UNARY(Ity_I32,Ity_I16);
+      case Iop_32Sto64: UNARY(Ity_I64,Ity_I32);
       case Iop_32to8:   UNARY(Ity_I8,Ity_I32);
 
+      case Iop_MulF64:   BINARY(Ity_F64,Ity_F64,Ity_F64);
+      case Iop_I64toF64: UNARY(Ity_F64,Ity_I64);
+
       default:
          ppIROp(op);
          vpanic("typeOfPrimop");
@@ -618,6 +632,8 @@ IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
          return e->Iex.LDle.ty;
       case Iex_Get:
          return e->Iex.Get.ty;
+      case Iex_GetI:
+         return e->Iex.GetI.ty;
       case Iex_Tmp:
          return lookupIRTypeEnv(tyenv, e->Iex.Tmp.tmp);
       case Iex_Const:
@@ -646,6 +662,7 @@ Bool isPlausibleType ( IRType ty )
    switch (ty) {
       case Ity_INVALID: case Ity_Bit:
       case Ity_I8: case Ity_I16: case Ity_I32: case Ity_I64: 
+      case Ity_F32: case Ity_F64:
          return True;
       default: 
          return False;
@@ -692,6 +709,9 @@ void useBeforeDef_Expr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts )
    switch (expr->tag) {
       case Iex_Get: 
          break;
+      case Iex_GetI:
+         useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.offset,def_counts);
+         break;
       case Iex_Tmp: 
          if (expr->Iex.Tmp.tmp < 0 || expr->Iex.Tmp.tmp >= bb->tyenv->types_used)
             sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
@@ -760,6 +780,11 @@ void tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
       case Iex_Get:
       case Iex_Tmp:
          break;
+      case Iex_GetI:
+         tcExpr(bb,stmt, expr->Iex.GetI.offset, gWordTy );
+         if (typeOfIRExpr(tyenv,expr->Iex.GetI.offset) != Ity_I32)
+            sanityCheckFail(bb,stmt,"IRExpr.GetI.offset: not :: Ity_I32");
+         break;
       case Iex_Binop: {
          IRType ttarg1, ttarg2;
          tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
index 9dd701edef45bf7591702598807f1c29a1fdf849..880cfb8e9cf49235868bf85d63f8daffe1035f26 100644 (file)
@@ -98,7 +98,7 @@ typedef
       Iop_DivModS64to32, // ditto, signed
       /* Widening conversions */
       Iop_8Uto16, Iop_8Uto32, Iop_16Uto32,
-      Iop_8Sto16, Iop_8Sto32, Iop_16Sto32,
+      Iop_8Sto16, Iop_8Sto32, Iop_16Sto32, Iop_32Sto64,
       /* Narrowing conversions */
       Iop_32to8,
       /* 8 <-> 16 bit conversions */