From: Paolo Bonzini Date: Thu, 29 Sep 2022 11:42:02 +0000 (+0100) Subject: tests/tcg: unify ppc64 and ppc64le Makefiles X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=37b0dba45c4e44a02000a4170f25af0110f501d5;p=qemu.git tests/tcg: unify ppc64 and ppc64le Makefiles Make tests/tcg/ppc64le include tests/tcg/ppc64 instead of duplicating the rules. Because the ppc64le vpath includes tests/tcg/ppc64 but not vice versa, the tests have to be moved from tests/tcg/ppc64le/ to tests/tcg/ppc64. Signed-off-by: Paolo Bonzini Signed-off-by: Alex Bennée Message-Id: <20220929114231.583801-23-alex.bennee@linaro.org> --- diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target index 331fae628e..7db7a3e2b3 100644 --- a/tests/tcg/ppc64/Makefile.target +++ b/tests/tcg/ppc64/Makefile.target @@ -3,7 +3,6 @@ # ppc64 specific tweaks VPATH += $(SRC_PATH)/tests/tcg/ppc64 -VPATH += $(SRC_PATH)/tests/tcg/ppc64le ifneq ($(CROSS_CC_HAS_POWER8_VECTOR),) PPC64_TESTS=bcdsub non_signalling_xscv diff --git a/tests/tcg/ppc64/bcdsub.c b/tests/tcg/ppc64/bcdsub.c new file mode 100644 index 0000000000..87c8c44a44 --- /dev/null +++ b/tests/tcg/ppc64/bcdsub.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include + +#define CRF_LT (1 << 3) +#define CRF_GT (1 << 2) +#define CRF_EQ (1 << 1) +#define CRF_SO (1 << 0) +#define UNDEF 0 + +#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) + +/* + * Unbounded result is equal to zero: + * sign = (PS) ? 0b1111 : 0b1100 + * CR6 = 0b0010 + */ +void test_bcdsub_eq(void) +{ + /* maximum positive BCD value */ + TEST(0x9999999999999999, 0x999999999999999c, + 0x9999999999999999, 0x999999999999999c, + 0, 0x0, 0xc, CRF_EQ); + TEST(0x9999999999999999, 0x999999999999999c, + 0x9999999999999999, 0x999999999999999c, + 1, 0x0, 0xf, CRF_EQ); +} + +/* + * Unbounded result is greater than zero: + * sign = (PS) ? 0b1111 : 0b1100 + * CR6 = (overflow) ? 0b0101 : 0b0100 + */ +void test_bcdsub_gt(void) +{ + /* 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); +} + +/* + * Unbounded result is less than zero: + * sign = 0b1101 + * CR6 = (overflow) ? 0b1001 : 0b1000 + */ +void test_bcdsub_lt(void) +{ + /* 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) +{ + TEST(0x0, 0x1c, 0x0, 0xf00, 0, UNDEF, UNDEF, CRF_SO); + TEST(0x0, 0x1c, 0x0, 0xf00, 1, UNDEF, UNDEF, CRF_SO); + + TEST(0x0, 0xf00, 0x0, 0x1c, 0, UNDEF, UNDEF, CRF_SO); + TEST(0x0, 0xf00, 0x0, 0x1c, 1, UNDEF, 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) +{ + struct sigaction action; + + action.sa_handler = _exit; + sigaction(SIGABRT, &action, NULL); + + test_bcdsub_eq(); + test_bcdsub_gt(); + test_bcdsub_lt(); + test_bcdsub_invalid(); + + return 0; +} diff --git a/tests/tcg/ppc64/byte_reverse.c b/tests/tcg/ppc64/byte_reverse.c new file mode 100644 index 0000000000..53b76fc2e2 --- /dev/null +++ b/tests/tcg/ppc64/byte_reverse.c @@ -0,0 +1,21 @@ +#include + +int main(void) +{ + unsigned long var; + + var = 0xFEDCBA9876543210; + asm("brh %0, %0" : "+r"(var)); + assert(var == 0xDCFE98BA54761032); + + var = 0xFEDCBA9876543210; + asm("brw %0, %0" : "+r"(var)); + assert(var == 0x98BADCFE10325476); + + var = 0xFEDCBA9876543210; + asm("brd %0, %0" : "+r"(var)); + assert(var == 0x1032547698BADCFE); + + return 0; +} + diff --git a/tests/tcg/ppc64/mffsce.c b/tests/tcg/ppc64/mffsce.c new file mode 100644 index 0000000000..20d882cb45 --- /dev/null +++ b/tests/tcg/ppc64/mffsce.c @@ -0,0 +1,37 @@ +#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 MFFSCE(FRT) asm("mffsce %0" : "=f" (FRT)) + +#define PPC_BIT_NR(nr) (63 - (nr)) + +#define FP_VE (1ull << PPC_BIT_NR(56)) +#define FP_UE (1ull << PPC_BIT_NR(58)) +#define FP_ZE (1ull << PPC_BIT_NR(59)) +#define FP_XE (1ull << PPC_BIT_NR(60)) +#define FP_NI (1ull << PPC_BIT_NR(61)) +#define FP_RN1 (1ull << PPC_BIT_NR(63)) + +int main(void) +{ + uint64_t frt, fpscr; + uint64_t test_value = FP_VE | FP_UE | FP_ZE | + FP_XE | FP_NI | FP_RN1; + MTFSF(0b11111111, test_value); /* set test value to cpu fpscr */ + MFFSCE(frt); + MFFS(fpscr); /* read the value that mffsce stored to cpu fpscr */ + + /* the returned value should be as the cpu fpscr was before */ + assert((frt & 0xff) == test_value); + + /* + * the cpu fpscr last 3 bits should be unchanged + * and enable bits should be unset + */ + assert((fpscr & 0xff) == (test_value & 0x7)); + + return 0; +} diff --git a/tests/tcg/ppc64/mtfsf.c b/tests/tcg/ppc64/mtfsf.c new file mode 100644 index 0000000000..bed5b1afa4 --- /dev/null +++ b/tests/tcg/ppc64/mtfsf.c @@ -0,0 +1,60 @@ +#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 */ + +#define FP_VE (1ull << FPSCR_VE) +#define FP_VXSOFT (1ull << FPSCR_VXSOFT) +#define FP_FI (1ull << FPSCR_FI) + +void sigfpe_handler(int sig, siginfo_t *si, void *ucontext) +{ + if (si->si_code == FPE_FLTINV) { + exit(0); + } + exit(1); +} + +int main(void) +{ + uint64_t fpscr; + + struct sigaction sa = { + .sa_sigaction = sigfpe_handler, + .sa_flags = SA_SIGINFO + }; + + /* + * Enable the MSR bits F0 and F1 to enable exceptions. + * This shouldn't be needed in linux-user as these bits are enabled by + * default, but this allows to execute either in a VM or a real machine + * to compare the behaviors. + */ + prctl(PR_SET_FPEXC, PR_FP_EXC_PRECISE); + + /* First test if the FI bit is being set correctly */ + 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); + + /* + * Although the VXSOFT exception has been chosen, based on test in a Power9 + * any combination of exception bit + its enabling bit should work. + * But if a different exception is chosen si_code check should + * change accordingly. + */ + MTFSF(0b11111111, FP_VE | FP_VXSOFT); + + return 1; +} diff --git a/tests/tcg/ppc64/non_signalling_xscv.c b/tests/tcg/ppc64/non_signalling_xscv.c new file mode 100644 index 0000000000..836df71ef0 --- /dev/null +++ b/tests/tcg/ppc64/non_signalling_xscv.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +#define TEST(INSN, B_HI, B_LO, T_HI, T_LO) \ + do { \ + uint64_t th, tl, bh = B_HI, bl = B_LO; \ + 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) \ + : "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); \ + } while (0) + +int main(void) +{ + /* SNaN shouldn't be silenced */ + TEST("xscvspdpn", 0x7fbfffff00000000ULL, 0x0, 0x7ff7ffffe0000000ULL, 0x0); + TEST("xscvdpspn", 0x7ff7ffffffffffffULL, 0x0, 0x7fbfffff7fbfffffULL, 0x0); + + /* + * SNaN inputs having no significant bits in the upper 23 bits of the + * signifcand will return Infinity as the result. + */ + TEST("xscvdpspn", 0x7ff000001fffffffULL, 0x0, 0x7f8000007f800000ULL, 0x0); + + return 0; +} diff --git a/tests/tcg/ppc64/signal_save_restore_xer.c b/tests/tcg/ppc64/signal_save_restore_xer.c new file mode 100644 index 0000000000..9227f4f455 --- /dev/null +++ b/tests/tcg/ppc64/signal_save_restore_xer.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +#define XER_SO (1 << 31) +#define XER_OV (1 << 30) +#define XER_CA (1 << 29) +#define XER_OV32 (1 << 19) +#define XER_CA32 (1 << 18) + +uint64_t saved; + +void sigtrap_handler(int sig, siginfo_t *si, void *ucontext) +{ + ucontext_t *uc = ucontext; + uc->uc_mcontext.regs->nip += 4; + saved = uc->uc_mcontext.regs->xer; + uc->uc_mcontext.regs->xer |= XER_OV | XER_OV32; +} + +int main(void) +{ + uint64_t initial = XER_CA | XER_CA32, restored; + struct sigaction sa = { + .sa_sigaction = sigtrap_handler, + .sa_flags = SA_SIGINFO + }; + + sigaction(SIGTRAP, &sa, NULL); + + asm("mtspr 1, %1\n\t" + "trap\n\t" + "mfspr %0, 1\n\t" + : "=r" (restored) + : "r" (initial)); + + assert(saved == initial); + assert(restored == (XER_OV | XER_OV32 | XER_CA | XER_CA32)); + + return 0; +} diff --git a/tests/tcg/ppc64/xxspltw.c b/tests/tcg/ppc64/xxspltw.c new file mode 100644 index 0000000000..4cff78bfdc --- /dev/null +++ b/tests/tcg/ppc64/xxspltw.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +#define WORD_A 0xAAAAAAAAUL +#define WORD_B 0xBBBBBBBBUL +#define WORD_C 0xCCCCCCCCUL +#define WORD_D 0xDDDDDDDDUL + +#define DWORD_HI (WORD_A << 32 | WORD_B) +#define DWORD_LO (WORD_C << 32 | WORD_D) + +#define TEST(HI, LO, UIM, RES) \ + do { \ + union { \ + uint64_t u; \ + double f; \ + } h = { .u = HI }, l = { .u = LO }; \ + /* \ + * Use a pair of FPRs to load the VSR avoiding insns \ + * newer than xxswapd. \ + */ \ + asm("xxmrghd 32, %0, %1\n\t" \ + "xxspltw 32, 32, %2\n\t" \ + "xxmrghd %0, 32, %0\n\t" \ + "xxswapd 32, 32\n\t" \ + "xxmrghd %1, 32, %1\n\t" \ + : "+f" (h.f), "+f" (l.f) \ + : "i" (UIM) \ + : "v0"); \ + printf("xxspltw(0x%016" PRIx64 "%016" PRIx64 ", %d) =" \ + " %016" PRIx64 "%016" PRIx64 "\n", HI, LO, UIM, \ + h.u, l.u); \ + assert(h.u == (RES)); \ + assert(l.u == (RES)); \ + } while (0) + +int main(void) +{ + TEST(DWORD_HI, DWORD_LO, 0, WORD_A << 32 | WORD_A); + TEST(DWORD_HI, DWORD_LO, 1, WORD_B << 32 | WORD_B); + TEST(DWORD_HI, DWORD_LO, 2, WORD_C << 32 | WORD_C); + TEST(DWORD_HI, DWORD_LO, 3, WORD_D << 32 | WORD_D); + return 0; +} diff --git a/tests/tcg/ppc64le/Makefile.target b/tests/tcg/ppc64le/Makefile.target index 6ca3003f02..daad5118a5 100644 --- a/tests/tcg/ppc64le/Makefile.target +++ b/tests/tcg/ppc64le/Makefile.target @@ -4,28 +4,4 @@ VPATH += $(SRC_PATH)/tests/tcg/ppc64le -ifneq ($(CROSS_CC_HAS_POWER8_VECTOR),) -PPC64LE_TESTS=bcdsub non_signalling_xscv -endif -$(PPC64LE_TESTS): CFLAGS += -mpower8-vector - -ifneq ($(CROSS_CC_HAS_POWER10),) -PPC64LE_TESTS += byte_reverse sha512-vector -endif -byte_reverse: CFLAGS += -mcpu=power10 -run-byte_reverse: QEMU_OPTS+=-cpu POWER10 -run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 - -sha512-vector: CFLAGS +=-mcpu=power10 -O3 -sha512-vector: sha512.c - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) - -run-sha512-vector: QEMU_OPTS+=-cpu POWER10 -run-plugin-sha512-vector-with-%: QEMU_OPTS+=-cpu POWER10 - -PPC64LE_TESTS += mtfsf -PPC64LE_TESTS += mffsce -PPC64LE_TESTS += signal_save_restore_xer -PPC64LE_TESTS += xxspltw - -TESTS += $(PPC64LE_TESTS) +include $(SRC_PATH)/tests/tcg/ppc64/Makefile.target diff --git a/tests/tcg/ppc64le/bcdsub.c b/tests/tcg/ppc64le/bcdsub.c deleted file mode 100644 index 87c8c44a44..0000000000 --- a/tests/tcg/ppc64le/bcdsub.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include -#include - -#define CRF_LT (1 << 3) -#define CRF_GT (1 << 2) -#define CRF_EQ (1 << 1) -#define CRF_SO (1 << 0) -#define UNDEF 0 - -#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) - -/* - * Unbounded result is equal to zero: - * sign = (PS) ? 0b1111 : 0b1100 - * CR6 = 0b0010 - */ -void test_bcdsub_eq(void) -{ - /* maximum positive BCD value */ - TEST(0x9999999999999999, 0x999999999999999c, - 0x9999999999999999, 0x999999999999999c, - 0, 0x0, 0xc, CRF_EQ); - TEST(0x9999999999999999, 0x999999999999999c, - 0x9999999999999999, 0x999999999999999c, - 1, 0x0, 0xf, CRF_EQ); -} - -/* - * Unbounded result is greater than zero: - * sign = (PS) ? 0b1111 : 0b1100 - * CR6 = (overflow) ? 0b0101 : 0b0100 - */ -void test_bcdsub_gt(void) -{ - /* 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); -} - -/* - * Unbounded result is less than zero: - * sign = 0b1101 - * CR6 = (overflow) ? 0b1001 : 0b1000 - */ -void test_bcdsub_lt(void) -{ - /* 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) -{ - TEST(0x0, 0x1c, 0x0, 0xf00, 0, UNDEF, UNDEF, CRF_SO); - TEST(0x0, 0x1c, 0x0, 0xf00, 1, UNDEF, UNDEF, CRF_SO); - - TEST(0x0, 0xf00, 0x0, 0x1c, 0, UNDEF, UNDEF, CRF_SO); - TEST(0x0, 0xf00, 0x0, 0x1c, 1, UNDEF, 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) -{ - struct sigaction action; - - action.sa_handler = _exit; - sigaction(SIGABRT, &action, NULL); - - test_bcdsub_eq(); - test_bcdsub_gt(); - test_bcdsub_lt(); - test_bcdsub_invalid(); - - return 0; -} diff --git a/tests/tcg/ppc64le/byte_reverse.c b/tests/tcg/ppc64le/byte_reverse.c deleted file mode 100644 index 53b76fc2e2..0000000000 --- a/tests/tcg/ppc64le/byte_reverse.c +++ /dev/null @@ -1,21 +0,0 @@ -#include - -int main(void) -{ - unsigned long var; - - var = 0xFEDCBA9876543210; - asm("brh %0, %0" : "+r"(var)); - assert(var == 0xDCFE98BA54761032); - - var = 0xFEDCBA9876543210; - asm("brw %0, %0" : "+r"(var)); - assert(var == 0x98BADCFE10325476); - - var = 0xFEDCBA9876543210; - asm("brd %0, %0" : "+r"(var)); - assert(var == 0x1032547698BADCFE); - - return 0; -} - diff --git a/tests/tcg/ppc64le/mffsce.c b/tests/tcg/ppc64le/mffsce.c deleted file mode 100644 index 20d882cb45..0000000000 --- a/tests/tcg/ppc64le/mffsce.c +++ /dev/null @@ -1,37 +0,0 @@ -#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 MFFSCE(FRT) asm("mffsce %0" : "=f" (FRT)) - -#define PPC_BIT_NR(nr) (63 - (nr)) - -#define FP_VE (1ull << PPC_BIT_NR(56)) -#define FP_UE (1ull << PPC_BIT_NR(58)) -#define FP_ZE (1ull << PPC_BIT_NR(59)) -#define FP_XE (1ull << PPC_BIT_NR(60)) -#define FP_NI (1ull << PPC_BIT_NR(61)) -#define FP_RN1 (1ull << PPC_BIT_NR(63)) - -int main(void) -{ - uint64_t frt, fpscr; - uint64_t test_value = FP_VE | FP_UE | FP_ZE | - FP_XE | FP_NI | FP_RN1; - MTFSF(0b11111111, test_value); /* set test value to cpu fpscr */ - MFFSCE(frt); - MFFS(fpscr); /* read the value that mffsce stored to cpu fpscr */ - - /* the returned value should be as the cpu fpscr was before */ - assert((frt & 0xff) == test_value); - - /* - * the cpu fpscr last 3 bits should be unchanged - * and enable bits should be unset - */ - assert((fpscr & 0xff) == (test_value & 0x7)); - - return 0; -} diff --git a/tests/tcg/ppc64le/mtfsf.c b/tests/tcg/ppc64le/mtfsf.c deleted file mode 100644 index bed5b1afa4..0000000000 --- a/tests/tcg/ppc64le/mtfsf.c +++ /dev/null @@ -1,60 +0,0 @@ -#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 */ - -#define FP_VE (1ull << FPSCR_VE) -#define FP_VXSOFT (1ull << FPSCR_VXSOFT) -#define FP_FI (1ull << FPSCR_FI) - -void sigfpe_handler(int sig, siginfo_t *si, void *ucontext) -{ - if (si->si_code == FPE_FLTINV) { - exit(0); - } - exit(1); -} - -int main(void) -{ - uint64_t fpscr; - - struct sigaction sa = { - .sa_sigaction = sigfpe_handler, - .sa_flags = SA_SIGINFO - }; - - /* - * Enable the MSR bits F0 and F1 to enable exceptions. - * This shouldn't be needed in linux-user as these bits are enabled by - * default, but this allows to execute either in a VM or a real machine - * to compare the behaviors. - */ - prctl(PR_SET_FPEXC, PR_FP_EXC_PRECISE); - - /* First test if the FI bit is being set correctly */ - 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); - - /* - * Although the VXSOFT exception has been chosen, based on test in a Power9 - * any combination of exception bit + its enabling bit should work. - * But if a different exception is chosen si_code check should - * change accordingly. - */ - MTFSF(0b11111111, FP_VE | FP_VXSOFT); - - return 1; -} diff --git a/tests/tcg/ppc64le/non_signalling_xscv.c b/tests/tcg/ppc64le/non_signalling_xscv.c deleted file mode 100644 index 836df71ef0..0000000000 --- a/tests/tcg/ppc64le/non_signalling_xscv.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include - -#define TEST(INSN, B_HI, B_LO, T_HI, T_LO) \ - do { \ - uint64_t th, tl, bh = B_HI, bl = B_LO; \ - 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) \ - : "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); \ - } while (0) - -int main(void) -{ - /* SNaN shouldn't be silenced */ - TEST("xscvspdpn", 0x7fbfffff00000000ULL, 0x0, 0x7ff7ffffe0000000ULL, 0x0); - TEST("xscvdpspn", 0x7ff7ffffffffffffULL, 0x0, 0x7fbfffff7fbfffffULL, 0x0); - - /* - * SNaN inputs having no significant bits in the upper 23 bits of the - * signifcand will return Infinity as the result. - */ - TEST("xscvdpspn", 0x7ff000001fffffffULL, 0x0, 0x7f8000007f800000ULL, 0x0); - - return 0; -} diff --git a/tests/tcg/ppc64le/signal_save_restore_xer.c b/tests/tcg/ppc64le/signal_save_restore_xer.c deleted file mode 100644 index 9227f4f455..0000000000 --- a/tests/tcg/ppc64le/signal_save_restore_xer.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include - -#define XER_SO (1 << 31) -#define XER_OV (1 << 30) -#define XER_CA (1 << 29) -#define XER_OV32 (1 << 19) -#define XER_CA32 (1 << 18) - -uint64_t saved; - -void sigtrap_handler(int sig, siginfo_t *si, void *ucontext) -{ - ucontext_t *uc = ucontext; - uc->uc_mcontext.regs->nip += 4; - saved = uc->uc_mcontext.regs->xer; - uc->uc_mcontext.regs->xer |= XER_OV | XER_OV32; -} - -int main(void) -{ - uint64_t initial = XER_CA | XER_CA32, restored; - struct sigaction sa = { - .sa_sigaction = sigtrap_handler, - .sa_flags = SA_SIGINFO - }; - - sigaction(SIGTRAP, &sa, NULL); - - asm("mtspr 1, %1\n\t" - "trap\n\t" - "mfspr %0, 1\n\t" - : "=r" (restored) - : "r" (initial)); - - assert(saved == initial); - assert(restored == (XER_OV | XER_OV32 | XER_CA | XER_CA32)); - - return 0; -} diff --git a/tests/tcg/ppc64le/xxspltw.c b/tests/tcg/ppc64le/xxspltw.c deleted file mode 100644 index 4cff78bfdc..0000000000 --- a/tests/tcg/ppc64le/xxspltw.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include - -#define WORD_A 0xAAAAAAAAUL -#define WORD_B 0xBBBBBBBBUL -#define WORD_C 0xCCCCCCCCUL -#define WORD_D 0xDDDDDDDDUL - -#define DWORD_HI (WORD_A << 32 | WORD_B) -#define DWORD_LO (WORD_C << 32 | WORD_D) - -#define TEST(HI, LO, UIM, RES) \ - do { \ - union { \ - uint64_t u; \ - double f; \ - } h = { .u = HI }, l = { .u = LO }; \ - /* \ - * Use a pair of FPRs to load the VSR avoiding insns \ - * newer than xxswapd. \ - */ \ - asm("xxmrghd 32, %0, %1\n\t" \ - "xxspltw 32, 32, %2\n\t" \ - "xxmrghd %0, 32, %0\n\t" \ - "xxswapd 32, 32\n\t" \ - "xxmrghd %1, 32, %1\n\t" \ - : "+f" (h.f), "+f" (l.f) \ - : "i" (UIM) \ - : "v0"); \ - printf("xxspltw(0x%016" PRIx64 "%016" PRIx64 ", %d) =" \ - " %016" PRIx64 "%016" PRIx64 "\n", HI, LO, UIM, \ - h.u, l.u); \ - assert(h.u == (RES)); \ - assert(l.u == (RES)); \ - } while (0) - -int main(void) -{ - TEST(DWORD_HI, DWORD_LO, 0, WORD_A << 32 | WORD_A); - TEST(DWORD_HI, DWORD_LO, 1, WORD_B << 32 | WORD_B); - TEST(DWORD_HI, DWORD_LO, 2, WORD_C << 32 | WORD_C); - TEST(DWORD_HI, DWORD_LO, 3, WORD_D << 32 | WORD_D); - return 0; -}