From 5ab57a757adab29dc08cf3a6da863877ee5e87db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Thu, 20 Jan 2022 12:40:54 -0300 Subject: [PATCH 1/3] tests/tcg/ppc64[le]: add tests for xs{max,min}cqp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo --- tests/tcg/ppc64/Makefile.target | 14 ++++++-- tests/tcg/ppc64le/Makefile.target | 6 +++- tests/tcg/ppc64le/xsmaxmincqp.c | 59 +++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 tests/tcg/ppc64le/xsmaxmincqp.c diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target index 0368007028c9a..bb1ef24980887 100644 --- a/tests/tcg/ppc64/Makefile.target +++ b/tests/tcg/ppc64/Makefile.target @@ -10,12 +10,22 @@ PPC64_TESTS=bcdsub non_signalling_xscv endif $(PPC64_TESTS): CFLAGS += -mpower8-vector -PPC64_TESTS += byte_reverse -PPC64_TESTS += mtfsf +PPC64_TESTS += byte_reverse mtfsf xsmaxmincqp ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),) +xsmaxmincqp: CFLAGS += -mcpu=power10 +run-xsmaxmincqp: QEMU_OPTS += -cpu POWER10 +run-plugin-xsmaxmincqp-with-%: QEMU_OPTS += -cpu POWER10 + run-byte_reverse: QEMU_OPTS+=-cpu POWER10 run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 else +xsmaxmincqp: + $(call skip-test, "BUILD of $@", "missing compiler support") +run-xsmaxmincqp: + $(call skip-test, "RUN of xsmaxmincqp", "not built") +run-plugin-xsmaxmincqp-with-%: + $(call skip-test, "RUN of xsmaxmincqp ($*)", "not built") + byte_reverse: $(call skip-test, "BUILD of $@", "missing compiler support") run-byte_reverse: diff --git a/tests/tcg/ppc64le/Makefile.target b/tests/tcg/ppc64le/Makefile.target index 480ff0898d7ea..51f7801ca22e2 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 xsmaxmincqp endif byte_reverse: CFLAGS += -mcpu=power10 run-byte_reverse: QEMU_OPTS+=-cpu POWER10 run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 +xsmaxmincqp: CFLAGS += -mcpu=power10 +run-xsmaxmincqp: QEMU_OPTS += -cpu POWER10 +run-plugin-xsmaxmincqp-with-%: QEMU_OPTS += -cpu POWER10 + PPC64LE_TESTS += mtfsf PPC64LE_TESTS += signal_save_restore_xer diff --git a/tests/tcg/ppc64le/xsmaxmincqp.c b/tests/tcg/ppc64le/xsmaxmincqp.c new file mode 100644 index 0000000000000..6bd394180360e --- /dev/null +++ b/tests/tcg/ppc64le/xsmaxmincqp.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include + +#define XSTR(x) #x +#define STR(x) XSTR(x) +#define I128(a, b) ((__int128)(a) << 64 | (b)) +#define MAX128(a, b) (a > b ? a : b) +#define MIN128(a, b) (a < b ? a : b) + +#define TEST(INSN, H1, L1, H2, L2, EXP) \ + do { \ + __uint128_t a = I128(H1, L1); \ + __uint128_t b = I128(H2, L2); \ + __uint128_t t; \ + \ + asm(INSN " %0, %1, %2\n\t" : "=v"(t) : "v"(a), "v"(b)); \ + \ + assert(t == EXP); \ + } while (0) + +#define TEST_NAN(H1, L1, H2, L2) \ + do { \ + /* If any of the input is NaN, VRT <- VRB */ \ + TEST("xsmaxcqp", H1, L1, H2, L2, I128(H2, L2)); \ + TEST("xsmaxcqp", H2, L2, H1, L1, I128(H1, L1)); \ + TEST("xsmincqp", H1, L1, H2, L2, I128(H2, L2)); \ + TEST("xsmincqp", H2, L2, H1, L1, I128(H1, L1)); \ + } while (0) + +#define TEST_GENERAL_CASE(H1, L1, H2, L2) \ + do { \ + TEST("xsmaxcqp", H1, L1, H2, L2, MAX128(I128(H1, L1), I128(H2, L2))); \ + TEST("xsmaxcqp", H1, L1, H2, L2, MAX128(I128(H1, L1), I128(H2, L2))); \ + TEST("xsmincqp", H2, L2, H1, L1, MIN128(I128(H1, L1), I128(H2, L2))); \ + TEST("xsmincqp", H2, L2, H1, L1, MIN128(I128(H1, L1), I128(H2, L2))); \ + } while (0) + +int main(void) +{ + struct sigaction action; + + action.sa_handler = _exit; + sigaction(SIGABRT, &action, NULL); + + TEST_NAN(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0x0ULL, 0X0ULL); + TEST_NAN(0xDEADC0DEULL, 0x0ULL, 0x7FFF000000000000ULL, 0x1ULL); + + TEST_GENERAL_CASE(0x000087810000E078ULL, 0x0006E3C8000438F5ULL, + 0x000B48600003780FULL, 0x00C304E00069660ULL); + TEST_GENERAL_CASE(0x0ULL, 0xF3C0C1FC8F3230ULL, 0x0ULL, 0xBEAAB9C5ULL); + TEST_GENERAL_CASE(0xC0583916EA04ULL, 0xB11DCFB3C40C58E9ULL, + 0x32BB5C6435F8ULL, 0x3CDABBEC03DD171BULL); + TEST_GENERAL_CASE(0xDEADC0DEULL, 0x0ULL, 0x7FF8000000000000ULL, 0x1ULL); + + return 0; +} From 556363b6abd7e4e004f36dc3511e2c5e361b0349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Fri, 21 Jan 2022 09:43:47 -0300 Subject: [PATCH 2/3] target/ppc: Make xs{max,min}[cj]dp return zero on second doubleword MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change xs{max,min}[cj]dp behavior to be closer to hardware and most recent ISAs by initializing the result with zeros instead of returning undefined values. Signed-off-by: Víctor Colombo --- target/ppc/fpu_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index f83a80e6852e8..20957f2340463 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2540,7 +2540,7 @@ VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i)) void helper_##name(CPUPPCState *env, \ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \ { \ - ppc_vsr_t t = *xt; \ + ppc_vsr_t t = { }; \ bool vxsnan_flag = false, vex_flag = false; \ \ if (unlikely(tp##_is_any_nan(xa->fld) || \ @@ -2572,7 +2572,7 @@ VSX_MAX_MINC(XSMINCQP, minnum, float128, f128); void helper_##name(CPUPPCState *env, \ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \ { \ - ppc_vsr_t t = *xt; \ + ppc_vsr_t t = { }; \ bool vxsnan_flag = false, vex_flag = false; \ \ if (unlikely(float64_is_any_nan(xa->VsrD(0)))) { \ From dbd5219c565f77686548d67be168b1f4bf0e6605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Fri, 21 Jan 2022 09:33:17 -0300 Subject: [PATCH 3/3] tests/tcg/ppc64[le]: Add tests for xs{max,min}[cj]dp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo --- tests/tcg/ppc64/Makefile.target | 6 ++- tests/tcg/ppc64le/Makefile.target | 6 ++- tests/tcg/ppc64le/xsmaxmincjdp.c | 83 +++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 tests/tcg/ppc64le/xsmaxmincjdp.c diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target index bb1ef24980887..c832eadbc4a45 100644 --- a/tests/tcg/ppc64/Makefile.target +++ b/tests/tcg/ppc64/Makefile.target @@ -10,12 +10,16 @@ PPC64_TESTS=bcdsub non_signalling_xscv endif $(PPC64_TESTS): CFLAGS += -mpower8-vector -PPC64_TESTS += byte_reverse mtfsf xsmaxmincqp +PPC64_TESTS += byte_reverse mtfsf xsmaxmincqp xsmaxmincjdp ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),) xsmaxmincqp: CFLAGS += -mcpu=power10 run-xsmaxmincqp: QEMU_OPTS += -cpu POWER10 run-plugin-xsmaxmincqp-with-%: QEMU_OPTS += -cpu POWER10 +xsmaxmincjdp: CFLAGS += -mcpu=power10 +run-xsmaxmincjdp: QEMU_OPTS += -cpu POWER10 +run-plugin-xsmaxmincjdp-with-%: QEMU_OPTS += -cpu POWER10 + run-byte_reverse: QEMU_OPTS+=-cpu POWER10 run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 else diff --git a/tests/tcg/ppc64le/Makefile.target b/tests/tcg/ppc64le/Makefile.target index 51f7801ca22e2..497897aeca5db 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 xsmaxmincqp +PPC64LE_TESTS += byte_reverse xsmaxmincqp xsmaxmincjdp endif byte_reverse: CFLAGS += -mcpu=power10 run-byte_reverse: QEMU_OPTS+=-cpu POWER10 run-plugin-byte_reverse-with-%: QEMU_OPTS+=-cpu POWER10 +xsmaxmincjdp: CFLAGS += -mcpu=power10 +run-xsmaxmincjdp: QEMU_OPTS += -cpu POWER10 +run-plugin-xsmaxmincjdp-with-%: QEMU_OPTS += -cpu POWER10 + xsmaxmincqp: CFLAGS += -mcpu=power10 run-xsmaxmincqp: QEMU_OPTS += -cpu POWER10 run-plugin-xsmaxmincqp-with-%: QEMU_OPTS += -cpu POWER10 diff --git a/tests/tcg/ppc64le/xsmaxmincjdp.c b/tests/tcg/ppc64le/xsmaxmincjdp.c new file mode 100644 index 0000000000000..66cd8e751f2a2 --- /dev/null +++ b/tests/tcg/ppc64le/xsmaxmincjdp.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +#define XSTR(x) #x +#define STR(x) XSTR(x) +#define I128(a, b) ((__int128)(a) << 64 | (b)) + +#define TEST(INSN, A, B, EXP) \ + do { \ + __uint128_t a = I128(A, 0); \ + __uint128_t b = I128(B, 0); \ + __uint128_t t; \ + \ + asm(INSN " %0, %1, %2\n\t" : "=wa"(t) : "wa"(a), "wa"(b)); \ + \ + assert(t == I128(EXP, 0)); \ + } while (0) + +static inline void test_nan() +{ + TEST("xsmaxcdp", 0x42ULL, 0x7FF0000000000001ULL, 0x7FF0000000000001ULL); + TEST("xsmaxcdp", 0x7FF0000000000001ULL, 0x42ULL, 0x42ULL); + + TEST("xsmaxcdp", 0x42ULL, 0x7FFF000000000000ULL, 0x7FFF000000000000ULL); + TEST("xsmaxcdp", 0x7FFF000000000000ULL, 0x42ULL, 0x42ULL); + + TEST("xsmaxcdp", 0x42ULL, 0x7FF8000000000000ULL, 0x7FF8000000000000ULL); + TEST("xsmaxcdp", 0x7FF8000000000000ULL, 0x42ULL, 0x42ULL); + + TEST("xsmincdp", 0x42ULL, 0x7FF0000000000001ULL, 0x7FF0000000000001ULL); + TEST("xsmincdp", 0x7FF0000000000001ULL, 0x42ULL, 0x42ULL); + + TEST("xsmincdp", 0x42ULL, 0x7FFF000000000000ULL, 0x7FFF000000000000ULL); + TEST("xsmincdp", 0x7FFF000000000000ULL, 0x42ULL, 0x42ULL); + + TEST("xsmincdp", 0x42ULL, 0x7FF8000000000000ULL, 0x7FF8000000000000ULL); + TEST("xsmincdp", 0x7FF8000000000000ULL, 0x42ULL, 0x42ULL); + + TEST("xsmaxjdp", 0x42ULL, 0x7FF0000000000001ULL, 0x7FF0000000000001ULL); + TEST("xsmaxjdp", 0x7FF0000000000001ULL, 0x42ULL, 0x7FF0000000000001ULL); + TEST("xsmaxjdp", 0x7FF8000000000000ULL, 0x7FF0000000000001ULL, + 0x7FF8000000000000ULL); + TEST("xsmaxjdp", 0x7FF0000000000001ULL, 0x7FF8000000000000ULL, + 0x7FF0000000000001ULL); + + TEST("xsminjdp", 0x42ULL, 0x7FF0000000000001ULL, 0x7FF0000000000001ULL); + TEST("xsminjdp", 0x7FF0000000000001ULL, 0x42ULL, 0x7FF0000000000001ULL); + TEST("xsminjdp", 0x7FF8000000000000ULL, 0x7FF0000000000001ULL, + 0x7FF8000000000000ULL); + TEST("xsminjdp", 0x7FF0000000000001ULL, 0x7FF8000000000000ULL, + 0x7FF0000000000001ULL); +} + +static inline void test_general_case() +{ + TEST("xsmaxcdp", 0xad53f789, 0xbeaab9c5, 0xbeaab9c5); + TEST("xsmaxcdp", 0x8600dd9ea0, 0x4b9f8cffd7, 0x8600dd9ea0); + + TEST("xsmincdp", 0xad53f789, 0xbeaab9c5, 0xad53f789); + TEST("xsmincdp", 0x8600dd9ea0, 0x4b9f8cffd7, 0x4b9f8cffd7); + + TEST("xsmaxjdp", 0xad53f789, 0xbeaab9c5, 0xbeaab9c5); + TEST("xsmaxjdp", 0x8600dd9ea0, 0x4b9f8cffd7, 0x8600dd9ea0); + + TEST("xsminjdp", 0xad53f789, 0xbeaab9c5, 0xad53f789); + TEST("xsminjdp", 0x8600dd9ea0, 0x4b9f8cffd7, 0x4b9f8cffd7); +} + +int main(void) +{ + struct sigaction action; + + action.sa_handler = _exit; + sigaction(SIGABRT, &action, NULL); + + test_nan(); + test_general_case(); + + return 0; +}