]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge r1593 (implement amd64 fxtract)
authorJulian Seward <jseward@acm.org>
Tue, 7 Mar 2006 01:40:44 +0000 (01:40 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 7 Mar 2006 01:40:44 +0000 (01:40 +0000)
git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_1_BRANCH@1594

VEX/priv/guest-amd64/toIR.c
VEX/priv/guest-generic/g_generic_x87.c
VEX/priv/guest-generic/g_generic_x87.h
VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c

index efa9747370f6880bf8646eae8b6e238c3ad43967..2de74470c08f821feebdb96c4a37b287a09af7ee 100644 (file)
 #include "main/vex_util.h"
 #include "main/vex_globals.h"
 #include "guest-generic/bb_to_IR.h"
+#include "guest-generic/g_generic_x87.h"
 #include "guest-amd64/gdefs.h"
 
 
@@ -4772,6 +4773,42 @@ ULong dis_FPU ( /*OUT*/Bool* decode_ok,
                fp_pop();
                break;
 
+            case 0xF4: { /* FXTRACT */
+               IRTemp argF = newTemp(Ity_F64);
+               IRTemp sigF = newTemp(Ity_F64);
+               IRTemp expF = newTemp(Ity_F64);
+               IRTemp argI = newTemp(Ity_I64);
+               IRTemp sigI = newTemp(Ity_I64);
+               IRTemp expI = newTemp(Ity_I64);
+               DIP("fxtract\n");
+               assign( argF, get_ST(0) );
+               assign( argI, unop(Iop_ReinterpF64asI64, mkexpr(argF)));
+               assign( sigI, 
+                       mkIRExprCCall(
+                          Ity_I64, 0/*regparms*/, 
+                          "x86amd64g_calculate_FXTRACT", 
+                          &x86amd64g_calculate_FXTRACT, 
+                          mkIRExprVec_2( mkexpr(argI), 
+                                         mkIRExpr_HWord(0)/*sig*/ )) 
+               );
+               assign( expI, 
+                       mkIRExprCCall(
+                          Ity_I64, 0/*regparms*/, 
+                          "x86amd64g_calculate_FXTRACT", 
+                          &x86amd64g_calculate_FXTRACT, 
+                          mkIRExprVec_2( mkexpr(argI), 
+                                         mkIRExpr_HWord(1)/*exp*/ )) 
+               );
+               assign( sigF, unop(Iop_ReinterpI64asF64, mkexpr(sigI)) );
+               assign( expF, unop(Iop_ReinterpI64asF64, mkexpr(expI)) );
+               /* exponent */
+               put_ST_UNCHECKED(0, mkexpr(expF) );
+               fp_push();
+               /* significand */
+               put_ST(0, mkexpr(sigF) );
+               break;
+            }
+
 //..             case 0xF5: { /* FPREM1 -- IEEE compliant */
 //..                IRTemp a1 = newTemp(Ity_F64);
 //..                IRTemp a2 = newTemp(Ity_F64);
index d574905230ca51d4667307cbf807c4cbf7bf7605..01b16b01121a3d082b2a35926b16dbb6d0503fa2 100644 (file)
@@ -437,6 +437,115 @@ void convert_f80le_to_f64le ( /*IN*/UChar* f80, /*OUT*/UChar* f64 )
 }
 
 
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
+/* Extract the signed significand or exponent component as per
+   fxtract.  Arg and result are doubles travelling under the guise of
+   ULongs.  Returns significand when getExp is zero and exponent
+   otherwise. */
+ULong x86amd64g_calculate_FXTRACT ( ULong arg, HWord getExp )
+{
+   ULong  uSig, uExp;
+   /* Long   sSig; */
+   Int    sExp, i;
+   UInt   sign, expExp;
+
+   /*
+    S  7FF    0------0   infinity
+    S  7FF    0X-----X   snan
+    S  7FF    1X-----X   qnan
+   */
+   const ULong posInf  = 0x7FF0000000000000ULL;
+   const ULong negInf  = 0xFFF0000000000000ULL;
+   const ULong nanMask = 0x7FF0000000000000ULL;
+   const ULong qNan    = 0x7FF8000000000000ULL;
+   const ULong posZero = 0x0000000000000000ULL;
+   const ULong negZero = 0x8000000000000000ULL;
+   const ULong bit51   = 1ULL << 51;
+   const ULong bit52   = 1ULL << 52;
+   const ULong sigMask = bit52 - 1;
+
+   /* Mimic PIII behaviour for special cases. */
+   if (arg == posInf)
+      return getExp ? posInf : posInf;
+   if (arg == negInf)
+      return getExp ? posInf : negInf;
+   if ((arg & nanMask) == nanMask)
+      return qNan;
+   if (arg == posZero)
+      return getExp ? negInf : posZero;
+   if (arg == negZero)
+      return getExp ? negInf : negZero;
+
+   /* Split into sign, exponent and significand. */
+   sign = ((UInt)(arg >> 63)) & 1;
+
+   /* Mask off exponent & sign. uSig is in range 0 .. 2^52-1. */
+   uSig = arg & sigMask;
+
+   /* Get the exponent. */
+   sExp = ((Int)(arg >> 52)) & 0x7FF;
+
+   /* Deal with denormals: if the exponent is zero, then the
+      significand cannot possibly be zero (negZero/posZero are handled
+      above).  Shift the significand left until bit 51 of it becomes
+      1, and decrease the exponent accordingly.
+   */
+   if (sExp == 0) {
+      for (i = 0; i < 52; i++) {
+         if (uSig & bit51)
+            break;
+         uSig <<= 1;
+         sExp--;
+      }
+      uSig <<= 1;
+   } else {
+      /* Add the implied leading-1 in the significand. */
+      uSig |= bit52;
+   }
+
+   /* Roll in the sign. */
+   /* sSig = uSig; */
+   /* if (sign) sSig =- sSig; */
+
+   /* Convert sig into a double.  This should be an exact conversion.
+      Then divide by 2^52, which should give a value in the range 1.0
+      to 2.0-epsilon, at least for normalised args. */
+   /* dSig = (Double)sSig; */
+   /* dSig /= 67108864.0;  */ /* 2^26 */
+   /* dSig /= 67108864.0;  */ /* 2^26 */
+   uSig &= sigMask;
+   uSig |= 0x3FF0000000000000ULL;
+   if (sign)
+      uSig ^= negZero;
+
+   /* Convert exp into a double.  Also an exact conversion. */
+   /* dExp = (Double)(sExp - 1023); */
+   sExp -= 1023;
+   if (sExp == 0) {
+      uExp = 0;
+   } else {
+      uExp   = sExp < 0 ? -sExp : sExp;
+      expExp = 0x3FF +52;
+      /* 1 <= uExp <= 1074 */
+      /* Skip first 42 iterations of normalisation loop as we know they
+         will always happen */
+      uExp <<= 42;
+      expExp -= 42;
+      for (i = 0; i < 52-42; i++) {
+         if (uExp & bit52)
+            break;
+         uExp <<= 1;
+         expExp--;
+      }
+      uExp &= sigMask;
+      uExp |= ((ULong)expExp) << 52;
+      if (sExp < 0) uExp ^= negZero;
+   }
+
+   return getExp ? uExp : uSig;
+}
+
+
 /*---------------------------------------------------------------*/
 /*--- end                       guest-generic/h_generic_x87.c ---*/
 /*---------------------------------------------------------------*/
index 51699606467efc372f2fe4550d46e5d497f1601f..357b1dee91f58c4512474f1ad60ab4199c2aa909 100644 (file)
@@ -105,6 +105,10 @@ typedef
 #define FP_REG(ii)    (10*(7-(ii)))
 
 
+/* Do the computations for x86/amd64 FXTRACT */
+extern ULong x86amd64g_calculate_FXTRACT ( ULong arg, HWord getExp );
+
+
 
 #endif /* ndef __G_GENERIC_X87_H */
 
index 235befc19b2aa32d9f895f2b2301d522ba3ed2f0..4e492df74460fef74a09a34c9ca9ab11adca9e01 100644 (file)
@@ -119,8 +119,6 @@ extern ULong x86g_check_ldmxcsr ( UInt mxcsr );
 
 extern UInt  x86g_create_mxcsr ( UInt sseround );
 
-extern ULong x86g_calculate_FXTRACT ( ULong arg, UInt getExp );
-
 
 /* Translate a guest virtual_addr into a guest linear address by
    consulting the supplied LDT/GDT structures.  Their representation
index d515fcaf3664dbe060cafb7aa36863e686aa1ebf..ce56bb3f6fe82885a709b4e21911a5891a42f4f7 100644 (file)
@@ -1243,115 +1243,6 @@ void x86g_dirtyhelper_storeF80le ( UInt addrU, ULong f64 )
 }
 
 
-/* CALLED FROM GENERATED CODE: CLEAN HELPER */
-/* Extract the signed significand or exponent component as per
-   fxtract.  Arg and result are doubles travelling under the guise of
-   ULongs.  Returns significand when getExp is zero and exponent
-   otherwise. */
-ULong x86g_calculate_FXTRACT ( ULong arg, UInt getExp )
-{
-   ULong  uSig, uExp;
-   /* Long   sSig; */
-   Int    sExp, i;
-   UInt   sign, expExp;
-
-   /*
-    S  7FF    0------0   infinity
-    S  7FF    0X-----X   snan
-    S  7FF    1X-----X   qnan
-   */
-   const ULong posInf  = 0x7FF0000000000000ULL;
-   const ULong negInf  = 0xFFF0000000000000ULL;
-   const ULong nanMask = 0x7FF0000000000000ULL;
-   const ULong qNan    = 0x7FF8000000000000ULL;
-   const ULong posZero = 0x0000000000000000ULL;
-   const ULong negZero = 0x8000000000000000ULL;
-   const ULong bit51   = 1ULL << 51;
-   const ULong bit52   = 1ULL << 52;
-   const ULong sigMask = bit52 - 1;
-
-   /* Mimic PIII behaviour for special cases. */
-   if (arg == posInf)
-      return getExp ? posInf : posInf;
-   if (arg == negInf)
-      return getExp ? posInf : negInf;
-   if ((arg & nanMask) == nanMask)
-      return qNan;
-   if (arg == posZero)
-      return getExp ? negInf : posZero;
-   if (arg == negZero)
-      return getExp ? negInf : negZero;
-
-   /* Split into sign, exponent and significand. */
-   sign = ((UInt)(arg >> 63)) & 1;
-
-   /* Mask off exponent & sign. uSig is in range 0 .. 2^52-1. */
-   uSig = arg & sigMask;
-
-   /* Get the exponent. */
-   sExp = ((Int)(arg >> 52)) & 0x7FF;
-
-   /* Deal with denormals: if the exponent is zero, then the
-      significand cannot possibly be zero (negZero/posZero are handled
-      above).  Shift the significand left until bit 51 of it becomes
-      1, and decrease the exponent accordingly.
-   */
-   if (sExp == 0) {
-      for (i = 0; i < 52; i++) {
-         if (uSig & bit51)
-            break;
-         uSig <<= 1;
-         sExp--;
-      }
-      uSig <<= 1;
-   } else {
-      /* Add the implied leading-1 in the significand. */
-      uSig |= bit52;
-   }
-
-   /* Roll in the sign. */
-   /* sSig = uSig; */
-   /* if (sign) sSig =- sSig; */
-
-   /* Convert sig into a double.  This should be an exact conversion.
-      Then divide by 2^52, which should give a value in the range 1.0
-      to 2.0-epsilon, at least for normalised args. */
-   /* dSig = (Double)sSig; */
-   /* dSig /= 67108864.0;  */ /* 2^26 */
-   /* dSig /= 67108864.0;  */ /* 2^26 */
-   uSig &= sigMask;
-   uSig |= 0x3FF0000000000000ULL;
-   if (sign)
-      uSig ^= negZero;
-
-   /* Convert exp into a double.  Also an exact conversion. */
-   /* dExp = (Double)(sExp - 1023); */
-   sExp -= 1023;
-   if (sExp == 0) {
-      uExp = 0;
-   } else {
-      uExp   = sExp < 0 ? -sExp : sExp;
-      expExp = 0x3FF +52;
-      /* 1 <= uExp <= 1074 */
-      /* Skip first 42 iterations of normalisation loop as we know they
-         will always happen */
-      uExp <<= 42;
-      expExp -= 42;
-      for (i = 0; i < 52-42; i++) {
-         if (uExp & bit52)
-            break;
-         uExp <<= 1;
-         expExp--;
-      }
-      uExp &= sigMask;
-      uExp |= ((ULong)expExp) << 52;
-      if (sExp < 0) uExp ^= negZero;
-   }
-
-   return getExp ? uExp : uSig;
-}
-
-
 /*----------------------------------------------*/
 /*--- The exported fns ..                    ---*/
 /*----------------------------------------------*/
index 8f759ccd909351ef39d4305fbd1da9706c0835f8..b53dba09725140a37a44d399164563c57593d758 100644 (file)
 #include "main/vex_util.h"
 #include "main/vex_globals.h"
 #include "guest-generic/bb_to_IR.h"
+#include "guest-generic/g_generic_x87.h"
 #include "guest-x86/gdefs.h"
 
 
@@ -3886,17 +3887,21 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, Int delta )
                assign( argF, get_ST(0) );
                assign( argI, unop(Iop_ReinterpF64asI64, mkexpr(argF)));
                assign( sigI, 
-                       mkIRExprCCall(Ity_I64, 0/*regparms*/, 
-                                     "x86g_calculate_FXTRACT", 
-                                     &x86g_calculate_FXTRACT, 
-                                     mkIRExprVec_2( mkexpr(argI), 
-                                                    mkU32(0)/*sig*/ )) );
+                       mkIRExprCCall(
+                          Ity_I64, 0/*regparms*/, 
+                          "x86amd64g_calculate_FXTRACT", 
+                          &x86amd64g_calculate_FXTRACT, 
+                          mkIRExprVec_2( mkexpr(argI), 
+                                         mkIRExpr_HWord(0)/*sig*/ )) 
+               );
                assign( expI, 
-                       mkIRExprCCall(Ity_I64, 0/*regparms*/, 
-                                     "x86g_calculate_FXTRACT", 
-                                     &x86g_calculate_FXTRACT, 
-                                     mkIRExprVec_2( mkexpr(argI), 
-                                                    mkU32(1)/*exp*/ )) );
+                       mkIRExprCCall(
+                          Ity_I64, 0/*regparms*/, 
+                          "x86amd64g_calculate_FXTRACT", 
+                          &x86amd64g_calculate_FXTRACT, 
+                          mkIRExprVec_2( mkexpr(argI), 
+                                         mkIRExpr_HWord(1)/*exp*/ )) 
+               );
                assign( sigF, unop(Iop_ReinterpI64asF64, mkexpr(sigI)) );
                assign( expF, unop(Iop_ReinterpI64asF64, mkexpr(expI)) );
                /* exponent */