diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target index 0368007028c9a..758e9ddb66bd9 100644 --- a/tests/tcg/ppc64/Makefile.target +++ b/tests/tcg/ppc64/Makefile.target @@ -10,11 +10,13 @@ PPC64_TESTS=bcdsub non_signalling_xscv endif $(PPC64_TESTS): CFLAGS += -mpower8-vector -PPC64_TESTS += byte_reverse -PPC64_TESTS += mtfsf +PPC64_TESTS += byte_reverse mtfsf xscmp ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),) run-byte_reverse: QEMU_OPTS+=-cpu POWER10 run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 + +run-xscmp: QEMU_OPTS+=-cpu POWER10 +run-plugin-xscmp-with-%: QEMU_OPTS+=-cpu POWER10 else byte_reverse: $(call skip-test, "BUILD of $@", "missing compiler support") @@ -22,6 +24,13 @@ run-byte_reverse: $(call skip-test, "RUN of byte_reverse", "not built") run-plugin-byte_reverse-with-%: $(call skip-test, "RUN of byte_reverse ($*)", "not built") + +xscmp: + $(call skip-test, "BUILD of $@", "missing compiler support") +run-xscmp: + $(call skip-test, "RUN of xscmp", "not built") +run-plugin-xscmp-with-%: + $(call skip-test, "RUN of xscmp ($*)", "not built") endif PPC64_TESTS += signal_save_restore_xer diff --git a/tests/tcg/ppc64le/Makefile.target b/tests/tcg/ppc64le/Makefile.target index 480ff0898d7ea..1091cca8a5a60 100644 --- a/tests/tcg/ppc64le/Makefile.target +++ b/tests/tcg/ppc64le/Makefile.target @@ -10,12 +10,16 @@ endif $(PPC64LE_TESTS): CFLAGS += -mpower8-vector ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),) -PPC64LE_TESTS += byte_reverse +PPC64LE_TESTS += byte_reverse xscmp endif byte_reverse: CFLAGS += -mcpu=power10 run-byte_reverse: QEMU_OPTS+=-cpu POWER10 run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 +xscmp: CFLAGS += -mcpu=power10 +run-xscmp: QEMU_OPTS+=-cpu POWER10 +run-plugin-xscmp-with-%: QEMU_OPTS+=-cpu POWER10 + PPC64LE_TESTS += mtfsf PPC64LE_TESTS += signal_save_restore_xer diff --git a/tests/tcg/ppc64le/xscmp.c b/tests/tcg/ppc64le/xscmp.c new file mode 100644 index 0000000000000..a9f57e6a4bb89 --- /dev/null +++ b/tests/tcg/ppc64le/xscmp.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include + +#define I128(a, b) ((__int128)(a) << 64 | (b)) + +#define TEST_QP(INSN, A, B, EXP) \ + do { \ + __uint128_t a = A, b = B; \ + __uint128_t t; \ + \ + asm(INSN " %0, %1, %2" : "=v"(t) : "v"(a), "v"(b)); \ + \ + assert(t == EXP); \ + } while (0) + +#define TEST_DP(INSN, A, B, EXP) \ + do { \ + __uint128_t a = A, b = B; \ + __uint128_t t; \ + \ + asm(INSN " %0, %1, %2" : "=wa"(t) : "wa"(a), "wa"(b)); \ + \ + assert(t == EXP); \ + } while (0) + +static inline void test_eq(void) +{ + /* TODO: test exceptions and flags */ + TEST_QP("xscmpeqqp", I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0x0, 0x0)); + TEST_QP("xscmpeqqp", I128(0x3F9DF3B612341234ULL, 0x5678123999999999ULL), + I128(0x3F9DF3B612341234ULL, 0x5678123999999999ULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL)); + TEST_QP("xscmpeqqp", I128(0x1ULL, 0x0), + I128(0x2ULL, 0x0), + I128(0x0, 0x0)); + + TEST_DP("xscmpeqdp", I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0x0, 0x0)); + TEST_DP("xscmpeqdp", I128(0x3F9DF3B612341234ULL, 0x1234ULL), + I128(0x3F9DF3B612341234ULL, 0x5678ULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0x0)); + TEST_DP("xscmpeqdp", I128(0x1ULL, 0x0), + I128(0x2ULL, 0x0), + I128(0x0, 0x0)); +} + +static inline void test_ge(void) +{ + /* TODO: test exceptions and flags */ + TEST_QP("xscmpgeqp", I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0x0, 0x0)); + TEST_QP("xscmpgeqp", I128(0x3F9DF3B612341234ULL, 0x5678123999999999ULL), + I128(0x3F9DF3B612341234ULL, 0x5678123999999999ULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL)); + TEST_QP("xscmpgeqp", I128(0x0, 0x2), + I128(0x0, 0x1), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL)); + + TEST_DP("xscmpgedp", I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0x0, 0x0)); + TEST_DP("xscmpgedp", I128(0x3F9DF3B612341234ULL, 0x1234ULL), + I128(0x3F9DF3B612341234ULL, 0x5678ULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0x0)); + TEST_DP("xscmpgedp", I128(0x2, 0x0), + I128(0x1, 0x0), + I128(0xFFFFFFFFFFFFFFFFULL, 0x0)); + TEST_DP("xscmpgedp", I128(0x1, 0x2), + I128(0x1, 0x1), + I128(0xFFFFFFFFFFFFFFFFULL, 0x0)); +} + +static inline void test_gt(void) +{ + /* TODO: test exceptions and flags */ + TEST_QP("xscmpgtqp", I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0x0, 0x0)); + TEST_QP("xscmpgtqp", I128(0x3F9DF3B612341234ULL, 0x5678123999999999ULL), + I128(0x3F9DF3B612341234ULL, 0x5678123999999999ULL), + I128(0x0, 0x0)); + TEST_QP("xscmpgtqp", I128(0x0, 0x2), + I128(0x0, 0x1), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL)); + + TEST_DP("xscmpgtdp", I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL), + I128(0x0, 0x0)); + TEST_DP("xscmpgtdp", I128(0x3F9DF3B612341234ULL, 0x1234ULL), + I128(0x3F9DF3B612341234ULL, 0x5678ULL), + I128(0x0, 0x0)); + TEST_DP("xscmpgtdp", I128(0x2, 0x0), + I128(0x1, 0x0), + I128(0xFFFFFFFFFFFFFFFFULL, 0x0)); + TEST_DP("xscmpgtdp", I128(0x1, 0x2), + I128(0x1, 0x1), + I128(0x0, 0x0)); +} + +int main(void) +{ + struct sigaction action; + + action.sa_handler = _exit; + sigaction(SIGABRT, &action, NULL); + + test_eq(); + test_ge(); + test_gt(); + + return 0; +}