]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x regtest: Refactor mul test cases for Clang support
authorAndreas Arnez <arnez@linux.ibm.com>
Fri, 29 Sep 2023 14:11:31 +0000 (16:11 +0200)
committerAndreas Arnez <arnez@linux.ibm.com>
Fri, 29 Sep 2023 14:11:31 +0000 (16:11 +0200)
The mul test case crashes when compiled with clang because of register
clashes in some inline assemblies.  Obviously clang does not treat
register clobbers as "early clobbers", but sometimes uses the same
registers for inputs as well.

Rewrite the inline assemblies in mul.h to avoid this issue.  Also, reduce
the code duplication in the process.  Adjust mul_GE.c accordingly.  Keep
the expected output for all mul test cases the same as before.

none/tests/s390x/mul.c
none/tests/s390x/mul.h
none/tests/s390x/mul_GE.c

index 1604c8ad7559be046118a46bf9d5d6bd72c1d9b9..f558ad3da691582e3f4d524da098064b1529db61 100644 (file)
@@ -29,23 +29,24 @@ static void do_imm_insns(void)
 #define msgr(x, y) "msgr " x ", " y "\n"
 #define msgf(x, y) "msgf " x ", " y "\n"
 #define msgfr(x, y) "msgfr " x ", " y "\n"
+#define msy(x, y) "msy " x ", " y "\n"
 
 static void do_regmem_insns(unsigned long m2)
 {
-       memsweep(m, m2);
+       rmemsweep(m, m2);
        regsweep(mr, m2);
-       memsweep(mh, m2);
+       rmemsweep(mh, m2);
        memsweep(mlg, m2);
        regsweep(mlgr, m2);
        memsweep(ml, m2);
        regsweep(mlr, m2);
-       memsweep(ms, m2);
+       rmemsweep(ms, m2);
        regsweep(msr, m2);
        memsweep(msg, m2);
        regsweep(msgr, m2);
        memsweep(msgf, m2);
        regsweep(msgfr, m2);
-       msysweep(m2);
+       memsweep(msy, m2);
 }
 
 int main()
index 578b7147c31267ebc0c9ed076ea1cab26c172a73..2d54387ed1d62e2fef5a43e19fa179ea17f4b51d 100644 (file)
 #include <stdio.h>
 
