From: Andreas Arnez Date: Fri, 29 Sep 2023 14:11:31 +0000 (+0200) Subject: s390x regtest: Refactor mul test cases for Clang support X-Git-Tag: VALGRIND_3_22_0~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f401afeeea0b928a79cfd2ea143bb49593e4a3f;p=thirdparty%2Fvalgrind.git s390x regtest: Refactor mul test cases for Clang support 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. --- diff --git a/none/tests/s390x/mul.c b/none/tests/s390x/mul.c index 1604c8ad75..f558ad3da6 100644 --- a/none/tests/s390x/mul.c +++ b/none/tests/s390x/mul.c @@ -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() diff --git a/none/tests/s390x/mul.h b/none/tests/s390x/mul.h index 578b7147c3..2d54387ed1 100644 --- a/none/tests/s390x/mul.h +++ b/none/tests/s390x/mul.h @@ -1,299 +1,76 @@ #include -#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); \ diff --git a/none/tests/s390x/mul_GE.c b/none/tests/s390x/mul_GE.c index f3a0c39fc6..a3635d6183 100644 --- a/none/tests/s390x/mul_GE.c +++ b/none/tests/s390x/mul_GE.c @@ -1,6 +1,8 @@ #include #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; }