From: Julian Seward Date: Sat, 16 Oct 2004 20:51:05 +0000 (+0000) Subject: Clear C2 after sin/cos/tan/sincos. This is needed to make the glibc X-Git-Tag: svn/VALGRIND_3_0_1^2~975 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1f53d5832a3025ca2a925bde3aeec7eba7f19ce;p=thirdparty%2Fvalgrind.git Clear C2 after sin/cos/tan/sincos. This is needed to make the glibc versions of these functions work properly. git-svn-id: svn://svn.valgrind.org/vex/trunk@359 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 144ef2a87e..1477f5e505 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -14,6 +14,13 @@ check 16/8 bit div/idiv FUCOMI(P): what happens to A and S flags? Currently are forced to zero. + + Limitations: + * no FP exceptions, except for handling stack over/underflow + * FP rounding mode observed only for float->int conversions + * FP sin/cos/tan/sincos: C2 flag is always cleared. IOW the + simulation claims the argument is in-range (-2^63 <= arg <= 2^63) + even when it isn't. */ /* Translates x86 code to IR. */ @@ -3161,13 +3168,6 @@ static IRExpr* get_ST ( Int i ) static void fp_push ( void ) { -#if 0 - put_ftop( - binop(Iop_And32, - binop(Iop_Sub32, get_ftop(), mkU32(1)), - mkU32(7)) - ); -#endif put_ftop( binop(Iop_Sub32, get_ftop(), mkU32(1)) ); } @@ -3177,16 +3177,18 @@ static void fp_push ( void ) static void fp_pop ( void ) { put_ST_TAG(0, mkU8(0)); -#if 0 - put_ftop( - binop(Iop_And32, - binop(Iop_Add32, get_ftop(), mkU32(1)), - mkU32(7)) - ); -#endif put_ftop( binop(Iop_Add32, get_ftop(), mkU32(1)) ); } +/* Clear the C2 bit of the FPU status register, for + sin/cos/tan/sincos. */ + +static void clear_C2 ( void ) +{ + put_C3210( binop(Iop_And32, get_C3210(), mkU32(~FC_MASK_C2)) ); +} + + /* ------------------------------------------------------- */ /* Given all that stack-mangling junk, we can now go ahead and describe FP instructions. @@ -3535,8 +3537,7 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) put_ST_UNCHECKED(0, unop(Iop_TanF64, get_ST(0))); fp_push(); put_ST(0, IRExpr_Const(IRConst_F64(1.0))); - /* Should we mess with C3210 here? The fact that we - don't is a hack. */ + clear_C2(); /* HACK */ break; case 0xF3: /* FPATAN */ @@ -3601,11 +3602,13 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) case 0xFE: /* FSIN */ DIP("fsin\n"); put_ST_UNCHECKED(0, unop(Iop_SinF64, get_ST(0))); + clear_C2(); /* HACK */ break; case 0xFF: /* FCOS */ DIP("fcos\n"); put_ST_UNCHECKED(0, unop(Iop_CosF64, get_ST(0))); + clear_C2(); /* HACK */ break; default: