+2015-05-19 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * config.gcc: Add vecintrin.h to extra_headers. Add s390-c.o to
+ c_target_objs and cxx_target_objs. Add t-s390 to tmake_file.
+ * config/s390/s390-builtin-types.def: New file.
+ * config/s390/s390-builtins.def: New file.
+ * config/s390/s390-builtins.h: New file.
+ * config/s390/s390-c.c: New file.
+ * config/s390/s390-modes.def: Add modes CCVEQANY, CCVH,
+ CCVHANY, CCVHU, CCVHUANY, CCVFHANY, CCVFHEANY.
+ * config/s390/s390-protos.h (s390_expand_vec_compare_cc)
+ (s390_cpu_cpp_builtins, s390_register_target_pragmas): Add
+ prototypes.
+ * config/s390/s390.c (s390-builtins.h, s390-builtins.def):
+ Include.
+ (flags_builtin, flags_overloaded_builtin_var, s390_builtin_types)
+ (s390_builtin_fn_types, s390_builtin_decls, code_for_builtin): New
+ variable definitions.
+ (s390_const_operand_ok): New function.
+ (s390_expand_builtin): Rewrite.
+ (s390_init_builtins): New function.
+ (s390_handle_vectorbool_attribute): New function.
+ (s390_attribute_table): Add s390_vector_bool attribute.
+ (s390_match_ccmode_set): Handle new cc modes CCVH, CCVHU.
+ (s390_branch_condition_mask): Generate masks for new modes.
+ (s390_expand_vec_compare_cc): New function.
+ (s390_mangle_type): Add mangling for vector bool types.
+ (enum s390_builtin): Remove.
+ (s390_atomic_assign_expand_fenv): Rename constants for sfpc and
+ efpc builtins.
+ * config/s390/s390.h (TARGET_CPU_CPP_BUILTINS): Call
+ s390_cpu_cpp_builtins.
+ (REGISTER_TARGET_PRAGMAS): New macro.
+ * config/s390/s390.md: Define more UNSPEC_VEC_* constants.
+ (insn_cmp mode attribute): Add new CC modes.
+ (s390_sfpc, s390_efpc): Rename patterns to sfpc and efpc.
+ (lcbb): New pattern definition.
+ * config/s390/s390intrin.h: Include vecintrin.h.
+ * config/s390/t-s390: New file.
+ * config/s390/vecintrin.h: New file.
+ * config/s390/vector.md: Include vx-builtins.md.
+ * config/s390/vx-builtins.md: New file.S/390 zvector builtin
+ support.
+
2015-05-19 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/s390-modes.def: Add new modes CCVEQ, CCVFH, and
+2015-05-19 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * gcc.target/s390/zvector/vec-dbl-math-compile-1.c: New test.
+ * gcc.target/s390/zvector/vec-genbytemask-1.c: New test.
+ * gcc.target/s390/zvector/vec-genmask-1.c: New test.
+ * gcc.target/s390/zvector/vec-lcbb-1.c: New test.
+ * gcc.target/s390/zvector/vec-overloading-1.c: New test.
+ * gcc.target/s390/zvector/vec-overloading-2.c: New test.
+ * gcc.target/s390/zvector/vec-overloading-3.c: New test.
+ * gcc.target/s390/zvector/vec-overloading-4.c: New test.
+ * gcc.target/s390/zvector/vec-test-mask-1.c: New test.
+ * gcc.target/s390/zvector/vec-elem-1.c: New test.
+
2015-05-19 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* gcc.target/s390/vector/vec-scalar-cmp-1.c: New test.
--- /dev/null
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O3 -mzarch -march=z13 -mzvector --save-temps" } */
+
+/* { dg-final { scan-assembler-times "vfcedb\t" 1 } } */
+/* { dg-final { scan-assembler-times "vfchdb\t" 2 } } */
+/* { dg-final { scan-assembler-times "vfchedb\t" 2 } } */
+
+/* { dg-final { scan-assembler-times "vfcedbs\t" 2 } } */
+/* { dg-final { scan-assembler-times "vfchdbs\t" 2 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
+
+#include <vecintrin.h>
+
+vector bool long long
+cmpeq (vector double a, vector double b)
+{
+ return vec_cmpeq (a, b); /* vfcedb */
+}
+
+vector bool long long
+cmpgt (vector double a, vector double b)
+{
+ return vec_cmpgt (a, b); /* vfchdb */
+}
+
+vector bool long long
+cmpge (vector double a, vector double b)
+{
+ return vec_cmpge (a, b); /* vfchedb */
+}
+
+vector bool long long
+cmplt (vector double a, vector double b)
+{
+ return vec_cmplt (a, b); /* vfchdb */
+}
+
+vector bool long long
+cmple (vector double a, vector double b)
+{
+ return vec_cmple (a, b); /* vfchedb */
+}
+
+int
+all_eq (vector double a, vector double b)
+{
+ return vec_all_eq (a, b);
+}
+
+int
+any_eq (vector double a, vector double b)
+{
+ return vec_any_eq (a, b);
+}
+
+int
+all_lt (vector double a, vector double b)
+{
+ return vec_all_lt (a, b);
+}
+
+int
+any_lt (vector double a, vector double b)
+{
+ return vec_any_lt (a, b);
+}
--- /dev/null
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O3 -mzarch -march=z13 -mzvector" } */
+
+/* { dg-final { scan-assembler "nilf\t%r2,15" } } */
+/* { dg-final { scan-assembler "vlgvb" } } */
+
+signed char
+foo(unsigned char uc)
+{
+ return __builtin_s390_vec_extract((__vector signed char){ 0 }, uc);
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3 -mzarch -march=z13 -mzvector" } */
+
+#include <vecintrin.h>
+
+
+vector unsigned char a, b, c, d;
+
+int
+foo ()
+{
+ a = vec_genmask (0);
+ b = vec_genmask (65535);
+ c = vec_genmask (43605);
+ d = vec_genmask (37830);
+}
+
+/* { dg-final { scan-assembler-times "vzero" 1 } } */
+/* { dg-final { scan-assembler-times "vone" 1 } } */
+/* { dg-final { scan-assembler-times "vgbm\t%v.*,43605" 1 } } */
+/* { dg-final { scan-assembler-times "vgbm\t%v.*,37830" 1 } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3 -mzarch -march=z13 -mzvector" } */
+
+#include <vecintrin.h>
+
+
+vector unsigned int a, b, c, d, e, f;
+
+int
+foo ()
+{
+ a = vec_genmasks_32 (0, 31);
+ b = vec_genmasks_32 (0, 0);
+ c = vec_genmasks_32 (31, 31);
+ d = vec_genmasks_32 (5, 5);
+ e = vec_genmasks_32 (31, 0);
+ f = vec_genmasks_32 (6, 5);
+}
+/* { dg-final { scan-assembler-times "vone" 1 } } */
+/* { dg-final { scan-assembler-times "vgmf\t%v.*,0,0" 1 } } */
+/* { dg-final { scan-assembler-times "vgmf\t%v.*,31,31" 1 } } */
+/* { dg-final { scan-assembler-times "vgmf\t%v.*,5,5" 1 } } */
+/* { dg-final { scan-assembler-times "vgmf\t%v.*,31,0" 1 } } */
+/* { dg-final { scan-assembler-times "vone" 1 } } */
--- /dev/null
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O3 -mzarch -march=z13 -mzvector" } */
+
+/* { dg-final { scan-assembler-times "\tlcbb\t" 4 } } */
+
+#include <vecintrin.h>
+
+/* CC will be extracted into a GPR and returned. */
+int
+foo1 (void *ptr)
+{
+ return __lcbb (ptr, 64);
+}
+
+int
+foo2 (void *ptr)
+{
+ return __lcbb (ptr, 128) > 16;
+}
+
+int
+foo3 (void *ptr)
+{
+ return __lcbb (ptr, 256) == 16;
+}
+
+int
+foo4 (void *ptr)
+{
+ return __lcbb (ptr, 512) < 16;
+}
--- /dev/null
+/* Test whether overloading works as expected. */
+
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-march=z13 -mzarch -mzvector -fdump-tree-original" } */
+
+__vector int var_v4si;
+__vector unsigned var_uv4si;
+__vector bool var_bv4si;
+__vector long long var_v2di;
+__vector unsigned long long var_uv2di;
+__vector bool long long var_bv2di;
+__vector double var_v2df;
+
+int *intptr;
+unsigned *uintptr;
+double *dblptr;
+unsigned long long ull;
+const int *cintptr;
+long long* llptr;
+unsigned long long* ullptr;
+
+typedef __vector int v4si;
+typedef __vector unsigned int uv4si;
+
+v4si var2_v4si;
+uv4si var2_uv4si;
+
+void
+foo ()
+{
+ __builtin_s390_vec_scatter_element (var_v4si, var_uv4si, intptr, (unsigned long long)0);
+ __builtin_s390_vec_scatter_element (var2_v4si, var2_uv4si, intptr, (unsigned long long)0);
+ __builtin_s390_vec_scatter_element (var_bv4si, var_uv4si, uintptr, (unsigned long long)0);
+ __builtin_s390_vec_scatter_element (var_uv4si, var_uv4si, uintptr, (unsigned long long)0);
+ __builtin_s390_vec_scatter_element (var_v2di, var_uv2di, llptr, (unsigned long long)0);
+ __builtin_s390_vec_scatter_element (var_bv2di, var_uv2di, ullptr, (unsigned long long)0);
+ __builtin_s390_vec_scatter_element (var_uv2di, var_uv2di, ullptr, (unsigned long long)0);
+ __builtin_s390_vec_scatter_element (var_v2df, var_uv2di, dblptr, (unsigned long long)0);
+
+ /* While the last argument is a int there is a way to convert it to
+ unsigned long long, so this variant is supposed to match. */
+ __builtin_s390_vec_scatter_element (var_v4si, var_uv4si, intptr, 0);
+
+ __builtin_s390_vec_insert_and_zero (intptr);
+ __builtin_s390_vec_insert_and_zero (cintptr);
+
+ __builtin_s390_vec_promote ((signed char)1, 1);
+ __builtin_s390_vec_promote ((unsigned char)1, 1);
+ __builtin_s390_vec_promote ((short int)1, 1);
+ __builtin_s390_vec_promote ((unsigned short int)1, 1);
+ __builtin_s390_vec_promote ((int)1, 1);
+ __builtin_s390_vec_promote ((unsigned)1, 1);
+ __builtin_s390_vec_promote ((long long)1, 1);
+ __builtin_s390_vec_promote ((unsigned long long)1, 1);
+ __builtin_s390_vec_promote ((double)1, 1);
+
+ /* This is supposed to match vec_promote_s32 */
+ __builtin_s390_vec_promote (1, (signed char) -1);
+
+ /* Constants in C usually are considered int. */
+ __builtin_s390_vec_promote (1, 1);
+
+ /* And (unsigned) long if they are too big for int. */
+ __builtin_s390_vec_promote (1ULL << 32, 1);
+ __builtin_s390_vec_promote (1LL << 32, 1);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_s390_vscef " 5 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_s390_vsceg " 4 "original" } } */
+
+/* { dg-final { scan-tree-dump-times "__builtin_s390_vllezf " 2 "original" } } */
+
+/* { dg-final { scan-tree-dump-times "__builtin_s390_vlvgb_noin " 2 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_s390_vlvgh_noin " 2 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_s390_vlvgf_noin " 4 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_s390_vlvgg_noin " 4 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_s390_vlvgg_dbl_noin " 1 "original" } } */
--- /dev/null
+/* Test whether overloading works as expected. */
+
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-march=z13 -mzarch -mzvector" } */
+
+__vector int v4si;
+__vector unsigned uv4si;
+__vector bool bv4si;
+__vector long long v2di;
+__vector unsigned long long uv2di;
+__vector bool long long bv2di;
+__vector double v2df;
+int *intptr;
+unsigned *uintptr;
+double *dblptr;
+long long ll;
+unsigned long long ull;
+const int *cintptr;
+long long* llptr;
+unsigned long long* ullptr;
+
+void
+foo ()
+{
+ __builtin_s390_vec_scatter_element (v4si, uv4si, (int*)0, 0); /* ok */
+ __builtin_s390_vec_insert_and_zero (intptr); /* ok */
+
+ /* The unsigned pointer must not match the signed pointer. */
+ __builtin_s390_vec_scatter_element (v4si, uv4si, uintptr, 0); /* { dg-error "invalid parameter combination for intrinsic" } */
+
+ /* Make sure signed int pointers don't match unsigned int pointers. */
+ __builtin_s390_vec_scatter_element (bv4si, uv4si, intptr, 0); /* { dg-error "invalid parameter combination for intrinsic" } */
+
+ /* Const pointers do not match unqualified operands. */
+ __builtin_s390_vec_scatter_element (v4si, uv4si, cintptr, 0); /* { dg-error "invalid parameter combination for intrinsic" } */
+
+ /* Volatile pointers do not match unqualified operands. */
+ __builtin_s390_vec_scatter_element (v4si, uv4si, cintptr, 0); /* { dg-error "invalid parameter combination for intrinsic" } */
+
+ /* The third operands needs to be double *. */
+ __builtin_s390_vec_scatter_element (v2df, uv4si, intptr, 0); /* { dg-error "invalid parameter combination for intrinsic" } */
+
+ /* This is an ambigious overload. */
+ __builtin_s390_vec_scatter_element (v4si, uv4si, 0, 0); /* { dg-error "invalid parameter combination for intrinsic" } */
+
+ /* Pointer to vector must not match. */
+ __builtin_s390_vec_scatter_element (v4si, uv4si, &v4si, 0); /* { dg-error "invalid parameter combination for intrinsic" } */
+
+ /* Don't accept const int* for int*. */
+ __builtin_s390_vec_scatter_element (v4si, uv4si, cintptr, 0); /* { dg-error "invalid parameter combination for intrinsic" } */
+
+ __builtin_s390_vec_load_pair (ll, ull); /* { dg-error "ambiguous overload for intrinsic" } */
+ __builtin_s390_vec_load_pair (ull, ll); /* { dg-error "ambiguous overload for intrinsic" } */
+}
--- /dev/null
+/* Check for error messages supposed to be issued during overloading. */
+
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-march=z13 -mzarch -mzvector" } */
+
+__vector int v4si;
+__vector unsigned uv4si;
+
+int *intptr;
+unsigned long long ull;
+const unsigned int *ucintptr;
+
+void
+foo ()
+{
+ /* A backend check makes sure the forth operand is a literal. */
+ __builtin_s390_vec_gather_element (uv4si, uv4si, ucintptr, 256); /* { dg-error "constant argument 4 for builtin.*is out of range for target type" } */
+ __builtin_s390_vec_gather_element (uv4si, uv4si, ucintptr, 5); /* { dg-error "constant argument 4 for builtin.*is out of range" } */
+}
--- /dev/null
+/* Check for error messages supposed to be issued during builtin expansion. */
+
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-march=z13 -mzarch -mzvector" } */
+
+__vector int v4si;
+__vector unsigned uv4si;
+
+int *intptr;
+unsigned long long ull;
+const unsigned int *ucintptr;
+
+void
+foo ()
+{
+ /* A backend check makes sure the forth operand is a literal. */
+ __builtin_s390_vec_scatter_element (v4si, uv4si, intptr, ull); /* { dg-error "constant value required for builtin" } */
+}
--- /dev/null
+/* { dg-do compile { target { s390*-*-* } } } */
+/* { dg-options "-O3 -mzarch -march=z13 -mzvector" } */
+
+/* { dg-final { scan-assembler-times "vtm" 2 } } */
+/* { dg-final { scan-assembler-times "ipm" 1 } } */
+
+#include <vecintrin.h>
+
+/* CC will be extracted into a GPR and returned. */
+int
+foo (vector unsigned int a, vector unsigned b)
+{
+ return vec_test_mask (a, b);
+}
+
+extern void baz (void);
+
+/* In that case the ipm/srl is supposed to optimized out by
+ combine/s390_canonicalize_comparison. */
+int
+bar (vector unsigned int a, vector unsigned b)
+{
+ if (vec_test_mask (a, b) == 2)
+ baz ();
+}