]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
s390: Fully exploit vgm, vgbm, vrepi
authorStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Fri, 12 Jul 2024 11:42:08 +0000 (13:42 +0200)
committerStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Fri, 12 Jul 2024 11:42:08 +0000 (13:42 +0200)
Currently instructions vgm and vrepi are utilized only for constant
vectors where the element mode equals the element mode of the
corresponding instruction.  This patch lifts this restriction by making
use of those instructions for constant vectors even if element modes
do not coincide.  For example, the constant vector

  (v2di){0x7ffffffe7ffffffe, 0x7ffffffe7ffffffe}

can be loaded via vgmf %v0,1,30.  Similar, the constant vector

  (v4si){0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}

can be loaded via vrepiq %v0,-86.

Analog, if the element mode of a constant vector is smaller than the
element mode of a corresponding instruction, we still may make use of
those instructions.  For example, the constant vector

  (v4si){0x7fff, 0xfffe0000, 0x7fff, 0xfffe0000}

can be loaded via vgmg %v0,17,46.  Similar, the constant vector

  (v4si){-1, -16643, -1, -16643}

can be loaded via vrepig %v0,-16643.

Additionally this patch enables vgm, vgbm, vrepi for partial vectors,
i.e., vectors of size less than 16 bytes.  Basically this is done by
treating a vector as a full vector resulting in replicating constants
into the ignored bits whereas vgbm sets those to zero.

Furthermore, there is no restriction to integer vectors anymore, i.e.,
supporting scalars of mode up to and including TI and TF and also
floating-point vectors.

Here are some numbers how often instructions are emitted for SPEC 2017:

        w/o patch     w/ patch
vgbm          140          365
vgm         17508        24452
vrepi        1360         2775

I expect most (maybe even all) to save us a load from the literal pool.

gcc/ChangeLog:

* config/s390/2964.md: Remove extended mnemonics for vgm.
* config/s390/3906.md: Remove extended mnemonics for vgm.
* config/s390/3931.md: Remove extended mnemonics for vgm.
* config/s390/8561.md: Remove extended mnemonics for vgm.
* config/s390/constraints.md (jKK): Remove constraint.
(jzz): Add constraint.
* config/s390/s390-protos.h (s390_contiguous_bitmask_vector_p):
Add prototype.
(s390_constant_via_vgm_p): Add prototype.
(s390_constant_via_vrepi_p): Add prototype.
* config/s390/s390.cc (s390_contiguous_bitmask_vector_p): New
function.
(s390_constant_via_vgm_vrepi_helper): New function.
(s390_constant_via_vgm_p): New function.
(s390_constant_via_vgbm_p): For the sake of symmetry rename
s390_bytemask_vector_p into s390_constant_via_vgbm_p.
(s390_bytemask_vector_p): Deal with non-integer and partial
vectors.
(s390_constant_via_vrepi_p): New function.
(s390_legitimate_constant_p): Allow partial vectors.
(legitimate_reload_constant_p): Fix indentation.
(legitimate_reload_vector_constant_p): Restrict to constraints
j00, jm1, jxx, jyy, jzz only, i.e., allow partial vectors.
(s390_expand_vec_init): Also make use of vrepi if possible.
(print_operand): Add q,p,r for vgm,vrepi,vgbm, respectively.
Remove e,s,t for constant vectors.
* config/s390/s390.md (movti): Add variants utilizing
vgbm,vgm,vrepi.
* config/s390/vector.md (mov<mode><tf_vr>): Adapt variants
for vgbm,vgm,vrepi for the new scheme.
(mov<mode>): Adapt variants for vgbm,vgm for the new
scheme and add vrepi variant for modes V_8,V_16,V_32,V_64.

gcc/testsuite/ChangeLog:

* gcc.target/s390/vector/vec-copysign.c: Change to non-extended
mnemonic.
* gcc.target/s390/vector/vec-genmask-1.c: Change to non-extended
mnemonic.
* gcc.target/s390/vector/vec-init-1.c: Change to non-extended
mnemonic.
* gcc.target/s390/vector/vec-vrepi-1.c: Change to non-extended
mnemonic.
* gcc.target/s390/zvector/autovec-double-quiet-uneq.c: Change to
non-extended mnemonic.
* gcc.target/s390/zvector/autovec-float-quiet-uneq.c: Change to
non-extended mnemonic.
* gcc.target/s390/zvector/vec-genmask-1.c: Change to
non-extended mnemonic.
* gcc.target/s390/zvector/vec-splat-1.c: Change to non-extended
mnemonic.
* gcc.target/s390/zvector/vec-splat-2.c: Change to non-extended
mnemonic.
* gcc.target/s390/vector/vgbm-double-1.c: New test.
* gcc.target/s390/vector/vgbm-float-1.c: New test.
* gcc.target/s390/vector/vgbm-int128-1.c: New test.
* gcc.target/s390/vector/vgbm-integer-1.c: New test.
* gcc.target/s390/vector/vgbm-longdouble-1.c: New test.
* gcc.target/s390/vector/vgm-df-1.c: New test.
* gcc.target/s390/vector/vgm-di-1.c: New test.
* gcc.target/s390/vector/vgm-hi-1.c: New test.
* gcc.target/s390/vector/vgm-int128-1.c: New test.
* gcc.target/s390/vector/vgm-longdouble-1.c: New test.
* gcc.target/s390/vector/vgm-qi-1.c: New test.
* gcc.target/s390/vector/vgm-sf-1.c: New test.
* gcc.target/s390/vector/vgm-si-1.c: New test.
* gcc.target/s390/vector/vgm-tf-1.c: New test.
* gcc.target/s390/vector/vgm-ti-1.c: New test.
* gcc.target/s390/vector/vrepi-df-1.c: New test.
* gcc.target/s390/vector/vrepi-di-1.c: New test.
* gcc.target/s390/vector/vrepi-hi-1.c: New test.
* gcc.target/s390/vector/vrepi-int128-1.c: New test.
* gcc.target/s390/vector/vrepi-qi-1.c: New test.
* gcc.target/s390/vector/vrepi-sf-1.c: New test.
* gcc.target/s390/vector/vrepi-si-1.c: New test.
* gcc.target/s390/vector/vrepi-tf-1.c: New test.
* gcc.target/s390/vector/vrepi-ti-1.c: New test.

42 files changed:
gcc/config/s390/2964.md
gcc/config/s390/3906.md
gcc/config/s390/3931.md
gcc/config/s390/8561.md
gcc/config/s390/constraints.md
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.cc
gcc/config/s390/s390.md
gcc/config/s390/vector.md
gcc/testsuite/gcc.target/s390/vector/vec-copysign.c
gcc/testsuite/gcc.target/s390/vector/vec-genmask-1.c
gcc/testsuite/gcc.target/s390/vector/vec-init-1.c
gcc/testsuite/gcc.target/s390/vector/vec-vrepi-1.c
gcc/testsuite/gcc.target/s390/vector/vgbm-double-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgbm-float-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgbm-int128-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgbm-integer-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgbm-longdouble-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-df-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-di-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-hi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-int128-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-longdouble-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-qi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-sf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-si-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-tf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vgm-ti-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-df-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-di-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-hi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-int128-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-qi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-sf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-si-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-tf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vrepi-ti-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/zvector/autovec-double-quiet-uneq.c
gcc/testsuite/gcc.target/s390/zvector/autovec-float-quiet-uneq.c
gcc/testsuite/gcc.target/s390/zvector/vec-genmask-1.c
gcc/testsuite/gcc.target/s390/zvector/vec-splat-1.c
gcc/testsuite/gcc.target/s390/zvector/vec-splat-2.c

index 21ef972a206cba57d95d6654290c739fb2bb3e6c..83f97da474769b5899bc5eb5abf05fd6247d759b 100644 (file)
@@ -92,7 +92,7 @@ vfchedb,vfchedbs,vfchesb,vfchesbs,vfchsb,vfchsbs,vfeeb,vfeef,vfeeh,vfeezbs,\
 vfeezhs,vfeneb,vfenef,vfeneh,vfenezb,vfenezf,vfenezh,vfidb,vfisb,vflcdb,\
 vflcsb,vflndb,vflnsb,vflpdb,vfmadb,vfmasb,vfmdb,vfmsb,vfmsdb,vfmssb,vfsdb,\
 vfssb,vftcidb,vftcisb,vgbm,vgfmab,vgfmaf,vgfmag,vgfmah,vgfmb,vgfmf,vgfmg,\
-vgfmh,vgm,vgmb,vgmf,vgmg,vgmh,vistrb,vistrbs,vistrf,vistrfs,vistrh,vlcb,\
+vgfmh,vgm,vistrb,vistrbs,vistrf,vistrfs,vistrh,vlcb,\
 vlcf,vlcg,vlch,vldeb,vleb,vledb,vlef,vleg,vleh,vleib,vleif,vleig,vleih,\
 vlpb,vlpf,vlpg,vlph,vmaeb,vmaef,vmaeh,vmahb,vmahf,vmahh,vmalb,vmaleb,\
 vmalef,vmaleh,vmalf,vmalhb,vmalhf,vmalhh,vmalhw,vmalob,vmalof,vmaloh,vmaob,\
@@ -178,7 +178,7 @@ verllb,verllf,verllg,verllh,verllvb,verllvf,verllvg,verllvh,veslb,veslf,\
 veslg,veslh,veslvb,veslvf,veslvg,veslvh,vesrab,vesraf,vesrag,vesrah,vesravb,\
 vesravf,vesravg,vesravh,vesrlb,vesrlf,vesrlg,vesrlh,vesrlvb,vesrlvf,vesrlvg,\
 vesrlvh,vfcedb,vfcesb,vfchdb,vfchedb,vfchesb,vfchsb,vflcdb,vflcsb,vflndb,\
-vflnsb,vflpdb,vgbm,vgm,vgmb,vgmf,vgmg,vgmh,vlcb,vlcf,vlcg,vlch,vleb,vlef,\
+vflnsb,vflpdb,vgbm,vgm,vlcb,vlcf,vlcg,vlch,vleb,vlef,\
 vleg,vleh,vleib,vleif,vleig,vleih,vlpb,vlpf,vlpg,vlph,vmnb,vmnf,vmng,vmnh,\
 vmnlb,vmnlf,vmnlg,vmnlh,vmrhb,vmrhf,vmrhg,vmrhh,vmrlb,vmrlf,vmrlg,vmrlh,\
 vmxb,vmxf,vmxg,vmxh,vn,vnc,vno,vnot,vo,vone,vpdi,vperm,vpkf,vpkg,vpkh,\
index e0ba59941fed33816a4b7e323e7c809dce164657..7da2e657e3b285a697c1360dd6b3da44005e13c6 100644 (file)
@@ -95,7 +95,7 @@ vfeezbs,vfeezhs,vfeneb,vfenef,vfeneh,vfenezb,vfenezf,vfenezh,vfidb,vfisb,\
 vflcdb,vflcsb,vflndb,vflnsb,vflpdb,vfmadb,vfmasb,vfmaxdb,vfmaxsb,vfmdb,\
 vfmindb,vfminsb,vfmsb,vfmsdb,vfmssb,vfnmadb,vfnmsdb,vfnmssb,vfsdb,vfssb,\
 vftcidb,vftcisb,vgbm,vgfmab,vgfmaf,vgfmag,vgfmah,vgfmb,vgfmf,vgfmg,vgfmh,vgm,\
