You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
1
(9) |
2
(7) |
3
(15) |
4
(14) |
|
5
(12) |
6
(18) |
7
(16) |
8
(13) |
9
(14) |
10
(20) |
11
(26) |
|
12
(14) |
13
(25) |
14
(20) |
15
(15) |
16
(14) |
17
(13) |
18
(12) |
|
19
(8) |
20
(16) |
21
(15) |
22
(37) |
23
(15) |
24
(18) |
25
(12) |
|
26
(8) |
27
(13) |
28
(12) |
|
|
|
|
|
From: <sv...@va...> - 2006-02-03 22:55:09
|
Author: sewardj
Date: 2006-02-03 22:55:04 +0000 (Fri, 03 Feb 2006)
New Revision: 5607
Log:
Followup to r5605: fixes for x86
Modified:
trunk/memcheck/mc_translate.c
Modified: trunk/memcheck/mc_translate.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/memcheck/mc_translate.c 2006-02-03 19:14:33 UTC (rev 5606)
+++ trunk/memcheck/mc_translate.c 2006-02-03 22:55:04 UTC (rev 5607)
@@ -1677,6 +1677,11 @@
case Iop_MulF64r32:
case Iop_DivF64:
case Iop_DivF64r32:
+ case Iop_ScaleF64:
+ case Iop_Yl2xF64:
+ case Iop_Yl2xp1F64:
+ case Iop_AtanF64:
+ /* I32(rm) x F64 x F64 -> F64 */
return mkLazy3(mce, Ity_I64, vatom1, vatom2, vatom3);
default:
ppIROp(op);
@@ -2005,8 +2010,12 @@
case Iop_RoundF64toF32:
case Iop_F64toI64:
case Iop_I64toF64:
- /* First arg is I32 (rounding mode), second is F64 or I64
- (data). */
+ case Iop_SinF64:
+ case Iop_CosF64:
+ case Iop_TanF64:
+ case Iop_2xm1F64:
+ case Iop_SqrtF64:
+ /* I32(rm) x I64/F64 -> I64/F64 */
return mkLazy2(mce, Ity_I64, vatom1, vatom2);
=20
case Iop_PRemC3210F64: case Iop_PRem1C3210F64:
@@ -2020,12 +2029,8 @@
/* First arg is I32 (rounding mode), second is F64 (data). */
return mkLazy2(mce, Ity_I16, vatom1, vatom2);
=20
- case Iop_ScaleF64:
- case Iop_Yl2xF64:
- case Iop_Yl2xp1F64:
case Iop_PRemF64:
case Iop_PRem1F64:
- case Iop_AtanF64:
return mkLazy2(mce, Ity_I64, vatom1, vatom2);
=20
case Iop_CmpF64:
@@ -2271,12 +2276,7 @@
case Iop_F32toF64:=20
case Iop_I32toF64:
case Iop_NegF64:
- case Iop_SinF64:
- case Iop_CosF64:
- case Iop_TanF64:
- case Iop_SqrtF64:
case Iop_AbsF64:
- case Iop_2xm1F64:
case Iop_Est5FRSqrt:
case Iop_Clz64:
case Iop_Ctz64:
|
|
From: <sv...@va...> - 2006-02-03 22:54:22
|
Author: sewardj
Date: 2006-02-03 22:54:17 +0000 (Fri, 03 Feb 2006)
New Revision: 1564
Log:
Followup to r1562: fixes for x86
Modified:
trunk/priv/guest-x86/toIR.c
trunk/priv/host-x86/isel.c
trunk/pub/libvex_ir.h
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 19:12:17 UTC (rev 1563)
+++ trunk/priv/guest-x86/toIR.c 2006-02-03 22:54:17 UTC (rev 1564)
@@ -630,6 +630,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);
@@ -3181,7 +3186,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'. */
@@ -3317,13 +3327,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)))
));
@@ -3341,13 +3353,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)
));
@@ -3366,7 +3380,10 @@
(Int)st_src, (Int)st_dst );
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();
@@ -3383,7 +3400,10 @@
(Int)st_src, (Int)st_dst );
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();
@@ -3876,19 +3896,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 */
@@ -3896,12 +3925,15 @@
=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
- case 0xF4: {
+ case 0xF4: { /* FXTRACT */
IRTemp argF =3D newTemp(Ity_F64);
IRTemp sigF =3D newTemp(Ity_F64);
IRTemp expF =3D newTemp(Ity_F64);
@@ -3968,23 +4000,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,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1)));
clear_C2(); /* HACK */
break;
}
@@ -3997,19 +4041,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
@@ -4095,7 +4148,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)))));
@@ -4103,7 +4157,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)));
@@ -4741,7 +4796,7 @@
get_ST(0),
unop(Iop_I32toF64,=20
unop(Iop_16Sto32,
- loadLE(Ity_I16,mkexpr(addr)))=
)),
+ loadLE(Ity_I16,mkexpr(addr=
))))),
mkU8(8)),
mkU32(0x4500)
));
@@ -4770,7 +4825,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
@@ -4779,7 +4835,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-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 19:12:17 UTC (rev 1563)
+++ trunk/priv/host-x86/isel.c 2006-02-03 22:54:17 UTC (rev 1564)
@@ -661,14 +661,14 @@
static HReg do_sse_Not128 ( ISelEnv* env, HReg src )
{
HReg dst =3D newVRegV(env);
- /* Set dst to zero. Not strictly necessary, but the idea of doing
- a FP comparison on whatever junk happens to be floating around
- in it is just too scary. */
+ /* Set dst to zero. If dst contains a NaN then all hell might
+ break loose after the comparison. So, first zero it. */
addInstr(env, X86Instr_SseReRg(Xsse_XOR, dst, dst));
/* And now make it all 1s ... */
addInstr(env, X86Instr_Sse32Fx4(Xsse_CMPEQF, dst, dst));
/* Finally, xor 'src' into it. */
addInstr(env, X86Instr_SseReRg(Xsse_XOR, src, dst));
+ /* Doesn't that just totally suck? */
return dst;
}
=20
@@ -2604,17 +2604,36 @@
return res;
}
=20
- if (e->tag =3D=3D Iex_Binop) {
+ if (e->tag =3D=3D Iex_Triop) {
X86FpOp fpop =3D Xfp_INVALID;
- switch (e->Iex.Binop.op) {
+ switch (e->Iex.Triop.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_AtanF64: fpop =3D Xfp_ATAN; break;
+ default: break;
+ }
+ if (fpop !=3D Xfp_INVALID) {
+ HReg res =3D newVRegF(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(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) {
+ 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;
@@ -2671,21 +2690,21 @@
return dst;
}
=20
- if (e->tag =3D=3D Iex_Unop) {
+ if (e->tag =3D=3D Iex_Binop) {
X86FpOp fpop =3D Xfp_INVALID;
- switch (e->Iex.Unop.op) {
- case Iop_NegF64: fpop =3D Xfp_NEG; break;
- case Iop_AbsF64: fpop =3D Xfp_ABS; break;
- case Iop_SqrtF64: fpop =3D Xfp_SQRT; break;
+ switch (e->Iex.Binop.op) {
case Iop_SinF64: fpop =3D Xfp_SIN; break;
case Iop_CosF64: fpop =3D Xfp_COS; break;
case Iop_TanF64: fpop =3D Xfp_TAN; break;
case Iop_2xm1F64: fpop =3D Xfp_2XM1; break;
+ case Iop_SqrtF64: fpop =3D Xfp_SQRT; break;
default: break;
}
if (fpop !=3D Xfp_INVALID) {
HReg res =3D newVRegF(env);
- HReg src =3D iselDblExpr(env, e->Iex.Unop.arg);
+ HReg src =3D iselDblExpr(env, e->Iex.Binop.arg2);
+ /* XXXROUNDINGFIXME */
+ /* set roundingmode here */
addInstr(env, X86Instr_FpUnary(fpop,src,res));
if (fpop !=3D Xfp_SQRT
&& fpop !=3D Xfp_NEG && fpop !=3D Xfp_ABS)
@@ -2695,7 +2714,24 @@
}
=20
if (e->tag =3D=3D Iex_Unop) {
+ X86FpOp fpop =3D Xfp_INVALID;
switch (e->Iex.Unop.op) {
+ case Iop_NegF64: fpop =3D Xfp_NEG; break;
+ case Iop_AbsF64: fpop =3D Xfp_ABS; break;
+ default: break;
+ }
+ if (fpop !=3D Xfp_INVALID) {
+ HReg res =3D newVRegF(env);
+ HReg src =3D iselDblExpr(env, e->Iex.Unop.arg);
+ addInstr(env, X86Instr_FpUnary(fpop,src,res));
+ if (fpop !=3D Xfp_NEG && fpop !=3D Xfp_ABS)
+ roundToF64(env, res);
+ return res;
+ }
+ }
+
+ if (e->tag =3D=3D Iex_Unop) {
+ switch (e->Iex.Unop.op) {
case Iop_I32toF64: {
HReg dst =3D newVRegF(env);
HReg ri =3D iselIntExpr_R(env, e->Iex.Unop.arg);
Modified: trunk/pub/libvex_ir.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/pub/libvex_ir.h 2006-02-03 19:12:17 UTC (rev 1563)
+++ trunk/pub/libvex_ir.h 2006-02-03 22:54:17 UTC (rev 1564)
@@ -658,9 +658,16 @@
=20
=20
/* Encoding of IEEE754-specified rounding modes. This is the same as
- the encoding used by Intel IA32 to indicate x87 rounding mode. */
+ the encoding used by Intel IA32 to indicate x87 rounding mode.
+ Note, various front and back ends rely on the actual numerical
+ values of these, so do not change them. */
typedef
- enum { Irrm_NEAREST=3D0, Irrm_NegINF=3D1, Irrm_PosINF=3D2, Irrm_ZERO=3D=
3 }
+ enum {=20
+ Irrm_NEAREST =3D 0,=20
+ Irrm_NegINF =3D 1,=20
+ Irrm_PosINF =3D 2,=20
+ Irrm_ZERO =3D 3=20
+ }
IRRoundingMode;
=20
/* Floating point comparison result values, as created by Iop_CmpF64.
|
|
From: Bernard L. <be...@br...> - 2006-02-03 22:39:31
|
Dear List,
working from the Valgrind-3.1.0 release, I find that
at some point since 2.4.0
(when I built it previously) it stopped building in a separate build
directory. Poking around
reveals that the offending omission is in
<srdir>/coregrind/Makefile . The CFLAGS settings have -I$(top_builddir)
by a separate
route, but the (variously decorated) CCASFLAGS don't. There may be a
better place
to add the inclusion - I did consider putting it in CCASFLAGS itself -
but in the end
I allowed this inclusion to join -I$(top_srcdir) and the rest in the
architecture-specific
macro definitions in
<srcdir>/Makefile.core.am
(heaven knows there's repetition enough in there).
So in the end the patch is to this file: it will propagate via the
autotools chain
into <srcdir>/coregrind/Makefile.in (and others), and thence into
<builddir>/coregrind/Makefile (and others).
Short'n'sweet.
Bernard Leak
--
Bugs? How many did you want?
|
|
From: <sv...@va...> - 2006-02-03 19:14:38
|
Author: sewardj
Date: 2006-02-03 19:14:33 +0000 (Fri, 03 Feb 2006)
New Revision: 5606
Log:
Followup to r5605: fixes for ppc64
Modified:
trunk/coregrind/m_dispatch/dispatch-ppc64-linux.S
Modified: trunk/coregrind/m_dispatch/dispatch-ppc64-linux.S
=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/coregrind/m_dispatch/dispatch-ppc64-linux.S 2006-02-03 16:12:27=
UTC (rev 5605)
+++ trunk/coregrind/m_dispatch/dispatch-ppc64-linux.S 2006-02-03 19:14:33=
UTC (rev 5606)
@@ -434,7 +434,7 @@
=20
/* This check avoidance may be removable if stfiwx is
implemented. */
-# if !defined(ENABLE_INNER)
+# if 0 //!defined(ENABLE_INNER)
/* Check FPSCR & 0xFF =3D=3D 0 (lowest 8bits are controls) */
mffs 4 /* fpscr -> fpr */
li 5,144 /* =3D> 96(parent_sp) */
|
|
From: <sv...@va...> - 2006-02-03 19:12:25
|
Author: sewardj
Date: 2006-02-03 19:12:17 +0000 (Fri, 03 Feb 2006)
New Revision: 1563
Log:
Followup to r1562: fixes for ppc64
Modified:
trunk/priv/host-ppc/isel.c
Modified: trunk/priv/host-ppc/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-ppc/isel.c 2006-02-03 16:08:03 UTC (rev 1562)
+++ trunk/priv/host-ppc/isel.c 2006-02-03 19:12:17 UTC (rev 1563)
@@ -136,13 +136,6 @@
return IRExpr_Unop(op, a);
}
=20
-#if 0
-static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 )
-{
- return IRExpr_Binop(op, a1, a2);
-}
-#endif
-
static IRExpr* mkU32 ( UInt i )
{
return IRExpr_Const(IRConst_U32(i));
@@ -2913,7 +2906,22 @@
}
=20
if (e->tag =3D=3D Iex_Binop) {
+ PPCFpOp fpop =3D Pfp_INVALID;
+ switch (e->Iex.Binop.op) {
+ case Iop_SqrtF64: fpop =3D Pfp_SQRT; break;
+ default: break;
+ }
+ if (fpop !=3D Pfp_INVALID) {
+ HReg fr_dst =3D newVRegF(env);
+ HReg fr_src =3D iselDblExpr(env, e->Iex.Binop.arg2);
+ set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );
+ addInstr(env, PPCInstr_FpUnary(fpop, fr_dst, fr_src));
+ return fr_dst;
+ }
+ }
=20
+ if (e->tag =3D=3D Iex_Binop) {
+
if (e->Iex.Binop.op =3D=3D Iop_RoundF64toF32) {
HReg r_dst =3D newVRegF(env);
HReg r_src =3D iselDblExpr(env, e->Iex.Binop.arg2);
@@ -2981,7 +2989,6 @@
switch (e->Iex.Unop.op) {
case Iop_NegF64: fpop =3D Pfp_NEG; break;
case Iop_AbsF64: fpop =3D Pfp_ABS; break;
- case Iop_SqrtF64: fpop =3D Pfp_SQRT; break;
case Iop_Est5FRSqrt: fpop =3D Pfp_RSQRTE; break;
default: break;
}
|
|
From: <sv...@va...> - 2006-02-03 16:12:35
|
Author: sewardj
Date: 2006-02-03 16:12:27 +0000 (Fri, 03 Feb 2006)
New Revision: 5605
Log:
* Track introduction of IR ternary primops and rounding modes, at least a=
s
to the extent needed to make ppc32 work.
* As a result, remove the replacements for glibc's floor/ceil fns on=20
ppc32/64, since vex can now correctly simulate the real ones.
Modified:
trunk/coregrind/m_dispatch/dispatch-ppc32-linux.S
trunk/coregrind/vg_preloaded.c
trunk/memcheck/mc_translate.c
Modified: trunk/coregrind/m_dispatch/dispatch-ppc32-linux.S
=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/coregrind/m_dispatch/dispatch-ppc32-linux.S 2006-02-02 05:53:44=
UTC (rev 5604)
+++ trunk/coregrind/m_dispatch/dispatch-ppc32-linux.S 2006-02-03 16:12:27=
UTC (rev 5605)
@@ -401,7 +401,7 @@
=20
/* This check avoidance may be removable if stfiwx is
implemented. */
-# if !defined(ENABLE_INNER)
+# if 0 //!defined(ENABLE_INNER)
/* Check FPSCR & 0xFF =3D=3D 0 (lowest 8bits are controls) */
mffs 4 /* fpscr -> fpr */
li 5,48
Modified: trunk/coregrind/vg_preloaded.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/coregrind/vg_preloaded.c 2006-02-02 05:53:44 UTC (rev 5604)
+++ trunk/coregrind/vg_preloaded.c 2006-02-03 16:12:27 UTC (rev 5605)
@@ -66,184 +66,7 @@
*(int *)0 =3D 'x';
}
=20
-/* ---------------------------------------------------------------------
- Avoid glibc's floor/ceil functions on ppc32/64. In recent glibcs
- (about 2.3.4 and after) these rely on doing fadd/fsub with with
- round to +inf/-inf set, which vex does not currently handle
- correctly. This just reroutes to the glibc default implementations.
- This is a really ugly hack.
- ------------------------------------------------------------------ */
=20
-#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
-/*
- * =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
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * =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
- */
-/*
- * floor(x)
- * Return x rounded toward -inf to integral value
- * Method:
- * Bit twiddling.
- * Exception:
- * Inexact flag raised if x not equal to floor(x).
- */
-
-typedef union
-{
- double value;
- struct
- {
- /*u_int32_t*/ UInt msw;
- /*u_int32_t*/ UInt lsw;
- } parts;
-} ieee_double_shape_type;
-
-/* Get two 32 bit ints from a double. */
-#define EXTRACT_WORDS(ix0,ix1,d) \
-do { \
- ieee_double_shape_type ew_u; \
- ew_u.value =3D (d); \
- (ix0) =3D ew_u.parts.msw; \
- (ix1) =3D ew_u.parts.lsw; \
-} while (0)
-
-/* Set a double from two 32 bit ints. */
-#define INSERT_WORDS(d,ix0,ix1) \
-do { \
- ieee_double_shape_type iw_u; \
- iw_u.parts.msw =3D (ix0); \
- iw_u.parts.lsw =3D (ix1); \
- (d) =3D iw_u.value; \
-} while (0)
-
-static double bit_twiddling_floor ( double x )
-{
- static const double huge =3D 1.0e300;
- /*int32_t*/ Int i0,i1,j0;
- /*u_int32_t*/ UInt i,j;
- EXTRACT_WORDS(i0,i1,x);
- j0 =3D ((i0>>20)&0x7ff)-0x3ff;
- if(j0<20) {
- if(j0<0) { /* raise inexact if x !=3D 0 */
- if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
- if(i0>=3D0) {i0=3Di1=3D0;}
- else if(((i0&0x7fffffff)|i1)!=3D0)
- { i0=3D0xbff00000;i1=3D0;}
- }
- } else {
- i =3D (0x000fffff)>>j0;
- if(((i0&i)|i1)=3D=3D0) return x; /* x is integral */
- if(huge+x>0.0) { /* raise inexact flag */
- if(i0<0) i0 +=3D (0x00100000)>>j0;
- i0 &=3D (~i); i1=3D0;
- }
- }
- } else if (j0>51) {
- if(j0=3D=3D0x400) return x+x; /* inf or NaN */
- else return x; /* x is integral */
- } else {
- i =3D ((/*u_int32_t*/UInt)(0xffffffff))>>(j0-20);
- if((i1&i)=3D=3D0) return x; /* x is integral */
- if(huge+x>0.0) { /* raise inexact flag */
- if(i0<0) {
- if(j0=3D=3D20) i0+=3D1;
- else {
- j =3D i1+(1<<(52-j0));
- if(j<i1) i0 +=3D1 ; /* got a carry */
- i1=3Dj;
- }
- }
- i1 &=3D (~i);
- }
- }
- INSERT_WORDS(x,i0,i1);
- return x;
-}
-
-/* Catch libm.so.6:__floor */
-double VG_REPLACE_FUNCTION_ZZ(libmZdsoZd6,ZuZufloor)(double);
-double VG_REPLACE_FUNCTION_ZZ(libmZdsoZd6,ZuZufloor)(double x) {
- return bit_twiddling_floor(x);
-}
-
-/* Catch libm.so.6:floor */
-double VG_REPLACE_FUNCTION_ZZ(libmZdsoZd6,floor)(double);
-double VG_REPLACE_FUNCTION_ZZ(libmZdsoZd6,floor)(double x) {
- return bit_twiddling_floor(x);
-}
-
-
-/*
- * ceil(x)
- * Return x rounded toward -inf to integral value
- * Method:
- * Bit twiddling.
- * Exception:
- * Inexact flag raised if x not equal to ceil(x).
- */
-static double bit_twiddling_ceil ( double x )
-{
- static const double huge =3D 1.0e300;
- /*int32_t*/ Int i0,i1,j0;
- /*u_int32_t*/ UInt i,j;
- EXTRACT_WORDS(i0,i1,x);
- j0 =3D ((i0>>20)&0x7ff)-0x3ff;
- if(j0<20) {
- if(j0<0) { /* raise inexact if x !=3D 0 */
- if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
- if(i0<0) {i0=3D0x80000000;i1=3D0;}
- else if((i0|i1)!=3D0) { i0=3D0x3ff00000;i1=3D0;}
- }
- } else {
- i =3D (0x000fffff)>>j0;
- if(((i0&i)|i1)=3D=3D0) return x; /* x is integral */
- if(huge+x>0.0) { /* raise inexact flag */
- if(i0>0) i0 +=3D (0x00100000)>>j0;
- i0 &=3D (~i); i1=3D0;
- }
- }
- } else if (j0>51) {
- if(j0=3D=3D0x400) return x+x; /* inf or NaN */
- else return x; /* x is integral */
- } else {
- i =3D ((/*u_int32_t*/UInt)(0xffffffff))>>(j0-20);
- if((i1&i)=3D=3D0) return x; /* x is integral */
- if(huge+x>0.0) { /* raise inexact flag */
- if(i0>0) {
- if(j0=3D=3D20) i0+=3D1;
- else {
- j =3D i1 + (1<<(52-j0));
- if(j<i1) i0+=3D1; /* got a carry */
- i1 =3D j;
- }
- }
- i1 &=3D (~i);
- }
- }
- INSERT_WORDS(x,i0,i1);
- return x;
-}
-
-/* Catch libm.so.6:__ceil */
-double VG_REPLACE_FUNCTION_ZZ(libmZdsoZd6,ZuZuceil)(double);
-double VG_REPLACE_FUNCTION_ZZ(libmZdsoZd6,ZuZuceil)(double x) {
- return bit_twiddling_ceil(x);
-}
-
-/* Catch libm.so.6:ceil */
-double VG_REPLACE_FUNCTION_ZZ(libmZdsoZd6,ceil)(double);
-double VG_REPLACE_FUNCTION_ZZ(libmZdsoZd6,ceil)(double x) {
- return bit_twiddling_ceil(x);
-}
-
-#endif
-
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/memcheck/mc_translate.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/memcheck/mc_translate.c 2006-02-02 05:53:44 UTC (rev 5604)
+++ trunk/memcheck/mc_translate.c 2006-02-03 16:12:27 UTC (rev 5605)
@@ -1106,6 +1106,61 @@
}
=20
=20
+/* 3-arg version of the above. */
+static
+IRAtom* mkLazy3 ( MCEnv* mce, IRType finalVty,=20
+ IRAtom* va1, IRAtom* va2, IRAtom* va3 )
+{
+ IRAtom* at;
+ IRType t1 =3D typeOfIRExpr(mce->bb->tyenv, va1);
+ IRType t2 =3D typeOfIRExpr(mce->bb->tyenv, va2);
+ IRType t3 =3D typeOfIRExpr(mce->bb->tyenv, va3);
+ tl_assert(isShadowAtom(mce,va1));
+ tl_assert(isShadowAtom(mce,va2));
+ tl_assert(isShadowAtom(mce,va3));
+
+ /* The general case is inefficient because PCast is an expensive
+ operation. Here are some special cases which use PCast only
+ twice rather than three times. */
+
+ /* I32 x I64 x I64 -> I64 */
+ /* Standard FP idiom: rm x FParg1 x FParg2 -> FPresult */
+ if (t1 =3D=3D Ity_I32 && t2 =3D=3D Ity_I64 && t3 =3D=3D Ity_I64=20
+ && finalVty =3D=3D Ity_I64) {
+ if (0) VG_(printf)("mkLazy3: I32 x I64 x I64 -> I64\n");
+ /* Widen 1st arg to I64. Since 1st arg is typically a rounding
+ mode indication which is fully defined, this should get
+ folded out later. */
+ at =3D mkPCastTo(mce, Ity_I64, va1);
+ /* Now fold in 2nd and 3rd args. */
+ at =3D mkUifU(mce, Ity_I64, at, va2);
+ at =3D mkUifU(mce, Ity_I64, at, va3);
+ /* and PCast once again. */
+ at =3D mkPCastTo(mce, Ity_I64, at);
+ return at;
+ }
+
+ if (0) {
+ VG_(printf)("mkLazy3 ");
+ ppIRType(t1);
+ VG_(printf)("_");
+ ppIRType(t2);
+ VG_(printf)("_");
+ ppIRType(t3);
+ VG_(printf)("_");
+ ppIRType(finalVty);
+ VG_(printf)("\n");
+ }
+
+ /* General case: force everything via 32-bit intermediaries. */
+ at =3D mkPCastTo(mce, Ity_I32, va1);
+ at =3D mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va2));
+ at =3D mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va3));
+ at =3D mkPCastTo(mce, finalVty, at);
+ return at;
+}
+
+
/* Do the lazy propagation game from a null-terminated vector of
atoms. This is presumably the arguments to a helper call, so the
IRCallee info is also supplied in order that we can know which
@@ -1591,6 +1646,46 @@
/*------------------------------------------------------------*/
=20
static=20
+IRAtom* expr2vbits_Triop ( MCEnv* mce,
+ IROp op,
+ IRAtom* atom1, IRAtom* atom2, IRAtom* atom3 )
+{
+ IRType and_or_ty;
+ IRAtom* (*uifu) (MCEnv*, IRAtom*, IRAtom*);
+ IRAtom* (*difd) (MCEnv*, IRAtom*, IRAtom*);
+ IRAtom* (*improve) (MCEnv*, IRAtom*, IRAtom*);
+
+ IRAtom* vatom1 =3D expr2vbits( mce, atom1 );
+ IRAtom* vatom2 =3D expr2vbits( mce, atom2 );
+ IRAtom* vatom3 =3D expr2vbits( mce, atom3 );
+
+ tl_assert(isOriginalAtom(mce,atom1));
+ tl_assert(isOriginalAtom(mce,atom2));
+ tl_assert(isOriginalAtom(mce,atom3));
+ tl_assert(isShadowAtom(mce,vatom1));
+ tl_assert(isShadowAtom(mce,vatom2));
+ tl_assert(isShadowAtom(mce,vatom3));
+ tl_assert(sameKindedAtoms(atom1,vatom1));
+ tl_assert(sameKindedAtoms(atom2,vatom2));
+ tl_assert(sameKindedAtoms(atom3,vatom3));
+ switch (op) {
+ case Iop_AddF64:
+ case Iop_AddF64r32:
+ case Iop_SubF64:
+ case Iop_SubF64r32:
+ case Iop_MulF64:
+ case Iop_MulF64r32:
+ case Iop_DivF64:
+ case Iop_DivF64r32:
+ return mkLazy3(mce, Ity_I64, vatom1, vatom2, vatom3);
+ default:
+ ppIROp(op);
+ VG_(tool_panic)("memcheck:expr2vbits_Triop");
+ }
+}
+
+
+static=20
IRAtom* expr2vbits_Binop ( MCEnv* mce,
IROp op,
IRAtom* atom1, IRAtom* atom2 )
@@ -1906,7 +2001,8 @@
=20
/* Scalar floating point */
=20
- case Iop_RoundF64:
+ case Iop_RoundF64toInt:
+ case Iop_RoundF64toF32:
case Iop_F64toI64:
case Iop_I64toF64:
/* First arg is I32 (rounding mode), second is F64 or I64
@@ -1930,10 +2026,6 @@
case Iop_PRemF64:
case Iop_PRem1F64:
case Iop_AtanF64:
- case Iop_AddF64:
- case Iop_DivF64:
- case Iop_SubF64:
- case Iop_MulF64:
return mkLazy2(mce, Ity_I64, vatom1, vatom2);
=20
case Iop_CmpF64:
@@ -2185,7 +2277,6 @@
case Iop_SqrtF64:
case Iop_AbsF64:
case Iop_2xm1F64:
- case Iop_Est8FRecip:
case Iop_Est5FRSqrt:
case Iop_Clz64:
case Iop_Ctz64:
@@ -2193,6 +2284,7 @@
=20
case Iop_Clz32:
case Iop_Ctz32:
+ case Iop_TruncF64asF32:
return mkPCastTo(mce, Ity_I32, vatom);
=20
case Iop_1Uto64:
@@ -2428,6 +2520,13 @@
case Iex_Const:
return definedOfType(shadowType(typeOfIRExpr(mce->bb->tyenv, e)=
));
=20
+ case Iex_Triop:
+ return expr2vbits_Triop(
+ mce,
+ e->Iex.Triop.op,
+ e->Iex.Triop.arg1, e->Iex.Triop.arg2, e->Iex.Triop.ar=
g3
+ );
+
case Iex_Binop:
return expr2vbits_Binop(
mce,
@@ -2931,6 +3030,10 @@
case Iex_Binop:=20
return isBogusAtom(e->Iex.Binop.arg1)
|| isBogusAtom(e->Iex.Binop.arg2);
+ case Iex_Triop:=20
+ return isBogusAtom(e->Iex.Triop.arg1)
+ || isBogusAtom(e->Iex.Triop.arg2)
+ || isBogusAtom(e->Iex.Triop.arg3);
case Iex_Mux0X:
return isBogusAtom(e->Iex.Mux0X.cond)
|| isBogusAtom(e->Iex.Mux0X.expr0)
|
|
From: <sv...@va...> - 2006-02-03 16:08:18
|
Author: sewardj
Date: 2006-02-03 16:08:03 +0000 (Fri, 03 Feb 2006)
New Revision: 1562
Log:
An overhaul of VEX's floating point handling, to facilitate correct
simulation of IEEE rounding modes in all FP operations.
The fundamental change is to add a third argument to the basic
floating point primops, eg AddF64, MulF64, etc, indicating the
(IR-encoded) rounding mode to be used for that operation.
Unfortunately IR did not have any way to support three-argument
primops, which means a new kind of IRExpr has been added: a ternary
op, IRExpr_Triop, which is simply a 3-argument form of the existing IR
binary operation node. The unfortunate side effect is that the size
of the union type IRExpr has increased from 16 to 20 bytes on 32-bit
platforms, and hence the JIT chews through more memory, but this does
not appear to have a measurable effect on the JIT's performance, at
least as measured by Valgrind's perf suite.
* Add IRExpr_Triop, and add handling code to dozens of places which
examine IRExprs.
* Rename/retype a bunch of floating point IR primops to take a 3rd
rounding mode argument (which is always the first arg).
* Add extra primops AddF64r32 et al, which do double-precision FP
operations and then round to single precision, still within a 64-bit
type. This is needed to simulate PPC's fadds et al without double
rounding.
* Adjust the PPC->IR front end, to generate these new primops and
rounding modes.
* Cause the IR optimiser to do a CSE pass on blocks containing any
floating point operations. This commons up the IR rounding mode
computations, which is important for generating efficient code from
the backend.
* Adjust the IR->PPC back end, so as to emit instructions to set the
rounding mode before each FP operation. Well, at least in
principle. In practice there is a bit of cleverness to avoid
repeatedly setting it to the same value. This depends on both the
abovementioned CSE pass, and on the SSA property of IR (cool stuff,
SSA!). The effect is that for most blocks containing FP code, the
rounding mode is set just once, at the start of the block, and the
resulting overhead is minimal. See comment on
set_FPU_rounding_mode().
This change requires followup changes in memcheck. Also, the
x86/amd64 front/back ends are temporarily broken.
Modified:
trunk/priv/guest-amd64/toIR.c
trunk/priv/guest-ppc/toIR.c
trunk/priv/guest-x86/toIR.c
trunk/priv/host-amd64/isel.c
trunk/priv/host-ppc/hdefs.c
trunk/priv/host-ppc/hdefs.h
trunk/priv/host-ppc/isel.c
trunk/priv/host-x86/isel.c
trunk/priv/ir/irdefs.c
trunk/priv/ir/iropt.c
trunk/pub/libvex_ir.h
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-01-31 16:32:25 UTC (rev 1561)
+++ trunk/priv/guest-amd64/toIR.c 2006-02-03 16:08:03 UTC (rev 1562)
@@ -4839,7 +4839,7 @@
case 0xFC: /* FRNDINT */
DIP("frndint\n");
put_ST_UNCHECKED(0,
- binop(Iop_RoundF64, get_roundingmode(), get_ST(0)) );
+ binop(Iop_RoundF64toInt, get_roundingmode(), get_ST(0)=
) );
break;
=20
case 0xFD: /* FSCALE */
Modified: trunk/priv/guest-ppc/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-ppc/toIR.c 2006-01-31 16:32:25 UTC (rev 1561)
+++ trunk/priv/guest-ppc/toIR.c 2006-02-03 16:08:03 UTC (rev 1562)
@@ -54,12 +54,6 @@
- lvxl,stvxl: load/store with 'least recently used' hint
- vexptefp, vlogefp
=20
- Floating Point
- - Single precision stores are rounded twice - once by F64toF32,
- and then again by the backend for storeBE( F32 ), giving a loss
- of precision.
-
-
LIMITATIONS:
=20
Various, including:
@@ -71,6 +65,7 @@
- All exceptions disabled in FPSCR
- condition codes not set in FPSCR
- some error in accuracy
+ - flt->int conversions are dubious in overflow cases
=20
- Altivec floating point:
- vmaddfp, vnmsubfp
@@ -483,6 +478,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);
@@ -2250,8 +2250,22 @@
case PPC_GST_FPSCR: {
/* Allow writes to Rounding Mode */
if (mask & 0x3) {
- stmt( IRStmt_Put( OFFB_FPROUND,
- binop(Iop_And32, src, mkU32(0x3)) ));
+ /* construct new fpround from new and old values as per mask:
+ new fpround =3D (src & (3 & mask)) | (fpround & (3 & ~mask))=
*/
+ stmt(=20
+ IRStmt_Put(=20
+ OFFB_FPROUND,
+ binop(
+ Iop_Or32,=20
+ binop(Iop_And32, src, mkU32(3 & mask)),
+ binop(
+ Iop_And32,=20
+ IRExpr_Get(OFFB_FPROUND,Ity_I32),
+ mkU32(3 & ~mask)
+ )
+ )
+ )
+ );
}
=20
/* Give EmWarn for attempted writes to:
@@ -5355,7 +5369,7 @@
IRRoundingMode. PPCRoundingMode encoding is different to
IRRoundingMode, so need to map it.
*/
-static IRExpr* /* :: Ity_I32 */ get_roundingmode ( void )
+static IRExpr* /* :: Ity_I32 */ get_IR_roundingmode ( void )
{
/*=20
rounding mode | PPC | IR
@@ -5369,20 +5383,14 @@
assign( rm_PPC32, getGST_masked( PPC_GST_FPSCR, MASK_FPSCR_RN ) );
=20
// rm_IR =3D XOR( rm_PPC32, (rm_PPC32 << 1) & 2)
- return binop(Iop_Xor32, mkexpr(rm_PPC32),
- binop(Iop_And32, mkU32(2),
- binop(Iop_Shl32, mkexpr(rm_PPC32), mkU8(1))));
+ return binop( Iop_Xor32,=20
+ mkexpr(rm_PPC32),
+ binop( Iop_And32,=20
+ binop(Iop_Shl32, mkexpr(rm_PPC32), mkU8(1)),
+ mkU32(2) ));
}
=20
-/* Round float to single precision
- - returns type Ity_F64 */
-static IRExpr* roundToSgl ( IRExpr* src )
-{
- return unop(Iop_F32toF64,
- binop(Iop_F64toF32, get_roundingmode(), src));
-}
=20
-
/*------------------------------------------------------------*/
/*--- Floating Point Instruction Translation ---*/
/*------------------------------------------------------------*/
@@ -5410,8 +5418,11 @@
assign( rA, getIReg(rA_addr) );
assign( rB, getIReg(rB_addr) );
=20
+ /* These are completely straightforward from a rounding and status
+ bits perspective: no rounding involved and no funny status or CR
+ bits affected. */
=20
- switch(opc1) {
+ switch (opc1) {
case 0x30: // lfs (Load Float Single, PPC32 p441)
DIP("lfs fr%u,%d(r%u)\n", frD_addr, simm16, rA_addr);
assign( EA, ea_rAor0_simm(rA_addr, simm16) );
@@ -5420,10 +5431,8 @@
break;
=20
case 0x31: // lfsu (Load Float Single, Update, PPC32 p442)
- if (rA_addr =3D=3D 0) {
- vex_printf("dis_fp_load(ppc)(instr,lfsu)\n");
+ if (rA_addr =3D=3D 0)
return False;
- }
DIP("lfsu fr%u,%d(r%u)\n", frD_addr, simm16, rA_addr);
assign( EA, ea_rA_simm(rA_addr, simm16) );
putFReg( frD_addr,
@@ -5438,10 +5447,8 @@
break;
=20
case 0x33: // lfdu (Load Float Double, Update, PPC32 p438)
- if (rA_addr =3D=3D 0) {
- vex_printf("dis_fp_load(ppc)(instr,lfdu)\n");
+ if (rA_addr =3D=3D 0)
return False;
- }
DIP("lfdu fr%u,%d(r%u)\n", frD_addr, simm16, rA_addr);
assign( EA, ea_rA_simm(rA_addr, simm16) );
putFReg( frD_addr, loadBE(Ity_F64, mkexpr(EA)) );
@@ -5463,10 +5470,8 @@
break;
=20
case 0x237: // lfsux (Load Float Single, Update Indxd, PPC32 p443)
- if (rA_addr =3D=3D 0) {
- vex_printf("dis_fp_load(ppc)(instr,lfsux)\n");
+ if (rA_addr =3D=3D 0)
return False;
- }
DIP("lfsux fr%u,r%u,r%u\n", frD_addr, rA_addr, rB_addr);
assign( EA, ea_rA_idxd(rA_addr, rB_addr) );
putFReg( frD_addr,
@@ -5481,10 +5486,8 @@
break;
=20
case 0x277: // lfdux (Load Float Double, Update Indxd, PPC32 p439)
- if (rA_addr =3D=3D 0) {
- vex_printf("dis_fp_load(ppc)(instr,lfdux)\n");
+ if (rA_addr =3D=3D 0)
return False;
- }
DIP("lfdux fr%u,r%u,r%u\n", frD_addr, rA_addr, rB_addr);
assign( EA, ea_rA_idxd(rA_addr, rB_addr) );
putFReg( frD_addr, loadBE(Ity_F64, mkexpr(EA)) );
@@ -5531,29 +5534,31 @@
assign( rA, getIReg(rA_addr) );
assign( rB, getIReg(rB_addr) );
=20
- switch(opc1) {
+ /* These are straightforward from a status bits perspective: no
+ funny status or CR bits affected. For single precision stores,
+ the values are truncated and denormalised (not rounded) to turn
+ them into single precision values. */
=20
+ switch (opc1) {
+
case 0x34: // stfs (Store Float Single, PPC32 p518)
DIP("stfs fr%u,%d(r%u)\n", frS_addr, simm16, rA_addr);
assign( EA, ea_rAor0_simm(rA_addr, simm16) );
- /* TODO
- This implementation ends up rounding twice, losing accuracy.
- - first via F64toF32, and then by the backend fp store (stfs)
- */
+ /* Use Iop_TruncF64asF32 to truncate and possible denormalise
+ the value to be stored in the correct way, without any
+ rounding. */
storeBE( mkexpr(EA),
- binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
+ unop(Iop_TruncF64asF32, mkexpr(frS)) );
break;
=20
case 0x35: // stfsu (Store Float Single, Update, PPC32 p519)
- if (rA_addr =3D=3D 0) {
- vex_printf("dis_fp_store(ppc)(instr,stfsu)\n");
+ if (rA_addr =3D=3D 0)
return False;
- }
DIP("stfsu fr%u,%d(r%u)\n", frS_addr, simm16, rA_addr);
assign( EA, ea_rA_simm(rA_addr, simm16) );
- /* This implementation loses accuracy - see note for stfs */
+ /* See comment for stfs */
storeBE( mkexpr(EA),
- binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) );
+ unop(Iop_TruncF64asF32, mkexpr(frS)) );
putIReg( rA_addr, mkexpr(EA) );
break;
=20
@@ -5564,10 +5569,8 @@
break;
=20
case 0x37: // stfdu (Store Float Double, Update, PPC32 p514)
- if (rA_addr =3D=3D 0) {
- vex_printf("dis_fp_store(ppc)(instr,stfdu)\n");
+ if (rA_addr =3D=3D 0)
return False;
- }
DIP("stfdu fr%u,%d(r%u)\n", frS_addr, simm16, rA_addr);
assign( EA, ea_rA_simm(rA_addr, simm16) );
storeBE( mkexpr(EA), mkexpr(frS) );
@@ -5579,26 +5582,23 @@
vex_printf("dis_fp_store(ppc)(instr,b0)\n");
return False;
}
-
switch(opc2) {
case 0x297: // stfsx (Store Float Single Indexed, PPC32 p521)
DIP("stfsx fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr);
assign( EA, ea_rAor0_idxd(rA_addr, rB_addr) );
- /* This implementation loses accuracy - see note for stfs */
- storeBE( mkexpr(EA), binop(Iop_F64toF32,
- get_roundingmode(), mkexpr(frS)) );
+ /* See note for stfs */
+ storeBE( mkexpr(EA),=20
+ unop(Iop_TruncF64asF32, mkexpr(frS)) );
break;
=20
case 0x2B7: // stfsux (Store Float Sgl, Update Indxd, PPC32 p520)
- if (rA_addr =3D=3D 0) {
- vex_printf("dis_fp_store(ppc)(instr,stfsux)\n");
+ if (rA_addr =3D=3D 0)
return False;
- }
DIP("stfsux fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr);
assign( EA, ea_rA_idxd(rA_addr, rB_addr) );
- /* This implementation loses accuracy - see note for stfs */
- storeBE( mkexpr(EA), binop(Iop_F64toF32,
- get_roundingmode(), mkexpr(frS)) );
+ /* See note for stfs */
+ storeBE( mkexpr(EA),=20
+ unop(Iop_TruncF64asF32, mkexpr(frS)) );
putIReg( rA_addr, mkexpr(EA) );
break;
=20
@@ -5609,10 +5609,8 @@
break;
=20
case 0x2F7: // stfdux (Store Float Dbl, Update Indxd, PPC32 p515)
- if (rA_addr =3D=3D 0) {
- vex_printf("dis_fp_store(ppc)(instr,stfdux)\n");
+ if (rA_addr =3D=3D 0)
return False;
- }
DIP("stfdux fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr);
assign( EA, ea_rA_idxd(rA_addr, rB_addr) );
storeBE( mkexpr(EA), mkexpr(frS) );
@@ -5655,13 +5653,24 @@
UChar frC_addr =3D ifieldRegC(theInstr);
UChar opc2 =3D ifieldOPClo5(theInstr);
UChar flag_rC =3D ifieldBIT0(theInstr);
- // Note: flag_rC ignored as fp exceptions not supported.
=20
- IRTemp frD =3D newTemp(Ity_F64);
- IRTemp frA =3D newTemp(Ity_F64);
- IRTemp frB =3D newTemp(Ity_F64);
- IRTemp frC =3D newTemp(Ity_F64);
+ IRTemp frD =3D newTemp(Ity_F64);
+ IRTemp frA =3D newTemp(Ity_F64);
+ IRTemp frB =3D newTemp(Ity_F64);
+ IRTemp frC =3D newTemp(Ity_F64);
+ IRExpr* rm =3D get_IR_roundingmode();
=20
+ /* By default, we will examine the results of the operation and set
+ fpscr[FPRF] accordingly. */
+ Bool set_FPRF =3D True;
+
+ /* By default, if flag_RC is set, we will clear cr1 after the
+ operation. In reality we should set cr1 to indicate the
+ exception status of the operation, but since we're not
+ simulating exceptions, the exception status will appear to be
+ zero. Hence cr1 should be cleared if this is a . form insn. */
+ Bool clear_CR1 =3D True;
+
assign( frA, getFReg(frA_addr));
assign( frB, getFReg(frB_addr));
assign( frC, getFReg(frC_addr));
@@ -5670,84 +5679,71 @@
case 0x3B:
switch (opc2) {
case 0x12: // fdivs (Floating Divide Single, PPC32 p407)
- if (frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fdivs)\n");
+ if (frC_addr !=3D 0)
return False;
- }
DIP("fdivs%s fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frB_addr);
- assign( frD, roundToSgl( binop(Iop_DivF64,
- mkexpr(frA), mkexpr(frB)) ));
+ assign( frD, triop( Iop_DivF64r32,=20
+ rm, mkexpr(frA), mkexpr(frB) ));
break;
=20
case 0x14: // fsubs (Floating Subtract Single, PPC32 p430)
- if (frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fsubs)\n");
+ if (frC_addr !=3D 0)
return False;
- }
DIP("fsubs%s fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frB_addr);
- assign( frD, roundToSgl(=20
- binop(Iop_SubF64, mkexpr(frA), mkexpr(frB)) ));
+ assign( frD, triop( Iop_SubF64r32,=20
+ rm, mkexpr(frA), mkexpr(frB) ));
break;
=20
case 0x15: // fadds (Floating Add Single, PPC32 p401)
- if (frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fadds)\n");
+ if (frC_addr !=3D 0)
return False;
- }
DIP("fadds%s fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frB_addr);
- assign( frD, roundToSgl(=20
- binop(Iop_AddF64, mkexpr(frA), mkexpr(frB)) ));
+ assign( frD, triop( Iop_AddF64r32,=20
+ rm, mkexpr(frA), mkexpr(frB) ));
break;
=20
case 0x16: // fsqrts (Floating SqRt (Single-Precision), PPC32 p428=
)
// NOTE: POWERPC OPTIONAL, "General-Purpose Group" (PPC32_FX)
- if (frA_addr !=3D 0 || frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fsqrts)\n");
+ if (frA_addr !=3D 0 || frC_addr !=3D 0)
return False;
- }
DIP("fsqrts%s fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frB_addr);
// however illogically, on ppc970 this insn behaves identically
- // to fsqrt (double-precision). So don't do round-to-single.
- assign( frD, unop(Iop_SqrtF64, mkexpr(frB)) );
+ // to fsqrt (double-precision). So use SqrtF64, not SqrtF64r32=
.
+ assign( frD, binop( Iop_SqrtF64, rm, mkexpr(frB) ));
break;
=20
case 0x18: // fres (Floating Reciprocal Estimate Single, PPC32 p42=
1)
// NOTE: POWERPC OPTIONAL, "Graphics Group" (PPC32_GX)
- if (frA_addr !=3D 0 || frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fres)\n");
+ if (frA_addr !=3D 0 || frC_addr !=3D 0)
return False;
- }
DIP("fres%s fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frB_addr);
- //assign( frD, unop(Iop_Est8FRecip, mkexpr(frB)) );
{ IRExpr* ieee_one
=3D IRExpr_Const(IRConst_F64i(0x3ff0000000000000ULL));
- assign( frD, roundToSgl(binop(Iop_DivF64, ieee_one, mkexpr(fr=
B))) );
+ assign( frD, triop( Iop_DivF64r32,=20
+ rm,
+ ieee_one, mkexpr(frB) ));
}
break;
=20
case 0x19: // fmuls (Floating Multiply Single, PPC32 p414)
- if (frB_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fmuls)\n");
+ if (frB_addr !=3D 0)
return False;
- }
DIP("fmuls%s fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr);
- assign( frD, roundToSgl( binop(Iop_MulF64,
- mkexpr(frA), mkexpr(frC)) ));
+ assign( frD, triop( Iop_MulF64r32,
+ rm, mkexpr(frA), mkexpr(frC) ));
break;
=20
case 0x1A: // frsqrtes (Floating Recip SqRt Est Single)
// NOTE: POWERPC OPTIONAL, "Graphics Group" (PPC32_GX)
// Undocumented instruction?
- if (frA_addr !=3D 0 || frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,frsqrte)\n");
+ if (frA_addr !=3D 0 || frC_addr !=3D 0)
return False;
- }
DIP("frsqrtes%s fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frB_addr);
assign( frD, unop(Iop_Est5FRSqrt, mkexpr(frB)) );
@@ -5762,44 +5758,36 @@
case 0x3F:
switch (opc2) { =20
case 0x12: // fdiv (Floating Div (Double-Precision), PPC32 p406)
- if (frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fdiv)\n");
+ if (frC_addr !=3D 0)
return False;
- }
DIP("fdiv%s fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frB_addr);
- assign( frD, binop( Iop_DivF64, mkexpr(frA), mkexpr(frB) ) );
+ assign( frD, triop(Iop_DivF64, rm, mkexpr(frA), mkexpr(frB)) );
break;
=20
case 0x14: // fsub (Floating Sub (Double-Precision), PPC32 p429)
- if (frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fsub)\n");
+ if (frC_addr !=3D 0)
return False;
- }
DIP("fsub%s fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frB_addr);
- assign( frD, binop( Iop_SubF64, mkexpr(frA), mkexpr(frB) ) );
+ assign( frD, triop(Iop_SubF64, rm, mkexpr(frA), mkexpr(frB)) );
break;
=20
case 0x15: // fadd (Floating Add (Double-Precision), PPC32 p400)
- if (frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fadd)\n");
+ if (frC_addr !=3D 0)
return False;
- }
DIP("fadd%s fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frB_addr);
- assign( frD, binop( Iop_AddF64, mkexpr(frA), mkexpr(frB) ) );
+ assign( frD, triop(Iop_AddF64, rm, mkexpr(frA), mkexpr(frB)) );
break;
=20
case 0x16: // fsqrt (Floating SqRt (Double-Precision), PPC32 p427)
// NOTE: POWERPC OPTIONAL, "General-Purpose Group" (PPC32_FX)
- if (frA_addr !=3D 0 || frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fsqrt)\n");
+ if (frA_addr !=3D 0 || frC_addr !=3D 0)
return False;
- }
DIP("fsqrt%s fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frB_addr);
- assign( frD, unop( Iop_SqrtF64, mkexpr(frB) ) );
+ assign( frD, binop(Iop_SqrtF64, rm, mkexpr(frB)) );
break;
=20
case 0x17: { // fsel (Floating Select, PPC32 p426)
@@ -5824,6 +5812,9 @@
binop(Iop_CmpEQ32, mkexpr(cc_b0), mkU32(0))),
mkexpr(frB),
mkexpr(frC) ));
+
+ /* One of the rare ones which don't mess with FPRF */
+ set_FPRF =3D False;
break;
}
=20
@@ -5831,35 +5822,32 @@
// NOTE: POWERPC OPTIONAL, "Graphics Group" (PPC32_GX)
// Note: unclear whether this insn really exists or not
// ppc970 doesn't have it, but POWER5 does
- if (frA_addr !=3D 0 || frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,fres)\n");
+ if (frA_addr !=3D 0 || frC_addr !=3D 0)
return False;
- }
DIP("fre%s fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frB_addr);
- //assign( frD, unop(Iop_Est8FRecip, mkexpr(frB)) );
{ IRExpr* ieee_one
=3D IRExpr_Const(IRConst_F64i(0x3ff0000000000000ULL));
- assign( frD, binop(Iop_DivF64, ieee_one, mkexpr(frB)) );
+ /* Does this really depend on the rounding mode? Play safe
+ and use the default. */
+ assign( frD, triop( Iop_DivF64,=20
+ mkU32(Irrm_NEAREST),=20
+ ieee_one, mkexpr(frB) ));
}
break;
=20
case 0x19: // fmul (Floating Mult (Double Precision), PPC32 p413)
- if (frB_addr !=3D 0) {
+ if (frB_addr !=3D 0)
vex_printf("dis_fp_arith(ppc)(instr,fmul)\n");
- return False;
- }
DIP("fmul%s fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr);
- assign( frD, binop( Iop_MulF64, mkexpr(frA), mkexpr(frC) ) );
+ assign( frD, triop(Iop_MulF64, rm, mkexpr(frA), mkexpr(frC)) );
break;
=20
case 0x1A: // frsqrte (Floating Recip SqRt Est., PPC32 p424)
// NOTE: POWERPC OPTIONAL, "Graphics Group" (PPC32_GX)
- if (frA_addr !=3D 0 || frC_addr !=3D 0) {
- vex_printf("dis_fp_arith(ppc)(instr,frsqrte)\n");
+ if (frA_addr !=3D 0 || frC_addr !=3D 0)
return False;
- }
DIP("frsqrte%s fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frB_addr);
assign( frD, unop(Iop_Est5FRSqrt, mkexpr(frB)) );
@@ -5877,6 +5865,17 @@
}
=20
putFReg( frD_addr, mkexpr(frD) );
+
+ if (set_FPRF) {
+ // XXX XXX XXX FIXME
+ // set FPRF from frD
+ }
+
+ if (flag_rC && clear_CR1) {
+ putCR321( 1, mkU8(0) );
+ putCR0( 1, mkU8(0) );
+ }
+
return True;
}
=20
@@ -5896,56 +5895,81 @@
UChar opc2 =3D ifieldOPClo5(theInstr);
UChar flag_rC =3D ifieldBIT0(theInstr);
=20
- IRTemp frD =3D newTemp(Ity_F64);
- IRTemp frA =3D newTemp(Ity_F64);
- IRTemp frB =3D newTemp(Ity_F64);
- IRTemp frC =3D newTemp(Ity_F64);
+ IRTemp frD =3D newTemp(Ity_F64);
+ IRTemp frA =3D newTemp(Ity_F64);
+ IRTemp frB =3D newTemp(Ity_F64);
+ IRTemp frC =3D newTemp(Ity_F64);
+ IRTemp rmt =3D newTemp(Ity_I32);
+ IRExpr* rm;
=20
+ /* By default, we will examine the results of the operation and set
+ fpscr[FPRF] accordingly. */
+ Bool set_FPRF =3D True;
+
+ /* By default, if flag_RC is set, we will clear cr1 after the
+ operation. In reality we should set cr1 to indicate the
+ exception status of the operation, but since we're not
+ simulating exceptions, the exception status will appear to be
+ zero. Hence cr1 should be cleared if this is a . form insn. */
+ Bool clear_CR1 =3D True;
+
+ /* Bind the rounding mode expression to a temp; there's no
+ point in creating gratuitous CSEs, as we know we'll need=20
+ to use it twice. */
+ assign( rmt, get_IR_roundingmode() );
+ rm =3D mkexpr(rmt);
+
assign( frA, getFReg(frA_addr));
assign( frB, getFReg(frB_addr));
assign( frC, getFReg(frC_addr));
=20
+ /* The rounding in this is all a bit dodgy. The idea is to only do
+ one rounding. That clearly isn't achieveable without dedicated
+ four-input IR primops, although in the single precision case we
+ can sort-of simulate it by doing the inner multiply in double
+ precision.=20
+
+ In the negated cases, the negation happens after rounding. */
+
switch (opc1) {
case 0x3B:
switch (opc2) {
case 0x1C: // fmsubs (Floating Mult-Subtr Single, PPC32 p412)
DIP("fmsubs%s fr%u,fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr, frB_addr);
- assign( frD, roundToSgl( binop( Iop_SubF64,
- binop(Iop_MulF64, mkexpr(frA),
- mkexpr(frC)),
- mkexpr(frB)) ));
- break;
+ assign( frD, triop( Iop_SubF64r32, rm,
+ triop( Iop_MulF64, rm, mkexpr(frA),
+ mkexpr(frC) ),
+ mkexpr(frB) ));
+ break;
=20
case 0x1D: // fmadds (Floating Mult-Add Single, PPC32 p409)
DIP("fmadds%s fr%u,fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr, frB_addr);
- assign( frD, roundToSgl( binop( Iop_AddF64,
- binop(Iop_MulF64, mkexpr(frA),
- mkexpr(frC)),
- mkexpr(frB)) ));
+ assign( frD, triop( Iop_AddF64r32, rm,
+ triop( Iop_MulF64, rm, mkexpr(frA),
+ mkexpr(frC) ),
+ mkexpr(frB) ));
break;
=20
case 0x1E: // fnmsubs (Float Neg Mult-Subtr Single, PPC32 p420)
DIP("fnmsubs%s fr%u,fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr, frB_addr);
- assign( frD, roundToSgl(
- unop(Iop_NegF64,
- binop(Iop_SubF64,
- binop(Iop_MulF64, mkexpr(frA),
- mkexpr(frC)),
- mkexpr(frB))) ));
+ assign( frD, unop( Iop_NegF64,
+ triop( Iop_SubF64r32, rm,
+ triop( Iop_MulF64, rm, mkexpr(frA),
+ mkexpr(frC) ),
+ mkexpr(frB) )));
break;
=20
case 0x1F: // fnmadds (Floating Negative Multiply-Add Single, PPC3=
2 p418)
DIP("fnmadds%s fr%u,fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr, frB_addr);
- assign( frD, roundToSgl(
- unop(Iop_NegF64,
- binop(Iop_AddF64,
- binop(Iop_MulF64, mkexpr(frA),
- mkexpr(frC)),
- mkexpr(frB))) ));
+ assign( frD, unop( Iop_NegF64,
+ triop( Iop_AddF64r32, rm,
+ triop( Iop_MulF64, rm, mkexpr(frA),
+ mkexpr(frC) ),
+ mkexpr(frB) )));
break;
=20
default:
@@ -5959,18 +5983,18 @@
case 0x1C: // fmsub (Float Mult-Sub (Dbl Precision), PPC32 p411)
DIP("fmsub%s fr%u,fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr, frB_addr);
- assign( frD, binop( Iop_SubF64,
- binop( Iop_MulF64, mkexpr(frA),
- mkexpr(frC) ),
+ assign( frD, triop( Iop_SubF64, rm,
+ triop( Iop_MulF64, rm, mkexpr(frA),
+ mkexpr(frC) ),
mkexpr(frB) ));
break;
=20
case 0x1D: // fmadd (Float Mult-Add (Dbl Precision), PPC32 p408)
DIP("fmadd%s fr%u,fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr, frB_addr);
- assign( frD, binop( Iop_AddF64,
- binop( Iop_MulF64, mkexpr(frA),
- mkexpr(frC) ),
+ assign( frD, triop( Iop_AddF64, rm,
+ triop( Iop_MulF64, rm, mkexpr(frA),
+ mkexpr(frC) ),
mkexpr(frB) ));
break;
=20
@@ -5978,20 +6002,20 @@
DIP("fnmsub%s fr%u,fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr, frB_addr);
assign( frD, unop( Iop_NegF64,
- binop( Iop_SubF64,
- binop( Iop_MulF64, mkexpr(frA),
- mkexpr(frC) ),
- mkexpr(frB) )));
+ triop( Iop_SubF64, rm,
+ triop( Iop_MulF64, rm, mkexpr(frA),
+ mkexpr(frC) ),
+ mkexpr(frB) )));
break;
=20
case 0x1F: // fnmadd (Float Neg Mult-Add (Dbl Precision), PPC32 p4=
17)
DIP("fnmadd%s fr%u,fr%u,fr%u,fr%u\n", flag_rC ? ".":"",
frD_addr, frA_addr, frC_addr, frB_addr);
assign( frD, unop( Iop_NegF64,
- binop( Iop_AddF64,
- binop( Iop_MulF64, mkexpr(frA),
- mkexpr(frC) ),
- mkexpr(frB) )));
+ triop( Iop_AddF64, rm,
+ triop( Iop_MulF64, rm, mkexpr(frA),
+ mkexpr(frC) ),
+ mkexpr(frB) )));
break;
=20
default:
@@ -6006,6 +6030,17 @@
}
=20
putFReg( frD_addr, mkexpr(frD) );
+
+ if (set_FPRF) {
+ // XXX XXX XXX FIXME
+ // set FPRF from frD
+ }
+
+ if (flag_rC && clear_CR1) {
+ putCR321( 1, mkU8(0) );
+ putCR0( 1, mkU8(0) );
+ }
+
return True;
}
=20
@@ -6051,18 +6086,37 @@
LT | 0x8 | 0x01
*/
=20
- // ccPPC32 =3D Shl(1, (0x2 & ~(ccIR>>5)) || (0x1 & (XOR(ccIR, ccIR>>6=
))))
+ // ccPPC32 =3D Shl(1, (~(ccIR>>5) & 2)=20
+ // | ((ccIR ^ (ccIR>>6)) & 1)
assign(
ccPPC32,
- binop(Iop_Shl32, mkU32(1),
- unop(Iop_32to8,=20
- binop(Iop_Or32,
- binop(Iop_And32, mkU32(2),
- unop(Iop_Not32,
- binop(Iop_Shr32, mkexpr(ccIR), mkU8(5)=
))),
- binop(Iop_And32, mkU32(1),
- binop(Iop_Xor32, mkexpr(ccIR),
- binop(Iop_Shr32, mkexpr(ccIR), mkU8(6=
)))))))
+ binop(
+ Iop_Shl32,=20
+ mkU32(1),
+ unop(
+ Iop_32to8,=20
+ binop(
+ Iop_Or32,
+ binop(
+ Iop_And32,=20
+ unop(
+ Iop_Not32,
+ binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))
+ ),
+ mkU32(2)
+ ),
+ binop(
+ Iop_And32,=20
+ binop(
+ Iop_Xor32,=20
+ mkexpr(ccIR),
+ binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))
+ ),
+ mkU32(1)
+ )
+ )
+ )
+ )
);
=20
putGST_field( PPC_GST_CR, mkexpr(ccPPC32), crfD );
@@ -6070,6 +6124,8 @@
/* CAB: TODO?: Support writing cc to FPSCR->FPCC ?
putGST_field( PPC_GST_FPSCR, mkexpr(ccPPC32), 4 );
*/
+ // XXX XXX XXX FIXME
+ // Also write the result into FPRF (it's not entirely clear how)
=20
/* Note: Differences between fcmpu and fcmpo are only in exception
flag settings, which aren't supported anyway. */
@@ -6102,11 +6158,23 @@
UInt opc2 =3D ifieldOPClo10(theInstr);
UChar flag_rC =3D ifieldBIT0(theInstr);
=20
- IRTemp frD =3D newTemp(Ity_F64);
- IRTemp frB =3D newTemp(Ity_F64);
- IRTemp r_tmp32 =3D newTemp(Ity_I32);
- IRTemp r_tmp64 =3D newTemp(Ity_I64);
+ IRTemp frD =3D newTemp(Ity_F64);
+ IRTemp frB =3D newTemp(Ity_F64);
+ IRTemp r_tmp32 =3D newTemp(Ity_I32);
+ IRTemp r_tmp64 =3D newTemp(Ity_I64);
+ IRExpr* rm =3D get_IR_roundingmode();
=20
+ /* By default, we will examine the results of the operation and set
+ fpscr[FPRF] accordingly. */
+ Bool set_FPRF =3D True;
+
+ /* By default, if flag_RC is set, we will clear cr1 after the
+ operation. In reality we should set cr1 to indicate the
+ exception status of the operation, but since we're not
+ simulating exceptions, the exception status will appear to be
+ zero. Hence cr1 should be cleared if this is a . form insn. */
+ Bool clear_CR1 =3D True;
+ =20
if (opc1 !=3D 0x3F || b16to20 !=3D 0) {
vex_printf("dis_fp_round(ppc)(instr)\n");
return False;
@@ -6117,42 +6185,52 @@
switch (opc2) {
case 0x00C: // frsp (Float Round to Single, PPC32 p423)
DIP("frsp%s fr%u,fr%u\n", flag_rC ? ".":"", frD_addr, frB_addr);
- assign( frD, roundToSgl( mkexpr(frB) ));
+ assign( frD, binop( Iop_RoundF64toF32, rm, mkexpr(frB) ));
break;
=20
case 0x00E: // fctiw (Float Conv to Int, PPC32 p404)
DIP("fctiw%s fr%u,fr%u\n", flag_rC ? ".":"", frD_addr, frB_addr);
assign( r_tmp32,
- binop(Iop_F64toI32, get_roundingmode(), mkexpr(frB)) );
+ binop(Iop_F64toI32, rm, mkexpr(frB)) );
assign( frD, unop( Iop_ReinterpI64asF64,
unop( Iop_32Uto64, mkexpr(r_tmp32))));
+ /* FPRF is undefined after fctiw. Leave unchanged. */
+ set_FPRF =3D False;
break;
=20
case 0x00F: // fctiwz (Float Conv to Int, Round to Zero, PPC32 p405)
DIP("fctiwz%s fr%u,fr%u\n", flag_rC ? ".":"", frD_addr, frB_addr);
- assign( r_tmp32, binop(Iop_F64toI32, mkU32(Irrm_ZERO), mkexpr(frB)=
) );
+ assign( r_tmp32,=20
+ binop(Iop_F64toI32, mkU32(Irrm_ZERO), mkexpr(frB) ));
assign( frD, unop( Iop_ReinterpI64asF64,
unop( Iop_32Uto64, mkexpr(r_tmp32))));
+ /* FPRF is undefined after fctiwz. Leave unchanged. */
+ set_FPRF =3D False;
break;
=20
case 0x32E: // fctid (Float Conv to Int DWord, PPC64 p437)
DIP("fctid%s fr%u,fr%u\n", flag_rC ? ".":"", frD_addr, frB_addr);
assign( r_tmp64,
- binop(Iop_F64toI64, get_roundingmode(), mkexpr(frB)) );
+ binop(Iop_F64toI64, rm, mkexpr(frB)) );
assign( frD, unop( Iop_ReinterpI64asF64, mkexpr(r_tmp64)) );
+ /* FPRF is undefined after fctid. Leave unchanged. */
+ set_FPRF =3D False;
break;
=20
case 0x32F: // fctidz (Float Conv to Int DWord, Round to Zero, PPC64 =
p437)
DIP("fctidz%s fr%u,fr%u\n", flag_rC ? ".":"", frD_addr, frB_addr);
- assign( r_tmp64, binop(Iop_F64toI64, mkU32(Irrm_ZERO), mkexpr(frB)=
) );
+ assign( r_tmp64,=20
+ binop(Iop_F64toI64, mkU32(Irrm_ZERO), mkexpr(frB)) );
assign( frD, unop( Iop_ReinterpI64asF64, mkexpr(r_tmp64)) );
+ /* FPRF is undefined after fctidz. Leave unchanged. */
+ set_FPRF =3D False;
break;
=20
case 0x34E: // fcfid (Float Conv from Int DWord, PPC64 p434)
DIP("fcfid%s fr%u,fr%u\n", flag_rC ? ".":"", frD_addr, frB_addr);
assign( r_tmp64, unop( Iop_ReinterpF64asI64, mkexpr(frB)) );
- assign( frD, binop(Iop_I64toF64, get_roundingmode(),
- mkexpr(r_tmp64)) );
+ assign( frD,=20
+ binop(Iop_I64toF64, rm, mkexpr(r_tmp64)) );
break;
=20
default:
@@ -6161,6 +6239,17 @@
}
=20
putFReg( frD_addr, mkexpr(frD) );
+
+ if (set_FPRF) {
+ // XXX XXX XXX FIXME
+ // set FPRF from frD
+ }
+
+ if (flag_rC && clear_CR1) {
+ putCR321( 1, mkU8(0) );
+ putCR0( 1, mkU8(0) );
+ }
+
return True;
}
=20
@@ -6216,6 +6305,15 @@
}
=20
putFReg( frD_addr, mkexpr(frD) );
+
+ /* None of these change FPRF. cr1 is set in the usual way though,
+ if flag_rC is set. */
+
+ if (flag_rC) {
+ putCR321( 1, mkU8(0) );
+ putCR0( 1, mkU8(0) );
+ }
+
return True;
}
=20
@@ -9160,7 +9258,7 @@
decode_noFX:
vassert(!allow_FX);
vex_printf("disInstr(ppc): "
- "declined to decode an GeneralPurpose-Optional insn.\n"=
);
+ "declined to decode a GeneralPurpose-Optional insn.\n")=
;
goto decode_failure;
decode_noGX:
vassert(!allow_GX);
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-01-31 16:32:25 UTC (rev 1561)
+++ trunk/priv/guest-x86/toIR.c 2006-02-03 16:08:03 UTC (rev 1562)
@@ -3992,7 +3992,7 @@
case 0xFC: /* FRNDINT */
DIP("frndint\n");
put_ST_UNCHECKED(0,
- binop(Iop_RoundF64, get_roundingmode(), get_ST(0)) );
+ binop(Iop_RoundF64toInt, get_roundingmode(), get_ST(0)=
) );
break;
=20
case 0xFD: /* FSCALE */
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-01-31 16:32:25 UTC (rev 1561)
+++ trunk/priv/host-amd64/isel.c 2006-02-03 16:08:03 UTC (rev 1562)
@@ -2850,7 +2850,7 @@
//.. }
//.. }
=20
- if (e->tag =3D=3D Iex_Binop && e->Iex.Binop.op =3D=3D Iop_RoundF64) {
+ 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);
HReg dst =3D newVRegV(env);
Modified: trunk/priv/host-ppc/hdefs.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-ppc/hdefs.c 2006-01-31 16:32:25 UTC (rev 1561)
+++ trunk/priv/host-ppc/hdefs.c 2006-02-03 16:08:03 UTC (rev 1562)
@@ -612,10 +612,14 @@
=20
HChar* showPPCFpOp ( PPCFpOp op ) {
switch (op) {
- case Pfp_ADD: return "fadd";
- case Pfp_SUB: return "fsub";
- case Pfp_MUL: return "fmul";
- case Pfp_DIV: return "fdiv";
+ case Pfp_ADDD: return "fadd";
+ case Pfp_SUBD: return "fsub";
+ case Pfp_MULD: return "fmul";
+ case Pfp_DIVD: return "fdiv";
+ case Pfp_ADDS: return "fadds";
+ case Pfp_SUBS: return "fsubs";
+ case Pfp_MULS: return "fmuls";
+ case Pfp_DIVS: return "fdivs";
case Pfp_SQRT: return "fsqrt";
case Pfp_ABS: return "fabs";
case Pfp_NEG: return "fneg";
@@ -3155,18 +3159,30 @@
UInt fr_srcL =3D fregNo(i->Pin.FpBinary.srcL);
UInt fr_srcR =3D fregNo(i->Pin.FpBinary.srcR);
switch (i->Pin.FpBinary.op) {
- case Pfp_ADD: // fadd, PPC32 p400
+ case Pfp_ADDD: // fadd, PPC32 p400
p =3D mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 21, 0 );
break;
- case Pfp_SUB: // fsub, PPC32 p429
+ case Pfp_ADDS: // fadds, PPC32 p401
+ p =3D mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 21, 0 );
+ break;
+ case Pfp_SUBD: // fsub, PPC32 p429
p =3D mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 20, 0 );
break;
- case Pfp_MUL: // fmul, PPC32 p413
+ case Pfp_SUBS: // fsubs, PPC32 p430
+ p =3D mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 20, 0 );
+ break;
+ case Pfp_MULD: // fmul, PPC32 p413
p =3D mkFormA( p, 63, fr_dst, fr_srcL, 0, fr_srcR, 25, 0 );
break;
- case Pfp_DIV: // fdiv, PPC32 p406
+ case Pfp_MULS: // fmuls, PPC32 p414
+ p =3D mkFormA( p, 59, fr_dst, fr_srcL, 0, fr_srcR, 25, 0 );
+ break;
+ case Pfp_DIVD: // fdiv, PPC32 p406
p =3D mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 18, 0 );
break;
+ case Pfp_DIVS: // fdivs, PPC32 p407
+ p =3D mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 18, 0 );
+ break;
default:
goto bad;
}
Modified: trunk/priv/host-ppc/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-ppc/hdefs.h 2006-01-31 16:32:25 UTC (rev 1561)
+++ trunk/priv/host-ppc/hdefs.h 2006-02-03 16:08:03 UTC (rev 1562)
@@ -368,7 +368,8 @@
enum {
Pfp_INVALID,
/* Binary */
- Pfp_ADD, Pfp_SUB, Pfp_MUL, Pfp_DIV,=20
+ Pfp_ADDD, Pfp_SUBD, Pfp_MULD, Pfp_DIVD,=20
+ Pfp_ADDS, Pfp_SUBS, Pfp_MULS, Pfp_DIVS,=20
=20
/* Unary */
Pfp_SQRT, Pfp_ABS, Pfp_NEG, Pfp_MOV, Pfp_RES, Pfp_RSQRTE
Modified: trunk/priv/host-ppc/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-ppc/isel.c 2006-01-31 16:32:25 UTC (rev 1561)
+++ trunk/priv/host-ppc/isel.c 2006-02-03 16:08:03 UTC (rev 1562)
@@ -188,8 +188,11 @@
- A Bool to tell us if the host is 32 or 64bit.
This is set at the start and does not change.
=20
- Note, this is mostly host-independent.
- (JRS 20050201: well, kinda... Compare with ISelEnv for amd64.)
+ - An IRExpr*, which may be NULL, holding the IR expression (an
+ IRRoundingMode-encoded value) to which the FPU's rounding mode
+ was most recently set. Setting to NULL is always safe. Used to
+ avoid redundant settings of the FPU's rounding mode, as
+ described in set_FPU_rounding_mode below.
*/
=20
typedef
@@ -210,6 +213,8 @@
UInt hwcaps;
=20
Bool mode64;
+
+ IRExpr* previous_rm;
}
ISelEnv;
=20
@@ -359,7 +364,7 @@
return PPCInstr_Alu(Palu_OR, r_dst, r_src, PPCRH_Reg(r_src));
}
=20
-/* Advance/retreat %sp by n. */
+/* Advance/retreat %r1 by n. */
=20
static void add_to_sp ( ISelEnv* env, UInt n )
{
@@ -464,6 +469,73 @@
return am4;
}
=20
+
+/* Given a guest-state array descriptor, an index expression and a
+ bias, generate a PPCAMode pointing at the relevant piece of=20
+ guest state. Only needed in 64-bit mode. */
+static
+PPCAMode* genGuestArrayOffset ( ISelEnv* env, IRArray* descr,
+ IRExpr* off, Int bias )
+{
+ HReg rtmp, roff;
+ Int elemSz =3D sizeofIRType(descr->elemTy);
+ Int nElems =3D descr->nElems;
+ Int shift =3D 0;
+
+ vassert(env->mode64);
+
+ /* Throw out any cases we don't need. In theory there might be a
+ day where we need to handle others, but not today. */
+
+ if (nElems !=3D 16 && nElems !=3D 32)
+ vpanic("genGuestArrayOffset(ppc64 host)(1)");
+
+ switch (elemSz) {
+ case 8: shift =3D 3; break;
+ default: vpanic("genGuestArrayOffset(ppc64 host)(2)");
+ }
+
+ if (bias < -100 || bias > 100) /* somewhat arbitrarily */
+ vpanic("genGuestArrayOffset(ppc64 host)(3)");
+ if (descr->base < 0 || descr->base > 2000) /* somewhat arbitrarily */
+ vpanic("genGuestArrayOffset(ppc64 host)(4)");
+
+ /* Compute off into a reg, %off. Then return:
+
+ addi %tmp, %off, bias (if bias !=3D 0)
+ andi %tmp, nElems-1
+ sldi %tmp, shift
+ addi %tmp, %tmp, base
+ ... Baseblockptr + %tmp ...
+ */
+ roff =3D iselWordExpr_R(env, off);
+ rtmp =3D newVRegI(env);
+ addInstr(env, PPCInstr_Alu(
+ Palu_ADD,=20
+ rtmp, roff,=20
+ PPCRH_Imm(True/*signed*/, toUShort(bias))));
+ addInstr(env, PPCInstr_Alu(
+ Palu_AND,=20
+ rtmp, rtmp,=20
+ PPCRH_Imm(False/*signed*/, toUShort(nElems-1))));
+ addInstr(env, PPCInstr_Shft(
+ Pshft_SHL,=20
+ False/*64-bit shift*/,
+ rtmp, rtmp,=20
+ PPCRH_Imm(False/*unsigned*/, toUShort(shift))));
+ addInstr(env, PPCInstr_Alu(
+ Palu_ADD,=20
+ rtmp, rtmp,=20
+ PPCRH_Imm(True/*signed*/, toUShort(descr->base))));
+ return
+ PPCAMode_RR( GuestStatePtr(env->mode64), rtmp );
+}
+
+
+/*---------------------------------------------------------*/
+/*--- ISEL: Function call helpers ---*/
+/*---------------------------------------------------------*/
+
/* Used only in doHelperCall. See big comment in doHelperCall re
handling of register-parameter args. This function figures out
whether evaluation of an expression might require use of a fixed
@@ -715,126 +787,92 @@
}
=20
=20
-/* Given a guest-state array descriptor, an index expression and a
- bias, generate a PPCAMode pointing at the relevant piece of=20
- guest state. Only needed in 64-bit mode. */
-static
-PPCAMode* genGuestArrayOffset ( ISelEnv* env, IRArray* descr,
- IRExpr* off, Int bias )
-{
- HReg rtmp, roff;
- Int elemSz =3D sizeofIRType(descr->elemTy);
- Int nElems =3D descr->nElems;
- Int shift =3D 0;
+/*---------------------------------------------------------*/
+/*--- ISEL: FP rounding mode helpers ---*/
+/*---------------------------------------------------------*/
=20
- vassert(env->mode64);
+///* Set FPU's rounding mode to the default */
+//static=20
+//void set_FPU_rounding_default ( ISelEnv* env )
+//{
+// HReg fr_src =3D newVRegF(env);
+// HReg r_src =3D newVRegI(env);
+//
+// /* Default rounding mode =3D 0x0
+// Only supporting the rounding-mode bits - the rest of FPSCR is 0x=
0
+// - so we can set the whole register at once (faster)
+// note: upper 32 bits ignored by FpLdFPSCR
+// */
+// addInstr(env, PPCInstr_LI(r_src, 0x0, env->mode64));
+// if (env->mode64) {
+// fr_src =3D mk_LoadR64toFPR( env, r_src ); // 1*I64 -> F6=
4
+// } else {
+// fr_src =3D mk_LoadRR32toFPR( env, r_src, r_src ); // 2*I32 -> F6=
4
+// }
+// addInstr(env, PPCInstr_FpLdFPSCR( fr_src ));
+//}
=20
- /* Throw out any cases we don't need. In theory there might be a
- day where we need to handle others, but not today. */
-
- if (nElems !=3D 16 && nElems !=3D 32)
- vpanic("genGuestArrayOffset(ppc64 host)(1)");
-
- switch (elemSz) {
- case 8: shift =3D 3; break;
- default: vpanic("genGuestArrayOffset(ppc64 host)(2)");
- }
-
- if (bias < -100 || bias > 100) /* somewhat arbitrarily */
- vpanic("genGuestArrayOffset(ppc64 host)(3)");
- if (descr->base < 0 || descr->base > 2000) /* somewhat arbitrarily */
- vpanic("genGuestArrayOffset(ppc64 host)(4)");
-
- /* Compute off into a reg, %off. Then return:
-
- addi %tmp, %off, bias (if bias !=3D 0)
- andi %tmp, nElems-1
- sldi %tmp, shift
- addi %tmp, %tmp, base
- ... Baseblockptr + %tmp ...
- */
- roff =3D iselWordExpr_R(env, off);
- rtmp =3D newVRegI(env);
- addInstr(env, PPCInstr_Alu(
- Palu_ADD,=20
- rtmp, roff,=20
- PPCRH_Imm(True/*signed*/, toUShort(bias))));
- addInstr(env, PPCInstr_Alu(
- Palu_AND,=20
- rtmp, rtmp,=20
- PPCRH_Imm(False/*signed*/, toUShort(nElems-1))));
- addInstr(env, PPCInstr_Shft(
- Pshft_SHL,=20
- False/*64-bit shift*/,
- rtmp, rtmp,=20
- PPCRH_Imm(False/*unsigned*/, toUShort(shift))));
- addInstr(env, PPCInstr_Alu(
- Palu_ADD,=20
- rtmp, rtmp,=20
- PPCRH_Imm(True/*signed*/, toUShort(descr->base))));
- return
- PPCAMode_RR( GuestStatePtr(env->mode64), rtmp );
-}
-
-
-
-/* Set FPU's rounding mode to the default */
-static=20
-void set_FPU_rounding_default ( ISelEnv* env )
-{
- HReg fr_src =3D newVRegF(env);
- HReg r_src =3D newVRegI(env);
-
- /* Default rounding mode =3D 0x0
- Only supporting the rounding-mode bits - the rest of FPSCR is 0x0
- - so we can set the whole register at once (faster)
- note: upper 32 bits ignored by FpLdFPSCR
- */
- addInstr(env, PPCInstr_LI(r_src, 0x0, env->mode64));
- if (env->mode64) {
- fr_src =3D mk_LoadR64toFPR( env, r_src ); // 1*I64 -> F64
- } else {
- fr_src =3D mk_LoadRR32toFPR( env, r_src, r_src ); // 2*I32 -> F64
- }
- addInstr(env, PPCInstr_FpLdFPSCR( fr_src ));
-}
-
/* Convert IR rounding mode to PPC encoding */
static HReg roundModeIRtoPPC ( ISelEnv* env, HReg r_rmIR )
{
-/*=20
+ /*=20
rounding mode | PPC | IR
------------------------
to nearest | 00 | 00
to zero | 01 | 11
to +infinity | 10 | 10
to -infinity | 11 | 01
-*/
+ */
HReg r_rmPPC =3D newVRegI(env);
- HReg r_tmp =3D newVRegI(env);
+ HReg r_tmp1 =3D newVRegI(env);
=20
vassert(hregClass(r_rmIR) =3D=3D HRcGPR(env->mode64));
=20
- // AND r_rmIR,3 -- shouldn't be needed; paranoia
- addInstr(env, PPCInstr_Alu( Palu_AND, r_rmIR, r_rmIR,
+ // r_rmPPC =3D XOR(r_rmIR, r_rmIR << 1) & 3
+ //
+ // slwi tmp1, r_rmIR, 1
+ // xor tmp1, r_rmIR, tmp1
+ // andi r_rmPPC, tmp1, 3
+
+ addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
+ r_tmp1, r_rmIR, PPCRH_Imm(False,1)));
+
+ addInstr(env, PPCInstr_Alu( Palu_XOR, r_tmp1, r_rmIR,
+ PPCRH_Reg(r_tmp1) ));
+
+ addInstr(env, PPCInstr_Alu( Palu_AND, r_rmPPC, r_tmp1,
PPCRH_Imm(False,3) ));
=20
- // r_rmPPC =3D XOR( r_rmIR, (r_rmIR << 1) & 2)
- addInstr(env, PPCInstr_Shft(Pshft_SHL, True/*32bit shift*/,
- r_tmp, r_rmIR, PPCRH_Imm(False,1)));
- addInstr(env, PPCInstr_Alu( Palu_AND, r_tmp, r_tmp,
- PPCRH_Imm(False,2) ));
- addInstr(env, PPCInstr_Alu( Palu_XOR, r_rmPPC, r_rmIR,
- PPCRH_Reg(r_tmp) ));
return r_rmPPC;
}
=20
=20
-/* Mess with the FPU's rounding mode: 'mode' is an I32-typed
- expression denoting a value in the range 0 .. 3, indicating a round
- mode encoded as per type IRRoundingMode. Set the PPC FPSCR to have
- the same rounding.
+/* Set the FPU's rounding mode: 'mode' is an I32-typed expression
+ denoting a value in the range 0 .. 3, indicating a round mode
+ encoded as per type IRRoundingMode. Set the PPC FPSCR to have the
+ same rounding.
+
For speed & simplicity, we're setting the *entire* FPSCR here.
+
+ Setting the rounding mode is expensive. So this function tries to
+ avoid repeatedly setting the rounding mode to the same thing by
+ first comparing 'mode' to the 'mode' tree supplied in the previous
+ call to this function, if any. (The previous value is stored in
+ env->previous_rm.) If 'mode' is a single IR temporary 't' and
+ env->previous_rm is also just 't', then the setting is skipped.
+
+ This is safe because of the SSA property of IR: an IR temporary can
+ only be defined once and so will have the same value regardless of
+ where it appears in the block. Cool stuff, SSA.
+
+ A safety condition: all attempts to set the RM must be aware of
+ this mechanism - by being routed through the functions here.
+
+ Of course this only helps if blocks where the RM is set more than
+ once and it is set to the same value each time, *and* that value is
+ held in the same IR temporary each time. In order to assure the
+ latter as much as possible, the IR optimiser takes care to do CSE
+ on any block with any sign of floating point activity.
*/
static
void set_FPU_rounding_mode ( ISelEnv* env, IRExpr* mode )
@@ -843,11 +881,23 @@
HReg r_src;
=20
vassert(typeOfIRExpr(env->type_env,mode) =3D=3D Ity_I32);
+ =20
+ /* Do we need to do anything? */
+ if (env->previous_rm
+ && env->previous_rm->tag =3D=3D Iex_Tmp
+ && mode->tag =3D=3D Iex_Tmp
+ && env->previous_rm->Iex.Tmp.tmp =3D=3D mode->Iex.Tmp.tmp) {
+ /* no - setting it to what it was before. */
+ vassert(typeOfIRExpr(env->type_env, env->previous_rm) =3D=3D Ity_I=
32);
+ return;
+ }
=20
- /* Only supporting the rounding-mode bits - the rest of FPSCR is 0x0
- - so we can set the whole register at once (faster)
- */
+ /* No luck - we better set it, and remember what we set it to. */
+ env->previous_rm =3D mode;
=20
+ /* Only supporting the rounding-mode bits - the rest of FPSCR is
+ 0x0 - so we can set the whole register at once (faster). */
+
// Resolve rounding mode and convert to PPC representation
r_src =3D roundModeIRtoPPC( env, iselWordExpr_R(env, mode) );
// gpr -> fpr
@@ -862,6 +912,10 @@
}
=20
=20
+/*---------------------------------------------------------*/
+/*--- ISEL: vector helpers ---*/
+/*---------------------------------------------------------*/
+
/*
Generates code for AvSplat
- takes in IRExpr* of type 8|16|32
@@ -962,7 +1016,7 @@
mnts =3D newVRegV(env);
vIsNan =3D newVRegV(env);=20
=20
- /* 32bit float =3D> sign(1) | expontent(8) | mantissa(23)
+ /* 32bit float =3D> sign(1) | exponent(8) | mantissa(23)
nan =3D> exponent all ones, mantissa > 0 */
=20
addInstr(env, PPCInstr_AvBinary(Pav_AND, expt, vSrc, msk_exp));
@@ -1322,8 +1376,8 @@
=20
add_to_sp( env, 16 );
=20
- /* Restore default FPU rounding. */
- set_FPU_rounding_default( env );
+ ///* Restore default FPU rounding. */
+ //set_FPU_rounding_default( env );
return idst;
}
=20
@@ -1345,8 +1399,8 @@
addInstr(env, PPCInstr_Load(8, idst, zero_r1, True/*mode64*/=
));
add_to_sp( env, 16 );
=20
- /* Restore default FPU rounding. */
- set_FPU_rounding_default( env );
+ ///* Restore default FPU rounding. */
+ //set_FPU_rounding_default( env );
return idst;
}
}
@@ -2179,8 +2233,7 @@
HReg hi, lo;
HReg tmp =3D newVRegI(env);
iselInt64Expr( &hi, &lo, env, e->Iex.Unop.arg );
- addInstr(env, mk_iMOVds_RR(tmp, lo));
- addInstr(env, PPCInstr_Alu(Palu_OR, tmp, tmp, PPCRH_Reg(hi)));
+ addInstr(env, PPCInstr_Alu(Palu_OR, tmp, lo, PPCRH_Reg(hi)));
addInstr(env, PPCInstr_Cmp(False/*sign*/, True/*32bit cmp*/,
7/*cr*/, tmp,PPCRH_Imm(False,0)));
return mk_PPCCondCode( Pct_FALSE, Pcf_7EQ );
@@ -2501,8 +2554,8 @@
addInstr(env, PPCInstr_Load(4, tLo, four_r1, False/*mode32*/=
));
add_to_sp( env, 16 );
=20
- /* Restore default FPU rounding. */
- set_FPU_rounding_default( env );
+ ///* Restore default FPU rounding. */
+ //set_FPU_rounding_default( env );
*rHi =3D tHi;
*rLo =3D tLo;
return;
@@ -2681,19 +2734,6 @@
return r_dst;
}
=20
- if (e->tag =3D=3D Iex_Binop
- && e->Iex.Binop.op =3D=3D Iop_F64toF32) {
- /* Although the result is still held in a standard FPU register,
- we need to round it to reflect the loss of accuracy/range
- entailed in casting it to a 32-bit float. */
- HReg r_dst =3D newVRegF(env);
- HReg r_src =3D iselDblExpr(env, e->Iex.Binop.arg2);
- set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );
- addInstr(env, PPCInstr_FpRSP(r_dst, r_src));
- set_FPU_rounding_default( env );
- return r_dst;
- }
-
if (e->tag =3D=3D Iex_Get) {
HReg r_dst =3D newVRegF(env);
PPCAMode* am_addr =3D PPCAMode_IR( e->Iex.Get.offset,
@@ -2702,6 +2742,50 @@
return r_dst;
}
=20
+ if (e->tag =3D=3D Iex_Unop && e->Iex.Unop.op =3D=3D Iop_TruncF64asF32=
) {
+ /* This is quite subtle. The only way to do the relevant
+ truncation is to do a single-precision store and then a
+ double precision load to get it back into a register. The
+ problem is, if the data is then written to memory a second
+ time, as in
+
+ STbe(...) =3D TruncF64asF32(...)
+
+ then will the second truncation further alter the value? The
+ answer is no: flds (as generated here) followed by fsts
+ (generated for the STbe) is the identity function on 32-bit
+ floats, so we are safe.
+
+ Another upshot of this is that if iselStmt can see the
+ entirety of
+
+ STbe(...) =3D TruncF64asF32(arg)
+
+ then it can short circuit having to deal with TruncF64asF32
+ individually; instead just compute arg into a 64-bit FP
+ register and do 'fsts' (since that itself does the
+ truncation).
+
+ We generate pretty poor code here (should be ok both for
+ 32-bit and 64-bit mode); but it is expected that for the most
+ part the latter optimisation will apply and hence this code
+ will not often be used.
+ */
+ HReg fsrc =3D iselDblExpr(env, e->Iex.Unop.arg);
+ HReg fdst =3D newVRegF(env);
+ PPCAMode* zero_r1 =3D PPCAMode_IR( 0, StackFramePtr(env->mode64) )=
;
+
+ sub_from_sp( env, 16 );
+ // store as F32, hence truncating
+ addInstr(env, PPCInstr_FpLdSt( False/*store*/, 4,
+ fsrc, zero_r1 ));
+ // and reload. Good huh?! (sigh)
+ addInstr(env, PPCInstr_FpLdSt( True/*load*/, 4,
+ fdst, zero_r1 ));
+ add_to_sp( env, 16 );
+ return fdst;
+ }
+
vex_printf("iselFltExpr(ppc): No such tag(%u)\n", e->tag);
ppIRExpr(e);
vpanic("iselFltExpr_wrk(ppc)");
@@ -2805,23 +2889,40 @@
return r_dst;
}
=20
- if (e->tag =3D=3D Iex_Binop) {
+ if (e->tag =3D=3D Iex_Triop) {
PPCFpOp fpop =3D Pfp_INVALID;
- switch (e->Iex.Binop.op) {
- case Iop_AddF64: fpop =3D Pfp_ADD; break;
- case Iop_SubF64: fpop =3D Pfp_SUB; break;
- case Iop_MulF64: fpop =3D Pfp_MUL; break;
- case Iop_DivF64: fpop =3D Pfp_DIV; break;
- default: break;
+ switch (e->Iex.Triop.op) {
+ case Iop_AddF64: fpop =3D Pfp_ADDD; break;
+ case Iop_SubF64: fpop =3D Pfp_SUBD; break;
+ case Iop_MulF64: fpop =3D Pfp_MULD; break;
+ case Iop_DivF64: fpop =3D Pfp_DIVD; break;
+ case Iop_AddF64r32: fpop =3D Pfp_ADDS; break;
+ case Iop_SubF64r32: fpop =3D Pfp_SUBS; break;
+ case Iop_MulF64r32: fpop =3D Pfp_MULS; break;
+ case Iop_DivF64r32: fpop =3D Pfp_DIVS; break;
+ default: break;
}
if (fpop !=3D Pfp_INVALID) {
HReg r_dst =3D newVRegF(env);
- HReg r_srcL =3...
[truncated message content] |
|
From: Julian S. <js...@ac...> - 2006-02-03 15:36:50
|
Over the past few days I've been working on changes which cause Valgrind to properly observe the rounding mode in all floating point computations. These involve some changes throughout the vex infrastructure and minor changes to Valgrind (mc_translate.c). I'll start committing them shortly. This will cause the x86 and amd64 ports to break for a while, since the initial work has been done on ppc32. I hope to have everything back working within 24 hours. J |
|
From: <js...@ac...> - 2006-02-03 11:08:36
|
Nightly build on minnie ( SuSE 10.0, ppc32 ) started at 2006-02-03 05:00:01 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 190 tests, 11 stderr failures, 4 stdout failures ================= memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/mempool (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigaltstack (stderr) memcheck/tests/stack_changes (stdout) memcheck/tests/stack_changes (stderr) memcheck/tests/xml1 (stderr) none/tests/faultstatus (stderr) none/tests/mremap (stderr) none/tests/ppc32/jm-fp (stdout) none/tests/ppc32/jm-fp (stderr) none/tests/ppc32/test_fx (stdout) none/tests/ppc32/test_fx (stderr) none/tests/ppc32/test_gx (stdout) |
|
From: <js...@ac...> - 2006-02-03 04:03:03
|
Nightly build on phoenix ( SuSE 10.0 ) started at 2006-02-03 03:30:02 GMT Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 221 tests, 7 stderr failures, 0 stdout failures ================= memcheck/tests/leak-tree (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: <js...@ac...> - 2006-02-03 03:56:46
|
Nightly build on g5 ( YDL 4.0, ppc970 ) started at 2006-02-03 04:40:00 CET Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 194 tests, 6 stderr failures, 1 stdout failure ================= memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/leakotron (stdout) memcheck/tests/pointer-trace (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_fcntl (stderr) none/tests/mremap (stderr) |
|
From: Tom H. <to...@co...> - 2006-02-03 03:43:54
|
Nightly build on dunsmere ( athlon, Fedora Core 4 ) started at 2006-02-03 03:30:05 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 223 tests, 8 stderr failures, 1 stdout failure ================= memcheck/tests/leak-tree (stderr) memcheck/tests/mempool (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/sse1_memory (stdout) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2006-02-03 03:29:46
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2006-02-03 03:15:02 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 222 tests, 21 stderr failures, 1 stdout failure ================= memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/mempool (stderr) memcheck/tests/partial_load_dflt (stderr) memcheck/tests/partial_load_ok (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/sse1_memory (stdout) memcheck/tests/xml1 (stderr) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2006-02-03 03:22:14
|
Nightly build on dellow ( x86_64, Fedora Core 4 ) started at 2006-02-03 03:10:05 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 242 tests, 6 stderr failures, 1 stdout failure ================= memcheck/tests/pointer-trace (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/sse1_memory (stdout) none/tests/amd64/faultstatus (stderr) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2006-02-03 03:16:58
|
Nightly build on aston ( x86_64, Fedora Core 3 ) started at 2006-02-03 03:05:05 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 242 tests, 6 stderr failures, 1 stdout failure ================= memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/sse1_memory (stdout) none/tests/amd64/faultstatus (stderr) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |