|
From: <sv...@va...> - 2006-02-05 16:06:33
|
Author: sewardj
Date: 2006-02-05 16:06:26 +0000 (Sun, 05 Feb 2006)
New Revision: 1567
Log:
Fixups following recent FP rounding mode changes.
Modified:
trunk/priv/guest-amd64/toIR.c
trunk/priv/host-amd64/hdefs.h
trunk/priv/host-amd64/isel.c
Modified: trunk/priv/guest-amd64/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-amd64/toIR.c 2006-02-04 15:24:00 UTC (rev 1566)
+++ trunk/priv/guest-amd64/toIR.c 2006-02-05 16:06:26 UTC (rev 1567)
@@ -235,6 +235,11 @@
return IRExpr_Binop(op, a1, a2);
}
=20
+static IRExpr* triop ( IROp op, IRExpr* a1, IRExpr* a2, IRExpr* a3 )
+{
+ return IRExpr_Triop(op, a1, a2, a3);
+}
+
static IRExpr* mkexpr ( IRTemp tmp )
{
return IRExpr_Tmp(tmp);
@@ -4091,7 +4096,12 @@
return binop( Iop_And32, get_fpround(), mkU32(3) );
}
=20
+static IRExpr* /* :: Ity_I32 */ get_FAKE_roundingmode ( void )
+{
+ return mkU32(Irrm_NEAREST);
+}
=20
+
/* --------- Get/set FP register tag bytes. --------- */
=20
/* Given i, and some expression e, generate 'ST_TAG(i) =3D e'. */
@@ -4212,13 +4222,15 @@
DIP("f%s%c %s\n", op_txt, dbl?'l':'s', dis_buf);
if (dbl) {
put_ST_UNCHECKED(0,=20
- binop( op,=20
+ triop( op,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
get_ST(0),=20
loadLE(Ity_F64,mkexpr(addr))
));
} else {
put_ST_UNCHECKED(0,=20
- binop( op,=20
+ triop( op,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
get_ST(0),=20
unop(Iop_F32toF64, loadLE(Ity_F32,mkexpr(addr)))
));
@@ -4236,13 +4248,15 @@
DIP("f%s%c %s\n", op_txt, dbl?'l':'s', dis_buf);
if (dbl) {
put_ST_UNCHECKED(0,=20
- binop( op,=20
+ triop( op,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
loadLE(Ity_F64,mkexpr(addr)),
get_ST(0)
));
} else {
put_ST_UNCHECKED(0,=20
- binop( op,=20
+ triop( op,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
unop(Iop_F32toF64, loadLE(Ity_F32,mkexpr(addr))),
get_ST(0)
));
@@ -4260,7 +4274,10 @@
DIP("f%s%s st(%u), st(%u)\n", op_txt, pop_after?"p":"", st_src, st_ds=
t );
put_ST_UNCHECKED(=20
st_dst,=20
- binop(op, get_ST(st_dst), get_ST(st_src) )=20
+ triop( op,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(st_dst),=20
+ get_ST(st_src) )=20
);
if (pop_after)
fp_pop();
@@ -4276,7 +4293,10 @@
DIP("f%s%s st(%u), st(%u)\n", op_txt, pop_after?"p":"", st_src, st_ds=
t );
put_ST_UNCHECKED(=20
st_dst,=20
- binop(op, get_ST(st_src), get_ST(st_dst) )=20
+ triop( op,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(st_src),=20
+ get_ST(st_dst) )=20
);
if (pop_after)
fp_pop();
@@ -4755,19 +4775,28 @@
=20
case 0xF0: /* F2XM1 */
DIP("f2xm1\n");
- put_ST_UNCHECKED(0, unop(Iop_2xm1F64, get_ST(0)));
+ put_ST_UNCHECKED(0,=20
+ binop(Iop_2xm1F64,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(0)));
break;
=20
case 0xF1: /* FYL2X */
DIP("fyl2x\n");
- put_ST_UNCHECKED(1, binop(Iop_Yl2xF64,
- get_ST(1), get_ST(0)));
+ put_ST_UNCHECKED(1,=20
+ triop(Iop_Yl2xF64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(1),=20
+ get_ST(0)));
fp_pop();
break;
=20
case 0xF2: /* FPTAN */
DIP("ftan\n");
- put_ST_UNCHECKED(0, unop(Iop_TanF64, get_ST(0)));
+ put_ST_UNCHECKED(0,=20
+ binop(Iop_TanF64,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(0)));
fp_push();
put_ST(0, IRExpr_Const(IRConst_F64(1.0)));
clear_C2(); /* HACK */
@@ -4775,8 +4804,11 @@
=20
case 0xF3: /* FPATAN */
DIP("fpatan\n");
- put_ST_UNCHECKED(1, binop(Iop_AtanF64,
- get_ST(1), get_ST(0)));
+ put_ST_UNCHECKED(1,=20
+ triop(Iop_AtanF64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(1),=20
+ get_ST(0)));
fp_pop();
break;
=20
@@ -4815,23 +4847,35 @@
//..=20
case 0xF9: /* FYL2XP1 */
DIP("fyl2xp1\n");
- put_ST_UNCHECKED(1, binop(Iop_Yl2xp1F64,
- get_ST(1), get_ST(0)));
+ put_ST_UNCHECKED(1,=20
+ triop(Iop_Yl2xp1F64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(1),=20
+ get_ST(0)));
fp_pop();
break;
=20
case 0xFA: /* FSQRT */
DIP("fsqrt\n");
- put_ST_UNCHECKED(0, unop(Iop_SqrtF64, get_ST(0)));
+ put_ST_UNCHECKED(0,=20
+ binop(Iop_SqrtF64,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(0)));
break;
=20
case 0xFB: { /* FSINCOS */
IRTemp a1 =3D newTemp(Ity_F64);
assign( a1, get_ST(0) );
DIP("fsincos\n");
- put_ST_UNCHECKED(0, unop(Iop_SinF64, mkexpr(a1)));
+ put_ST_UNCHECKED(0,=20
+ binop(Iop_SinF64,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1)));
fp_push();
- put_ST(0, unop(Iop_CosF64, mkexpr(a1)));
+ put_ST(0,=20
+ binop(Iop_CosF64,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1)));
clear_C2(); /* HACK */
break;
}
@@ -4844,19 +4888,28 @@
=20
case 0xFD: /* FSCALE */
DIP("fscale\n");
- put_ST_UNCHECKED(0, binop(Iop_ScaleF64,
- get_ST(0), get_ST(1)));
+ put_ST_UNCHECKED(0,=20
+ triop(Iop_ScaleF64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(0),=20
+ get_ST(1)));
break;
=20
case 0xFE: /* FSIN */
DIP("fsin\n");
- put_ST_UNCHECKED(0, unop(Iop_SinF64, get_ST(0)));
+ put_ST_UNCHECKED(0,=20
+ binop(Iop_SinF64,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(0)));
clear_C2(); /* HACK */
break;
=20
case 0xFF: /* FCOS */
DIP("fcos\n");
- put_ST_UNCHECKED(0, unop(Iop_CosF64, get_ST(0)));
+ put_ST_UNCHECKED(0,=20
+ binop(Iop_CosF64,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ get_ST(0)));
clear_C2(); /* HACK */
break;
=20
@@ -4911,7 +4964,8 @@
=20
do_fop_m32:
put_ST_UNCHECKED(0,=20
- binop(fop,=20
+ triop(fop,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
get_ST(0),
unop(Iop_I32toF64,
loadLE(Ity_I32, mkexpr(addr)))));
@@ -4919,7 +4973,8 @@
=20
do_foprev_m32:
put_ST_UNCHECKED(0,=20
- binop(fop,=20
+ triop(fop,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
unop(Iop_I32toF64,
loadLE(Ity_I32, mkexpr(addr))),
get_ST(0)));
@@ -5548,7 +5603,8 @@
=20
do_fop_m16:
put_ST_UNCHECKED(0,=20
- binop(fop,=20
+ triop(fop,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
get_ST(0),
unop(Iop_I32toF64,
unop(Iop_16Sto32,=20
@@ -5557,7 +5613,8 @@
=20
do_foprev_m16:
put_ST_UNCHECKED(0,=20
- binop(fop,=20
+ triop(fop,=20
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
unop(Iop_I32toF64,
unop(Iop_16Sto32,=20
loadLE(Ity_I16, mkexpr(addr)))),
Modified: trunk/priv/host-amd64/hdefs.h
=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-amd64/hdefs.h 2006-02-04 15:24:00 UTC (rev 1566)
+++ trunk/priv/host-amd64/hdefs.h 2006-02-05 16:06:26 UTC (rev 1567)
@@ -307,10 +307,9 @@
enum {
Afp_INVALID,
/* Binary */
-//.. Xfp_ADD, Xfp_SUB, Xfp_MUL, Xfp_DIV,=20
- Afp_SCALE, Afp_ATAN, Afp_YL2X, Afp_YL2XP1, //Xfp_PREM, Xfp_PREM1,
+ Afp_SCALE, Afp_ATAN, Afp_YL2X, Afp_YL2XP1,=20
/* Unary */
- Afp_SQRT, //Xfp_ABS, Xfp_NEG, Xfp_MOV,=20
+ Afp_SQRT,
Afp_SIN, Afp_COS, Afp_TAN,
Afp_ROUND, Afp_2XM1
}
@@ -333,7 +332,6 @@
Asse_RCPF, Asse_RSQRTF, Asse_SQRTF,=20
/* Bitwise */
Asse_AND, Asse_OR, Asse_XOR, Asse_ANDN,
-//.. /* Integer binary */
Asse_ADD8, Asse_ADD16, Asse_ADD32, Asse_ADD64,
Asse_QADD8U, Asse_QADD16U,
Asse_QADD8S, Asse_QADD16S,
Modified: trunk/priv/host-amd64/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-amd64/isel.c 2006-02-04 15:24:00 UTC (rev 1566)
+++ trunk/priv/host-amd64/isel.c 2006-02-05 16:06:26 UTC (rev 1567)
@@ -2804,9 +2804,9 @@
return res;
}
=20
- if (e->tag =3D=3D Iex_Binop) {
+ if (e->tag =3D=3D Iex_Triop) {
AMD64SseOp op =3D Asse_INVALID;
- switch (e->Iex.Binop.op) {
+ switch (e->Iex.Triop.op) {
case Iop_AddF64: op =3D Asse_ADDF; break;
case Iop_SubF64: op =3D Asse_SUBF; break;
case Iop_MulF64: op =3D Asse_MULF; break;
@@ -2815,41 +2815,16 @@
}
if (op !=3D Asse_INVALID) {
HReg dst =3D newVRegV(env);
- HReg argL =3D iselDblExpr(env, e->Iex.Binop.arg1);
- HReg argR =3D iselDblExpr(env, e->Iex.Binop.arg2);
+ HReg argL =3D iselDblExpr(env, e->Iex.Triop.arg2);
+ HReg argR =3D iselDblExpr(env, e->Iex.Triop.arg3);
addInstr(env, mk_vMOVsd_RR(argL, dst));
+ /* XXXROUNDINGFIXME */
+ /* set roundingmode here */
addInstr(env, AMD64Instr_Sse64FLo(op, argR, dst));
return dst;
}
}
=20
-//.. if (e->tag =3D=3D Iex_Binop) {
-//.. X86FpOp fpop =3D Xfp_INVALID;
-//.. switch (e->Iex.Binop.op) {
-//.. case Iop_AddF64: fpop =3D Xfp_ADD; break;
-//.. case Iop_SubF64: fpop =3D Xfp_SUB; break;
-//.. case Iop_MulF64: fpop =3D Xfp_MUL; break;
-//.. case Iop_DivF64: fpop =3D Xfp_DIV; break;
-//.. case Iop_ScaleF64: fpop =3D Xfp_SCALE; break;
-//.. case Iop_AtanF64: fpop =3D Xfp_ATAN; break;
-//.. case Iop_Yl2xF64: fpop =3D Xfp_YL2X; break;
-//.. case Iop_Yl2xp1F64: fpop =3D Xfp_YL2XP1; break;
-//.. 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) {
AMD64AMode* m8_rsp =3D AMD64AMode_IR(-8, hregAMD64_RSP());
HReg arg =3D iselDblExpr(env, e->Iex.Binop.arg2);
@@ -2874,17 +2849,17 @@
return dst;
}
=20
- if (e->tag =3D=3D Iex_Binop=20
- && (e->Iex.Binop.op =3D=3D Iop_ScaleF64
- || e->Iex.Binop.op =3D=3D Iop_AtanF64
- || e->Iex.Binop.op =3D=3D Iop_Yl2xF64
- || e->Iex.Binop.op =3D=3D Iop_Yl2xp1F64)
+ if (e->tag =3D=3D Iex_Triop=20
+ && (e->Iex.Triop.op =3D=3D Iop_ScaleF64
+ || e->Iex.Triop.op =3D=3D Iop_AtanF64
+ || e->Iex.Triop.op =3D=3D Iop_Yl2xF64
+ || e->Iex.Triop.op =3D=3D Iop_Yl2xp1F64)
) {
AMD64AMode* m8_rsp =3D AMD64AMode_IR(-8, hregAMD64_RSP());
- HReg arg1 =3D iselDblExpr(env, e->Iex.Binop.arg1);
- HReg arg2 =3D iselDblExpr(env, e->Iex.Binop.arg2);
+ HReg arg1 =3D iselDblExpr(env, e->Iex.Triop.arg2);
+ HReg arg2 =3D iselDblExpr(env, e->Iex.Triop.arg3);
HReg dst =3D newVRegV(env);
- Bool arg2first =3D toBool(e->Iex.Binop.op =3D=3D Iop_ScaleF64)=
;
+ Bool arg2first =3D toBool(e->Iex.Triop.op =3D=3D Iop_ScaleF64)=
;
addInstr(env, AMD64Instr_A87Free(2));
=20
/* one arg -> top of x87 stack */
@@ -2898,7 +2873,9 @@
addInstr(env, AMD64Instr_A87PushPop(m8_rsp, True/*push*/));
=20
/* do it */
- switch (e->Iex.Binop.op) {
+ /* XXXROUNDINGFIXME */
+ /* set roundingmode here */
+ switch (e->Iex.Triop.op) {
case Iop_ScaleF64:=20
addInstr(env, AMD64Instr_A87FpOp(Afp_SCALE));
break;
@@ -2964,11 +2941,9 @@
return dst;
}
=20
- if (e->tag =3D=3D Iex_Unop) {
+ if (e->tag =3D=3D Iex_Binop) {
A87FpOp fpop =3D Afp_INVALID;
- switch (e->Iex.Unop.op) {
-//.. case Iop_NegF64: fpop =3D Xfp_NEG; break;
-//.. case Iop_AbsF64: fpop =3D Xfp_ABS; break;
+ switch (e->Iex.Binop.op) {
case Iop_SqrtF64: fpop =3D Afp_SQRT; break;
case Iop_SinF64: fpop =3D Afp_SIN; break;
case Iop_CosF64: fpop =3D Afp_COS; break;
@@ -2978,14 +2953,16 @@
}
if (fpop !=3D Afp_INVALID) {
AMD64AMode* m8_rsp =3D AMD64AMode_IR(-8, hregAMD64_RSP());
- HReg arg =3D iselDblExpr(env, e->Iex.Unop.arg);
+ HReg arg =3D iselDblExpr(env, e->Iex.Binop.arg2);
HReg dst =3D newVRegV(env);
- Int nNeeded =3D e->Iex.Unop.op=3D=3DIop_TanF64 ? 2 : 1;
+ Int nNeeded =3D e->Iex.Binop.op=3D=3DIop_TanF64 ? 2 : 1;
addInstr(env, AMD64Instr_SseLdSt(False/*store*/, 8, arg, m8_rsp=
));
addInstr(env, AMD64Instr_A87Free(nNeeded));
addInstr(env, AMD64Instr_A87PushPop(m8_rsp, True/*push*/));
+ /* XXXROUNDINGFIXME */
+ /* set roundingmode here */
addInstr(env, AMD64Instr_A87FpOp(fpop));
- if (e->Iex.Unop.op=3D=3DIop_TanF64) {
+ if (e->Iex.Binop.op=3D=3DIop_TanF64) {
/* get rid of the extra 1.0 that fptan pushes */
addInstr(env, AMD64Instr_A87PushPop(m8_rsp, False/*pop*/));
}
|