+2020-05-13 Kelvin Nilsen <kelvin@gcc.gnu.org>
+
+ * config/rs6000/altivec.h (vec_extractl): New #define.
+ (vec_extracth): Likewise.
+ * config/rs6000/altivec.md (UNSPEC_EXTRACTL): New constant.
+ (UNSPEC_EXTRACTR): Likewise.
+ (vextractl<mode>): New expansion.
+ (vextractl<mode>_internal): New insn.
+ (vextractr<mode>): New expansion.
+ (vextractr<mode>_internal): New insn.
+ * config/rs6000/rs6000-builtin.def (__builtin_altivec_vextdubvlx):
+ New built-in function.
+ (__builtin_altivec_vextduhvlx): Likewise.
+ (__builtin_altivec_vextduwvlx): Likewise.
+ (__builtin_altivec_vextddvlx): Likewise.
+ (__builtin_altivec_vextdubvhx): Likewise.
+ (__builtin_altivec_vextduhvhx): Likewise.
+ (__builtin_altivec_vextduwvhx): Likewise.
+ (__builtin_altivec_vextddvhx): Likewise.
+ (__builtin_vec_extractl): New overloaded built-in function.
+ (__builtin_vec_extracth): Likewise.
+ * config/rs6000/rs6000-call.c (altivec_overloaded_builtins):
+ Define overloaded forms of __builtin_vec_extractl and
+ __builtin_vec_extracth.
+ (builtin_function_type): Add cases to mark arguments of new
+ built-in functions as unsigned.
+ (rs6000_common_init_builtins): Add
+ opaque_ftype_opaque_opaque_opaque_opaque.
+ * config/rs6000/rs6000.md (du_or_d): New mode attribute.
+ * doc/extend.texi (PowerPC AltiVec Built-in Functions Available
+ for a Future Architecture): Add description of vec_extractl and
+ vec_extractr built-in functions.
+
2020-05-13 Richard Biener <rguenther@suse.de>
* target.def (add_stmt_cost): Add new vectype parameter.
#define vec_genpcvm(a, b) __builtin_vec_xxgenpcvm (a, b)
/* Overloaded built-in functions for future architecture. */
+#define vec_extractl(a, b, c) __builtin_vec_extractl (a, b, c)
+#define vec_extracth(a, b, c) __builtin_vec_extracth (a, b, c)
+
#define vec_gnb(a, b) __builtin_vec_gnb (a, b)
#define vec_clrl(a, b) __builtin_vec_clrl (a, b)
#define vec_clrr(a, b) __builtin_vec_clrr (a, b)
UNSPEC_XXEVAL
UNSPEC_VSTRIR
UNSPEC_VSTRIL
+ UNSPEC_EXTRACTL
+ UNSPEC_EXTRACTR
])
(define_c_enum "unspecv"
DONE;
})
+(define_expand "vextractl<mode>"
+ [(set (match_operand:V2DI 0 "altivec_register_operand")
+ (unspec:V2DI [(match_operand:VI2 1 "altivec_register_operand")
+ (match_operand:VI2 2 "altivec_register_operand")
+ (match_operand:SI 3 "register_operand")]
+ UNSPEC_EXTRACTL))]
+ "TARGET_FUTURE"
+{
+ if (BYTES_BIG_ENDIAN)
+ {
+ emit_insn (gen_vextractl<mode>_internal (operands[0], operands[1],
+ operands[2], operands[3]));
+ emit_insn (gen_xxswapd_v2di (operands[0], operands[0]));
+ }
+ else
+ emit_insn (gen_vextractr<mode>_internal (operands[0], operands[2],
+ operands[1], operands[3]));
+ DONE;
+})
+
+(define_insn "vextractl<mode>_internal"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (unspec:V2DI [(match_operand:VEC_I 1 "altivec_register_operand" "v")
+ (match_operand:VEC_I 2 "altivec_register_operand" "v")
+ (match_operand:SI 3 "register_operand" "r")]
+ UNSPEC_EXTRACTL))]
+ "TARGET_FUTURE"
+ "vext<du_or_d><wd>vlx %0,%1,%2,%3"
+ [(set_attr "type" "vecsimple")])
+
+(define_expand "vextractr<mode>"
+ [(set (match_operand:V2DI 0 "altivec_register_operand")
+ (unspec:V2DI [(match_operand:VI2 1 "altivec_register_operand")
+ (match_operand:VI2 2 "altivec_register_operand")
+ (match_operand:SI 3 "register_operand")]
+ UNSPEC_EXTRACTR))]
+ "TARGET_FUTURE"
+{
+ if (BYTES_BIG_ENDIAN)
+ {
+ emit_insn (gen_vextractr<mode>_internal (operands[0], operands[1],
+ operands[2], operands[3]));
+ emit_insn (gen_xxswapd_v2di (operands[0], operands[0]));
+ }
+ else
+ emit_insn (gen_vextractl<mode>_internal (operands[0], operands[2],
+ operands[1], operands[3]));
+ DONE;
+})
+
+(define_insn "vextractr<mode>_internal"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (unspec:V2DI [(match_operand:VEC_I 1 "altivec_register_operand" "v")
+ (match_operand:VEC_I 2 "altivec_register_operand" "v")
+ (match_operand:SI 3 "register_operand" "r")]
+ UNSPEC_EXTRACTR))]
+ "TARGET_FUTURE"
+ "vext<du_or_d><wd>vrx %0,%1,%2,%3"
+ [(set_attr "type" "vecsimple")])
+
(define_expand "vstrir_<mode>"
[(set (match_operand:VIshort 0 "altivec_register_operand")
(unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")]
BU_FUTURE_V_2 (XXGENPCVM_V4SI, "xxgenpcvm_v4si", CONST, xxgenpcvm_v4si)
BU_FUTURE_V_2 (XXGENPCVM_V2DI, "xxgenpcvm_v2di", CONST, xxgenpcvm_v2di)
+BU_FUTURE_V_3 (VEXTRACTBL, "vextdubvlx", CONST, vextractlv16qi)
+BU_FUTURE_V_3 (VEXTRACTHL, "vextduhvlx", CONST, vextractlv8hi)
+BU_FUTURE_V_3 (VEXTRACTWL, "vextduwvlx", CONST, vextractlv4si)
+BU_FUTURE_V_3 (VEXTRACTDL, "vextddvlx", CONST, vextractlv2di)
+
+BU_FUTURE_V_3 (VEXTRACTBR, "vextdubvhx", CONST, vextractrv16qi)
+BU_FUTURE_V_3 (VEXTRACTHR, "vextduhvhx", CONST, vextractrv8hi)
+BU_FUTURE_V_3 (VEXTRACTWR, "vextduwvhx", CONST, vextractrv4si)
+BU_FUTURE_V_3 (VEXTRACTDR, "vextddvhx", CONST, vextractrv2di)
+
BU_FUTURE_V_1 (VSTRIBR, "vstribr", CONST, vstrir_v16qi)
BU_FUTURE_V_1 (VSTRIHR, "vstrihr", CONST, vstrir_v8hi)
BU_FUTURE_V_1 (VSTRIBL, "vstribl", CONST, vstril_v16qi)
BU_FUTURE_OVERLOAD_4 (XXEVAL, "xxeval")
BU_FUTURE_OVERLOAD_2 (XXGENPCVM, "xxgenpcvm")
+BU_FUTURE_OVERLOAD_3 (EXTRACTL, "extractl")
+BU_FUTURE_OVERLOAD_3 (EXTRACTH, "extracth")
+
BU_FUTURE_OVERLOAD_1 (VSTRIR, "strir")
BU_FUTURE_OVERLOAD_1 (VSTRIL, "stril")
RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI,
RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI },
+ { FUTURE_BUILTIN_VEC_EXTRACTL, FUTURE_BUILTIN_VEXTRACTBL,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V16QI,
+ RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTQI },
+ { FUTURE_BUILTIN_VEC_EXTRACTL, FUTURE_BUILTIN_VEXTRACTHL,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V8HI,
+ RS6000_BTI_unsigned_V8HI, RS6000_BTI_UINTQI },
+ { FUTURE_BUILTIN_VEC_EXTRACTL, FUTURE_BUILTIN_VEXTRACTWL,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V4SI,
+ RS6000_BTI_unsigned_V4SI, RS6000_BTI_UINTQI },
+ { FUTURE_BUILTIN_VEC_EXTRACTL, FUTURE_BUILTIN_VEXTRACTDL,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_UINTQI },
+
+ { FUTURE_BUILTIN_VEC_EXTRACTH, FUTURE_BUILTIN_VEXTRACTBR,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V16QI,
+ RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTQI },
+ { FUTURE_BUILTIN_VEC_EXTRACTH, FUTURE_BUILTIN_VEXTRACTHR,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V8HI,
+ RS6000_BTI_unsigned_V8HI, RS6000_BTI_UINTQI },
+ { FUTURE_BUILTIN_VEC_EXTRACTH, FUTURE_BUILTIN_VEXTRACTWR,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V4SI,
+ RS6000_BTI_unsigned_V4SI, RS6000_BTI_UINTQI },
+ { FUTURE_BUILTIN_VEC_EXTRACTH, FUTURE_BUILTIN_VEXTRACTDR,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
+ RS6000_BTI_unsigned_V2DI, RS6000_BTI_UINTQI },
+
{ FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIBL,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 },
{ FUTURE_BUILTIN_VEC_VSTRIL, FUTURE_BUILTIN_VSTRIBL,
case CRYPTO_BUILTIN_VSHASIGMAW:
case CRYPTO_BUILTIN_VSHASIGMAD:
case CRYPTO_BUILTIN_VSHASIGMA:
+ case FUTURE_BUILTIN_VEXTRACTBL:
+ case FUTURE_BUILTIN_VEXTRACTHL:
+ case FUTURE_BUILTIN_VEXTRACTWL:
+ case FUTURE_BUILTIN_VEXTRACTDL:
+ case FUTURE_BUILTIN_VEXTRACTBR:
+ case FUTURE_BUILTIN_VEXTRACTHR:
+ case FUTURE_BUILTIN_VEXTRACTWR:
+ case FUTURE_BUILTIN_VEXTRACTDR:
h.uns_p[0] = 1;
h.uns_p[1] = 1;
h.uns_p[2] = 1;
tree opaque_ftype_opaque = NULL_TREE;
tree opaque_ftype_opaque_opaque = NULL_TREE;
tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
+ tree opaque_ftype_opaque_opaque_opaque_opaque = NULL_TREE;
HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
/* Create Altivec and VSX builtins on machines with at least the
if (rs6000_overloaded_builtin_p (d->code))
{
- type = opaque_ftype_opaque_opaque_opaque;
+ type = opaque_ftype_opaque_opaque_opaque_opaque;
if (!type)
- type = opaque_ftype_opaque_opaque_opaque
+ type = opaque_ftype_opaque_opaque_opaque_opaque
= build_function_type_list (opaque_V4SI_type_node,
opaque_V4SI_type_node,
opaque_V4SI_type_node,
(V1TI "q")
(TI "q")])
+; For double extract from different origin types
+(define_mode_attr du_or_d [(QI "du")
+ (HI "du")
+ (SI "du")
+ (DI "d")
+ (V16QI "du")
+ (V8HI "du")
+ (V4SI "du")
+ (V2DI "d")])
+
;; How many bits in this mode?
(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
(SF "32") (DF "64")])
integer value between 2 and 7 inclusive.
@findex vec_gnb
+@smallexample
+@exdent vector unsigned long long int
+@exdent vec_extractl (vector unsigned char, vector unsigned char, unsigned int)
+@exdent vector unsigned long long int
+@exdent vec_extractl (vector unsigned short, vector unsigned short, unsigned int)
+@exdent vector unsigned long long int
+@exdent vec_extractl (vector unsigned int, vector unsigned int, unsigned int)
+@exdent vector unsigned long long int
+@exdent vec_extractl (vector unsigned long long, vector unsigned long long, unsigned int)
+@end smallexample
+Extract a single element from the vector formed by catenating this function's
+first two arguments at the byte offset specified by this function's
+third argument. On big-endian targets, this function behaves as if
+implemented by the Future @code{vextdubvlx}, @code{vextduhvlx},
+@code{vextduwvlx}, or @code{vextddvlx} instructions, depending on the
+types of the function's first two arguments. On little-endian
+targets, this function behaves as if implemented by the Future
+@code{vextdubvrx}, @code{vextduhvrx},
+@code{vextduwvrx}, or @code{vextddvrx} instructions.
+The byte offset of the element to be extracted is calculated
+by computing the remainder of dividing the third argument by 32.
+If this reminader value is not a multiple of the vector element size,
+or if its value added to the vector element size exceeds 32, the
+result is undefined.
+@findex vec_extractl
+
+@smallexample
+@exdent vector unsigned long long int
+@exdent vec_extractr (vector unsigned char, vector unsigned char, unsigned int)
+@exdent vector unsigned long long int
+@exdent vec_extractr (vector unsigned short, vector unsigned short, unsigned int)
+@exdent vector unsigned long long int
+@exdent vec_extractr (vector unsigned int, vector unsigned int, unsigned int)
+@exdent vector unsigned long long int
+@exdent vec_extractr (vector unsigned long long, vector unsigned long long, unsigned int)
+@end smallexample
+Extract a single element from the vector formed by catenating this function's
+first two arguments at the byte offset calculated by subtracting this
+function's third argument from 31. On big-endian targets, this
+function behaves as if
+implemented by the Future
+@code{vextdubvrx}, @code{vextduhvrx},
+@code{vextduwvrx}, or @code{vextddvrx} instructions, depending on the
+types of the function's first two arguments.
+On little-endian
+targets, this function behaves as if implemented by the Future
+@code{vextdubvlx}, @code{vextduhvlx},
+@code{vextduwvlx}, or @code{vextddvlx} instructions.
+The byte offset of the element to be extracted, measured from the
+right end of the catenation of the two vector arguments, is calculated
+by computing the remainder of dividing the third argument by 32.
+If this reminader value is not a multiple of the vector element size,
+or if its value added to the vector element size exceeds 32, the
+result is undefined.
+@findex vec_extractr
+
@smallexample
@exdent vector unsigned long long int
@exdent vec_pdep (vector unsigned long long int, vector unsigned long long int)
+2020-05-13 Kelvin Nilsen <kelvin@gcc.gnu.org>
+
+ * gcc.target/powerpc/vec-extracth-0.c: New.
+ * gcc.target/powerpc/vec-extracth-1.c: New.
+ * gcc.target/powerpc/vec-extracth-2.c: New.
+ * gcc.target/powerpc/vec-extracth-3.c: New.
+ * gcc.target/powerpc/vec-extracth-4.c: New.
+ * gcc.target/powerpc/vec-extracth-5.c: New.
+ * gcc.target/powerpc/vec-extracth-6.c: New.
+ * gcc.target/powerpc/vec-extracth-7.c: New.
+ * gcc.target/powerpc/vec-extracth-be-0.c: New.
+ * gcc.target/powerpc/vec-extracth-be-1.c: New.
+ * gcc.target/powerpc/vec-extracth-be-2.c: New.
+ * gcc.target/powerpc/vec-extracth-be-3.c: New.
+ * gcc.target/powerpc/vec-extractl-0.c: New.
+ * gcc.target/powerpc/vec-extractl-1.c: New.
+ * gcc.target/powerpc/vec-extractl-2.c: New.
+ * gcc.target/powerpc/vec-extractl-3.c: New.
+ * gcc.target/powerpc/vec-extractl-4.c: New.
+ * gcc.target/powerpc/vec-extractl-5.c: New.
+ * gcc.target/powerpc/vec-extractl-6.c: New.
+ * gcc.target/powerpc/vec-extractl-7.c: New.
+ * gcc.target/powerpc/vec-extractl-be-0.c: New.
+ * gcc.target/powerpc/vec-extractl-be-1.c: New.
+ * gcc.target/powerpc/vec-extractl-be-2.c: New.
+ * gcc.target/powerpc/vec-extractl-be-3.c: New.
+
2020-05-13 Patrick Palka <ppalka@redhat.com>
PR c++/79706
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned char source_a = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ vector unsigned char source_b = {
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 15 };
+ vector unsigned long long int result_3 = { 0, 11 };
+ vector unsigned long long int result_4 = { 0, 23 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 15), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 4), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 24), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextdubvlx\M} { target le } } } */
+/* { dg-final { scan-assembler {\mvextdubvrx\M} { target be } } } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned char source_a = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ vector unsigned char source_b = {
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 15 };
+ vector unsigned long long int result_3 = { 0, 11 };
+ vector unsigned long long int result_4 = { 0, 23 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 15), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 4), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 24), result_4))
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned short source_a = { 0, 2, 4, 6, 8, 10, 12, 14 };
+ vector unsigned short source_b = { 16, 18, 20, 22, 24, 26, 28, 30 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 14 };
+ vector unsigned long long int result_3 = { 0, 6 };
+ vector unsigned long long int result_4 = { 0, 18 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 14), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextduhvlx\M} { target le } } } */
+/* { dg-final { scan-assembler {\mvextduhvrx\M} { target be } } } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned short source_a = { 0, 2, 4, 6, 8, 10, 12, 14 };
+ vector unsigned short source_b = { 16, 18, 20, 22, 24, 26, 28, 30 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 14 };
+ vector unsigned long long int result_3 = { 0, 6 };
+ vector unsigned long long int result_4 = { 0, 18 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 14), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned int source_a = { 0, 4, 8, 12 };
+ vector unsigned int source_b = { 16, 20, 24, 28 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 12 };
+ vector unsigned long long int result_3 = { 0, 4 };
+ vector unsigned long long int result_4 = { 0, 16 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 12), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextduwvlx\M} { target le } } } */
+/* { dg-final { scan-assembler {\mvextduwvrx\M} { target be } } } */
--- /dev/null
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned int source_a = { 0, 4, 8, 12 };
+ vector unsigned int source_b = { 16, 20, 24, 28 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 12 };
+ vector unsigned long long int result_3 = { 0, 4 };
+ vector unsigned long long int result_4 = { 0, 16 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 12), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned long long source_a = { 0, 14 };
+ vector unsigned long long source_b = { 16, 30 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 14 };
+ vector unsigned long long int result_3 = { 0, 0 };
+ vector unsigned long long int result_4 = { 0, 30 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 8), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 16), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextddvlx\M} { target le } } } */
+/* { dg-final { scan-assembler {\mvextddvrx\M} { target be } } } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned long long source_a = { 0, 14 };
+ vector unsigned long long source_b = { 16, 30 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 14 };
+ vector unsigned long long int result_3 = { 0, 0 };
+ vector unsigned long long int result_4 = { 0, 30 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 8), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 16), result_4))
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future -mbig-endian" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned char source_a = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ vector unsigned char source_b = {
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 15 };
+ vector unsigned long long int result_3 = { 0, 11 };
+ vector unsigned long long int result_4 = { 0, 23 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 15), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 4), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 24), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextdubvrx\M} } } */
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future -mbig-endian" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned short source_a = { 0, 2, 4, 6, 8, 10, 12, 14 };
+ vector unsigned short source_b = { 16, 18, 20, 22, 24, 26, 28, 30 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 14 };
+ vector unsigned long long int result_3 = { 0, 6 };
+ vector unsigned long long int result_4 = { 0, 18 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 14), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextduhvrx\M} } } */
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future -mbig-endian" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned int source_a = { 0, 4, 8, 12 };
+ vector unsigned int source_b = { 16, 20, 24, 28 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 12 };
+ vector unsigned long long int result_3 = { 0, 4 };
+ vector unsigned long long int result_4 = { 0, 16 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 12), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextduwvrx\M} } } */
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future -mbig-endian" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned long long source_a = { 0, 14 };
+ vector unsigned long long source_b = { 16, 30 };
+
+ vector unsigned long long int result_1 = { 0, 16 };
+ vector unsigned long long int result_2 = { 0, 14 };
+ vector unsigned long long int result_3 = { 0, 0 };
+ vector unsigned long long int result_4 = { 0, 30 };
+
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 8), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extracth (source_b, source_a, 16), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextddvrx\M} } } */
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned char source_a = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ vector unsigned char source_b = {
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
+
+ vector unsigned long long int result_1 = { 0, 15 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 20 };
+ vector unsigned long long int result_4 = { 0, 8 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 15), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 4), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 24), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextdubvrx\M} { target le } } } */
+/* { dg-final { scan-assembler {\mvextdubvlx\M} { target be } } } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned char source_a = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ vector unsigned char source_b = {
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
+
+ vector unsigned long long int result_1 = { 0, 15 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 20 };
+ vector unsigned long long int result_4 = { 0, 8 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 15), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 4), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 24), result_4))
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned short source_a = { 0, 2, 4, 6, 8, 10, 12, 14 };
+ vector unsigned short source_b = { 16, 18, 20, 22, 24, 26, 28, 30 };
+
+ vector unsigned long long int result_1 = { 0, 14 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 24 };
+ vector unsigned long long int result_4 = { 0, 12 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 14), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextduhvrx\M} { target le } } } */
+/* { dg-final { scan-assembler {\mvextduhvlx\M} { target be } } } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned short source_a = { 0, 2, 4, 6, 8, 10, 12, 14 };
+ vector unsigned short source_b = { 16, 18, 20, 22, 24, 26, 28, 30 };
+
+ vector unsigned long long int result_1 = { 0, 14 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 24 };
+ vector unsigned long long int result_4 = { 0, 12 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 14), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned int source_a = { 0, 4, 8, 12 };
+ vector unsigned int source_b = { 16, 20, 24, 28 };
+
+ vector unsigned long long int result_1 = { 0, 12 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 24 };
+ vector unsigned long long int result_4 = { 0, 4 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 12), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 20), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextduwvrx\M} { target le } } } */
+/* { dg-final { scan-assembler {\mvextduwvlx\M} { target be } } } */
--- /dev/null
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned int source_a = { 0, 4, 8, 12 };
+ vector unsigned int source_b = { 16, 20, 24, 28 };
+
+ vector unsigned long long int result_1 = { 0, 12 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 24 };
+ vector unsigned long long int result_4 = { 0, 4 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 12), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 20), result_4))
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned long long source_a = { 0, 14 };
+ vector unsigned long long source_b = { 16, 30 };
+
+ vector unsigned long long int result_1 = { 0, 14 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 30 };
+ vector unsigned long long int result_4 = { 0, 0 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 8), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 16), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextddvrx\M} { target le } } } */
+/* { dg-final { scan-assembler {\mvextddvlx\M} { target be } } } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target powerpc_future_hw } */
+/* { dg-options "-mdejagnu-cpu=future" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned long long source_a = { 0, 14 };
+ vector unsigned long long source_b = { 16, 30 };
+
+ vector unsigned long long int result_1 = { 0, 14 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 30 };
+ vector unsigned long long int result_4 = { 0, 0 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 8), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 16), result_4))
+ abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future -mbig-endian" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned char source_a = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ vector unsigned char source_b = {
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
+
+ vector unsigned long long int result_1 = { 0, 15 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 20 };
+ vector unsigned long long int result_4 = { 0, 8 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 15), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 4), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 24), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextdubvlx\M} } } */
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future -mbig-endian" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned short source_a = { 0, 2, 4, 6, 8, 10, 12, 14 };
+ vector unsigned short source_b = { 16, 18, 20, 22, 24, 26, 28, 30 };
+
+ vector unsigned long long int result_1 = { 0, 14 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 24 };
+ vector unsigned long long int result_4 = { 0, 12 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 14), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 28), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextduhvlx\M} } } */
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future -mbig-endian" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned int source_a = { 0, 4, 8, 12 };
+ vector unsigned int source_b = { 16, 20, 24, 28 };
+
+ vector unsigned long long int result_1 = { 0, 12 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 24 };
+ vector unsigned long long int result_4 = { 0, 4 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 12), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 20), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextduwvlx\M} } } */
--- /dev/null
+/* { dg-options "-mdejagnu-cpu=future -mbig-endian" } */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+int
+main (int argc, char *argv [])
+{
+ vector unsigned long long source_a = { 0, 14 };
+ vector unsigned long long source_b = { 16, 30 };
+
+ vector unsigned long long int result_1 = { 0, 14 };
+ vector unsigned long long int result_2 = { 0, 16 };
+ vector unsigned long long int result_3 = { 0, 30 };
+ vector unsigned long long int result_4 = { 0, 0 };
+
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 8), result_1))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_a, source_b, 16), result_2))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 8), result_3))
+ abort ();
+ if (!vec_all_eq (vec_extractl (source_b, source_a, 16), result_4))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler {\mvextddvlx\M} } } */