From ced5cfffeea22ef9003c95a83ce7c31e428702fb Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Sat, 5 Mar 2022 07:16:46 +0100 Subject: Use long endian options for ppc64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC options pairs -mlittle/-mlittle-endian and -mbig/-mbig-endian are equivalent on ppc64 architecture. However, Clang supports only long version of the options. Use longer form in configure to properly support both GCC and Clang compiler. In addition, fix this issue in tcg test configure. Signed-off-by: Miroslav Rezanina Reviewed-by: Greg Kurz Message-Id: <20220131091714.4825-1-mrezanin@redhat.com> Signed-off-by: Cédric Le Goater --- tests/tcg/configure.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh index 0663bd1..ed4b5cc 100755 --- a/tests/tcg/configure.sh +++ b/tests/tcg/configure.sh @@ -64,9 +64,9 @@ fi : ${cross_cc_ppc="powerpc-linux-gnu-gcc"} : ${cross_cc_cflags_ppc="-m32"} : ${cross_cc_ppc64="powerpc64-linux-gnu-gcc"} -: ${cross_cc_cflags_ppc64="-m64 -mbig"} +: ${cross_cc_cflags_ppc64="-m64 -mbig-endian"} : ${cross_cc_ppc64le="$cross_cc_ppc64"} -: ${cross_cc_cflags_ppc64le="-m64 -mlittle"} +: ${cross_cc_cflags_ppc64le="-m64 -mlittle-endian"} : ${cross_cc_riscv64="riscv64-linux-gnu-gcc"} : ${cross_cc_s390x="s390x-linux-gnu-gcc"} : ${cross_cc_sh4="sh4-linux-gnu-gcc"} -- cgit v1.1 From d21939ca8b71a7c5479866e61a40d7b7b28a1bc0 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Sat, 5 Mar 2022 07:16:46 +0100 Subject: tests/tcg/ppc64le: use inline asm instead of __builtin_mtfsf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LLVM/Clang does not support __builtin_mtfsf. Acked-by: Alex Bennée Reviewed-by: Richard Henderson Signed-off-by: Matheus Ferst Message-Id: <20220304165417.1981159-2-matheus.ferst@eldorado.org.br> Signed-off-by: Cédric Le Goater --- tests/tcg/ppc64le/mtfsf.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/tcg/ppc64le/mtfsf.c b/tests/tcg/ppc64le/mtfsf.c index b3d31f3..bed5b1a 100644 --- a/tests/tcg/ppc64le/mtfsf.c +++ b/tests/tcg/ppc64le/mtfsf.c @@ -1,8 +1,12 @@ #include +#include #include #include #include +#define MTFSF(FLM, FRB) asm volatile ("mtfsf %0, %1" :: "i" (FLM), "f" (FRB)) +#define MFFS(FRT) asm("mffs %0" : "=f" (FRT)) + #define FPSCR_VE 7 /* Floating-point invalid operation exception enable */ #define FPSCR_VXSOFT 10 /* Floating-point invalid operation exception (soft) */ #define FPSCR_FI 17 /* Floating-point fraction inexact */ @@ -21,10 +25,7 @@ void sigfpe_handler(int sig, siginfo_t *si, void *ucontext) int main(void) { - union { - double d; - long long ll; - } fpscr; + uint64_t fpscr; struct sigaction sa = { .sa_sigaction = sigfpe_handler, @@ -40,10 +41,9 @@ int main(void) prctl(PR_SET_FPEXC, PR_FP_EXC_PRECISE); /* First test if the FI bit is being set correctly */ - fpscr.ll = FP_FI; - __builtin_mtfsf(0b11111111, fpscr.d); - fpscr.d = __builtin_mffs(); - assert((fpscr.ll & FP_FI) != 0); + MTFSF(0b11111111, FP_FI); + MFFS(fpscr); + assert((fpscr & FP_FI) != 0); /* Then test if the deferred exception is being called correctly */ sigaction(SIGFPE, &sa, NULL); @@ -54,8 +54,7 @@ int main(void) * But if a different exception is chosen si_code check should * change accordingly. */ - fpscr.ll = FP_VE | FP_VXSOFT; - __builtin_mtfsf(0b11111111, fpscr.d); + MTFSF(0b11111111, FP_VE | FP_VXSOFT); return 1; } -- cgit v1.1 From 8189cb850728fd52cd98f5ee4640b5dc4e40239d Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Sat, 5 Mar 2022 07:16:46 +0100 Subject: tests/tcg/ppc64le: drop __int128 usage in bcdsub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using __int128 with inline asm constraints like "v" generates incorrect code when compiling with LLVM/Clang (e.g., only one doubleword of the VSR is loaded). Instead, use a GPR pair to pass the 128-bits value and load the VSR with mtvsrd/xxmrghd. Reviewed-by: Richard Henderson Signed-off-by: Matheus Ferst Message-Id: <20220304165417.1981159-4-matheus.ferst@eldorado.org.br> Signed-off-by: Cédric Le Goater --- tests/tcg/ppc64le/bcdsub.c | 129 +++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 68 deletions(-) (limited to 'tests') diff --git a/tests/tcg/ppc64le/bcdsub.c b/tests/tcg/ppc64le/bcdsub.c index 8c188ca..12da19b 100644 --- a/tests/tcg/ppc64le/bcdsub.c +++ b/tests/tcg/ppc64le/bcdsub.c @@ -1,6 +1,7 @@ #include #include #include +#include #define CRF_LT (1 << 3) #define CRF_GT (1 << 2) @@ -8,24 +9,39 @@ #define CRF_SO (1 << 0) #define UNDEF 0 -#define BCDSUB(vra, vrb, ps) \ - asm ("bcdsub. %1,%2,%3,%4;" \ - "mfocrf %0,0b10;" \ - : "=r" (cr), "=v" (vrt) \ - : "v" (vra), "v" (vrb), "i" (ps) \ - : ); - -#define TEST(vra, vrb, ps, exp_res, exp_cr6) \ +/* + * Use GPR pairs to load the VSR values and place the resulting VSR and CR6 in + * th, tl, and cr. Note that we avoid newer instructions (e.g., mtvsrdd/mfvsrld) + * so we can run this test on POWER8 machines. + */ +#define BCDSUB(AH, AL, BH, BL, PS) \ + asm ("mtvsrd 32, %3\n\t" \ + "mtvsrd 33, %4\n\t" \ + "xxmrghd 32, 32, 33\n\t" \ + "mtvsrd 33, %5\n\t" \ + "mtvsrd 34, %6\n\t" \ + "xxmrghd 33, 33, 34\n\t" \ + "bcdsub. 0, 0, 1, %7\n\t" \ + "mfocrf %0, 0b10\n\t" \ + "mfvsrd %1, 32\n\t" \ + "xxswapd 32, 32\n\t" \ + "mfvsrd %2, 32\n\t" \ + : "=r" (cr), "=r" (th), "=r" (tl) \ + : "r" (AH), "r" (AL), "r" (BH), "r" (BL), "i" (PS) \ + : "v0", "v1", "v2"); + +#define TEST(AH, AL, BH, BL, PS, TH, TL, CR6) \ do { \ - __int128 vrt = 0; \ int cr = 0; \ - BCDSUB(vra, vrb, ps); \ - if (exp_res) \ - assert(vrt == exp_res); \ - assert((cr >> 4) == exp_cr6); \ + uint64_t th, tl; \ + BCDSUB(AH, AL, BH, BL, PS); \ + if (TH != UNDEF || TL != UNDEF) { \ + assert(tl == TL); \ + assert(th == TH); \ + } \ + assert((cr >> 4) == CR6); \ } while (0) - /* * Unbounded result is equal to zero: * sign = (PS) ? 0b1111 : 0b1100 @@ -33,13 +49,13 @@ */ void test_bcdsub_eq(void) { - __int128 a, b; - /* maximum positive BCD value */ - a = b = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999c); - - TEST(a, b, 0, 0xc, CRF_EQ); - TEST(a, b, 1, 0xf, CRF_EQ); + TEST(0x9999999999999999, 0x999999999999999c, + 0x9999999999999999, 0x999999999999999c, + 0, 0x0, 0xc, CRF_EQ); + TEST(0x9999999999999999, 0x999999999999999c, + 0x9999999999999999, 0x999999999999999c, + 1, 0x0, 0xf, CRF_EQ); } /* @@ -49,21 +65,16 @@ void test_bcdsub_eq(void) */ void test_bcdsub_gt(void) { - __int128 a, b, c; - - /* maximum positive BCD value */ - a = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999c); - - /* negative one BCD value */ - b = (__int128) 0x1d; - - TEST(a, b, 0, 0xc, (CRF_GT | CRF_SO)); - TEST(a, b, 1, 0xf, (CRF_GT | CRF_SO)); - - c = (((__int128) 0x9999999999999999) << 64 | 0x999999999999998c); - - TEST(c, b, 0, a, CRF_GT); - TEST(c, b, 1, (a | 0x3), CRF_GT); + /* maximum positive and negative one BCD values */ + TEST(0x9999999999999999, 0x999999999999999c, 0x0, 0x1d, 0, + 0x0, 0xc, (CRF_GT | CRF_SO)); + TEST(0x9999999999999999, 0x999999999999999c, 0x0, 0x1d, 1, + 0x0, 0xf, (CRF_GT | CRF_SO)); + + TEST(0x9999999999999999, 0x999999999999998c, 0x0, 0x1d, 0, + 0x9999999999999999, 0x999999999999999c, CRF_GT); + TEST(0x9999999999999999, 0x999999999999998c, 0x0, 0x1d, 1, + 0x9999999999999999, 0x999999999999999f, CRF_GT); } /* @@ -73,45 +84,27 @@ void test_bcdsub_gt(void) */ void test_bcdsub_lt(void) { - __int128 a, b; - - /* positive zero BCD value */ - a = (__int128) 0xc; - - /* positive one BCD value */ - b = (__int128) 0x1c; - - TEST(a, b, 0, 0x1d, CRF_LT); - TEST(a, b, 1, 0x1d, CRF_LT); - - /* maximum negative BCD value */ - a = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999d); - - /* positive one BCD value */ - b = (__int128) 0x1c; - - TEST(a, b, 0, 0xd, (CRF_LT | CRF_SO)); - TEST(a, b, 1, 0xd, (CRF_LT | CRF_SO)); + /* positive zero and positive one BCD values */ + TEST(0x0, 0xc, 0x0, 0x1c, 0, 0x0, 0x1d, CRF_LT); + TEST(0x0, 0xc, 0x0, 0x1c, 1, 0x0, 0x1d, CRF_LT); + + /* maximum negative and positive one BCD values */ + TEST(0x9999999999999999, 0x999999999999999d, 0x0, 0x1c, 0, + 0x0, 0xd, (CRF_LT | CRF_SO)); + TEST(0x9999999999999999, 0x999999999999999d, 0x0, 0x1c, 1, + 0x0, 0xd, (CRF_LT | CRF_SO)); } void test_bcdsub_invalid(void) { - __int128 a, b; - - /* positive one BCD value */ - a = (__int128) 0x1c; - b = 0xf00; - - TEST(a, b, 0, UNDEF, CRF_SO); - TEST(a, b, 1, UNDEF, CRF_SO); - - TEST(b, a, 0, UNDEF, CRF_SO); - TEST(b, a, 1, UNDEF, CRF_SO); + TEST(0x0, 0x1c, 0x0, 0xf00, 0, UNDEF, UNDEF, CRF_SO); + TEST(0x0, 0x1c, 0x0, 0xf00, 1, UNDEF, UNDEF, CRF_SO); - a = 0xbad; + TEST(0x0, 0xf00, 0x0, 0x1c, 0, UNDEF, UNDEF, CRF_SO); + TEST(0x0, 0xf00, 0x0, 0x1c, 1, UNDEF, UNDEF, CRF_SO); - TEST(a, b, 0, UNDEF, CRF_SO); - TEST(a, b, 1, UNDEF, CRF_SO); + TEST(0x0, 0xbad, 0x0, 0xf00, 0, UNDEF, UNDEF, CRF_SO); + TEST(0x0, 0xbad, 0x0, 0xf00, 1, UNDEF, UNDEF, CRF_SO); } int main(void) -- cgit v1.1 From 63c2b746bebef3ec9de4f29d5beeea4ee809c892 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Sat, 5 Mar 2022 07:16:46 +0100 Subject: tests/tcg/ppc64le: emit bcdsub with .long when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on GCC docs[1], we use the '-mpower8-vector' flag at config-time to detect the toolchain support to the bcdsub instruction. LLVM/Clang supports this flag since version 3.6[2], but the instruction and related builtins were only added in LLVM 14[3]. In the absence of other means to detect this support at config-time, we resort to __has_builtin to identify the presence of __builtin_bcdsub at compile-time. If the builtin is not available, the instruction is emitted with a ".long". [1] https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/PowerPC-AltiVec_002fVSX-Built-in-Functions.html [2] https://github.com/llvm/llvm-project/commit/59eb767e11d4ffefb5f55409524e5c8416b2b0db [3] https://github.com/llvm/llvm-project/commit/c933c2eb334660c131f4afc9d194fafb0cec0423 Reviewed-by: Richard Henderson Signed-off-by: Matheus Ferst Message-Id: <20220304165417.1981159-5-matheus.ferst@eldorado.org.br> Signed-off-by: Cédric Le Goater --- tests/tcg/ppc64le/bcdsub.c | 73 ++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 31 deletions(-) (limited to 'tests') diff --git a/tests/tcg/ppc64le/bcdsub.c b/tests/tcg/ppc64le/bcdsub.c index 12da19b..87c8c44 100644 --- a/tests/tcg/ppc64le/bcdsub.c +++ b/tests/tcg/ppc64le/bcdsub.c @@ -9,37 +9,48 @@ #define CRF_SO (1 << 0) #define UNDEF 0 -/* - * Use GPR pairs to load the VSR values and place the resulting VSR and CR6 in - * th, tl, and cr. Note that we avoid newer instructions (e.g., mtvsrdd/mfvsrld) - * so we can run this test on POWER8 machines. - */ -#define BCDSUB(AH, AL, BH, BL, PS) \ - asm ("mtvsrd 32, %3\n\t" \ - "mtvsrd 33, %4\n\t" \ - "xxmrghd 32, 32, 33\n\t" \ - "mtvsrd 33, %5\n\t" \ - "mtvsrd 34, %6\n\t" \ - "xxmrghd 33, 33, 34\n\t" \ - "bcdsub. 0, 0, 1, %7\n\t" \ - "mfocrf %0, 0b10\n\t" \ - "mfvsrd %1, 32\n\t" \ - "xxswapd 32, 32\n\t" \ - "mfvsrd %2, 32\n\t" \ - : "=r" (cr), "=r" (th), "=r" (tl) \ - : "r" (AH), "r" (AL), "r" (BH), "r" (BL), "i" (PS) \ - : "v0", "v1", "v2"); - -#define TEST(AH, AL, BH, BL, PS, TH, TL, CR6) \ - do { \ - int cr = 0; \ - uint64_t th, tl; \ - BCDSUB(AH, AL, BH, BL, PS); \ - if (TH != UNDEF || TL != UNDEF) { \ - assert(tl == TL); \ - assert(th == TH); \ - } \ - assert((cr >> 4) == CR6); \ +#ifdef __has_builtin +#if !__has_builtin(__builtin_bcdsub) +#define NO_BUILTIN_BCDSUB +#endif +#endif + +#ifdef NO_BUILTIN_BCDSUB +#define BCDSUB(T, A, B, PS) \ + ".long 4 << 26 | (" #T ") << 21 | (" #A ") << 16 | (" #B ") << 11" \ + " | 1 << 10 | (" #PS ") << 9 | 65\n\t" +#else +#define BCDSUB(T, A, B, PS) "bcdsub. " #T ", " #A ", " #B ", " #PS "\n\t" +#endif + +#define TEST(AH, AL, BH, BL, PS, TH, TL, CR6) \ + do { \ + int cr = 0; \ + uint64_t th, tl; \ + /* \ + * Use GPR pairs to load the VSR values and place the resulting VSR and\ + * CR6 in th, tl, and cr. Note that we avoid newer instructions (e.g., \ + * mtvsrdd/mfvsrld) so we can run this test on POWER8 machines. \ + */ \ + asm ("mtvsrd 32, %3\n\t" \ + "mtvsrd 33, %4\n\t" \ + "xxmrghd 32, 32, 33\n\t" \ + "mtvsrd 33, %5\n\t" \ + "mtvsrd 34, %6\n\t" \ + "xxmrghd 33, 33, 34\n\t" \ + BCDSUB(0, 0, 1, PS) \ + "mfocrf %0, 0b10\n\t" \ + "mfvsrd %1, 32\n\t" \ + "xxswapd 32, 32\n\t" \ + "mfvsrd %2, 32\n\t" \ + : "=r" (cr), "=r" (th), "=r" (tl) \ + : "r" (AH), "r" (AL), "r" (BH), "r" (BL) \ + : "v0", "v1", "v2"); \ + if (TH != UNDEF || TL != UNDEF) { \ + assert(tl == TL); \ + assert(th == TH); \ + } \ + assert((cr >> 4) == CR6); \ } while (0) /* -- cgit v1.1 From 68455cf59394267363b090a1828b6c52994a4ee3 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Sat, 5 Mar 2022 07:16:46 +0100 Subject: tests/tcg/ppc64le: Use Altivec register names in clobber list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LLVM/Clang doesn't know the VSX registers when compiling with -mabi=elfv1. Use only registers >= 32 and list them with their Altivec name. Reviewed-by: Richard Henderson Signed-off-by: Matheus Ferst Message-Id: <20220304165417.1981159-6-matheus.ferst@eldorado.org.br> Signed-off-by: Cédric Le Goater --- tests/tcg/ppc64le/non_signalling_xscv.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/tcg/ppc64le/non_signalling_xscv.c b/tests/tcg/ppc64le/non_signalling_xscv.c index 91e25ca..836df71 100644 --- a/tests/tcg/ppc64le/non_signalling_xscv.c +++ b/tests/tcg/ppc64le/non_signalling_xscv.c @@ -6,16 +6,16 @@ #define TEST(INSN, B_HI, B_LO, T_HI, T_LO) \ do { \ uint64_t th, tl, bh = B_HI, bl = B_LO; \ - asm("mtvsrd 0, %2\n\t" \ - "mtvsrd 1, %3\n\t" \ - "xxmrghd 0, 0, 1\n\t" \ - INSN " 0, 0\n\t" \ - "mfvsrd %0, 0\n\t" \ - "xxswapd 0, 0\n\t" \ - "mfvsrd %1, 0\n\t" \ + asm("mtvsrd 32, %2\n\t" \ + "mtvsrd 33, %3\n\t" \ + "xxmrghd 32, 32, 33\n\t" \ + INSN " 32, 32\n\t" \ + "mfvsrd %0, 32\n\t" \ + "xxswapd 32, 32\n\t" \ + "mfvsrd %1, 32\n\t" \ : "=r" (th), "=r" (tl) \ : "r" (bh), "r" (bl) \ - : "vs0", "vs1"); \ + : "v0", "v1"); \ printf(INSN "(0x%016" PRIx64 "%016" PRIx64 ") = 0x%016" PRIx64 \ "%016" PRIx64 "\n", bh, bl, th, tl); \ assert(th == T_HI && tl == T_LO); \ -- cgit v1.1