-vgmb,vgmf,vgmg,vgmh,vistrb,vistrbs,vistrf,vistrfs,vistrh,vlcb,vlcf,vlcg,\
+vistrb,vistrbs,vistrf,vistrfs,vistrh,vlcb,vlcf,vlcg,\
 vlch,vldeb,vleb,vledb,vlef,vleg,vleh,vleib,vleif,vleig,vleih,vlpb,vlpf,\
 vlpg,vlph,vmaeb,vmaef,vmaeh,vmahb,vmahf,vmahh,vmalb,vmaleb,vmalef,vmaleh,\
 vmalf,vmalhb,vmalhf,vmalhh,vmalhw,vmalob,vmalof,vmaloh,vmaob,vmaof,vmaoh,\
@@ -183,7 +183,7 @@ verllf,verllg,verllh,verllvb,verllvf,verllvg,verllvh,veslb,veslf,veslg,veslh,\
 veslvb,veslvf,veslvg,veslvh,vesrab,vesraf,vesrag,vesrah,vesravb,vesravf,\
 vesravg,vesravh,vesrlb,vesrlf,vesrlg,vesrlh,vesrlvb,vesrlvf,vesrlvg,vesrlvh,\
 vfcedb,vfcesb,vfchdb,vfchedb,vfchesb,vfchsb,vflcdb,vflcsb,vflndb,vflnsb,\
-vflpdb,vfmaxdb,vfmaxsb,vfmindb,vfminsb,vgbm,vgm,vgmb,vgmf,vgmg,vgmh,vlcb,\
+vflpdb,vfmaxdb,vfmaxsb,vfmindb,vfminsb,vgbm,vgm,vlcb,\
 vlcf,vlcg,vlch,vleb,vlef,vleg,vleh,vleib,vleif,vleig,vleih,vlpb,vlpf,vlpg,\
 vlph,vmnb,vmnf,vmng,vmnh,vmnlb,vmnlf,vmnlg,vmnlh,vmrhb,vmrhf,vmrhg,vmrhh,\
 vmrlb,vmrlf,vmrlg,vmrlh,vmxb,vmxf,vmxg,vmxh,vn,vnc,vnn,vno,vnot,vnx,vo,voc,\
index 740e0f3718f921a1603187f9232864276d61a350..632c2456b6a32b36f6aab51c93683823b270bfdd 100644 (file)
@@ -944,10 +944,6 @@ vgfmf,
 vgfmg,
 vgfmh,
 vgm,
-vgmb,
-vgmf,
-vgmg,
-vgmh,
 vistrb,
 vistrbs,
 vistrf,
@@ -1854,10 +1850,6 @@ vfmindb,
 vfminsb,
 vgbm,
 vgm,
-vgmb,
-vgmf,
-vgmg,
-vgmh,
 vlcb,
 vlcf,
 vlcg,
index ca6984de886590904910dca7e151b4b2dcf3348c..6e2daf21c74c7c7b5f4aae9897570e04c75aca91 100644 (file)
@@ -94,7 +94,7 @@ vfeezfs,vfeezhs,vfeneb,vfenef,vfeneh,vfenezb,vfenezf,vfenezh,vfidb,vfisb,\
 vflcdb,vflcsb,vflndb,vflnsb,vflpdb,vflpsb,vfmadb,vfmasb,vfmaxdb,vfmaxsb,\
 vfmdb,vfmindb,vfminsb,vfmsb,vfmsdb,vfmssb,vfnmadb,vfnmasb,vfnmsdb,vfnmssb,\
 vfsdb,vfssb,vftcidb,vftcisb,vgbm,vgfmab,vgfmaf,vgfmag,vgfmah,vgfmb,vgfmf,\
-vgfmg,vgfmh,vgm,vgmb,vgmf,vgmg,vgmh,vistrb,vistrbs,vistrf,vistrfs,vistrh,\
+vgfmg,vgfmh,vgm,vistrb,vistrbs,vistrf,vistrfs,vistrh,\
 vistrhs,vlcb,vlcf,vlcg,vlch,vldeb,vleb,vledb,vlef,vleg,vleh,vleib,vleif,vleig,\
 vleih,vlpb,vlpf,vlpg,vlph,vmaeb,vmaef,vmaeh,vmahb,vmahf,vmahh,vmalb,vmaleb,\
 vmalef,vmaleh,vmalf,vmalhb,vmalhf,vmalhh,vmalhw,vmalob,vmalof,vmaloh,vmaob,\
@@ -185,7 +185,7 @@ verllvg,verllvh,veslb,veslf,veslg,veslh,veslvb,veslvf,veslvg,veslvh,vesrab,\
 vesraf,vesrag,vesrah,vesravb,vesravf,vesravg,vesravh,vesrlb,vesrlf,vesrlg,\
 vesrlh,vesrlvb,vesrlvf,vesrlvg,vesrlvh,vfcedb,vfcesb,vfchdb,vfchedb,vfchesb,\
 vfchsb,vflcdb,vflcsb,vflndb,vflnsb,vflpdb,vflpsb,vfmaxdb,vfmaxsb,vfmindb,\
-vfminsb,vgbm,vgm,vgmb,vgmf,vgmg,vgmh,vlcb,vlcf,vlcg,vlch,vleb,vlef,vleg,vleh,\
+vfminsb,vgbm,vgm,vlcb,vlcf,vlcg,vlch,vleb,vlef,vleg,vleh,\
 vleib,vleif,vleig,vleih,vlpb,vlpf,vlpg,vlph,vmnb,vmnf,vmng,vmnh,vmnlb,vmnlf,\
 vmnlg,vmnlh,vmrhb,vmrhf,vmrhg,vmrhh,vmrlb,vmrlf,vmrlg,vmrlh,vmxb,vmxf,vmxg,\
 vmxh,vmxlb,vmxlf,vmxlg,vmxlh,vn,vnc,vnn,vno,vnot,vnx,vo,voc,vone,vpdi,\
index 51924cfd05d27add72c55abc36095d33f52a7ecf..3f498d2b6aaa3bc7c7348ca6130dd843851a843f 100644 (file)
@@ -34,8 +34,7 @@
 ;;         jm1: constant scalar or vector with all bits set
 ;;         jxx: contiguous bitmask of 0 or 1 in all vector elements
 ;;         jyy: constant consisting of byte chunks being either 0 or 0xff
-;;         jKK: constant vector with all elements having the same value and
-;;              matching K constraint
+;;         jzz: constant consisting of 16-bit chunks which may be sign-extended
 ;;         jm6: An integer operand with the lowest order 6 bits all ones.
 ;;         jdd: A constant operand that fits into the data section.
 ;;         j>f: An integer operand whose lower 32 bits are greater than or equal to 15
   "All one bit scalar or vector constant"
   (match_test "op == CONSTM1_RTX (GET_MODE (op))"))
 
-; vector generate mask operand - support for up to 64 bit elements
+; vector generate mask operand
 (define_constraint "jxx"
   "@internal"
-  (and (match_code "const_vector")
-       (match_test "s390_contiguous_bitmask_vector_p (op, NULL, NULL)")))
+  (match_test "s390_constant_via_vgm_p (op, NULL, NULL, NULL)"))
 
-; vector generate byte mask operand - this is only supposed to deal
-; with real vectors 128 bit values of being either 0 or -1 are handled
-; with j00 and jm1
+; vector generate byte mask operand - constant 0 and -1 vectors are handled
+; by j00 and jm1, respectively.
 (define_constraint "jyy"
   "@internal"
-  (and (match_code "const_vector")
-       (match_test "s390_bytemask_vector_p (op, NULL)")))
+  (match_test "s390_constant_via_vgbm_p (op, NULL)"))
 
-; vector replicate immediate operand - support for up to 64 bit elements
-(define_constraint "jKK"
+; vector replicate immediate operand
+(define_constraint "jzz"
   "@internal"
-  (and (and (and (match_code "const_vector")
-                (match_test "const_vec_duplicate_p (op)"))
-           (match_test "GET_MODE_UNIT_SIZE (GET_MODE (op)) <= 8"))
-       (match_test "satisfies_constraint_K (XVECEXP (op, 0, 0))")))
+  (match_test "s390_constant_via_vrepi_p (op, NULL, NULL)"))
 
 (define_constraint "jm6"
   "@internal An integer operand with the lowest order 6 bits all ones."
index 8c2985a79c4dc4a976dbaa234c8835a48c3d2605..b4646ccb6060103d93c0e9fdddc7c2abd39ae26d 100644 (file)
@@ -75,8 +75,9 @@ extern int s390_const_double_ok_for_constraint_p (rtx, int, const char *);
 extern int s390_single_part (rtx, machine_mode, machine_mode, int);
 extern unsigned HOST_WIDE_INT s390_extract_part (rtx, machine_mode, int);
 extern bool s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT, bool, int, int *, int *);
-extern bool s390_contiguous_bitmask_vector_p (rtx, int *, int *);
-extern bool s390_bytemask_vector_p (rtx, unsigned *);
+extern bool s390_constant_via_vgm_p (rtx, machine_mode *, int *, int *);
+extern bool s390_constant_via_vrepi_p (rtx, machine_mode *, short *);
+extern bool s390_constant_via_vgbm_p (rtx, unsigned *);
 extern bool s390_split_ok_p (rtx, rtx, machine_mode, int);
 extern bool s390_overlap_p (rtx, rtx, HOST_WIDE_INT);
 extern bool s390_offset_p (rtx, rtx, rtx);
index 05a0fde7fb06026f1fab57380f4d452b96feceb3..7aea776da2f315cffd7186f092a6c62d27ef2a8a 100644 (file)
@@ -2663,67 +2663,205 @@ s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, bool wrap_p,
   return b;
 }
 
-/* Return true if OP contains the same contiguous bitfield in *all*
-   its elements.  START and END can be used to obtain the start and
-   end position of the bitfield.
+/* Return true if OP is a constant which fits into a vector register and if it
+   is a 16-byte constant, then the high and low half must equal.  Otherwise
+   return false.  The out parameter *VEC2 equals the high/low half for 16-byte
+   constants and for smaller constants it equals the concatination of constant
+   OP until an 8-byte constant is constructed.  */
 
