]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: BFP testsuite: condolidate FPC insns in bfp-insn.c
authorFlorian Krohm <flo2030@eich-krohm.de>
Tue, 23 Sep 2025 13:18:25 +0000 (13:18 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Tue, 23 Sep 2025 13:18:25 +0000 (13:18 +0000)
Remove srnm, srnmb, and rounding-2 testcases.
Also test EFPC and LFPC.

Part of fixing https://bugs.kde.org/show_bug.cgi?id=509572

17 files changed:
.gitignore
none/tests/s390x/Makefile.am
none/tests/s390x/bfp-fpc.c [new file with mode: 0644]
none/tests/s390x/bfp-fpc.stderr.exp [moved from none/tests/s390x/rounding-2.stderr.exp with 100% similarity]
none/tests/s390x/bfp-fpc.stdout.exp [new file with mode: 0644]
none/tests/s390x/bfp-fpc.vgtest [new file with mode: 0644]
none/tests/s390x/rounding-2.c [deleted file]
none/tests/s390x/rounding-2.stdout.exp [deleted file]
none/tests/s390x/rounding-2.vgtest [deleted file]
none/tests/s390x/srnm.c [deleted file]
none/tests/s390x/srnm.stderr.exp [deleted file]
none/tests/s390x/srnm.stdout.exp [deleted file]
none/tests/s390x/srnm.vgtest [deleted file]
none/tests/s390x/srnmb.c [deleted file]
none/tests/s390x/srnmb.stderr.exp [deleted file]
none/tests/s390x/srnmb.stdout.exp [deleted file]
none/tests/s390x/srnmb.vgtest [deleted file]

index fb69b92a02e345354ae86408303c8746093bfc48..e70c9cc4214566e299103696cd2cfcf89dcaf62a 100644 (file)
 /none/tests/s390x/sub
 /none/tests/s390x/sub-z14
 /none/tests/s390x/sub_EI
-/none/tests/s390x/bfp-tdc
 /none/tests/s390x/hfp
 /none/tests/s390x/xc
 /none/tests/s390x/xor
 /none/tests/s390x/rounding-3
 /none/tests/s390x/bfp-arith
 /none/tests/s390x/bfp-load
+/none/tests/s390x/bfp-fpc
+/none/tests/s390x/bfp-tdc
 /none/tests/s390x/bfp-3
 /none/tests/s390x/bfp-compare
-/none/tests/s390x/srnm
-/none/tests/s390x/srnmb
 /none/tests/s390x/comp-1
 /none/tests/s390x/comp-2
 /none/tests/s390x/ex
index b1f41a90faa25bded237941be72bff279069447c..7d2d1f8c48d46236dc32ed94a27e04c5a83e62c6 100644 (file)
@@ -9,8 +9,8 @@ INSN_TESTS = clc clcle cvb cvd icm lpr lam_stam xc mvst add sub mul \
              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_warn \
-             bfp-tdc bfp-load rounding-1 rounding-2 rounding-3 bfp-arith \
-             bfp-3 bfp-compare srnm srnmb comp-1 comp-2 exrl tmll tm stmg \
+             bfp-tdc bfp-load bfp-fpc rounding-1 rounding-3 bfp-arith \
+             bfp-3 bfp-compare comp-1 comp-2 exrl tmll tm stmg \
             ex clst mvc test_fork test_sig rounding-6 rxsbg popcnt \
             high-word traps \
             spechelper-alr spechelper-algr \
diff --git a/none/tests/s390x/bfp-fpc.c b/none/tests/s390x/bfp-fpc.c
new file mode 100644 (file)
index 0000000..0862c5b
--- /dev/null
@@ -0,0 +1,178 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "opcodes.h"
+#include "rounding.h"
+
+/* Instructions modifying / querying the FPC register:
+   EFPC, LFPC, SFPC, STFPC, SRNM, SRNMB.
+
+   No tests for SFASR and LFAS asa they are not implemented */
+
+void
+sfpc(unsigned mode)
+{
+   register unsigned r asm("1") = mode;
+   __asm__ volatile ( SFPC(1) : : "d"(r) );
+}
+
+unsigned
+get_rounding_mode(void)
+{
+   unsigned fpc1;
+   uint64_t fpc2 = ~(uint64_t)0;
+
+   __asm__ volatile ("stfpc  %0" : "=Q"(fpc1));
+   __asm__ volatile ("efpc   %0" : "+d"(fpc2));
+
+   assert((fpc1 & 0x7) == (fpc2 & 0x7));
+   assert((fpc2 >> 32) == 0xFFFFFFFF);
+
+   return fpc1 & 0x7;
+}
+
+#define srnm(b,d)                                         \
+   ({                                                     \
+      __asm__ volatile ("srnm  %[displ] (%[base])\n\t"    \
+                        : : [base]"a"(b), [displ]"L"(d)); \
+   })
+
+#define srnmb(b,d)                                        \
+   ({                                                     \
+      __asm__ volatile ("srnmb  %[displ] (%[base])\n\t"   \
+                        : : [base]"a"(b), [displ]"L"(d)); \
+   })
+
+int main(void)
+{
+   /* Order of rounding modes is such that the first rounding mode in
+      the list differs from the default rounding mode which is
+      FPC_BFP_ROUND_NEAREST_EVEN. */
+   const unsigned rmodes[] = {
+      FPC_BFP_ROUND_ZERO,
+      FPC_BFP_ROUND_POSINF,
+      FPC_BFP_ROUND_NEGINF,
+      FPC_BFP_ROUND_PREPARE_SHORT,
+      FPC_BFP_ROUND_NEAREST_EVEN,
+   };
+
+   int initial = get_rounding_mode();
+   assert(initial == FPC_BFP_ROUND_NEAREST_EVEN);
+
+   printf("initial rounding mode: %u\n", initial);
+
+   printf("Setting FPC rounding mode via SFPC\n");
+   for (int i = 0; i < sizeof rmodes / sizeof rmodes[0]; ++i) {
+      printf("setting rounding mode to %u\n", rmodes[i]);
+      sfpc(rmodes[i]);
+      printf("...checking: %u\n", get_rounding_mode());
+   }
+
+   putchar('\n');
+   printf("Setting FPC rounding mode via SRNM\n");
+   /* Only rounding modes 0,1,2,3 are valid for SRNM */
+
+   /* Rounding mode --> base register */
+   printf(".... using base register\n");
+   printf("setting rounding mode to %u\n", 0);
+   srnm(0, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 1);
+   srnm(1, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 2);
+   srnm(2, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 3);
+   srnm(3, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+
+   /* Rounding mode --> displacement */
+   printf(".... using displacement\n");
+   printf("setting rounding mode to %u\n", 0);
+   srnm(0, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 1);
+   srnm(0, 1);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 2);
+   srnm(0, 2);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 3);
+   srnm(0, 3);
+   printf("...checking: %u\n", get_rounding_mode());
+
+   putchar('\n');
+   printf("Setting FPC rounding mode via SRNMB\n");
+   /* All rounding modes allowed */
+
+   /* Rounding mode --> base register */
+   printf(".... using base register\n");
+   printf("setting rounding mode to %u\n", 0);
+   srnmb(0, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 1);
+   srnmb(1, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 2);
+   srnmb(2, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 3);
+   srnmb(3, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 7);
+   srnmb(7, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+
+   /* Rounding mode --> displacement */
+   printf(".... using displacement\n");
+   printf("setting rounding mode to %u\n", 0);
+   srnmb(0, 0);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 1);
+   srnmb(0, 1);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 2);
+   srnmb(0, 2);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 3);
+   srnmb(0, 3);
+   printf("...checking: %u\n", get_rounding_mode());
+   printf("setting rounding mode to %u\n", 7);
+   srnmb(0, 7);
+   printf("...checking: %u\n", get_rounding_mode());
+
+   putchar('\n');
+   printf("SRNM specific checks\n");
+   /* Making sure base reg and displacement are added. */
+   srnm(1,2);  // 1 + 2 = 3
+   printf("rounding mode = %u\n", get_rounding_mode());
+   /* Making sure extra bits get masked away */
+   srnm(0,0xfff);  /* 3 */
+   printf("rounding mode = %u\n", get_rounding_mode());
+   srnm(0xfff,0);  /* 3 */
+   printf("rounding mode = %u\n", get_rounding_mode());
+   srnm(0xfff,0xfff);  /* 3 */
+   printf("rounding mode = %u\n", get_rounding_mode());
+   srnm(3,3);      /* 2 */
+   printf("rounding mode = %u\n", get_rounding_mode());
+
+   putchar('\n');
+   printf("SRNMB specific checks\n");
+   /* Making sure base reg and displacement are added. */
+   srnmb(3,4);  // 3 + 4 = 7
+   printf("rounding mode = %u\n", get_rounding_mode());
+
+   putchar('\n');
+   printf("LFPC\n");
+   unsigned fpcval;
+   
+   sfpc(3);                                       /* Set rounding mode to 3 */
+   printf("rounding mode = %u\n", get_rounding_mode());
+   __asm__ volatile ("stfpc %0" : "=Q"(fpcval));  /* Store FPC -> fpcval; */
+   fpcval = (fpcval & ~0x7) | 0x2;                /* modify rounding mode bits */
+   __asm__ volatile ("lfpc  %0" : "=Q"(fpcval));  
+   printf("rounding mode = %u\n", get_rounding_mode());
+   
+   return 0;
+}
diff --git a/none/tests/s390x/bfp-fpc.stdout.exp b/none/tests/s390x/bfp-fpc.stdout.exp
new file mode 100644 (file)
index 0000000..6e6c2c9
--- /dev/null
@@ -0,0 +1,70 @@
+initial rounding mode: 0
+Setting FPC rounding mode via SFPC
+setting rounding mode to 1
+...checking: 1
+setting rounding mode to 2
+...checking: 2
+setting rounding mode to 3
+...checking: 3
+setting rounding mode to 7
+...checking: 7
+setting rounding mode to 0
+...checking: 0
+
+Setting FPC rounding mode via SRNM
+.... using base register
+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
+.... using displacement
+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
+
+Setting FPC rounding mode via SRNMB
+.... using base register
+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
+setting rounding mode to 7
+...checking: 7
+.... using displacement
+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
+setting rounding mode to 7
+...checking: 7
+
+SRNM specific checks
+rounding mode = 3
+rounding mode = 3
+rounding mode = 3
+rounding mode = 2
+rounding mode = 2
+
+SRNMB specific checks
+rounding mode = 7
+
+LFPC
+rounding mode = 3
+rounding mode = 2
diff --git a/none/tests/s390x/bfp-fpc.vgtest b/none/tests/s390x/bfp-fpc.vgtest
new file mode 100644 (file)
index 0000000..d7306a2
--- /dev/null
@@ -0,0 +1,2 @@
+prog: bfp-fpc
+prereq: ../../../tests/s390x_features s390x-fpext
diff --git a/none/tests/s390x/rounding-2.c b/none/tests/s390x/rounding-2.c
deleted file mode 100644 (file)
index 32813ad..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#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" : "=Q"(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.stdout.exp b/none/tests/s390x/rounding-2.stdout.exp
deleted file mode 100644 (file)
index e0da369..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644 (file)
index c6e067d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-prog: rounding-2
diff --git a/none/tests/s390x/srnm.c b/none/tests/s390x/srnm.c
deleted file mode 100644 (file)
index b2948f3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "opcodes.h"
-
-#define srnm(b,d) \
-   ({ \
-      __asm__ volatile ( "lghi 8," #b "\n\t" \
-                         "srnm " #d "(8)\n\t" ::: "8"); \
-   })
-
-#define get_rounding_mode() \
-   ({ \
-      unsigned fpc; \
-      __asm__ volatile ("stfpc  %0" : "=Q"(fpc)); \
-      fpc & 0x7; \
-   })
-
-int main(void)
-{
-   printf("initial rounding mode = %u\n", get_rounding_mode());
-
-   /* Set basic rounding modes in various ways */
-   srnm(1,2);  // 1 + 2 = 3
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnm(2,0);
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnm(0,1);
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnm(0,0);
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   /* Some rounding modes with bits to be ignored */
-   srnm(0xff,0);  // -> 3
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnm(0,0xfe);  // -> 2
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnm(0xf0,0x0f);  // -> 3
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   return 0;
-}
diff --git a/none/tests/s390x/srnm.stderr.exp b/none/tests/s390x/srnm.stderr.exp
deleted file mode 100644 (file)
index 139597f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/none/tests/s390x/srnm.stdout.exp b/none/tests/s390x/srnm.stdout.exp
deleted file mode 100644 (file)
index a5a0278..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-initial rounding mode = 0
-rounding mode = 3
-rounding mode = 2
-rounding mode = 1
-rounding mode = 0
-rounding mode = 3
-rounding mode = 2
-rounding mode = 3
diff --git a/none/tests/s390x/srnm.vgtest b/none/tests/s390x/srnm.vgtest
deleted file mode 100644 (file)
index 4144aeb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-prog: srnm
diff --git a/none/tests/s390x/srnmb.c b/none/tests/s390x/srnmb.c
deleted file mode 100644 (file)
index 72fc799..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "opcodes.h"
-
-#define srnmb(b,d) \
-   ({ \
-      __asm__ volatile ( "lghi 8," #b "\n\t" \
-                         SRNMB(8,d) \
-                         ::: "8"); \
-   })
-
-
-/* Like srnm above, except it uses r0 as a base register */
-#define srnmb0(d) \
-   ({ \
-      __asm__ volatile ( SRNMB(0,d) \
-                         ::: "0"); \
-   })
-
-#define get_rounding_mode() \
-   ({ \
-      unsigned fpc; \
-      __asm__ volatile ("stfpc  %0" : "=Q"(fpc)); \
-      fpc & 0x7; \
-   })
-
-int main(void)
-{
-   setlinebuf(stdout);
-   printf("initial rounding mode = %u\n", get_rounding_mode());
-
-   /* Set basic rounding modes in various ways */
-   srnmb(1,002);  // 1 + 2 = 3
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnmb(2,000);
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnmb(0,001);
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnmb(0,000);
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-#if 0
-   // fpext
-   srnmb(7,000);  // -> 7
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnmb(0,000);  // -> 0
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnmb(0,007);  // -> 7
-   printf("rounding mode = %u\n", get_rounding_mode());
-#endif
-
-   srnmb(0,001);
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   srnmb0(004);    // -> specification exception
-   printf("rounding mode = %u\n", get_rounding_mode());
-
-   return 0;
-}
diff --git a/none/tests/s390x/srnmb.stderr.exp b/none/tests/s390x/srnmb.stderr.exp
deleted file mode 100644 (file)
index bfdaf8b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-vex s390->IR: specification exception: B2B8 0004
-valgrind: Unrecognised instruction at address 0x.........
-   at 0x........: main (srnmb.c:59)
-Your program just tried to execute an instruction that Valgrind
-did not recognise.  There are two possible reasons for this.
-1. Your program has a bug and erroneously jumped to a non-code
-   location.  If you are running Memcheck and you just saw a
-   warning about a bad jump, it's probably your program's fault.
-2. The instruction is legitimate but Valgrind doesn't handle it,
-   i.e. it's Valgrind's fault.  If you think this is the case or
-   you are not sure, please let us know and we'll try to fix it.
-Either way, Valgrind will now raise a SIGILL signal which will
-probably kill your program.
-
-Process terminating with default action of signal 4 (SIGILL)
- Illegal opcode at address 0x........
-   at 0x........: main (srnmb.c:59)
-
diff --git a/none/tests/s390x/srnmb.stdout.exp b/none/tests/s390x/srnmb.stdout.exp
deleted file mode 100644 (file)
index c9127aa..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-initial rounding mode = 0
-rounding mode = 3
-rounding mode = 2
-rounding mode = 1
-rounding mode = 0
-rounding mode = 1
diff --git a/none/tests/s390x/srnmb.vgtest b/none/tests/s390x/srnmb.vgtest
deleted file mode 100644 (file)
index 6eff81b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-prog: srnmb
-vgopts: --show-emwarns=yes