From: Matheus Ferst <matheus.ferst@eldorado.org.br>
LLVM/Clang doesn't like inline asm with __int128, use a vector type
instead.
Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
Alternatively, we could pass VSR values in GPR pairs, as we did in
tests/tcg/ppc64le/non_signalling_xscv.c
---
tests/tcg/ppc64le/bcdsub.c | 92 +++++++++++++++++++++-----------------
1 file changed, 52 insertions(+), 40 deletions(-)
diff --git a/tests/tcg/ppc64le/bcdsub.c b/tests/tcg/ppc64le/bcdsub.c
index 8c188cae6d..17403daf22 100644
--- a/tests/tcg/ppc64le/bcdsub.c
+++ b/tests/tcg/ppc64le/bcdsub.c
@@ -1,6 +1,7 @@
#include <assert.h>
#include <unistd.h>
#include <signal.h>
+#include <altivec.h>
#define CRF_LT (1 << 3)
#define CRF_GT (1 << 2)
@@ -8,6 +9,16 @@
#define CRF_SO (1 << 0)
#define UNDEF 0
+#ifdef __LITTLE_ENDIAN__
+#define HIGH(T) (T)[1]
+#define LOW(T) (T)[0]
+#define U128(H, L) (vector unsigned long long) {L, H}
+#else
+#define HIGH(T) (T)[0]
+#define LOW(T) (T)[1]
+#define U128(H, L) (vector unsigned long long) {H, L}
+#endif
+
#define BCDSUB(vra, vrb, ps) \
asm ("bcdsub. %1,%2,%3,%4;" \
"mfocrf %0,0b10;" \
@@ -15,17 +26,18 @@
: "v" (vra), "v" (vrb), "i" (ps) \
: );
-#define TEST(vra, vrb, ps, exp_res, exp_cr6) \
- do { \
- __int128 vrt = 0; \
- int cr = 0; \
- BCDSUB(vra, vrb, ps); \
- if (exp_res) \
- assert(vrt == exp_res); \
- assert((cr >> 4) == exp_cr6); \
+#define TEST(vra, vrb, ps, exp_res_h, exp_res_l, exp_cr6) \
+ do { \
+ vector unsigned long long vrt = U128(0, 0); \
+ int cr = 0; \
+ BCDSUB(vra, vrb, ps); \
+ if (exp_res_h || exp_res_l) { \
+ assert(HIGH(vrt) == exp_res_h); \
+ assert(LOW(vrt) == exp_res_l); \
+ } \
+ assert((cr >> 4) == exp_cr6); \
} while (0)
-
/*
* Unbounded result is equal to zero:
* sign = (PS) ? 0b1111 : 0b1100
@@ -33,13 +45,13 @@
*/
void test_bcdsub_eq(void)
{
- __int128 a, b;
+ vector unsigned long long a, b;
/* maximum positive BCD value */
- a = b = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999c);
+ a = b = U128(0x9999999999999999, 0x999999999999999c);
- TEST(a, b, 0, 0xc, CRF_EQ);
- TEST(a, b, 1, 0xf, CRF_EQ);
+ TEST(a, b, 0, 0x0, 0xc, CRF_EQ);
+ TEST(a, b, 1, 0x0, 0xf, CRF_EQ);
}
/*
@@ -49,21 +61,21 @@ void test_bcdsub_eq(void)
*/
void test_bcdsub_gt(void)
{
- __int128 a, b, c;
+ vector unsigned long long a, b, c;
/* maximum positive BCD value */
- a = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999c);
+ a = U128(0x9999999999999999, 0x999999999999999c);
/* negative one BCD value */
- b = (__int128) 0x1d;
+ b = U128(0x0, 0x1d);
- TEST(a, b, 0, 0xc, (CRF_GT | CRF_SO));
- TEST(a, b, 1, 0xf, (CRF_GT | CRF_SO));
+ TEST(a, b, 0, 0x0, 0xc, (CRF_GT | CRF_SO));
+ TEST(a, b, 1, 0x0, 0xf, (CRF_GT | CRF_SO));
- c = (((__int128) 0x9999999999999999) << 64 | 0x999999999999998c);
+ c = U128(0x9999999999999999, 0x999999999999998c);
- TEST(c, b, 0, a, CRF_GT);
- TEST(c, b, 1, (a | 0x3), CRF_GT);
+ TEST(c, b, 0, HIGH(a), LOW(a), CRF_GT);
+ TEST(c, b, 1, HIGH(a), (LOW(a) | 0x3), CRF_GT);
}
/*
@@ -73,45 +85,45 @@ void test_bcdsub_gt(void)
*/
void test_bcdsub_lt(void)
{
- __int128 a, b;
+ vector unsigned long long a, b;
/* positive zero BCD value */
- a = (__int128) 0xc;
+ a = U128(0x0, 0xc);
/* positive one BCD value */
- b = (__int128) 0x1c;
+ b = U128(0x0, 0x1c);
- TEST(a, b, 0, 0x1d, CRF_LT);
- TEST(a, b, 1, 0x1d, CRF_LT);
+ TEST(a, b, 0, 0x0, 0x1d, CRF_LT);
+ TEST(a, b, 1, 0x0, 0x1d, CRF_LT);
/* maximum negative BCD value */
- a = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999d);
+ a = U128(0x9999999999999999, 0x999999999999999d);
/* positive one BCD value */
- b = (__int128) 0x1c;
+ b = U128(0x0, 0x1c);
- TEST(a, b, 0, 0xd, (CRF_LT | CRF_SO));
- TEST(a, b, 1, 0xd, (CRF_LT | CRF_SO));
+ TEST(a, b, 0, 0x0, 0xd, (CRF_LT | CRF_SO));
+ TEST(a, b, 1, 0x0, 0xd, (CRF_LT | CRF_SO));
}
void test_bcdsub_invalid(void)
{
- __int128 a, b;
+ vector unsigned long long a, b;
/* positive one BCD value */
- a = (__int128) 0x1c;
- b = 0xf00;
+ a = U128(0x0, 0x1c);
+ b = U128(0x0, 0xf00);
- TEST(a, b, 0, UNDEF, CRF_SO);
- TEST(a, b, 1, UNDEF, CRF_SO);
+ TEST(a, b, 0, UNDEF, UNDEF, CRF_SO);
+ TEST(a, b, 1, UNDEF, UNDEF, CRF_SO);
- TEST(b, a, 0, UNDEF, CRF_SO);
- TEST(b, a, 1, UNDEF, CRF_SO);
+ TEST(b, a, 0, UNDEF, UNDEF, CRF_SO);
+ TEST(b, a, 1, UNDEF, UNDEF, CRF_SO);
- a = 0xbad;
+ a = U128(0x0, 0xbad);
- TEST(a, b, 0, UNDEF, CRF_SO);
- TEST(a, b, 1, UNDEF, CRF_SO);
+ TEST(a, b, 0, UNDEF, UNDEF, CRF_SO);
+ TEST(a, b, 1, UNDEF, UNDEF, CRF_SO);
}
int main(void)
--
2.25.1
On 2/8/22 21:31, matheus.ferst@eldorado.org.br wrote:
> From: Matheus Ferst <matheus.ferst@eldorado.org.br>
>
> LLVM/Clang doesn't like inline asm with __int128, use a vector type
> instead.
>
> Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
> ---
> Alternatively, we could pass VSR values in GPR pairs, as we did in
> tests/tcg/ppc64le/non_signalling_xscv.c
> ---
> tests/tcg/ppc64le/bcdsub.c | 92 +++++++++++++++++++++-----------------
> 1 file changed, 52 insertions(+), 40 deletions(-)
>
> diff --git a/tests/tcg/ppc64le/bcdsub.c b/tests/tcg/ppc64le/bcdsub.c
> index 8c188cae6d..17403daf22 100644
> --- a/tests/tcg/ppc64le/bcdsub.c
> +++ b/tests/tcg/ppc64le/bcdsub.c
> @@ -1,6 +1,7 @@
> #include <assert.h>
> #include <unistd.h>
> #include <signal.h>
> +#include <altivec.h>
>
> #define CRF_LT (1 << 3)
> #define CRF_GT (1 << 2)
> @@ -8,6 +9,16 @@
> #define CRF_SO (1 << 0)
> #define UNDEF 0
>
> +#ifdef __LITTLE_ENDIAN__
Shouldn't we be using :
#if BYTE_ORDER == LITTLE_ENDIAN
instead ?
Thanks,
C.
> +#define HIGH(T) (T)[1]
> +#define LOW(T) (T)[0]
> +#define U128(H, L) (vector unsigned long long) {L, H}
> +#else
> +#define HIGH(T) (T)[0]
> +#define LOW(T) (T)[1]
> +#define U128(H, L) (vector unsigned long long) {H, L}
> +#endif
> +
> #define BCDSUB(vra, vrb, ps) \
> asm ("bcdsub. %1,%2,%3,%4;" \
> "mfocrf %0,0b10;" \
> @@ -15,17 +26,18 @@
> : "v" (vra), "v" (vrb), "i" (ps) \
> : );
>
> -#define TEST(vra, vrb, ps, exp_res, exp_cr6) \
> - do { \
> - __int128 vrt = 0; \
> - int cr = 0; \
> - BCDSUB(vra, vrb, ps); \
> - if (exp_res) \
> - assert(vrt == exp_res); \
> - assert((cr >> 4) == exp_cr6); \
> +#define TEST(vra, vrb, ps, exp_res_h, exp_res_l, exp_cr6) \
> + do { \
> + vector unsigned long long vrt = U128(0, 0); \
> + int cr = 0; \
> + BCDSUB(vra, vrb, ps); \
> + if (exp_res_h || exp_res_l) { \
> + assert(HIGH(vrt) == exp_res_h); \
> + assert(LOW(vrt) == exp_res_l); \
> + } \
> + assert((cr >> 4) == exp_cr6); \
> } while (0)
>
> -
> /*
> * Unbounded result is equal to zero:
> * sign = (PS) ? 0b1111 : 0b1100
> @@ -33,13 +45,13 @@
> */
> void test_bcdsub_eq(void)
> {
> - __int128 a, b;
> + vector unsigned long long a, b;
>
> /* maximum positive BCD value */
> - a = b = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999c);
> + a = b = U128(0x9999999999999999, 0x999999999999999c);
>
> - TEST(a, b, 0, 0xc, CRF_EQ);
> - TEST(a, b, 1, 0xf, CRF_EQ);
> + TEST(a, b, 0, 0x0, 0xc, CRF_EQ);
> + TEST(a, b, 1, 0x0, 0xf, CRF_EQ);
> }
>
> /*
> @@ -49,21 +61,21 @@ void test_bcdsub_eq(void)
> */
> void test_bcdsub_gt(void)
> {
> - __int128 a, b, c;
> + vector unsigned long long a, b, c;
>
> /* maximum positive BCD value */
> - a = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999c);
> + a = U128(0x9999999999999999, 0x999999999999999c);
>
> /* negative one BCD value */
> - b = (__int128) 0x1d;
> + b = U128(0x0, 0x1d);
>
> - TEST(a, b, 0, 0xc, (CRF_GT | CRF_SO));
> - TEST(a, b, 1, 0xf, (CRF_GT | CRF_SO));
> + TEST(a, b, 0, 0x0, 0xc, (CRF_GT | CRF_SO));
> + TEST(a, b, 1, 0x0, 0xf, (CRF_GT | CRF_SO));
>
> - c = (((__int128) 0x9999999999999999) << 64 | 0x999999999999998c);
> + c = U128(0x9999999999999999, 0x999999999999998c);
>
> - TEST(c, b, 0, a, CRF_GT);
> - TEST(c, b, 1, (a | 0x3), CRF_GT);
> + TEST(c, b, 0, HIGH(a), LOW(a), CRF_GT);
> + TEST(c, b, 1, HIGH(a), (LOW(a) | 0x3), CRF_GT);
> }
>
> /*
> @@ -73,45 +85,45 @@ void test_bcdsub_gt(void)
> */
> void test_bcdsub_lt(void)
> {
> - __int128 a, b;
> + vector unsigned long long a, b;
>
> /* positive zero BCD value */
> - a = (__int128) 0xc;
> + a = U128(0x0, 0xc);
>
> /* positive one BCD value */
> - b = (__int128) 0x1c;
> + b = U128(0x0, 0x1c);
>
> - TEST(a, b, 0, 0x1d, CRF_LT);
> - TEST(a, b, 1, 0x1d, CRF_LT);
> + TEST(a, b, 0, 0x0, 0x1d, CRF_LT);
> + TEST(a, b, 1, 0x0, 0x1d, CRF_LT);
>
> /* maximum negative BCD value */
> - a = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999d);
> + a = U128(0x9999999999999999, 0x999999999999999d);
>
> /* positive one BCD value */
> - b = (__int128) 0x1c;
> + b = U128(0x0, 0x1c);
>
> - TEST(a, b, 0, 0xd, (CRF_LT | CRF_SO));
> - TEST(a, b, 1, 0xd, (CRF_LT | CRF_SO));
> + TEST(a, b, 0, 0x0, 0xd, (CRF_LT | CRF_SO));
> + TEST(a, b, 1, 0x0, 0xd, (CRF_LT | CRF_SO));
> }
>
> void test_bcdsub_invalid(void)
> {
> - __int128 a, b;
> + vector unsigned long long a, b;
>
> /* positive one BCD value */
> - a = (__int128) 0x1c;
> - b = 0xf00;
> + a = U128(0x0, 0x1c);
> + b = U128(0x0, 0xf00);
>
> - TEST(a, b, 0, UNDEF, CRF_SO);
> - TEST(a, b, 1, UNDEF, CRF_SO);
> + TEST(a, b, 0, UNDEF, UNDEF, CRF_SO);
> + TEST(a, b, 1, UNDEF, UNDEF, CRF_SO);
>
> - TEST(b, a, 0, UNDEF, CRF_SO);
> - TEST(b, a, 1, UNDEF, CRF_SO);
> + TEST(b, a, 0, UNDEF, UNDEF, CRF_SO);
> + TEST(b, a, 1, UNDEF, UNDEF, CRF_SO);
>
> - a = 0xbad;
> + a = U128(0x0, 0xbad);
>
> - TEST(a, b, 0, UNDEF, CRF_SO);
> - TEST(a, b, 1, UNDEF, CRF_SO);
> + TEST(a, b, 0, UNDEF, UNDEF, CRF_SO);
> + TEST(a, b, 1, UNDEF, UNDEF, CRF_SO);
> }
>
> int main(void)
On 17/02/2022 05:09, Cédric Le Goater wrote: > On 2/8/22 21:31, matheus.ferst@eldorado.org.br wrote: >> From: Matheus Ferst <matheus.ferst@eldorado.org.br> >> >> LLVM/Clang doesn't like inline asm with __int128, use a vector type >> instead. >> >> Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br> >> --- >> Alternatively, we could pass VSR values in GPR pairs, as we did in >> tests/tcg/ppc64le/non_signalling_xscv.c >> --- >> tests/tcg/ppc64le/bcdsub.c | 92 +++++++++++++++++++++----------------- >> 1 file changed, 52 insertions(+), 40 deletions(-) >> >> diff --git a/tests/tcg/ppc64le/bcdsub.c b/tests/tcg/ppc64le/bcdsub.c >> index 8c188cae6d..17403daf22 100644 >> --- a/tests/tcg/ppc64le/bcdsub.c >> +++ b/tests/tcg/ppc64le/bcdsub.c >> @@ -1,6 +1,7 @@ >> #include <assert.h> >> #include <unistd.h> >> #include <signal.h> >> +#include <altivec.h> >> >> #define CRF_LT (1 << 3) >> #define CRF_GT (1 << 2) >> @@ -8,6 +9,16 @@ >> #define CRF_SO (1 << 0) >> #define UNDEF 0 >> >> +#ifdef __LITTLE_ENDIAN__ > > Shouldn't we be using : > > #if BYTE_ORDER == LITTLE_ENDIAN > > instead ? > I guess it is better, I'll send a v2. Thanks, Matheus K. Ferst Instituto de Pesquisas ELDORADO <http://www.eldorado.org.br/> Analista de Software Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>
On 17/02/2022 09:46, Matheus K. Ferst wrote: > On 17/02/2022 05:09, Cédric Le Goater wrote: >> On 2/8/22 21:31, matheus.ferst@eldorado.org.br wrote: >>> From: Matheus Ferst <matheus.ferst@eldorado.org.br> >>> >>> LLVM/Clang doesn't like inline asm with __int128, use a vector type >>> instead. >>> >>> Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br> >>> --- >>> Alternatively, we could pass VSR values in GPR pairs, as we did in >>> tests/tcg/ppc64le/non_signalling_xscv.c >>> --- >>> tests/tcg/ppc64le/bcdsub.c | 92 +++++++++++++++++++++----------------- >>> 1 file changed, 52 insertions(+), 40 deletions(-) >>> >>> diff --git a/tests/tcg/ppc64le/bcdsub.c b/tests/tcg/ppc64le/bcdsub.c >>> index 8c188cae6d..17403daf22 100644 >>> --- a/tests/tcg/ppc64le/bcdsub.c >>> +++ b/tests/tcg/ppc64le/bcdsub.c >>> @@ -1,6 +1,7 @@ >>> #include <assert.h> >>> #include <unistd.h> >>> #include <signal.h> >>> +#include <altivec.h> >>> >>> #define CRF_LT (1 << 3) >>> #define CRF_GT (1 << 2) >>> @@ -8,6 +9,16 @@ >>> #define CRF_SO (1 << 0) >>> #define UNDEF 0 >>> >>> +#ifdef __LITTLE_ENDIAN__ >> >> Shouldn't we be using : >> >> #if BYTE_ORDER == LITTLE_ENDIAN >> >> instead ? >> > > I guess it is better, I'll send a v2. > Actually, it doesn't work for LLVM and needs endian.h for GCC[1]. This check is also used in sigbus and sha1 tests. The first shouldn't be a problem (allow_fail is zero for ppc), but sha1 gives the wrong result for BE: $ ./qemu-ppc64le tests/tcg/ppc64le-linux-user/sha1 SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6 $ ./qemu-ppc64 tests/tcg/ppc64-linux-user/sha1 SHA1=70f1d4d65eb47309ffacc5a28ff285ad826006da and 'make check-tcg' succeeds anyway... [1] https://godbolt.org/z/fYbzbbexn -- Matheus K. Ferst Instituto de Pesquisas ELDORADO <http://www.eldorado.org.br/> Analista de Software Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>
© 2016 - 2026 Red Hat, Inc.