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
(3) |
2
(26) |
3
(15) |
4
(19) |
5
(16) |
6
(16) |
7
(13) |
|
8
(1) |
9
(12) |
10
|
11
(4) |
12
(17) |
13
(21) |
14
(15) |
|
15
(12) |
16
(14) |
17
(14) |
18
(12) |
19
(16) |
20
(27) |
21
(37) |
|
22
(25) |
23
(23) |
24
(14) |
25
(14) |
26
(14) |
27
(14) |
28
(11) |
|
29
(3) |
30
(13) |
|
|
|
|
|
|
From: <sv...@va...> - 2012-04-29 20:20:23
|
sewardj 2012-04-29 21:20:16 +0100 (Sun, 29 Apr 2012)
New Revision: 12546
Log:
Test cases for POWER Power Decimal Floating Point (DFP) test class,
test group and test exponent instructions dtstdc, dtstdcq, dtstdg,
dtstdgq, dtstex and dtstexq. Bug #298862. (Carl Love,
ca...@us... and Maynard Johnson, may...@us...)
Added files:
trunk/none/tests/ppc64/test_dfp4.c
trunk/none/tests/ppc64/test_dfp4.stderr.exp
trunk/none/tests/ppc64/test_dfp4.stdout.exp
trunk/none/tests/ppc64/test_dfp4.vgtest
Modified files:
trunk/memcheck/mc_translate.c
trunk/none/tests/ppc32/Makefile.am
trunk/none/tests/ppc64/Makefile.am
Added: trunk/none/tests/ppc64/test_dfp4.vgtest (+2 -0)
===================================================================
--- trunk/none/tests/ppc64/test_dfp4.vgtest 2012-04-29 12:35:37 +01:00 (rev 12545)
+++ trunk/none/tests/ppc64/test_dfp4.vgtest 2012-04-29 21:20:16 +01:00 (rev 12546)
@@ -0,0 +1,2 @@
+prereq: ../../../tests/check_dfp_cap
+prog: test_dfp4
Added: trunk/none/tests/ppc64/test_dfp4.stderr.exp (+2 -0)
===================================================================
--- trunk/none/tests/ppc64/test_dfp4.stderr.exp 2012-04-29 12:35:37 +01:00 (rev 12545)
+++ trunk/none/tests/ppc64/test_dfp4.stderr.exp 2012-04-29 21:20:16 +01:00 (rev 12546)
@@ -0,0 +1,2 @@
+
+
Modified: trunk/none/tests/ppc32/Makefile.am (+6 -2)
===================================================================
--- trunk/none/tests/ppc32/Makefile.am 2012-04-29 12:35:37 +01:00 (rev 12545)
+++ trunk/none/tests/ppc32/Makefile.am 2012-04-29 21:20:16 +01:00 (rev 12546)
@@ -33,7 +33,8 @@
test_dfp1.stderr.exp test_dfp1.stdout.exp test_dfp1.vgtest \
test_dfp2.stderr.exp test_dfp2.stdout.exp test_dfp2.vgtest \
test_dfp2.stdout.exp_Without_dcffix \
- test_dfp3.stderr.exp test_dfp3.stdout.exp test_dfp3.vgtest
+ test_dfp3.stderr.exp test_dfp3.stdout.exp test_dfp3.vgtest \
+ test_dfp4.stderr.exp test_dfp4.stdout.exp test_dfp4.vgtest
check_PROGRAMS = \
allexec \
@@ -44,7 +45,7 @@
test_isa_2_06_part1 \
test_isa_2_06_part2 \
test_isa_2_06_part3 \
- test_dfp1 test_dfp2 test_dfp3
+ test_dfp1 test_dfp2 test_dfp3 test_dfp4
AM_CFLAGS += @FLAG_M32@
@@ -96,3 +97,6 @@
@FLAG_M32@ $(BUILD_FLAGS_DFP)
test_dfp3_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(DFP_FLAG) \
@FLAG_M32@ $(BUILD_FLAGS_DFP)
+
+test_dfp4_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(DFP_FLAG) \
+ @FLAG_M32@ $(BUILD_FLAGS_DFP)
Property changed: trunk/none/tests/ppc64/test_dfp4.stdout.exp (+0 -0)
___________________________________________________________________
Name: svn:special
+ *
Added: trunk/none/tests/ppc64/test_dfp4.stdout.exp (+1 -0)
===================================================================
--- trunk/none/tests/ppc64/test_dfp4.stdout.exp 2012-04-29 12:35:37 +01:00 (rev 12545)
+++ trunk/none/tests/ppc64/test_dfp4.stdout.exp 2012-04-29 21:20:16 +01:00 (rev 12546)
@@ -0,0 +1 @@
+link ../../../none/tests/ppc32/test_dfp4.stdout.exp
\ No newline at end of file
Property changed: trunk/none/tests/ppc64/test_dfp4.c (+0 -0)
___________________________________________________________________
Name: svn:special
+ *
Added: trunk/none/tests/ppc64/test_dfp4.c (+1 -0)
===================================================================
--- trunk/none/tests/ppc64/test_dfp4.c 2012-04-29 12:35:37 +01:00 (rev 12545)
+++ trunk/none/tests/ppc64/test_dfp4.c 2012-04-29 21:20:16 +01:00 (rev 12546)
@@ -0,0 +1 @@
+link ../../../none/tests/ppc32/test_dfp4.c
\ No newline at end of file
Modified: trunk/memcheck/mc_translate.c (+1 -0)
===================================================================
--- trunk/memcheck/mc_translate.c 2012-04-29 12:35:37 +01:00 (rev 12545)
+++ trunk/memcheck/mc_translate.c 2012-04-29 21:20:16 +01:00 (rev 12546)
@@ -3508,6 +3508,7 @@
case Iop_ReinterpI32asF32:
case Iop_ReinterpF32asI32:
case Iop_ReinterpI64asD64:
+ case Iop_ReinterpD64asI64:
case Iop_NotV128:
case Iop_Not64:
case Iop_Not32:
Modified: trunk/none/tests/ppc64/Makefile.am (+6 -2)
===================================================================
--- trunk/none/tests/ppc64/Makefile.am 2012-04-29 12:35:37 +01:00 (rev 12545)
+++ trunk/none/tests/ppc64/Makefile.am 2012-04-29 21:20:16 +01:00 (rev 12546)
@@ -21,12 +21,13 @@
test_dfp1.stderr.exp test_dfp1.stdout.exp test_dfp1.vgtest \
test_dfp2.stderr.exp test_dfp2.stdout.exp test_dfp2.vgtest \
test_dfp2.stdout.exp_Without_dcffix \
- test_dfp3.stderr.exp test_dfp3.stdout.exp test_dfp3.vgtest
+ test_dfp3.stderr.exp test_dfp3.stdout.exp test_dfp3.vgtest \
+ test_dfp4.stderr.exp test_dfp4.stdout.exp test_dfp4.vgtest
check_PROGRAMS = \
allexec \
jm-insns lsw round std_reg_imm twi_tdi tw_td power6_bcmp power6_mf_gpr test_isa_2_06_part1 \
- test_isa_2_06_part2 test_isa_2_06_part3 test_dfp1 test_dfp2 test_dfp3
+ test_isa_2_06_part2 test_isa_2_06_part3 test_dfp1 test_dfp2 test_dfp3 test_dfp4
AM_CFLAGS += @FLAG_M64@
AM_CXXFLAGS += @FLAG_M64@
@@ -75,3 +76,6 @@
@FLAG_M64@ $(BUILD_FLAGS_DFP)
test_dfp3_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(DFP_FLAG) \
@FLAG_M64@ $(BUILD_FLAGS_DFP)
+
+test_dfp4_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -lm -g -mregnames $(DFP_FLAG) \
+ @FLAG_M64@ $(BUILD_FLAGS_DFP)
|
|
From: <sv...@va...> - 2012-04-29 20:19:26
|
sewardj 2012-04-29 21:19:17 +0100 (Sun, 29 Apr 2012)
New Revision: 2317
Log:
Add support for POWER Power Decimal Floating Point (DFP) test class,
test group and test exponent instructions dtstdc, dtstdcq, dtstdg,
dtstdgq, dtstex and dtstexq. Bug #298862. (Carl Love,
ca...@us...)
Modified files:
trunk/priv/guest_ppc_toIR.c
trunk/priv/host_ppc_isel.c
trunk/priv/ir_defs.c
trunk/pub/libvex_ir.h
Modified: trunk/priv/ir_defs.c (+4 -0)
===================================================================
--- trunk/priv/ir_defs.c 2012-04-26 15:16:52 +01:00 (rev 2316)
+++ trunk/priv/ir_defs.c 2012-04-29 21:19:17 +01:00 (rev 2317)
@@ -975,6 +975,7 @@
case Iop_SignificanceRoundD128: vex_printf("Iop_SignificanceRoundD128");
return;
case Iop_ReinterpI64asD64: vex_printf("ReinterpI64asD64"); return;
+ case Iop_ReinterpD64asI64: vex_printf("ReinterpD64asI64"); return;
default: vpanic("ppIROp(1)");
}
@@ -2654,6 +2655,9 @@
case Iop_D64toD128:
UNARY(Ity_D64, Ity_D128);
+ case Iop_ReinterpD64asI64:
+ UNARY(Ity_D64, Ity_I64);
+
case Iop_ReinterpI64asD64:
UNARY(Ity_I64, Ity_D64);
Modified: trunk/priv/guest_ppc_toIR.c (+777 -0)
===================================================================
--- trunk/priv/guest_ppc_toIR.c 2012-04-26 15:16:52 +01:00 (rev 2316)
+++ trunk/priv/guest_ppc_toIR.c 2012-04-29 21:19:17 +01:00 (rev 2317)
@@ -8509,8 +8509,116 @@
}
/*------------------------------------------------------------*/
+/*--- Decimal Floating Point (DFP) Helper functions ---*/
+/*------------------------------------------------------------*/
+#define DFP_LONG 1
+#define DFP_EXTND 2
+#define DFP_LONG_ENCODED_FIELD_MASK 0x1F00
+#define DFP_EXTND_ENCODED_FIELD_MASK 0x1F000
+#define DFP_LONG_EXP_MSK 0XFF
+#define DFP_EXTND_EXP_MSK 0XFFF
+
+#define DFP_G_FIELD_LONG_MASK 0x7FFC0000 // upper 32-bits only
+#define DFP_LONG_GFIELD_RT_SHIFT (63 - 13 - 32) // adj for upper 32-bits
+#define DFP_G_FIELD_EXTND_MASK 0x7FFFC000 // upper 32-bits only
+#define DFP_EXTND_GFIELD_RT_SHIFT (63 - 17 - 32) //adj for upper 32 bits
+
+#define DFP_T_FIELD_LONG_MASK 0x3FFFF // mask for upper 32-bits
+#define DFP_T_FIELD_EXTND_MASK 0x03FFFF // mask for upper 32-bits
+
+#define DFP_LONG_EXP_MAX 369 // biased max
+#define DFP_LONG_EXP_MIN 0 // biased min
+#define DFP_EXTND_EXP_MAX 6111 // biased max
+#define DFP_EXTND_EXP_MIN 0 // biased min
+
+#define AND(x, y) binop( Iop_And32, x, y )
+#define OR(x, y) binop( Iop_Or32, x, y )
+#define AND4(w, x, y, z) AND( AND( w, x ), AND( y, z ) )
+#define OR3(x, y, z) OR( x, OR( y, z ) )
+#define OR4(w, x, y, z) OR( OR( w, x ), OR( y, z ) )
+#define SHL(value, by) binop( Iop_Shl32, value, mkU8( by ) )
+
+static void Get_lmd(IRTemp * lmd, IRExpr * gfield_0_4 )
+{
+
+ /* Extract the exponent and the left most digit of the mantissa
+ * from the G field bits [0:4].
+ */
+ IRTemp lmd_07_mask = newTemp( Ity_I32 );
+ IRTemp lmd_8_00_mask = newTemp( Ity_I32 );
+ IRTemp lmd_8_01_mask = newTemp( Ity_I32 );
+ IRTemp lmd_8_10_mask = newTemp( Ity_I32 );
+ IRTemp lmd_9_00_mask = newTemp( Ity_I32 );
+ IRTemp lmd_9_01_mask = newTemp( Ity_I32 );
+ IRTemp lmd_9_10_mask = newTemp( Ity_I32 );
+
+ IRTemp lmd_07_val = newTemp( Ity_I32 );
+ IRTemp lmd_8_val = newTemp( Ity_I32 );
+ IRTemp lmd_9_val = newTemp( Ity_I32 );
+
+ /* The left most digit (LMD) encoding is as follows:
+ * lmd
+ * 0 - 7 (lmexp << 3) | lmd
+ * 8 0b11000 (24 decimal) if lme=0b00;
+ * 0b11010 (26 decimal) if lme=0b01;
+ * 0b11100 (28 decimal) if lme=0b10
+ * 9 0b11001 (25 decimal) if lme=0b00;
+ * 0b11011 (27 decimal) if lme=0b01;
+ * 0b11101 (29 decimal) if lme=0b10;
+ */
+
+ /* Generate the masks for each condition of LMD and exponent bits */
+ assign( lmd_07_mask, unop( Iop_1Sto32, binop( Iop_CmpLE32U,
+ gfield_0_4,
+ mkU32( 0b10111 ) ) ) );
+ assign( lmd_8_00_mask, unop( Iop_1Sto32, binop( Iop_CmpEQ32,
+ gfield_0_4,
+ mkU32( 0b11000 ) ) ) );
+ assign( lmd_8_01_mask, unop( Iop_1Sto32, binop( Iop_CmpEQ32,
+ gfield_0_4,
+ mkU32( 0b11010 ) ) ) );
+ assign( lmd_8_10_mask, unop( Iop_1Sto32, binop( Iop_CmpEQ32,
+ gfield_0_4,
+ mkU32( 0b11100 ) ) ) );
+ assign( lmd_9_00_mask, unop( Iop_1Sto32, binop( Iop_CmpEQ32,
+ gfield_0_4,
+ mkU32( 0b11001 ) ) ) );
+ assign( lmd_9_01_mask, unop( Iop_1Sto32, binop( Iop_CmpEQ32,
+ gfield_0_4,
+ mkU32( 0b11011 ) ) ) );
+ assign( lmd_9_10_mask, unop( Iop_1Sto32, binop( Iop_CmpEQ32,
+ gfield_0_4,
+ mkU32( 0b11101 ) ) ) );
+
+ /* Generate the values for each LMD condition, assuming the condition
+ * is TRUE.
+ */
+ assign( lmd_07_val, binop( Iop_And32, gfield_0_4, mkU32( 0x7 ) ) );
+ assign( lmd_8_val, mkU32( 0x8 ) );
+ assign( lmd_9_val, mkU32( 0x9 ) );
+
+ assign( *lmd,
+ OR( OR3 ( AND( mkexpr( lmd_07_mask ), mkexpr( lmd_07_val ) ),
+ AND( mkexpr( lmd_8_00_mask ), mkexpr( lmd_8_val ) ),
+ AND( mkexpr( lmd_8_01_mask ), mkexpr( lmd_8_val ) )),
+ OR4( AND( mkexpr( lmd_8_10_mask ), mkexpr( lmd_8_val ) ),
+ AND( mkexpr( lmd_9_00_mask ), mkexpr( lmd_9_val ) ),
+ AND( mkexpr( lmd_9_01_mask ), mkexpr( lmd_9_val ) ),
+ AND( mkexpr( lmd_9_10_mask ), mkexpr( lmd_9_val ) )
+ ) ) );
+}
+
+#undef AND
+#undef OR
+#undef AND4
+#undef OR3
+#undef OR4
+#undef SHL
+
+/*------------------------------------------------------------*/
/*--- Decimal Floating Point (DFP) instruction translation ---*/
/*------------------------------------------------------------*/
+
/* DFP Arithmetic instructions */
static Bool dis_dfp_arith(UInt theInstr)
{
@@ -9228,6 +9336,651 @@
return True;
}
+/* Test class/group/exponent/significance instructions. */
+static Bool dis_dfp_exponent_test ( UInt theInstr )
+{
+ UChar frA_addr = ifieldRegA( theInstr );
+ UChar frB_addr = ifieldRegB( theInstr );
+ UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) );
+ IRTemp frA = newTemp( Ity_D64 );
+ IRTemp frB = newTemp( Ity_D64 );
+ IRTemp frA128 = newTemp( Ity_D128 );
+ IRTemp frB128 = newTemp( Ity_D128 );
+ UInt opc1 = ifieldOPC( theInstr );
+ IRTemp gfield_A = newTemp( Ity_I32 );
+ IRTemp gfield_B = newTemp( Ity_I32 );
+ IRTemp gfield_mask = newTemp( Ity_I32 );
+ IRTemp exponent_A = newTemp( Ity_I32 );
+ IRTemp exponent_B = newTemp( Ity_I32 );
+ IRTemp A_NaN_true = newTemp( Ity_I32 );
+ IRTemp B_NaN_true = newTemp( Ity_I32 );
+ IRTemp A_inf_true = newTemp( Ity_I32 );
+ IRTemp B_inf_true = newTemp( Ity_I32 );
+ IRTemp A_equals_B = newTemp( Ity_I32 );
+ IRTemp finite_number = newTemp( Ity_I32 );
+ IRTemp cc0 = newTemp( Ity_I32 );
+ IRTemp cc1 = newTemp( Ity_I32 );
+ IRTemp cc2 = newTemp( Ity_I32 );
+ IRTemp cc3 = newTemp( Ity_I32 );
+
+ /* The dtstex and dtstexg instructions only differ in the size of the
+ * exponent field. The following switch statement takes care of the size
+ * specific setup. Once the value of the exponents, the G-field shift
+ * and mask is setup the remaining code is identical.
+ */
+ switch (opc1) {
+ case 0x3b: // dtstex Extended instruction setup
+ DIP("dtstex %u,r%u,r%d\n", crfD, frA_addr, frB_addr);
+ assign( frA, getDReg( frA_addr ) );
+ assign( frB, getDReg( frB_addr ) );
+ assign( gfield_mask, mkU32( DFP_G_FIELD_LONG_MASK ) );
+ assign(exponent_A, unop( Iop_64to32,
+ unop( Iop_ReinterpD64asI64,
+ unop( Iop_ExtractExpD64,
+ mkexpr( frA ) ) ) ) );
+ assign(exponent_B, unop( Iop_64to32,
+ unop( Iop_ReinterpD64asI64,
+ unop( Iop_ExtractExpD64,
+ mkexpr( frB ) ) ) ) );
+ break;
+
+ case 0x3F: // dtstexq Quad instruction setup
+ DIP("dtstexq %u,r%u,r%d\n", crfD, frA_addr, frB_addr);
+ assign( frA128, getDReg_pair( frA_addr ) );
+ assign( frB128, getDReg_pair( frB_addr ) );
+ assign( frA, unop( Iop_D128HItoD64, mkexpr( frA128 ) ) );
+ assign( frB, unop( Iop_D128HItoD64, mkexpr( frB128 ) ) );
+ assign( gfield_mask, mkU32( DFP_G_FIELD_EXTND_MASK ) );
+ assign( exponent_A, unop( Iop_64to32,
+ unop( Iop_ReinterpD64asI64,
+ unop( Iop_ExtractExpD128,
+ mkexpr( frA128 ) ) ) ) );
+ assign( exponent_B, unop( Iop_64to32,
+ unop( Iop_ReinterpD64asI64,
+ unop( Iop_ExtractExpD128,
+ mkexpr( frB128 ) ) ) ) );
+ break;
+ default:
+ vex_printf("dis_dfp_exponent_test(ppc)(opc2)\n");
+ return False;
+ }
+
+ /* Extract the Gfield */
+ assign( gfield_A, binop( Iop_And32,
+ mkexpr( gfield_mask ),
+ unop( Iop_64HIto32,
+ unop( Iop_ReinterpD64asI64,
+ mkexpr(frA) ) ) ) );
+
+ assign( gfield_B, binop( Iop_And32,
+ mkexpr( gfield_mask ),
+ unop( Iop_64HIto32,
+ unop( Iop_ReinterpD64asI64,
+ mkexpr(frB) ) ) ) );
+
+ /* check for NAN */
+ assign( A_NaN_true, binop(Iop_Or32,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( gfield_A ),
+ mkU32( 0x7C000000 ) ) ),
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( gfield_A ),
+ mkU32( 0x7E000000 ) )
+ ) ) );
+ assign( B_NaN_true, binop(Iop_Or32,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( gfield_B ),
+ mkU32( 0x7C000000 ) ) ),
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( gfield_B ),
+ mkU32( 0x7E000000 ) )
+ ) ) );
+
+ /* check for infinity */
+ assign( A_inf_true,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( gfield_A ),
+ mkU32( 0x78000000 ) ) ) );
+
+ assign( B_inf_true,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( gfield_B ),
+ mkU32( 0x78000000 ) ) ) );
+
+ assign( finite_number,
+ unop( Iop_Not32,
+ binop( Iop_Or32,
+ binop( Iop_Or32,
+ mkexpr( A_NaN_true ),
+ mkexpr( B_NaN_true ) ),
+ binop( Iop_Or32,
+ mkexpr( A_inf_true ),
+ mkexpr( B_inf_true ) ) ) ) );
+
+ /* Calculate the condition code bits
+ * If QNaN,SNaN, +infinity, -infinity then cc0, cc1 and cc2 are zero
+ * regardless of the value of the comparisons and cc3 is 1. Otherwise,
+ * cc0, cc1 and cc0 reflect the results of the comparisons.
+ */
+ assign( A_equals_B,
+ binop( Iop_Or32,
+ unop( Iop_1Uto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( exponent_A ),
+ mkexpr( exponent_B ) ) ),
+ binop( Iop_Or32,
+ binop( Iop_And32,
+ mkexpr( A_inf_true ),
+ mkexpr( B_inf_true ) ),
+ binop( Iop_And32,
+ mkexpr( A_NaN_true ),
+ mkexpr( B_NaN_true ) ) ) ) );
+
+ assign( cc0, binop( Iop_And32,
+ mkexpr( finite_number ),
+ binop( Iop_Shl32,
+ unop( Iop_1Uto32,
+ binop( Iop_CmpLT32U,
+ mkexpr( exponent_A ),
+ mkexpr( exponent_B ) ) ),
+ mkU8( 3 ) ) ) );
+
+ assign( cc1, binop( Iop_And32,
+ mkexpr( finite_number ),
+ binop( Iop_Shl32,
+ unop( Iop_1Uto32,
+ binop( Iop_CmpLT32U,
+ mkexpr( exponent_B ),
+ mkexpr( exponent_A ) ) ),
+ mkU8( 2 ) ) ) );
+
+ assign( cc2, binop( Iop_Shl32,
+ binop( Iop_And32,
+ mkexpr( A_equals_B ),
+ mkU32( 1 ) ),
+ mkU8( 1 ) ) );
+
+ assign( cc3, binop( Iop_And32,
+ unop( Iop_Not32, mkexpr( A_equals_B ) ),
+ binop( Iop_And32,
+ mkU32( 0x1 ),
+ binop( Iop_Or32,
+ binop( Iop_Or32,
+ mkexpr ( A_inf_true ),
+ mkexpr ( B_inf_true ) ),
+ binop( Iop_Or32,
+ mkexpr ( A_NaN_true ),
+ mkexpr ( B_NaN_true ) ) )
+ ) ) );
+
+ /* store the condition code */
+ putGST_field( PPC_GST_CR,
+ binop( Iop_Or32,
+ mkexpr( cc0 ),
+ binop( Iop_Or32,
+ mkexpr( cc1 ),
+ binop( Iop_Or32,
+ mkexpr( cc2 ),
+ mkexpr( cc3 ) ) ) ),
+ crfD );
+ return True;
+}
+
+/* Test class/group/exponent/significance instructions. */
+static Bool dis_dfp_class_test ( UInt theInstr )
+{
+ UChar frA_addr = ifieldRegA( theInstr );
+ IRTemp frA = newTemp( Ity_D64 );
+ IRTemp abs_frA = newTemp( Ity_D64 );
+ IRTemp frAI64_hi = newTemp( Ity_I64 );
+ IRTemp frAI64_lo = newTemp( Ity_I64 );
+ UInt opc1 = ifieldOPC( theInstr );
+ UInt opc2 = ifieldOPClo9( theInstr );
+ UChar crfD = toUChar( IFIELD( theInstr, 23, 3 ) ); // AKA BF
+ UInt DCM = IFIELD( theInstr, 10, 6 );
+ IRTemp DCM_calc = newTemp( Ity_I32 );
+ UInt max_exp = 0;
+ UInt min_exp = 0;
+ IRTemp min_subnormalD64 = newTemp( Ity_D64 );
+ IRTemp min_subnormalD128 = newTemp( Ity_D128 );
+ IRTemp significand64 = newTemp( Ity_D64 );
+ IRTemp significand128 = newTemp( Ity_D128 );
+ IRTemp exp_min_normal = newTemp( Ity_D64 );
+ IRTemp exponent = newTemp( Ity_I32 );
+
+ IRTemp infinity_true = newTemp( Ity_I32 );
+ IRTemp SNaN_true = newTemp( Ity_I32 );
+ IRTemp QNaN_true = newTemp( Ity_I32 );
+ IRTemp subnormal_true = newTemp( Ity_I32 );
+ IRTemp normal_true = newTemp( Ity_I32 );
+ IRTemp extreme_true = newTemp( Ity_I32 );
+ IRTemp lmd = newTemp( Ity_I32 );
+ IRTemp lmd_zero_true = newTemp( Ity_I32 );
+ IRTemp zero_true = newTemp( Ity_I32 );
+ IRTemp sign = newTemp( Ity_I32 );
+ IRTemp field = newTemp( Ity_I32 );
+ IRTemp ccIR_zero = newTemp( Ity_I32 );
+ IRTemp ccIR_subnormal = newTemp( Ity_I32 );
+
+ /* UInt size = DFP_LONG; JRS:unused */
+ IRTemp gfield = newTemp( Ity_I32 );
+ IRTemp gfield_0_4_shift = newTemp( Ity_I8 );
+ IRTemp gfield_mask = newTemp( Ity_I32 );
+ IRTemp dcm0 = newTemp( Ity_I32 );
+ IRTemp dcm1 = newTemp( Ity_I32 );
+ IRTemp dcm2 = newTemp( Ity_I32 );
+ IRTemp dcm3 = newTemp( Ity_I32 );
+ IRTemp dcm4 = newTemp( Ity_I32 );
+ IRTemp dcm5 = newTemp( Ity_I32 );
+
+ /* The only difference between the dtstdc and dtstdcq instructions is
+ * size of the T and G fields. The calculation of the 4 bit field
+ * is the same. Setup the parameters and values that are DFP size
+ * specific. The rest of the code is independent of the DFP size.
+ *
+ * The Io_CmpD64 is used below. The instruction sets the ccIR values.
+ * The interpretation of the ccIR values is as follows:
+ *
+ * DFP cmp result | IR
+ * --------------------------
+ * UN | 0x45
+ * EQ | 0x40
+ * GT | 0x00
+ * LT | 0x01
+ */
+
+ assign( frA, getDReg( frA_addr ) );
+ assign( frAI64_hi, unop( Iop_ReinterpD64asI64, mkexpr( frA ) ) );
+
+ assign( abs_frA, unop( Iop_ReinterpI64asD64,
+ binop( Iop_And64,
+ unop( Iop_ReinterpD64asI64,
+ mkexpr( frA ) ),
+ mkU64( 0x7FFFFFFFFFFFFFFFULL ) ) ) );
+ assign( gfield_0_4_shift, mkU8( 31 - 5 ) ); // G-field[0:4]
+ switch (opc1) {
+ case 0x3b: // dtstdc, dtstdg
+ DIP("dtstd%s %u,r%u,%d\n", opc2 == 0xc2 ? "c" : "g",
+ crfD, frA_addr, DCM);
+ /* setup the parameters for the long format of the two instructions */
+ assign( frAI64_lo, mkU64( 0 ) );
+ assign( gfield_mask, mkU32( DFP_G_FIELD_LONG_MASK ) );
+ max_exp = DFP_LONG_EXP_MAX;
+ min_exp = DFP_LONG_EXP_MIN;
+
+ assign( exponent, unop( Iop_64to32,
+ unop( Iop_ReinterpD64asI64,
+ unop( Iop_ExtractExpD64,
+ mkexpr( frA ) ) ) ) );
+ assign( significand64,
+ unop( Iop_ReinterpI64asD64,
+ mkU64( 0x2234000000000001ULL ) ) ); // dfp 1.0
+ assign( exp_min_normal,
+ unop( Iop_ReinterpI64asD64, mkU64( 398 - 383 ) ) );
+ assign( min_subnormalD64,
+ binop( Iop_InsertExpD64,
+ mkexpr( exp_min_normal ),
+ mkexpr( significand64 ) ) );
+
+ assign( ccIR_subnormal,
+ binop( Iop_CmpD64,
+ mkexpr( abs_frA ),
+ mkexpr( min_subnormalD64 ) ) );
+
+ /* compare absolute value of frA with zero */
+ assign( ccIR_zero,
+ binop( Iop_CmpD64,
+ mkexpr( abs_frA ),
+ unop( Iop_ReinterpI64asD64,
+ mkU64( 0x2238000000000000ULL ) ) ) );
+
+ /* size = DFP_LONG; JRS: unused */
+ break;
+
+ case 0x3F: // dtstdcq, dtstdgq
+ DIP("dtstd%sq %u,r%u,%d\n", opc2 == 0xc2 ? "c" : "g",
+ crfD, frA_addr, DCM);
+ /* setup the parameters for the extended format of the
+ * two instructions
+ */
+ assign( frAI64_lo, unop( Iop_ReinterpD64asI64,
+ getDReg( frA_addr+1 ) ) );
+
+ assign( gfield_mask, mkU32( DFP_G_FIELD_EXTND_MASK ) );
+ max_exp = DFP_EXTND_EXP_MAX;
+ min_exp = DFP_EXTND_EXP_MIN;
+ assign( exponent, unop( Iop_64to32,
+ unop( Iop_ReinterpD64asI64,
+ unop( Iop_ExtractExpD128,
+ getDReg_pair( frA_addr) ) ) ) );
+
+ /* create quand exponent for minimum normal number */
+ assign( exp_min_normal,
+ unop( Iop_ReinterpI64asD64, mkU64( 6176 - 6143 ) ) );
+ assign( significand128,
+ unop( Iop_D64toD128,
+ unop( Iop_ReinterpI64asD64,
+ mkU64( 0x2234000000000001ULL ) ) ) ); // dfp 1.0
+
+ assign( min_subnormalD128,
+ binop( Iop_InsertExpD128,
+ mkexpr( exp_min_normal ),
+ mkexpr( significand128 ) ) );
+
+ assign( ccIR_subnormal,
+ binop( Iop_CmpD128,
+ binop( Iop_D64HLtoD128,
+ unop( Iop_ReinterpI64asD64,
+ binop( Iop_And64,
+ unop( Iop_ReinterpD64asI64,
+ mkexpr( frA ) ),
+ mkU64( 0x7FFFFFFFFFFFFFFFULL ) ) ),
+ getDReg( frA_addr+1 ) ),
+ mkexpr( min_subnormalD128 ) ) );
+ assign( ccIR_zero,
+ binop( Iop_CmpD128,
+ binop( Iop_D64HLtoD128,
+ mkexpr( abs_frA ),
+ getDReg( frA_addr+1 ) ),
+ unop( Iop_D64toD128,
+ unop( Iop_ReinterpI64asD64,
+ mkU64( 0x0ULL ) ) ) ) );
+
+ /* size = DFP_EXTND; JRS:unused */
+ break;
+ default:
+ vex_printf("dis_dfp_class_test(ppc)(opc2)\n");
+ return False;
+ }
+
+ /* The G-field is in the upper 32-bits. The I64 logical operations
+ * do not seem to be supported in 32-bit mode so keep things as 32-bit
+ * operations.
+ */
+ assign( gfield, binop( Iop_And32,
+ mkexpr( gfield_mask ),
+ unop( Iop_64HIto32,
+ mkexpr(frAI64_hi) ) ) );
+
+ /* There is a lot of code that is the same to do the class and group
+ * instructions. Later there is an if statement to handle the specific
+ * instruction.
+ *
+ * Will be using I32 values, compares, shifts and logical operations for
+ * this code as the 64-bit compare, shifts, logical operations are not
+ * supported in 32-bit mode.
+ */
+
+ /* Check the bits for Infinity, QNaN or Signaling NaN */
+ assign( infinity_true,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ binop( Iop_And32,
+ mkU32( 0x7C000000 ),
+ mkexpr( gfield ) ),
+ mkU32( 0x78000000 ) ) ) );
+
+ assign( SNaN_true,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ binop( Iop_And32,
+ mkU32( 0x7E000000 ),
+ mkexpr( gfield ) ),
+ mkU32( 0x7E000000 ) ) ) );
+
+ assign( QNaN_true,
+ binop( Iop_And32,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ binop( Iop_And32,
+ mkU32( 0x7E000000 ),
+ mkexpr( gfield ) ),
+ mkU32( 0x7C000000 ) ) ),
+ unop( Iop_Not32,
+ mkexpr( SNaN_true ) ) ) );
+
+ assign( zero_true,
+ binop( Iop_And32,
+ unop(Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( ccIR_zero ),
+ mkU32( 0x40 ) ) ), // ccIR code for Equal
+ unop( Iop_Not32,
+ binop( Iop_Or32,
+ mkexpr( infinity_true ),
+ binop( Iop_Or32,
+ mkexpr( QNaN_true ),
+ mkexpr( SNaN_true ) ) ) ) ) );
+
+ /* Do compare of frA the minimum normal value. Comparison is size
+ * depenent and was done above to get the ccIR value.
+ */
+ assign( subnormal_true,
+ binop( Iop_And32,
+ binop( Iop_Or32,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( ccIR_subnormal ),
+ mkU32( 0x40 ) ) ), // ccIR code for Equal
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( ccIR_subnormal ),
+ mkU32( 0x1 ) ) ) ), // ccIR code for LT
+ unop( Iop_Not32,
+ binop( Iop_Or32,
+ binop( Iop_Or32,
+ mkexpr( infinity_true ),
+ mkexpr( zero_true) ),
+ binop( Iop_Or32,
+ mkexpr( QNaN_true ),
+ mkexpr( SNaN_true ) ) ) ) ) );
+
+ /* Normal number is not subnormal, infinity, NaN or Zero */
+ assign( normal_true,
+ unop( Iop_Not32,
+ binop( Iop_Or32,
+ binop( Iop_Or32,
+ mkexpr( infinity_true ),
+ mkexpr( zero_true ) ),
+ binop( Iop_Or32,
+ mkexpr( subnormal_true ),
+ binop( Iop_Or32,
+ mkexpr( QNaN_true ),
+ mkexpr( SNaN_true ) ) ) ) ) );
+
+ /* Calculate the DCM bit field based on the tests for the specific
+ * instruction
+ */
+ if (opc2 == 0xC2) { // dtstdc, dtstdcq
+ /* DCM[0:5] Bit Data Class definition
+ * 0 Zero
+ * 1 Subnormal
+ * 2 Normal
+ * 3 Infinity
+ * 4 Quiet NaN
+ * 5 Signaling NaN
+ */
+
+ assign( dcm0, binop( Iop_Shl32,
+ mkexpr( zero_true ),
+ mkU8( 5 ) ) );
+ assign( dcm1, binop( Iop_Shl32,
+ binop( Iop_And32,
+ mkexpr( subnormal_true ),
+ mkU32( 1 ) ),
+ mkU8( 4 ) ) );
+ assign( dcm2, binop( Iop_Shl32,
+ binop( Iop_And32,
+ mkexpr( normal_true ),
+ mkU32( 1 ) ),
+ mkU8( 3 ) ) );
+ assign( dcm3, binop( Iop_Shl32,
+ binop( Iop_And32,
+ mkexpr( infinity_true),
+ mkU32( 1 ) ),
+ mkU8( 2 ) ) );
+ assign( dcm4, binop( Iop_Shl32,
+ binop( Iop_And32,
+ mkexpr( QNaN_true ),
+ mkU32( 1 ) ),
+ mkU8( 1 ) ) );
+ assign( dcm5, binop( Iop_And32, mkexpr( SNaN_true), mkU32( 1 ) ) );
+
+ } else if (opc2 == 0xE2) { // dtstdg, dtstdgq
+ /* check if the exponent is extreme */
+ assign( extreme_true, binop( Iop_Or32,
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( exponent ),
+ mkU32( max_exp ) ) ),
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( exponent ),
+ mkU32( min_exp ) ) ) ) );
+
+ /* Check if LMD is zero */
+ Get_lmd( &lmd, binop( Iop_Shr32,
+ mkexpr( gfield ), mkU8( 31 - 5 ) ) );
+
+ assign( lmd_zero_true, unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( lmd ),
+ mkU32( 0 ) ) ) );
+
+ /* DCM[0:5] Bit Data Class definition
+ * 0 Zero with non-extreme exponent
+ * 1 Zero with extreme exponent
+ * 2 Subnormal or (Normal with extreme exponent)
+ * 3 Normal with non-extreme exponent and
+ * leftmost zero digit in significand
+ * 4 Normal with non-extreme exponent and
+ * leftmost nonzero digit in significand
+ * 5 Special symbol (Infinity, QNaN, or SNaN)
+ */
+ assign( dcm0, binop( Iop_Shl32,
+ binop( Iop_And32,
+ binop( Iop_And32,
+ unop( Iop_Not32,
+ mkexpr( extreme_true ) ),
+ mkexpr( zero_true ) ),
+ mkU32( 0x1 ) ),
+ mkU8( 5 ) ) );
+
+ assign( dcm1, binop( Iop_Shl32,
+ binop( Iop_And32,
+ binop( Iop_And32,
+ mkexpr( extreme_true ),
+ mkexpr( zero_true ) ),
+ mkU32( 0x1 ) ),
+ mkU8( 4 ) ) );
+
+ assign( dcm2, binop( Iop_Shl32,
+ binop( Iop_And32,
+ binop( Iop_Or32,
+ binop( Iop_And32,
+ mkexpr( extreme_true ),
+ mkexpr( normal_true ) ),
+ mkexpr( subnormal_true ) ),
+ mkU32( 0x1 ) ),
+ mkU8( 3 ) ) );
+
+ assign( dcm3, binop( Iop_Shl32,
+ binop( Iop_And32,
+ binop( Iop_And32,
+ binop( Iop_And32,
+ unop( Iop_Not32,
+ mkexpr( extreme_true ) ),
+ mkexpr( normal_true ) ),
+ unop( Iop_1Sto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( lmd ),
+ mkU32( 0 ) ) ) ),
+ mkU32( 0x1 ) ),
+ mkU8( 2 ) ) );
+
+ assign( dcm4, binop( Iop_Shl32,
+ binop( Iop_And32,
+ binop( Iop_And32,
+ binop( Iop_And32,
+ unop( Iop_Not32,
+ mkexpr( extreme_true ) ),
+ mkexpr( normal_true ) ),
+ unop( Iop_1Sto32,
+ binop( Iop_CmpNE32,
+ mkexpr( lmd ),
+ mkU32( 0 ) ) ) ),
+ mkU32( 0x1 ) ),
+ mkU8( 1 ) ) );
+
+ assign( dcm5, binop( Iop_And32,
+ binop( Iop_Or32,
+ mkexpr( SNaN_true),
+ binop( Iop_Or32,
+ mkexpr( QNaN_true),
+ mkexpr( infinity_true) ) ),
+ mkU32( 0x1 ) ) );
+ }
+
+ /* create DCM field */
+ assign( DCM_calc,
+ binop( Iop_Or32,
+ mkexpr( dcm0 ),
+ binop( Iop_Or32,
+ mkexpr( dcm1 ),
+ binop( Iop_Or32,
+ mkexpr( dcm2 ),
+ binop( Iop_Or32,
+ mkexpr( dcm3 ),
+ binop( Iop_Or32,
+ mkexpr( dcm4 ),
+ mkexpr( dcm5 ) ) ) ) ) ) );
+
+ /* Get the sign of the DFP number, ignore sign for QNaN */
+ assign( sign,
+ unop( Iop_1Uto32,
+ binop( Iop_CmpEQ32,
+ binop( Iop_Shr32,
+ unop( Iop_64HIto32, mkexpr( frAI64_hi ) ),
+ mkU8( 63 - 32 ) ),
+ mkU32( 1 ) ) ) );
+
+ /* This instruction generates a four bit field to be stored in the
+ * condition code register. The condition code register consists of 7
+ * fields. The field to be written to is specified by the BF (AKA crfD)
+ * field.
+ *
+ * The field layout is as follows:
+ *
+ * Field Meaning
+ * 0000 Operand positive with no match
+ * 0100 Operand positive with at least one match
+ * 0001 Operand negative with no match
+ * 0101 Operand negative with at least one match
+ */
+ assign( field, binop( Iop_Or32,
+ binop( Iop_Shl32,
+ mkexpr( sign ),
+ mkU8( 3 ) ),
+ binop( Iop_Shl32,
+ unop( Iop_1Uto32,
+ binop( Iop_CmpNE32,
+ binop( Iop_And32,
+ mkU32( DCM ),
+ mkexpr( DCM_calc ) ),
+ mkU32( 0 ) ) ),
+ mkU8( 1 ) ) ) );
+
+ putGST_field( PPC_GST_CR, mkexpr( field ), crfD );
+ return True;
+}
+
+
/*------------------------------------------------------------*/
/*--- AltiVec Instruction Translation ---*/
/*------------------------------------------------------------*/
@@ -14465,6 +15218,13 @@
if (dis_dfp_shift( theInstr ))
goto decode_success;
goto decode_failure;
+ case 0xc2: // dtstdc, DFP test data class
+ case 0xe2: // dtstdg, DFP test data group
+ if (!allow_DFP)
+ goto decode_failure;
+ if (dis_dfp_class_test( theInstr ))
+ goto decode_success;
+ goto decode_failure;
}
opc2 = ifieldOPClo8( theInstr );
@@ -14477,6 +15237,12 @@
if (dis_dfp_quantize_sig_rrnd( theInstr ) )
goto decode_success;
goto decode_failure;
+ case 0xA2: // dtstex - DFP Test exponent
+ if (!allow_DFP)
+ goto decode_failure;
+ if (dis_dfp_exponent_test( theInstr ) )
+ goto decode_success;
+ goto decode_failure;
case 0x63: // drintx - Round to an integer value
case 0xE3: // drintn - Round to an integer value
if (!allow_DFP)
@@ -14799,6 +15565,13 @@
if (dis_dfp_shiftq( theInstr ))
goto decode_success;
goto decode_failure;
+ case 0xc2: // dtstdc, DFP test data class
+ case 0xe2: // dtstdg, DFP test data group
+ if (!allow_DFP)
+ goto decode_failure;
+ if (dis_dfp_class_test( theInstr ))
+ goto decode_success;
+ goto decode_failure;
default:
break;
}
@@ -14813,6 +15586,10 @@
if (dis_dfp_quantize_sig_rrndq( theInstr ))
goto decode_success;
goto decode_failure;
+ case 0xA2: // dtstexq - DFP Test exponent Quad
+ if (dis_dfp_exponent_test( theInstr ) )
+ goto decode_success;
+ goto decode_failure;
case 0x63: // drintxq - DFP Round to an integer value
case 0xE3: // drintnq - DFP Round to an integer value
if (!allow_DFP)
Modified: trunk/pub/libvex_ir.h (+3 -0)
===================================================================
--- trunk/pub/libvex_ir.h 2012-04-26 15:16:52 +01:00 (rev 2316)
+++ trunk/pub/libvex_ir.h 2012-04-29 21:19:17 +01:00 (rev 2317)
@@ -1107,6 +1107,9 @@
/* Conversion I64 -> D64 */
Iop_ReinterpI64asD64,
+ /* Conversion D64 -> I64 */
+ Iop_ReinterpD64asI64,
+
/* ------------------ 128-bit SIMD FP. ------------------ */
/* --- 32x4 vector FP --- */
Modified: trunk/priv/host_ppc_isel.c (+49 -0)
===================================================================
--- trunk/priv/host_ppc_isel.c 2012-04-26 15:16:52 +01:00 (rev 2316)
+++ trunk/priv/host_ppc_isel.c 2012-04-29 21:19:17 +01:00 (rev 2317)
@@ -1983,7 +1983,28 @@
add_to_sp( env, 16 ); // Reset SP
return r_dst;
}
+ break;
+ case Iop_ReinterpD64asI64:
+ if (mode64) {
+ PPCAMode *am_addr;
+ HReg fr_src = iselDfp64Expr(env, e->Iex.Unop.arg);
+ HReg r_dst = newVRegI(env);
+
+ sub_from_sp( env, 16 ); // Move SP down 16 bytes
+ am_addr = PPCAMode_IR( 0, StackFramePtr(mode64) );
+
+ // store as D64
+ addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
+ fr_src, am_addr ));
+ // load as Ity_I64
+ addInstr(env, PPCInstr_Load( 8, r_dst, am_addr, mode64 ));
+ add_to_sp( env, 16 ); // Reset SP
+ return r_dst;
+ }
+
+ break;
+
default:
break;
}
@@ -3132,6 +3153,34 @@
return;
}
+ case Iop_ReinterpD64asI64: {
+ HReg fr_src = iselDfp64Expr(env, e->Iex.Unop.arg);
+ PPCAMode *am_addr0, *am_addr1;
+ HReg r_dstLo = newVRegI(env);
+ HReg r_dstHi = newVRegI(env);
+
+
+ sub_from_sp( env, 16 ); // Move SP down 16 bytes
+ am_addr0 = PPCAMode_IR( 0, StackFramePtr(False/*mode32*/) );
+ am_addr1 = PPCAMode_IR( 4, StackFramePtr(False/*mode32*/) );
+
+ // store as D64
+ addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8,
+ fr_src, am_addr0 ));
+
+ // load hi,lo as Ity_I32's
+ addInstr(env, PPCInstr_Load( 4, r_dstHi,
+ am_addr0, False/*mode32*/ ));
+ addInstr(env, PPCInstr_Load( 4, r_dstLo,
+ am_addr1, False/*mode32*/ ));
+ *rHi = r_dstHi;
+ *rLo = r_dstLo;
+
+ add_to_sp( env, 16 ); // Reset SP
+
+ return;
+ }
+
default:
break;
}
|
|
From: <sv...@va...> - 2012-04-29 11:35:45
|
sewardj 2012-04-29 12:35:37 +0100 (Sun, 29 Apr 2012)
New Revision: 12545
Log:
Correctly parse DW_FORM_ref_addr -- its format is different in Dwarf2
vs Dwarf3 and later. Fixes #298864. (Tom Tromey, tr...@re...)
Modified files:
trunk/coregrind/m_debuginfo/readdwarf3.c
Modified: trunk/coregrind/m_debuginfo/readdwarf3.c (+10 -2)
===================================================================
--- trunk/coregrind/m_debuginfo/readdwarf3.c 2012-04-27 23:59:43 +01:00 (rev 12544)
+++ trunk/coregrind/m_debuginfo/readdwarf3.c 2012-04-29 12:35:37 +01:00 (rev 12545)
@@ -1121,9 +1121,17 @@
So for the moment we merely range-check, to see that they
actually do specify a plausible offset within this
object's .debug_info, and return the value unchanged.
+
+ In DWARF 2, DW_FORM_ref_addr is address-sized, but in
+ DWARF 3 and later, it is offset-sized.
*/
- *cts = (ULong)(UWord)get_UWord(c);
- *ctsSzB = sizeof(UWord);
+ if (cc->version == 2) {
+ *cts = (ULong)(UWord)get_UWord(c);
+ *ctsSzB = sizeof(UWord);
+ } else {
+ *cts = get_Dwarfish_UWord(c, cc->is_dw64);
+ *ctsSzB = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
+ }
TRACE_D3("0x%lx", (UWord)*cts);
if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)*cts);
if (/* the following 2 are surely impossible, but ... */
|