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
(1) |
|
2
(19) |
3
(17) |
4
(15) |
5
(20) |
6
(29) |
7
(13) |
8
(16) |
|
9
(20) |
10
(5) |
11
(10) |
12
(17) |
13
(17) |
14
(22) |
15
(8) |
|
16
(4) |
17
(15) |
18
(7) |
19
(14) |
20
(16) |
21
(18) |
22
(9) |
|
23
(2) |
24
(12) |
25
(3) |
26
(3) |
27
(20) |
28
(9) |
29
(4) |
|
30
(3) |
31
(4) |
|
|
|
|
|
|
From: Philippe W. <phi...@sk...> - 2012-12-24 04:47:19
|
valgrind revision: 13197 VEX revision: 2616 C compiler: gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2) Assembler: GNU assembler version 2.21.53.0.1-6.fc16 20110716 C library: GNU C Library development release version 2.14.90 uname -mrs: Linux 3.3.1-3.fc16.ppc64 ppc64 Vendor version: Fedora release 16 (Verne) Nightly build on gcc110 ( Fedora release 16 (Verne), ppc64 ) Started at 2012-12-23 20:00:09 PST Ended at 2012-12-23 20:45:34 PST 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 == 542 tests, 10 stderr failures, 5 stdout failures, 1 stderrB failure, 1 stdoutB failure, 2 post failures == gdbserver_tests/mcmain_pic (stdout) gdbserver_tests/mcmain_pic (stderr) gdbserver_tests/mcmain_pic (stdoutB) gdbserver_tests/mcmain_pic (stderrB) memcheck/tests/linux/getregset (stdout) memcheck/tests/linux/getregset (stderr) memcheck/tests/supp_unknown (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/vbit-test/vbit-test (stderr) memcheck/tests/wrap8 (stdout) memcheck/tests/wrap8 (stderr) massif/tests/big-alloc (post) massif/tests/deep-D (post) none/tests/ppc32/test_dfp2 (stdout) none/tests/ppc32/test_dfp2 (stderr) none/tests/ppc64/test_dfp2 (stdout) none/tests/ppc64/test_dfp2 (stderr) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) |
|
From: Christian B. <bor...@de...> - 2012-12-24 03:13:26
|
valgrind revision: 13197 VEX revision: 2616 C compiler: gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973] Assembler: GNU assembler (GNU Binutils; SUSE Linux Enterprise 11) 2.21.1 C library: GNU C Library stable release version 2.11.3 (20110527) uname -mrs: Linux 3.0.42-0.7-default s390x Vendor version: Welcome to SUSE Linux Enterprise Server 11 SP2 (s390x) - Kernel %r (%t). Nightly build on sless390 ( SUSE Linux Enterprise Server 11 SP1 gcc 4.3.4 on z196 (s390x) ) Started at 2012-12-24 03:45:01 CET Ended at 2012-12-24 04:13:16 CET Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... done Regression test results follow == 618 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... done Regression test results follow == 616 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Mon Dec 24 03:59:17 2012 --- new.short Mon Dec 24 04:13:16 2012 *************** *** 8,10 **** ! == 616 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == --- 8,10 ---- ! == 618 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == |
|
From: Christian B. <bor...@de...> - 2012-12-24 03:09:32
|
valgrind revision: 13197 VEX revision: 2616 C compiler: gcc (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9bb4) Assembler: GNU assembler version 2.21.51.0.6-6bb6.fc15 20110118 C library: GNU C Library stable release version 2.14.1 uname -mrs: Linux 3.6.8-57.x.20121204-s390xperformance s390x Vendor version: unknown Nightly build on fedora390 ( Fedora 15 with devel libc/toolchain on z196 (s390x) ) Started at 2012-12-24 03:45:01 CET Ended at 2012-12-24 04:09:37 CET Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 619 tests, 2 stderr failures, 0 stdout failures, 6 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcbreak (stderrB) gdbserver_tests/mcclean_after_fork (stderrB) gdbserver_tests/mcleak (stderrB) gdbserver_tests/mcmain_pic (stderrB) gdbserver_tests/mcvabits (stderrB) gdbserver_tests/mssnapshot (stderrB) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 617 tests, 2 stderr failures, 0 stdout failures, 6 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcbreak (stderrB) gdbserver_tests/mcclean_after_fork (stderrB) gdbserver_tests/mcleak (stderrB) gdbserver_tests/mcmain_pic (stderrB) gdbserver_tests/mcvabits (stderrB) gdbserver_tests/mssnapshot (stderrB) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Mon Dec 24 03:57:22 2012 --- new.short Mon Dec 24 04:09:37 2012 *************** *** 8,10 **** ! == 617 tests, 2 stderr failures, 0 stdout failures, 6 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcbreak (stderrB) --- 8,10 ---- ! == 619 tests, 2 stderr failures, 0 stdout failures, 6 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcbreak (stderrB) |
|
From: Florian K. <br...@ac...> - 2012-12-24 00:35:17
|
I propose to get rid of this file because
(a) it has been broken since at least July 2009 (VEX r1904)
(b) nobody bothers to maintain it (which sort of implies that
none of us is using it)
(c) there are no bugzillas requesting to fix it
(d) it's easy to get a working Makefile for icc by using
VEX/Makefile-gcc as a template
And we don't ship it in the release tarball.
OK to remove?
Florian
|
|
From: <sv...@va...> - 2012-12-24 00:25:41
|
florian 2012-12-24 00:25:34 +0000 (Mon, 24 Dec 2012)
New Revision: 2616
Log:
Fix VEX standalone build with Makefile-gcc. This has been bit-rotting
for a while.
Modified files:
trunk/Makefile-gcc
trunk/test_main.c
Modified: trunk/test_main.c (+5 -5)
===================================================================
--- trunk/test_main.c 2012-12-24 00:14:31 +00:00 (rev 2615)
+++ trunk/test_main.c 2012-12-24 00:25:34 +00:00 (rev 2616)
@@ -1187,7 +1187,7 @@
IRRegArray* new_descr
= mkIRRegArray( descr->base + mce->layout->total_sizeB,
tyS, descr->nElems);
- stmt( mce->bb, IRStmt_PutI( new_descr, ix, bias, vatom ));
+ stmt( mce->bb, IRStmt_PutI( mkIRPutI( new_descr, ix, bias, vatom ) ));
}
}
@@ -2641,10 +2641,10 @@
case Ist_PutI:
do_shadow_PUTI( &mce,
- st->Ist.PutI.descr,
- st->Ist.PutI.ix,
- st->Ist.PutI.bias,
- st->Ist.PutI.data );
+ st->Ist.PutI.details->descr,
+ st->Ist.PutI.details->ix,
+ st->Ist.PutI.details->bias,
+ st->Ist.PutI.details->data );
break;
case Ist_Store:
Modified: trunk/Makefile-gcc (+13 -7)
===================================================================
--- trunk/Makefile-gcc 2012-12-24 00:14:31 +00:00 (rev 2615)
+++ trunk/Makefile-gcc 2012-12-24 00:25:34 +00:00 (rev 2616)
@@ -3,7 +3,7 @@
pub/libvex_ir.h \
pub/libvex.h \
pub/libvex_trc_values.h \
- pub/libvex_emwarn.h \
+ pub/libvex_emnote.h \
pub/libvex_guest_x86.h \
pub/libvex_guest_amd64.h \
pub/libvex_guest_arm.h \
@@ -11,7 +11,7 @@
pub/libvex_guest_ppc64.h \
pub/libvex_guest_s390x.h \
pub/libvex_s390x_common.h \
- pub/libvex_guest_mips.h \
+ pub/libvex_guest_mips32.h \
pub/libvex_guest_offsets.h
PRIV_HEADERS = priv/host_x86_defs.h \
@@ -19,7 +19,6 @@
priv/host_arm_defs.h \
priv/host_ppc_defs.h \
priv/host_s390_defs.h \
- priv/host_s390_disasm.h \
priv/host_mips_defs.h \
priv/host_generic_regs.h \
priv/host_generic_simd64.h \
@@ -33,15 +32,19 @@
priv/guest_arm_defs.h \
priv/guest_ppc_defs.h \
priv/guest_mips_defs.h \
+ priv/s390_disasm.h \
+ priv/s390_defs.h \
priv/ir_match.h \
priv/ir_opt.h
LIB_OBJS = priv/ir_defs.o \
priv/ir_match.o \
priv/ir_opt.o \
+ priv/ir_inject.o \
priv/main_main.o \
priv/main_globals.o \
priv/main_util.o \
+ priv/s390_disasm.o \
priv/host_x86_defs.o \
priv/host_amd64_defs.o \
priv/host_arm_defs.o \
@@ -53,7 +56,6 @@
priv/host_arm_isel.o \
priv/host_ppc_isel.o \
priv/host_s390_isel.o \
- priv/host_s390_disasm.o \
priv/host_mips_isel.o \
priv/host_generic_regs.o \
priv/host_generic_simd64.o \
@@ -231,6 +233,10 @@
$(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir_defs.o \
-c priv/ir_defs.c
+priv/ir_inject.o: $(ALL_HEADERS) priv/ir_inject.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir_inject.o \
+ -c priv/ir_inject.c
+
priv/ir_match.o: $(ALL_HEADERS) priv/ir_match.c
$(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir_match.o \
-c priv/ir_match.c
@@ -363,9 +369,9 @@
$(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_s390_toIR.o \
-c priv/guest_s390_toIR.c
-priv/host_s390_disasm.o: $(ALL_HEADERS) priv/host_s390_disasm.c
- $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/host_s390_disasm.o \
- -c priv/host_s390_disasm.c
+priv/s390_disasm.o: $(ALL_HEADERS) priv/s390_disasm.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/s390_disasm.o \
+ -c priv/s390_disasm.c
priv/guest_mips_helpers.o: $(ALL_HEADERS) priv/guest_mips_helpers.c
$(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest_mips_helpers.o \
|
|
From: <sv...@va...> - 2012-12-24 00:16:33
|
florian 2012-12-24 00:16:23 +0000 (Mon, 24 Dec 2012)
New Revision: 13197
Log:
Updated for s390_defs.h.
Modified files:
trunk/Makefile.vex.am
Modified: trunk/Makefile.vex.am (+1 -0)
===================================================================
--- trunk/Makefile.vex.am 2012-12-23 16:17:18 +00:00 (rev 13196)
+++ trunk/Makefile.vex.am 2012-12-24 00:16:23 +00:00 (rev 13197)
@@ -52,6 +52,7 @@
priv/host_arm_defs.h \
priv/host_s390_defs.h \
priv/s390_disasm.h \
+ priv/s390_defs.h \
priv/host_mips_defs.h
BUILT_SOURCES = pub/libvex_guest_offsets.h
|
|
From: <sv...@va...> - 2012-12-24 00:14:40
|
florian 2012-12-24 00:14:31 +0000 (Mon, 24 Dec 2012)
New Revision: 2615
Log:
s390: New file s390_defs.h to contain definitions that are
neither guest nor host specific, but just s390 specific. These
definitions formerly resided in host_s390_defs.h
Added files:
trunk/priv/s390_defs.h
Modified files:
trunk/priv/guest_s390_helpers.c
trunk/priv/guest_s390_toIR.c
trunk/priv/host_s390_defs.h
trunk/priv/s390_disasm.c
Modified: trunk/priv/host_s390_defs.h (+1 -92)
===================================================================
--- trunk/priv/host_s390_defs.h 2012-12-23 01:09:16 +00:00 (rev 2614)
+++ trunk/priv/host_s390_defs.h 2012-12-24 00:14:31 +00:00 (rev 2615)
@@ -36,6 +36,7 @@
#include "libvex_basictypes.h" /* Bool */
#include "libvex.h" /* VexArchInfo */
#include "host_generic_regs.h" /* HReg */
+#include "s390_defs.h" /* s390_cc_t */
/* --------- Registers --------- */
const HChar *s390_hreg_as_string(HReg);
@@ -254,98 +255,6 @@
} s390_dfp_binop_t;
-/* Condition code. The encoding of the enumerators matches the value of
- the mask field in the various branch opcodes. */
-typedef enum {
- S390_CC_NEVER= 0,
- S390_CC_OVFL = 1, /* overflow */
- S390_CC_H = 2, /* A > B ; high */
- S390_CC_NLE = 3, /* not low or equal */
- S390_CC_L = 4, /* A < B ; low */
- S390_CC_NHE = 5, /* not high or equal */
- S390_CC_LH = 6, /* low or high */
- S390_CC_NE = 7, /* A != B ; not zero */
- S390_CC_E = 8, /* A == B ; zero */
- S390_CC_NLH = 9, /* not low or high */
- S390_CC_HE = 10, /* A >= B ; high or equal*/
- S390_CC_NL = 11, /* not low */
- S390_CC_LE = 12, /* A <= B ; low or equal */
- S390_CC_NH = 13, /* not high */
- S390_CC_NO = 14, /* not overflow */
- S390_CC_ALWAYS = 15
-} s390_cc_t;
-
-
-/* BFP Rounding mode as it is encoded in the m3 field of certain
- instructions (e.g. CFEBR) */
-typedef enum {
- S390_BFP_ROUND_PER_FPC = 0,
- S390_BFP_ROUND_NEAREST_AWAY = 1,
- /* 2 is not allowed */
- S390_BFP_ROUND_PREPARE_SHORT = 3,
- S390_BFP_ROUND_NEAREST_EVEN = 4,
- S390_BFP_ROUND_ZERO = 5,
- S390_BFP_ROUND_POSINF = 6,
- S390_BFP_ROUND_NEGINF = 7
-} s390_bfp_round_t;
-
-
-/* BFP Rounding mode as it is encoded in bits [29:31] of the FPC register.
- Only rounding modes 0..3 are universally supported. Others require
- additional hardware facilities. */
-typedef enum {
- S390_FPC_BFP_ROUND_NEAREST_EVEN = 0,
- S390_FPC_BFP_ROUND_ZERO = 1,
- S390_FPC_BFP_ROUND_POSINF = 2,
- S390_FPC_BFP_ROUND_NEGINF = 3,
- /* 4,5,6 are not allowed */
- S390_FPC_BFP_ROUND_PREPARE_SHORT = 7
-} s390_fpc_bfp_round_t;
-
-
-/* DFP Rounding mode as it is encoded in the m3 field of certain
- instructions (e.g. CGDTR) */
-typedef enum {
- S390_DFP_ROUND_PER_FPC_0 = 0,
- S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1 = 1,
- S390_DFP_ROUND_PER_FPC_2 = 2,
- S390_DFP_ROUND_PREPARE_SHORT_3 = 3,
- S390_DFP_ROUND_NEAREST_EVEN_4 = 4,
- S390_DFP_ROUND_ZERO_5 = 5,
- S390_DFP_ROUND_POSINF_6 = 6,
- S390_DFP_ROUND_NEGINF_7 = 7,
- S390_DFP_ROUND_NEAREST_EVEN_8 = 8,
- S390_DFP_ROUND_ZERO_9 = 9,
- S390_DFP_ROUND_POSINF_10 = 10,
- S390_DFP_ROUND_NEGINF_11 = 11,
- S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12 = 12,
- S390_DFP_ROUND_NEAREST_TIE_TOWARD_0 = 13,
- S390_DFP_ROUND_AWAY_0 = 14,
- S390_DFP_ROUND_PREPARE_SHORT_15 = 15
-} s390_dfp_round_t;
-
-
-/* DFP Rounding mode as it is encoded in bits [25:27] of the FPC register. */
-typedef enum {
- S390_FPC_DFP_ROUND_NEAREST_EVEN = 0,
- S390_FPC_DFP_ROUND_ZERO = 1,
- S390_FPC_DFP_ROUND_POSINF = 2,
- S390_FPC_DFP_ROUND_NEGINF = 3,
- S390_FPC_DFP_ROUND_NEAREST_AWAY_0 = 4,
- S390_FPC_DFP_ROUND_NEAREST_TOWARD_0 = 5,
- S390_FPC_DFP_ROUND_AWAY_ZERO = 6,
- S390_FPC_DFP_ROUND_PREPARE_SHORT = 7
-} s390_fpc_dfp_round_t;
-
-
-/* Invert the condition code */
-static __inline__ s390_cc_t
-s390_cc_invert(s390_cc_t cond)
-{
- return S390_CC_ALWAYS - cond;
-}
-
-
/* The details of a CDAS insn. Carved out to keep the size of
s390_insn low */
typedef struct {
Modified: trunk/priv/guest_s390_helpers.c (+1 -1)
===================================================================
--- trunk/priv/guest_s390_helpers.c 2012-12-23 01:09:16 +00:00 (rev 2614)
+++ trunk/priv/guest_s390_helpers.c 2012-12-24 00:14:31 +00:00 (rev 2615)
@@ -41,7 +41,7 @@
#include "main_globals.h"
#include "guest_generic_bb_to_IR.h"
#include "guest_s390_defs.h"
-#include "host_s390_defs.h" /* S390_BFP_ROUND_xyzzy */
+#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
void
LibVEX_GuestS390X_initialise(VexGuestS390XState *state)
Added: trunk/priv/s390_defs.h (+135 -0)
===================================================================
--- trunk/priv/s390_defs.h 2012-12-23 01:09:16 +00:00 (rev 2614)
+++ trunk/priv/s390_defs.h 2012-12-24 00:14:31 +00:00 (rev 2615)
@@ -0,0 +1,135 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
+
+/*---------------------------------------------------------------*/
+/*--- begin s390_defs.h ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright IBM Corp. 2010-2012
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __VEX_S390_DEFS_H
+#define __VEX_S390_DEFS_H
+
+
+/* Condition code. The encoding of the enumerators matches the value of
+ the mask field in the various branch opcodes. */
+typedef enum {
+ S390_CC_NEVER = 0,
+ S390_CC_OVFL = 1, /* overflow */
+ S390_CC_H = 2, /* A > B ; high */
+ S390_CC_NLE = 3, /* not low or equal */
+ S390_CC_L = 4, /* A < B ; low */
+ S390_CC_NHE = 5, /* not high or equal */
+ S390_CC_LH = 6, /* low or high */
+ S390_CC_NE = 7, /* A != B ; not zero */
+ S390_CC_E = 8, /* A == B ; zero */
+ S390_CC_NLH = 9, /* not low or high */
+ S390_CC_HE = 10, /* A >= B ; high or equal*/
+ S390_CC_NL = 11, /* not low */
+ S390_CC_LE = 12, /* A <= B ; low or equal */
+ S390_CC_NH = 13, /* not high */
+ S390_CC_NO = 14, /* not overflow */
+ S390_CC_ALWAYS = 15
+} s390_cc_t;
+
+
+/* Invert the condition code */
+static __inline__ s390_cc_t
+s390_cc_invert(s390_cc_t cond)
+{
+ return S390_CC_ALWAYS - cond;
+}
+
+
+/* BFP Rounding mode as it is encoded in the m3 field of certain
+ instructions (e.g. CFEBR) */
+typedef enum {
+ S390_BFP_ROUND_PER_FPC = 0,
+ S390_BFP_ROUND_NEAREST_AWAY = 1,
+ /* 2 is not allowed */
+ S390_BFP_ROUND_PREPARE_SHORT = 3,
+ S390_BFP_ROUND_NEAREST_EVEN = 4,
+ S390_BFP_ROUND_ZERO = 5,
+ S390_BFP_ROUND_POSINF = 6,
+ S390_BFP_ROUND_NEGINF = 7
+} s390_bfp_round_t;
+
+
+/* BFP Rounding mode as it is encoded in bits [29:31] of the FPC register.
+ Only rounding modes 0..3 are universally supported. Others require
+ additional hardware facilities. */
+typedef enum {
+ S390_FPC_BFP_ROUND_NEAREST_EVEN = 0,
+ S390_FPC_BFP_ROUND_ZERO = 1,
+ S390_FPC_BFP_ROUND_POSINF = 2,
+ S390_FPC_BFP_ROUND_NEGINF = 3,
+ /* 4,5,6 are not allowed */
+ S390_FPC_BFP_ROUND_PREPARE_SHORT = 7
+} s390_fpc_bfp_round_t;
+
+
+/* DFP Rounding mode as it is encoded in the m3 field of certain
+ instructions (e.g. CGDTR) */
+typedef enum {
+ S390_DFP_ROUND_PER_FPC_0 = 0,
+ S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1 = 1,
+ S390_DFP_ROUND_PER_FPC_2 = 2,
+ S390_DFP_ROUND_PREPARE_SHORT_3 = 3,
+ S390_DFP_ROUND_NEAREST_EVEN_4 = 4,
+ S390_DFP_ROUND_ZERO_5 = 5,
+ S390_DFP_ROUND_POSINF_6 = 6,
+ S390_DFP_ROUND_NEGINF_7 = 7,
+ S390_DFP_ROUND_NEAREST_EVEN_8 = 8,
+ S390_DFP_ROUND_ZERO_9 = 9,
+ S390_DFP_ROUND_POSINF_10 = 10,
+ S390_DFP_ROUND_NEGINF_11 = 11,
+ S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12 = 12,
+ S390_DFP_ROUND_NEAREST_TIE_TOWARD_0 = 13,
+ S390_DFP_ROUND_AWAY_0 = 14,
+ S390_DFP_ROUND_PREPARE_SHORT_15 = 15
+} s390_dfp_round_t;
+
+
+/* DFP Rounding mode as it is encoded in bits [25:27] of the FPC register. */
+typedef enum {
+ S390_FPC_DFP_ROUND_NEAREST_EVEN = 0,
+ S390_FPC_DFP_ROUND_ZERO = 1,
+ S390_FPC_DFP_ROUND_POSINF = 2,
+ S390_FPC_DFP_ROUND_NEGINF = 3,
+ S390_FPC_DFP_ROUND_NEAREST_AWAY_0 = 4,
+ S390_FPC_DFP_ROUND_NEAREST_TOWARD_0 = 5,
+ S390_FPC_DFP_ROUND_AWAY_ZERO = 6,
+ S390_FPC_DFP_ROUND_PREPARE_SHORT = 7
+} s390_fpc_dfp_round_t;
+
+
+/* The length of the longest mnemonic: locgrnhe */
+#define S390_MAX_MNEMONIC_LEN 8
+
+
+/*---------------------------------------------------------------*/
+/*--- end s390_defs.h ---*/
+/*---------------------------------------------------------------*/
+
+#endif /* __VEX_S390_DEFS_H */
Modified: trunk/priv/guest_s390_toIR.c (+2 -1)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-12-23 01:09:16 +00:00 (rev 2614)
+++ trunk/priv/guest_s390_toIR.c 2012-12-24 00:14:31 +00:00 (rev 2615)
@@ -41,7 +41,8 @@
#include "guest_generic_bb_to_IR.h" /* DisResult */
#include "guest_s390_defs.h" /* prototypes for this file's functions */
#include "s390_disasm.h"
-#include "host_s390_defs.h" /* S390_BFP_ROUND_xyzzy */
+#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
+#include "host_s390_defs.h" /* s390_host_has_xyzzy */
/*------------------------------------------------------------*/
Modified: trunk/priv/s390_disasm.c (+1 -3)
===================================================================
--- trunk/priv/s390_disasm.c 2012-12-23 01:09:16 +00:00 (rev 2614)
+++ trunk/priv/s390_disasm.c 2012-12-24 00:14:31 +00:00 (rev 2615)
@@ -34,12 +34,10 @@
#include "libvex_basictypes.h"
#include "main_util.h" // vassert
#include "main_globals.h" // vex_traceflags
+#include "s390_defs.h" // S390_MAX_MNEMONIC_LEN
#include "s390_disasm.h"
-/* The length of the longest mnemonic: locgrnhe */
-#define S390_MAX_MNEMONIC_LEN 8
-
/* Return the mnemonic padded with blanks to its right */
static const HChar *
mnemonic(const HChar *mnm)
|
|
From: Christian B. <bor...@de...> - 2012-12-23 03:14:36
|
valgrind revision: 13195 VEX revision: 2614 C compiler: gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973] Assembler: GNU assembler (GNU Binutils; SUSE Linux Enterprise 11) 2.21.1 C library: GNU C Library stable release version 2.11.3 (20110527) uname -mrs: Linux 3.0.42-0.7-default s390x Vendor version: Welcome to SUSE Linux Enterprise Server 11 SP2 (s390x) - Kernel %r (%t). Nightly build on sless390 ( SUSE Linux Enterprise Server 11 SP1 gcc 4.3.4 on z196 (s390x) ) Started at 2012-12-23 03:45:01 CET Ended at 2012-12-23 04:14:24 CET Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... done Regression test results follow == 616 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == |
|
From: <sv...@va...> - 2012-12-23 01:09:28
|
florian 2012-12-23 01:09:16 +0000 (Sun, 23 Dec 2012)
New Revision: 2614
Log:
s390: Simplify the optimisation for PUTs to tracked registers.
There is no need to treat the guest IA register specially. The first
assignment in a SB to any tracked register will always assign the full value
and not do an incremental update. Therefore, maintaining
env->first_IA_assignment is redundant. Interestingly, the old code
forgot to mark the tracking state as valid when first_IA_assignment was
true, resulting in an inefficiency (in the order of 0.8% of insns).
Also, when a tracked register already contains the value that it is
being assigned, there is not need to
(a) check whether that register requires precise memory exceptions and
(b) if so, assign the new value.
By definition, the register is up-to-date and reassigning the new value
which is also the old value is meaningless. No idea, what I was thinking
at the time.
Modified files:
trunk/priv/host_s390_isel.c
Modified: trunk/priv/host_s390_isel.c (+3 -24)
===================================================================
--- trunk/priv/host_s390_isel.c 2012-12-22 15:01:04 +00:00 (rev 2613)
+++ trunk/priv/host_s390_isel.c 2012-12-23 01:09:16 +00:00 (rev 2614)
@@ -38,7 +38,7 @@
#include "main_util.h"
#include "main_globals.h"
-#include "guest_s390_defs.h" /* guest_s390x_state_requires_precise_mem_exns */
+#include "guest_s390_defs.h" /* S390X_GUEST_OFFSET */
#include "host_generic_regs.h"
#include "host_s390_defs.h"
@@ -82,8 +82,6 @@
point of the destination, thereby avoiding the destination's
event check.
- - A flag to indicate whether the guest IA has been assigned to.
-
- Values of certain guest registers which are often assigned constants.
*/
@@ -122,7 +120,6 @@
Addr64 max_ga;
Bool chaining_allowed;
- Bool first_IA_assignment;
Bool old_value_valid[NUM_TRACKED_REGS];
} ISelEnv;
@@ -2965,20 +2962,6 @@
if (guest_reg == GUEST_UNKNOWN) goto not_special;
- if (guest_reg == GUEST_IA) {
- /* If this is the first assignment to the IA reg, don't special case
- it. We need to do a full 8-byte assignment here. The reason is
- that in case of a redirected translation the guest IA does not
- contain the redirected-to address. Instead it contains the
- redirected-from address and those can be far apart. So in order to
- do incremnetal updates if the IA in the future we need to get the
- initial address of the super block correct. */
- if (env->first_IA_assignment) {
- env->first_IA_assignment = False;
- goto not_special;
- }
- }
-
if (stmt->Ist.Put.data->tag != Iex_Const) {
/* Invalidate guest register contents */
env->old_value_valid[guest_reg] = False;
@@ -2999,12 +2982,9 @@
env->old_value_valid[guest_reg] = True;
/* If the register already contains the new value, there is nothing
- to do here. Unless the guest register requires precise memory
- exceptions. */
+ to do here. */
if (old_value_is_valid && new_value == old_value) {
- if (! guest_s390x_state_requires_precise_mem_exns(offset, offset + 8)) {
- return;
- }
+ return;
}
/* guest register = 0 */
@@ -3463,7 +3443,6 @@
env->type_env = bb->tyenv;
/* Set up data structures for tracking guest register values. */
- env->first_IA_assignment = True;
for (i = 0; i < NUM_TRACKED_REGS; ++i) {
env->old_value[i] = 0; /* just something to have a defined value */
env->old_value_valid[i] = False;
|
|
From: <sv...@va...> - 2012-12-22 15:01:16
|
florian 2012-12-22 15:01:04 +0000 (Sat, 22 Dec 2012)
New Revision: 2613
Log:
s390: Reduce the size of an s390_insn from 48 bytes to 32 bytes by
- adding one level of indirection for CDAS and DFP binops
- rearranging and tweaking the variant for helper calls
- using seperate insns kinds for signed and unsigned multiplication
and division.
Add an assert to make sure the size stays at 32 bytes.
Modified files:
trunk/priv/host_s390_defs.c
trunk/priv/host_s390_defs.h
Modified: trunk/priv/host_s390_defs.h (+35 -23)
===================================================================
--- trunk/priv/host_s390_defs.h 2012-12-22 14:50:41 +00:00 (rev 2612)
+++ trunk/priv/host_s390_defs.h 2012-12-22 15:01:04 +00:00 (rev 2613)
@@ -121,8 +121,10 @@
S390_INSN_COND_MOVE, /* conditonal "move" to register */
S390_INSN_LOAD_IMMEDIATE,
S390_INSN_ALU,
- S390_INSN_MUL, /* n-bit operands; 2n-bit result */
- S390_INSN_DIV, /* 2n-bit dividend; n-bit divisor; n-bit quot/rem */
+ S390_INSN_SMUL, /* signed multiply; n-bit operands; 2n-bit result */
+ S390_INSN_UMUL, /* unsigned multiply; n-bit operands; 2n-bit result */
+ S390_INSN_SDIV, /* signed division; 2n-bit / n-bit -> n-bit quot/rem */
+ S390_INSN_UDIV, /* unsigned division; 2n-bit / n-bit -> n-bit quot/rem */
S390_INSN_DIVS, /* n-bit dividend; n-bit divisor; n-bit quot/rem */
S390_INSN_CLZ, /* count left-most zeroes */
S390_INSN_UNOP,
@@ -344,7 +346,33 @@
}
+/* The details of a CDAS insn. Carved out to keep the size of
+ s390_insn low */
typedef struct {
+ HReg op1_high;
+ HReg op1_low;
+ s390_amode *op2;
+ HReg op3_high;
+ HReg op3_low;
+ HReg old_mem_high;
+ HReg old_mem_low;
+ HReg scratch;
+} s390_cdas;
+
+/* The details of a binary DFP insn. Carved out to keep the size of
+ s390_insn low */
+typedef struct {
+ s390_dfp_binop_t tag;
+ s390_dfp_round_t rounding_mode;
+ HReg dst_hi; /* 128-bit result high part; 64-bit result */
+ HReg dst_lo; /* 128-bit result low part */
+ HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
+ HReg op2_lo; /* 128-bit operand low part */
+ HReg op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
+ HReg op3_lo; /* 128-bit operand low part */
+} s390_dfp_binop;
+
+typedef struct {
s390_insn_tag tag;
/* Usually, this is the size of the result of an operation.
Exceptions are:
@@ -380,13 +408,11 @@
s390_opnd_RMI op2;
} alu;
struct {
- Bool signed_multiply;
HReg dst_hi; /* r10 */
HReg dst_lo; /* also op1 r11 */
s390_opnd_RMI op2;
} mul;
struct {
- Bool signed_divide;
HReg op1_hi; /* also remainder r10 */
HReg op1_lo; /* also quotient r11 */
s390_opnd_RMI op2;
@@ -426,14 +452,7 @@
HReg old_mem;
} cas;
struct {
- HReg op1_high;
- HReg op1_low;
- s390_amode *op2;
- HReg op3_high;
- HReg op3_low;
- HReg old_mem_high;
- HReg old_mem_low;
- HReg scratch;
+ s390_cdas *details;
} cdas;
/* Pseudo-insn for representing a helper call.
TARGET is the absolute address of the helper function
@@ -442,10 +461,10 @@
i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
passed in r2 and so forth. */
struct {
- s390_cc_t cond;
+ s390_cc_t cond : 16;
+ UInt num_args : 16;
+ HReg dst; /* if not INVALID_HREG, put return value here */
Addr64 target;
- UInt num_args;
- HReg dst; /* if not INVALID_HREG, put return value here */
const HChar *name; /* callee's name (for debugging) */
} helper_call;
@@ -507,14 +526,7 @@
HReg op2_lo; /* 128-bit operand low part */
} bfp_compare;
struct {
- s390_dfp_binop_t tag;
- HReg dst_hi; /* 128-bit result high part; 64-bit result */
- HReg dst_lo; /* 128-bit result low part */
- HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
- HReg op2_lo; /* 128-bit operand low part */
- HReg op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
- HReg op3_lo; /* 128-bit operand low part */
- s390_dfp_round_t rounding_mode;
+ s390_dfp_binop *details;
} dfp_binop;
struct {
s390_dfp_conv_t tag;
Modified: trunk/priv/host_s390_defs.c (+132 -104)
===================================================================
--- trunk/priv/host_s390_defs.c 2012-12-22 14:50:41 +00:00 (rev 2612)
+++ trunk/priv/host_s390_defs.c 2012-12-22 15:01:04 +00:00 (rev 2613)
@@ -563,14 +563,16 @@
s390_opnd_RMI_get_reg_usage(u, insn->variant.alu.op2);
break;
- case S390_INSN_MUL:
+ case S390_INSN_SMUL:
+ case S390_INSN_UMUL:
addHRegUse(u, HRmRead, insn->variant.mul.dst_lo); /* op1 */
addHRegUse(u, HRmWrite, insn->variant.mul.dst_lo);
addHRegUse(u, HRmWrite, insn->variant.mul.dst_hi);
s390_opnd_RMI_get_reg_usage(u, insn->variant.mul.op2);
break;
- case S390_INSN_DIV:
+ case S390_INSN_SDIV:
+ case S390_INSN_UDIV:
addHRegUse(u, HRmRead, insn->variant.div.op1_lo);
addHRegUse(u, HRmRead, insn->variant.div.op1_hi);
addHRegUse(u, HRmWrite, insn->variant.div.op1_lo);
@@ -611,16 +613,19 @@
addHRegUse(u, HRmWrite, insn->variant.cas.old_mem);
break;
- case S390_INSN_CDAS:
- addHRegUse(u, HRmRead, insn->variant.cdas.op1_high);
- addHRegUse(u, HRmRead, insn->variant.cdas.op1_low);
- s390_amode_get_reg_usage(u, insn->variant.cas.op2);
- addHRegUse(u, HRmRead, insn->variant.cdas.op3_high);
- addHRegUse(u, HRmRead, insn->variant.cdas.op3_low);
- addHRegUse(u, HRmWrite, insn->variant.cdas.old_mem_high);
- addHRegUse(u, HRmWrite, insn->variant.cdas.old_mem_low);
- addHRegUse(u, HRmWrite, insn->variant.cdas.scratch);
+ case S390_INSN_CDAS: {
+ s390_cdas *cdas = insn->variant.cdas.details;
+
+ addHRegUse(u, HRmRead, cdas->op1_high);
+ addHRegUse(u, HRmRead, cdas->op1_low);
+ s390_amode_get_reg_usage(u, cdas->op2);
+ addHRegUse(u, HRmRead, cdas->op3_high);
+ addHRegUse(u, HRmRead, cdas->op3_low);
+ addHRegUse(u, HRmWrite, cdas->old_mem_high);
+ addHRegUse(u, HRmWrite, cdas->old_mem_low);
+ addHRegUse(u, HRmWrite, cdas->scratch);
break;
+ }
case S390_INSN_COMPARE:
addHRegUse(u, HRmRead, insn->variant.compare.src1);
@@ -703,16 +708,19 @@
addHRegUse(u, HRmRead, insn->variant.bfp_convert.op_lo);
break;
- case S390_INSN_DFP_BINOP:
- addHRegUse(u, HRmWrite, insn->variant.dfp_binop.dst_hi);
- addHRegUse(u, HRmRead, insn->variant.dfp_binop.op2_hi); /* left */
- addHRegUse(u, HRmRead, insn->variant.dfp_binop.op3_hi); /* right */
+ case S390_INSN_DFP_BINOP: {
+ s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
+
+ addHRegUse(u, HRmWrite, dfp_binop->dst_hi);
+ addHRegUse(u, HRmRead, dfp_binop->op2_hi); /* left */
+ addHRegUse(u, HRmRead, dfp_binop->op3_hi); /* right */
if (insn->size == 16) {
- addHRegUse(u, HRmWrite, insn->variant.dfp_binop.dst_lo);
- addHRegUse(u, HRmRead, insn->variant.dfp_binop.op2_lo); /* left */
- addHRegUse(u, HRmRead, insn->variant.dfp_binop.op3_lo); /* right */
+ addHRegUse(u, HRmWrite, dfp_binop->dst_lo);
+ addHRegUse(u, HRmRead, dfp_binop->op2_lo); /* left */
+ addHRegUse(u, HRmRead, dfp_binop->op3_lo); /* right */
}
break;
+ }
case S390_INSN_DFP_COMPARE:
addHRegUse(u, HRmWrite, insn->variant.dfp_compare.dst);
@@ -837,13 +845,15 @@
s390_opnd_RMI_map_regs(m, &insn->variant.alu.op2);
break;
- case S390_INSN_MUL:
+ case S390_INSN_SMUL:
+ case S390_INSN_UMUL:
insn->variant.mul.dst_hi = lookupHRegRemap(m, insn->variant.mul.dst_hi);
insn->variant.mul.dst_lo = lookupHRegRemap(m, insn->variant.mul.dst_lo);
s390_opnd_RMI_map_regs(m, &insn->variant.mul.op2);
break;
- case S390_INSN_DIV:
+ case S390_INSN_SDIV:
+ case S390_INSN_UDIV:
insn->variant.div.op1_hi = lookupHRegRemap(m, insn->variant.div.op1_hi);
insn->variant.div.op1_lo = lookupHRegRemap(m, insn->variant.div.op1_lo);
s390_opnd_RMI_map_regs(m, &insn->variant.div.op2);
@@ -881,16 +891,19 @@
insn->variant.cas.old_mem = lookupHRegRemap(m, insn->variant.cas.old_mem);
break;
- case S390_INSN_CDAS:
- insn->variant.cdas.op1_high = lookupHRegRemap(m, insn->variant.cdas.op1_high);
- insn->variant.cdas.op1_low = lookupHRegRemap(m, insn->variant.cdas.op1_low);
- s390_amode_map_regs(m, insn->variant.cdas.op2);
- insn->variant.cdas.op3_high = lookupHRegRemap(m, insn->variant.cdas.op3_high);
- insn->variant.cdas.op3_low = lookupHRegRemap(m, insn->variant.cdas.op3_low);
- insn->variant.cdas.old_mem_high = lookupHRegRemap(m, insn->variant.cdas.old_mem_high);
- insn->variant.cdas.old_mem_low = lookupHRegRemap(m, insn->variant.cdas.old_mem_low);
- insn->variant.cdas.scratch = lookupHRegRemap(m, insn->variant.cdas.scratch);
+ case S390_INSN_CDAS: {
+ s390_cdas *cdas = insn->variant.cdas.details;
+
+ cdas->op1_high = lookupHRegRemap(m, cdas->op1_high);
+ cdas->op1_low = lookupHRegRemap(m, cdas->op1_low);
+ s390_amode_map_regs(m, cdas->op2);
+ cdas->op3_high = lookupHRegRemap(m, cdas->op3_high);
+ cdas->op3_low = lookupHRegRemap(m, cdas->op3_low);
+ cdas->old_mem_high = lookupHRegRemap(m, cdas->old_mem_high);
+ cdas->old_mem_low = lookupHRegRemap(m, cdas->old_mem_low);
+ cdas->scratch = lookupHRegRemap(m, cdas->scratch);
break;
+ }
case S390_INSN_COMPARE:
insn->variant.compare.src1 = lookupHRegRemap(m, insn->variant.compare.src1);
@@ -971,22 +984,19 @@
lookupHRegRemap(m, insn->variant.bfp_convert.op_lo);
break;
- case S390_INSN_DFP_BINOP:
- insn->variant.dfp_binop.dst_hi =
- lookupHRegRemap(m, insn->variant.dfp_binop.dst_hi);
- insn->variant.dfp_binop.op2_hi =
- lookupHRegRemap(m, insn->variant.dfp_binop.op2_hi);
- insn->variant.dfp_binop.op3_hi =
- lookupHRegRemap(m, insn->variant.dfp_binop.op3_hi);
+ case S390_INSN_DFP_BINOP: {
+ s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
+
+ dfp_binop->dst_hi = lookupHRegRemap(m, dfp_binop->dst_hi);
+ dfp_binop->op2_hi = lookupHRegRemap(m, dfp_binop->op2_hi);
+ dfp_binop->op3_hi = lookupHRegRemap(m, dfp_binop->op3_hi);
if (insn->size == 16) {
- insn->variant.dfp_binop.dst_lo =
- lookupHRegRemap(m, insn->variant.dfp_binop.dst_lo);
- insn->variant.dfp_binop.op2_lo =
- lookupHRegRemap(m, insn->variant.dfp_binop.op2_lo);
- insn->variant.dfp_binop.op3_lo =
- lookupHRegRemap(m, insn->variant.dfp_binop.op3_lo);
+ dfp_binop->dst_lo = lookupHRegRemap(m, dfp_binop->dst_lo);
+ dfp_binop->op2_lo = lookupHRegRemap(m, dfp_binop->op2_lo);
+ dfp_binop->op3_lo = lookupHRegRemap(m, dfp_binop->op3_lo);
}
break;
+ }
case S390_INSN_DFP_COMPARE:
insn->variant.dfp_compare.dst =
@@ -4828,12 +4838,11 @@
vassert(! hregIsVirtual(dst_hi));
vassert(! hregIsVirtual(dst_lo));
- insn->tag = S390_INSN_MUL;
+ insn->tag = signed_multiply ? S390_INSN_SMUL : S390_INSN_UMUL;
insn->size = size;
insn->variant.mul.dst_hi = dst_hi;
insn->variant.mul.dst_lo = dst_lo;
insn->variant.mul.op2 = op2;
- insn->variant.mul.signed_multiply = signed_multiply;
return insn;
}
@@ -4849,12 +4858,11 @@
vassert(! hregIsVirtual(op1_hi));
vassert(! hregIsVirtual(op1_lo));
- insn->tag = S390_INSN_DIV;
+ insn->tag = signed_divide ? S390_INSN_SDIV : S390_INSN_UDIV;
insn->size = size;
insn->variant.div.op1_hi = op1_hi;
insn->variant.div.op1_lo = op1_lo;
insn->variant.div.op2 = op2;
- insn->variant.div.signed_divide = signed_divide;
return insn;
}
@@ -4967,6 +4975,7 @@
HReg scratch)
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
+ s390_cdas *cdas = LibVEX_Alloc(sizeof(s390_cdas));
vassert(size == 4 || size == 8);
vassert(op2->x == 0);
@@ -4974,15 +4983,17 @@
insn->tag = S390_INSN_CDAS;
insn->size = size;
- insn->variant.cdas.op1_high = op1_high;
- insn->variant.cdas.op1_low = op1_low;
- insn->variant.cdas.op2 = op2;
- insn->variant.cdas.op3_high = op3_high;
- insn->variant.cdas.op3_low = op3_low;
- insn->variant.cdas.old_mem_high = old_mem_high;
- insn->variant.cdas.old_mem_low = old_mem_low;
- insn->variant.cdas.scratch = scratch;
+ insn->variant.cdas.details = cdas;
+ cdas->op1_high = op1_high;
+ cdas->op1_low = op1_low;
+ cdas->op2 = op2;
+ cdas->op3_high = op3_high;
+ cdas->op3_low = op3_low;
+ cdas->old_mem_high = old_mem_high;
+ cdas->old_mem_low = old_mem_low;
+ cdas->scratch = scratch;
+
return insn;
}
@@ -5259,20 +5270,23 @@
HReg op3, s390_dfp_round_t rounding_mode)
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
+ s390_dfp_binop *dfp_binop = LibVEX_Alloc(sizeof(s390_dfp_binop));
vassert(size == 8);
insn->tag = S390_INSN_DFP_BINOP;
insn->size = size;
- insn->variant.dfp_binop.tag = tag;
- insn->variant.dfp_binop.dst_hi = dst;
- insn->variant.dfp_binop.op2_hi = op2;
- insn->variant.dfp_binop.op3_hi = op3;
- insn->variant.dfp_binop.dst_lo = INVALID_HREG;
- insn->variant.dfp_binop.op2_lo = INVALID_HREG;
- insn->variant.dfp_binop.op3_lo = INVALID_HREG;
- insn->variant.dfp_binop.rounding_mode = rounding_mode;
+ insn->variant.dfp_binop.details = dfp_binop;
+ dfp_binop->tag = tag;
+ dfp_binop->dst_hi = dst;
+ dfp_binop->op2_hi = op2;
+ dfp_binop->op3_hi = op3;
+ dfp_binop->dst_lo = INVALID_HREG;
+ dfp_binop->op2_lo = INVALID_HREG;
+ dfp_binop->op3_lo = INVALID_HREG;
+ dfp_binop->rounding_mode = rounding_mode;
+
return insn;
}
@@ -5323,24 +5337,26 @@
HReg op3_lo, s390_dfp_round_t rounding_mode)
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
+ s390_dfp_binop *dfp_binop = LibVEX_Alloc(sizeof(s390_dfp_binop));
vassert(size == 16);
vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
vassert(is_valid_fp128_regpair(op3_hi, op3_lo));
-
insn->tag = S390_INSN_DFP_BINOP;
insn->size = size;
- insn->variant.dfp_binop.tag = tag;
- insn->variant.dfp_binop.dst_hi = dst_hi;
- insn->variant.dfp_binop.dst_lo = dst_lo;
- insn->variant.dfp_binop.op2_hi = op2_hi;
- insn->variant.dfp_binop.op2_lo = op2_lo;
- insn->variant.dfp_binop.op3_hi = op3_hi;
- insn->variant.dfp_binop.op3_lo = op3_lo;
- insn->variant.dfp_binop.rounding_mode = rounding_mode;
+ insn->variant.dfp_binop.details = dfp_binop;
+ dfp_binop->tag = tag;
+ dfp_binop->dst_hi = dst_hi;
+ dfp_binop->dst_lo = dst_lo;
+ dfp_binop->op2_hi = op2_hi;
+ dfp_binop->op2_lo = op2_lo;
+ dfp_binop->op3_hi = op3_hi;
+ dfp_binop->op3_lo = op3_lo;
+ dfp_binop->rounding_mode = rounding_mode;
+
return insn;
}
@@ -5804,8 +5820,9 @@
&insn->variant.alu.op2);
break;
- case S390_INSN_MUL:
- if (insn->variant.mul.signed_multiply) {
+ case S390_INSN_SMUL:
+ case S390_INSN_UMUL:
+ if (insn->tag == S390_INSN_SMUL) {
op = "v-muls";
} else {
op = "v-mulu";
@@ -5814,8 +5831,9 @@
&insn->variant.mul.op2);
break;
- case S390_INSN_DIV:
- if (insn->variant.div.signed_divide) {
+ case S390_INSN_SDIV:
+ case S390_INSN_UDIV:
+ if (insn->tag == S390_INSN_SDIV) {
op = "v-divs";
} else {
op = "v-divu";
@@ -5874,13 +5892,14 @@
insn->variant.cas.old_mem);
break;
- case S390_INSN_CDAS:
+ case S390_INSN_CDAS: {
+ s390_cdas *cdas = insn->variant.cdas.details;
+
s390_sprintf(buf, "%M %R,%R,%A,%R,%R,%R,%R", "v-cdas",
- insn->variant.cdas.op1_high, insn->variant.cdas.op1_low,
- insn->variant.cdas.op2, insn->variant.cdas.op3_high,
- insn->variant.cdas.op3_low, insn->variant.cdas.old_mem_high,
- insn->variant.cdas.old_mem_low);
+ cdas->op1_high, cdas->op1_low, cdas->op2, cdas->op3_high,
+ cdas->op3_low, cdas->old_mem_high, cdas->old_mem_low);
break;
+ }
case S390_INSN_COMPARE:
if (insn->variant.compare.signed_comparison) {
@@ -5990,19 +6009,20 @@
insn->variant.bfp_convert.op_hi);
break;
- case S390_INSN_DFP_BINOP:
- switch (insn->variant.dfp_binop.tag) {
+ case S390_INSN_DFP_BINOP: {
+ s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
+
+ switch (dfp_binop->tag) {
case S390_DFP_ADD: op = "v-dadd"; break;
case S390_DFP_SUB: op = "v-dsub"; break;
case S390_DFP_MUL: op = "v-dmul"; break;
case S390_DFP_DIV: op = "v-ddiv"; break;
default: goto fail;
}
- s390_sprintf(buf, "%M %R,%R,%R", op,
- insn->variant.dfp_binop.dst_hi,
- insn->variant.dfp_binop.op2_hi,
- insn->variant.dfp_binop.op3_hi);
+ s390_sprintf(buf, "%M %R,%R,%R", op, dfp_binop->dst_hi,
+ dfp_binop->op2_hi, dfp_binop->op3_hi);
break;
+ }
case S390_INSN_DFP_COMPARE:
s390_sprintf(buf, "%M %R,%R,%R", "v-dcmp", insn->variant.dfp_compare.dst,
@@ -7242,15 +7262,16 @@
UChar r1, r1p1, r3, /*r3p1,*/ b, old_high, old_low, scratch;
Int d;
s390_amode *am;
+ s390_cdas *cdas = insn->variant.cdas.details;
- r1 = hregNumber(insn->variant.cdas.op1_high); /* expected value */
- r1p1 = hregNumber(insn->variant.cdas.op1_low); /* expected value */
- r3 = hregNumber(insn->variant.cdas.op3_high);
- /* r3p1 = hregNumber(insn->variant.cdas.op3_low); */ /* unused */
- old_high = hregNumber(insn->variant.cdas.old_mem_high);
- old_low = hregNumber(insn->variant.cdas.old_mem_low);
- scratch = hregNumber(insn->variant.cdas.scratch);
- am = insn->variant.cdas.op2;
+ r1 = hregNumber(cdas->op1_high); /* expected value */
+ r1p1 = hregNumber(cdas->op1_low); /* expected value */
+ r3 = hregNumber(cdas->op3_high);
+ /* r3p1 = hregNumber(cdas->op3_low); */ /* unused */
+ old_high = hregNumber(cdas->old_mem_high);
+ old_low = hregNumber(cdas->old_mem_low);
+ scratch = hregNumber(cdas->scratch);
+ am = cdas->op2;
b = hregNumber(am->b);
d = am->d;
@@ -7421,7 +7442,7 @@
r1 = hregNumber(insn->variant.mul.dst_hi);
op2 = insn->variant.mul.op2;
- signed_multiply = insn->variant.mul.signed_multiply;
+ signed_multiply = insn->tag == S390_INSN_SMUL;
switch (op2.tag) {
case S390_OPND_REG: {
@@ -7535,7 +7556,7 @@
r1 = hregNumber(insn->variant.div.op1_hi);
op2 = insn->variant.div.op2;
- signed_divide = insn->variant.div.signed_divide;
+ signed_divide = insn->tag == S390_INSN_SDIV;
switch (op2.tag) {
case S390_OPND_REG: {
@@ -8150,14 +8171,16 @@
static UChar *
s390_insn_dfp_binop_emit(UChar *buf, const s390_insn *insn)
{
- UInt r1 = hregNumber(insn->variant.dfp_binop.dst_hi);
- UInt r2 = hregNumber(insn->variant.dfp_binop.op2_hi);
- UInt r3 = hregNumber(insn->variant.dfp_binop.op3_hi);
- UInt m4 = hregNumber(insn->variant.dfp_binop.rounding_mode);
+ s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
+ UInt r1 = hregNumber(dfp_binop->dst_hi);
+ UInt r2 = hregNumber(dfp_binop->op2_hi);
+ UInt r3 = hregNumber(dfp_binop->op3_hi);
+ UInt m4 = hregNumber(dfp_binop->rounding_mode);
+
switch (insn->size) {
case 8:
- switch (insn->variant.dfp_binop.tag) {
+ switch (dfp_binop->tag) {
case S390_DFP_ADD: return s390_emit_ADTRA(buf, r3, m4, r1, r2); break;
case S390_DFP_SUB: return s390_emit_SDTRA(buf, r3, m4, r1, r2); break;
case S390_DFP_MUL: return s390_emit_MDTRA(buf, r3, m4, r1, r2); break;
@@ -8167,7 +8190,7 @@
break;
case 16:
- switch (insn->variant.dfp_binop.tag) {
+ switch (dfp_binop->tag) {
case S390_DFP_ADD: return s390_emit_AXTRA(buf, r3, m4, r1, r2);
case S390_DFP_SUB: return s390_emit_SXTRA(buf, r3, m4, r1, r2);
case S390_DFP_MUL: return s390_emit_MXTRA(buf, r3, m4, r1, r2);
@@ -8737,6 +8760,9 @@
{
UChar *end;
+ /* Used to be 48 bytes. Make sure it stays low */
+ vassert(sizeof(s390_insn) == 32);
+
switch (insn->tag) {
case S390_INSN_LOAD:
end = s390_insn_load_emit(buf, insn);
@@ -8762,11 +8788,13 @@
end = s390_insn_alu_emit(buf, insn);
break;
- case S390_INSN_MUL:
+ case S390_INSN_SMUL:
+ case S390_INSN_UMUL:
end = s390_insn_mul_emit(buf, insn);
break;
- case S390_INSN_DIV:
+ case S390_INSN_SDIV:
+ case S390_INSN_UDIV:
end = s390_insn_div_emit(buf, insn);
break;
|
|
From: Florian K. <br...@ac...> - 2012-12-22 14:52:45
|
On 12/22/2012 07:09 AM, Maran Pakkirisamy wrote:
>
> On 12/22/2012 02:35 AM, sv...@va... wrote:
>> +/* The result of a Iop_CmpDxx operation is a condition code. It is
>> + encoded using the values defined in type IRCmpDxxResult.
>> + Before we can store the condition code into the guest state (or do
>> + anything else with it for that matter) we need to convert it to
>> + the encoding that s390 uses. This is what this function does. */
>> +static IRExpr *
>> +convert_vex_dfpcc_to_s390(IRTemp vex_cc)
>> +{
>> + /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
>> + same. currently. */
>> + return convert_vex_dfpcc_to_s390(vex_cc);
>> +}
>> +
>>
>
> convert_vex_bfpcc_to_s390(vex_cc);
>
>
> is supposed to be returned.
Urgh.. Yes, of course. Fixed in VEX r2612.
I guess we're not testing this :)
Florian
|
|
From: <sv...@va...> - 2012-12-22 14:50:55
|
florian 2012-12-22 14:50:41 +0000 (Sat, 22 Dec 2012)
New Revision: 2612
Log:
s390: Fix a silly mistake causing an infinite loop.
Spotted by Maran Pakkirisamy (ma...@li...).
Modified files:
trunk/priv/guest_s390_toIR.c
Modified: trunk/priv/guest_s390_toIR.c (+1 -1)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-12-22 02:28:25 +00:00 (rev 2611)
+++ trunk/priv/guest_s390_toIR.c 2012-12-22 14:50:41 +00:00 (rev 2612)
@@ -1677,7 +1677,7 @@
{
/* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
same. currently. */
- return convert_vex_dfpcc_to_s390(vex_cc);
+ return convert_vex_bfpcc_to_s390(vex_cc);
}
|
|
From: Maran P. <ma...@li...> - 2012-12-22 12:40:27
|
On 12/22/2012 02:35 AM, sv...@va... wrote:
> +/* The result of a Iop_CmpDxx operation is a condition code. It is
> + encoded using the values defined in type IRCmpDxxResult.
> + Before we can store the condition code into the guest state (or do
> + anything else with it for that matter) we need to convert it to
> + the encoding that s390 uses. This is what this function does. */
> +static IRExpr *
> +convert_vex_dfpcc_to_s390(IRTemp vex_cc)
> +{
> + /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
> + same. currently. */
> + return convert_vex_dfpcc_to_s390(vex_cc);
> +}
> +
>
convert_vex_bfpcc_to_s390(vex_cc);
is supposed to be returned.
|
|
From: Philippe W. <phi...@sk...> - 2012-12-22 04:55:44
|
valgrind revision: 13195 VEX revision: 2611 C compiler: gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2) Assembler: GNU assembler version 2.21.53.0.1-6.fc16 20110716 C library: GNU C Library development release version 2.14.90 uname -mrs: Linux 3.3.1-3.fc16.ppc64 ppc64 Vendor version: Fedora release 16 (Verne) Nightly build on gcc110 ( Fedora release 16 (Verne), ppc64 ) Started at 2012-12-21 20:00:41 PST Ended at 2012-12-21 20:53:56 PST 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 == 542 tests, 10 stderr failures, 5 stdout failures, 1 stderrB failure, 1 stdoutB failure, 2 post failures == gdbserver_tests/mcmain_pic (stdout) gdbserver_tests/mcmain_pic (stderr) gdbserver_tests/mcmain_pic (stdoutB) gdbserver_tests/mcmain_pic (stderrB) memcheck/tests/linux/getregset (stdout) memcheck/tests/linux/getregset (stderr) memcheck/tests/supp_unknown (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/vbit-test/vbit-test (stderr) memcheck/tests/wrap8 (stdout) memcheck/tests/wrap8 (stderr) massif/tests/big-alloc (post) massif/tests/deep-D (post) none/tests/ppc32/test_dfp2 (stdout) none/tests/ppc32/test_dfp2 (stderr) none/tests/ppc64/test_dfp2 (stdout) none/tests/ppc64/test_dfp2 (stderr) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) |
|
From: Christian B. <bor...@de...> - 2012-12-22 03:13:47
|
valgrind revision: 13195 VEX revision: 2611 C compiler: gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973] Assembler: GNU assembler (GNU Binutils; SUSE Linux Enterprise 11) 2.21.1 C library: GNU C Library stable release version 2.11.3 (20110527) uname -mrs: Linux 3.0.42-0.7-default s390x Vendor version: Welcome to SUSE Linux Enterprise Server 11 SP2 (s390x) - Kernel %r (%t). Nightly build on sless390 ( SUSE Linux Enterprise Server 11 SP1 gcc 4.3.4 on z196 (s390x) ) Started at 2012-12-22 03:45:01 CET Ended at 2012-12-22 04:13:33 CET Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... done Regression test results follow == 616 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... done Regression test results follow == 615 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sat Dec 22 03:59:25 2012 --- new.short Sat Dec 22 04:13:33 2012 *************** *** 8,10 **** ! == 615 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == --- 8,10 ---- ! == 616 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == |
|
From: Christian B. <bor...@de...> - 2012-12-22 03:08:42
|
valgrind revision: 13195 VEX revision: 2611 C compiler: gcc (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9bb4) Assembler: GNU assembler version 2.21.51.0.6-6bb6.fc15 20110118 C library: GNU C Library stable release version 2.14.1 uname -mrs: Linux 3.6.8-57.x.20121204-s390xperformance s390x Vendor version: unknown Nightly build on fedora390 ( Fedora 15 with devel libc/toolchain on z196 (s390x) ) Started at 2012-12-22 03:45:01 CET Ended at 2012-12-22 04:08:45 CET Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 617 tests, 2 stderr failures, 0 stdout failures, 6 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcbreak (stderrB) gdbserver_tests/mcclean_after_fork (stderrB) gdbserver_tests/mcleak (stderrB) gdbserver_tests/mcmain_pic (stderrB) gdbserver_tests/mcvabits (stderrB) gdbserver_tests/mssnapshot (stderrB) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 616 tests, 2 stderr failures, 0 stdout failures, 6 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcbreak (stderrB) gdbserver_tests/mcclean_after_fork (stderrB) gdbserver_tests/mcleak (stderrB) gdbserver_tests/mcmain_pic (stderrB) gdbserver_tests/mcvabits (stderrB) gdbserver_tests/mssnapshot (stderrB) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sat Dec 22 03:56:57 2012 --- new.short Sat Dec 22 04:08:45 2012 *************** *** 8,10 **** ! == 616 tests, 2 stderr failures, 0 stdout failures, 6 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcbreak (stderrB) --- 8,10 ---- ! == 617 tests, 2 stderr failures, 0 stdout failures, 6 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcbreak (stderrB) |
|
From: <sv...@va...> - 2012-12-22 02:28:41
|
florian 2012-12-22 02:28:25 +0000 (Sat, 22 Dec 2012)
New Revision: 2611
Log:
s390: Generalise S390_INSN_GADD which only worked on the guest
state to S390_INSN_MADD which works for any memory location
addressable with base reg + 20-bit displacement.
Modified files:
trunk/priv/host_s390_defs.c
trunk/priv/host_s390_defs.h
trunk/priv/host_s390_isel.c
Modified: trunk/priv/host_s390_defs.h (+5 -4)
===================================================================
--- trunk/priv/host_s390_defs.h 2012-12-22 02:09:40 +00:00 (rev 2610)
+++ trunk/priv/host_s390_defs.h 2012-12-22 02:28:25 +00:00 (rev 2611)
@@ -142,7 +142,7 @@
S390_INSN_DFP_CONVERT,
S390_INSN_MFENCE,
S390_INSN_MZERO, /* Assign zero to a memory location */
- S390_INSN_GADD, /* Add a value to a guest register */
+ S390_INSN_MADD, /* Add a value to a memory location */
S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */
S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */
/* The following 5 insns are mandated by translation chaining */
@@ -537,10 +537,10 @@
s390_amode *dst;
} mzero;
struct {
- UInt offset;
+ s390_amode *dst;
UChar delta;
ULong value; /* for debugging only */
- } gadd;
+ } madd;
struct {
HReg mode;
} set_fpc_bfprm;
@@ -655,7 +655,8 @@
s390_dfp_round_t);
s390_insn *s390_insn_mfence(void);
s390_insn *s390_insn_mzero(UChar size, s390_amode *dst);
-s390_insn *s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value);
+s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
+ ULong value);
s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
Modified: trunk/priv/host_s390_defs.c (+35 -18)
===================================================================
--- trunk/priv/host_s390_defs.c 2012-12-22 02:09:40 +00:00 (rev 2610)
+++ trunk/priv/host_s390_defs.c 2012-12-22 02:28:25 +00:00 (rev 2611)
@@ -737,8 +737,11 @@
s390_amode_get_reg_usage(u, insn->variant.mzero.dst);
break;
+ case S390_INSN_MADD:
+ s390_amode_get_reg_usage(u, insn->variant.madd.dst);
+ break;
+
case S390_INSN_MFENCE:
- case S390_INSN_GADD:
break;
case S390_INSN_SET_FPC_BFPRM:
@@ -1017,8 +1020,11 @@
s390_amode_map_regs(m, insn->variant.mzero.dst);
break;
+ case S390_INSN_MADD:
+ s390_amode_map_regs(m, insn->variant.madd.dst);
+ break;
+
case S390_INSN_MFENCE:
- case S390_INSN_GADD:
break;
case S390_INSN_SET_FPC_BFPRM:
@@ -5444,15 +5450,21 @@
s390_insn *
-s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value)
+s390_insn_madd(UChar size, s390_amode *dst, UChar delta, ULong value)
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
- insn->tag = S390_INSN_GADD;
+ vassert(size == 4 || size == 8);
+
+ /* This insn will be mapped to an ASI or AGSI so we can only allow base
+ register plus 12-bit / 20-bit displacement. */
+ vassert(dst->tag == S390_AMODE_B12 || dst->tag == S390_AMODE_B20);
+
+ insn->tag = S390_INSN_MADD;
insn->size = size;
- insn->variant.gadd.offset = offset;
- insn->variant.gadd.delta = delta;
- insn->variant.gadd.value = value;
+ insn->variant.madd.dst = dst;
+ insn->variant.madd.delta = delta;
+ insn->variant.madd.value = value;
return insn;
}
@@ -6018,11 +6030,11 @@
s390_sprintf(buf, "%M %A", "v-mzero", insn->variant.mzero.dst);
break;
- case S390_INSN_GADD:
- s390_sprintf(buf, "%M %G += %I (= %I)", "v-gadd",
- insn->variant.gadd.offset,
- (Long)(Char)insn->variant.gadd.delta,
- insn->variant.gadd.value);
+ case S390_INSN_MADD:
+ s390_sprintf(buf, "%M %A += %I (= %I)", "v-madd",
+ insn->variant.madd.dst,
+ (Long)(Char)insn->variant.madd.delta,
+ insn->variant.madd.value);
break;
case S390_INSN_SET_FPC_BFPRM:
@@ -8237,11 +8249,16 @@
static UChar *
-s390_insn_gadd_emit(UChar *buf, const s390_insn *insn)
+s390_insn_madd_emit(UChar *buf, const s390_insn *insn)
{
- return s390_emit_AGSI(buf, insn->variant.gadd.delta,
- S390_REGNO_GUEST_STATE_POINTER,
- DISP20(insn->variant.gadd.offset));
+ s390_amode *am = insn->variant.madd.dst;
+
+ if (insn->size == 4) {
+ return s390_emit_ASI(buf, insn->variant.madd.delta, am->b,
+ DISP20(am->d));
+ }
+
+ return s390_emit_AGSI(buf, insn->variant.madd.delta, am->b, DISP20(am->d));
}
@@ -8829,8 +8846,8 @@
end = s390_insn_mzero_emit(buf, insn);
break;
- case S390_INSN_GADD:
- end = s390_insn_gadd_emit(buf, insn);
+ case S390_INSN_MADD:
+ end = s390_insn_madd_emit(buf, insn);
break;
case S390_INSN_SET_FPC_BFPRM:
Modified: trunk/priv/host_s390_isel.c (+5 -5)
===================================================================
--- trunk/priv/host_s390_isel.c 2012-12-22 02:09:40 +00:00 (rev 2610)
+++ trunk/priv/host_s390_isel.c 2012-12-22 02:28:25 +00:00 (rev 2611)
@@ -2912,6 +2912,7 @@
case Ity_I16:
case Ity_I32:
case Ity_I64:
+ /* fixs390: We could check for INSN_MADD here. */
if (am->tag == S390_AMODE_B12 &&
s390_expr_is_const_zero(stmt->Ist.Store.data)) {
addInstr(env, s390_insn_mzero(sizeofIRType(tyd), am));
@@ -3020,7 +3021,8 @@
difference = new_value - old_value;
if (s390_host_has_gie && ulong_fits_signed_8bit(difference)) {
- addInstr(env, s390_insn_gadd(sizeofIRType(tyd), offset,
+ am = s390_amode_for_guest_state(offset);
+ addInstr(env, s390_insn_madd(sizeofIRType(tyd), am,
(difference & 0xFF), new_value));
return;
}
@@ -3029,13 +3031,11 @@
Use R0 as a scratch reg. */
if ((old_value >> 32) == (new_value >> 32)) {
HReg r0 = make_gpr(0);
- HReg gsp = make_gpr(S390_REGNO_GUEST_STATE_POINTER);
- s390_amode *gam;
- gam = s390_amode_b12(offset + 4, gsp);
+ am = s390_amode_for_guest_state(offset + 4);
addInstr(env, s390_insn_load_immediate(4, r0,
new_value & 0xFFFFFFFF));
- addInstr(env, s390_insn_store(4, gam, r0));
+ addInstr(env, s390_insn_store(4, am, r0));
return;
}
|
|
From: <sv...@va...> - 2012-12-22 02:09:54
|
florian 2012-12-22 02:09:40 +0000 (Sat, 22 Dec 2012)
New Revision: 2610
Log:
s390: Fix an assert.
Modified files:
trunk/priv/host_s390_defs.c
Modified: trunk/priv/host_s390_defs.c (+1 -1)
===================================================================
--- trunk/priv/host_s390_defs.c 2012-12-21 21:43:00 +00:00 (rev 2609)
+++ trunk/priv/host_s390_defs.c 2012-12-22 02:09:40 +00:00 (rev 2610)
@@ -5296,7 +5296,7 @@
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
- vassert(size == 8);
+ vassert(size == 4 || size == 8);
insn->tag = S390_INSN_DFP_CONVERT;
insn->size = size;
|
|
From: Kevin F. <kfi...@gm...> - 2012-12-21 23:18:18
|
Bug 79362 ( https://bugs.kde.org/show_bug.cgi?id=79362 ) has had a working patch for a while now, in fact I refreshed the patch recently. As far as I can tell, it is ready to be applied/committed to trunk. If there is more work to be done before it can be applied I would be more than willing to put in some time, I just need to know what to do. Kevin |
|
From: <sv...@va...> - 2012-12-21 21:43:14
|
florian 2012-12-21 21:43:00 +0000 (Fri, 21 Dec 2012)
New Revision: 2609
Log:
s390: Rename s390_conv_t to s390_bfp_conv_t. Purely mechanical.
Modified files:
trunk/priv/host_s390_defs.c
trunk/priv/host_s390_defs.h
trunk/priv/host_s390_isel.c
Modified: trunk/priv/host_s390_defs.h (+5 -5)
===================================================================
--- trunk/priv/host_s390_defs.h 2012-12-21 21:05:17 +00:00 (rev 2608)
+++ trunk/priv/host_s390_defs.h 2012-12-21 21:43:00 +00:00 (rev 2609)
@@ -233,7 +233,7 @@
S390_BFP_F128_TO_U64,
S390_BFP_F128_TO_F32,
S390_BFP_F128_TO_F64
-} s390_conv_t;
+} s390_bfp_conv_t;
/* Type conversion operations: to and/or from decimal floating point */
typedef enum {
@@ -492,7 +492,7 @@
HReg op_lo; /* 128-bit operand low part */
} bfp_unop;
struct {
- s390_conv_t tag;
+ s390_bfp_conv_t tag;
s390_bfp_round_t rounding_mode;
HReg dst_hi; /* 128-bit result high part; 32/64-bit result */
HReg dst_lo; /* 128-bit result low part */
@@ -623,7 +623,7 @@
s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
HReg op);
s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
-s390_insn *s390_insn_bfp_convert(UChar size, s390_conv_t tag, HReg dst,
+s390_insn *s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst,
HReg op, s390_bfp_round_t);
s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
HReg dst_lo, HReg op2_hi, HReg op2_lo);
@@ -631,9 +631,9 @@
HReg dst_lo, HReg op_hi, HReg op_lo);
s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
HReg op1_lo, HReg op2_hi, HReg op2_lo);
-s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_conv_t,
+s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t,
HReg dst_hi, HReg dst_lo, HReg op);
-s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_conv_t,
+s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t,
HReg dst, HReg op_hi, HReg op_lo,
s390_bfp_round_t);
s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
Modified: trunk/priv/host_s390_defs.c (+4 -4)
===================================================================
--- trunk/priv/host_s390_defs.c 2012-12-21 21:05:17 +00:00 (rev 2608)
+++ trunk/priv/host_s390_defs.c 2012-12-21 21:43:00 +00:00 (rev 2609)
@@ -5094,7 +5094,7 @@
s390_insn *
-s390_insn_bfp_convert(UChar size, s390_conv_t tag, HReg dst, HReg op,
+s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst, HReg op,
s390_bfp_round_t rounding_mode)
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
@@ -5196,7 +5196,7 @@
static s390_insn *
-s390_insn_bfp128_convert(UChar size, s390_conv_t tag, HReg dst_hi,
+s390_insn_bfp128_convert(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
HReg dst_lo, HReg op_hi, HReg op_lo,
s390_bfp_round_t rounding_mode)
{
@@ -5226,7 +5226,7 @@
s390_insn *
-s390_insn_bfp128_convert_to(UChar size, s390_conv_t tag, HReg dst_hi,
+s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
HReg dst_lo, HReg op)
{
/* Conversion to bfp128 never requires a rounding mode. Provide default
@@ -5239,7 +5239,7 @@
s390_insn *
-s390_insn_bfp128_convert_from(UChar size, s390_conv_t tag, HReg dst,
+s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t tag, HReg dst,
HReg op_hi, HReg op_lo,
s390_bfp_round_t rounding_mode)
{
Modified: trunk/priv/host_s390_isel.c (+4 -4)
===================================================================
--- trunk/priv/host_s390_isel.c 2012-12-21 21:05:17 +00:00 (rev 2608)
+++ trunk/priv/host_s390_isel.c 2012-12-21 21:43:00 +00:00 (rev 2609)
@@ -975,7 +975,7 @@
{
IRType ty = typeOfIRExpr(env->type_env, expr);
UChar size;
- s390_conv_t conv;
+ s390_bfp_conv_t conv;
vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I64);
@@ -1891,7 +1891,7 @@
case Iex_Unop: {
IRExpr *left = expr->Iex.Unop.arg;
s390_bfp_unop_t bfpop;
- s390_conv_t conv;
+ s390_bfp_conv_t conv;
HReg op_hi, op_lo, op, f12, f13, f14, f15;
/* We use non-virtual registers as pairs (f13, f15) and (f12, f14)) */
@@ -2104,7 +2104,7 @@
IRExpr *irrm = expr->Iex.Binop.arg1;
IRExpr *left = expr->Iex.Binop.arg2;
HReg h1, dst;
- s390_conv_t conv;
+ s390_bfp_conv_t conv;
switch (op) {
case Iop_SqrtF32:
@@ -2189,7 +2189,7 @@
IROp op = expr->Iex.Unop.op;
IRExpr *left = expr->Iex.Unop.arg;
s390_bfp_unop_t bfpop;
- s390_conv_t conv;
+ s390_bfp_conv_t conv;
HReg h1, dst;
if (op == Iop_F128HItoF64 || op == Iop_F128LOtoF64) {
|
|
From: <sv...@va...> - 2012-12-21 21:05:30
|
florian 2012-12-21 21:05:17 +0000 (Fri, 21 Dec 2012)
New Revision: 2608
Log:
s390: Distinguish between conversion to/from IRCmpFxxResult and
IRCmpDxxResult, even though the encodings are currently the same.
Rename convert_s390_fpcc_to_vex to convert_s390_to_vex_bfpcc.
Add convert_s390_to_vex_dfpcc and convert_vex_dfpcc_to_s390.
Modified files:
trunk/priv/guest_s390_toIR.c
trunk/priv/host_s390_isel.c
Modified: trunk/priv/guest_s390_toIR.c (+71 -53)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-12-21 20:24:24 +00:00 (rev 2607)
+++ trunk/priv/guest_s390_toIR.c 2012-12-21 21:05:17 +00:00 (rev 2608)
@@ -50,7 +50,6 @@
static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
-static IRExpr *convert_vex_fpcc_to_s390(IRTemp);
/*------------------------------------------------------------*/
@@ -1619,6 +1618,70 @@
/*------------------------------------------------------------*/
+/*--- Condition code helpers ---*/
+/*------------------------------------------------------------*/
+
+/* The result of a Iop_CmpFxx operation is a condition code. It is
+ encoded using the values defined in type IRCmpFxxResult.
+ Before we can store the condition code into the guest state (or do
+ anything else with it for that matter) we need to convert it to
+ the encoding that s390 uses. This is what this function does.
+
+ s390 VEX b6 b2 b0 cc.1 cc.0
+ 0 0x40 EQ 1 0 0 0 0
+ 1 0x01 LT 0 0 1 0 1
+ 2 0x00 GT 0 0 0 1 0
+ 3 0x45 Unordered 1 1 1 1 1
+
+ The following bits from the VEX encoding are interesting:
+ b0, b2, b6 with b0 being the LSB. We observe:
+
+ cc.0 = b0;
+ cc.1 = b2 | (~b0 & ~b6)
+
+ with cc being the s390 condition code.
+*/
+static IRExpr *
+convert_vex_bfpcc_to_s390(IRTemp vex_cc)
+{
+ IRTemp cc0 = newTemp(Ity_I32);
+ IRTemp cc1 = newTemp(Ity_I32);
+ IRTemp b0 = newTemp(Ity_I32);
+ IRTemp b2 = newTemp(Ity_I32);
+ IRTemp b6 = newTemp(Ity_I32);
+
+ assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
+ assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
+ mkU32(1)));
+ assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
+ mkU32(1)));
+
+ assign(cc0, mkexpr(b0));
+ assign(cc1, binop(Iop_Or32, mkexpr(b2),
+ binop(Iop_And32,
+ binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
+ binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
+ )));
+
+ return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
+}
+
+
+/* The result of a Iop_CmpDxx operation is a condition code. It is
+ encoded using the values defined in type IRCmpDxxResult.
+ Before we can store the condition code into the guest state (or do
+ anything else with it for that matter) we need to convert it to
+ the encoding that s390 uses. This is what this function does. */
+static IRExpr *
+convert_vex_dfpcc_to_s390(IRTemp vex_cc)
+{
+ /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
+ same. currently. */
+ return convert_vex_dfpcc_to_s390(vex_cc);
+}
+
+
+/*------------------------------------------------------------*/
/*--- Build IR for formats ---*/
/*------------------------------------------------------------*/
static void
@@ -9194,7 +9257,7 @@
assign(op2, get_dpr_dw0(r2));
assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cdtr";
@@ -9212,7 +9275,7 @@
assign(op2, get_dpr_pair(r2));
assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cxtr";
@@ -10849,51 +10912,6 @@
return "axbr";
}
-/* The result of a Iop_CmdFxx operation is a condition code. It is
- encoded using the values defined in type IRCmpFxxResult.
- Before we can store the condition code into the guest state (or do
- anything else with it for that matter) we need to convert it to
- the encoding that s390 uses. This is what this function does.
-
- s390 VEX b6 b2 b0 cc.1 cc.0
- 0 0x40 EQ 1 0 0 0 0
- 1 0x01 LT 0 0 1 0 1
- 2 0x00 GT 0 0 0 1 0
- 3 0x45 Unordered 1 1 1 1 1
-
- The following bits from the VEX encoding are interesting:
- b0, b2, b6 with b0 being the LSB. We observe:
-
- cc.0 = b0;
- cc.1 = b2 | (~b0 & ~b6)
-
- with cc being the s390 condition code.
-*/
-static IRExpr *
-convert_vex_fpcc_to_s390(IRTemp vex_cc)
-{
- IRTemp cc0 = newTemp(Ity_I32);
- IRTemp cc1 = newTemp(Ity_I32);
- IRTemp b0 = newTemp(Ity_I32);
- IRTemp b2 = newTemp(Ity_I32);
- IRTemp b6 = newTemp(Ity_I32);
-
- assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
- assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
- mkU32(1)));
- assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
- mkU32(1)));
-
- assign(cc0, mkexpr(b0));
- assign(cc1, binop(Iop_Or32, mkexpr(b2),
- binop(Iop_And32,
- binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
- binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
- )));
-
- return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
-}
-
static const HChar *
s390_irgen_CEBR(UChar r1, UChar r2)
{
@@ -10906,7 +10924,7 @@
assign(op2, get_fpr_w0(r2));
assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cebr";
@@ -10924,7 +10942,7 @@
assign(op2, get_fpr_dw0(r2));
assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cdbr";
@@ -10942,7 +10960,7 @@
assign(op2, get_fpr_pair(r2));
assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cxbr";
@@ -10960,7 +10978,7 @@
assign(op2, load(Ity_F32, mkexpr(op2addr)));
assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "ceb";
@@ -10978,7 +10996,7 @@
assign(op2, load(Ity_F64, mkexpr(op2addr)));
assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
- assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
return "cdb";
Modified: trunk/priv/host_s390_isel.c (+20 -6)
===================================================================
--- trunk/priv/host_s390_isel.c 2012-12-21 20:24:24 +00:00 (rev 2607)
+++ trunk/priv/host_s390_isel.c 2012-12-21 21:05:17 +00:00 (rev 2608)
@@ -727,8 +727,13 @@
return S390_DFP_ROUND_PER_FPC_0;
}
+
+/*---------------------------------------------------------*/
+/*--- Condition code helper functions ---*/
+/*---------------------------------------------------------*/
+
/* CC_S390 holds the condition code in s390 encoding. Convert it to
- VEX encoding
+ VEX encoding (IRCmpFResult)
s390 VEX b6 b2 b0 cc.1 cc.0
0 0x40 EQ 1 0 0 0 0
@@ -743,7 +748,7 @@
VEX = b0 | (b2 << 2) | (b6 << 6);
*/
static HReg
-convert_s390_fpcc_to_vex(ISelEnv *env, HReg cc_s390)
+convert_s390_to_vex_bfpcc(ISelEnv *env, HReg cc_s390)
{
HReg cc0, cc1, b2, b6, cc_vex;
@@ -775,7 +780,16 @@
return cc_vex;
}
+/* CC_S390 holds the condition code in s390 encoding. Convert it to
+ VEX encoding (IRCmpDResult) */
+static HReg
+convert_s390_to_vex_dfpcc(ISelEnv *env, HReg cc_s390)
+{
+ /* The encodings for IRCmpFResult and IRCmpDResult are the same/ */
+ return convert_s390_to_vex_bfpcc(env, cc_s390);
+}
+
/*---------------------------------------------------------*/
/*--- ISEL: Integer expressions (128 bit) ---*/
/*---------------------------------------------------------*/
@@ -1177,7 +1191,7 @@
addInstr(env, s390_insn_bfp_compare(size, cc_s390, h1, h2));
- return convert_s390_fpcc_to_vex(env, cc_s390);
+ return convert_s390_to_vex_bfpcc(env, cc_s390);
}
case Iop_CmpF128: {
@@ -1204,7 +1218,7 @@
res = newVRegI(env);
addInstr(env, s390_insn_bfp128_compare(16, cc_s390, f12, f14, f13, f15));
- return convert_s390_fpcc_to_vex(env, cc_s390);
+ return convert_s390_to_vex_bfpcc(env, cc_s390);
}
case Iop_CmpD64: {
@@ -1217,7 +1231,7 @@
addInstr(env, s390_insn_dfp_compare(size, cc_s390, h1, h2));
- return convert_s390_fpcc_to_vex(env, cc_s390);
+ return convert_s390_to_vex_dfpcc(env, cc_s390);
}
case Iop_CmpD128: {
@@ -1244,7 +1258,7 @@
res = newVRegI(env);
addInstr(env, s390_insn_dfp128_compare(16, cc_s390, f12, f14, f13, f15));
- return convert_s390_fpcc_to_vex(env, cc_s390);
+ return convert_s390_to_vex_dfpcc(env, cc_s390);
}
case Iop_Add8:
|
|
From: <sv...@va...> - 2012-12-21 20:24:37
|
florian 2012-12-21 20:24:24 +0000 (Fri, 21 Dec 2012)
New Revision: 2607
Log:
Define IRCmpD64Result and IRCmpD128Result.
Modified files:
trunk/pub/libvex_ir.h
Modified: trunk/pub/libvex_ir.h (+11 -5)
===================================================================
--- trunk/pub/libvex_ir.h 2012-12-21 18:55:03 +00:00 (rev 2606)
+++ trunk/pub/libvex_ir.h 2012-12-21 20:24:24 +00:00 (rev 2607)
@@ -1070,7 +1070,7 @@
* D64 x D64 -> IRCmpD64Result(I32) */
Iop_CmpD64,
- /* D128 x D128 -> IRCmpD64Result(I32) */
+ /* D128 x D128 -> IRCmpD128Result(I32) */
Iop_CmpD128,
/* QUANTIZE AND ROUND INSTRUCTIONS
@@ -1522,7 +1522,7 @@
}
IRRoundingModeDFP;
-/* Floating point comparison result values, as created by Iop_CmpF64.
+/* Binary floating point comparison result values.
This is also derived from what IA32 does. */
typedef
enum {
@@ -1531,11 +1531,17 @@
Ircr_GT = 0x00,
Ircr_EQ = 0x40
}
- IRCmpF64Result;
+ IRCmpFResult;
-typedef IRCmpF64Result IRCmpF32Result;
-typedef IRCmpF64Result IRCmpF128Result;
+typedef IRCmpFResult IRCmpF32Result;
+typedef IRCmpFResult IRCmpF64Result;
+typedef IRCmpFResult IRCmpF128Result;
+/* Decimal floating point result values. */
+typedef IRCmpFResult IRCmpDResult;
+typedef IRCmpDResult IRCmpD64Result;
+typedef IRCmpDResult IRCmpD128Result;
+
/* ------------------ Expressions ------------------ */
typedef struct _IRQop IRQop; /* forward declaration */
|
|
From: <sv...@va...> - 2012-12-21 18:55:12
|
florian 2012-12-21 18:55:03 +0000 (Fri, 21 Dec 2012)
New Revision: 2606
Log:
s390: Add support for storing DFP values (32/64 bit).
Modified files:
trunk/priv/host_s390_isel.c
Modified: trunk/priv/host_s390_isel.c (+5 -0)
===================================================================
--- trunk/priv/host_s390_isel.c 2012-12-21 17:32:12 +00:00 (rev 2605)
+++ trunk/priv/host_s390_isel.c 2012-12-21 18:55:03 +00:00 (rev 2606)
@@ -2911,6 +2911,11 @@
src = s390_isel_float_expr(env, stmt->Ist.Store.data);
break;
+ case Ity_D32:
+ case Ity_D64:
+ src = s390_isel_dfp_expr(env, stmt->Ist.Store.data);
+ break;
+
case Ity_F128:
case Ity_D128:
/* Cannot occur. No such instruction */
|
|
From: <sv...@va...> - 2012-12-21 18:35:01
|
florian 2012-12-21 18:34:48 +0000 (Fri, 21 Dec 2012)
New Revision: 13195
Log:
Companion patch to VEX r2605. Adds a few testcases and adapts the vbit
tester. This is part of fixing BZ #307113.
Patch by Maran Pakkirisamy (ma...@li...).
Added files:
trunk/none/tests/s390x/dfp-2.c
trunk/none/tests/s390x/dfp-2.stderr.exp
trunk/none/tests/s390x/dfp-2.stdout.exp
trunk/none/tests/s390x/dfp-2.vgtest
trunk/none/tests/s390x/dfp_utils.h
Modified directories:
trunk/none/tests/s390x/
Modified files:
trunk/memcheck/tests/vbit-test/irops.c
trunk/none/tests/s390x/Makefile.am
trunk/none/tests/s390x/dfp-1.c
trunk/none/tests/s390x/dfp-1.stdout.exp
trunk/none/tests/s390x/opcodes.h
Modified: trunk/none/tests/s390x/
Modified: trunk/none/tests/s390x/dfp-1.stdout.exp (+33 -9)
===================================================================
--- trunk/none/tests/s390x/dfp-1.stdout.exp 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/dfp-1.stdout.exp 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -1,9 +1,33 @@
-Decimal floating point 64-bit arithmetic
-dfp64_add: 2220ff3fcff3fcff
-dfp64_add: 6e24ff3fcff3fcff
-dfp64_sub: ee20ff3fcff3fcff
-dfp64_sub: ee24ff3fcff3fcff
-dfp64_mul: 6e208c0000000000
-dfp64_mul: 6e248c0000000000
-dfp64_div: 6a206ec7ff7fab55
-dfp64_div: 2a3dec7b1ec7b1ed
+Decimal floating point arithmetic
+64-bit ADD
+2230000000000194 + 222c000000000005 = 222c000000000cc5 cc = 2
+a230000000000194 + 222c000000000005 = a22c000000000cb5 cc = 1
+2230000000000194 + a230000000000194 = 2230000000000000 cc = 0
+64-bit SUBTRACT
+2230000000000194 - 222c000000000005 = 222c000000000cb5 cc = 2
+a230000000000194 - 222c000000000005 = a22c000000000cc5 cc = 1
+2230000000000194 - 2230000000000194 = 2230000000000000 cc = 0
+64-bit MULTIPLY
+2230000000000194 * 2238000000000007 = 22300000000008de cc = 0
+a230000000000194 * 2238000000000007 = a2300000000008de cc = 0
+a230000000000194 * 2238000000000000 = a230000000000000 cc = 0
+64-bit DIVIDE
+2238000000000022 / 2238000000000007 = 2dfcc2d74c2d74c3 cc = 0
+a238000000000022 / 2238000000000007 = adfcc2d74c2d74c3 cc = 0
+2238000000000000 / 2238000000000007 = 2238000000000000 cc = 0
+128-bit ADD
+220780000000000000000194 + 220740000000000000000005 = 220740000000000000000cc5 cc = 2
+a20780000000000000000194 + 220740000000000000000005 = a20740000000000000000cb5 cc = 1
+220780000000000000000194 + a20780000000000000000194 = 220780000000000000000000 cc = 0
+128-bit SUBTRACT
+220780000000000000000194 - 220740000000000000000005 = 220740000000000000000cb5 cc = 2
+a20780000000000000000194 - 220740000000000000000005 = a20740000000000000000cc5 cc = 1
+220780000000000000000194 - 220780000000000000000194 = 220780000000000000000000 cc = 0
+128-bit MULTIPLY
+220780000000000000000194 * 220800000000000000000007 = 2207800000000000000008de cc = 0
+a20780000000000000000194 * 220800000000000000000007 = a207800000000000000008de cc = 0
+220780000000000000000194 * 220800000000000000000000 = 220780000000000000000000 cc = 0
+128-bit DIVIDE
+220800000000000000000022 / 220800000000000000000007 = 2dffcc2d74c2d74c2d74c2d74c2d74c3 cc = 0
+a20800000000000000000022 / 220800000000000000000007 = adffcc2d74c2d74c2d74c2d74c2d74c3 cc = 0
+220800000000000000000000 / 220800000000000000000007 = 220800000000000000000000 cc = 0
Modified: trunk/memcheck/tests/vbit-test/irops.c (+19 -19)
===================================================================
--- trunk/memcheck/tests/vbit-test/irops.c 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/memcheck/tests/vbit-test/irops.c 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -477,30 +477,30 @@
{ DEFOP(Iop_Recip32x2, UNDEF_UNKNOWN), },
{ DEFOP(Iop_Rsqrte32x2, UNDEF_UNKNOWN), },
/* ------------------ Decimal Floating Point ------------------ */
- { DEFOP(Iop_AddD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_SubD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_MulD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_DivD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_AddD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_SubD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_MulD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_DivD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_AddD64, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_SubD64, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_MulD64, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_DivD64, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_AddD128, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_SubD128, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_MulD128, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_DivD128, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_ShlD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_ShrD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_ShlD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_ShrD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_D32toD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_D64toD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_D32toD64, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_D64toD128, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_I64StoD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_D64toD32, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_D128toD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_D64toD32, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_D128toD64, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_I64StoD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_D64toI64S, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_D128toI64S, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_RoundD64toInt, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_RoundD128toInt, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_CmpD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_CmpD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_CmpD64, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_CmpD128, UNDEF_ALL), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_QuantizeD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_QuantizeD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_SignificanceRoundD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
@@ -509,13 +509,13 @@
{ DEFOP(Iop_ExtractExpD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_InsertExpD64, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_InsertExpD128, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_D64HLtoD128, UNDEF_CONCAT), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_D128HItoD64, UNDEF_UPPER), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_D128LOtoD64, UNDEF_TRUNC), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_D64HLtoD128, UNDEF_CONCAT), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_D128HItoD64, UNDEF_UPPER), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_D128LOtoD64, UNDEF_TRUNC), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_DPBtoBCD, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
{ DEFOP(Iop_BCDtoDPB, UNDEF_ALL), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_ReinterpI64asD64, UNDEF_SAME), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
- { DEFOP(Iop_ReinterpD64asI64, UNDEF_SAME), .s390x = 0, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_ReinterpI64asD64, UNDEF_SAME), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
+ { DEFOP(Iop_ReinterpD64asI64, UNDEF_SAME), .s390x = 1, .ppc64 = 1, .ppc32 = 1 },
/* ------------------ 128-bit SIMD FP. ------------------ */
{ DEFOP(Iop_Add32Fx4, UNDEF_UNKNOWN), },
{ DEFOP(Iop_Sub32Fx4, UNDEF_UNKNOWN), },
Added: trunk/none/tests/s390x/dfp-2.c (+79 -0)
===================================================================
--- trunk/none/tests/s390x/dfp-2.c 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/dfp-2.c 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include "dfp_utils.h"
+
+/* Test various DFP ops:
+ - extract significance 64/128 bit
+ - load and test 64/128 bit
+*/
+
+#if 0 //fixs390: enable it when Iop_ExtractSigD64/D128 is available
+void esdtr(_Decimal64 in)
+{
+ long out;
+ asm volatile(".insn rre, 0xb3e70000, %[out], %[in]\n\t"
+ :[out] "=d" (out) :[in] "f" (in));
+ printf("ESDTR ");
+ DFP_VAL_PRINT(in, _Decimal64);
+ printf(" -> %ld\n", out);
+}
+
+void esxtr(_Decimal128 in)
+{
+ long out;
+ asm volatile(".insn rre, 0xb3ef0000, %[out], %[in]\n\t"
+ :[out] "=d" (out) :[in] "f" (in));
+ printf("ESXTR ");
+ DFP_VAL_PRINT(in, _Decimal128);
+ printf(" -> %ld\n", out);
+}
+#endif
+
+void ltdtr(_Decimal64 in)
+{
+ _Decimal64 out;
+ int cc;
+ asm volatile(".insn rre, 0xb3d60000, %[out], %[in]\n\t"
+ "ipm %1\n\t"
+ "srl %1,28\n\t"
+ :[out] "=d" (out), "=d" (cc)
+ :[in] "f" (in));
+ printf("LTDTR ");
+ DFP_VAL_PRINT(in, _Decimal64);
+ printf(" -> %d\n", cc);
+}
+
+void ltxtr(_Decimal128 in)
+{
+ _Decimal128 out;
+ int cc;
+ asm volatile(".insn rre, 0xb3de0000, %[out], %[in]\n\t"
+ "ipm %1\n\t"
+ "srl %1,28\n\t"
+ :[out] "=f" (out), "=d" (cc)
+ :[in] "f" (in));
+ printf("LTXTR ");
+ DFP_VAL_PRINT(in, _Decimal128);
+ printf(" -> %d\n", cc);
+}
+
+int main() {
+ _Decimal64 d64 = 50.0005DD;
+ _Decimal128 d128 = 50.0005DL;
+
+#if 0 //fixs390: enable it when Iop_ExtractSigD64/D128 is available
+ esdtr(d64);
+ esdtr(-d64);
+ esdtr(0.DD);
+ esxtr(d128);
+ esxtr(-d128);
+ esxtr(0.DL);
+#endif
+ ltdtr(d64);
+ ltdtr(-d64);
+ ltdtr(0.0DD);
+ ltxtr(d128);
+ ltxtr(-d128);
+ ltxtr(0.0DL);
+
+ return 0;
+}
Modified: trunk/none/tests/s390x/dfp-1.c (+156 -57)
===================================================================
--- trunk/none/tests/s390x/dfp-1.c 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/dfp-1.c 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -1,74 +1,173 @@
#include <stdio.h>
#include "opcodes.h"
+#include "dfp_utils.h"
-volatile _Decimal64 d64_1, d64_2;
+volatile _Decimal64 d64_1, d64_2, result_64;
+volatile _Decimal128 d128_1, d128_2, result_128;
-#define DFP64_BINOP(insn, op1, op2, type, round, cc) \
-({ \
- register type f1 asm("f1") = op1; \
- register type f2 asm("f2") = op2; \
- /* f1 = f1 (op) f2 */ \
- asm volatile(insn(2,round,1,1) \
- "ipm %1\n\t" \
- "srl %1,28\n\t" \
- :"+f" (f1), "=d" (cc) \
- :"f"(f2) \
- ); \
- f1; \
-})
+#define DFP_BINOP(insn, op1, op2, type, round, cc) \
+ ({ \
+ register type d1 asm("f0") = op1; \
+ register type d2 asm("f1") = op2; \
+ /* d1 = d1 (op) d2 */ \
+ asm volatile(insn(1,round,0,0) \
+ "ipm %1\n\t" \
+ "srl %1,28\n\t" \
+ :"+f" (d1), "=d" (cc) \
+ :"f"(d2) \
+ ); \
+ d1; \
+ })
int main() {
- _Decimal64 result;
int cc;
- printf("Decimal floating point 64-bit arithmetic\n");
- // fixs390: print result in DFP format once required insns are supported.
+ printf("Decimal floating point arithmetic\n");
/* 64-bit ADD */
- /* case 1: result has maximum significand digits */
- d64_1 = 999999999.0DD;
- d64_2 = 0.999999DD;
- result = DFP64_BINOP(ADTRA, d64_1, d64_2, _Decimal64, 1, cc);
- printf("dfp64_add: %lx\n", *((unsigned long *) &result));
- /* case 2: result is rounded */
- d64_1 = 99999999999.0DD;
- d64_2 = 0.999999DD;
- result = DFP64_BINOP(ADTRA, d64_1, d64_2, _Decimal64, 3, cc);
- printf("dfp64_add: %lx\n", *((unsigned long *) &result));
+ printf("64-bit ADD\n");
+ /* case 1: cc = 2 */
+ d64_1 = 3.14DD;
+ d64_2 = 0.005DD;
+ result_64 = DFP_BINOP(ADTRA, d64_1, d64_2, _Decimal64, 1, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "+", cc);
+ /* case 2: cc = 1 */
+ d64_1 = -3.14DD;
+ d64_2 = 0.005DD;
+ result_64 = DFP_BINOP(ADTRA, d64_1, d64_2, _Decimal64, 1, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "+", cc);
+ /* case 2: cc = 0 */
+ d64_1 = 3.14DD;
+ d64_2 = -d64_1;
+ result_64 = DFP_BINOP(ADTRA, d64_1, d64_2, _Decimal64, 3, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "+", cc);
+
/* 64-bit SUBTRACT */
- /* case 1: result has maximum significand digits */
- d64_1 = 0.000001DD;
- d64_2 = 10000000000.0DD;
- result = DFP64_BINOP(SDTRA, d64_1, d64_2, _Decimal64, 4, cc);
- printf("dfp64_sub: %lx\n", *((unsigned long *) &result));
- /* case 2: result is rounded */
- d64_1 = 0.000001DD;
- d64_2 = 100000000000.0DD;
- result = DFP64_BINOP(SDTRA, d64_1, d64_2, _Decimal64, 5, cc);
- printf("dfp64_sub: %lx\n", *((unsigned long *) &result));
+ printf("64-bit SUBTRACT\n");
+ /* case 1: cc = 2 */
+ d64_1 = 3.14DD;
+ d64_2 = 0.005DD;
+ result_64 = DFP_BINOP(SDTRA, d64_1, d64_2, _Decimal64, 4, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "-", cc);
+ /* case 2: cc = 1 */
+ d64_1 = -3.14DD;
+ d64_2 = 0.005DD;
+ result_64 = DFP_BINOP(SDTRA, d64_1, d64_2, _Decimal64, 5, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "-", cc);
+ /* case 3: cc = 0 */
+ d64_1 = 3.14DD;
+ d64_2 = d64_1;
+ result_64 = DFP_BINOP(SDTRA, d64_1, d64_2, _Decimal64, 5, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "-", cc);
/* 64-bit MULTIPLY */
- /* case 1: result has maximum significand digits */
- d64_1 = 9999999999.999999DD;
- d64_2 = .99DD;
- result = DFP64_BINOP(MDTRA, d64_1, d64_2, _Decimal64, 6, cc);
- printf("dfp64_mul: %lx\n", *((unsigned long *) &result));
- /* case 2: result is rounded */
- d64_1 = 99999999999.999999DD;
- d64_2 = .99DD;
- result = DFP64_BINOP(MDTRA, d64_1, d64_2, _Decimal64, 7, cc);
- printf("dfp64_mul: %lx\n", *((unsigned long *) &result));
+ printf("64-bit MULTIPLY\n");
+ /* case 1: cc = 2 */
+ d64_1 = 3.14DD;
+ d64_2 = 7.DD;
+ result_64 = DFP_BINOP(MDTRA, d64_1, d64_2, _Decimal64, 6, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "*", cc);
+ /* case 2: cc = 1 */
+ d64_1 = -3.14DD;
+ d64_2 = 7.DD;
+ result_64 = DFP_BINOP(MDTRA, d64_1, d64_2, _Decimal64, 7, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "*", cc);
+ /* case 3: cc = 0 */
+ d64_1 = -3.14DD;
+ d64_2 = 0.DD;
+ result_64 = DFP_BINOP(MDTRA, d64_1, d64_2, _Decimal64, 7, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "*", cc);
/* 64-bit DIVIDE */
- /* case 1: result has maximum significand digits */
- d64_1 = 8888888888.888877DD;
- d64_2 = 0.999999DD;
- result = DFP64_BINOP(DDTRA, d64_1, d64_2, _Decimal64, d, cc);
- printf("dfp64_div: %lx\n", *((unsigned long *) &result));
- /* case 2: result is rounded */
- d64_1 = 88888888888.888877DD;
- d64_2 = 0.000003DD;
- result = DFP64_BINOP(DDTRA, d64_1, d64_2, _Decimal64, e, cc);
- printf("dfp64_div: %lx\n", *((unsigned long *) &result));
+ printf("64-bit DIVIDE\n");
+ /* case 1: cc = 2 */
+ d64_1 = 22.DD;
+ d64_2 = 7.DD;
+ result_64 = DFP_BINOP(DDTRA, d64_1, d64_2, _Decimal64, d, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "/", cc);
+ /* case 2: cc = 1 */
+ d64_1 = -22.DD;
+ d64_2 = 7.DD;
+ result_64 = DFP_BINOP(DDTRA, d64_1, d64_2, _Decimal64, e, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "/", cc);
+ /* case 3: cc = 0 */
+ d64_1 = 0.DD;
+ d64_2 = 7.DD;
+ result_64 = DFP_BINOP(DDTRA, d64_1, d64_2, _Decimal64, e, cc);
+ DFP_BINOP_PRINT(d64_1, d64_2, result_64, _Decimal64, "/", cc);
+
+ /* 128-bit ADD */
+ printf("128-bit ADD\n");
+ /* case 1: cc = 2 */
+ d128_1 = 3.14DL;
+ d128_2 = 0.005DL;
+ result_128 = DFP_BINOP(AXTRA, d128_1, d128_2, _Decimal128, 1, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "+", cc);
+ /* case 2: cc = 1 */
+ d128_1 = -3.14DL;
+ d128_2 = 0.005DL;
+ result_128 = DFP_BINOP(AXTRA, d128_1, d128_2, _Decimal128, 1, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "+", cc);
+ /* case 3: cc = 0 */
+ d128_1 = 3.14DL;
+ d128_2 = -d128_1;
+ result_128 = DFP_BINOP(AXTRA, d128_1, d128_2, _Decimal128, 3, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "+", cc);
+
+ /* 128-bit SUBTRACT */
+ printf("128-bit SUBTRACT\n");
+ /* case 1: cc = 2 */
+ d128_1 = 3.14DL;
+ d128_2 = 0.005DL;
+ result_128 = DFP_BINOP(SXTRA, d128_1, d128_2, _Decimal128, 4, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "-", cc);
+ /* case 2: cc = 1 */
+ d128_1 = -3.14DL;
+ d128_2 = 0.005DL;
+ result_128 = DFP_BINOP(SXTRA, d128_1, d128_2, _Decimal128, 5, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "-", cc);
+ /* case 3: cc = 0 */
+ d128_1 = 3.14DL;
+ d128_2 = d128_1;
+ result_128 = DFP_BINOP(SXTRA, d128_1, d128_2, _Decimal128, 5, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "-", cc);
+
+ /* 128-bit MULTIPLY */
+ printf("128-bit MULTIPLY\n");
+ /* case 1: cc = 2 */
+ d128_1 = 3.14DL;
+ d128_2 = 7.DL;
+ result_128 = DFP_BINOP(MXTRA, d128_1, d128_2, _Decimal128, 6, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "*", cc);
+ /* case 2: cc = 1 */
+ d128_1 = -3.14DL;
+ d128_2 = 7.DL;
+ result_128 = DFP_BINOP(MXTRA, d128_1, d128_2, _Decimal128, 7, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "*", cc);
+ /* case 3: cc = 0 */
+ d128_1 = 3.14DL;
+ d128_2 = 0.DL;
+ result_128 = DFP_BINOP(MXTRA, d128_1, d128_2, _Decimal128, 7, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "*", cc);
+
+ /* 128-bit DIVIDE */
+ printf("128-bit DIVIDE\n");
+ /* case 1: cc = 2 */
+ d128_1 = 22.DL;
+ d128_2 = 7.DL;
+ result_128 = DFP_BINOP(DXTRA, d128_1, d128_2, _Decimal128, d, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "/", cc);
+ /* case 2: cc = 1 */
+ d128_1 = -22.DL;
+ d128_2 = 7.DL;
+ result_128 = DFP_BINOP(DXTRA, d128_1, d128_2, _Decimal128, e, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "/", cc);
+ /* case 3: cc = 0 */
+ d128_1 = 0.DL;
+ d128_2 = 7.DL;
+ result_128 = DFP_BINOP(DXTRA, d128_1, d128_2, _Decimal128, e, cc);
+ DFP_BINOP_PRINT(d128_1, d128_2, result_128, _Decimal128, "/", cc);
+
+ return 0;
}
Modified: trunk/none/tests/s390x/opcodes.h (+8 -0)
===================================================================
--- trunk/none/tests/s390x/opcodes.h 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/opcodes.h 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -127,15 +127,19 @@
#define ALY(r1,x2,b2,dl2,dh2) RXY_RRRD(e3,r1,x2,b2,dl2,dh2,5e)
#define ARK(r3,r1,r2) RRF_R0RR2(b9f8,r3,0,r1,r2)
#define ASI(i2,b1,dl1,dh1) SIY_IRD(eb,i2,b1,dl1,dh1,6a)
+#define AXTRA(r3,m4,r1,r2) RRF_FUFF2(b3da,r3,m4,r1,r2)
#define AY(r1,x2,b2,dl2,dh2) RXY_RRRD(e3,r1,x2,b2,dl2,dh2,5a)
#define CDFBRA(m3,m4,r1,r2) RRF_UUFR(b395,m3,m4,r1,r2)
#define CDGBRA(m3,m4,r1,r2) RRF_UUFR(b3a5,m3,m4,r1,r2)
#define CDLFBR(m3,m4,r1,r2) RRF_UUFR(b391,m3,m4,r1,r2)
#define CDLGBR(m3,m4,r1,r2) RRF_UUFR(b3a1,m3,m4,r1,r2)
+#define CDTR(r1,r2) RRE_RERE(b3e4,r1,r2)
+#define CEDTR(r1,r2) RRE_RERE(b3f4,r1,r2)
#define CEFBRA(m3,m4,r1,r2) RRF_UUFR(b394,m3,m4,r1,r2)
#define CEGBRA(m3,m4,r1,r2) RRF_UUFR(b3a4,m3,m4,r1,r2)
#define CELFBR(m3,m4,r1,r2) RRF_UUFR(b390,m3,m4,r1,r2)
#define CELGBR(m3,m4,r1,r2) RRF_UUFR(b3a0,m3,m4,r1,r2)
+#define CEXTR(r1,r2) RRE_RERE(b3fc,r1,r2)
#define CFEBRA(m3,m4,r1,r2) RRF_UURF(b398,m3,m4,r1,r2)
#define CFDBRA(m3,m4,r1,r2) RRF_UURF(b399,m3,m4,r1,r2)
#define CFI(r1,i2) RIL_RI(c2,r1,d,i2)
@@ -211,8 +215,10 @@
#define CXGBRA(m3,m4,r1,r2) RRF_UUFR(b3a6,m3,m4,r1,r2)
#define CXLFBR(m3,m4,r1,r2) RRF_UUFR(b392,m3,m4,r1,r2)
#define CXLGBR(m3,m4,r1,r2) RRF_UUFR(b3a2,m3,m4,r1,r2)
+#define CXTR(r1,r2) RRE_RERE(b3ec,r1,r2)
#define CY(r1,x2,b2,dl2,dh2) RXY_RRRD(e3,r1,x2,b2,dl2,dh2,59)
#define DDTRA(r3,m4,r1,r2) RRF_FUFF2(b3d1,r3,m4,r1,r2)
+#define DXTRA(r3,m4,r1,r2) RRF_FUFF2(b3d9,r3,m4,r1,r2)
#define EXRL(r1,i2) RIL_RP(c6,r1,0,i2)
#define FLOGR(r1,r2) RRE_RR(b983,00,r1,r2)
#define ICMY(r1,r3,b2,dl2,dh2) RSY_RURD(eb,r1,r3,b2,dl2,dh2,81)
@@ -287,6 +293,7 @@
#define MVHHI(b1,d1,i2) SIL_RDI(e544,b1,d1,i2)
#define MVHI(b1,d1,i2) SIL_RDI(e54c,b1,d1,i2)
#define MVIY(i2,b1,dl1,dh1) SIY_URD(eb,i2,b1,dl1,dh1,52)
+#define MXTRA(r3,m4,r1,r2) RRF_FUFF2(b3d8,r3,m4,r1,r2)
#define NGRK(r3,r1,r2) RRF_R0RR2(b9e4,r3,0,r1,r2)
#define NIHF(r1,i2) RIL_RU(c0,r1,a,i2)
#define NILF(r1,i2) RIL_RU(c0,r1,b,i2)
@@ -341,6 +348,7 @@
#define STOCG(r1,r3,b2,dl2,dh2) RSY_RDRM(eb,r1,r3,b2,dl2,dh2,e3)
#define STRL(r1,i2) RIL_RP(c4,r1,f,i2)
#define STY(r1,x2,b2,dl2,dh2) RXY_RRRD(e3,r1,x2,b2,dl2,dh2,50)
+#define SXTRA(r3,m4,r1,r2) RRF_FUFF2(b3db,r3,m4,r1,r2)
#define SY(r1,x2,b2,dl2,dh2) RXY_RRRD(e3,r1,x2,b2,dl2,dh2,5b)
#define TMY(i2,b1,dl1,dh1) SIY_URD(eb,i2,b1,dl1,dh1,51)
#define XGRK(r3,r1,r2) RRF_R0RR2(b9e7,r3,0,r1,r2)
Added: trunk/none/tests/s390x/dfp-2.vgtest (+2 -0)
===================================================================
--- trunk/none/tests/s390x/dfp-2.vgtest 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/dfp-2.vgtest 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -0,0 +1,2 @@
+prog: dfp-2
+prereq: test -e dfp-2 && ../../../tests/s390x_features s390x-dfp
Modified: trunk/none/tests/s390x/Makefile.am (+3 -2)
===================================================================
--- trunk/none/tests/s390x/Makefile.am 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/Makefile.am 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -19,7 +19,7 @@
spechelper-icm-1 spechelper-icm-2 spechelper-tmll \
spechelper-tm laa
if BUILD_DFP_TESTS
- INSN_TESTS += dfp-1
+ INSN_TESTS += dfp-1 dfp-2
endif
check_PROGRAMS = $(INSN_TESTS) \
@@ -35,7 +35,8 @@
fpext_fail.vgtest fpext_fail.stderr.exp fpext_fail.stdout.exp \
test.h opcodes.h add.h and.h div.h insert.h \
mul.h or.h sub.h xor.h table.h svc.h rounding.h \
- dfp-1.stderr.exp dfp-1.stdout.exp dfp-1.vgtest
+ dfp-1.stderr.exp dfp-1.stdout.exp dfp-1.vgtest \
+ dfp-2.stderr.exp dfp-2.stdout.exp dfp-2.vgtest
AM_CFLAGS += @FLAG_M64@
AM_CXXFLAGS += @FLAG_M64@
Property changed: trunk/none/tests/s390x (+0 -0)
___________________________________________________________________
Name: svn:ignore
- .deps
add
add_EI
add_GE
allexec
and
and_EI
clc
clcle
cvb
cvd
div
ex_clone
ex_sig
flogr
icm
insert
insert_EI
lam_stam
lpr
Makefile
Makefile.in
mul
mul_GE
mvst
or
or_EI
srst
sub
sub_EI
tcxb
xc
xor
xor_EI
stck
stcke
stckf
op_exception
fgx
condloadstore
fold_And16
stfle
op00
cksm
clcl
mvcl
troo
trot
trto
trtt
tr
tre
clrj
clgrj
crj
cgrj
clij
clgij
cij
cgij
cs
csg
cds
cdsg
cu21
cu21_1
cu24
cu24_1
cu42
cu12
cu12_1
cu14
cu14_1
cu41
ecag
fpext
fpext_warn
fpconv
rounding-1
rounding-2
rounding-3
rounding-4
rounding-5
bfp-1
bfp-2
bfp-3
bfp-4
srnm
srnmb
comp-1
comp-2
ex
exrl
tm
tmll
stmg
test_sig
test_clone
test_fork
clst
mvc
spechelper-algr
spechelper-tmll
spechelper-icm-1
spechelper-icm-2
spechelper-cr
spechelper-ltr
spechelper-alr
spechelper-clr
spechelper-slr
spechelper-slgr
spechelper-or
spechelper-tm
rounding-6
laa
+ .deps
add
add_EI
add_GE
allexec
and
and_EI
clc
clcle
cvb
cvd
div
ex_clone
ex_sig
flogr
icm
insert
insert_EI
lam_stam
lpr
Makefile
Makefile.in
mul
mul_GE
mvst
or
or_EI
srst
sub
sub_EI
tcxb
xc
xor
xor_EI
stck
stcke
stckf
op_exception
fgx
condloadstore
fold_And16
stfle
op00
cksm
clcl
mvcl
troo
trot
trto
trtt
tr
tre
clrj
clgrj
crj
cgrj
clij
clgij
cij
cgij
cs
csg
cds
cdsg
cu21
cu21_1
cu24
cu24_1
cu42
cu12
cu12_1
cu14
cu14_1
cu41
ecag
fpext
fpext_warn
fpconv
rounding-1
rounding-2
rounding-3
rounding-4
rounding-5
bfp-1
bfp-2
bfp-3
bfp-4
srnm
srnmb
comp-1
comp-2
ex
exrl
tm
tmll
stmg
test_sig
test_clone
test_fork
clst
mvc
spechelper-algr
spechelper-tmll
spechelper-icm-1
spechelper-icm-2
spechelper-cr
spechelper-ltr
spechelper-alr
spechelper-clr
spechelper-slr
spechelper-slgr
spechelper-or
spechelper-tm
rounding-6
laa
dfp-1
dfp-2
Added: trunk/none/tests/s390x/dfp_utils.h (+27 -0)
===================================================================
--- trunk/none/tests/s390x/dfp_utils.h 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/dfp_utils.h 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -0,0 +1,27 @@
+#ifndef DFP_UTILS_H
+#define DFP_UTILS_H
+
+/* convinience macros to print DFP values to avoid linking libdfp to
+ DFP testcases */
+
+#define DFP_VAL_PRINT(op, type) \
+ { \
+ size_t n = sizeof(type); \
+ if (n == 8) \
+ printf("%lx", *((unsigned long *) &op)); \
+ else \
+ printf("%lx%08lx", *((unsigned long *) &op), \
+ *(((unsigned long *) &op) + 1)); \
+ }
+
+#define DFP_BINOP_PRINT(op1, op2, result, type, op, cc) \
+ { \
+ DFP_VAL_PRINT(op1, type); \
+ printf(" "op" "); \
+ DFP_VAL_PRINT(op2, type); \
+ printf(" = "); \
+ DFP_VAL_PRINT(result, type); \
+ printf(" cc = %d\n", cc); \
+ }
+
+#endif /* DFP_UTILS_H */
Added: trunk/none/tests/s390x/dfp-2.stdout.exp (+6 -0)
===================================================================
--- trunk/none/tests/s390x/dfp-2.stdout.exp 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/dfp-2.stdout.exp 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -0,0 +1,6 @@
+LTDTR 22280000000a0005 -> 2
+LTDTR a2280000000a0005 -> 1
+LTDTR 2234000000000000 -> 0
+LTXTR 2207000000000000000a0005 -> 2
+LTXTR a207000000000000000a0005 -> 1
+LTXTR 2207c0000000000000000000 -> 0
Added: trunk/none/tests/s390x/dfp-2.stderr.exp (+2 -0)
===================================================================
--- trunk/none/tests/s390x/dfp-2.stderr.exp 2012-12-21 10:34:08 +00:00 (rev 13194)
+++ trunk/none/tests/s390x/dfp-2.stderr.exp 2012-12-21 18:34:48 +00:00 (rev 13195)
@@ -0,0 +1,2 @@
+
+
|
|
From: <sv...@va...> - 2012-12-21 17:32:35
|
florian 2012-12-21 17:32:12 +0000 (Fri, 21 Dec 2012)
New Revision: 2605
Log:
Add support for these DFP insns:
AXTRA, CDTR, CXTR, DXTRA, LDETR, LXDTR, LDXTR, LEDTR, LTXTR, MXTRA, SXTRA
This is part of fixing BZ #307113.
Patch by Maran Pakkirisamy (ma...@li...) with some minor
mods.
Modified files:
trunk/priv/guest_s390_defs.h
trunk/priv/guest_s390_helpers.c
trunk/priv/guest_s390_toIR.c
trunk/priv/host_s390_defs.c
trunk/priv/host_s390_defs.h
trunk/priv/host_s390_isel.c
Modified: trunk/priv/guest_s390_defs.h (+3 -1)
===================================================================
--- trunk/priv/guest_s390_defs.h 2012-12-21 04:40:28 +00:00 (rev 2604)
+++ trunk/priv/guest_s390_defs.h 2012-12-21 17:32:12 +00:00 (rev 2605)
@@ -137,7 +137,8 @@
S390_CC_OP_BFP_32_TO_UINT_64 = 39,
S390_CC_OP_BFP_64_TO_UINT_64 = 40,
S390_CC_OP_BFP_128_TO_UINT_64 = 41,
- S390_CC_OP_DFP_RESULT_64 = 42
+ S390_CC_OP_DFP_RESULT_64 = 42,
+ S390_CC_OP_DFP_RESULT_128 = 43
};
/*------------------------------------------------------------*/
@@ -196,6 +197,7 @@
| S390_CC_OP_BFP_64_TO_UINT_64 | F source | Z rounding mode | |
| S390_CC_OP_BFP_128_TO_UINT_64 | F source hi 64 bits | F source low 64 bits | Z rounding mode |
| S390_CC_OP_DFP_RESULT_64 | D result | | |
+ | S390_CC_OP_DFP_RESULT_128 | D result hi 64 bits | D result low 64 bits | |
+--------------------------------+-----------------------+----------------------+-----------------+
*/
Modified: trunk/priv/host_s390_defs.h (+39 -1)
===================================================================
--- trunk/priv/host_s390_defs.h 2012-12-21 04:40:28 +00:00 (rev 2604)
+++ trunk/priv/host_s390_defs.h 2012-12-21 17:32:12 +00:00 (rev 2605)
@@ -138,6 +138,8 @@
S390_INSN_BFP_COMPARE,
S390_INSN_BFP_CONVERT,
S390_INSN_DFP_BINOP, /* Decimal floating point */
+ S390_INSN_DFP_COMPARE,
+ S390_INSN_DFP_CONVERT,
S390_INSN_MFENCE,
S390_INSN_MZERO, /* Assign zero to a memory location */
S390_INSN_GADD, /* Add a value to a guest register */
@@ -199,7 +201,7 @@
S390_BFP_SQRT
} s390_bfp_unop_t;
-/* Type conversion operations: to and/or from floating point */
+/* Type conversion operations: to and/or from binary floating point */
typedef enum {
S390_BFP_I32_TO_F32,
S390_BFP_I32_TO_F64,
@@ -233,6 +235,13 @@
S390_BFP_F128_TO_F64
} s390_conv_t;
+/* Type conversion operations: to and/or from decimal floating point */
+typedef enum {
+ S390_DFP_D32_TO_D64,
+ S390_DFP_D64_TO_D32,
+ S390_DFP_D64_TO_D128,
+ S390_DFP_D128_TO_D64
+} s390_dfp_conv_t;
/* The kind of binary DFP operations */
typedef enum {
@@ -507,6 +516,21 @@
HReg op3_lo; /* 128-bit operand low part */
s390_dfp_round_t rounding_mode;
} dfp_binop;
+ struct {
+ s390_dfp_conv_t tag;
+ s390_dfp_round_t rounding_mode;
+ HReg dst_hi; /* 128-bit result high part; 64-bit result */
+ HReg dst_lo; /* 128-bit result low part */
+ HReg op_hi; /* 128-bit operand high part; 64-bit opnd */
+ HReg op_lo; /* 128-bit operand low part */
+ } dfp_convert;
+ struct {
+ HReg dst; /* condition code in s390 encoding */
+ HReg op1_hi; /* 128-bit operand high part; 64-bit opnd 1 */
+ HReg op1_lo; /* 128-bit operand low part */
+ HReg op2_hi; /* 128-bit operand high part; 64-bit opnd 2 */
+ HReg op2_lo; /* 128-bit operand low part */
+ } dfp_compare;
/* Miscellaneous */
struct {
@@ -615,6 +639,20 @@
s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
HReg op2, HReg op3,
s390_dfp_round_t rounding_mode);
+s390_insn *s390_insn_dfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
+s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst,
+ HReg op, s390_dfp_round_t);
+s390_insn *s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t, HReg dst_hi,
+ HReg dst_lo, HReg op2_hi, HReg op2_lo,
+ HReg op3_hi, HReg op3_lo,
+ s390_dfp_round_t rounding_mode);
+s390_insn *s390_insn_dfp128_compare(UChar size, HReg dst, HReg op1_hi,
+ HReg op1_lo, HReg op2_hi, HReg op2_lo);
+s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t,
+ HReg dst_hi, HReg dst_lo, HReg op);
+s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t,
+ HReg dst, HReg op_hi, HReg op_lo,
+ s390_dfp_round_t);
s390_insn *s390_insn_mfence(void);
s390_insn *s390_insn_mzero(UChar size, s390_amode *dst);
s390_insn *s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value);
Modified: trunk/priv/host_s390_defs.c (+448 -10)
===================================================================
--- trunk/priv/host_s390_defs.c 2012-12-21 04:40:28 +00:00 (rev 2604)
+++ trunk/priv/host_s390_defs.c 2012-12-21 17:32:12 +00:00 (rev 2605)
@@ -714,6 +714,25 @@
}
break;
+ case S390_INSN_DFP_COMPARE:
+ addHRegUse(u, HRmWrite, insn->variant.dfp_compare.dst);
+ addHRegUse(u, HRmRead, insn->variant.dfp_compare.op1_hi); /* left */
+ addHRegUse(u, HRmRead, insn->variant.dfp_compare.op2_hi); /* right */
+ if (insn->size == 16) {
+ addHRegUse(u, HRmRead, insn->variant.dfp_compare.op1_lo); /* left */
+ addHRegUse(u, HRmRead, insn->variant.dfp_compare.op2_lo); /* right */
+ }
+ break;
+
+ case S390_INSN_DFP_CONVERT:
+ addHRegUse(u, HRmWrite, insn->variant.dfp_convert.dst_hi);
+ if (insn->variant.dfp_convert.dst_lo != INVALID_HREG)
+ addHRegUse(u, HRmWrite, insn->variant.dfp_convert.dst_lo);
+ addHRegUse(u, HRmRead, insn->variant.dfp_convert.op_hi); /* operand */
+ if (insn->variant.dfp_convert.op_lo != INVALID_HREG)
+ addHRegUse(u, HRmRead, insn->variant.dfp_convert.op_lo); /* operand */
+ break;
+
case S390_INSN_MZERO:
s390_amode_get_reg_usage(u, insn->variant.mzero.dst);
break;
@@ -966,6 +985,34 @@
}
break;
+ case S390_INSN_DFP_COMPARE:
+ insn->variant.dfp_compare.dst =
+ lookupHRegRemap(m, insn->variant.dfp_compare.dst);
+ insn->variant.dfp_compare.op1_hi =
+ lookupHRegRemap(m, insn->variant.dfp_compare.op1_hi);
+ insn->variant.dfp_compare.op2_hi =
+ lookupHRegRemap(m, insn->variant.dfp_compare.op2_hi);
+ if (insn->size == 16) {
+ insn->variant.dfp_compare.op1_lo =
+ lookupHRegRemap(m, insn->variant.dfp_compare.op1_lo);
+ insn->variant.dfp_compare.op2_lo =
+ lookupHRegRemap(m, insn->variant.dfp_compare.op2_lo);
+ }
+ break;
+
+ case S390_INSN_DFP_CONVERT:
+ insn->variant.dfp_convert.dst_hi =
+ lookupHRegRemap(m, insn->variant.dfp_convert.dst_hi);
+ if (insn->variant.dfp_convert.dst_lo != INVALID_HREG)
+ insn->variant.dfp_convert.dst_lo =
+ lookupHRegRemap(m, insn->variant.dfp_convert.dst_lo);
+ insn->variant.dfp_convert.op_hi =
+ lookupHRegRemap(m, insn->variant.dfp_convert.op_hi);
+ if (insn->variant.dfp_convert.op_lo != INVALID_HREG)
+ insn->variant.dfp_convert.op_lo =
+ lookupHRegRemap(m, insn->variant.dfp_convert.op_lo);
+ break;
+
case S390_INSN_MZERO:
s390_amode_map_regs(m, insn->variant.mzero.dst);
break;
@@ -1164,6 +1211,19 @@
static UChar *
+emit_RRF5(UChar *p, UInt op, UChar m4, UChar r1, UChar r2)
+{
+ ULong the_insn = op;
+
+ the_insn |= ((ULong)m4) << 8;
+ the_insn |= ((ULong)r1) << 4;
+ the_insn |= ((ULong)r2) << 0;
+
+ return emit_4bytes(p, the_insn);
+}
+
+
+static UChar *
emit_RS(UChar *p, UInt op, UChar r1, UChar r3, UChar b2, UShort d2)
{
ULong the_insn = op;
@@ -3895,6 +3955,44 @@
static UChar *
+s390_emit_AXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0 || s390_host_has_fpext);
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+ if (m4 == 0)
+ s390_disasm(ENC4(MNM, FPR, FPR, FPR), "axtr", r1, r2, r3);
+ else
+ s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "axtra", r1, r2, r3, m4);
+ }
+
+ return emit_RRF4(p, 0xb3da0000, r3, m4, r1, r2);
+}
+
+
+static UChar *
+s390_emit_CDTR(UChar *p, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+ s390_disasm(ENC3(MNM, FPR, FPR), "cdtr", r1, r2);
+
+ return emit_RRE(p, 0xb3e40000, r1, r2);
+}
+
+
+static UChar *
+s390_emit_CXTR(UChar *p, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+ s390_disasm(ENC3(MNM, FPR, FPR), "cxtr", r1, r2);
+
+ return emit_RRE(p, 0xb3ec0000, r1, r2);
+}
+
+
+static UChar *
s390_emit_DDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
{
vassert(s390_host_has_dfp);
@@ -3911,6 +4009,76 @@
static UChar *
+s390_emit_DXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0 || s390_host_has_fpext);
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+ if (m4 == 0)
+ s390_disasm(ENC4(MNM, FPR, FPR, FPR), "dxtr", r1, r2, r3);
+ else
+ s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "dxtra", r1, r2, r3, m4);
+ }
+
+ return emit_RRF4(p, 0xb3d90000, r3, m4, r1, r2);
+}
+
+
+static UChar *
+s390_emit_LDETR(UChar *p, UChar m4, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+ s390_disasm(ENC4(MNM, FPR, FPR, UINT), "ldetr", r1, r2, m4);
+
+ return emit_RRF5(p, 0xb3d40000, m4, r1, r2);
+}
+
+
+static UChar *
+s390_emit_LXDTR(UChar *p, UChar m4, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+ s390_disasm(ENC4(MNM, FPR, FPR, UINT), "lxdtr", r1, r2, m4);
+
+ return emit_RRF5(p, 0xb3dc0000, m4, r1, r2);
+}
+
+
+static UChar *
+s390_emit_LEDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0);
+ vassert(m3 == 0 || s390_host_has_fpext);
+
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+ s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
+ "ledtr", r1, m3, r2, m4);
+ }
+
+ return emit_RRF2(p, 0xb3d50000, m3, m4, r1, r2);
+}
+
+
+static UChar *
+s390_emit_LDXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0);
+ vassert(m3 == 0 || s390_host_has_fpext);
+
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+ s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
+ "ldxtr", r1, m3, r2, m4);
+ }
+
+ return emit_RRF2(p, 0xb3dd0000, m3, m4, r1, r2);
+}
+
+
+static UChar *
s390_emit_MDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
{
vassert(s390_host_has_dfp);
@@ -3927,6 +4095,22 @@
static UChar *
+s390_emit_MXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0 || s390_host_has_fpext);
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+ if (m4 == 0)
+ s390_disasm(ENC4(MNM, FPR, FPR, FPR), "mxtr", r1, r2, r3);
+ else
+ s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "mxtra", r1, r2, r3, m4);
+ }
+
+ return emit_RRF4(p, 0xb3d80000, r3, m4, r1, r2);
+}
+
+
+static UChar *
s390_emit_SDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
{
vassert(s390_host_has_dfp);
@@ -3943,6 +4127,22 @@
static UChar *
+s390_emit_SXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0 || s390_host_has_fpext);
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+ if (m4 == 0)
+ s390_disasm(ENC4(MNM, FPR, FPR, FPR), "sxtr", r1, r2, r3);
+ else
+ s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "sxtra", r1, r2, r3, m4);
+ }
+
+ return emit_RRF4(p, 0xb3db0000, r3, m4, r1, r2);
+}
+
+
+static UChar *
s390_emit_LOCGR(UChar *p, UChar m3, UChar r1, UChar r2)
{
vassert(s390_host_has_lsc);
@@ -4914,11 +5114,11 @@
}
-/* Check validity of a register pair for 128-bit BFP. Valid register
+/* Check validity of a register pair for 128-bit FP. Valid register
pairs are (0,2), (1,3), (4, 6), (5, 7), (8, 10), (9, 11), (12, 14),
and (13, 15). */
static Bool
-is_valid_bfp128_regpair(HReg hi, HReg lo)
+is_valid_fp128_regpair(HReg hi, HReg lo)
{
UInt hi_regno = hregNumber(hi);
UInt lo_regno = hregNumber(lo);
@@ -4936,8 +5136,8 @@
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
vassert(size == 16);
- vassert(is_valid_bfp128_regpair(dst_hi, dst_lo));
- vassert(is_valid_bfp128_regpair(op2_hi, op2_lo));
+ vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
+ vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
insn->tag = S390_INSN_BFP_BINOP;
insn->size = size;
@@ -4958,8 +5158,8 @@
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
vassert(size == 16);
- vassert(is_valid_bfp128_regpair(dst_hi, dst_lo));
- vassert(is_valid_bfp128_regpair(op_hi, op_lo));
+ vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
+ vassert(is_valid_fp128_regpair(op_hi, op_lo));
insn->tag = S390_INSN_BFP_UNOP;
insn->size = size;
@@ -4980,8 +5180,8 @@
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
vassert(size == 16);
- vassert(is_valid_bfp128_regpair(op1_hi, op1_lo));
- vassert(is_valid_bfp128_regpair(op2_hi, op2_lo));
+ vassert(is_valid_fp128_regpair(op1_hi, op1_lo));
+ vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
insn->tag = S390_INSN_BFP_COMPARE;
insn->size = size;
@@ -5004,11 +5204,11 @@
if (size == 16) {
/* From smaller size to 16 bytes */
- vassert(is_valid_bfp128_regpair(dst_hi, dst_lo));
+ vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
vassert(op_lo == INVALID_HREG);
} else {
/* From 16 bytes to smaller size */
- vassert(is_valid_bfp128_regpair(op_hi, op_lo));
+ vassert(is_valid_fp128_regpair(op_hi, op_lo));
vassert(dst_lo == INVALID_HREG);
}
@@ -5072,6 +5272,149 @@
s390_insn *
+s390_insn_dfp_compare(UChar size, HReg dst, HReg op1, HReg op2)
+{
+ s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
+
+ vassert(size == 8);
+
+ insn->tag = S390_INSN_DFP_COMPARE;
+ insn->size = size;
+ insn->variant.dfp_compare.dst = dst;
+ insn->variant.dfp_compare.op1_hi = op1;
+ insn->variant.dfp_compare.op2_hi = op2;
+ insn->variant.dfp_compare.op1_lo = INVALID_HREG;
+ insn->variant.dfp_compare.op2_lo = INVALID_HREG;
+
+ return insn;
+}
+
+
+s390_insn *
+s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst, HReg op,
+ s390_dfp_round_t rounding_mode)
+{
+ s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
+
+ vassert(size == 8);
+
+ insn->tag = S390_INSN_DFP_CONVERT;
+ insn->size = size;
+ insn->variant.dfp_convert.tag = tag;
+ insn->variant.dfp_convert.dst_hi = dst;
+ insn->variant.dfp_convert.op_hi = op;
+ insn->variant.dfp_convert.dst_lo = INVALID_HREG;
+ insn->variant.dfp_convert.op_lo = INVALID_HREG;
+ insn->variant.dfp_convert.rounding_mode = rounding_mode;
+
+ return insn;
+}
+
+
+s390_insn *
+s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t tag, HReg dst_hi,
+ HReg dst_lo, HReg op2_hi, HReg op2_lo, HReg op3_hi,
+ HReg op3_lo, s390_dfp_round_t rounding_mode)
+{
+ s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
+
+ vassert(size == 16);
+ vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
+ vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
+ vassert(is_valid_fp128_regpair(op3_hi, op3_lo));
+
+
+ insn->tag = S390_INSN_DFP_BINOP;
+ insn->size = size;
+ insn->variant.dfp_binop.tag = tag;
+ insn->variant.dfp_binop.dst_hi = dst_hi;
+ insn->variant.dfp_binop.dst_lo = dst_lo;
+ insn->variant.dfp_binop.op2_hi = op2_hi;
+ insn->variant.dfp_binop.op2_lo = op2_lo;
+ insn->variant.dfp_binop.op3_hi = op3_hi;
+ insn->variant.dfp_binop.op3_lo = op3_lo;
+ insn->variant.dfp_binop.rounding_mode = rounding_mode;
+
+ return insn;
+}
+
+
+s390_insn *
+s390_insn_dfp128_compare(UChar size, HReg dst, HReg op1_hi, HReg op1_lo,
+ HReg op2_hi, HReg op2_lo)
+{
+ s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
+
+ vassert(size == 16);
+ vassert(is_valid_fp128_regpair(op1_hi, op1_lo));
+ vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
+
+ insn->tag = S390_INSN_DFP_COMPARE;
+ insn->size = size;
+ insn->variant.dfp_compare.dst = dst;
+ insn->variant.dfp_compare.op1_hi = op1_hi;
+ insn->variant.dfp_compare.op1_lo = op1_lo;
+ insn->variant.dfp_compare.op2_hi = op2_hi;
+ insn->variant.dfp_compare.op2_lo = op2_lo;
+
+ return insn;
+}
+
+
+static s390_insn *
+s390_insn_dfp128_convert(UChar size, s390_dfp_conv_t tag, HReg dst_hi,
+ HReg dst_lo, HReg op_hi, HReg op_lo,
+ s390_dfp_round_t rounding_mode)
+{
+ s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
+
+ if (size == 16) {
+ /* From smaller size to 16 bytes */
+ vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
+ vassert(op_lo == INVALID_HREG);
+ } else {
+ /* From 16 bytes to smaller size */
+ vassert(is_valid_fp128_regpair(op_hi, op_lo));
+ vassert(dst_lo == INVALID_HREG);
+ }
+
+ insn->tag = S390_INSN_DFP_CONVERT;
+ insn->size = size;
+ insn->variant.dfp_convert.tag = tag;
+ insn->variant.dfp_convert.dst_hi = dst_hi;
+ insn->variant.dfp_convert.dst_lo = dst_lo;
+ insn->variant.dfp_convert.op_hi = op_hi;
+ insn->variant.dfp_convert.op_lo = op_lo;
+ insn->variant.dfp_convert.rounding_mode = rounding_mode;
+
+ return insn;
+}
+
+
+s390_insn *
+s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t tag, HReg dst_hi,
+ HReg dst_lo, HReg op)
+{
+ /* Conversion to dfp128 never requires a rounding mode. Provide default
+ rounding mode. It will not be used when emitting insns. */
+ s390_dfp_round_t rounding_mode = S390_DFP_ROUND_NEAREST_EVEN_4;
+
+ return s390_insn_dfp128_convert(size, tag, dst_hi, dst_lo, op,
+ INVALID_HREG, rounding_mode);
+}
+
+
+s390_insn *
+s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t tag, HReg dst,
+ HReg op_hi, HReg op_lo,
+ s390_dfp_round_t rounding_mode)
+{
+ return s390_insn_dfp128_convert(size, tag, dst, INVALID_HREG, op_hi, op_lo,
+ rounding_mode);
+}
+
+
+s390_insn *
s390_insn_mfence(void)
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
@@ -5649,6 +5992,24 @@
insn->variant.dfp_binop.op3_hi);
break;
+ case S390_INSN_DFP_COMPARE:
+ s390_sprintf(buf, "%M %R,%R,%R", "v-dcmp", insn->variant.dfp_compare.dst,
+ insn->variant.dfp_compare.op1_hi,
+ insn->variant.dfp_compare.op2_hi);
+ break;
+
+ case S390_INSN_DFP_CONVERT:
+ switch (insn->variant.dfp_convert.tag) {
+ case S390_DFP_D32_TO_D64:
+ case S390_DFP_D64_TO_D32:
+ case S390_DFP_D64_TO_D128:
+ case S390_DFP_D128_TO_D64: op = "v-d2d"; break;
+ default: goto fail;
+ }
+ s390_sprintf(buf, "%M %R,%R", op, insn->variant.dfp_convert.dst_hi,
+ insn->variant.dfp_convert.op_hi);
+ break;
+
case S390_INSN_MFENCE:
s390_sprintf(buf, "%M", "v-mfence");
return buf; /* avoid printing "size = ..." which is meaningless */
@@ -5778,6 +6139,16 @@
goto common;
}
+ case S390_INSN_DFP_CONVERT:
+ switch (insn->variant.dfp_convert.tag) {
+ case S390_DFP_D32_TO_D64: p += vex_sprintf(p, "4 -> "); goto common;
+ case S390_DFP_D64_TO_D32:
+ case S390_DFP_D64_TO_D128:p += vex_sprintf(p, "8 -> "); goto common;
+ case S390_DFP_D128_TO_D64:p += vex_sprintf(p, "16 -> "); goto common;
+ default:
+ goto common;
+ }
+
default:
goto common;
}
@@ -7782,6 +8153,17 @@
default: goto fail;
}
break;
+
+ case 16:
+ switch (insn->variant.dfp_binop.tag) {
+ case S390_DFP_ADD: return s390_emit_AXTRA(buf, r3, m4, r1, r2);
+ case S390_DFP_SUB: return s390_emit_SXTRA(buf, r3, m4, r1, r2);
+ case S390_DFP_MUL: return s390_emit_MXTRA(buf, r3, m4, r1, r2);
+ case S390_DFP_DIV: return s390_emit_DXTRA(buf, r3, m4, r1, r2);
+ default: goto fail;
+ }
+ break;
+
default: goto fail;
}
@@ -7791,6 +8173,54 @@
static UChar *
+s390_insn_dfp_compare_emit(UChar *buf, const s390_insn *insn)
+{
+ UInt dst = hregNumber(insn->variant.dfp_compare.dst);
+ UInt r1 = hregNumber(insn->variant.dfp_compare.op1_hi);
+ UInt r2 = hregNumber(insn->variant.dfp_compare.op2_hi);
+
+ switch (insn->size) {
+ case 8: buf = s390_emit_CDTR(buf, r1, r2); break;
+ case 16: buf = s390_emit_CXTR(buf, r1, r2); break;
+ default: goto fail;
+ }
+
+ return s390_emit_load_cc(buf, dst); /* Load condition code into DST */
+
+ fail:
+ vpanic("s390_insn_dfp_compare_emit");
+}
+
+
+static UChar *
+s390_insn_dfp_convert_emit(UChar *buf, const s390_insn *insn)
+{
+ UInt r1 = hregNumber(insn->variant.dfp_convert.dst_hi);
+ UInt r2 = hregNumber(insn->variant.dfp_convert.op_hi);
+ s390_dfp_round_t m3 = insn->variant.dfp_convert.rounding_mode;
+ /* The IEEE-inexact-exception control is not modelled. So the
+ m4 field is 0 (which is what GCC does, too) */
+ const UInt m4 = 0;
+
+ switch (insn->variant.dfp_convert.tag) {
+
+ /* Load lengthened */
+ case S390_DFP_D32_TO_D64: return s390_emit_LDETR(buf, m4, r1, r2);
+ case S390_DFP_D64_TO_D128: return s390_emit_LXDTR(buf, m4, r1, r2);
+
+ /* Load rounded */
+ case S390_DFP_D64_TO_D32: return s390_emit_LEDTR(buf, m3, m4, r1, r2);
+ case S390_DFP_D128_TO_D64: return s390_emit_LDXTR(buf, m3, m4, r1, r2);
+
+ default: goto fail;
+ }
+
+ fail:
+ vpanic("s390_insn_dfp_convert_emit");
+}
+
+
+static UChar *
s390_insn_mfence_emit(UChar *buf, const s390_insn *insn)
{
return s390_emit_BCR(buf, 0xF, 0x0);
@@ -8383,6 +8813,14 @@
end = s390_insn_dfp_binop_emit(buf, insn);
break;
+ case S390_INSN_DFP_COMPARE:
+ end = s390_insn_dfp_compare_emit(buf, insn);
+ break;
+
+ case S390_INSN_DFP_CONVERT:
+ end = s390_insn_dfp_convert_emit(buf, insn);
+ break;
+
case S390_INSN_MFENCE:
end = s390_insn_mfence_emit(buf, insn);
break;
Modified: trunk/priv/host_s390_isel.c (+361 -4)
===================================================================
--- trunk/priv/host_s390_isel.c 2012-12-21 04:40:28 +00:00 (rev 2604)
+++ trunk/priv/host_s390_isel.c 2012-12-21 17:32:12 +00:00 (rev 2605)
@@ -136,6 +136,7 @@
static HReg s390_isel_float_expr(ISelEnv *, IRExpr *);
static void s390_isel_float128_expr(HReg *, HReg *, ISelEnv *, IRExpr *);
static HReg s390_isel_dfp_expr(ISelEnv *, IRExpr *);
+static void s390_isel_dfp128_expr(HReg *, HReg *, ISelEnv *, IRExpr *);
static Int
@@ -1206,6 +1207,46 @@
return convert_s390_fpcc_to_vex(env, cc_s390);
}
+ case Iop_CmpD64: {
+ HReg cc_s390, h2;
+
+ h1 = s390_isel_dfp_expr(env, arg1);
+ h2 = s390_isel_dfp_expr(env, arg2);
+ cc_s390 = newVRegI(env);
+ size = 8;
+
+ addInstr(env, s390_insn_dfp_compare(size, cc_s390, h1, h2));
+
+ return convert_s390_fpcc_to_vex(env, cc_s390);
+ }
+
+ case Iop_CmpD128: {
+ HReg op1_hi, op1_lo, op2_hi, op2_lo, f12, f13, f14, f15, cc_s390;
+
+ s390_isel_dfp128_expr(&op1_hi, &op1_lo, env, arg1); /* 1st operand */
+ s390_isel_dfp128_expr(&op2_hi, &op2_lo, env, arg2); /* 2nd operand */
+ cc_s390 = newVRegI(env);
+
+ /* We use non-virtual registers as pairs (f13, f15) and (f12, f14)) */
+ f12 = make_fpr(12);
+ f13 = make_fpr(13);
+ f14 = make_fpr(14);
+ f15 = make_fpr(15);
+
+ /* 1st operand --> (f12, f14) */
+ addInstr(env, s390_insn_move(8, f12, op1_hi));
+ addInstr(env, s390_insn_move(8, f14, op1_lo));
+
+ /* 2nd operand --> (f13, f15) */
+ addInstr(env, s390_insn_move(8, f13, op2_hi));
+ addInstr(env, s390_insn_move(8, f15, op2_lo));
+
+ res = newVRegI(env);
+ addInstr(env, s390_insn_dfp128_compare(16, cc_s390, f12, f14, f13, f15));
+
+ return convert_s390_fpcc_to_vex(env, cc_s390);
+ }
+
case Iop_Add8:
case Iop_Add16:
case Iop_Add32:
@@ -1357,6 +1398,14 @@
return dst;
}
+ if (unop == Iop_ReinterpD64asI64) {
+ dst = newVRegI(env);
+ h1 = s390_isel_dfp_expr(env, arg); /* Process the operand */
+ addInstr(env, s390_insn_move(size, dst, h1));
+
+ return dst;
+ }
+
/* Expressions whose argument is 1-bit wide */
if (typeOfIRExpr(env->type_env, arg) == Ity_I1) {
s390_cc_t cond = s390_isel_cc(env, arg);
@@ -2216,6 +2265,189 @@
/*---------------------------------------------------------*/
+/*--- ISEL: Decimal point expressions (128 bit) ---*/
+/*---------------------------------------------------------*/
+static void
+s390_isel_dfp128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env,
+ IRExpr *expr)
+{
+ IRType ty = typeOfIRExpr(env->type_env, expr);
+
+ vassert(ty == Ity_D128);
+
+ switch (expr->tag) {
+ case Iex_RdTmp:
+ /* Return the virtual registers that hold the temporary. */
+ lookupIRTemp128(dst_hi, dst_lo, env, expr->Iex.RdTmp.tmp);
+ return;
+
+ /* --------- LOAD --------- */
+ case Iex_Load: {
+ IRExpr *addr_hi, *addr_lo;
+ s390_amode *am_hi, *am_lo;
+
+ if (expr->Iex.Load.end != Iend_BE)
+ goto irreducible;
+
+ addr_hi = expr->Iex.Load.addr;
+ addr_lo = IRExpr_Binop(Iop_Add64, addr_hi, mkU64(8));
+
+ am_hi = s390_isel_amode(env, addr_hi);
+ am_lo = s390_isel_amode(env, addr_lo);
+
+ *dst_hi = newVRegF(env);
+ *dst_lo = newVRegF(env);
+ addInstr(env, s390_insn_load(8, *dst_hi, am_hi));
+ addInstr(env, s390_insn_load(8, *dst_hi, am_lo));
+ return;
+ }
+
+ /* --------- GET --------- */
+ case Iex_Get:
+ /* This is not supported because loading 128-bit from the guest
+ state is almost certainly wrong. Use get_dpr_pair instead. */
+ vpanic("Iex_Get with D128 data");
+
+ /* --------- 4-ary OP --------- */
+ case Iex_Qop:
+ vpanic("Iex_Qop with D128 data");
+
+ /* --------- TERNARY OP --------- */
+ case Iex_Triop: {
+ IRTriop *triop = expr->Iex.Triop.details;
+ IROp op = triop->op;
+ IRExpr *irrm = triop->arg1;
+ IRExpr *left = triop->arg2;
+ IRExpr *right = triop->arg3;
+ s390_dfp_round_t rounding_mode;
+ s390_dfp_binop_t dfpop;
+ HReg op1_hi, op1_lo, op2_hi, op2_lo, f9, f11, f12, f13, f14, f15;
+
+ s390_isel_dfp128_expr(&op1_hi, &op1_lo, env, left); /* 1st operand */
+ s390_isel_dfp128_expr(&op2_hi, &op2_lo, env, right); /* 2nd operand */
+
+ /* We use non-virtual registers as pairs with (f9, f11) as op1,
+ (f12, f14) as op2 and (f13, f15) as destination) */
+ f9 = make_fpr(9);
+ f11 = make_fpr(11);
+ f12 = make_fpr(12);
+ f13 = make_fpr(13);
+ f14 = make_fpr(14);
+ f15 = make_fpr(15);
+
+ /* 1st operand --> (f9, f11) */
+ addInstr(env, s390_insn_move(8, f9, op1_hi));
+ addInstr(env, s390_insn_move(8, f11, op1_lo));
+
+ /* 2nd operand --> (f12, f14) */
+ addInstr(env, s390_insn_move(8, f12, op2_hi));
+ addInstr(env, s390_insn_move(8, f14, op2_lo));
+
+ switch (op) {
+ case Iop_AddD128: dfpop = S390_DFP_ADD; break;
+ case Iop_SubD128: dfpop = S390_DFP_SUB; break;
+ case Iop_MulD128: dfpop = S390_DFP_MUL; break;
+ case Iop_DivD128: dfpop = S390_DFP_DIV; break;
+ default:
+ goto irreducible;
+ }
+
+ /* DFP binary ops have insns with rounding mode field
+ when the floating point extension facility is installed. */
+ if (s390_host_has_fpext) {
+ rounding_mode = get_dfp_rounding_mode(env, irrm);
+ } else {
+ set_dfp_rounding_mode_in_fpc(env, irrm);
+ rounding_mode = S390_DFP_ROUND_PER_FPC_0;
+ }
+
+ addInstr(env, s390_insn_dfp128_binop(16, dfpop, f13, f15, f9, f11,
+ f12, f14, rounding_mode));
+
+ /* Move result to virtual destination register */
+ *dst_hi = newVRegF(env);
+ *dst_lo = newVRegF(env);
+ addInstr(env, s390_insn_move(8, *dst_hi, f13));
+ addInstr(env, s390_insn_move(8, *dst_lo, f15));
+
+ return;
+ }
+
+ /* --------- BINARY OP --------- */
+ case Iex_Binop: {
+ switch (expr->Iex.Binop.op) {
+ case Iop_D64HLtoD128:
+ *dst_hi = s390_isel_dfp_expr(env, expr->Iex.Binop.arg1);
+ *dst_lo = s390_isel_dfp_expr(env, expr->Iex.Binop.arg2);
+ return;
+
+ default:
+ goto irreducible;
+ }
+ }
+
+ /* --------- UNARY OP --------- */
+ case Iex_Unop: {
+ IRExpr *left = expr->Iex.Unop.arg;
+ s390_dfp_conv_t conv;
+ // HReg op, f12, f13, f14, f15;
+ HReg op, f12, f14;
+
+ /* We use non-virtual registers as pairs (f13, f15) and (f12, f14)) */
+ f12 = make_fpr(12);
+ // f13 = make_fpr(13);
+ f14 = make_fpr(14);
+ // f15 = make_fpr(15);
+
+ switch (expr->Iex.Unop.op) {
+ case Iop_D64toD128: conv = S390_DFP_D64_TO_D128; goto convert_dfp;
+ default:
+ goto irreducible;
+ }
+
+ convert_dfp:
+ op = s390_isel_dfp_expr(env, left);
+ addInstr(env, s390_insn_dfp128_convert_to(16, conv, f12, f14, op));
+ goto move_dst;
+
+ move_dst:
+ /* Move result to virtual destination registers */
+ *dst_hi = newVRegF(env);
+ *dst_lo = newVRegF(env);
+ addInstr(env, s390_insn_move(8, *dst_hi, f12));
+ addInstr(env, s390_insn_move(8, *dst_lo, f14));
+ return;
+ }
+
+ default:
+ goto irreducible;
+ }
+
+ /* We get here if no pattern matched. */
+ irreducible:
+ ppIRExpr(expr);
+ vpanic("s390_isel_dfp128_expr_wrk: cannot reduce tree");
+
+}
+
+
+/* Compute a 128-bit value into two 64-bit registers. These may be either
+ real or virtual regs; in any case they must not be changed by subsequent
+ code emitted by the caller. */
+static void
+s390_isel_dfp128_expr(HReg *dst_hi, HReg *dst_lo, ISelEnv *env, IRExpr *expr)
+{
+ s390_isel_dfp128_expr_wrk(dst_hi, dst_lo, env, expr);
+
+ /* Sanity checks ... */
+ vassert(hregIsVirtual(*dst_hi));
+ vassert(hregIsVirtual(*dst_lo));
+ vassert(hregClass(*dst_hi) == HRcFlt64);
+ vassert(hregClass(*dst_lo) == HRcFlt64);
+}
+
+
+/*---------------------------------------------------------*/
/*--- ISEL: Decimal point expressions (64 bit) ---*/
/*---------------------------------------------------------*/
@@ -2225,7 +2457,7 @@
IRType ty = typeOfIRExpr(env->type_env, expr);
UChar size;
- vassert(ty == Ity_D64);
+ vassert(ty == Ity_D64 || ty == Ity_D32);
size = sizeofIRType(ty);
@@ -2257,6 +2489,114 @@
return dst;
}
+ /* --------- BINARY OP --------- */
+ case Iex_Binop: {
+ IROp op = expr->Iex.Binop.op;
+ IRExpr *irrm = expr->Iex.Binop.arg1;
+ IRExpr *left = expr->Iex.Binop.arg2;
+ HReg h1, dst;
+ s390_dfp_conv_t conv;
+
+ switch (op) {
+ case Iop_D64toD32: conv = S390_DFP_D64_TO_D32; goto convert_dfp;
+
+ convert_dfp:
+ h1 = s390_isel_dfp_expr(env, left);
+ goto convert;
+
+ convert: {
+ s390_dfp_round_t rounding_mode;
+ /* convert-from-fixed and load-rounded have a rounding mode field
+ when the floating point extension facility is installed. */
+ dst = newVRegF(env);
+ if (s390_host_has_fpext) {
+ rounding_mode = get_dfp_rounding_mode(env, irrm);
+ } else {
+ set_dfp_rounding_mode_in_fpc(env, irrm);
+ rounding_mode = S390_DFP_ROUND_PER_FPC_0;
+ }
+ addInstr(env, s390_insn_dfp_convert(size, conv, dst, h1,
+ rounding_mode));
+ return dst;
+ }
+ default:
+ goto irreducible;
+
+ case Iop_D128toD64: {
+ HReg op_hi, op_lo, f13, f15;
+ s390_dfp_round_t rounding_mode;
+
+ conv = S390_DFP_D128_TO_D64;
+
+ s390_isel_dfp128_expr(&op_hi, &op_lo, env, left);
+
+ /* We use non-virtual registers as pairs (f13, f15) */
+ f13 = make_fpr(13);
+ f15 = make_fpr(15);
+
+ /* operand --> (f13, f15) */
+ addInstr(env, s390_insn_move(8, f13, op_hi));
+ addInstr(env, s390_insn_move(8, f15, op_lo));
+
+ dst = newVRegF(env);
+ /* load-rounded has a rounding mode field when the floating point
+ extension facility is installed. */
+ if (s390_host_has_fpext) {
+ rounding_mode = get_dfp_rounding_mode(env, irrm);
+ } else {
+ set_dfp_rounding_mode_in_fpc(env, irrm);
+ rounding_mode = S390_DFP_ROUND_PER_FPC_0;
+ }
+ addInstr(env, s390_insn_dfp128_convert_from(size, conv, dst, f13, f15,
+ rounding_mode));
+ return dst;
+ }
+
+ }
+ }
+
+ /* --------- UNARY OP --------- */
+ case Iex_Unop: {
+ IROp op = expr->Iex.Unop.op;
+ IRExpr *left = expr->Iex.Unop.arg;
+ s390_dfp_conv_t conv;
+ HReg h1, dst;
+
+ if (op == Iop_D128HItoD64 || op == Iop_D128LOtoD64) {
+ HReg dst_hi, dst_lo;
+
+ s390_isel_dfp128_expr(&dst_hi, &dst_lo, env, left);
+ return op == Iop_D128LOtoD64 ? dst_lo : dst_hi;
+ }
+
+ if (op == Iop_ReinterpI64asD64) {
+ dst = newVRegF(env);
+ h1 = s390_isel_int_expr(env, left); /* Process the operand */
+ addInstr(env, s390_insn_move(size, dst, h1));
+
+ return dst;
+ }
+
+ switch (op) {
+ case Iop_D32toD64: conv = S390_DFP_D32_TO_D64; goto convert_dfp1;
+
+ convert_dfp1:
+ h1 = s390_isel_dfp_expr(env, left);
+ goto convert1;
+
+ convert1:
+ dst = newVRegF(env);
+ /* No rounding mode is needed for these conversions. Just stick
+ one in. It won't be used later on. */
+ addInstr(env, s390_insn_dfp_convert(size, conv, dst, h1,
+ S390_DFP_ROUND_NEAREST_EVEN_4));
+ return dst;
+
+ default:
+ goto irreducible;
+ }
+ }
+
/* --------- TERNARY OP --------- */
case Iex_Triop: {
IRTriop *triop = expr->Iex.Triop.details;
@@ -2572,8 +2912,9 @@
break;
case Ity_F128:
+ case Ity_D128:
/* Cannot occur. No such instruction */
- vpanic("Ist_Store with F128 data");
+ vpanic("Ist_Store with 128-bit floating point data");
default:
goto stmt_fail;
@@ -2703,9 +3044,11 @@
break;
case Ity_F128:
- /* Does not occur. See function put_fpr_pair. */
- vpanic("Ist_Put with F128 data");
+ case Ity_D128:
+ /* Does not occur. See function put_(f|d)pr_pair. */
+ vpanic("Ist_Put with 128-bit floating point data");
+ case Ity_D32:
case Ity_D64:
src = s390_isel_dfp_expr(env, stmt->Ist.Put.data);
break;
@@ -2768,11 +3111,23 @@
return;
}
+ case Ity_D32:
case Ity_D64:
src = s390_isel_dfp_expr(env, stmt->Ist.WrTmp.data);
dst = lookupIRTemp(env, tmp);
break;
+ case Ity_D128: {
+ HReg dst_hi, dst_lo, res_hi, res_lo;
+
+ s390_isel_dfp128_expr(&res_hi, &res_lo, env, stmt->Ist.WrTmp.data);
+ lookupIRTemp128(&dst_hi, &dst_lo, env, tmp);
+
+ addInstr(env, s390_insn_move(8, dst_hi, res_hi));
+ addInstr(env, s390_insn_move(8, dst_lo, res_lo));
+ return;
+ }
+
default:
goto stmt_fail;
}
@@ -3138,11 +3493,13 @@
case Ity_F32:
case Ity_F64:
+ case Ity_D32:
case Ity_D64:
hreg = mkHReg(j++, HRcFlt64, True);
break;
case Ity_F128:
+ case Ity_D128:
hreg = mkHReg(j++, HRcFlt64, True);
hregHI = mkHReg(j++, HRcFlt64, True);
break;
Modified: trunk/priv/guest_s390_toIR.c (+312 -23)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-12-21 04:40:28 +00:00 (rev 2604)
+++ trunk/priv/guest_s390_toIR.c 2012-12-21 17:32:12 +00:00 (rev 2605)
@@ -50,6 +50,7 @@
static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
+static IRExpr *convert_vex_fpcc_to_s390(IRTemp);
/*------------------------------------------------------------*/
@@ -455,6 +456,29 @@
put_fpr_dw0(archreg + 2, low);
}
+/* Read a floating point register pair cointaining DFP value
+ and combine their contents into a 128-bit value */
+
+static IRExpr *
+get_dpr_pair(UInt archreg)
+{
+ IRExpr *high = get_dpr_dw0(archreg);
+ IRExpr *low = get_dpr_dw0(archreg + 2);
+
+ return binop(Iop_D64HLtoD128, high, low);
+}
+
+/* Write a 128-bit decimal floating point value into a register pair. */
+static void
+put_dpr_pair(UInt archreg, IRExpr *expr)
+{
+ IRExpr *high = unop(Iop_D128HItoD64, expr);
+ IRExpr *low = unop(Iop_D128LOtoD64, expr);
+
+ put_dpr_dw0(archreg, high);
+ put_dpr_dw0(archreg + 2, low);
+}
+
/* Terminate the current IRSB with an emulation failure. */
static void
emulation_failure(VexEmNote fail_kind)
@@ -667,7 +691,23 @@
}
+/* Write a 128-bit decimal floating point value into the flags thunk.
+ This is done by splitting the value into two 64-bits values. */
static void
+s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
+{
+ IRExpr *op, *hi, *lo, *ndep;
+
+ op = mkU64(opc);
+ hi = unop(Iop_D128HItoD64, mkexpr(d1));
+ lo = unop(Iop_D128LOtoD64, mkexpr(d1));
+ ndep = mkU64(0);
+
+ s390_cc_thunk_fill(op, hi, lo, ndep);
+}
+
+
+static void
s390_cc_set(UInt val)
{
s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
@@ -912,6 +952,22 @@
return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
}
+/* Write word #0 of a dpr to the guest state. */
+static __inline__ void
+put_dpr_w0(UInt archreg, IRExpr *expr)
+{
+ vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
+
+ stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
+}
+
+/* Read word #0 of a dpr register. */
+static __inline__ IRExpr *
+get_dpr_w0(UInt archreg)
+{
+ return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
+}
+
/* Write double word #0 of a fpr containg DFP value to the guest state. */
static __inline__ void
put_dpr_dw0(UInt archreg, IRExpr *expr)
@@ -1889,6 +1945,16 @@
}
static void
+s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
+ UChar m4, UChar r1, UChar r2)
+{
+ const HChar *mnm = irgen(m4, r1, r2);
+
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
+ s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
+}
+
+static void
s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
UChar r2),
UChar m3, UChar m4, UChar r1, UChar r2)
@@ -8929,18 +8995,6 @@
}
static const HChar *
-s390_irgen_LTDTR(UChar r1, UChar r2)
-{
- IRTemp result = newTemp(Ity_D64);
-
- assign(result, get_dpr_dw0(r2));
- put_dpr_dw0(r1, mkexpr(result));
- s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
-
- return "ltdtr";
-}
-
-static const HChar *
s390_irgen_MEEBR(UChar r1, UChar r2)
{
IRTemp op1 = newTemp(Ity_F32);
@@ -9105,6 +9159,66 @@
}
static const HChar *
+s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
+{
+ IRTemp op1 = newTemp(Ity_D128);
+ IRTemp op2 = newTemp(Ity_D128);
+ IRTemp result = newTemp(Ity_D128);
+ IRTemp rounding_mode;
+
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0 || s390_host_has_fpext);
+ /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
+ since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+ rounding_mode = encode_dfp_rounding_mode(m4);
+ assign(op1, get_dpr_pair(r2));
+ assign(op2, get_dpr_pair(r3));
+ assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
+ mkexpr(op2)));
+ put_dpr_pair(r1, mkexpr(result));
+
+ s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
+
+ return (m4 == 0) ? "axtr" : "axtra";
+}
+
+static const HChar *
+s390_irgen_CDTR(UChar r1, UChar r2)
+{
+ IRTemp op1 = newTemp(Ity_D64);
+ IRTemp op2 = newTemp(Ity_D64);
+ IRTemp cc_vex = newTemp(Ity_I32);
+ IRTemp cc_s390 = newTemp(Ity_I32);
+
+ assign(op1, get_dpr_dw0(r1));
+ assign(op2, get_dpr_dw0(r2));
+ assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
+
+ assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
+
+ return "cdtr";
+}
+
+static const HChar *
+s390_irgen_CXTR(UChar r1, UChar r2)
+{
+ IRTemp op1 = newTemp(Ity_D128);
+ IRTemp op2 = newTemp(Ity_D128);
+ IRTemp cc_vex = newTemp(Ity_I32);
+ IRTemp cc_s390 = newTemp(Ity_I32);
+
+ assign(op1, get_dpr_pair(r1));
+ assign(op2, get_dpr_pair(r2));
+ assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
+
+ assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
+ s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
+
+ return "cxtr";
+}
+
+static const HChar *
s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
{
IRTemp op1 = newTemp(Ity_D64);
@@ -9127,6 +9241,112 @@
}
static const HChar *
+s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
+{
+ IRTemp op1 = newTemp(Ity_D128);
+ IRTemp op2 = newTemp(Ity_D128);
+ IRTemp result = newTemp(Ity_D128);
+ IRTemp rounding_mode;
+
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0 || s390_host_has_fpext);
+ /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
+ since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+ rounding_mode = encode_dfp_rounding_mode(m4);
+ assign(op1, get_dpr_pair(r2));
+ assign(op2, get_dpr_pair(r3));
+ assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
+ mkexpr(op2)));
+ put_dpr_pair(r1, mkexpr(result));
+
+ return (m4 == 0) ? "dxtr" : "dxtra";
+}
+
+static const HChar *
+s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
+{
+ IRTemp op = newTemp(Ity_D32);
+
+ vassert(s390_host_has_dfp);
+
+ assign(op, get_dpr_w0(r2));
+ put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
+
+ return "ldetr";
+}
+
+static const HChar *
+s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
+{
+ IRTemp op = newTemp(Ity_D64);
+
+ assign(op, get_dpr_dw0(r2));
+ put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
+
+ return "lxdtr";
+}
+
+static const HChar *
+s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
+ UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m3 = S390_DFP_ROUND_PER_FPC_0;
+ }
+ IRTemp result = newTemp(Ity_D64);
+
+ assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
+ get_dpr_pair(r2)));
+ put_dpr_dw0(r1, mkexpr(result));
+
+ return "ldxtr";
+}
+
+static const HChar *
+s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
+ UChar r1, UChar r2)
+{
+ vassert(s390_host_has_dfp);
+ if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m3 = S390_DFP_ROUND_PER_FPC_0;
+ }
+ IRTemp op = newTemp(Ity_D64);
+
+ assign(op, get_dpr_dw0(r2));
+ put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
+ mkexpr(op)));
+
+ return "ledtr";
+}
+
+static const HChar *
+s390_irgen_LTDTR(UChar r1, UChar r2)
+{
+ IRTemp result = newTemp(Ity_D64);
+
+ assign(result, get_dpr_dw0(r2));
+ put_dpr_dw0(r1, mkexpr(result));
+ s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
+
+ return "ltdtr";
+}
+
+static const HChar *
+s390_irgen_LTXTR(UChar r1, UChar r2)
+{
+ IRTemp result = newTemp(Ity_D128);
+
+ assign(result, get_dpr_pair(r2));
+ put_dpr_pair(r1, mkexpr(result));
+ s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
+
+ return "ltxtr";
+}
+
+static const HChar *
s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
{
IRTemp op1 = newTemp(Ity_D64);
@@ -9149,6 +9369,28 @@
}
static const HChar *
+s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
+{
+ IRTemp op1 = newTemp(Ity_D128);
+ IRTemp op2 = newTemp(Ity_D128);
+ IRTemp result = newTemp(Ity_D128);
+ IRTemp rounding_mode;
+
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0 || s390_host_has_fpext);
+ /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
+ since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+ rounding_mode = encode_dfp_rounding_mode(m4);
+ assign(op1, get_dpr_pair(r2));
+ assign(op2, get_dpr_pair(r3));
+ assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
+ mkexpr(op2)));
+ put_dpr_pair(r1, mkexpr(result));
+
+ return (m4 == 0) ? "mxtr" : "mxtra";
+}
+
+static const HChar *
s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
{
IRTemp op1 = newTemp(Ity_D64);
@@ -9171,7 +9413,30 @@
return (m4 == 0) ? "sdtr" : "sdtra";
}
+static const HChar *
+s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
+{
+ IRTemp op1 = newTemp(Ity_D128);
+ IRTemp op2 = newTemp(Ity_D128);
+ IRTemp result = newTemp(Ity_D128);
+ IRTemp rounding_mode;
+ vassert(s390_host_has_dfp);
+ vassert(m4 == 0 || s390_host_has_fpext);
+ /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
+ since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+ rounding_mode = encode_dfp_rounding_mode(m4);
+ assign(op1, get_dpr_pair(r2));
+ assign(op2, get_dpr_pair(r3));
+ assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
+ mkexpr(op2)));
+ put_dpr_pair(r1, mkexpr(result));
+
+ s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
+
+ return (m4 == 0) ? "sxtr" : "sxtra";
+}
+
static const HChar *
s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
{
@@ -12721,6 +12986,13 @@
unsigned int r2 : 4;
} RRF4;
struct {
+ unsigned int op : 16;
+ unsigned int : 4;
+ unsigned int m4 : 4;
+ unsigned int r1 : 4;
+ unsigned int r2 : 4;
+ } RRF5;
+ struct {
unsigned int op : 8;
unsigned int r1 : 4;
unsigned int r3 : 4;
@@ -13196,31 +13468,48 @@
case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
ovl.fmt.RRF4.r2); goto ok;
- case 0xb3d4: /* LDETR */ goto unimplemented;
- case 0xb3d5: /* LEDTR */ goto unimplemented;
+ case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
+ ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
+ case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
+ ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+ ovl.fmt.RRF2.r2); goto ok;
case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
ovl.fmt.RRE.r2); goto ok;
case 0xb3d7: /* FIDTR */ goto unimplemented;
- case 0xb3d8: /* MXTR */ goto unimplemented;
- case 0xb3d9: /* DXTR */ goto unimplemented;
- case 0xb3da: /* AXTR */ goto unimplemented;
- case 0xb3db: /* SXTR */ goto unimplemented;
- case 0xb3dc: /* LXDTR */ goto unimplemented;
- case 0xb3dd: /* LDXTR */ goto unimplemented;
- case 0xb3de: /* LTXTR */ goto unimplemented;
+ case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
+ ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
+ ovl.fmt.RRF4.r2); goto ok;
+ case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
+ ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
+ ovl.fmt.RRF4.r2); goto ok;
+ case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
+ ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
+ ovl.fmt.RRF4.r2); goto ok;
+ case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
+ ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
+ ovl.fmt.RRF4.r2); goto ok;
+ case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
+ ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
+ case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
+ ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+ ovl.fmt.RRF2.r2); goto ok;
+ case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
+ ovl.fmt.RRE.r2); goto ok;
case 0xb3df: /* FIXTR */ goto unimplemented;
case 0xb3e0: /* KDTR */ goto unimplemented;
case 0xb3e1: /* CGDTR */ goto unimplemented;
case 0xb3e2: /* CUDTR */ goto unimplemented;
case 0xb3e3: /* CSDTR */ goto unimplemented;
- case 0xb3e4: /* CDTR */ goto unimplemented;
+ case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
+ ovl.fmt.RRE.r2); goto ok;
case 0xb3e5: /* EEDTR */ goto unimplemented;
case 0xb3e7: /* ESDTR */ goto unimplemented;
case 0xb3e8: /* KXTR */ goto unimplemented;
case 0xb3e9: /* CGXTR */ goto unimplemented;
case 0xb3ea: /* CUXTR */ goto unimplemented;
case 0xb3eb: /* CSXTR */ goto unimplemented;
- case 0xb3ec: /* CXTR */ goto unimplemented;
+ case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
+ ovl.fmt.RRE.r2); goto ok;
case 0xb3ed: /* EEXTR */ goto unimplemented;
case 0xb3ef: /* ESXTR */ goto unimplemented;
case 0xb3f1: /* CDGTR */ goto unimplemented;
Modified: trunk/priv/guest_s390_helpers.c (+15 -0)
===================================================================
--- trunk/priv/guest_s390_helpers.c 2012-12-21 04:40:28 +00:00 (rev 2604)
+++ trunk/priv/guest_s390_helpers.c 2012-12-21 17:32:12 +00:00 (rev 2605)
@@ -1165,7 +1165,19 @@
psw >> 28; /* cc */ \
})
+#define S390_CC_FOR_DFP128_RESULT(hi,lo) \
+({ \
+ __asm__ volatile ( \
+ "ldr 4,%[high]\n\t" \
+ "ldr 6,%[low]\n\t" \
+ ".insn rre, 0xb3de0000,0,4\n\t" /* LTXTR */ \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw) \
+ : [high] "f"(hi), [low] "f"(lo) \
+ : "cc", "f0", "f2", "f4", "f6"); \
+ psw >> 28; /* cc */ \
+})
+
/* Return the value of the condition code from the supplied thunk parameters.
This is not the value of the PSW. It is the value of the 2 CC bits within
the PSW. The returned value is thusly in the interval [0:3]. */
@@ -1384,6 +1396,9 @@
case S390_CC_OP_DFP_RESULT_64:
return S390_CC_FOR_DFP_RESULT(cc_dep1);
+ case S390_CC_OP_DFP_RESULT_128:
+ return S390_CC_FOR_DFP128_RESULT(cc_dep1, cc_dep2);
+
default:
break;
}
|