From: Julian Seward Date: Mon, 25 Oct 2004 02:27:01 +0000 (+0000) Subject: Add various FP insns apparently needed by mozilla. Not convinced X-Git-Tag: svn/VALGRIND_3_0_1^2~918 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=872b84bf692f78bb2ccbaade3103815b8f2048b6;p=thirdparty%2Fvalgrind.git Add various FP insns apparently needed by mozilla. Not convinced they are all correct. git-svn-id: svn://svn.valgrind.org/vex/trunk@416 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index e9b6672308..51de9d44b7 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -13,6 +13,7 @@ check flag settings for cmpxchg FUCOMI(P): what happens to A and S flags? Currently are forced to zero. + Fix CPUID, or more precisely, eflags bit 21 so it is changeable. x87 FP Limitations: * no FP exceptions, except for handling stack over/underflow @@ -20,6 +21,8 @@ * 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. + * some of the FCOM cases could do with testing -- not convinced + that the args are the right way round. */ /* Translates x86 code to IR. */ @@ -34,7 +37,7 @@ #include "guest-x86/gdefs.h" -#define RESTEER_THRESH 0; //10 +#define RESTEER_THRESH 10 /*------------------------------------------------------------*/ @@ -2267,7 +2270,7 @@ UInt dis_Grp1 ( UChar sorb, helper_ADC( sz, dst1, dst0, src ); } else if (gregOfRM(modrm) == 3 /* SBB */) { - vassert(0); + helper_SBB( sz, dst1, dst0, src ); } else { assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src))); if (isAddSub(op8)) @@ -3546,6 +3549,22 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) fp_do_op_mem_ST_0 ( addr, "mul", dis_buf, Iop_MulF64, False ); break; + case 3: /* FCOM single-real */ + DIP("fcomps %s\n", dis_buf); + /* This forces C1 to zero, which isn't right. */ + put_C3210( + binop( Iop_And32, + binop(Iop_Shl32, + binop(Iop_CmpF64, + get_ST(0), + unop(Iop_F32toF64, + loadLE(Ity_F32,mkexpr(addr)))), + mkU8(8)), + mkU32(0x4500) + )); + fp_pop(); + break; + case 4: /* FSUB single-real */ fp_do_op_mem_ST_0 ( addr, "sub", dis_buf, Iop_SubF64, False ); break; @@ -3579,7 +3598,22 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) fp_do_op_ST_ST ( "mul", Iop_MulF64, modrm - 0xC8, 0, False ); break; -#if 0 +#if 1 + /* Dunno if this is right */ + case 0xD0 ... 0xD7: /* FCOM %st(?),%st(0) */ + r_dst = (UInt)modrm - 0xD0; + DIP("fcom %%st(0),%%st(%d)\n", r_dst); + /* This forces C1 to zero, which isn't right. */ + put_C3210( + binop( Iop_And32, + binop(Iop_Shl32, + binop(Iop_CmpF64, get_ST(0), get_ST(r_dst)), + mkU8(8)), + mkU32(0x4500) + )); + break; +#endif +#if 1 /* Dunno if this is right */ case 0xD8 ... 0xDF: /* FCOMP %st(?),%st(0) */ r_dst = (UInt)modrm - 0xD8; @@ -4089,8 +4123,22 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) fp_do_op_mem_ST_0 ( addr, "mul", dis_buf, Iop_MulF64, True ); break; + case 2: /* FCOM double-real */ + DIP("fcoml %s\n", dis_buf); + /* This forces C1 to zero, which isn't right. */ + put_C3210( + binop( Iop_And32, + binop(Iop_Shl32, + binop(Iop_CmpF64, + get_ST(0), + loadLE(Ity_F64,mkexpr(addr))), + mkU8(8)), + mkU32(0x4500) + )); + break; + case 3: /* FCOMP double-real */ - DIP("fcomp %s\n", dis_buf); + DIP("fcompl %s\n", dis_buf); /* This forces C1 to zero, which isn't right. */ put_C3210( binop( Iop_And32, @@ -4273,6 +4321,20 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) fp_do_op_ST_ST ( "mul", Iop_MulF64, 0, modrm - 0xC8, True ); break; + case 0xD9: /* FCOMPP %st(0),%st(1) */ + DIP("fuompp %%st(0),%%st(1)\n"); + /* This forces C1 to zero, which isn't right. */ + put_C3210( + binop( Iop_And32, + binop(Iop_Shl32, + binop(Iop_CmpF64, get_ST(0), get_ST(1)), + mkU8(8)), + mkU32(0x4500) + )); + fp_pop(); + fp_pop(); + break; + case 0xE0 ... 0xE7: /* FSUBRP %st(0),%st(?) */ fp_do_oprev_ST_ST ( "subr", Iop_SubF64, 0, modrm - 0xE0, True ); break;