|
From: <sv...@va...> - 2006-03-07 01:15:55
|
Author: sewardj
Date: 2006-03-07 01:15:50 +0000 (Tue, 07 Mar 2006)
New Revision: 1593
Log:
Move the helper function for x86 'fxtract' to g_generic_x87.c so
it can be shared by the x86 and amd64 front ends, then use it to
implement fxtract on amd64.
Modified:
trunk/priv/guest-amd64/toIR.c
trunk/priv/guest-generic/g_generic_x87.c
trunk/priv/guest-generic/g_generic_x87.h
trunk/priv/guest-x86/gdefs.h
trunk/priv/guest-x86/ghelpers.c
trunk/priv/guest-x86/toIR.c
Modified: trunk/priv/guest-amd64/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-amd64/toIR.c 2006-03-07 00:24:59 UTC (rev 1592)
+++ trunk/priv/guest-amd64/toIR.c 2006-03-07 01:15:50 UTC (rev 1593)
@@ -154,6 +154,7 @@
#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"
=20
=20
@@ -4828,6 +4829,42 @@
fp_pop();
break;
=20
+ case 0xF4: { /* FXTRACT */
+ IRTemp argF =3D newTemp(Ity_F64);
+ IRTemp sigF =3D newTemp(Ity_F64);
+ IRTemp expF =3D newTemp(Ity_F64);
+ IRTemp argI =3D newTemp(Ity_I64);
+ IRTemp sigI =3D newTemp(Ity_I64);
+ IRTemp expI =3D newTemp(Ity_I64);
+ DIP("fxtract\n");
+ assign( argF, get_ST(0) );
+ assign( argI, unop(Iop_ReinterpF64asI64, mkexpr(argF)));
+ assign( sigI,=20
+ mkIRExprCCall(
+ Ity_I64, 0/*regparms*/,=20
+ "x86amd64g_calculate_FXTRACT",=20
+ &x86amd64g_calculate_FXTRACT,=20
+ mkIRExprVec_2( mkexpr(argI),=20
+ mkIRExpr_HWord(0)/*sig*/ ))=20
+ );
+ assign( expI,=20
+ mkIRExprCCall(
+ Ity_I64, 0/*regparms*/,=20
+ "x86amd64g_calculate_FXTRACT",=20
+ &x86amd64g_calculate_FXTRACT,=20
+ mkIRExprVec_2( mkexpr(argI),=20
+ mkIRExpr_HWord(1)/*exp*/ ))=20
+ );
+ 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 =3D newTemp(Ity_F64);
//.. IRTemp a2 =3D newTemp(Ity_F64);
Modified: trunk/priv/guest-generic/g_generic_x87.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-generic/g_generic_x87.c 2006-03-07 00:24:59 UTC (rev=
1592)
+++ trunk/priv/guest-generic/g_generic_x87.c 2006-03-07 01:15:50 UTC (rev=
1593)
@@ -437,6 +437,115 @@
}
=20
=20
+/* 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 =3D 0x7FF0000000000000ULL;
+ const ULong negInf =3D 0xFFF0000000000000ULL;
+ const ULong nanMask =3D 0x7FF0000000000000ULL;
+ const ULong qNan =3D 0x7FF8000000000000ULL;
+ const ULong posZero =3D 0x0000000000000000ULL;
+ const ULong negZero =3D 0x8000000000000000ULL;
+ const ULong bit51 =3D 1ULL << 51;
+ const ULong bit52 =3D 1ULL << 52;
+ const ULong sigMask =3D bit52 - 1;
+
+ /* Mimic PIII behaviour for special cases. */
+ if (arg =3D=3D posInf)
+ return getExp ? posInf : posInf;
+ if (arg =3D=3D negInf)
+ return getExp ? posInf : negInf;
+ if ((arg & nanMask) =3D=3D nanMask)
+ return qNan;
+ if (arg =3D=3D posZero)
+ return getExp ? negInf : posZero;
+ if (arg =3D=3D negZero)
+ return getExp ? negInf : negZero;
+
+ /* Split into sign, exponent and significand. */
+ sign =3D ((UInt)(arg >> 63)) & 1;
+
+ /* Mask off exponent & sign. uSig is in range 0 .. 2^52-1. */
+ uSig =3D arg & sigMask;
+
+ /* Get the exponent. */
+ sExp =3D ((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 =3D=3D 0) {
+ for (i =3D 0; i < 52; i++) {
+ if (uSig & bit51)
+ break;
+ uSig <<=3D 1;
+ sExp--;
+ }
+ uSig <<=3D 1;
+ } else {
+ /* Add the implied leading-1 in the significand. */
+ uSig |=3D bit52;
+ }
+
+ /* Roll in the sign. */
+ /* sSig =3D uSig; */
+ /* if (sign) sSig =3D- 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 =3D (Double)sSig; */
+ /* dSig /=3D 67108864.0; */ /* 2^26 */
+ /* dSig /=3D 67108864.0; */ /* 2^26 */
+ uSig &=3D sigMask;
+ uSig |=3D 0x3FF0000000000000ULL;
+ if (sign)
+ uSig ^=3D negZero;
+
+ /* Convert exp into a double. Also an exact conversion. */
+ /* dExp =3D (Double)(sExp - 1023); */
+ sExp -=3D 1023;
+ if (sExp =3D=3D 0) {
+ uExp =3D 0;
+ } else {
+ uExp =3D sExp < 0 ? -sExp : sExp;
+ expExp =3D 0x3FF +52;
+ /* 1 <=3D uExp <=3D 1074 */
+ /* Skip first 42 iterations of normalisation loop as we know they
+ will always happen */
+ uExp <<=3D 42;
+ expExp -=3D 42;
+ for (i =3D 0; i < 52-42; i++) {
+ if (uExp & bit52)
+ break;
+ uExp <<=3D 1;
+ expExp--;
+ }
+ uExp &=3D sigMask;
+ uExp |=3D ((ULong)expExp) << 52;
+ if (sExp < 0) uExp ^=3D negZero;
+ }
+
+ return getExp ? uExp : uSig;
+}
+
+
/*---------------------------------------------------------------*/
/*--- end guest-generic/h_generic_x87.c ---*/
/*---------------------------------------------------------------*/
Modified: trunk/priv/guest-generic/g_generic_x87.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-generic/g_generic_x87.h 2006-03-07 00:24:59 UTC (rev=
1592)
+++ trunk/priv/guest-generic/g_generic_x87.h 2006-03-07 01:15:50 UTC (rev=
1593)
@@ -105,7 +105,11 @@
#define FP_REG(ii) (10*(7-(ii)))
=20
=20
+/* Do the computations for x86/amd64 FXTRACT */
+extern ULong x86amd64g_calculate_FXTRACT ( ULong arg, HWord getExp );
=20
+
+
#endif /* ndef __G_GENERIC_X87_H */
=20
/*---------------------------------------------------------------*/
Modified: trunk/priv/guest-x86/gdefs.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-x86/gdefs.h 2006-03-07 00:24:59 UTC (rev 1592)
+++ trunk/priv/guest-x86/gdefs.h 2006-03-07 01:15:50 UTC (rev 1593)
@@ -120,9 +120,7 @@
=20
extern UInt x86g_create_mxcsr ( UInt sseround );
=20
-extern ULong x86g_calculate_FXTRACT ( ULong arg, UInt getExp );
=20
-
/* Translate a guest virtual_addr into a guest linear address by
consulting the supplied LDT/GDT structures. Their representation
must be as specified in pub/libvex_guest_x86.h. To indicate a
Modified: trunk/priv/guest-x86/ghelpers.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-x86/ghelpers.c 2006-03-07 00:24:59 UTC (rev 1592)
+++ trunk/priv/guest-x86/ghelpers.c 2006-03-07 01:15:50 UTC (rev 1593)
@@ -1243,115 +1243,6 @@
}
=20
=20
-/* 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 =3D 0x7FF0000000000000ULL;
- const ULong negInf =3D 0xFFF0000000000000ULL;
- const ULong nanMask =3D 0x7FF0000000000000ULL;
- const ULong qNan =3D 0x7FF8000000000000ULL;
- const ULong posZero =3D 0x0000000000000000ULL;
- const ULong negZero =3D 0x8000000000000000ULL;
- const ULong bit51 =3D 1ULL << 51;
- const ULong bit52 =3D 1ULL << 52;
- const ULong sigMask =3D bit52 - 1;
-
- /* Mimic PIII behaviour for special cases. */
- if (arg =3D=3D posInf)
- return getExp ? posInf : posInf;
- if (arg =3D=3D negInf)
- return getExp ? posInf : negInf;
- if ((arg & nanMask) =3D=3D nanMask)
- return qNan;
- if (arg =3D=3D posZero)
- return getExp ? negInf : posZero;
- if (arg =3D=3D negZero)
- return getExp ? negInf : negZero;
-
- /* Split into sign, exponent and significand. */
- sign =3D ((UInt)(arg >> 63)) & 1;
-
- /* Mask off exponent & sign. uSig is in range 0 .. 2^52-1. */
- uSig =3D arg & sigMask;
-
- /* Get the exponent. */
- sExp =3D ((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 =3D=3D 0) {
- for (i =3D 0; i < 52; i++) {
- if (uSig & bit51)
- break;
- uSig <<=3D 1;
- sExp--;
- }
- uSig <<=3D 1;
- } else {
- /* Add the implied leading-1 in the significand. */
- uSig |=3D bit52;
- }
-
- /* Roll in the sign. */
- /* sSig =3D uSig; */
- /* if (sign) sSig =3D- 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 =3D (Double)sSig; */
- /* dSig /=3D 67108864.0; */ /* 2^26 */
- /* dSig /=3D 67108864.0; */ /* 2^26 */
- uSig &=3D sigMask;
- uSig |=3D 0x3FF0000000000000ULL;
- if (sign)
- uSig ^=3D negZero;
-
- /* Convert exp into a double. Also an exact conversion. */
- /* dExp =3D (Double)(sExp - 1023); */
- sExp -=3D 1023;
- if (sExp =3D=3D 0) {
- uExp =3D 0;
- } else {
- uExp =3D sExp < 0 ? -sExp : sExp;
- expExp =3D 0x3FF +52;
- /* 1 <=3D uExp <=3D 1074 */
- /* Skip first 42 iterations of normalisation loop as we know they
- will always happen */
- uExp <<=3D 42;
- expExp -=3D 42;
- for (i =3D 0; i < 52-42; i++) {
- if (uExp & bit52)
- break;
- uExp <<=3D 1;
- expExp--;
- }
- uExp &=3D sigMask;
- uExp |=3D ((ULong)expExp) << 52;
- if (sExp < 0) uExp ^=3D negZero;
- }
-
- return getExp ? uExp : uSig;
-}
-
-
/*----------------------------------------------*/
/*--- The exported fns .. ---*/
/*----------------------------------------------*/
Modified: trunk/priv/guest-x86/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-x86/toIR.c 2006-03-07 00:24:59 UTC (rev 1592)
+++ trunk/priv/guest-x86/toIR.c 2006-03-07 01:15:50 UTC (rev 1593)
@@ -156,6 +156,7 @@
#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"
=20
=20
@@ -3944,17 +3945,21 @@
assign( argF, get_ST(0) );
assign( argI, unop(Iop_ReinterpF64asI64, mkexpr(argF)));
assign( sigI,=20
- mkIRExprCCall(Ity_I64, 0/*regparms*/,=20
- "x86g_calculate_FXTRACT",=20
- &x86g_calculate_FXTRACT,=20
- mkIRExprVec_2( mkexpr(argI),=20
- mkU32(0)/*sig*/ )) )=
;
+ mkIRExprCCall(
+ Ity_I64, 0/*regparms*/,=20
+ "x86amd64g_calculate_FXTRACT",=20
+ &x86amd64g_calculate_FXTRACT,=20
+ mkIRExprVec_2( mkexpr(argI),=20
+ mkIRExpr_HWord(0)/*sig*/ ))=20
+ );
assign( expI,=20
- mkIRExprCCall(Ity_I64, 0/*regparms*/,=20
- "x86g_calculate_FXTRACT",=20
- &x86g_calculate_FXTRACT,=20
- mkIRExprVec_2( mkexpr(argI),=20
- mkU32(1)/*exp*/ )) )=
;
+ mkIRExprCCall(
+ Ity_I64, 0/*regparms*/,=20
+ "x86amd64g_calculate_FXTRACT",=20
+ &x86amd64g_calculate_FXTRACT,=20
+ mkIRExprVec_2( mkexpr(argI),=20
+ mkIRExpr_HWord(1)/*exp*/ ))=20
+ );
assign( sigF, unop(Iop_ReinterpI64asF64, mkexpr(sigI)) );
assign( expF, unop(Iop_ReinterpI64asF64, mkexpr(expI)) );
/* exponent */
|