s390x: Testcases for floating point 32/64-bit. Related to VEX r2525.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12966 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/none/tests/s390x/Makefile.am b/none/tests/s390x/Makefile.am
index da22c4b..f03c58c 100644
--- a/none/tests/s390x/Makefile.am
+++ b/none/tests/s390x/Makefile.am
@@ -9,7 +9,7 @@
trto trot trtt tr tre cij cgij clij clgij crj cgrj clrj clgrj \
cs csg cds cdsg cu21 cu21_1 cu24 cu24_1 cu42 cu12 cu12_1 \
ex_sig ex_clone cu14 cu14_1 cu41 fpconv ecag fpext fpext_warn \
- rounding-1
+ rounding-1 rounding-2 rounding-3 rounding-4 rounding-5 bfp-1
check_PROGRAMS = $(INSN_TESTS) \
allexec \
diff --git a/none/tests/s390x/bfp-1.c b/none/tests/s390x/bfp-1.c
new file mode 100644
index 0000000..2cf558e
--- /dev/null
+++ b/none/tests/s390x/bfp-1.c
@@ -0,0 +1,93 @@
+#include <stdio.h>
+
+/* Simple test to see that basic operators are mapped
+ correctly. Uses default rounding mode. */
+
+volatile double d1, d2;
+volatile float f1, f2;
+
+void fadd8(void)
+{
+ printf("%f + %f = %f\n", d1, d2, d1 + d2);
+}
+
+void fsub8(void)
+{
+ printf("%f - %f = %f\n", d1, d2, d1 - d2);
+}
+
+void fmul8(void)
+{
+ printf("%f * %f = %f\n", d1, d2, d1 * d2);
+}
+
+void fdiv8(void)
+{
+ printf("%f / %f = %f\n", d1, d2, d1 / d2);
+}
+
+void fadd4(void)
+{
+ register float r1 asm("f1") = f1;
+ register float r2 asm("f2") = f2;
+
+ __asm__ volatile ("aebr %[r1],%[r2]\n\t"
+ : [r1] "+f"(r1)
+ : [r2] "f"(r2) : "cc");
+ printf("%f + %f = %f\n", f1, f2, r1);
+}
+
+void fsub4(void)
+{
+ register float r1 asm("f1") = f1;
+ register float r2 asm("f2") = f2;
+
+ __asm__ volatile ("sebr %[r1],%[r2]\n\t"
+ : [r1] "+f"(r1)
+ : [r2] "f"(r2) : "cc");
+ printf("%f - %f = %f\n", f1, f2, r1);
+}
+
+void fmul4(void)
+{
+ register float r1 asm("f1") = f1;
+ register float r2 asm("f2") = f2;
+
+ __asm__ volatile ("meebr %[r1],%[r2]\n\t"
+ : [r1] "+f"(r1)
+ : [r2] "f"(r2) : "cc");
+ printf("%f * %f = %f\n", f1, f2, r1);
+}
+
+void fdiv4(void)
+{
+ register float r1 asm("f1") = f1;
+ register float r2 asm("f2") = f2;
+
+ __asm__ volatile ("debr %[r1],%[r2]\n\t"
+ : [r1] "+f"(r1)
+ : [r2] "f"(r2) : "cc");
+ printf("%f / %f = %f\n", f1, f2, r1);
+}
+
+
+int main()
+{
+ printf("double arithmetic\n");
+ d1 = 10.5;
+ d2 = 1.25;
+ fadd8();
+ fsub8();
+ fmul8();
+ fdiv8();
+
+ printf("float arithmetic\n");
+ f1 = 10.5f;
+ f2 = 1.25f;
+ fadd4();
+ fsub4();
+ fmul4();
+ fdiv4();
+
+ return 0;
+}
diff --git a/none/tests/s390x/bfp-1.stderr.exp b/none/tests/s390x/bfp-1.stderr.exp
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/none/tests/s390x/bfp-1.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/bfp-1.stdout.exp b/none/tests/s390x/bfp-1.stdout.exp
new file mode 100644
index 0000000..023c598
--- /dev/null
+++ b/none/tests/s390x/bfp-1.stdout.exp
@@ -0,0 +1,10 @@
+double arithmetic
+10.500000 + 1.250000 = 11.750000
+10.500000 - 1.250000 = 9.250000
+10.500000 * 1.250000 = 13.125000
+10.500000 / 1.250000 = 8.400000
+float arithmetic
+10.500000 + 1.250000 = 11.750000
+10.500000 - 1.250000 = 9.250000
+10.500000 * 1.250000 = 13.125000
+10.500000 / 1.250000 = 8.400000
diff --git a/none/tests/s390x/bfp-1.vgtest b/none/tests/s390x/bfp-1.vgtest
new file mode 100644
index 0000000..9d67c4a
--- /dev/null
+++ b/none/tests/s390x/bfp-1.vgtest
@@ -0,0 +1 @@
+prog: bfp-1
diff --git a/none/tests/s390x/opcodes.h b/none/tests/s390x/opcodes.h
index 8dd6097..1d0daaf 100644
--- a/none/tests/s390x/opcodes.h
+++ b/none/tests/s390x/opcodes.h
@@ -52,6 +52,7 @@
".long 0x" #i4 #m3 #u0 #op2 "\n\t"
#define RRE_RR(op,u0,r1,r2) ".long 0x" #op #u0 #r1 #r2 "\n\t"
#define RRE_RERE(op,r1,r2) ".long 0x" #op "00" #r1 #r2 "\n\t"
+#define RRE_R0(op,r1) ".long 0x" #op "00" #r1 "0" "\n\t"
#define SIL_RDU(op,b1,d1,i2) \
".short 0x" #op "\n\t" \
".long 0x" #b1 #d1 #i2 "\n\t"
@@ -299,6 +300,7 @@
#define RNSBG(r1,r2,i3,i4,i5) RIE_RRUUU(ec,r1,r2,i3,i4,i5,54)
#define ROSBG(r1,r2,i3,i4,i5) RIE_RRUUU(ec,r1,r2,i3,i4,i5,56)
#define RXSBG(r1,r2,i3,i4,i5) RIE_RRUUU(ec,r1,r2,i3,i4,i5,57)
+#define SFPC(r1) RRE_R0(b384,r1)
#define SGRK(r3,r1,r2) RRF_R0RR2(b9e9,r3,0,r1,r2)
#define SHHHR(r3,r1,r2) RRF_R0RR2(b9c9,r3,0,r1,r2)
#define SHHLR(r3,r1,r2) RRF_R0RR2(b9d9,r3,0,r1,r2)
diff --git a/none/tests/s390x/rounding-2.c b/none/tests/s390x/rounding-2.c
new file mode 100644
index 0000000..ecc5a19
--- /dev/null
+++ b/none/tests/s390x/rounding-2.c
@@ -0,0 +1,41 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "opcodes.h"
+
+/* Basic test that we can set the rounding mode in the FPC and
+ query it. Covers only generally available rounding modes. */
+
+void
+set_rounding_mode(unsigned mode)
+{
+ register unsigned r asm("1") = mode;
+ __asm__ volatile ( SFPC(1) : : "d"(r) );
+}
+
+unsigned
+get_rounding_mode(void)
+{
+ unsigned fpc;
+
+ __asm__ volatile ("stfpc %0\n\t" : "=m"(fpc));
+
+ return fpc & 0x7;
+}
+
+
+int main(void)
+{
+ int i;
+ const unsigned rmodes[] = { 0, 1, 2, 3 };
+
+ printf("initial rounding mode: %u\n", get_rounding_mode());
+
+ for (i = 0; i < sizeof rmodes / sizeof rmodes[0]; ++i) {
+ printf("setting rounding mode to %u\n", rmodes[i]);
+ set_rounding_mode(rmodes[i]);
+ printf("...checking: %u\n", get_rounding_mode());
+ }
+
+ return 0;
+}
diff --git a/none/tests/s390x/rounding-2.stderr.exp b/none/tests/s390x/rounding-2.stderr.exp
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/none/tests/s390x/rounding-2.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/rounding-2.stdout.exp b/none/tests/s390x/rounding-2.stdout.exp
new file mode 100644
index 0000000..e0da369
--- /dev/null
+++ b/none/tests/s390x/rounding-2.stdout.exp
@@ -0,0 +1,9 @@
+initial rounding mode: 0
+setting rounding mode to 0
+...checking: 0
+setting rounding mode to 1
+...checking: 1
+setting rounding mode to 2
+...checking: 2
+setting rounding mode to 3
+...checking: 3
diff --git a/none/tests/s390x/rounding-2.vgtest b/none/tests/s390x/rounding-2.vgtest
new file mode 100644
index 0000000..c6e067d
--- /dev/null
+++ b/none/tests/s390x/rounding-2.vgtest
@@ -0,0 +1 @@
+prog: rounding-2
diff --git a/none/tests/s390x/rounding-3.c b/none/tests/s390x/rounding-3.c
new file mode 100644
index 0000000..4c12f9c
--- /dev/null
+++ b/none/tests/s390x/rounding-3.c
@@ -0,0 +1,116 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include "opcodes.h"
+
+/* Test "convert to fixed" with "per fpc" rounding.
+ Covers all generally available rounding modes.
+
+ Note, that "convert to fixed" with rounding mode specified as
+ part of the insn is already tested in fpconv.c
+*/
+
+void
+set_rounding_mode(unsigned mode)
+{
+ register unsigned r asm("1") = mode;
+ __asm__ volatile ( SFPC(1) : : "d"(r) );
+}
+
+unsigned
+get_rounding_mode(void)
+{
+ unsigned fpc;
+
+ __asm__ volatile ("stfpc %0\n\t" : "=m"(fpc));
+
+ return fpc & 0x7;
+}
+
+
+const char *
+rtext(unsigned fpc_round)
+{
+ switch (fpc_round) {
+ case 0: return "[-> near]";
+ case 1: return "[-> zero]";
+ case 2: return "[-> +inf]";
+ case 3: return "[-> -inf]";
+ }
+ assert(0);
+}
+
+#define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \
+do { \
+ src_type src = value; \
+ dst_type dst; \
+ unsigned cc; \
+ \
+ __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \
+ "ipm %[cc]\n\t" \
+ "srl %[cc],28\n\t" \
+ : [dst] "=d"(dst), [cc] "=d"(cc) \
+ : [src] "f"(src) \
+ : "cc"); \
+ \
+ printf("%s %f\t-> %"dst_fmt"\tcc = %u\n", \
+ opcode, src, dst, cc); \
+} while (0)
+
+
+#define cfebr(value) \
+ convert_to_int("cfebr",float,int32_t,PRId32,0,value)
+#define cfdbr(value) \
+ convert_to_int("cfdbr",double,int32_t,PRId32,0,value)
+#define cgebr(value) \
+ convert_to_int("cgebr",float,int64_t,PRId64,0,value)
+#define cgdbr(value) \
+ convert_to_int("cgdbr",double,int64_t,PRId64,0,value)
+
+int main(void)
+{
+ int i, j;
+ static const unsigned rmodes[] = { 0, 1, 2, 3 };
+ static const float fval[] = {
+ 1.4f, 1.5f, 2.5f, 1.6f, -1.4f, -1.5f, -2.5f, -1.6f, 0.0f,
+ };
+ static const double dval[] = {
+ 1.4, 1.5, 2.5, 1.6, -1.4, -1.5, -2.5, -1.6, 0.0,
+ };
+
+
+ for (i = 0; i < sizeof rmodes / sizeof rmodes[0]; ++i) {
+ printf("setting rounding mode to %s\n", rtext(rmodes[i]));
+ set_rounding_mode(rmodes[i]);
+ assert(get_rounding_mode() == rmodes[i]);
+
+ /* f32 -> i32 */
+ for (j = 0; j < sizeof fval / sizeof fval[0]; ++j) {
+ cfebr(fval[j]);
+ assert(get_rounding_mode() == rmodes[i]);
+ }
+
+ /* f32 -> i64 */
+ for (j = 0; j < sizeof fval / sizeof fval[0]; ++j) {
+ cgebr(fval[j]);
+ assert(get_rounding_mode() == rmodes[i]);
+ }
+
+ /* f64 -> i32 */
+ for (j = 0; j < sizeof dval / sizeof dval[0]; ++j) {
+ cfdbr(dval[j]);
+ assert(get_rounding_mode() == rmodes[i]);
+ }
+
+ /* f64 -> i64 */
+ for (j = 0; j < sizeof dval / sizeof dval[0]; ++j) {
+ cgdbr(dval[j]);
+ assert(get_rounding_mode() == rmodes[i]);
+ }
+
+ }
+
+ return 0;
+}
diff --git a/none/tests/s390x/rounding-3.stderr.exp b/none/tests/s390x/rounding-3.stderr.exp
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/none/tests/s390x/rounding-3.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/rounding-3.stdout.exp b/none/tests/s390x/rounding-3.stdout.exp
new file mode 100644
index 0000000..5b08525
--- /dev/null
+++ b/none/tests/s390x/rounding-3.stdout.exp
@@ -0,0 +1,148 @@
+setting rounding mode to [-> near]
+cfebr 1.400000 -> 1 cc = 2
+cfebr 1.500000 -> 2 cc = 2
+cfebr 2.500000 -> 2 cc = 2
+cfebr 1.600000 -> 2 cc = 2
+cfebr -1.400000 -> -1 cc = 1
+cfebr -1.500000 -> -2 cc = 1
+cfebr -2.500000 -> -2 cc = 1
+cfebr -1.600000 -> -2 cc = 1
+cfebr 0.000000 -> 0 cc = 0
+cgebr 1.400000 -> 1 cc = 2
+cgebr 1.500000 -> 2 cc = 2
+cgebr 2.500000 -> 2 cc = 2
+cgebr 1.600000 -> 2 cc = 2
+cgebr -1.400000 -> -1 cc = 1
+cgebr -1.500000 -> -2 cc = 1
+cgebr -2.500000 -> -2 cc = 1
+cgebr -1.600000 -> -2 cc = 1
+cgebr 0.000000 -> 0 cc = 0
+cfdbr 1.400000 -> 1 cc = 2
+cfdbr 1.500000 -> 2 cc = 2
+cfdbr 2.500000 -> 2 cc = 2
+cfdbr 1.600000 -> 2 cc = 2
+cfdbr -1.400000 -> -1 cc = 1
+cfdbr -1.500000 -> -2 cc = 1
+cfdbr -2.500000 -> -2 cc = 1
+cfdbr -1.600000 -> -2 cc = 1
+cfdbr 0.000000 -> 0 cc = 0
+cgdbr 1.400000 -> 1 cc = 2
+cgdbr 1.500000 -> 2 cc = 2
+cgdbr 2.500000 -> 2 cc = 2
+cgdbr 1.600000 -> 2 cc = 2
+cgdbr -1.400000 -> -1 cc = 1
+cgdbr -1.500000 -> -2 cc = 1
+cgdbr -2.500000 -> -2 cc = 1
+cgdbr -1.600000 -> -2 cc = 1
+cgdbr 0.000000 -> 0 cc = 0
+setting rounding mode to [-> zero]
+cfebr 1.400000 -> 1 cc = 2
+cfebr 1.500000 -> 1 cc = 2
+cfebr 2.500000 -> 2 cc = 2
+cfebr 1.600000 -> 1 cc = 2
+cfebr -1.400000 -> -1 cc = 1
+cfebr -1.500000 -> -1 cc = 1
+cfebr -2.500000 -> -2 cc = 1
+cfebr -1.600000 -> -1 cc = 1
+cfebr 0.000000 -> 0 cc = 0
+cgebr 1.400000 -> 1 cc = 2
+cgebr 1.500000 -> 1 cc = 2
+cgebr 2.500000 -> 2 cc = 2
+cgebr 1.600000 -> 1 cc = 2
+cgebr -1.400000 -> -1 cc = 1
+cgebr -1.500000 -> -1 cc = 1
+cgebr -2.500000 -> -2 cc = 1
+cgebr -1.600000 -> -1 cc = 1
+cgebr 0.000000 -> 0 cc = 0
+cfdbr 1.400000 -> 1 cc = 2
+cfdbr 1.500000 -> 1 cc = 2
+cfdbr 2.500000 -> 2 cc = 2
+cfdbr 1.600000 -> 1 cc = 2
+cfdbr -1.400000 -> -1 cc = 1
+cfdbr -1.500000 -> -1 cc = 1
+cfdbr -2.500000 -> -2 cc = 1
+cfdbr -1.600000 -> -1 cc = 1
+cfdbr 0.000000 -> 0 cc = 0
+cgdbr 1.400000 -> 1 cc = 2
+cgdbr 1.500000 -> 1 cc = 2
+cgdbr 2.500000 -> 2 cc = 2
+cgdbr 1.600000 -> 1 cc = 2
+cgdbr -1.400000 -> -1 cc = 1
+cgdbr -1.500000 -> -1 cc = 1
+cgdbr -2.500000 -> -2 cc = 1
+cgdbr -1.600000 -> -1 cc = 1
+cgdbr 0.000000 -> 0 cc = 0
+setting rounding mode to [-> +inf]
+cfebr 1.400000 -> 2 cc = 2
+cfebr 1.500000 -> 2 cc = 2
+cfebr 2.500000 -> 3 cc = 2
+cfebr 1.600000 -> 2 cc = 2
+cfebr -1.400000 -> -1 cc = 1
+cfebr -1.500000 -> -1 cc = 1
+cfebr -2.500000 -> -2 cc = 1
+cfebr -1.600000 -> -1 cc = 1
+cfebr 0.000000 -> 0 cc = 0
+cgebr 1.400000 -> 2 cc = 2
+cgebr 1.500000 -> 2 cc = 2
+cgebr 2.500000 -> 3 cc = 2
+cgebr 1.600000 -> 2 cc = 2
+cgebr -1.400000 -> -1 cc = 1
+cgebr -1.500000 -> -1 cc = 1
+cgebr -2.500000 -> -2 cc = 1
+cgebr -1.600000 -> -1 cc = 1
+cgebr 0.000000 -> 0 cc = 0
+cfdbr 1.400000 -> 2 cc = 2
+cfdbr 1.500000 -> 2 cc = 2
+cfdbr 2.500000 -> 3 cc = 2
+cfdbr 1.600000 -> 2 cc = 2
+cfdbr -1.400000 -> -1 cc = 1
+cfdbr -1.500000 -> -1 cc = 1
+cfdbr -2.500000 -> -2 cc = 1
+cfdbr -1.600000 -> -1 cc = 1
+cfdbr 0.000000 -> 0 cc = 0
+cgdbr 1.400000 -> 2 cc = 2
+cgdbr 1.500000 -> 2 cc = 2
+cgdbr 2.500000 -> 3 cc = 2
+cgdbr 1.600000 -> 2 cc = 2
+cgdbr -1.400000 -> -1 cc = 1
+cgdbr -1.500000 -> -1 cc = 1
+cgdbr -2.500000 -> -2 cc = 1
+cgdbr -1.600000 -> -1 cc = 1
+cgdbr 0.000000 -> 0 cc = 0
+setting rounding mode to [-> -inf]
+cfebr 1.400000 -> 1 cc = 2
+cfebr 1.500000 -> 1 cc = 2
+cfebr 2.500000 -> 2 cc = 2
+cfebr 1.600000 -> 1 cc = 2
+cfebr -1.400000 -> -2 cc = 1
+cfebr -1.500000 -> -2 cc = 1
+cfebr -2.500000 -> -3 cc = 1
+cfebr -1.600000 -> -2 cc = 1
+cfebr 0.000000 -> 0 cc = 0
+cgebr 1.400000 -> 1 cc = 2
+cgebr 1.500000 -> 1 cc = 2
+cgebr 2.500000 -> 2 cc = 2
+cgebr 1.600000 -> 1 cc = 2
+cgebr -1.400000 -> -2 cc = 1
+cgebr -1.500000 -> -2 cc = 1
+cgebr -2.500000 -> -3 cc = 1
+cgebr -1.600000 -> -2 cc = 1
+cgebr 0.000000 -> 0 cc = 0
+cfdbr 1.400000 -> 1 cc = 2
+cfdbr 1.500000 -> 1 cc = 2
+cfdbr 2.500000 -> 2 cc = 2
+cfdbr 1.600000 -> 1 cc = 2
+cfdbr -1.400000 -> -2 cc = 1
+cfdbr -1.500000 -> -2 cc = 1
+cfdbr -2.500000 -> -3 cc = 1
+cfdbr -1.600000 -> -2 cc = 1
+cfdbr 0.000000 -> 0 cc = 0
+cgdbr 1.400000 -> 1 cc = 2
+cgdbr 1.500000 -> 1 cc = 2
+cgdbr 2.500000 -> 2 cc = 2
+cgdbr 1.600000 -> 1 cc = 2
+cgdbr -1.400000 -> -2 cc = 1
+cgdbr -1.500000 -> -2 cc = 1
+cgdbr -2.500000 -> -3 cc = 1
+cgdbr -1.600000 -> -2 cc = 1
+cgdbr 0.000000 -> 0 cc = 0
diff --git a/none/tests/s390x/rounding-3.vgtest b/none/tests/s390x/rounding-3.vgtest
new file mode 100644
index 0000000..8168710
--- /dev/null
+++ b/none/tests/s390x/rounding-3.vgtest
@@ -0,0 +1 @@
+prog: rounding-3
diff --git a/none/tests/s390x/rounding-4.c b/none/tests/s390x/rounding-4.c
new file mode 100644
index 0000000..e0a3cb3
--- /dev/null
+++ b/none/tests/s390x/rounding-4.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <assert.h>
+#include "opcodes.h"
+
+/* Test "load rounded" with universally available rounding modes.
+ Rounding mode is provided via FPC.
+ Also test "load lengthened" (which is independent of rounding modes). */
+
+volatile double d;
+volatile float f;
+
+const char *
+rtext(unsigned fpc_round)
+{
+ switch (fpc_round) {
+ case 0: return "[-> near]";
+ case 1: return "[-> zero]";
+ case 2: return "[-> +inf]";
+ case 3: return "[-> -inf]";
+ }
+ assert(0);
+}
+
+void
+set_rounding_mode(unsigned mode)
+{
+ printf("setting FPC rounding mode to %s\n", rtext(mode));
+ register unsigned r asm("1") = mode;
+ __asm__ volatile ( SFPC(1) : : "d"(r) );
+}
+
+
+void
+load_rounded(void)
+{
+ f = d;
+ printf("load rounded d = %22.20g f = %22.20g\n", d, f);
+}
+
+void
+load_lengthened(void)
+{
+ d = f;
+ printf("load lengthened d = %22.20g f = %22.20g\n", d, f);
+}
+
+/* Tests for load rounded and load lengthened */
+int main()
+{
+ d = 12345678.98765432E21;
+ set_rounding_mode(0);
+ load_rounded();
+ set_rounding_mode(1);
+ load_rounded();
+ set_rounding_mode(2);
+ load_rounded();
+ set_rounding_mode(3);
+ load_rounded();
+ printf("\n");
+
+ d = -12345678.98765432E21;
+ set_rounding_mode(0);
+ load_rounded();
+ set_rounding_mode(1);
+ load_rounded();
+ set_rounding_mode(2);
+ load_rounded();
+ set_rounding_mode(3);
+ load_rounded();
+ printf("\n");
+
+ load_lengthened();
+
+ return 0;
+}
diff --git a/none/tests/s390x/rounding-4.stderr.exp b/none/tests/s390x/rounding-4.stderr.exp
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/none/tests/s390x/rounding-4.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/rounding-4.stdout.exp b/none/tests/s390x/rounding-4.stdout.exp
new file mode 100644
index 0000000..a1e5d6e
--- /dev/null
+++ b/none/tests/s390x/rounding-4.stdout.exp
@@ -0,0 +1,19 @@
+setting FPC rounding mode to [-> near]
+load rounded d = 1.2345678987654319598e+28 f = 1.234567915439125133e+28
+setting FPC rounding mode to [-> zero]
+load rounded d = 1.2345678987654319598e+28 f = 1.2345677973799630613e+28
+setting FPC rounding mode to [-> +inf]
+load rounded d = 1.2345678987654319598e+28 f = 1.234567915439125133e+28
+setting FPC rounding mode to [-> -inf]
+load rounded d = 1.2345678987654319598e+28 f = 1.2345677973799630613e+28
+
+setting FPC rounding mode to [-> near]
+load rounded d = -1.2345678987654319598e+28 f = -1.234567915439125133e+28
+setting FPC rounding mode to [-> zero]
+load rounded d = -1.2345678987654319598e+28 f = -1.2345677973799630613e+28
+setting FPC rounding mode to [-> +inf]
+load rounded d = -1.2345678987654319598e+28 f = -1.2345677973799630613e+28
+setting FPC rounding mode to [-> -inf]
+load rounded d = -1.2345678987654319598e+28 f = -1.234567915439125133e+28
+
+load lengthened d = -1.234567915439125133e+28 f = -1.234567915439125133e+28
diff --git a/none/tests/s390x/rounding-4.vgtest b/none/tests/s390x/rounding-4.vgtest
new file mode 100644
index 0000000..e264b57
--- /dev/null
+++ b/none/tests/s390x/rounding-4.vgtest
@@ -0,0 +1 @@
+prog: rounding-4
diff --git a/none/tests/s390x/rounding-5.c b/none/tests/s390x/rounding-5.c
new file mode 100644
index 0000000..e1eab40
--- /dev/null
+++ b/none/tests/s390x/rounding-5.c
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <assert.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include "opcodes.h"
+
+/* Test "convert from fixed" with universally available rounding modes.
+ Rounding mode is provided via FPC. */
+
+volatile int32_t i32;
+volatile int64_t i64;
+
+const char *
+rtext(unsigned fpc_round)
+{
+ switch (fpc_round) {
+ case 0: return "[-> near]";
+ case 1: return "[-> zero]";
+ case 2: return "[-> +inf]";
+ case 3: return "[-> -inf]";
+ }
+ assert(0);
+}
+
+void
+set_rounding_mode(unsigned mode)
+{
+ printf("setting FPC rounding mode to %s\n", rtext(mode));
+ register unsigned r asm("1") = mode;
+ __asm__ volatile ( SFPC(1) : : "d"(r) );
+}
+
+void cefbr(unsigned mode)
+{
+ set_rounding_mode(mode);
+
+ float out;
+
+ __asm__ volatile("cefbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i32));
+ printf("cefbr: %"PRId32" -> %f\n", i32, out);
+}
+
+void cegbr(unsigned mode)
+{
+ set_rounding_mode(mode);
+
+ float out;
+
+ __asm__ volatile("cegbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
+ printf("cegbr: %"PRId64" -> %f\n", i64, out);
+}
+
+void cdgbr(unsigned mode)
+{
+ set_rounding_mode(mode);
+
+ double out;
+
+ __asm__ volatile("cdgbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
+ printf("cegbr: %"PRId64" -> %f\n", i64, out);
+}
+
+
+int main()
+{
+ int mode;
+
+ /* i32 -> f32 */
+ i32 = INT32_MAX;
+ for (mode = 0; mode <= 3; ++mode) cefbr(mode);
+ printf("\n");
+ i32 = INT32_MIN;
+ for (mode = 0; mode <= 3; ++mode) cefbr(mode);
+ printf("\n");
+
+ /* i64 -> f32 */
+ i64 = INT64_MAX;
+ for (mode = 0; mode <= 3; ++mode) cegbr(mode);
+ printf("\n");
+ i64 = INT64_MIN;
+ for (mode = 0; mode <= 3; ++mode) cegbr(mode);
+ printf("\n");
+
+ /* i64 -> f64 */
+ i64 = INT64_MAX;
+ for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
+ printf("\n");
+ i64 = INT64_MIN;
+ for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
+ printf("\n");
+
+ return 0;
+}
diff --git a/none/tests/s390x/rounding-5.stderr.exp b/none/tests/s390x/rounding-5.stderr.exp
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/none/tests/s390x/rounding-5.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/rounding-5.stdout.exp b/none/tests/s390x/rounding-5.stdout.exp
new file mode 100644
index 0000000..80e55f6
--- /dev/null
+++ b/none/tests/s390x/rounding-5.stdout.exp
@@ -0,0 +1,54 @@
+setting FPC rounding mode to [-> near]
+cefbr: 2147483647 -> 2147483648.000000
+setting FPC rounding mode to [-> zero]
+cefbr: 2147483647 -> 2147483520.000000
+setting FPC rounding mode to [-> +inf]
+cefbr: 2147483647 -> 2147483648.000000
+setting FPC rounding mode to [-> -inf]
+cefbr: 2147483647 -> 2147483520.000000
+
+setting FPC rounding mode to [-> near]
+cefbr: -2147483648 -> -2147483648.000000
+setting FPC rounding mode to [-> zero]
+cefbr: -2147483648 -> -2147483648.000000
+setting FPC rounding mode to [-> +inf]
+cefbr: -2147483648 -> -2147483648.000000
+setting FPC rounding mode to [-> -inf]
+cefbr: -2147483648 -> -2147483648.000000
+
+setting FPC rounding mode to [-> near]
+cegbr: 9223372036854775807 -> 9223372036854775808.000000
+setting FPC rounding mode to [-> zero]
+cegbr: 9223372036854775807 -> 9223371487098961920.000000
+setting FPC rounding mode to [-> +inf]
+cegbr: 9223372036854775807 -> 9223372036854775808.000000
+setting FPC rounding mode to [-> -inf]
+cegbr: 9223372036854775807 -> 9223371487098961920.000000
+
+setting FPC rounding mode to [-> near]
+cegbr: -9223372036854775808 -> -9223372036854775808.000000
+setting FPC rounding mode to [-> zero]
+cegbr: -9223372036854775808 -> -9223372036854775808.000000
+setting FPC rounding mode to [-> +inf]
+cegbr: -9223372036854775808 -> -9223372036854775808.000000
+setting FPC rounding mode to [-> -inf]
+cegbr: -9223372036854775808 -> -9223372036854775808.000000
+
+setting FPC rounding mode to [-> near]
+cegbr: 9223372036854775807 -> 9223372036854775808.000000
+setting FPC rounding mode to [-> zero]
+cegbr: 9223372036854775807 -> 9223372036854774784.000000
+setting FPC rounding mode to [-> +inf]
+cegbr: 9223372036854775807 -> 9223372036854775808.000000
+setting FPC rounding mode to [-> -inf]
+cegbr: 9223372036854775807 -> 9223372036854774784.000000
+
+setting FPC rounding mode to [-> near]
+cegbr: -9223372036854775808 -> -9223372036854775808.000000
+setting FPC rounding mode to [-> zero]
+cegbr: -9223372036854775808 -> -9223372036854775808.000000
+setting FPC rounding mode to [-> +inf]
+cegbr: -9223372036854775808 -> -9223372036854775808.000000
+setting FPC rounding mode to [-> -inf]
+cegbr: -9223372036854775808 -> -9223372036854775808.000000
+
diff --git a/none/tests/s390x/rounding-5.vgtest b/none/tests/s390x/rounding-5.vgtest
new file mode 100644
index 0000000..51f3021
--- /dev/null
+++ b/none/tests/s390x/rounding-5.vgtest
@@ -0,0 +1 @@
+prog: rounding-5