diff mbox series

[RFC,3/3] tests/tcg/ppc64le: Use vector types instead of __int128

Message ID 20220208203145.3844662-4-matheus.ferst@eldorado.org.br
State New
Headers show
Series tests/tcg/ppc64le: fix the build of TCG tests with Clang | expand

Commit Message

Matheus K. Ferst Feb. 8, 2022, 8:31 p.m. UTC
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(-)

Comments

Cédric Le Goater Feb. 17, 2022, 8:09 a.m. UTC | #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)
Matheus K. Ferst Feb. 17, 2022, 12:46 p.m. UTC | #2
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>
Matheus K. Ferst Feb. 21, 2022, 5:29 p.m. UTC | #3
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 mbox series

Patch

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)