Remove srnm, srnmb, and rounding-2 testcases.
Also test EFPC and LFPC.
Part of fixing https://bugs.kde.org/show_bug.cgi?id=509572
/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
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 \
--- /dev/null
+#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;
+}
--- /dev/null
+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
--- /dev/null
+prog: bfp-fpc
+prereq: ../../../tests/s390x_features s390x-fpext
+++ /dev/null
-#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;
-}
+++ /dev/null
-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
+++ /dev/null
-prog: rounding-2
+++ /dev/null
-#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;
-}
+++ /dev/null
-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
+++ /dev/null
-prog: srnm
+++ /dev/null
-#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;
-}
+++ /dev/null
-
-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)
-
+++ /dev/null
-initial rounding mode = 0
-rounding mode = 3
-rounding mode = 2
-rounding mode = 1
-rounding mode = 0
-rounding mode = 1
+++ /dev/null
-prog: srnmb
-vgopts: --show-emwarns=yes