|
From: <sv...@va...> - 2006-02-06 22:18:46
|
Author: sewardj
Date: 2006-02-06 22:18:38 +0000 (Mon, 06 Feb 2006)
New Revision: 1569
Log:
Redo x86g_calculate_FXTRACT to only use integer arithmetic.
Modified:
trunk/priv/guest-x86/ghelpers.c
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-02-06 03:58:31 UTC (rev 1568)
+++ trunk/priv/guest-x86/ghelpers.c 2006-02-06 22:18:38 UTC (rev 1569)
@@ -1250,11 +1250,10 @@
otherwise. */
ULong x86g_calculate_FXTRACT ( ULong arg, UInt getExp )
{
- ULong uSig;
- Long sSig;
- Double dSig, dExp;
+ ULong uSig, uExp;
+ /* Long sSig; */
Int sExp, i;
- UInt sign;
+ UInt sign, expExp;
=20
/*
S 7FF 0------0 infinity
@@ -1269,6 +1268,7 @@
const ULong negZero =3D 0x8000000000000000ULL;
const ULong bit51 =3D 1ULL << 51;
const ULong bit52 =3D 1ULL << 52;
+ const ULong sigMask =3D bit52 - 1;
=20
/* Mimic PIII behaviour for special cases. */
if (arg =3D=3D posInf)
@@ -1286,7 +1286,7 @@
sign =3D ((UInt)(arg >> 63)) & 1;
=20
/* Mask off exponent & sign. uSig is in range 0 .. 2^52-1. */
- uSig =3D arg & (bit52 - 1);
+ uSig =3D arg & sigMask;
=20
/* Get the exponent. */
sExp =3D ((Int)(arg >> 52)) & 0x7FF;
@@ -1310,20 +1310,45 @@
}
=20
/* Roll in the sign. */
- sSig =3D uSig;
- if (sign) sSig =3D- sSig;
+ /* sSig =3D uSig; */
+ /* if (sign) sSig =3D- sSig; */
=20
/* 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 */
+ /* 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;
=20
/* Convert exp into a double. Also an exact conversion. */
- dExp =3D (Double)(sExp - 1023);
+ /* 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;
+ }
=20
- return *(ULong*)(getExp ? &dExp : &dSig);
+ return getExp ? uExp : uSig;
}
=20
=20
@@ -1442,7 +1467,7 @@
{
Int stno, preg;
UInt tag;
- Double* vexRegs =3D (Double*)(&vex_state->guest_FPREG[0]);
+ ULong* vexRegs =3D (ULong*)(&vex_state->guest_FPREG[0]);
UChar* vexTags =3D (UChar*)(&vex_state->guest_FPTAG[0]);
Fpu_State* x87 =3D (Fpu_State*)x87_state;
UInt ftop =3D (x87->env[FP_ENV_STAT] >> 11) & 7;
@@ -1464,7 +1489,7 @@
of sync, in that it thinks all FP registers are defined by
this helper, but in reality some have not been updated. */
if (moveRegs)
- vexRegs[preg] =3D 0.0;
+ vexRegs[preg] =3D 0; /* IEEE754 64-bit zero */
vexTags[preg] =3D 0;
} else {
/* register is non-empty */
@@ -1502,7 +1527,7 @@
{
Int i, stno, preg;
UInt tagw;
- Double* vexRegs =3D (Double*)(&vex_state->guest_FPREG[0]);
+ ULong* vexRegs =3D (ULong*)(&vex_state->guest_FPREG[0]);
UChar* vexTags =3D (UChar*)(&vex_state->guest_FPTAG[0]);
Fpu_State* x87 =3D (Fpu_State*)x87_state;
UInt ftop =3D vex_state->guest_FTOP;
|