-   START/STOP give the position of the first/last bit of the bitfield
-   counting from the lowest order bit starting with zero.  In order to
-   use these values for S/390 instructions this has to be converted to
-   "bits big endian" style.  */
+static bool
+s390_constant_via_vgm_vrepi_1 (rtx op, unsigned HOST_WIDE_INT *vec2)
+{
+  unsigned HOST_WIDE_INT vec;
+
+  if (GET_CODE (op) == CONST_VECTOR)
+    switch (GET_MODE_SIZE (GET_MODE (op)))
+      {
+      case 1:
+       {
+         rtx op_v1qi = gen_lowpart (V1QImode, op);
+         vec = UINTVAL (XVECEXP (op_v1qi, 0, 0));
+         vec &= GET_MODE_MASK (QImode);
+         vec |= vec <<  8;
+         vec |= vec << 16;
+         vec |= vec << 32;
+         *vec2 = vec;
+         return true;
+       }
+      case 2:
+       {
+         rtx op_v1hi = gen_lowpart (V1HImode, op);
+         vec = UINTVAL (XVECEXP (op_v1hi, 0, 0));
+         vec &= GET_MODE_MASK (HImode);
+         vec |= vec << 16;
+         vec |= vec << 32;
+         *vec2 = vec;
+         return true;
+       }
+      case 4:
+       {
+         rtx op_v1si = gen_lowpart (V1SImode, op);
+         vec = UINTVAL (XVECEXP (op_v1si, 0, 0));
+         vec &= GET_MODE_MASK (SImode);
+         vec |= vec << 32;
+         *vec2 = vec;
+         return true;
+       }
+      case 8:
+       {
+         rtx op_v1di = gen_lowpart (V1DImode, op);
+         vec = UINTVAL (XVECEXP (op_v1di, 0, 0));
+         *vec2 = vec;
+         return true;
+       }
+      case 16:
+       {
+         rtx op_v2di = gen_lowpart (V2DImode, op);
+         vec = UINTVAL (XVECEXP (op_v2di, 0, 0));
+         unsigned HOST_WIDE_INT tmp = UINTVAL (XVECEXP (op_v2di, 0, 1));
+         if (vec != tmp)
+           return false;
+         *vec2 = vec;
+         return true;
+       }
+      default:
+       return false;
+      }
+  else if (CONST_WIDE_INT_P (op) && CONST_WIDE_INT_NUNITS (op) == 2)
+    {
+      vec = CONST_WIDE_INT_ELT (op, 0);
+      unsigned HOST_WIDE_INT tmp = CONST_WIDE_INT_ELT (op, 1);
+      if (vec != tmp)
+       return false;
+      *vec2 = vec;
+      return true;
+    }
+  else if (CONST_DOUBLE_P (op) && GET_MODE (op) == TFmode)
+    {
+      long l[4];
+      const REAL_VALUE_TYPE *rv = CONST_DOUBLE_REAL_VALUE (op);
+      REAL_VALUE_TO_TARGET_LONG_DOUBLE (*rv, l);
+      vec = ((unsigned HOST_WIDE_INT) l[0] << 32)
+           | ((unsigned HOST_WIDE_INT) l[1] & 0xffffffffUL);
+      unsigned HOST_WIDE_INT tmp
+       = ((unsigned HOST_WIDE_INT) l[2] << 32)
+        | ((unsigned HOST_WIDE_INT) l[3] & 0xffffffffUL);
+      if (vec != tmp)
+       return false;
+      *vec2 = vec;
+      return true;
+    }
+  else
+    return false;
+}
+
+/* Return true if constant OP can be loaded via VGM.  Otherwise return false.
+   If MODE, START, and END are not null, then out parameter *MODE is the
+   element size of VGM, and *START and *END are the starting and ending bit
+   positions, respectively.  */
 
 bool
-s390_contiguous_bitmask_vector_p (rtx op, int *start, int *end)
+s390_constant_via_vgm_p (rtx op, machine_mode *mode, int *start, int *end)
 {
-  unsigned HOST_WIDE_INT mask;
-  int size;
-  rtx elt;
-  bool b;
-
-  /* Handle floats by bitcasting them to ints.  */
-  op = gen_lowpart (related_int_vector_mode (GET_MODE (op)).require (), op);
+  unsigned HOST_WIDE_INT vec;
 
-  gcc_assert (!!start == !!end);
-  if (!const_vec_duplicate_p (op, &elt)
-      || !CONST_INT_P (elt))
+  if (!s390_constant_via_vgm_vrepi_1 (op, &vec))
     return false;
 
-  size = GET_MODE_UNIT_BITSIZE (GET_MODE (op));
+  machine_mode iter;
+  FOR_EACH_MODE_UNTIL (iter, TImode)
+    {
+      unsigned HOST_WIDE_INT bits = vec & GET_MODE_MASK (iter);
+      bool b = s390_contiguous_bitmask_p (bits, true, GET_MODE_BITSIZE (iter),
+                                         start, end);
+      if (!b)
+       continue;
+      unsigned HOST_WIDE_INT vec2 = bits;
+      for (int i = 1; i < 8 / GET_MODE_SIZE (iter); ++i)
+       vec2 |= bits << (GET_MODE_BITSIZE (iter) * i);
+      if (vec == vec2)
+       {
+         if (mode && start && end)
+           {
+             *mode = iter;
+             *start -= (HOST_BITS_PER_WIDE_INT - GET_MODE_BITSIZE (iter));
+             *end -= (HOST_BITS_PER_WIDE_INT - GET_MODE_BITSIZE (iter));
+           }
+         return true;
+       }
+    }
+
+  return false;
+}
+
+/* Return true if constant OP can be loaded via VREPI.  Otherwise return false.
+   If MODE and IMM are not null, then out parameter *MODE is the element size
+   of VREPI, and *IMM is the signed integer immediate.  */
+
+bool
+s390_constant_via_vrepi_p (rtx op, machine_mode *mode, short *imm)
+{
+  unsigned HOST_WIDE_INT vec;
 
-  /* We cannot deal with V1TI/V1TF. This would require a vgmq.  */
-  if (size > 64)
+  if (!s390_constant_via_vgm_vrepi_1 (op, &vec))
     return false;
 
-  mask = UINTVAL (elt);
+  unsigned HOST_WIDE_INT bits = (short) (vec & 0xffff);
 
-  b = s390_contiguous_bitmask_p (mask, true, size, start, end);
-  if (b)
+  machine_mode iter;
+  FOR_EACH_MODE_UNTIL (iter, TImode)
     {
-      if (start)
+      unsigned HOST_WIDE_INT tmp = bits & GET_MODE_MASK (iter);
+      unsigned HOST_WIDE_INT vec2 = tmp;
+      for (int i = 1; i < 8 / GET_MODE_SIZE (iter); ++i)
+       vec2 |= tmp << (GET_MODE_BITSIZE (iter) * i);
+      if (vec == vec2)
        {
-         *start -= (HOST_BITS_PER_WIDE_INT - size);
-         *end -= (HOST_BITS_PER_WIDE_INT - size);
+         if (mode && imm)
+           {
+             *mode = iter;
+             /* Although, vrepib ignores the high half of the 16-bit mask,
+                canonicalize to an 8-bit sign-extended mask.  */
+             *imm = iter == QImode ? (signed char) (bits & 0xff)
+                                   : (short) (bits & 0xffff);
+           }
+         return true;
        }
-      return true;
     }
-  else
-    return false;
+
+  return false;
 }
 
-/* Return true if C consists only of byte chunks being either 0 or
+/* Return true if OP consists only of byte chunks being either 0 or
    0xff.  If MASK is !=NULL a byte mask is generated which is
    appropriate for the vector generate byte mask instruction.  */
 
 bool
-s390_bytemask_vector_p (rtx op, unsigned *mask)
+s390_constant_via_vgbm_p (rtx op, unsigned *mask)
 {
   int i;
   unsigned tmp_mask = 0;
   int nunit, unit_size;
 
-  if (!VECTOR_MODE_P (GET_MODE (op))
-      || GET_CODE (op) != CONST_VECTOR
-      || !CONST_INT_P (XVECEXP (op, 0, 0)))
+  if (GET_CODE (op) == CONST_VECTOR)
+    {
+      if (GET_MODE_INNER (GET_MODE (op)) == TImode
+         || GET_MODE_INNER (GET_MODE (op)) == TFmode)
+       /* For the sake of simplicity, bitcast 16-byte one-element vector
+          into two-element vector so we don't have to special case them in
+          the following.  */
+       op = gen_lowpart (V2DImode, op);
+      else
+       /* Handle floats by bitcasting them to ints.  */
+       op = gen_lowpart (related_int_vector_mode (GET_MODE (op)).require (),
+                         op);
+    }
+  else if ((CONST_WIDE_INT_P (op) && CONST_WIDE_INT_NUNITS (op) == 2)
+          || (CONST_DOUBLE_P (op) && GET_MODE (op) == TFmode))
+    /* For the sake of simplicity, bitcast the 16-byte constants into a vector
+       so we don't have to special case them in the following.  */
+    op = gen_lowpart (V2DImode, op);
+  else
     return false;
 
   nunit = GET_MODE_NUNITS (GET_MODE (op));
@@ -2734,9 +2872,6 @@ s390_bytemask_vector_p (rtx op, unsigned *mask)
       unsigned HOST_WIDE_INT c;
       int j;
 
-      if (!CONST_INT_P (XVECEXP (op, 0, i)))
-       return false;
-
       c = UINTVAL (XVECEXP (op, 0, i));
       for (j = 0; j < unit_size; j++)
        {
@@ -2748,7 +2883,7 @@ s390_bytemask_vector_p (rtx op, unsigned *mask)
     }
 
   if (mask != NULL)
-    *mask = tmp_mask;
+    *mask = tmp_mask << (16 - GET_MODE_SIZE (GET_MODE (op)));
 
   return true;
 }
