From 93504b89c41bc90a766486b13cad76ccef195bf2 Mon Sep 17 00:00:00 2001 From: Florian Krohm Date: Sat, 5 Sep 2015 20:39:27 +0000 Subject: [PATCH] Changes related to new IROp Iop_RoundF128toInt. See VEX r3183. s390: Add testcase for fixbr. Patch by Andreas Arnez . Part of fixing BZ #350290. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15629 --- NEWS | 1 + docs/internals/3_10_BUGSTATUS.txt | 2 - docs/internals/s390-opcodes.csv | 6 +-- memcheck/mc_translate.c | 4 ++ memcheck/tests/vbit-test/irops.c | 5 ++- memcheck/tests/vbit-test/util.c | 1 + none/tests/s390x/Makefile.am | 4 +- none/tests/s390x/fixbr.c | 73 +++++++++++++++++++++++++++++++ none/tests/s390x/fixbr.stderr.exp | 2 + none/tests/s390x/fixbr.stdout.exp | 36 +++++++++++++++ none/tests/s390x/fixbr.vgtest | 2 + 11 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 none/tests/s390x/fixbr.c create mode 100644 none/tests/s390x/fixbr.stderr.exp create mode 100644 none/tests/s390x/fixbr.stdout.exp create mode 100644 none/tests/s390x/fixbr.vgtest diff --git a/NEWS b/NEWS index d40bf317cd..f4dda77b8b 100644 --- a/NEWS +++ b/NEWS @@ -358,6 +358,7 @@ where XXXXXX is the bug number as listed below. 349941 di_notify_mmap might create wrong start/size DebugInfoMapping 350062 vex x86->IR: 0x66 0xF 0x3A 0xB (ROUNDSD) on OS X 350202 Add limited param to 'monitor block_list' +350290 s390x: Support instructions fixbr(a) 350809 Fix none/tests/async-sigs for Solaris 350811 Remove reference to --db-attach which has been removed. 350813 Memcheck/x86: enable handwritten assembly helpers for x86/Solaris too diff --git a/docs/internals/3_10_BUGSTATUS.txt b/docs/internals/3_10_BUGSTATUS.txt index f9fc9524c7..5f10c60f2d 100644 --- a/docs/internals/3_10_BUGSTATUS.txt +++ b/docs/internals/3_10_BUGSTATUS.txt @@ -73,8 +73,6 @@ go in here. === VEX/s390x ========================================================== -350290 s390x unsupported instruction fixbra - === VEX general ======================================================== === Syscalls/ioctls ==================================================== diff --git a/docs/internals/s390-opcodes.csv b/docs/internals/s390-opcodes.csv index 6c6ba0d43c..c0757eec1b 100644 --- a/docs/internals/s390-opcodes.csv +++ b/docs/internals/s390-opcodes.csv @@ -293,9 +293,9 @@ ltebr,"load and test short bfp",implemented, lcxbr,"load complement extended bfp",implemented, lcdbr,"load complement long bfp",implemented, lcebr,"load complement short bfp",implemented, -fixbr,"load fp integer extended bfp","not implemented", -fidbr,"load fp integer long bfp","implemented", -fiebr,"load fp integer short bfp","implemented", +fixbr,"load fp integer extended bfp",implemented, +fidbr,"load fp integer long bfp",implemented, +fiebr,"load fp integer short bfp",implemented, lfpc,"load fpc",implemented, lxdbr,"load lengthened long to extended bfp",implemented, lxdb,"load lengthened long to extended bfp",implemented, diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index d2ac7987bd..4358d2e8b4 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -3785,6 +3785,10 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce, /* I32(rm) x D128 -> D128 */ return mkLazy2(mce, Ity_I128, vatom1, vatom2); + case Iop_RoundF128toInt: + /* I32(rm) x F128 -> F128 */ + return mkLazy2(mce, Ity_I128, vatom1, vatom2); + case Iop_D64toI64S: case Iop_D64toI64U: case Iop_I64StoD64: diff --git a/memcheck/tests/vbit-test/irops.c b/memcheck/tests/vbit-test/irops.c index e35b3bfb32..d0e3b581f4 100644 --- a/memcheck/tests/vbit-test/irops.c +++ b/memcheck/tests/vbit-test/irops.c @@ -241,8 +241,9 @@ static irop_t irops[] = { { DEFOP(Iop_CosF64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, { DEFOP(Iop_TanF64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, { DEFOP(Iop_2xm1F64, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, - { DEFOP(Iop_RoundF64toInt, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, - { DEFOP(Iop_RoundF32toInt, UNDEF_ALL), .s390x = 0, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 }, + { DEFOP(Iop_RoundF128toInt, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 0, .tilegx = 0 }, + { DEFOP(Iop_RoundF64toInt, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, + { DEFOP(Iop_RoundF32toInt, UNDEF_ALL), .s390x = 1, .amd64 = 1, .x86 = 1, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 1, .mips64 = 1, .tilegx = 0 }, { DEFOP(Iop_MAddF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, { DEFOP(Iop_MSubF32, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 0, .ppc32 = 0, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, { DEFOP(Iop_MAddF64, UNDEF_ALL), .s390x = 1, .amd64 = 0, .x86 = 0, .arm = 0, .ppc64 = 1, .ppc32 = 1, .mips32 = 0, .mips64 = 1, .tilegx = 0 }, diff --git a/memcheck/tests/vbit-test/util.c b/memcheck/tests/vbit-test/util.c index 17ef972bcf..8553e58436 100644 --- a/memcheck/tests/vbit-test/util.c +++ b/memcheck/tests/vbit-test/util.c @@ -811,6 +811,7 @@ typeof_primop(IROp op, IRType *t_dst, IRType *t_arg1, IRType *t_arg2, UNARY(Ity_F128, Ity_F128); case Iop_SqrtF128: + case Iop_RoundF128toInt: BINARY(ity_RMode,Ity_F128, Ity_F128); case Iop_I32StoF128: UNARY(Ity_I32, Ity_F128); diff --git a/none/tests/s390x/Makefile.am b/none/tests/s390x/Makefile.am index f4fede1fa2..6545117e32 100644 --- a/none/tests/s390x/Makefile.am +++ b/none/tests/s390x/Makefile.am @@ -22,7 +22,7 @@ if BUILD_DFP_TESTS INSN_TESTS += dfp-1 dfp-2 dfp-3 dfp-4 dfptest dfpext dfpconv srnmt pfpo endif if HAS_MLONG_DOUBLE_128 - INSN_TESTS += fpext + INSN_TESTS += fpext fixbr endif check_PROGRAMS = $(INSN_TESTS) \ @@ -36,6 +36,7 @@ EXTRA_DIST = \ ecag.stdout.exp-z10ec ecag.stdout.exp-z196 ecag.stdout.exp-zec12 \ ecag.stdout.exp-z13 \ op00.stderr.exp1 op00.stderr.exp2 op00.vgtest \ + fixbr.vgtest fixbr.stderr.exp fixbr.stdout.exp \ fpext.vgtest fpext.stderr.exp fpext.stdout.exp \ fpext_fail.vgtest fpext_fail.stderr.exp fpext_fail.stdout.exp \ test.h opcodes.h add.h and.h div.h insert.h dfp_utils.h \ @@ -60,5 +61,6 @@ cu12_1_CFLAGS = $(AM_CFLAGS) -DM3=1 cu14_1_CFLAGS = $(AM_CFLAGS) -DM3=1 cu21_1_CFLAGS = $(AM_CFLAGS) -DM3=1 cu24_1_CFLAGS = $(AM_CFLAGS) -DM3=1 +fixbr_CFLAGS = $(AM_CFLAGS) @FLAG_MLONG_DOUBLE_128@ fpext_CFLAGS = $(AM_CFLAGS) @FLAG_MLONG_DOUBLE_128@ ex_clone_LDFLAGS = -lpthread diff --git a/none/tests/s390x/fixbr.c b/none/tests/s390x/fixbr.c new file mode 100644 index 0000000000..ba99210b5e --- /dev/null +++ b/none/tests/s390x/fixbr.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include "opcodes.h" +#include "rounding.h" + +/* Test "fixbr" with rounding mode given in insn (m3 field) + Covers all generally available rounding modes that can be mapped to + IRRoundingMode. As a consequence m3=1 which is "round to nearest with + ties away from 0" is not tested here. +*/ + +const char * +rtext(unsigned m3_round) +{ + switch (m3_round) { + case 0: return "[-> per fpc]"; + case 1: return "[-> nearest away]"; + case 3: return "[-> prepare short]"; // floating point extension fac needed + case 4: return "[-> nearest even]"; + case 5: return "[-> 0]"; + case 6: return "[-> +inf]"; + case 7: return "[-> -inf]"; + } + assert(0); +} + +#define round_to_int(value,round) \ +do { \ + long double src = value; \ + long double dst; \ + \ + __asm__ volatile ("fixbr %[dst]," #round ",%[src]\n\t" \ + : [dst] "=f"(dst) \ + : [src] "f"(src)); \ + \ + printf("fixbr %.5Lf\t-> %Lg %s\n", \ + src, dst, rtext(round)); \ +} while (0) + +#define fixbr(value,round) round_to_int(value,round) + +void +set_rounding_mode(unsigned mode) +{ + register unsigned r asm("1") = mode; + __asm__ volatile ( SFPC(1) : : "d"(r) ); +} + + +int main(void) +{ + int j; + static const long double dval[] = { + 1.25, 1.5, 2.5, 1.75, -1.25, -1.5, -2.5, -1.75, 0.0, + }; + + assert(sizeof(long double) == 16); + + /* f128 -> f128, round to int */ + for (j = 0; j < sizeof dval / sizeof dval[0]; ++j) { + set_rounding_mode(FPC_BFP_ROUND_ZERO); + fixbr(dval[j], M3_BFP_ROUND_NEAREST_EVEN); + set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN); + fixbr(dval[j], M3_BFP_ROUND_ZERO); + fixbr(dval[j], M3_BFP_ROUND_POSINF); + fixbr(dval[j], M3_BFP_ROUND_NEGINF); + } + + return 0; +} diff --git a/none/tests/s390x/fixbr.stderr.exp b/none/tests/s390x/fixbr.stderr.exp new file mode 100644 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/s390x/fixbr.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/s390x/fixbr.stdout.exp b/none/tests/s390x/fixbr.stdout.exp new file mode 100644 index 0000000000..787c0d8d27 --- /dev/null +++ b/none/tests/s390x/fixbr.stdout.exp @@ -0,0 +1,36 @@ +fixbr 1.25000 -> 1 [-> nearest even] +fixbr 1.25000 -> 1 [-> 0] +fixbr 1.25000 -> 2 [-> +inf] +fixbr 1.25000 -> 1 [-> -inf] +fixbr 1.50000 -> 2 [-> nearest even] +fixbr 1.50000 -> 1 [-> 0] +fixbr 1.50000 -> 2 [-> +inf] +fixbr 1.50000 -> 1 [-> -inf] +fixbr 2.50000 -> 2 [-> nearest even] +fixbr 2.50000 -> 2 [-> 0] +fixbr 2.50000 -> 3 [-> +inf] +fixbr 2.50000 -> 2 [-> -inf] +fixbr 1.75000 -> 2 [-> nearest even] +fixbr 1.75000 -> 1 [-> 0] +fixbr 1.75000 -> 2 [-> +inf] +fixbr 1.75000 -> 1 [-> -inf] +fixbr -1.25000 -> -1 [-> nearest even] +fixbr -1.25000 -> -1 [-> 0] +fixbr -1.25000 -> -1 [-> +inf] +fixbr -1.25000 -> -2 [-> -inf] +fixbr -1.50000 -> -2 [-> nearest even] +fixbr -1.50000 -> -1 [-> 0] +fixbr -1.50000 -> -1 [-> +inf] +fixbr -1.50000 -> -2 [-> -inf] +fixbr -2.50000 -> -2 [-> nearest even] +fixbr -2.50000 -> -2 [-> 0] +fixbr -2.50000 -> -2 [-> +inf] +fixbr -2.50000 -> -3 [-> -inf] +fixbr -1.75000 -> -2 [-> nearest even] +fixbr -1.75000 -> -1 [-> 0] +fixbr -1.75000 -> -1 [-> +inf] +fixbr -1.75000 -> -2 [-> -inf] +fixbr 0.00000 -> 0 [-> nearest even] +fixbr 0.00000 -> 0 [-> 0] +fixbr 0.00000 -> 0 [-> +inf] +fixbr 0.00000 -> 0 [-> -inf] diff --git a/none/tests/s390x/fixbr.vgtest b/none/tests/s390x/fixbr.vgtest new file mode 100644 index 0000000000..22eb7afab4 --- /dev/null +++ b/none/tests/s390x/fixbr.vgtest @@ -0,0 +1,2 @@ +prog: fixbr +prereq: test -e fixbr && ../../../tests/s390x_features s390x-fpext -- 2.47.2