This was patch 10 from the previous series. The patch was updated to address feedback comments.
Carl --------------------------------------------------- rs6000, extend vec_xxpermdi built-in for __int128 args Add a new signed and unsigned overloaded instances for vec_xxpermdi __int128 vec_xxpermdi (__int128, __int128, const int); __uint128 vec_xxpermdi (__uint128, __uint128, const int); Update the documentation to include a reference to the new built-in instances. Add test cases for the new overloaded instances. gcc/ChangeLog: * config/rs6000/rs6000-overload.def (vec_xxpermdi): Add new overloaded built-in instances. * doc/extend.texi: Add documentation for new overloaded built-in instances. gcc/testsuite/ChangeLog:gcc/testsuite/ChangeLog: * gcc.target/powerpc/vec_perm-runnable-i128.c: New test file. --- gcc/config/rs6000/rs6000-overload.def | 4 + gcc/doc/extend.texi | 2 + .../powerpc/vec_perm-runnable-i128.c | 229 ++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/vec_perm-runnable-i128.c diff --git a/gcc/config/rs6000/rs6000-overload.def b/gcc/config/rs6000/rs6000-overload.def index a210c5ad10d..45000f161e4 100644 --- a/gcc/config/rs6000/rs6000-overload.def +++ b/gcc/config/rs6000/rs6000-overload.def @@ -4932,6 +4932,10 @@ XXPERMDI_4SF XXPERMDI_VF vd __builtin_vsx_xxpermdi (vd, vd, const int); XXPERMDI_2DF XXPERMDI_VD + vsq __builtin_vsx_xxpermdi (vsq, vsq, const int); + XXPERMDI_1TI XXPERMDI_1TI + vuq __builtin_vsx_xxpermdi (vuq, vuq, const int); + XXPERMDI_1TI XXPERMDI_1TUI [VEC_XXSLDWI, vec_xxsldwi, __builtin_vsx_xxsldwi] vsc __builtin_vsx_xxsldwi (vsc, vsc, const int); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 0756230b19e..edfef1bdab7 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -22555,6 +22555,8 @@ void vec_vsx_st (vector bool char, int, signed char *); vector double vec_xxpermdi (vector double, vector double, const int); vector float vec_xxpermdi (vector float, vector float, const int); vector long long vec_xxpermdi (vector long long, vector long long, const int); +vector __int128 vec_xxpermdi (vector __int128, vector __int128, const int); +vector __int128 vec_xxpermdi (vector __uint128, vector __uint128, const int); vector unsigned long long vec_xxpermdi (vector unsigned long long, vector unsigned long long, const int); vector int vec_xxpermdi (vector int, vector int, const int); diff --git a/gcc/testsuite/gcc.target/powerpc/vec_perm-runnable-i128.c b/gcc/testsuite/gcc.target/powerpc/vec_perm-runnable-i128.c new file mode 100644 index 00000000000..2d5dce09404 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec_perm-runnable-i128.c @@ -0,0 +1,229 @@ +/* { dg-do run } */ +/* { dg-require-effective-target vmx_hw } */ +/* { dg-options "-save-temps" } */ + +#include <altivec.h> + +#define DEBUG 0 + +#if DEBUG +#include <stdio.h> +void print_i128 (unsigned __int128 val) +{ + printf(" 0x%016llx%016llx", + (unsigned long long)(val >> 64), + (unsigned long long)(val & 0xFFFFFFFFFFFFFFFF)); +} +#endif + +extern void abort (void); + +union convert_union { + vector signed __int128 s128; + vector unsigned __int128 u128; + char val[16]; +} convert; + +int check_u128_result(vector unsigned __int128 vresult_u128, + vector unsigned __int128 expected_vresult_u128) +{ + /* Use a for loop to check each byte manually so the test case will + run with ISA 2.06. + + Return 1 if they match, 0 otherwise. */ + + int i; + + union convert_union result; + union convert_union expected; + + result.u128 = vresult_u128; + expected.u128 = expected_vresult_u128; + + /* Check if each byte of the result and expected match. */ + for (i = 0; i < 16; i++) + { + if (result.val[i] != expected.val[i]) + return 0; + } + return 1; +} + +int check_s128_result(vector signed __int128 vresult_s128, + vector signed __int128 expected_vresult_s128) +{ + /* Convert the arguments to unsigned, then check equality. */ + union convert_union result; + union convert_union expected; + + result.s128 = vresult_s128; + expected.s128 = expected_vresult_s128; + + return check_u128_result (result.u128, expected.u128); +} + + +int +main (int argc, char *argv []) +{ + int i; + + vector signed __int128 src_va_s128; + vector signed __int128 src_vb_s128; + vector signed __int128 vresult_s128; + vector signed __int128 expected_vresult_s128; + + vector unsigned __int128 src_va_u128; + vector unsigned __int128 src_vb_u128; + vector unsigned __int128 src_vc_u128; + vector unsigned __int128 vresult_u128; + vector unsigned __int128 expected_vresult_u128; + + src_va_s128 = (vector signed __int128) {0x123456789ABCDEF0}; + src_va_s128 = src_va_s128 << 64; + src_va_s128 |= (vector signed __int128) {0x22446688AACCEE00}; + src_vb_s128 = (vector signed __int128) {0xFEDCBA9876543210}; + src_vb_s128 = src_vb_s128 << 64; + src_vb_s128 |= (vector signed __int128) {0x3333333333333333}; + + src_va_u128 = (vector unsigned __int128) {0x13579ACE02468BDF}; + src_va_u128 = src_va_u128 << 64; + src_va_u128 |= (vector unsigned __int128) {0x1133557799BBDD00}; + src_vb_u128 = (vector unsigned __int128) {0xA987654FEDCB3210}; + src_vb_u128 = src_vb_u128 << 64; + src_vb_u128 |= (vector unsigned __int128) {0x5555555555555555}; + + + /* Signed 128-bit arguments. */ + vresult_s128 = vec_xxpermdi (src_va_s128, src_vb_s128, 0x1); + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + /* BE expected results */ + expected_vresult_s128 = (vector signed __int128) {0x123456789ABCDEF0}; + expected_vresult_s128 = expected_vresult_s128 << 64; + expected_vresult_s128 |= (vector signed __int128) {0x3333333333333333}; +#else + /* LE expected results */ + expected_vresult_s128 = (vector signed __int128) {0xFEDCBA9876543210}; + expected_vresult_s128 = expected_vresult_s128 << 64; + expected_vresult_s128 |= (vector signed __int128) {0x22446688AACCEE00}; +#endif + + if (!check_s128_result (vresult_s128, expected_vresult_s128)) +#if DEBUG + { + printf ("ERROR, vec_xxpermdi (src_va_s128, src_vb_s128, 0x1) result does not match expected output.\n"); + printf (" src_va_s128: "); + print_i128 ((unsigned __int128) src_va_s128); + printf ("\n src_vb_s128: "); + print_i128 ((unsigned __int128) src_vb_s128); + printf ("\n Result: "); + print_i128 ((unsigned __int128) vresult_s128); + printf ("\n Expected result: "); + print_i128 ((unsigned __int128) expected_vresult_s128); + printf ("\n"); + } +#else + abort (); +#endif + + vresult_s128 = vec_xxpermdi (src_va_s128, src_vb_s128, 0x2); + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + /* BE expected results */ + expected_vresult_s128 = (vector signed __int128) {0x22446688AACCEE00}; + expected_vresult_s128 = expected_vresult_s128 << 64; + expected_vresult_s128 |= (vector signed __int128) {0xFEDCBA9876543210}; +#else + /* LE expected results */ + expected_vresult_s128 = (vector signed __int128) {0x3333333333333333}; + expected_vresult_s128 = expected_vresult_s128 << 64; + expected_vresult_s128 |= (vector signed __int128) {0x123456789ABCDEF0}; +#endif + + if (!check_s128_result (vresult_s128, expected_vresult_s128)) +#if DEBUG + { + printf ("ERROR, vec_xxpermdi (src_va_s128, src_vb_s128, 0x2) result does not match expected output.\n"); + printf (" src_va_s128: "); + print_i128 ((unsigned __int128) src_va_s128); + printf ("\n src_vb_s128: "); + print_i128 ((unsigned __int128) src_vb_s128); + printf ("\n Result: "); + print_i128 ((unsigned __int128) vresult_s128); + printf ("\n Expected result: "); + print_i128 ((unsigned __int128) expected_vresult_s128); + printf ("\n"); + } +#else + abort (); +#endif + + /* Unigned arguments. */ + vresult_u128 = vec_xxpermdi (src_va_u128, src_vb_u128, 0x1); + + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + /* BE expected results */ + expected_vresult_u128 = (vector unsigned __int128) {0x13579ACE02468BDF}; + expected_vresult_u128 = expected_vresult_u128 << 64; + expected_vresult_u128 |= (vector unsigned __int128) {0x5555555555555555}; +#else + /* LE expected results */ + expected_vresult_u128 = (vector unsigned __int128) {0xA987654FEDCB3210}; + expected_vresult_u128 = expected_vresult_u128 << 64; + expected_vresult_u128 |= (vector unsigned __int128) {0x1133557799BBDD00}; +#endif + + if (!check_u128_result (vresult_u128, expected_vresult_u128)) +#if DEBUG + { + printf ("ERROR, vec_xxpermdi (src_va_u128, src_vb_u128, 0x1) result does not match expected output.\n"); + printf (" src_va_s128: "); + print_i128 ((unsigned __int128) src_va_s128); + printf ("\n src_vb_s128: "); + print_i128 ((unsigned __int128) src_vb_s128); + printf ("\n Result: "); + print_i128 ((unsigned __int128) vresult_u128); + printf ("\n Expected result: "); + print_i128 ((unsigned __int128) expected_vresult_u128); + printf ("\n"); + } +#else + abort (); +#endif + + /* Unigned arguments. */ + vresult_u128 = vec_xxpermdi (src_va_u128, src_vb_u128, 0x2); + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + /* BE expected results */ + expected_vresult_u128 = (vector unsigned __int128) {0x1133557799BBDD00}; + expected_vresult_u128 = expected_vresult_u128 << 64; + expected_vresult_u128 |= (vector unsigned __int128) {0xA987654FEDCB3210}; +#else + /* LE expected results */ + expected_vresult_u128 = (vector unsigned __int128) {0x5555555555555555}; + expected_vresult_u128 = expected_vresult_u128 << 64; + expected_vresult_u128 |= (vector unsigned __int128) {0x13579ACE02468BDF}; +#endif + + if (!check_u128_result (vresult_u128, expected_vresult_u128)) +#if DEBUG + { + printf ("ERROR, vec_xxpermdi (src_va_u128, src_vb_u128, 0x2) result does not match expected output.\n"); + printf (" src_va_s128: "); + print_i128 ((unsigned __int128) src_va_s128); + printf ("\n src_vb_s128: "); + print_i128 ((unsigned __int128) src_vb_s128); + printf ("\n Result: "); + print_i128 ((unsigned __int128) vresult_u128); + printf ("\n Expected result: "); + print_i128 ((unsigned __int128) expected_vresult_u128); + printf ("\n"); + } +#else + abort (); +#endif + + return 0; +} -- 2.45.0