]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add FP conditional move insn (host) and isel rule to generate it.
authorJulian Seward <jseward@acm.org>
Mon, 30 Aug 2004 17:54:18 +0000 (17:54 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 30 Aug 2004 17:54:18 +0000 (17:54 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@222

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

index ef53f788090e80c939f0d32fb30f3a392c787500..6171ad9ef499151bb2677ec21695de3ac4d2b87f 100644 (file)
@@ -580,6 +580,15 @@ X86Instr* X86Instr_FpI64 ( Bool toInt, HReg freg, HReg iregHi, HReg iregLo ) {
    i->Xin.FpI64.iregLo = iregLo;
    return i;
 }
+X86Instr* X86Instr_FpCMov ( X86CondCode cond, HReg src, HReg dst ) {
+   X86Instr* i        = LibVEX_Alloc(sizeof(X86Instr));
+   i->tag             = Xin_FpCMov;
+   i->Xin.FpCMov.cond = cond;
+   i->Xin.FpCMov.src  = src;
+   i->Xin.FpCMov.dst  = dst;
+   vassert(cond != Xcc_ALWAYS);
+   return i;
+}
 
 
 void ppX86Instr ( X86Instr* i ) {
@@ -725,6 +734,12 @@ void ppX86Instr ( X86Instr* i ) {
             ppHRegX86(i->Xin.FpI64.freg);
          }
          return;
+      case Xin_FpCMov:
+         vex_printf("gcmov%s ", showX86CondCode(i->Xin.FpCMov.cond));
+         ppHRegX86(i->Xin.FpCMov.src);
+         vex_printf(",");
+         ppHRegX86(i->Xin.FpCMov.dst);
+         return;
       default:
          vpanic("ppX86Instr");
    }
index b77e30d9c9b97e922c22e3b23fbc3d4e250b8997..9e15ac9e1c827d2c9ec896af92bdbca9dea4adef 100644 (file)
@@ -277,7 +277,8 @@ typedef
       Xin_FpUnary,   /* FP fake unary op */
       Xin_FpBinary,  /* FP fake binary op */
       Xin_FpLdSt,    /* FP fake load/store */
-      Xin_FpI64      /* FP fake to/from 64-bit signed int */
+      Xin_FpI64,     /* FP fake to/from 64-bit signed int */
+      Xin_FpCMov     /* FP fake floating point conditional move */
    }
    X86InstrTag;
 
@@ -396,7 +397,14 @@ typedef
             HReg iregHi;
             HReg iregLo;
          } FpI64;
-     } Xin;
+         /* Mov src to dst on the given condition, which may not
+            be the bogus Xcc_ALWAYS. */
+         struct {
+            X86CondCode cond;
+            HReg        src;
+            HReg        dst;
+         } FpCMov;
+      } Xin;
    }
    X86Instr;
 
@@ -421,6 +429,7 @@ extern X86Instr* X86Instr_FpBinary ( X86FpOp op, HReg srcL, HReg srcR, HReg dst
 extern X86Instr* X86Instr_FpLdSt   ( Bool isLoad, UChar sz, HReg reg, X86AMode* );
 extern X86Instr* X86Instr_FpI64    ( Bool toInt, HReg freg, 
                                      HReg iregHi, HReg iregLo );
+extern X86Instr* X86Instr_FpCMov   ( X86CondCode, HReg src, HReg dst );
 
 extern void ppX86Instr ( X86Instr* );
 
index 86b2c2d28b94744c2fcd4be3997949720d96ce8a..b1d1880d3f594a15aa87e29d1c8591167271dc24 100644 (file)
@@ -622,6 +622,22 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
       break;
    }
 
+   case Iex_GetI: {
+      /* First off, compute the index expression into an integer reg.
+         The referenced address will then be 0 + ebp + reg*1, that is,
+         an X86AMode_IRRS. */
+      HReg idx = iselIntExpr_R(env, e->Iex.GetI.offset);
+      HReg dst = newVRegI(env);
+      if (ty == Ity_I8) {
+         addInstr(env, 
+                  X86Instr_LoadEX( 
+                     1, False,
+                     X86AMode_IRRS(0, hregX86_EBP(), idx, 0),
+                     dst ));
+         return dst;
+      }
+   }
+
    /* --------- CCALL --------- */
    case Iex_CCall: {
       Addr64 helper;
@@ -1251,9 +1267,10 @@ static void iselIntExpr64_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
 
 static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
 {
-  //   MatchInfo mi;
+   //   MatchInfo mi;
+   IRType ty = typeOfIRExpr(env->type_env,e);
    vassert(e);
-   vassert(typeOfIRExpr(env->type_env,e) == Ity_F64);
+   vassert(ty == Ity_F64);
 
    if (e->tag == Iex_Tmp) {
       return lookupIRTemp(env, e->Iex.Tmp.tmp);
@@ -1288,8 +1305,8 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
 
    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. */
+         The referenced 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, 
@@ -1324,6 +1341,21 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
       }
    }
 
+   /* --------- MULTIPLEX --------- */
+   if (e->tag == Iex_Mux0X) {
+     if (ty == Ity_F64
+         && typeOfIRExpr(env->type_env,e->Iex.Mux0X.cond) == Ity_I8) {
+        HReg r8  = iselIntExpr_R(env, e->Iex.Mux0X.cond);
+        HReg rX  = iselDblExpr(env, e->Iex.Mux0X.exprX);
+        HReg r0  = iselDblExpr(env, e->Iex.Mux0X.expr0);
+        HReg dst = newVRegF(env);
+        addInstr(env, X86Instr_FpCMov(Xcc_ALWAYS,rX,dst));
+        addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8)));
+        addInstr(env, X86Instr_FpCMov(Xcc_Z,r0,dst));
+        return dst;
+      }
+   }
+
    ppIRExpr(e);
    vpanic("iselDblExpr");
 }