Message ID | 20220208203145.3844662-4-matheus.ferst@eldorado.org.br |
---|---|
State | Superseded |
Headers | show |
Series | tests/tcg/ppc64le: fix the build of TCG tests with Clang | expand |
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
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)