-#define MUL_REG_MEM(insn, m1, m2)                      \
+union reg_pair {
+       struct { unsigned long a, b; };
+       unsigned __int128 pair;
+};
+
+#define MUL_REG_OP(insn, m1, fmt, m2)                                   \
+({                                                                     \
+       union reg_pair tmp = { { m1, m1 } };                            \
+       unsigned cc;                                                    \
+       asm ("xr %[cc],%[cc]\n"                                         \
+            insn("%[pair]", "%[op]")                                   \
+            "ipm %[cc]\n"                                              \
+            : [pair] "+d" (tmp.pair), [cc] "=&d" (cc)                  \
+            : [op] fmt (m2)                                            \
+            : "cc");                                                   \
+       printf(#insn " %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%u)\n", \
+              m1, m2, tmp.a, tmp.b, cc >> 28);                         \
+})
+
+#define MUL_REG_REG_REG(insn, m1, none, m2)                             \
+({                                                                     \
+       union reg_pair tmp = { { 0, 0 } };                              \
+       unsigned cc;                                                    \
+       asm ("xr %[cc],%[cc]\n"                                         \
+            insn("%[pair]", "%[a]", "%[b]")                            \
+            "ipm %[cc]\n"                                              \
+            : [pair] "+d" (tmp.pair), [cc] "=&d" (cc)                  \
+            : [a] "d" (m1), [b] "d" (m2)                               \
+            : "cc");                                                   \
+       printf(#insn " %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", \
+              m1, m2, tmp.a, tmp.b, cc >> 28);                         \
+})
+
+#define MUL_REG_XIMM(insn, m1, um2, m2)                                 \
+({                                                                     \
+       union reg_pair tmp = { { m1, m1 } };                            \
+       unsigned cc;                                                    \
+       asm ("xr %[cc],%[cc]\n"                                         \
+            insn("%[pair]", "0x" #m2)                                  \
+            "ipm %[cc]\n"                                              \
+            : [pair] "+d" (tmp.pair), [cc] "=&d" (cc)                  \
+            :: "cc");                                                  \
+       printf(#insn " %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", \
+              m1, (unsigned long) 0x##um2##m2, tmp.a, tmp.b, cc >> 28); \
+})
+
+#define sweep(f, i, x, m2)                             \
 ({                                                     \
-       unsigned long tmp1 = m1;                        \
-       unsigned long tmp2 = m1;                        \
-       int cc;                                         \
-       asm volatile(   "lgr 2, %[tmp1]\n"              \
-                       "lgr 3, %[tmp2]\n"              \
-                       "xr %[cc],%[cc]\n"              \
-                       insn("2", "%[m2]")              \
-                       "ipm %[cc]\n"                   \
-                       "srl %[cc],28\n"                \
-                       "lgr %[tmp1],2\n"               \
-                       "lgr %[tmp2],3\n"               \
-                       : [tmp1] "+d" (tmp1)            \
-                       , [tmp2] "+d" (tmp2)            \
-                       , [cc] "=&d" (cc)               \
-                       : [m2] "Q" (m2)                 \
-                       : "2","3","cc");                \
-       printf(#insn " %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", m1, m2, tmp1, tmp2, cc); \
-})
-
-#define MUL_REG_REG(insn, m1, m2)                      \
-({                                                     \
-       unsigned long tmp1 = m1;                        \
-       unsigned long tmp2 = m1;                        \
-       int cc;                                         \
-       asm volatile(   "lgr 2, %[tmp1]\n"              \
-                       "lgr 3, %[tmp2]\n"              \
-                       "xr %[cc],%[cc]\n"              \
-                       insn("2", "%[m2]")              \
-                       "ipm %[cc]\n"                   \
-                       "srl %[cc],28\n"                \
-                       "lgr %[tmp1],2\n"               \
-                       "lgr %[tmp2],3\n"               \
-                       : [tmp1] "+d" (tmp1)            \
-                       , [tmp2] "+d" (tmp2)            \
-                       , [cc] "=&d" (cc)               \
-                       : [m2] "d" (m2)                 \
-                       : "2","3","cc");                \
-       printf(#insn " %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", m1, m2, tmp1, tmp2, cc); \
-})
-
-#define MUL_REG_REG_REG(insn, m1, m2)                  \
-({                                                     \
-       unsigned long tmp1 = m1;                        \
-       unsigned long tmp2 = m1;                        \
-       int cc;                                         \
-       asm volatile(   "xr %[cc],%[cc]\n"              \
-                       "lghi 2,0\n"                   \
-                       "lghi 3,0\n"                   \
-                       insn("2", "%[tmp1]", "%[m2]")   \
-                       "ipm %[cc]\n"                   \
-                       "srl %[cc],28\n"                \
-                       "lgr %[tmp1],2\n"               \
-                       "lgr %[tmp2],3\n"               \
-                       : [tmp1] "+d" (tmp1)            \
-                       , [tmp2] "+d" (tmp2)            \
-                       , [cc] "=&d" (cc)               \
-                       : [m2] "d" (m2)                 \
-                       : "2","3","cc");                \
-       printf(#insn " %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", m1, m2, tmp1, tmp2, cc); \
-})
-
-#define MUL_REG_IMM(insn, m1, m2)                      \
-({                                                     \
-       unsigned long tmp1 = m1;                        \
-       unsigned long tmp2 = m1;                        \
-       int cc;                                         \
-       asm volatile(   "lgr 2, %[tmp1]\n"              \
-                       "lgr 3, %[tmp2]\n"              \
-                       "xr %[cc],%[cc]\n"              \
-                       insn("2", #m2)                  \
-                       "ipm %[cc]\n"                   \
-                       "srl %[cc],28\n"                \
-                       "lgr %[tmp1],2\n"               \
-                       "lgr %[tmp2],3\n"               \
-                       : [tmp1] "+d" (tmp1)            \
-                       , [tmp2] "+d" (tmp2)            \
-                       , [cc] "=&d" (cc)               \
-                       :: "2","3","cc");               \
-       printf(#insn " %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", m1, (unsigned long) m2, tmp1, tmp2, cc); \
-})
-
-#define MUL_REG_XIMM(insn, m1, um2, m2)                        \
-({                                                     \
-       unsigned long tmp1 = m1;                        \
-       unsigned long tmp2 = m1;                        \
-       int cc;                                         \
-       asm volatile(   "lgr 2, %[tmp1]\n"              \
-                       "lgr 3, %[tmp2]\n"              \
-                       "xr %[cc],%[cc]\n"              \
-                       insn(2,m2)                      \
-                       "ipm %[cc]\n"                   \
-                       "srl %[cc],28\n"                \
-                       "lgr %[tmp1],2\n"               \
-                       "lgr %[tmp2],3\n"               \
-                       : [tmp1] "+d" (tmp1)            \
-                       , [tmp2] "+d" (tmp2)            \
-                       , [cc] "=&d" (cc)               \
-                       :: "2","3","cc");               \
-       printf(#insn " %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", m1, (unsigned long) 0x##um2##m2, tmp1, tmp2, cc); \
-})
-
-
-#define memsweep(i, m2)                                        \
-({                                                     \
-       MUL_REG_MEM(i, 0ul, m2);                        \
-       MUL_REG_MEM(i, 1ul, m2);                        \
-       MUL_REG_MEM(i, 0xfffful, m2);                   \
-       MUL_REG_MEM(i, 0x7ffful, m2);                   \
-       MUL_REG_MEM(i, 0x8000ul, m2);                   \
-       MUL_REG_MEM(i, 0xfffffffful, m2);               \
-       MUL_REG_MEM(i, 0x80000000ul, m2);               \
-       MUL_REG_MEM(i, 0x7ffffffful, m2);               \
-       MUL_REG_MEM(i, 0xfffffffffffffffful, m2);       \
-       MUL_REG_MEM(i, 0x8000000000000000ul, m2);       \
-       MUL_REG_MEM(i, 0x7ffffffffffffffful, m2);       \
-})
-
-#define regsweep(i, m2)                                        \
-({                                                     \
-       MUL_REG_REG(i, 0ul, m2);                        \
-       MUL_REG_REG(i, 1ul, m2);                        \
-       MUL_REG_REG(i, 0xfffful, m2);                   \
-       MUL_REG_REG(i, 0x7ffful, m2);                   \
-       MUL_REG_REG(i, 0x8000ul, m2);                   \
-       MUL_REG_REG(i, 0xfffffffful, m2);               \
-       MUL_REG_REG(i, 0x80000000ul, m2);               \
-       MUL_REG_REG(i, 0x7ffffffful, m2);               \
-       MUL_REG_REG(i, 0xfffffffffffffffful, m2);       \
-       MUL_REG_REG(i, 0x8000000000000000ul, m2);       \
-       MUL_REG_REG(i, 0x7ffffffffffffffful, m2);       \
-})
-
-#define regregsweep(i, m2)                             \
-({                                                     \
-       MUL_REG_REG_REG(i, 0ul, m2);                    \
-       MUL_REG_REG_REG(i, 1ul, m2);                    \
-       MUL_REG_REG_REG(i, 0xfffful, m2);               \
-       MUL_REG_REG_REG(i, 0x7ffful, m2);               \
-       MUL_REG_REG_REG(i, 0x8000ul, m2);               \
-       MUL_REG_REG_REG(i, 0xfffffffful, m2);           \
-       MUL_REG_REG_REG(i, 0x80000000ul, m2);           \
-       MUL_REG_REG_REG(i, 0x7ffffffful, m2);           \
-       MUL_REG_REG_REG(i, 0xfffffffffffffffful, m2);   \
-       MUL_REG_REG_REG(i, 0x8000000000000000ul, m2);   \
-       MUL_REG_REG_REG(i, 0x7ffffffffffffffful, m2);   \
-})
-
-#define immsweep(i, m2)                                        \
-({                                                     \
-       MUL_REG_IMM(i, 0ul, m2);                        \
-       MUL_REG_IMM(i, 1ul, m2);                        \
-       MUL_REG_IMM(i, 0xfffful, m2);                   \
-       MUL_REG_IMM(i, 0x7ffful, m2);                   \
-       MUL_REG_IMM(i, 0x8000ul, m2);                   \
-       MUL_REG_IMM(i, 0xfffffffful, m2);               \
-       MUL_REG_IMM(i, 0x80000000ul, m2);               \
-       MUL_REG_IMM(i, 0x7ffffffful, m2);               \
-       MUL_REG_IMM(i, 0xfffffffffffffffful, m2);       \
-       MUL_REG_IMM(i, 0x8000000000000000ul, m2);       \
-       MUL_REG_IMM(i, 0x7ffffffffffffffful, m2);       \
-})
-
-#define ximmsweep(i, um2, m2)                          \
-({                                                     \
-       MUL_REG_XIMM(i, 0ul, um2, m2);                  \
-       MUL_REG_XIMM(i, 1ul, um2, m2);                  \
-       MUL_REG_XIMM(i, 0xfffful, um2, m2);             \
-       MUL_REG_XIMM(i, 0x7ffful, um2, m2);             \
-       MUL_REG_XIMM(i, 0x8000ul, um2, m2);             \
-       MUL_REG_XIMM(i, 0xfffffffful, um2, m2);         \
-       MUL_REG_XIMM(i, 0x80000000ul, um2, m2);         \
-       MUL_REG_XIMM(i, 0x7ffffffful, um2, m2);         \
-       MUL_REG_XIMM(i, 0xfffffffffffffffful, um2, m2); \
-       MUL_REG_XIMM(i, 0x8000000000000000ul, um2, m2); \
-       MUL_REG_XIMM(i, 0x7ffffffffffffffful, um2, m2); \
-})
-
-#define MUL_MSY(m1, m2)                                        \
-({                                                     \
-       unsigned long tmp1 = m1;                        \
-       unsigned long tmp2 = m1;                        \
-       int cc;                                         \
-       register unsigned long *addr asm("5") = &m2;    \
-       asm volatile(   "lgr 2, %[tmp1]\n"              \
-                       "lgr 3, %[tmp2]\n"              \
-                       "xr %[cc],%[cc]\n"              \
-                       MSY(2,0,5,000,00)               \
-                       "ipm %[cc]\n"                   \
-                       "srl %[cc],28\n"                \
-                       "lgr %[tmp1],2\n"               \
-                       "lgr %[tmp2],3\n"               \
-                       : [tmp1] "+d" (tmp1)            \
-                       , [tmp2] "+d" (tmp2)            \
-                       , [cc] "=&d" (cc)               \
-                       : [m2] "Q" (m2)                 \
-                       , [addr] "d" (addr)             \
-                       : "2","3","cc");                \
-       printf("msy %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", m1, m2, tmp1, tmp2, cc); \
-})
-
-#define msysweep(s2)                           \
-({                                             \
-       MUL_MSY(0ul, s2);                       \
-       MUL_MSY(1ul, s2);                       \
-       MUL_MSY(0xfffful, s2);                  \
-       MUL_MSY(0x7ffful, s2);                  \
-       MUL_MSY(0x8000ul, s2);                  \
-       MUL_MSY(0xfffffffful, s2);              \
-       MUL_MSY(0x80000000ul, s2);              \
-       MUL_MSY(0x7ffffffful, s2);              \
-       MUL_MSY(0xfffffffffffffffful, s2);      \
-       MUL_MSY(0x8000000000000000ul, s2);      \
-       MUL_MSY(0x7ffffffffffffffful, s2);      \
-})
-
-#define MUL_MHY(m1, m2)                                        \
-({                                                     \
-       unsigned long tmp1 = m1;                        \
-       unsigned long tmp2 = m1;                        \
-       int cc;                                         \
-       register unsigned long *addr asm("5") = &m2;    \
-       asm volatile(   "lgr 2, %[tmp1]\n"              \
-                       "lgr 3, %[tmp2]\n"              \
-                       "xr %[cc],%[cc]\n"              \
-                       MHY(2,0,5,000,00)               \
-                       "ipm %[cc]\n"                   \
-                       "srl %[cc],28\n"                \
-                       "lgr %[tmp1],2\n"               \
-                       "lgr %[tmp2],3\n"               \
-                       : [tmp1] "+d" (tmp1)            \
-                       , [tmp2] "+d" (tmp2)            \
-                       , [cc] "=&d" (cc)               \
-                       : [m2] "Q" (m2)                 \
-                       , [addr] "d" (addr)             \
-                       : "2","3","cc");                \
-       printf("mhy %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", m1, m2, tmp1, tmp2, cc); \
-})
-
-#define mhysweep(s2)                           \
-({                                             \
-       MUL_MHY(0ul, s2);                       \
-       MUL_MHY(1ul, s2);                       \
-       MUL_MHY(0xfffful, s2);                  \
-       MUL_MHY(0x7ffful, s2);                  \
-       MUL_MHY(0x8000ul, s2);                  \
-       MUL_MHY(0xfffffffful, s2);              \
-       MUL_MHY(0x80000000ul, s2);              \
-       MUL_MHY(0x7ffffffful, s2);              \
-       MUL_MHY(0xfffffffffffffffful, s2);      \
-       MUL_MHY(0x8000000000000000ul, s2);      \
-       MUL_MHY(0x7ffffffffffffffful, s2);      \
-})
-
-#define MUL_MFY(m1, m2)                                        \
-({                                                     \
-       unsigned long tmp1 = m1;                        \
-       unsigned long tmp2 = m1;                        \
-       int cc;                                         \
-       register unsigned long *addr asm("5") = &m2;    \
-       asm volatile(   "lgr 2, %[tmp1]\n"              \
-                       "lgr 3, %[tmp2]\n"              \
-                       "xr %[cc],%[cc]\n"              \
-                       MFY(2,0,5,000,00)               \
-                       "ipm %[cc]\n"                   \
-                       "srl %[cc],28\n"                \
-                       "lgr %[tmp1],2\n"               \
-                       "lgr %[tmp2],3\n"               \
-                       : [tmp1] "+d" (tmp1)            \
-                       , [tmp2]"+d" (tmp2)             \
-                       , [cc] "=&d" (cc)               \
-                       : [m2] "Q" (m2)                 \
-                       , [addr] "d" (addr)             \
-                       : "2","3");                     \
-       printf("mfy %16.16lX * %16.16lX = %16.16lX%16.16lX (cc=%d)\n", m1, m2, tmp1, tmp2, cc); \
-})
-
-#define mfysweep(s2)                           \
-({                                             \
-       MUL_MFY(0ul, s2);                       \
-       MUL_MFY(1ul, s2);                       \
-       MUL_MFY(0xfffful, s2);                  \
-       MUL_MFY(0x7ffful, s2);                  \
-       MUL_MFY(0x8000ul, s2);                  \
-       MUL_MFY(0xfffffffful, s2);              \
-       MUL_MFY(0x80000000ul, s2);              \
-       MUL_MFY(0x7ffffffful, s2);              \
-       MUL_MFY(0xfffffffffffffffful, s2);      \
-       MUL_MFY(0x8000000000000000ul, s2);      \
-       MUL_MFY(0x7ffffffffffffffful, s2);      \
-})
-
-#define for_each_m2(f)                         \
+       f(i, 0ul, x, m2);                               \
+       f(i, 1ul, x, m2);                               \
+       f(i, 0xfffful, x, m2);                          \
+       f(i, 0x7ffful, x, m2);                          \
+       f(i, 0x8000ul, x, m2);                          \
+       f(i, 0xfffffffful, x, m2);                      \
+       f(i, 0x80000000ul, x, m2);                      \
+       f(i, 0x7ffffffful, x, m2);                      \
+       f(i, 0xfffffffffffffffful, x, m2);              \
+       f(i, 0x8000000000000000ul, x, m2);              \
+       f(i, 0x7ffffffffffffffful, x, m2);              \
+})
+
+#define singlesweep(i, fmt, m2) sweep(MUL_REG_OP, i, fmt, m2)
+#define regregsweep(i, m2) sweep(MUL_REG_REG_REG, i, , m2)
+#define ximmsweep(i, um2, m2) sweep(MUL_REG_XIMM, i, um2, m2)
+
+#define regsweep(i, m2) singlesweep(i, "d", m2)
+#define memsweep(i, m2) singlesweep(i, "T", m2)
+#define rmemsweep(i, m2) singlesweep(i, "R", m2)
+#define immsweep(i, m2) singlesweep(i, "n", (unsigned long)m2)
+
+#define for_each_m2(do_regmem_insns)            \
 ({                                             \
        do_regmem_insns(0x0ul);                 \
        do_regmem_insns(0x7ffffffffffffffful);  \
index f3a0c39fc65273d53f93fc8ef48a03db764a8445..a3635d61830aa8f0054b39f7bcc21d2930167e03 100644 (file)
@@ -1,6 +1,8 @@
 #include <stdio.h>
 #include "mul.h"
-#include "opcodes.h"
+
+#define MSFI(x, y) ".insn rilu,0xc20100000000," x "," y "\n"
+#define MSGFI(x, y) ".insn rilu,0xc20000000000," x "," y "\n"
 
 static void do_imm_insns(void)
 {
@@ -23,29 +25,18 @@ static void do_imm_insns(void)
 
 }
 
+#define mhy(x, y) ".insn rxy,0xe3000000007c," x "," y "\n"
+#define mfy(x, y) ".insn rxy,0xe3000000005c," x "," y "\n"
 
 static void do_regmem_insns(unsigned long m2)
 {
-       mhysweep(m2);
-       mfysweep(m2);
+       memsweep(mhy, m2);
+       memsweep(mfy, m2);
 }
 
 int main()
 {
-       do_regmem_insns(0x0ul);
-       do_regmem_insns(0x7ffffffffffffffful);
-       do_regmem_insns(0x8000000000000000ul);
-       do_regmem_insns(0xfffffffffffffffful);
-       do_regmem_insns(0x7fffffff00000000ul);
-       do_regmem_insns(0x8000000000000000ul);
-       do_regmem_insns(0xffffffff00000000ul);
-       do_regmem_insns(0x000000007ffffffful);
-       do_regmem_insns(0x0000000080000000ul);
-       do_regmem_insns(0x00000000fffffffful);
-       do_regmem_insns(0x000000000000fffful);
-       do_regmem_insns(0x0000000000007ffful);
-       do_regmem_insns(0x0000000000008000ul);
-       do_regmem_insns(0x000000000000fffful);
+       for_each_m2(do_regmem_insns);
        do_imm_insns();
        return 0;
 }