@@ -4317,14 +4452,11 @@ legitimate_pic_operand_p (rtx op)
 static bool
 s390_legitimate_constant_p (machine_mode mode, rtx op)
 {
-  if (TARGET_VX && VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
+  if (TARGET_VX && GET_CODE (op) == CONST_VECTOR)
     {
-      if (GET_MODE_SIZE (mode) != 16)
-       return 0;
-
       if (!satisfies_constraint_j00 (op)
          && !satisfies_constraint_jm1 (op)
-         && !satisfies_constraint_jKK (op)
+         && !satisfies_constraint_jzz (op)
          && !satisfies_constraint_jxx (op)
          && !satisfies_constraint_jyy (op))
        return 0;
@@ -4457,7 +4589,7 @@ legitimate_reload_constant_p (rtx op)
       && GET_CODE (op) == CONST_INT
       && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
       && s390_single_part (op, word_mode, HImode, 0) >= 0)
-  return true;
+    return true;
 
   if (TARGET_EXTIMM
       && GET_CODE (op) == CONST_INT
@@ -4518,15 +4650,11 @@ legitimate_reload_fp_constant_p (rtx op)
 static bool
 legitimate_reload_vector_constant_p (rtx op)
 {
-  if (TARGET_VX && GET_MODE_SIZE (GET_MODE (op)) == 16
-      && (satisfies_constraint_j00 (op)
-         || satisfies_constraint_jm1 (op)
-         || satisfies_constraint_jKK (op)
-         || satisfies_constraint_jxx (op)
-         || satisfies_constraint_jyy (op)))
-    return true;
-
-  return false;
+  return TARGET_VX && (satisfies_constraint_j00 (op)
+                      || satisfies_constraint_jm1 (op)
+                      || satisfies_constraint_jzz (op)
+                      || satisfies_constraint_jxx (op)
+                      || satisfies_constraint_jyy (op));
 }
 
 /* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
@@ -7395,13 +7523,15 @@ s390_expand_vec_init (rtx target, rtx vals)
        all_regs = false;
     }
 
-  /* Use vector gen mask or vector gen byte mask if possible.  */
+  /* Use vector gen mask or vector gen byte mask or vector replicate immediate
+     if possible.  */
   if (all_same && all_const_int)
     {
       rtx vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
       if (XVECEXP (vals, 0, 0) == const0_rtx
-         || s390_contiguous_bitmask_vector_p (vec, NULL, NULL)
-         || s390_bytemask_vector_p (vec, NULL))
+         || s390_constant_via_vgm_p (vec, NULL, NULL, NULL)
+         || s390_constant_via_vrepi_p (vec, NULL, NULL)
+         || s390_constant_via_vgbm_p (vec, NULL))
        {
          emit_insn (gen_rtx_SET (target, vec));
          return;
@@ -8455,6 +8585,9 @@ print_operand_address (FILE *file, rtx addr)
     'M': print the second word of a TImode operand.
     'N': print the second word of a DImode operand.
     'O': print only the displacement of a memory reference or address.
+    'p': print immediate and element size mask for instruction vrepi
+    'q': print start/end bit positions and element size mask for instruction vgm
+    'r': print immediate for instruction vgbm
     'R': print only the base register of a memory reference or address.
     'S': print S-type memory reference (base+displacement).
     'Y': print address style operand without index (e.g. shift count or setmem
@@ -8472,7 +8605,6 @@ print_operand_address (FILE *file, rtx addr)
     'o': print integer X as if it's an unsigned 32bit word.
     's': "start" of contiguous bitmask X in either DImode or vector inner mode.
     't': CONST_INT: "start" of contiguous bitmask X in SImode.
-        CONST_VECTOR: Generate a bitmask for vgbm instruction.
     'x': print integer X as if it's an unsigned halfword.
     'v': print register number as vector register (v1 instead of f1).
     'V': print the second word of a TFmode operand as vector register.
@@ -8560,6 +8692,67 @@ print_operand (FILE *file, rtx x, int code)
       }
       return;
 
+    case 'p':
+      {
+       machine_mode mode;
+       short imm;
+       bool b = s390_constant_via_vrepi_p (x, &mode, &imm);
+       gcc_checking_assert (b);
+       switch (mode)
+         {
+         case QImode:
+           fprintf (file, "%i,0", imm);
+           break;
+         case HImode:
+           fprintf (file, "%i,1", imm);
+           break;
+         case SImode:
+           fprintf (file, "%i,2", imm);
+           break;
+         case DImode:
+           fprintf (file, "%i,3", imm);
+           break;
+         default:
+           gcc_unreachable ();
+         }
+      }
+      return;
+
+    case 'q':
+      {
+       machine_mode mode;
+       int start, end;
+       bool b = s390_constant_via_vgm_p (x, &mode, &start, &end);
+       gcc_checking_assert (b);
+       switch (mode)
+         {
+         case QImode:
+           fprintf (file, "%u,%u,0", start, end);
+           break;
+         case HImode:
+           fprintf (file, "%u,%u,1", start, end);
+           break;
+         case SImode:
+           fprintf (file, "%u,%u,2", start, end);
+           break;
+         case DImode:
+           fprintf (file, "%u,%u,3", start, end);
+           break;
+         default:
+           gcc_unreachable ();
+         }
+      }
+      return;
+
+    case 'r':
+      {
+       unsigned mask;
+       bool b = s390_constant_via_vgbm_p (x, &mask);
+       gcc_checking_assert (b);
+       fprintf (file, "%u", mask);
+      }
+      return;
+
     case 'R':
       {
        struct s390_address ad;
@@ -8773,26 +8966,6 @@ print_operand (FILE *file, rtx x, int code)
          fprintf (file, HOST_WIDE_INT_PRINT_DEC,
                   ((INTVAL (XVECEXP (x, 0, 0)) & 0xffff) ^ 0x8000) - 0x8000);
          break;
-       case 'e':
-       case 's':
-         {
-           int start, end;
-           bool ok;
-
-           ok = s390_contiguous_bitmask_vector_p (x, &start, &end);
-           gcc_assert (ok);
-           ival = (code == 's') ? start : end;
-           fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
-         }
-         break;
-       case 't':
-         {
-           unsigned mask;
-           bool ok = s390_bytemask_vector_p (x, &mask);
-           gcc_assert (ok);
-           fprintf (file, "%u", mask);
-         }
-         break;
 
        default:
          output_operand_lossage ("invalid constant vector for output "
index 2555006bb4b98567936a4f6e93e3c5edcea4ef27..303026f6af7ccc3c089896b8c4b9b0872456249b 100644 (file)
 ; FIXME: More constants are possible by enabling jxx, jyy constraints
 ; for TImode (use double-int for the calculations)
 (define_insn "movti"
-  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v,  v,  v,v,d,v,R,d,    d, d,    d, d,o")
-        (match_operand:TI 1 "general_operand"      " S,d,v,j00,jm1,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
+  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v,  v,  v,  v,  v,  v,v,d,v,R,d,    d, d,    d, d,o")
+        (match_operand:TI 1 "general_operand"      " S,d,v,j00,jm1,jyy,jxx,jzz,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
   "TARGET_ZARCH"
   "@
    lmg\t%0,%N0,%S1
    vlr\t%v0,%v1
    vzero\t%v0
    vone\t%v0
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    vlvgp\t%v0,%1,%N1
    #
    vl\t%v0,%1%A1
    #
    #
    #"
-  [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
-   (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*")
-   (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
+  [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRI,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
+   (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
+   (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
 
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
index 26fd505f2cd9979d067c3ea9894b1661a99c68b8..6367885965749e1123cc5b71f2b96ec5126bfc58 100644 (file)
 ; vgmb, vgmh, vgmf, vgmg, vrepib, vrepih, vrepif, vrepig
 (define_insn "mov<mode><tf_vr>"
   [(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R,  v,  v,  v,  v,  v,v,*d,*d,?o")
-       (match_operand:V_128 1 "general_operand"      " v,R,v,j00,jm1,jyy,jxx,jKK,d, v,dT,*d"))]
+       (match_operand:V_128 1 "general_operand"      " v,R,v,j00,jm1,jyy,jxx,jzz,d, v,dT,*d"))]
   ""
   "@
    vlr\t%v0,%v1
    vst\t%v1,%0%A0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm<bhfgq>\t%v0,%s1,%e1
-   vrepi<bhfgq>\t%v0,%h1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    vlvgp\t%v0,%1,%N1
    #
    #
 ; However, this would probably be slower.
 
 (define_insn "mov<mode>"
-  [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  v,d,  Q,  S,  Q,  S,  d,  d,d,R,T")
-        (match_operand:V_8 1 "general_operand"      " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,T,d,d"))]
+  [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  v,  v,d,  Q,  S,  Q,  S,  d,  d,d,R,T")
+        (match_operand:V_8 1 "general_operand"      " v,d,v,R,v,j00,jm1,jyy,jxx,jzz,d,j00,j00,jm1,jm1,j00,jm1,T,d,d"))]
   "TARGET_VX"
   "@
    vlr\t%v0,%v1
    vsteb\t%v1,%0,0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm\t%v0,%s1,%e1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    lr\t%0,%1
    mvi\t%0,0
    mviy\t%0,0
    llc\t%0,%1
    stc\t%1,%0
    stcy\t%1,%0"
-  [(set_attr "op_type"      "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RXY,RX,RXY")])
+  [(set_attr "op_type"      "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RXY,RX,RXY")])
 
 (define_insn "mov<mode>"
-  [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  v,d,  Q,  Q,  d,  d,d,d,d,R,T,b")
-        (match_operand:V_16 1 "general_operand"      " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
+  [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  v,  v,d,  Q,  Q,  d,  d,d,d,d,R,T,b")
+        (match_operand:V_16 1 "general_operand"      " v,d,v,R,v,j00,jm1,jyy,jxx,jzz,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
   ""
   "@
    vlr\t%v0,%v1
    vsteh\t%v1,%0,0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm\t%v0,%s1,%e1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    lr\t%0,%1
    mvhhi\t%0,0
    mvhhi\t%0,-1
    sth\t%1,%0
    sthy\t%1,%0
    sthrl\t%1,%0"
-  [(set_attr "op_type"      "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
+  [(set_attr "op_type"      "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
 
 (define_insn "mov<mode>"
-  [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R,  f,  v,  v,  v,  v,  Q,  Q,  d,  d,d,d,d,d,R,T,b")
-       (match_operand:V_32 1 "general_operand"      " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
+  [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R,  f,  v,  v,  v,  v,  v,  Q,  Q,  d,  d,d,d,d,d,R,T,b")
+       (match_operand:V_32 1 "general_operand"      " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,jzz,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
   "TARGET_VX"
   "@
    ldr\t%v0,%v1
    lzer\t%v0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm\t%v0,%s1,%e1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    mvhi\t%0,0
    mvhi\t%0,-1
    lhi\t%0,0
    st\t%1,%0
    sty\t%1,%0
    strl\t%1,%0"
-  [(set_attr "op_type" "RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
+  [(set_attr "op_type" "RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
                         RIL,RR,RX,RXY,RX,RXY,RIL")])
 
 (define_insn "mov<mode>"
   [(set (match_operand:V_64 0 "nonimmediate_operand"
-         "=f,f,f,R,T,v,v,d,v,R,  f,  v,  v,  v,  v,  Q,  Q,  d,  d,f,d,d,d,d,T,b")
+         "=f,f,f,R,T,v,v,d,v,R,  f,  v,  v,  v,  v,  v,  Q,  Q,  d,  d,f,d,d,d,d,T,b")
         (match_operand:V_64 1 "general_operand"
-         " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
+         " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,jzz,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
   "TARGET_ZARCH"
   "@
    ldr\t%0,%1
    lzdr\t%0
    vzero\t%v0
    vone\t%v0
-   vgbm\t%v0,%t1
-   vgm\t%v0,%s1,%e1
+   vgbm\t%v0,%r1
+   vgm\t%v0,%q1
+   vrepi\t%v0,%p1
    mvghi\t%0,0
    mvghi\t%0,-1
    lghi\t%0,0
    lg\t%0,%1
    stg\t%1,%0
    stgrl\t%1,%0"
-  [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,
+  [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,VRI,
                         SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")])
 
 
index b723ceb13be9b4872b350cf169a79601294c4f44..f5822cf90c7a4313594918241e6febbdae942a26 100644 (file)
@@ -1,8 +1,8 @@
 /* { dg-do compile { target { s390*-*-* } } } */
 /* { dg-options "-O2 -ftree-vectorize -mzarch -fno-unroll-loops" } */
-/* { dg-final { scan-assembler-times "vgmg" 1 } } */
-/* { dg-final { scan-assembler-times "vgmf" 1 } } */
-/* { dg-final { scan-assembler-times "vsel" 2 } } */
+/* { dg-final { scan-assembler-times {vgm\t%v[0-9]+,[0-9]+,[0-9]+,3} 1 } } */
+/* { dg-final { scan-assembler-times {vgm\t%v[0-9]+,[0-9]+,[0-9]+,2} 1 } } */
+/* { dg-final { scan-assembler-times {vsel} 2 } } */
 
 #include <math.h>
 
index f3030877ca5d370db0c083e3f2662eadab70bdb9..05da56e6bcf42f0c8ffda4742a9bbc660fc6e2da 100644 (file)
@@ -12,14 +12,14 @@ foo1 ()
 {
   return (uv2di){ 0x000fffffffffff00, 0x000fffffffffff00 };
 }
-/* { dg-final { scan-assembler-times "vgmg\t%v24,12,55" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,12,55,3" 1 } } */
 
 uv4si __attribute__((noinline))
 foo2 ()
 {
   return (uv4si){ 0xff00000f, 0xff00000f, 0xff00000f, 0xff00000f };
 }
-/* { dg-final { scan-assembler-times "vgmf\t%v24,28,7" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,28,7,2" 1 } } */
 
 uv8hi __attribute__((noinline))
 foo3a ()
@@ -27,7 +27,7 @@ foo3a ()
   return (uv8hi){ 0xfff0, 0xfff0, 0xfff0, 0xfff0,
       0xfff0, 0xfff0, 0xfff0, 0xfff0 };
 }
-/* { dg-final { scan-assembler-times "vgmh\t%v24,0,11" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,0,11,1" 1 } } */
 
 uv8hi __attribute__((noinline))
 foo3b ()
@@ -35,7 +35,7 @@ foo3b ()
   return (uv8hi){ 0x0fff, 0x0fff, 0x0fff, 0x0fff,
       0x0fff, 0x0fff, 0x0fff, 0x0fff };
 }
-/* { dg-final { scan-assembler-times "vgmh\t%v24,4,15" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,4,15,1" 1 } } */
 
 uv16qi __attribute__((noinline))
 foo4 ()
@@ -45,7 +45,7 @@ foo4 ()
       0x8, 0x8, 0x8, 0x8,
       0x8, 0x8, 0x8, 0x8 };
 }
-/* { dg-final { scan-assembler-times "vgmb\t%v24,4,4" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v24,4,4,0" 1 } } */
 
 int
 main ()
index 4deb6b8db52088045c33b7607e317fdeeb0867ce..b584660161a5e38310e76ed191c8d341916e92cf 100644 (file)
@@ -30,7 +30,7 @@ h ()
 {
   return G == 1;
 }
-/* { dg-final { scan-assembler-times "vgmf\t%v.*,31,31" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v.*,31,31,2" 1 } } */
 
 v4si
 i ()
@@ -51,14 +51,14 @@ k ()
 {
   return G == (v4si){ 0xff80, 0xff80, 0xff80, 0xff80 };
 }
-/* { dg-final { scan-assembler-times "vgmf\t%v.*,16,24" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v.*,16,24,2" 1 } } */
 
 v4si
 l ()
 {
   return G == (v4si){ 0xf000000f, 0xf000000f, 0xf000000f, 0xf000000f };
 }
-/* { dg-final { scan-assembler-times "vgmf\t%v.*,28,3" 1 } } */
+/* { dg-final { scan-assembler-times "vgm\t%v.*,28,3,2" 1 } } */
 
 v4si
 m ()
index bfb9974342f90f7c0b9762abcc3dd065bcfad841..327a2162bb6dc3393bd91a15a8d9f03c54c0646c 100644 (file)
@@ -12,14 +12,14 @@ foo1 ()
 {
   return (uv2di){ 0x7f0f, 0x7f0f };
 }
-/* { dg-final { scan-assembler-times "vrepig\t%v24,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v24,32527,3" 1 } } */
 
 uv4si __attribute__((noinline))
 foo2 ()
 {
   return (uv4si){ 0x7f0f, 0x7f0f, 0x7f0f, 0x7f0f };
 }
-/* { dg-final { scan-assembler-times "vrepif\t%v24,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v24,32527,2" 1 } } */
 
 uv8hi __attribute__((noinline))
 foo3 ()
@@ -27,7 +27,7 @@ foo3 ()
   return (uv8hi){ 0x7f0f, 0x7f0f, 0x7f0f, 0x7f0f,
       0x7f0f, 0x7f0f, 0x7f0f, 0x7f0f };
 }
-/* { dg-final { scan-assembler-times "vrepih\t%v24,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v24,32527,1" 1 } } */
 
 uv16qi __attribute__((noinline))
 foo4 ()
@@ -37,7 +37,7 @@ foo4 ()
       0x77, 0x77, 0x77, 0x77,
       0x77, 0x77, 0x77, 0x77 };
 }
-/* { dg-final { scan-assembler-times "vrepib\t%v24,119" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v24,119,0" 1 } } */
 
 int
 main ()
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-double-1.c b/gcc/testsuite/gcc.target/s390/vector/vgbm-double-1.c
new file mode 100644 (file)
index 0000000..0bf445a
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+typedef double v1df __attribute__ ((vector_size (8)));
+typedef double v2df __attribute__ ((vector_size (16)));
+
+/*
+** test_v1df:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v1df
+test_v1df (void)
+{
+  return (v1df){7.064161009310759e-304};
+}
+
+/*
+** test_v2df:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v2df
+test_v2df (void)
+{
+  return (v2df){7.064161009310759e-304, 7.064161009310759e-304};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-float-1.c b/gcc/testsuite/gcc.target/s390/vector/vgbm-float-1.c
new file mode 100644 (file)
index 0000000..7090f9a
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+typedef float v2sf __attribute__ ((vector_size (8)));
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+/*
+** test_v2sf:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v2sf
+test_v2sf (void)
+{
+  return (v2sf){2.34184089e-38f, 0.f};
+}
+
+/*
+** test_v4sf:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v4sf
+test_v4sf (void)
+{
+  return (v4sf){2.34184089e-38f, 0.f, 2.34184089e-38f, 0.f};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-int128-1.c b/gcc/testsuite/gcc.target/s390/vector/vgbm-int128-1.c
new file mode 100644 (file)
index 0000000..e8db56c
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about V1TI const vectors.  Thus, ensure that we end up with
+   a V1TI const vector before expanding.  Likewise, for 128-bit scalar.  */
+/* { dg-final { scan-tree-dump "{ 0xff00ff0000000000ff00ff00000000 }" "optimized" } } */
+/* { dg-final { scan-tree-dump "= 0xff00ff0000000000ff00ff00000000;" "optimized" } } */
+
+typedef long long v2di __attribute__ ((vector_size (16)));
+typedef __int128 v1ti __attribute__ ((vector_size (16)));
+
+/*
+** test_v1ti:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v1ti
+test_v1ti (void)
+{
+  return (v1ti)(v2di){0xff00ff00000000, 0xff00ff00000000};
+}
+
+/*
+** test_int128:
+**     vgbm    (%v[0-9]+),20560
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128 (void)
+{
+  return ((__int128) 0xff00ff00000000 << 64) | 0xff00ff00000000;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-integer-1.c b/gcc/testsuite/gcc.target/s390/vector/vgbm-integer-1.c
new file mode 100644 (file)
index 0000000..688f8b2
--- /dev/null
@@ -0,0 +1,115 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+typedef char v8qi __attribute__ ((vector_size (8)));
+typedef char v16qi __attribute__ ((vector_size (16)));
+
+typedef short v4hi __attribute__ ((vector_size (8)));
+typedef short v8hi __attribute__ ((vector_size (16)));
+
+typedef int v2si __attribute__ ((vector_size (8)));
+typedef int v4si __attribute__ ((vector_size (16)));
+
+typedef long long v1di __attribute__ ((vector_size (8)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v8qi:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v8qi
+test_v8qi (void)
+{
+  return (v8qi){0, -1, 0, -1, 0, 0, 0, 0};
+}
+
+/*
+** test_v16qi:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v16qi
+test_v16qi (void)
+{
+  return (v16qi){0, -1, 0, -1, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0};
+}
+
+/*
+** test_v4hi:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v4hi
+test_v4hi (void)
+{
+  return (v4hi){0xff, 0xff, 0, 0};
+}
+
+/*
+** test_v8hi:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v8hi
+test_v8hi (void)
+{
+  return (v8hi){0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0};
+}
+
+/*
+** test_v2si:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v2si
+test_v2si (void)
+{
+  return (v2si){0xff00ff, 0};
+}
+
+/*
+** test_v4si:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v4si
+test_v4si (void)
+{
+  return (v4si){0xff00ff, 0, 0xff00ff, 0};
+}
+
+/*
+** test_v1di:
+**     vgbm    %v24,20480
+**     br      %r14
+*/
+
+v1di
+test_v1di (void)
+{
+  return (v1di){0xff00ff00000000};
+}
+
+/*
+** test_v2di:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v2di
+test_v2di (void)
+{
+  return (v2di){0xff00ff00000000, 0xff00ff00000000};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgbm-longdouble-1.c b/gcc/testsuite/gcc.target/s390/vector/vgbm-longdouble-1.c
new file mode 100644 (file)
index 0000000..e954d3e
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE MASK nor
+   via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE BYTE MASK.  */
+
+typedef long double v1tf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1tf:
+**     vgbm    %v24,20560
+**     br      %r14
+*/
+
+v1tf
+test_v1tf (void)
+{
+  return (v1tf){9.77049323250296736880493184970933526e-4856L};
+}
+
+/*
+** test_longdouble:
+**     vgbm    (%v[0-9]+),20560
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble (void)
+{
+  return 9.77049323250296736880493184970933526e-4856L;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-df-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-df-1.c
new file mode 100644 (file)
index 0000000..124a4e4
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef double v1df __attribute__ ((vector_size (8)));
+typedef double v2df __attribute__ ((vector_size (16)));
+
+/*
+** test_v1df_via_vgmb:
+**     vgm     %v24,0,1,0
+**     br      %r14
+*/
+
+v1df
+test_v1df_via_vgmb (void)
+{
+  return (v1df){-8577.505882352939806878566741943359375};
+}
+
+/*
+** test_v2df_via_vgmb:
+**     vgm     %v24,0,1,0
+**     br      %r14
+*/
+
+v2df
+test_v2df_via_vgmb (void)
+{
+  return (v2df){-8577.505882352939806878566741943359375, -8577.505882352939806878566741943359375};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-di-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-di-1.c
new file mode 100644 (file)
index 0000000..bd406a0
--- /dev/null
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef long long v1di __attribute__ ((vector_size (8)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v1di_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmb (void)
+{
+  return (v1di){0xe0e0e0e0e0e0e0e0};
+}
+
+/*
+** test_v2di_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmb (void)
+{
+  return (v2di){0xe0e0e0e0e0e0e0e0, 0xe0e0e0e0e0e0e0e0};
+}
+
+/*
+** test_v1di_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmb_wrap (void)
+{
+  return (v1di){0xe7e7e7e7e7e7e7e7};
+}
+
+/*
+** test_v2di_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmb_wrap (void)
+{
+  return (v2di){0xe7e7e7e7e7e7e7e7, 0xe7e7e7e7e7e7e7e7};
+}
+
+/*
+** test_v1di_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmh (void)
+{
+  return (v1di){0x7e007e007e007e0};
+}
+
+/*
+** test_v2di_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmh (void)
+{
+  return (v2di){0x7e007e007e007e0, 0x7e007e007e007e0};
+}
+
+/*
+** test_v1di_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmf (void)
+{
+  return (v1di){0x7ffffffe7ffffffe};
+}
+
+/*
+** test_v2di_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmf (void)
+{
+  return (v2di){0x7ffffffe7ffffffe, 0x7ffffffe7ffffffe};
+}
+
+/*
+** test_v1di_via_vgmg:
+**     vgm     %v24,17,46,3
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vgmg (void)
+{
+  return (v1di){0x7ffffffe0000};
+}
+
+/*
+** test_v2di_via_vgmg:
+**     vgm     %v24,17,46,3
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vgmg (void)
+{
+  return (v2di){0x7ffffffe0000, 0x7ffffffe0000};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-hi-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-hi-1.c
new file mode 100644 (file)
index 0000000..1e0fb68
--- /dev/null
@@ -0,0 +1,216 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef short  v1hi __attribute__ ((vector_size (2)));
+typedef short  v2hi __attribute__ ((vector_size (4)));
+typedef short  v4hi __attribute__ ((vector_size (8)));
+typedef short  v8hi __attribute__ ((vector_size (16)));
+
+/*
+** test_v1hi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vgmb (void)
+{
+  return (v1hi){0xe0e0};
+}
+
+/*
+** test_v2hi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vgmb (void)
+{
+  return (v2hi){0xe0e0, 0xe0e0};
+}
+
+/*
+** test_v4hi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmb (void)
+{
+  return (v4hi){0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0};
+}
+
+/*
+** test_v8hi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmb (void)
+{
+  return (v8hi){0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0, 0xe0e0};
+}
+
+/*
+** test_v1hi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vgmb_wrap (void)
+{
+  return (v1hi){0xe7e7};
+}
+
+/*
+** test_v2hi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vgmb_wrap (void)
+{
+  return (v2hi){0xe7e7, 0xe7e7};
+}
+
+/*
+** test_v4hi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmb_wrap (void)
+{
+  return (v4hi){0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7};
+}
+
+/*
+** test_v8hi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmb_wrap (void)
+{
+  return (v8hi){0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7};
+}
+
+/*
+** test_v1hi_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vgmh (void)
+{
+  return (v1hi){0x7e0};
+}
+
+/*
+** test_v2hi_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vgmh (void)
+{
+  return (v2hi){0x7e0, 0x7e0};
+}
+
+/*
+** test_v4hi_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmh (void)
+{
+  return (v4hi){0x7e0, 0x7e0, 0x7e0, 0x7e0};
+}
+
+/*
+** test_v8hi_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmh (void)
+{
+  return (v8hi){0x7e0, 0x7e0, 0x7e0, 0x7e0, 0x7e0, 0x7e0, 0x7e0, 0x7e0};
+}
+
+/*
+** test_v2hi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vgmf (void)
+{
+  return (v2hi){0x7fff, 0xfffe};
+}
+
+/*
+** test_v4hi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmf (void)
+{
+  return (v4hi){0x7fff, 0xfffe, 0x7fff, 0xfffe};
+}
+
+/*
+** test_v8hi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmf (void)
+{
+  return (v8hi){0x7fff, 0xfffe, 0x7fff, 0xfffe, 0x7fff, 0xfffe, 0x7fff, 0xfffe};
+}
+
+/*
+** test_v4hi_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vgmg (void)
+{
+  return (v4hi){0x7fff, 0xffff, 0xffff, 0xfffe};
+}
+
+/*
+** test_v8hi_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vgmg (void)
+{
+  return (v8hi){0x7fff, 0xffff, 0xffff, 0xfffe, 0x7fff, 0xffff, 0xffff, 0xfffe};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-int128-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-int128-1.c
new file mode 100644 (file)
index 0000000..a49ed3e
--- /dev/null
@@ -0,0 +1,69 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about __int128 constants.  Thus, ensure that we end up with
+   128-bit constants before expanding.  */
+/* { dg-final { scan-tree-dump "= 0xe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e;" "optimized" } } */
+/* { dg-final { scan-tree-dump "= 0x7ffe7ffe7ffe7ffe7ffe7ffe7ffe7ffe;" "optimized" } } */
+/* { dg-final { scan-tree-dump "= 0x7ffffffe7ffffffe7ffffffe7ffffffe;" "optimized" } } */
+/* { dg-final { scan-tree-dump "= 0x7ffffffffffffffe7ffffffffffffffe;" "optimized" } } */
+
+/*
+** test_int128_via_vgmb:
+**     vgm     (%v[0-9]+),4,6,0
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vgmb (void)
+{
+  return ((__int128) 0x0e0e0e0e0e0e0e0e << 64) | 0x0e0e0e0e0e0e0e0e;
+}
+
+/*
+** test_int128_via_vgmh:
+**     vgm     (%v[0-9]+),1,14,1
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vgmh (void)
+{
+  return ((__int128) 0x7ffe7ffe7ffe7ffe << 64) | 0x7ffe7ffe7ffe7ffe;
+}
+
+/*
+** test_int128_via_vgmf:
+**     vgm     (%v[0-9]+),1,30,2
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vgmf (void)
+{
+  return ((__int128) 0x7ffffffe7ffffffe << 64) | 0x7ffffffe7ffffffe;
+}
+
+/*
+** test_int128_via_vgmg:
+**     vgm     (%v[0-9]+),1,62,3
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vgmg (void)
+{
+  return ((__int128) 0x7ffffffffffffffe << 64) | 0x7ffffffffffffffe;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-longdouble-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-longdouble-1.c
new file mode 100644 (file)
index 0000000..c989ca5
--- /dev/null
@@ -0,0 +1,59 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+/*
+** test_longdouble_via_vgmb:
+**     vgm     (%v[0-9]+),4,6,0
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble_via_vgmb (void)
+{
+  return 2.263171865473961260249112278523378513150597635104e-3849L;
+}
+
+/*
+** test_longdouble_via_vgmh:
+**     vgm     (%v[0-9]+),1,14,1
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble_via_vgmh (void)
+{
+  return 8.9228500591371968978175957554634715383668519805586e+4931L;
+}
+
+/*
+** test_longdouble_via_vgmf:
+**     vgm     (%v[0-9]+),9,30,2
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble_via_vgmf (void)
+{
+  return 5.7202348769040302108562404806917908642856158381792e-4894L;
+}
+
+/*
+** test_longdouble_via_vgmg:
+**     vgm     (%v[0-9]+),9,62,3
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+long double
+test_longdouble_via_vgmg (void)
+{
+  return 5.7203220768525291179165318133287569460629228746232e-4894L;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-qi-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-qi-1.c
new file mode 100644 (file)
index 0000000..b39c006
--- /dev/null
@@ -0,0 +1,241 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef signed char  v1qi __attribute__ ((vector_size (1)));
+typedef signed char  v2qi __attribute__ ((vector_size (2)));
+typedef signed char  v4qi __attribute__ ((vector_size (4)));
+typedef signed char  v8qi __attribute__ ((vector_size (8)));
+typedef signed char  v16qi __attribute__ ((vector_size (16)));
+
+/*
+** test_v1qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v1qi
+test_v1qi_via_vgmb (void)
+{
+  return (v1qi){0xe0};
+}
+
+/*
+** test_v2qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vgmb (void)
+{
+  return (v2qi){0xe0, 0xe0};
+}
+
+/*
+** test_v4qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vgmb (void)
+{
+  return (v4qi){0xe0, 0xe0, 0xe0, 0xe0};
+}
+
+/*
+** test_v8qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmb (void)
+{
+  return (v8qi){0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0};
+}
+
+/*
+** test_v16qi_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmb (void)
+{
+  return (v16qi){0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0};
+}
+
+/*
+** test_v1qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v1qi
+test_v1qi_via_vgmb_wrap (void)
+{
+  return (v1qi){0xe7};
+}
+
+/*
+** test_v2qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vgmb_wrap (void)
+{
+  return (v2qi){0xe7, 0xe7};
+}
+
+/*
+** test_v4qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vgmb_wrap (void)
+{
+  return (v4qi){0xe7, 0xe7, 0xe7, 0xe7};
+}
+
+/*
+** test_v8qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmb_wrap (void)
+{
+  return (v8qi){0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7};
+}
+
+/*
+** test_v16qi_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmb_wrap (void)
+{
+  return (v16qi){0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7};
+}
+
+/*
+** test_v2qi_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vgmh (void)
+{
+  return (v2qi){0x7f, 0xfe};
+}
+
+/*
+** test_v4qi_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vgmh (void)
+{
+  return (v4qi){0x7f, 0xfe, 0x7f, 0xfe};
+}
+
+/*
+** test_v8qi_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmh (void)
+{
+  return (v8qi){0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe};
+}
+
+/*
+** test_v16qi_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmh (void)
+{
+  return (v16qi){0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe};
+}
+
+/*
+** test_v4qi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vgmf (void)
+{
+  return (v4qi){0x7f, 0xff, 0xff, 0xfe};
+}
+
+/*
+** test_v8qi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmf (void)
+{
+  return (v8qi){0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe};
+}
+
+/*
+** test_v16qi_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmf (void)
+{
+  return (v16qi){0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfe};
+}
+
+/*
+** test_v8qi_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vgmg (void)
+{
+  return (v8qi){0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe};
+}
+
+/*
+** test_v16qi_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vgmg (void)
+{
+  return (v16qi){0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-sf-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-sf-1.c
new file mode 100644 (file)
index 0000000..851b97b
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef float v1sf __attribute__ ((vector_size (4)));
+typedef float v2sf __attribute__ ((vector_size (8)));
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1sf_via_vgmb:
+**     vgm     %v24,0,3,0
+**     br      %r14
+*/
+
+v1sf
+test_v1sf_via_vgmb (void)
+{
+  return (v1sf){-5.9654142e29};
+}
+
+/*
+** test_v2sf_via_vgmb:
+**     vgm     %v24,0,3,0
+**     br      %r14
+*/
+
+v2sf
+test_v2sf_via_vgmb (void)
+{
+  return (v2sf){-5.9654142e29, -5.9654142e29};
+}
+
+/*
+** test_v4sf_via_vgmb:
+**     vgm     %v24,0,3,0
+**     br      %r14
+*/
+
+v4sf
+test_v4sf_via_vgmb (void)
+{
+  return (v4sf){-5.9654142e29, -5.9654142e29, -5.9654142e29, -5.9654142e29};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-si-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-si-1.c
new file mode 100644 (file)
index 0000000..32dbd1e
--- /dev/null
@@ -0,0 +1,179 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef int  v1si __attribute__ ((vector_size (4)));
+typedef int  v2si __attribute__ ((vector_size (8)));
+typedef int  v4si __attribute__ ((vector_size (16)));
+
+/*
+** test_v1si_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vgmb (void)
+{
+  return (v1si){0xe0e0e0e0};
+}
+
+/*
+** test_v2si_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmb (void)
+{
+  return (v2si){0xe0e0e0e0, 0xe0e0e0e0};
+}
+
+/*
+** test_v4si_via_vgmb:
+**     vgm     %v24,0,2,0
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmb (void)
+{
+  return (v4si){0xe0e0e0e0, 0xe0e0e0e0, 0xe0e0e0e0, 0xe0e0e0e0};
+}
+
+/*
+** test_v1si_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vgmb_wrap (void)
+{
+  return (v1si){0xe7e7e7e7};
+}
+
+/*
+** test_v2si_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmb_wrap (void)
+{
+  return (v2si){0xe7e7e7e7, 0xe7e7e7e7};
+}
+
+/*
+** test_v4si_via_vgmb_wrap:
+**     vgm     %v24,5,2,0
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmb_wrap (void)
+{
+  return (v4si){0xe7e7e7e7, 0xe7e7e7e7, 0xe7e7e7e7, 0xe7e7e7e7};
+}
+
+/*
+** test_v1si_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vgmh (void)
+{
+  return (v1si){0x7e007e0};
+}
+
+/*
+** test_v2si_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmh (void)
+{
+  return (v2si){0x7e007e0, 0x7e007e0};
+}
+
+/*
+** test_v4si_via_vgmh:
+**     vgm     %v24,5,10,1
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmh (void)
+{
+  return (v4si){0x7e007e0, 0x7e007e0, 0x7e007e0, 0x7e007e0};
+}
+
+/*
+** test_v1si_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vgmf (void)
+{
+  return (v1si){0x7ffffffe};
+}
+
+/*
+** test_v2si_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmf (void)
+{
+  return (v2si){0x7ffffffe, 0x7ffffffe};
+}
+
+/*
+** test_v4si_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmf (void)
+{
+  return (v4si){0x7ffffffe, 0x7ffffffe, 0x7ffffffe, 0x7ffffffe};
+}
+
+/*
+** test_v2si_via_vgmg:
+**     vgm     %v24,17,46,3
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vgmg (void)
+{
+  return (v2si){0x7fff, 0xfffe0000};
+}
+
+/*
+** test_v4si_via_vgmg:
+**     vgm     %v24,17,46,3
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vgmg (void)
+{
+  return (v4si){0x7fff, 0xfffe0000, 0x7fff, 0xfffe0000};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-tf-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-tf-1.c
new file mode 100644 (file)
index 0000000..c88c9e7
--- /dev/null
@@ -0,0 +1,57 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+typedef long double v1tf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1tf_via_vgmb:
+**     vgm     %v24,4,6,0
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vgmb (void)
+{
+  return (v1tf){2.263171865473961260249112278523378513150597635104e-3849L};
+}
+
+/*
+** test_v1tf_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vgmh (void)
+{
+  return (v1tf){8.9228500591371968978175957554634715383668519805586e+4931L};
+}
+
+/*
+** test_v1tf_via_vgmf:
+**     vgm     %v24,9,30,2
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vgmf (void)
+{
+  return (v1tf){5.7202348769040302108562404806917908642856158381792e-4894L};
+}
+
+/*
+** test_v1tf_via_vgmg:
+**     vgm     %v24,9,62,3
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vgmg (void)
+{
+  return (v1tf){5.7203220768525291179165318133287569460629228746232e-4894L};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vgm-ti-1.c b/gcc/testsuite/gcc.target/s390/vector/vgm-ti-1.c
new file mode 100644 (file)
index 0000000..5eaeb0c
--- /dev/null
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR REPLICATE IMMEDIATE but via VECTOR GENERATE MASK.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about V1TI const vectors.  Thus, ensure that we end up with
+   a V1TI const vector before expanding.  */
+/* { dg-final { scan-tree-dump "{ 0xe0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e }" "optimized" } } */
+/* { dg-final { scan-tree-dump "{ 0x7ffe7ffe7ffe7ffe7ffe7ffe7ffe7ffe }" "optimized" } } */
+/* { dg-final { scan-tree-dump "{ 0x7ffffffe7ffffffe7ffffffe7ffffffe }" "optimized" } } */
+/* { dg-final { scan-tree-dump "{ 0x7ffffffffffffffe7ffffffffffffffe }" "optimized" } } */
+
+typedef __int128  v1ti __attribute__ ((vector_size (16)));
+typedef long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v1ti_via_vgmb:
+**     vgm     %v24,4,6,0
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vgmb (void)
+{
+  return (v1ti)(v2di){0x0e0e0e0e0e0e0e0e, 0x0e0e0e0e0e0e0e0e};
+}
+
+/*
+** test_v1ti_via_vgmh:
+**     vgm     %v24,1,14,1
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vgmh (void)
+{
+  return (v1ti)(v2di){0x7ffe7ffe7ffe7ffe, 0x7ffe7ffe7ffe7ffe};
+}
+
+/*
+** test_v1ti_via_vgmf:
+**     vgm     %v24,1,30,2
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vgmf (void)
+{
+  return (v1ti)(v2di){0x7ffffffe7ffffffe, 0x7ffffffe7ffffffe};
+}
+
+/*
+** test_v1ti_via_vgmg:
+**     vgm     %v24,1,62,3
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vgmg (void)
+{
+  return (v1ti)(v2di){0x7ffffffffffffffe, 0x7ffffffffffffffe};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-df-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-df-1.c
new file mode 100644 (file)
index 0000000..62c16e4
--- /dev/null
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef double v1df __attribute__ ((vector_size (8)));
+typedef double v2df __attribute__ ((vector_size (16)));
+
+/*
+** test_v1df_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1df
+test_v1df_via_vrepib (void)
+{
+  return (v1df){-3.7206620809969885e-103};
+}
+
+/*
+** test_v2df_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2df
+test_v2df_via_vrepib (void)
+{
+  return (v2df){-3.7206620809969885e-103, -3.7206620809969885e-103};
+}
+
+/*
+** test_v1df_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1df
+test_v1df_via_vrepih (void)
+{
+  return (v1df){-2.8368052823634315e-05};
+}
+
+/*
+** test_v2df_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2df
+test_v2df_via_vrepih (void)
+{
+  return (v2df){-2.8368052823634315e-05, -2.8368052823634315e-05};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-di-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-di-1.c
new file mode 100644 (file)
index 0000000..dcd65a5
--- /dev/null
@@ -0,0 +1,106 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef long long v1di __attribute__ ((vector_size (8)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v1di_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vrepib (void)
+{
+  return (v1di){0xaaaaaaaaaaaaaaaa};
+}
+
+/*
+** test_v2di_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vrepib (void)
+{
+  return (v2di){0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa};
+}
+
+/*
+** test_v1di_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vrepih (void)
+{
+  return (v1di){0xbefdbefdbefdbefd};
+}
+
+/*
+** test_v2di_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vrepih (void)
+{
+  return (v2di){0xbefdbefdbefdbefd, 0xbefdbefdbefdbefd};
+}
+
+/*
+** test_v1di_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vrepif (void)
+{
+  return (v1di){0xffffbefdffffbefd};
+}
+
+/*
+** test_v2di_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vrepif (void)
+{
+  return (v2di){0xffffbefdffffbefd, 0xffffbefdffffbefd};
+}
+
+/*
+** test_v1di_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v1di
+test_v1di_via_vrepig (void)
+{
+  return (v1di){-16643};
+}
+
+/*
+** test_v2di_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v2di
+test_v2di_via_vrepig (void)
+{
+  return (v2di){-16643, -16643};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-hi-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-hi-1.c
new file mode 100644 (file)
index 0000000..5cdf713
--- /dev/null
@@ -0,0 +1,168 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef short v1hi __attribute__ ((vector_size (2)));
+typedef short v2hi __attribute__ ((vector_size (4)));
+typedef short v4hi __attribute__ ((vector_size (8)));
+typedef short v8hi __attribute__ ((vector_size (16)));
+
+/*
+** test_v1hi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vrepib (void)
+{
+  return (v1hi){0xaaaa};
+}
+
+/*
+** test_v2hi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vrepib (void)
+{
+  return (v2hi){0xaaaa, 0xaaaa};
+}
+
+/*
+** test_v4hi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vrepib (void)
+{
+  return (v4hi){0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa};
+}
+
+/*
+** test_v8hi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vrepib (void)
+{
+  return (v8hi){0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa};
+}
+
+/*
+** test_v1hi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1hi
+test_v1hi_via_vrepih (void)
+{
+  return (v1hi){-16643};
+}
+
+/*
+** test_v2hi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vrepih (void)
+{
+  return (v2hi){-16643, -16643};
+}
+
+/*
+** test_v4hi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vrepih (void)
+{
+  return (v4hi){-16643, -16643, -16643, -16643};
+}
+
+/*
+** test_v8hi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vrepih (void)
+{
+  return (v8hi){-16643, -16643, -16643, -16643, -16643, -16643, -16643, -16643};
+}
+
+/*
+** test_v2hi_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v2hi
+test_v2hi_via_vrepif (void)
+{
+  return (v2hi){-1, -16643};
+}
+
+/*
+** test_v4hi_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vrepif (void)
+{
+  return (v4hi){-1, -16643, -1, -16643};
+}
+
+/*
+** test_v8hi_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vrepif (void)
+{
+  return (v8hi){-1, -16643, -1, -16643, -1, -16643, -1, -16643};
+}
+
+/*
+** test_v4hi_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v4hi
+test_v4hi_via_vrepig (void)
+{
+  return (v4hi){-1, -1, -1, -16643};
+}
+
+/*
+** test_v8hi_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v8hi
+test_v8hi_via_vrepig (void)
+{
+  return (v8hi){-1, -1, -1, -16643, -1, -1, -1, -16643};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-int128-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-int128-1.c
new file mode 100644 (file)
index 0000000..95cb4cb
--- /dev/null
@@ -0,0 +1,69 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about int128 const vectors.  Thus, ensure that we end up with
+   a int128 const vector before expanding.  */
+/* { dg-final { scan-tree-dump "= -0x55555555555555555555555555555556;" "optimized" } } */
+/* { dg-final { scan-tree-dump "= -0x41024102410241024102410241024103;" "optimized" } } */
+/* { dg-final { scan-tree-dump "= -0x4102000041020000410200004103;" "optimized" } } */
+/* { dg-final { scan-tree-dump "= -0x41020000000000004103;" "optimized" } } */
+
+/*
+** test_int128_via_vrepib:
+**     vrepi   (%v[0-9]+),-86,0
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vrepib (void)
+{
+  return ((__int128) 0xaaaaaaaaaaaaaaaa << 64) | 0xaaaaaaaaaaaaaaaa;
+}
+
+/*
+** test_int128_via_vrepih:
+**     vrepi   (%v[0-9]+),-16643,1
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vrepih (void)
+{
+  return ((__int128) 0xbefdbefdbefdbefd << 64) | 0xbefdbefdbefdbefd;
+}
+
+/*
+** test_int128_via_vrepif:
+**     vrepi   (%v[0-9]+),-16643,2
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vrepif (void)
+{
+  return ((__int128) 0xffffbefdffffbefd << 64) | 0xffffbefdffffbefd;
+}
+
+/*
+** test_int128_via_vrepig:
+**     vrepi   (%v[0-9]+),-16643,3
+**     vst     \1,0\(%r2\),3
+**     br      %r14
+*/
+
+__int128
+test_int128_via_vrepig (void)
+{
+  return ((__int128) 0xffffffffffffbefd << 64) | 0xffffffffffffbefd;
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-qi-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-qi-1.c
new file mode 100644 (file)
index 0000000..735e228
--- /dev/null
@@ -0,0 +1,145 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef signed char v1qi __attribute__ ((vector_size (1)));
+typedef signed char v2qi __attribute__ ((vector_size (2)));
+typedef signed char v4qi __attribute__ ((vector_size (4)));
+typedef signed char v8qi __attribute__ ((vector_size (8)));
+typedef signed char v16qi __attribute__ ((vector_size (16)));
+
+/*
+** test_v1qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1qi
+test_v1qi_via_vrepib (void)
+{
+  return (v1qi){0xaa};
+}
+
+/*
+** test_v2qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vrepib (void)
+{
+  return (v2qi){0xaa, 0xaa};
+}
+
+/*
+** test_v4qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vrepib (void)
+{
+  return (v4qi){0xaa, 0xaa, 0xaa, 0xaa};
+}
+
+/*
+** test_v8qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vrepib (void)
+{
+  return (v8qi){0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
+}
+
+/*
+** test_v16qi_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vrepib (void)
+{
+  return (v16qi){0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
+}
+
+/*
+** test_v2qi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2qi
+test_v2qi_via_vrepih (void)
+{
+  return (v2qi){0xbe, 0xfd};
+}
+
+/*
+** test_v4qi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v4qi
+test_v4qi_via_vrepih (void)
+{
+  return (v4qi){0xbe, 0xfd, 0xbe, 0xfd};
+}
+
+/*
+** test_v8qi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v8qi
+test_v8qi_via_vrepih (void)
+{
+  return (v8qi){0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd};
+}
+
+/*
+** test_v16qi_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vrepih (void)
+{
+  return (v16qi){0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd, 0xbe, 0xfd};
+}
+
+/*
+** test_v16qi_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vrepif (void)
+{
+  return (v16qi){-1, -1, 0xbe, 0xfd, -1, -1, 0xbe, 0xfd, -1, -1, 0xbe, 0xfd, -1, -1, 0xbe, 0xfd};
+}
+
+/*
+** test_v16qi_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v16qi
+test_v16qi_via_vrepig (void)
+{
+  return (v16qi){-1, -1, -1, -1, -1, -1, 0xbe, 0xfd, -1, -1, -1, -1, -1, -1, 0xbe, 0xfd};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-sf-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-sf-1.c
new file mode 100644 (file)
index 0000000..4ab0c1f
--- /dev/null
@@ -0,0 +1,83 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef float v1sf __attribute__ ((vector_size (4)));
+typedef float v2sf __attribute__ ((vector_size (8)));
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1sf_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1sf
+test_v1sf_via_vrepib (void)
+{
+  return (v1sf){-3.03164883e-13f};
+}
+
+/*
+** test_v2sf_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2sf
+test_v2sf_via_vrepib (void)
+{
+  return (v2sf){-3.03164883e-13f, -3.03164883e-13f};
+}
+
+/*
+** test_v4sf_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v4sf
+test_v4sf_via_vrepib (void)
+{
+  return (v4sf){-3.03164883e-13f, -3.03164883e-13f, -3.03164883e-13f, -3.03164883e-13f};
+}
+
+/*
+** test_v1sf_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1sf
+test_v1sf_via_vrepih (void)
+{
+  return (v1sf){-0.49559775f};
+}
+
+/*
+** test_v2sf_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2sf
+test_v2sf_via_vrepih (void)
+{
+  return (v2sf){-0.49559775f, -0.49559775f};
+}
+
+/*
+** test_v4sf_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v4sf
+test_v4sf_via_vrepih (void)
+{
+  return (v4sf){-0.49559775f, -0.49559775f, -0.49559775f, -0.49559775f};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-si-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-si-1.c
new file mode 100644 (file)
index 0000000..5406828
--- /dev/null
@@ -0,0 +1,143 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef int v1si __attribute__ ((vector_size (4)));
+typedef int v2si __attribute__ ((vector_size (8)));
+typedef int v4si __attribute__ ((vector_size (16)));
+
+/*
+** test_v1si_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vrepib (void)
+{
+  return (v1si){0xaaaaaaaa};
+}
+
+/*
+** test_v2si_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vrepib (void)
+{
+  return (v2si){0xaaaaaaaa, 0xaaaaaaaa};
+}
+
+/*
+** test_v4si_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vrepib (void)
+{
+  return (v4si){0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa};
+}
+
+/*
+** test_v1si_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vrepih (void)
+{
+  return (v1si){-1090666755};
+}
+
+/*
+** test_v2si_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vrepih (void)
+{
+  return (v2si){-1090666755, -1090666755};
+}
+
+/*
+** test_v4si_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vrepih (void)
+{
+  return (v4si){-1090666755, -1090666755, -1090666755, -1090666755};
+}
+
+/*
+** test_v1si_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v1si
+test_v1si_via_vrepif (void)
+{
+  return (v1si){-16643};
+}
+
+/*
+** test_v2si_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vrepif (void)
+{
+  return (v2si){-16643, -16643};
+}
+
+/*
+** test_v4si_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vrepif (void)
+{
+  return (v4si){-16643, -16643, -16643, -16643};
+}
+
+/*
+** test_v2si_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v2si
+test_v2si_via_vrepig (void)
+{
+  return (v2si){-1, -16643};
+}
+
+/*
+** test_v4si_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v4si
+test_v4si_via_vrepig (void)
+{
+  return (v4si){-1, -16643, -1, -16643};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-tf-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-tf-1.c
new file mode 100644 (file)
index 0000000..37eb755
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vxe } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+typedef long double v1tf __attribute__ ((vector_size (16)));
+
+/*
+** test_v1tf_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vrepib (void)
+{
+  return (v1tf){-1.98172062152833090752940986271726055e-1644L};
+}
+
+/*
+** test_v1tf_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1tf
+test_v1tf_via_vrepih (void)
+{
+  return (v1tf){-3.76981572984797096816094251528390952e-78L};
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/vrepi-ti-1.c b/gcc/testsuite/gcc.target/s390/vector/vrepi-ti-1.c
new file mode 100644 (file)
index 0000000..3966c11
--- /dev/null
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target s390_vx } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-O2 -march=z13 -mzarch -fdump-tree-optimized" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Test loading constants which cannot be loaded via VECTOR GENERATE BYTE MASK
+   nor via VECTOR GENERATE MASK but via VECTOR REPLICATE IMMEDIATE.  */
+
+/* As time of writing this, there is no support for 128-bit integer literals.
+   Therefore, we have to emulate them as e.g. via two long literals.  However,
+   this test is all about V1TI const vectors.  Thus, ensure that we end up with
+   a V1TI const vector before expanding.  */
+/* { dg-final { scan-tree-dump "{ -0x55555555555555555555555555555556 }" "optimized" } } */
+/* { dg-final { scan-tree-dump "{ -0x41024102410241024102410241024103 }" "optimized" } } */
+/* { dg-final { scan-tree-dump "{ -0x4102000041020000410200004103 }" "optimized" } } */
+/* { dg-final { scan-tree-dump "{ -0x41020000000000004103 }" "optimized" } } */
+
+typedef __int128 v1ti __attribute__ ((vector_size (16)));
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+/*
+** test_v1ti_via_vrepib:
+**     vrepi   %v24,-86,0
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vrepib (void)
+{
+  return (v1ti)(v2di){0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa};
+}
+
+/*
+** test_v1ti_via_vrepih:
+**     vrepi   %v24,-16643,1
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vrepih (void)
+{
+  return (v1ti)(v2di){0xbefdbefdbefdbefd, 0xbefdbefdbefdbefd};
+}
+
+/*
+** test_v1ti_via_vrepif:
+**     vrepi   %v24,-16643,2
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vrepif (void)
+{
+  return (v1ti)(v2di){0xffffbefdffffbefd, 0xffffbefdffffbefd};
+}
+
+/*
+** test_v1ti_via_vrepig:
+**     vrepi   %v24,-16643,3
+**     br      %r14
+*/
+
+v1ti
+test_v1ti_via_vrepig (void)
+{
+  return (v1ti)(v2di){-16643, -16643};
+}
index 8948be28ed5d6ba6070ba2bce881730955b18b65..7d0d0235ad7a480ccd8bd1cf95954b302de8fa41 100644 (file)
@@ -6,7 +6,7 @@
 AUTOVEC_DOUBLE (QUIET_UNEQ);
 
 /* { dg-final { scan-assembler {\n\tvzero\t} } } */
-/* { dg-final { scan-assembler {\n\tvgmg\t} } } */
+/* { dg-final { scan-assembler {\n\tvgm\t%v[0-9]+,[0-9]+,[0-9]+,3} } } */
 /* { dg-final { scan-assembler-times {\n\tvfchdb\t} 2 } } */
 /* { dg-final { scan-assembler {\n\tvo\t} } } */
 /* { dg-final { scan-assembler {\n\tvsel\t} } } */
index 0a2aca0d5dd37e4ac30f824fbf42c9b5f33fe795..1793367c4269e1927b1bf8a560ba2650a8fedefc 100644 (file)
@@ -6,7 +6,7 @@
 AUTOVEC_FLOAT (QUIET_UNEQ);
 
 /* { dg-final { scan-assembler {\n\tvzero\t} } } */
-/* { dg-final { scan-assembler {\n\tvgmf\t} } } */
+/* { dg-final { scan-assembler {\n\tvgm\t%v[0-9]+,[0-9]+,[0-9]+,2} } } */
 /* { dg-final { scan-assembler-times {\n\tvfchsb\t} 2 } } */
 /* { dg-final { scan-assembler {\n\tvo\t} } } */
 /* { dg-final { scan-assembler {\n\tvsel\t} } } */
index 0e57b8dbc0533bea7f61c43758a44a1a6a712086..8acfdc88d27ef97b1cd9c36378bb3e6262daa1c2 100644 (file)
@@ -24,9 +24,9 @@ bar ()
   f = vec_genmasks_32 (6, 5);
 }
 
-/* a + f: { dg-final { scan-assembler-times "vone" 2 } } */
-/* b: { dg-final { scan-assembler-times "vgmf\t%v.*,0,0" 1 } } */
-/* c: { dg-final { scan-assembler-times "vgmf\t%v.*,31,31" 1 } } */
-/* d: { dg-final { scan-assembler-times "vgmf\t%v.*,5,5" 1 } } */
-/* e: { dg-final { scan-assembler-times "vgmf\t%v.*,31,0" 1 } } */
-/* b - e: { dg-final { scan-assembler-times "vgmf" 4 } } */
+/* a + f: { dg-final { scan-assembler-times {vone} 2 } } */
+/* b: { dg-final { scan-assembler-times {vgm\t%v.*,0,0,2} 1 } } */
+/* c: { dg-final { scan-assembler-times {vgm\t%v.*,31,31,2} 1 } } */
+/* d: { dg-final { scan-assembler-times {vgm\t%v.*,5,5,2} 1 } } */
+/* e: { dg-final { scan-assembler-times {vgm\t%v.*,31,0,2} 1 } } */
+/* b - e: { dg-final { scan-assembler-times {vgm\t%v[0-9]+,[0-9]+,[0-9]+,2} 4 } } */
index bab2e2d4028f9089c60f716f682adfe6dab84ed6..c57cd2c53a2f63f697860785729990ec6638aa5e 100644 (file)
@@ -29,14 +29,14 @@ foo ()
   uv2di = vec_splats ((unsigned long long)0x7f0f);
 }
 
-/* { dg-final { scan-assembler-times "vrepib\t%v.*,119" 1 } } */
-/* { dg-final { scan-assembler-times "vrepib\t%v.*,119" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,119,0" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,119,0" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepih\t%v.*,32527" 1 } } */
-/* { dg-final { scan-assembler-times "vrepih\t%v.*,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,1" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,1" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepif\t%v.*,32527" 1 } } */
-/* { dg-final { scan-assembler-times "vrepif\t%v.*,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,2" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,2" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepig\t%v.*,32527" 1 } } */
-/* { dg-final { scan-assembler-times "vrepig\t%v.*,32527" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,3" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,32527,3" 1 } } */
index 7ad090b2d5efee7afdef9c6d1e5dc48ba7238607..73af0e68f9f9962a22a52ad0773f1cb170a635a4 100644 (file)
@@ -29,14 +29,14 @@ foo ()
   uv2di = vec_splat_u64 (64000);
 }
 
-/* { dg-final { scan-assembler-times "vrepib\t%v.*,-112" 1 } } */
-/* { dg-final { scan-assembler-times "vrepib\t%v.*,-41" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-112,0" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-41,0" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepih\t%v.*,-32000" 1 } } */
-/* { dg-final { scan-assembler-times "vrepih\t%v.*,-1536" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-32000,1" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-1536,1" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepif\t%v.*,-32000" 1 } } */
-/* { dg-final { scan-assembler-times "vrepif\t%v.*,-1536" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-32000,2" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-1536,2" 1 } } */
 
-/* { dg-final { scan-assembler-times "vrepig\t%v.*,-32000" 1 } } */
-/* { dg-final { scan-assembler-times "vrepig\t%v.*,-1536" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-32000,3" 1 } } */
+/* { dg-final { scan-assembler-times "vrepi\t%v.*,-1536,3" 1 } } */