]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fill in enough to get through a simple x86 FP processing program
authorJulian Seward <jseward@acm.org>
Tue, 31 Aug 2004 11:47:54 +0000 (11:47 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 31 Aug 2004 11:47:54 +0000 (11:47 +0000)
without dying.  Doesn't produce the right answer (yet).

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

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

index 6171ad9ef499151bb2677ec21695de3ac4d2b87f..0c3bf5e9cac00e646590a769c984406515bfb0b5 100644 (file)
@@ -852,6 +852,10 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
             addHRegUse(u, HRmRead, i->Xin.FpI64.iregLo);
          }
          return;
+      case Xin_FpCMov:
+         addHRegUse(u, HRmRead, i->Xin.FpCMov.src);
+         addHRegUse(u, HRmModify, i->Xin.FpCMov.dst);
+         return;
       default:
          ppX86Instr(i);
          vpanic("getRegUsage_X86Instr");
@@ -933,6 +937,10 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i)
          mapReg(m, &i->Xin.FpI64.iregHi);
          mapReg(m, &i->Xin.FpI64.iregLo);
          return;
+      case Xin_FpCMov:
+         mapReg(m, &i->Xin.FpCMov.src);
+         mapReg(m, &i->Xin.FpCMov.dst);
+         return;
       default:
          ppX86Instr(i);
          vpanic("mapRegs_X86Instr");
@@ -968,7 +976,7 @@ Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst )
 
 
 /* x86 spill/reload using the hacked104 testbed.  Spill slots
-   start at word 51, and there are 24 in total. 
+   start at word 53, and there are 100 in total. 
 */
 
 X86Instr* genSpill_X86 ( HReg rreg, Int offset )
@@ -1752,6 +1760,21 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
         goto done;
      }
 
+   case Xin_FpCMov:
+      /* jmp fwds if !condition */
+      *p++ = 0x70 + (i->Xin.FpCMov.cond ^ 1);
+      *p++ = 0; /* # of bytes in the next bit, which we don't know yet */
+      ptmp = p;
+
+      /* ffree %st7 ; fld %st(src) ; fstp %st(1+dst) */
+      p = do_ffree_st7(p);
+      p = do_fld_st(p, 0+hregNumber(i->Xin.FpCMov.src));
+      p = do_fstp_st(p, 1+hregNumber(i->Xin.FpCMov.dst));
+
+      /* Fill in the jump offset. */
+      *(ptmp-1) = p - ptmp;
+      goto done;
+
    default: 
       goto bad;
    }
index 9e15ac9e1c827d2c9ec896af92bdbca9dea4adef..145358f28e262fcf1e7d495fa078656598cc55d5 100644 (file)
@@ -278,7 +278,7 @@ typedef
       Xin_FpBinary,  /* FP fake binary op */
       Xin_FpLdSt,    /* FP fake load/store */
       Xin_FpI64,     /* FP fake to/from 64-bit signed int */
-      Xin_FpCMov     /* FP fake floating point conditional move */
+      Xin_FpCMov     /* FP fake floating point (un)conditional move */
    }
    X86InstrTag;
 
index b1d1880d3f594a15aa87e29d1c8591167271dc24..146077f491a335cac88b11668c51f32c1d4b35d1 100644 (file)
@@ -1265,6 +1265,24 @@ static void iselIntExpr64_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
    real or virtual; in any case it must not be changed by subsequent
    code emitted by the caller.  */
 
+/* IEEE 754 formats.  From http://www.freesoft.org/CIE/RFC/1832/32.htm:
+
+    Type                  S (1 bit)   E (11 bits)   F (52 bits)
+    ----                  ---------   -----------   -----------
+    signalling NaN        u           2047 (max)    .0uuuuu---u
+                                                    (with at least
+                                                     one 1 bit)
+    quiet NaN             u           2047 (max)    .1uuuuu---u
+
+    negative infinity     1           2047 (max)    .000000---0
+
+    positive infinity     0           2047 (max)    .000000---0
+
+    negative zero         1           0             .000000---0
+
+    positive zero         0           0             .000000---0
+*/
+
 static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
 {
    //   MatchInfo mi;
@@ -1282,8 +1300,23 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
       vassert(sizeof(u) == 8);
       vassert(sizeof(u.i64) == 8);
       vassert(sizeof(u.f64) == 8);
-      vassert(e->Iex.Const.con->tag == Ico_F64);
-      u.f64 = e->Iex.Const.con->Ico.F64;
+
+      if (e->Iex.Const.con->tag == Ico_F64) {
+         u.f64 = e->Iex.Const.con->Ico.F64;
+      } 
+      else if (e->Iex.Const.con->tag == Ico_NaN64) {
+         /* QNaN is 0 2047 1 0(51times) 
+            == 0b 11111111111b 1 0(51times)
+            == 0x7FF8 0000 0000 0000
+         */
+         /* Since we're running on a little-endian target, and
+            generating code for one: */
+         u.i64[1] = 0x7FF80000;
+         u.i64[0] = 0x00000000;
+      }
+      else
+         vpanic("iselDblExpr(x86): const");
+
       addInstr(env, X86Instr_Push(X86RMI_Imm(u.i64[1])));
       addInstr(env, X86Instr_Push(X86RMI_Imm(u.i64[0])));
       addInstr(env, X86Instr_FpLdSt(True/*load*/, 8, freg, 
@@ -1349,7 +1382,7 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e )
         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_FpUnary(Xfp_MOV,rX,dst));
         addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8)));
         addInstr(env, X86Instr_FpCMov(Xcc_Z,r0,dst));
         return dst;
@@ -1444,6 +1477,14 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
                              X86AMode_IRRS(0, hregX86_EBP(), idx, 0)) );
          return;
       }
+      if (ty == Ity_I8) {
+         HReg r = iselIntExpr_R(env, stmt->Ist.Put.expr);
+         addInstr(env, X86Instr_Store(
+                          1,
+                          r,
+                          X86AMode_IRRS(0, hregX86_EBP(), idx, 0)) );
+         return;
+      }
       break;
    }