From: Julian Seward Date: Sat, 4 Feb 2006 15:20:13 +0000 (+0000) Subject: More x86 tidying up following rounding changes. X-Git-Tag: svn/VALGRIND_3_2_3^2~96 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=921541e7b000af56841355d005511ae1bdf70d12;p=thirdparty%2Fvalgrind.git More x86 tidying up following rounding changes. git-svn-id: svn://svn.valgrind.org/vex/trunk@1565 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index d9aa5cb2a8..f8b22d9379 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -3973,9 +3973,16 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, Int delta ) to get the C3210 flag values. */ assign( a1, get_ST(0) ); assign( a2, get_ST(1) ); - put_ST_UNCHECKED(0, binop(Iop_PRem1F64, - mkexpr(a1), mkexpr(a2))); - put_C3210( binop(Iop_PRem1C3210F64, mkexpr(a1), mkexpr(a2)) ); + put_ST_UNCHECKED(0, + triop(Iop_PRem1F64, + get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */ + mkexpr(a1), + mkexpr(a2))); + put_C3210( + triop(Iop_PRem1C3210F64, + get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */ + mkexpr(a1), + mkexpr(a2)) ); break; } @@ -3992,9 +3999,16 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, Int delta ) to get the C3210 flag values. */ assign( a1, get_ST(0) ); assign( a2, get_ST(1) ); - put_ST_UNCHECKED(0, binop(Iop_PRemF64, - mkexpr(a1), mkexpr(a2))); - put_C3210( binop(Iop_PRemC3210F64, mkexpr(a1), mkexpr(a2)) ); + put_ST_UNCHECKED(0, + triop(Iop_PRemF64, + get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */ + mkexpr(a1), + mkexpr(a2))); + put_C3210( + triop(Iop_PRemC3210F64, + get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */ + mkexpr(a1), + mkexpr(a2)) ); break; } diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index b30a215b35..0d55f30a31 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -760,6 +760,34 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) break; } + /* --------- TERNARY OP --------- */ + case Iex_Triop: { + /* C3210 flags following FPU partial remainder (fprem), both + IEEE compliant (PREM1) and non-IEEE compliant (PREM). */ + if (e->Iex.Triop.op == Iop_PRemC3210F64 + || e->Iex.Triop.op == Iop_PRem1C3210F64) { + HReg junk = newVRegF(env); + HReg dst = newVRegI(env); + HReg srcL = iselDblExpr(env, e->Iex.Triop.arg2); + HReg srcR = iselDblExpr(env, e->Iex.Triop.arg3); + /* XXXROUNDINGFIXME */ + /* set roundingmode here */ + addInstr(env, X86Instr_FpBinary( + e->Iex.Binop.op==Iop_PRemC3210F64 + ? Xfp_PREM : Xfp_PREM1, + srcL,srcR,junk + )); + /* The previous pseudo-insn will have left the FPU's C3210 + flags set correctly. So bag them. */ + addInstr(env, X86Instr_FpStSW_AX()); + addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), dst)); + addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(0x4700), dst)); + return dst; + } + + break; + } + /* --------- BINARY OP --------- */ case Iex_Binop: { X86AluOp aluOp; @@ -972,27 +1000,6 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) return dst; } - /* C3210 flags following FPU partial remainder (fprem), both - IEEE compliant (PREM1) and non-IEEE compliant (PREM). */ - if (e->Iex.Binop.op == Iop_PRemC3210F64 - || e->Iex.Binop.op == Iop_PRem1C3210F64) { - HReg junk = newVRegF(env); - HReg dst = newVRegI(env); - HReg srcL = iselDblExpr(env, e->Iex.Binop.arg1); - HReg srcR = iselDblExpr(env, e->Iex.Binop.arg2); - addInstr(env, X86Instr_FpBinary( - e->Iex.Binop.op==Iop_PRemC3210F64 - ? Xfp_PREM : Xfp_PREM1, - srcL,srcR,junk - )); - /* The previous pseudo-insn will have left the FPU's C3210 - flags set correctly. So bag them. */ - addInstr(env, X86Instr_FpStSW_AX()); - addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), dst)); - addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(0x4700), dst)); - return dst; - } - break; } @@ -2615,6 +2622,8 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) case Iop_Yl2xF64: fpop = Xfp_YL2X; break; case Iop_Yl2xp1F64: fpop = Xfp_YL2XP1; break; case Iop_AtanF64: fpop = Xfp_ATAN; break; + case Iop_PRemF64: fpop = Xfp_PREM; break; + case Iop_PRem1F64: fpop = Xfp_PREM1; break; default: break; } if (fpop != Xfp_INVALID) { @@ -2631,25 +2640,6 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) } } - if (e->tag == Iex_Binop) { - X86FpOp fpop = Xfp_INVALID; - switch (e->Iex.Binop.op) { - case Iop_PRemF64: fpop = Xfp_PREM; break; - case Iop_PRem1F64: fpop = Xfp_PREM1; break; - default: break; - } - if (fpop != Xfp_INVALID) { - HReg res = newVRegF(env); - HReg srcL = iselDblExpr(env, e->Iex.Binop.arg1); - HReg srcR = iselDblExpr(env, e->Iex.Binop.arg2); - addInstr(env, X86Instr_FpBinary(fpop,srcL,srcR,res)); - if (fpop != Xfp_ADD && fpop != Xfp_SUB - && fpop != Xfp_MUL && fpop != Xfp_DIV) - roundToF64(env, res); - return res; - } - } - if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_RoundF64toInt) { HReg rf = iselDblExpr(env, e->Iex.Binop.arg2); HReg dst = newVRegF(env);