From: Carl Love Date: Wed, 27 May 2020 03:44:50 +0000 (-0500) Subject: rs6000, Add vector shift double builtin support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=82f10dee344bf0807cab9f32745b35af3f2139d8;p=gcc.git rs6000, Add vector shift double builtin support GCC maintainers: The following patch adds support for the vector shift double builtins. The patch has been compiled and tested on powerpc64le-unknown-linux-gnu (Power 8 LE) powerpc64le-unknown-linux-gnu (Power 9 LE) and Mambo with no regression errors. Please let me know if this patch is acceptable for the mainline branch. Thanks. Carl Love ------------------------------------------------------- gcc/ChangeLog 2020-08-04 Carl Love * config/rs6000/altivec.h (vec_sldb, vec_srdb): New defines. * config/rs6000/altivec.md (UNSPEC_SLDB, UNSPEC_SRDB): New. (SLDB_lr): New attribute. (VSHIFT_DBL_LR): New iterator. (vsdb_): New define_insn. * config/rs6000/rs6000-builtin.def (VSLDB_V16QI, VSLDB_V8HI, VSLDB_V4SI, VSLDB_V2DI, VSRDB_V16QI, VSRDB_V8HI, VSRDB_V4SI, VSRDB_V2DI): New BU_P10V_3 definitions. (SLDB, SRDB): New BU_P10_OVERLOAD_3 definitions. * config/rs6000/rs6000-call.c (P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VEC_SRDB): New definitions. (rs6000_expand_ternop_builtin) [CODE_FOR_vsldb_v16qi, CODE_FOR_vsldb_v8hi, CODE_FOR_vsldb_v4si, CODE_FOR_vsldb_v2di, CODE_FOR_vsrdb_v16qi, CODE_FOR_vsrdb_v8hi, CODE_FOR_vsrdb_v4si, CODE_FOR_vsrdb_v2di]: Add clauses. * doc/extend.texi: Add description for vec_sldb and vec_srdb. gcc/testsuite/ChangeLog 2020-08-04 Carl Love * gcc.target/powerpc/vec-shift-double-runnable.c: New test file. --- diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h index 62fe0bfc6fb..1a5c216ce6c 100644 --- a/gcc/config/rs6000/altivec.h +++ b/gcc/config/rs6000/altivec.h @@ -707,6 +707,8 @@ __altivec_scalar_pred(vec_any_nle, #define vec_inserth(a, b, c) __builtin_vec_inserth (a, b, c) #define vec_replace_elt(a, b, c) __builtin_vec_replace_elt (a, b, c) #define vec_replace_unaligned(a, b, c) __builtin_vec_replace_un (a, b, c) +#define vec_sldb(a, b, c) __builtin_vec_sldb (a, b, c) +#define vec_srdb(a, b, c) __builtin_vec_srdb (a, b, c) #define vec_gnb(a, b) __builtin_vec_gnb (a, b) #define vec_clrl(a, b) __builtin_vec_clrl (a, b) diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index dff4399ba4a..9d9734114ac 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -173,6 +173,8 @@ UNSPEC_XXEVAL UNSPEC_VSTRIR UNSPEC_VSTRIL + UNSPEC_SLDB + UNSPEC_SRDB ]) (define_c_enum "unspecv" @@ -783,6 +785,22 @@ DONE; }) +;; Map UNSPEC_SLDB to "l" and UNSPEC_SRDB to "r". +(define_int_attr SLDB_lr [(UNSPEC_SLDB "l") + (UNSPEC_SRDB "r")]) + +(define_int_iterator VSHIFT_DBL_LR [UNSPEC_SLDB UNSPEC_SRDB]) + +(define_insn "vsdb_" + [(set (match_operand:VI2 0 "register_operand" "=v") + (unspec:VI2 [(match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v") + (match_operand:QI 3 "const_0_to_12_operand" "n")] + VSHIFT_DBL_LR))] + "TARGET_POWER10" + "vsdbi %0,%1,%2,%3" + [(set_attr "type" "vecsimple")]) + (define_expand "vstrir_" [(set (match_operand:VIshort 0 "altivec_register_operand") (unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")] diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 6e11d38d1fa..bfb3376e97e 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -2764,6 +2764,16 @@ BU_P10V_3 (VREPLACE_UN_V2DI, "vreplace_un_v2di", CONST, vreplace_un_v2di) BU_P10V_3 (VREPLACE_UN_UV2DI, "vreplace_un_uv2di", CONST, vreplace_un_v2di) BU_P10V_3 (VREPLACE_UN_V2DF, "vreplace_un_v2df", CONST, vreplace_un_v2df) +BU_P10V_3 (VSLDB_V16QI, "vsldb_v16qi", CONST, vsldb_v16qi) +BU_P10V_3 (VSLDB_V8HI, "vsldb_v8hi", CONST, vsldb_v8hi) +BU_P10V_3 (VSLDB_V4SI, "vsldb_v4si", CONST, vsldb_v4si) +BU_P10V_3 (VSLDB_V2DI, "vsldb_v2di", CONST, vsldb_v2di) + +BU_P10V_3 (VSRDB_V16QI, "vsrdb_v16qi", CONST, vsrdb_v16qi) +BU_P10V_3 (VSRDB_V8HI, "vsrdb_v8hi", CONST, vsrdb_v8hi) +BU_P10V_3 (VSRDB_V4SI, "vsrdb_v4si", CONST, vsrdb_v4si) +BU_P10V_3 (VSRDB_V2DI, "vsrdb_v2di", CONST, vsrdb_v2di) + BU_P10V_1 (VSTRIBR, "vstribr", CONST, vstrir_v16qi) BU_P10V_1 (VSTRIHR, "vstrihr", CONST, vstrir_v8hi) BU_P10V_1 (VSTRIBL, "vstribl", CONST, vstril_v16qi) @@ -2810,6 +2820,8 @@ BU_P10_OVERLOAD_3 (INSERTL, "insertl") BU_P10_OVERLOAD_3 (INSERTH, "inserth") BU_P10_OVERLOAD_3 (REPLACE_ELT, "replace_elt") BU_P10_OVERLOAD_3 (REPLACE_UN, "replace_un") +BU_P10_OVERLOAD_3 (SLDB, "sldb") +BU_P10_OVERLOAD_3 (SRDB, "srdb") BU_P10_OVERLOAD_1 (VSTRIR, "strir") BU_P10_OVERLOAD_1 (VSTRIL, "stril") diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c index 5dd1f666feb..2955399a578 100644 --- a/gcc/config/rs6000/rs6000-call.c +++ b/gcc/config/rs6000/rs6000-call.c @@ -5669,6 +5669,56 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { { P10_BUILTIN_VEC_REPLACE_UN, P10_BUILTIN_VREPLACE_UN_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_double, RS6000_BTI_INTQI }, + { P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VSLDB_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VSLDB_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VSLDB_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VSLDB_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VSLDB_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VSLDB_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VSLDB_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SLDB, P10_BUILTIN_VSLDB_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_UINTQI }, + + { P10_BUILTIN_VEC_SRDB, P10_BUILTIN_VSRDB_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SRDB, P10_BUILTIN_VSRDB_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SRDB, P10_BUILTIN_VSRDB_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SRDB, P10_BUILTIN_VSRDB_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SRDB, P10_BUILTIN_VSRDB_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SRDB, P10_BUILTIN_VSRDB_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SRDB, P10_BUILTIN_VSRDB_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_SRDB, P10_BUILTIN_VSRDB_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_UINTQI }, + { P10_BUILTIN_VEC_VSTRIL, P10_BUILTIN_VSTRIBL, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, { P10_BUILTIN_VEC_VSTRIL, P10_BUILTIN_VSTRIBL, @@ -10124,6 +10174,26 @@ rs6000_expand_quaternop_builtin (enum insn_code icode, tree exp, rtx target) } } + else if (icode == CODE_FOR_vsldb_v16qi + || icode == CODE_FOR_vsldb_v8hi + || icode == CODE_FOR_vsldb_v4si + || icode == CODE_FOR_vsldb_v2di + || icode == CODE_FOR_vsrdb_v16qi + || icode == CODE_FOR_vsrdb_v8hi + || icode == CODE_FOR_vsrdb_v4si + || icode == CODE_FOR_vsrdb_v2di) + { + /* Check whether the 3rd argument is an integer constant in the range + 0 to 7 inclusive. */ + STRIP_NOPS (arg2); + if (TREE_CODE (arg2) != INTEGER_CST + || !IN_RANGE (TREE_INT_CST_LOW (arg2), 0, 7)) + { + error ("argument 3 must be a constant in the range 0 to 7"); + return CONST0_RTX (tmode); + } + } + if (target == 0 || GET_MODE (target) != tmode || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index f9b57e4d616..d74f3a62329 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -21140,6 +21140,59 @@ The programmer is responsible for understanding the endianness issues involved with the first argument and the result. @findex vec_replace_unaligned +Vector Shift Left Double Bit Immediate +@smallexample +@exdent vector signed char vec_sldb (vector signed char, vector signed char, +const unsigned int); +@exdent vector unsigned char vec_sldb (vector unsigned char, +vector unsigned char, const unsigned int); +@exdent vector signed short vec_sldb (vector signed short, vector signed short, +const unsigned int); +@exdent vector unsigned short vec_sldb (vector unsigned short, +vector unsigned short, const unsigned int); +@exdent vector signed int vec_sldb (vector signed int, vector signed int, +const unsigned int); +@exdent vector unsigned int vec_sldb (vector unsigned int, vector unsigned int, +const unsigned int); +@exdent vector signed long long vec_sldb (vector signed long long, +vector signed long long, const unsigned int); +@exdent vector unsigned long long vec_sldb (vector unsigned long long, +vector unsigned long long, const unsigned int); +@end smallexample + +Shift the combined input vectors left by the amount specified by the low-order +three bits of the third argument, and return the leftmost remaining 128 bits. +Code using this instruction must be endian-aware. + +@findex vec_sldb + +Vector Shift Right Double Bit Immediate + +@smallexample +@exdent vector signed char vec_srdb (vector signed char, vector signed char, +const unsigned int); +@exdent vector unsigned char vec_srdb (vector unsigned char, vector unsigned char, +const unsigned int); +@exdent vector signed short vec_srdb (vector signed short, vector signed short, +const unsigned int); +@exdent vector unsigned short vec_srdb (vector unsigned short, vector unsigned short, +const unsigned int); +@exdent vector signed int vec_srdb (vector signed int, vector signed int, +const unsigned int); +@exdent vector unsigned int vec_srdb (vector unsigned int, vector unsigned int, +const unsigned int); +@exdent vector signed long long vec_srdb (vector signed long long, +vector signed long long, const unsigned int); +@exdent vector unsigned long long vec_srdb (vector unsigned long long, +vector unsigned long long, const unsigned int); +@end smallexample + +Shift the combined input vectors right by the amount specified by the low-order +three bits of the third argument, and return the remaining 128 bits. Code +using this built-in must be endian-aware. + +@findex vec_srdb + @smallexample @exdent vector unsigned long long int @exdent vec_pext (vector unsigned long long int, vector unsigned long long int) diff --git a/gcc/testsuite/gcc.target/powerpc/vec-shift-double-runnable.c b/gcc/testsuite/gcc.target/powerpc/vec-shift-double-runnable.c new file mode 100644 index 00000000000..13213bd22ee --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-shift-double-runnable.c @@ -0,0 +1,384 @@ +/* { dg-do run } */ +/* { dg-require-effective-target power10_hw } */ +/* { dg-options "-mdejagnu-cpu=power10" } */ +#include + +#define DEBUG 0 + +#ifdef DEBUG +#include +#endif + +extern void abort (void); + +int +main (int argc, char *argv []) +{ + int i; + + vector signed char vresult_char; + vector signed char expected_vresult_char; + vector signed char src_va_char; + vector signed char src_vb_char; + + vector unsigned char vresult_uchar; + vector unsigned char expected_vresult_uchar; + vector unsigned char src_va_uchar; + vector unsigned char src_vb_uchar; + + vector short int vresult_sh; + vector short int expected_vresult_sh; + vector short int src_va_sh; + vector short int src_vb_sh; + + vector short unsigned int vresult_ush; + vector short unsigned int expected_vresult_ush; + vector short unsigned int src_va_ush; + vector short unsigned int src_vb_ush; + + vector int vresult_int; + vector int expected_vresult_int; + vector int src_va_int; + vector int src_vb_int; + int src_a_int; + + vector unsigned int vresult_uint; + vector unsigned int expected_vresult_uint; + vector unsigned int src_va_uint; + vector unsigned int src_vb_uint; + unsigned int src_a_uint; + + vector long long int vresult_llint; + vector long long int expected_vresult_llint; + vector long long int src_va_llint; + vector long long int src_vb_llint; + long long int src_a_llint; + + vector unsigned long long int vresult_ullint; + vector unsigned long long int expected_vresult_ullint; + vector unsigned long long int src_va_ullint; + vector unsigned long long int src_vb_ullint; + unsigned int long long src_a_ullint; + + /* Vector shift double left */ + src_va_char = (vector signed char) { 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30 }; + src_vb_char = (vector signed char) { 10, 20, 30, 40, 50, 60, 70, 80, 90, + 100, 110, 120, 130, 140, 150, 160 }; + vresult_char = (vector signed char) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + expected_vresult_char = (vector signed char) { 80, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14 }; + + vresult_char = vec_sldb (src_va_char, src_vb_char, 7); + + if (!vec_all_eq (vresult_char, expected_vresult_char)) { +#if DEBUG + printf("ERROR, vec_sldb (src_va_char_, src_vb_char, 7)\n"); + for(i = 0; i < 16; i++) + printf(" vresult_char[%d] = %d, expected_vresult_char[%d] = %d\n", + i, vresult_char[i], i, expected_vresult_char[i]); +#else + abort(); +#endif + } + + src_va_uchar = (vector unsigned char) { 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30 }; + src_vb_uchar = (vector unsigned char) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + vresult_uchar = (vector unsigned char) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + expected_vresult_uchar = (vector unsigned char) { 0, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14 }; + + vresult_uchar = vec_sldb (src_va_uchar, src_vb_uchar, 7); + + if (!vec_all_eq (vresult_uchar, expected_vresult_uchar)) { +#if DEBUG + printf("ERROR, vec_sldb (src_va_uchar_, src_vb_uchar, 7)\n"); + for(i = 0; i < 16; i++) + printf(" vresult_uchar[%d] = %d, expected_vresult_uchar[%d] = %d\n", + i, vresult_uchar[i], i, expected_vresult_uchar[i]); +#else + abort(); +#endif + } + + src_va_sh = (vector short int) { 0, 2, 4, 6, 8, 10, 12, 14 }; + src_vb_sh = (vector short int) { 0, 0, 0, 0, 0, 0, 0, 0 }; + vresult_sh = (vector short int) { 0, 0, 0, 0, 0, 0, 0, 0 }; + expected_vresult_sh = (vector short int) { 0, 2*128, 4*128, 6*128, + 8*128, 10*128, 12*128, 14*128 }; + + vresult_sh = vec_sldb (src_va_sh, src_vb_sh, 7); + + if (!vec_all_eq (vresult_sh, expected_vresult_sh)) { +#if DEBUG + printf("ERROR, vec_sldb (src_va_sh_, src_vb_sh, 7)\n"); + for(i = 0; i < 8; i++) + printf(" vresult_sh[%d] = %d, expected_vresult_sh[%d] = %d\n", + i, vresult_sh[i], i, expected_vresult_sh[i]); +#else + abort(); +#endif + } + + src_va_ush = (vector short unsigned int) { 0, 2, 4, 6, 8, 10, 12, 14 }; + src_vb_ush = (vector short unsigned int) { 10, 20, 30, 40, 50, 60, 70, 80 }; + vresult_ush = (vector short unsigned int) { 0, 0, 0, 0, 0, 0, 0, 0 }; + expected_vresult_ush = (vector short unsigned int) { 0, 2*128, 4*128, 6*128, + 8*128, 10*128, 12*128, + 14*128 }; + + vresult_ush = vec_sldb (src_va_ush, src_vb_ush, 7); + + if (!vec_all_eq (vresult_ush, expected_vresult_ush)) { +#if DEBUG + printf("ERROR, vec_sldb (src_va_ush_, src_vb_ush, 7)\n"); + for(i = 0; i < 8; i++) + printf(" vresult_ush[%d] = %d, expected_vresult_ush[%d] = %d\n", + i, vresult_ush[i], i, expected_vresult_ush[i]); +#else + abort(); +#endif + } + + src_va_int = (vector signed int) { 0, 2, 3, 1 }; + src_vb_int = (vector signed int) { 0, 0, 0, 0 }; + vresult_int = (vector signed int) { 0, 0, 0, 0 }; + expected_vresult_int = (vector signed int) { 0, 2*128, 3*128, 1*128 }; + + vresult_int = vec_sldb (src_va_int, src_vb_int, 7); + + if (!vec_all_eq (vresult_int, expected_vresult_int)) { +#if DEBUG + printf("ERROR, vec_sldb (src_va_int_, src_vb_int, 7)\n"); + for(i = 0; i < 4; i++) + printf(" vresult_int[%d] = %d, expected_vresult_int[%d] = %d\n", + i, vresult_int[i], i, expected_vresult_int[i]); +#else + abort(); +#endif + } + + src_va_uint = (vector unsigned int) { 0, 2, 4, 6 }; + src_vb_uint = (vector unsigned int) { 10, 20, 30, 40 }; + vresult_uint = (vector unsigned int) { 0, 0, 0, 0 }; + expected_vresult_uint = (vector unsigned int) { 0, 2*128, 4*128, 6*128 }; + + vresult_uint = vec_sldb (src_va_uint, src_vb_uint, 7); + + if (!vec_all_eq (vresult_uint, expected_vresult_uint)) { +#if DEBUG + printf("ERROR, vec_sldb (src_va_uint_, src_vb_uint, 7)\n"); + for(i = 0; i < 4; i++) + printf(" vresult_uint[%d] = %d, expected_vresult_uint[%d] = %d\n", + i, vresult_uint[i], i, expected_vresult_uint[i]); +#else + abort(); +#endif + } + + src_va_llint = (vector signed long long int) { 5, 6 }; + src_vb_llint = (vector signed long long int) { 0, 0 }; + vresult_llint = (vector signed long long int) { 0, 0 }; + expected_vresult_llint = (vector signed long long int) { 5*128, 6*128 }; + + vresult_llint = vec_sldb (src_va_llint, src_vb_llint, 7); + + if (!vec_all_eq (vresult_llint, expected_vresult_llint)) { +#if DEBUG + printf("ERROR, vec_sldb (src_va_llint_, src_vb_llint, 7)\n"); + for(i = 0; i < 2; i++) + printf(" vresult_llint[%d] = %d, expected_vresult_llint[%d] = %d\n", + i, vresult_llint[i], i, expected_vresult_llint[i]); +#else + abort(); +#endif + } + + src_va_ullint = (vector unsigned long long int) { 54, 26 }; + src_vb_ullint = (vector unsigned long long int) { 10, 20 }; + vresult_ullint = (vector unsigned long long int) { 0, 0 }; + expected_vresult_ullint = (vector unsigned long long int) { 54*128, + 26*128 }; + + vresult_ullint = vec_sldb (src_va_ullint, src_vb_ullint, 7); + + if (!vec_all_eq (vresult_ullint, expected_vresult_ullint)) { +#if DEBUG + printf("ERROR, vec_sldb (src_va_ullint_, src_vb_ullint, 7)\n"); + for(i = 0; i < 2; i++) + printf(" vresult_ullint[%d] = %d, expected_vresult_ullint[%d] = %d\n", + i, vresult_ullint[i], i, expected_vresult_ullint[i]); +#else + abort(); +#endif + } + + /* Vector shift double right */ + src_va_char = (vector signed char) { 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30 }; + src_vb_char = (vector signed char) { 10, 12, 14, 16, 18, 20, 22, 24, 26, + 28, 30, 32, 34, 36, 38, 40 }; + vresult_char = (vector signed char) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + expected_vresult_char = (vector signed char) { 24, 28, 32, 36, 40, 44, 48, + 52, 56, 60, 64, 68, 72, 76, + 80, 0 }; + + vresult_char = vec_srdb (src_va_char, src_vb_char, 7); + + if (!vec_all_eq (vresult_char, expected_vresult_char)) { +#if DEBUG + printf("ERROR, vec_srdb (src_va_char_, src_vb_char, 7)\n"); + for(i = 0; i < 16; i++) + printf(" vresult_char[%d] = %d, expected_vresult_char[%d] = %d\n", + i, vresult_char[i], i, expected_vresult_char[i]); +#else + abort(); +#endif + } + + src_va_uchar = (vector unsigned char) { 100, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + src_vb_uchar = (vector unsigned char) { 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 24, 26, 28, 30 }; + vresult_uchar = (vector unsigned char) { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + expected_vresult_uchar = (vector unsigned char) { 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, + 56, 60, 200 }; + + vresult_uchar = vec_srdb (src_va_uchar, src_vb_uchar, 7); + + if (!vec_all_eq (vresult_uchar, expected_vresult_uchar)) { +#if DEBUG + printf("ERROR, vec_srdb (src_va_uchar_, src_vb_uchar, 7)\n"); + for(i = 0; i < 16; i++) + printf(" vresult_uchar[%d] = %d, expected_vresult_uchar[%d] = %d\n", + i, vresult_uchar[i], i, expected_vresult_uchar[i]); +#else + abort(); +#endif + } + + src_va_sh = (vector short int) { 0, 0, 0, 0, 0, 0, 0, 0 }; + src_vb_sh = (vector short int) { 0, 2*128, 4*128, 6*128, + 8*128, 10*128, 12*128, 14*128 }; + vresult_sh = (vector short int) { 0, 0, 0, 0, 0, 0, 0, 0 }; + expected_vresult_sh = (vector short int) { 0, 2, 4, 6, 8, 10, 12, 14 }; + + vresult_sh = vec_srdb (src_va_sh, src_vb_sh, 7); + + if (!vec_all_eq (vresult_sh, expected_vresult_sh)) { +#if DEBUG + printf("ERROR, vec_srdb (src_va_sh_, src_vb_sh, 7)\n"); + for(i = 0; i < 8; i++) + printf(" vresult_sh[%d] = %d, expected_vresult_sh[%d] = %d\n", + i, vresult_sh[i], i, expected_vresult_sh[i]); +#else + abort(); +#endif + } + + src_va_ush = (vector short unsigned int) { 0, 20, 30, 40, 50, 60, 70, 80 }; + src_vb_ush = (vector short unsigned int) { 0, 2*128, 4*128, 6*128, + 8*128, 10*128, 12*128, 14*128 }; + vresult_ush = (vector short unsigned int) { 0, 0, 0, 0, 0, 0, 0, 0 }; + expected_vresult_ush = (vector short unsigned int) { 0, 2, 4, 6, 8, 10, + 12, 14 }; + + vresult_ush = vec_srdb (src_va_ush, src_vb_ush, 7); + + if (!vec_all_eq (vresult_ush, expected_vresult_ush)) { +#if DEBUG + printf("ERROR, vec_srdb (src_va_ush_, src_vb_ush, 7)\n"); + for(i = 0; i < 8; i++) + printf(" vresult_ush[%d] = %d, expected_vresult_ush[%d] = %d\n", + i, vresult_ush[i], i, expected_vresult_ush[i]); +#else + abort(); +#endif + } + + src_va_int = (vector signed int) { 0, 0, 0, 0 }; + src_vb_int = (vector signed int) { 0, 2*128, 3*128, 1*128 }; + vresult_int = (vector signed int) { 0, 0, 0, 0 }; + expected_vresult_int = (vector signed int) { 0, 2, 3, 1 }; + + vresult_int = vec_srdb (src_va_int, src_vb_int, 7); + + if (!vec_all_eq (vresult_int, expected_vresult_int)) { +#if DEBUG + printf("ERROR, vec_srdb (src_va_int_, src_vb_int, 7)\n"); + for(i = 0; i < 4; i++) + printf(" vresult_int[%d] = %d, expected_vresult_int[%d] = %d\n", + i, vresult_int[i], i, expected_vresult_int[i]); +#else + abort(); +#endif + } + + src_va_uint = (vector unsigned int) { 0, 20, 30, 40 }; + src_vb_uint = (vector unsigned int) { 128, 2*128, 4*128, 6*128 }; + vresult_uint = (vector unsigned int) { 0, 0, 0, 0 }; + expected_vresult_uint = (vector unsigned int) { 1, 2, 4, 6 }; + + vresult_uint = vec_srdb (src_va_uint, src_vb_uint, 7); + + if (!vec_all_eq (vresult_uint, expected_vresult_uint)) { +#if DEBUG + printf("ERROR, vec_srdb (src_va_uint_, src_vb_uint, 7)\n"); + for(i = 0; i < 4; i++) + printf(" vresult_uint[%d] = %d, expected_vresult_uint[%d] = %d\n", + i, vresult_uint[i], i, expected_vresult_uint[i]); +#else + abort(); +#endif + } + + src_va_llint = (vector signed long long int) { 0, 0 }; + src_vb_llint = (vector signed long long int) { 5*128, 6*128 }; + vresult_llint = (vector signed long long int) { 0, 0 }; + expected_vresult_llint = (vector signed long long int) { 5, 6 }; + + vresult_llint = vec_srdb (src_va_llint, src_vb_llint, 7); + + if (!vec_all_eq (vresult_llint, expected_vresult_llint)) { +#if DEBUG + printf("ERROR, vec_srdb (src_va_llint_, src_vb_llint, 7)\n"); + for(i = 0; i < 2; i++) + printf(" vresult_llint[%d] = %d, expected_vresult_llint[%d] = %d\n", + i, vresult_llint[i], i, expected_vresult_llint[i]); +#else + abort(); +#endif + } + + src_va_ullint = (vector unsigned long long int) { 0, 0 }; + src_vb_ullint = (vector unsigned long long int) { 54*128, 26*128 }; + vresult_ullint = (vector unsigned long long int) { 0, 0 }; + expected_vresult_ullint = (vector unsigned long long int) { 54, 26 }; + + vresult_ullint = vec_srdb (src_va_ullint, src_vb_ullint, 7); + + if (!vec_all_eq (vresult_ullint, expected_vresult_ullint)) { +#if DEBUG + printf("ERROR, vec_srdb (src_va_ullint_, src_vb_ullint, 7)\n"); + for(i = 0; i < 2; i++) + printf(" vresult_ullint[%d] = %d, expected_vresult_ullint[%d] = %d\n", + i, vresult_ullint[i], i, expected_vresult_ullint[i]); +#else + abort(); +#endif + } + + return 0; +} + +/* { dg-final { scan-assembler-times {\msldbi\M} 6 } } */ +/* { dg-final { scan-assembler-times {\msrdbi\M} 6 } } */ + +