|
From: <sv...@va...> - 2006-02-04 15:20:19
|
Author: sewardj
Date: 2006-02-04 15:20:13 +0000 (Sat, 04 Feb 2006)
New Revision: 1565
Log:
More x86 tidying up following rounding changes.
Modified:
trunk/priv/guest-x86/toIR.c
trunk/priv/host-x86/isel.c
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-02-03 22:54:17 UTC (rev 1564)
+++ trunk/priv/guest-x86/toIR.c 2006-02-04 15:20:13 UTC (rev 1565)
@@ -3973,9 +3973,16 @@
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,=20
+ triop(Iop_PRem1F64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1),=20
+ mkexpr(a2)));
+ put_C3210(
+ triop(Iop_PRem1C3210F64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1),=20
+ mkexpr(a2)) );
break;
}
=20
@@ -3992,9 +3999,16 @@
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,=20
+ triop(Iop_PRemF64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1),=20
+ mkexpr(a2)));
+ put_C3210(=20
+ triop(Iop_PRemC3210F64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1),=20
+ mkexpr(a2)) );
break;
}
=20
Modified: trunk/priv/host-x86/isel.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/host-x86/isel.c 2006-02-03 22:54:17 UTC (rev 1564)
+++ trunk/priv/host-x86/isel.c 2006-02-04 15:20:13 UTC (rev 1565)
@@ -760,6 +760,34 @@
break;
}
=20
+ /* --------- 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 =3D=3D Iop_PRemC3210F64
+ || e->Iex.Triop.op =3D=3D Iop_PRem1C3210F64) {
+ HReg junk =3D newVRegF(env);
+ HReg dst =3D newVRegI(env);
+ HReg srcL =3D iselDblExpr(env, e->Iex.Triop.arg2);
+ HReg srcR =3D iselDblExpr(env, e->Iex.Triop.arg3);
+ /* XXXROUNDINGFIXME */
+ /* set roundingmode here */
+ addInstr(env, X86Instr_FpBinary(
+ e->Iex.Binop.op=3D=3DIop_PRemC3210F64=20
+ ? 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 @@
return dst;
}
=20
- /* C3210 flags following FPU partial remainder (fprem), both
- IEEE compliant (PREM1) and non-IEEE compliant (PREM). */
- if (e->Iex.Binop.op =3D=3D Iop_PRemC3210F64
- || e->Iex.Binop.op =3D=3D Iop_PRem1C3210F64) {
- HReg junk =3D newVRegF(env);
- HReg dst =3D newVRegI(env);
- HReg srcL =3D iselDblExpr(env, e->Iex.Binop.arg1);
- HReg srcR =3D iselDblExpr(env, e->Iex.Binop.arg2);
- addInstr(env, X86Instr_FpBinary(
- e->Iex.Binop.op=3D=3DIop_PRemC3210F64=20
- ? 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;
}
=20
@@ -2615,6 +2622,8 @@
case Iop_Yl2xF64: fpop =3D Xfp_YL2X; break;
case Iop_Yl2xp1F64: fpop =3D Xfp_YL2XP1; break;
case Iop_AtanF64: fpop =3D Xfp_ATAN; break;
+ case Iop_PRemF64: fpop =3D Xfp_PREM; break;
+ case Iop_PRem1F64: fpop =3D Xfp_PREM1; break;
default: break;
}
if (fpop !=3D Xfp_INVALID) {
@@ -2631,25 +2640,6 @@
}
}
=20
- if (e->tag =3D=3D Iex_Binop) {
- X86FpOp fpop =3D Xfp_INVALID;
- switch (e->Iex.Binop.op) {
- case Iop_PRemF64: fpop =3D Xfp_PREM; break;
- case Iop_PRem1F64: fpop =3D Xfp_PREM1; break;
- default: break;
- }
- if (fpop !=3D Xfp_INVALID) {
- HReg res =3D newVRegF(env);
- HReg srcL =3D iselDblExpr(env, e->Iex.Binop.arg1);
- HReg srcR =3D iselDblExpr(env, e->Iex.Binop.arg2);
- addInstr(env, X86Instr_FpBinary(fpop,srcL,srcR,res));
- if (fpop !=3D Xfp_ADD && fpop !=3D Xfp_SUB=20
- && fpop !=3D Xfp_MUL && fpop !=3D Xfp_DIV)
- roundToF64(env, res);
- return res;
- }
- }
-
if (e->tag =3D=3D Iex_Binop && e->Iex.Binop.op =3D=3D Iop_RoundF64toI=
nt) {
HReg rf =3D iselDblExpr(env, e->Iex.Binop.arg2);
HReg dst =3D newVRegF(env);
|