aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>2025-01-20 10:01:10 +0100
committerStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>2025-01-20 10:01:10 +0100
commit4cf5e261df34878033e20fb2b8a13ea643ab7f4c (patch)
tree9de4a6ec634d4e76c2091b09ea4ea46054d47542 /gcc
parent2e87d6e44198e2b134555d661366a2f941615511 (diff)
downloadgcc-4cf5e261df34878033e20fb2b8a13ea643ab7f4c.zip
gcc-4cf5e261df34878033e20fb2b8a13ea643ab7f4c.tar.gz
gcc-4cf5e261df34878033e20fb2b8a13ea643ab7f4c.tar.bz2
s390: arch15: Vector load positive: Add 128-bit integer support
For previous architectures emulate operation abs. gcc/ChangeLog: * config/s390/s390-builtins.def (s390_vec_abs_s128): Add. (s390_vlpq): Add. * config/s390/s390-builtin-types.def: Update accordingly. * config/s390/vector.md (abs<mode>2): Emulate w/o VXE3. (*abs<mode>2): Add 128-bit variant. (*vec_sel0<mode>): Make it a ... (vec_sel0<mode>): named pattern. gcc/testsuite/ChangeLog: * gcc.target/s390/vector/vec-abs-emu.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/s390/s390-builtin-types.def1
-rw-r--r--gcc/config/s390/s390-builtins.def2
-rw-r--r--gcc/config/s390/vector.md29
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c46
4 files changed, 73 insertions, 5 deletions
diff --git a/gcc/config/s390/s390-builtin-types.def b/gcc/config/s390/s390-builtin-types.def
index 7aeea34..398ea6e 100644
--- a/gcc/config/s390/s390-builtin-types.def
+++ b/gcc/config/s390/s390-builtin-types.def
@@ -136,6 +136,7 @@ DEF_OPAQUE_VECTOR_TYPE (BT_OV4SI, BT_INT, 4)
DEF_FN_TYPE_0 (BT_FN_INT, BT_INT)
DEF_FN_TYPE_0 (BT_FN_UINT, BT_UINT)
DEF_FN_TYPE_0 (BT_FN_VOID, BT_VOID)
+DEF_FN_TYPE_1 (BT_FN_INT128_INT128, BT_INT128, BT_INT128)
DEF_FN_TYPE_1 (BT_FN_INT128_V2DI, BT_INT128, BT_V2DI)
DEF_FN_TYPE_1 (BT_FN_INT_INT, BT_INT, BT_INT)
DEF_FN_TYPE_1 (BT_FN_INT_VOIDPTR, BT_INT, BT_VOIDPTR)
diff --git a/gcc/config/s390/s390-builtins.def b/gcc/config/s390/s390-builtins.def
index 9c33344..32ec2eb 100644
--- a/gcc/config/s390/s390-builtins.def
+++ b/gcc/config/s390/s390-builtins.def
@@ -1820,6 +1820,7 @@ OB_DEF_VAR (s390_vec_abs_s8, s390_vlpb, 0,
OB_DEF_VAR (s390_vec_abs_s16, s390_vlph, 0, 0, BT_OV_V8HI_V8HI)
OB_DEF_VAR (s390_vec_abs_s32, s390_vlpf, 0, 0, BT_OV_V4SI_V4SI)
OB_DEF_VAR (s390_vec_abs_s64, s390_vlpg, 0, 0, BT_OV_V2DI_V2DI)
+OB_DEF_VAR (s390_vec_abs_s128, s390_vlpq, 0, 0, BT_OV_V1TI_V1TI) /* NOGEN */
OB_DEF_VAR (s390_vec_abs_flt, s390_vflpsb, B_VXE, 0, BT_OV_V4SF_V4SF)
OB_DEF_VAR (s390_vec_abs_dbl, s390_vflpdb, 0, 0, BT_OV_V2DF_V2DF)
@@ -1827,6 +1828,7 @@ B_DEF (s390_vlpb, absv16qi2, 0,
B_DEF (s390_vlph, absv8hi2, 0, B_VX, 0, BT_FN_V8HI_V8HI)
B_DEF (s390_vlpf, absv4si2, 0, B_VX, 0, BT_FN_V4SI_V4SI)
B_DEF (s390_vlpg, absv2di2, 0, B_VX, 0, BT_FN_V2DI_V2DI)
+B_DEF (s390_vlpq, absti2, 0, B_VX, 0, BT_FN_INT128_INT128)
B_DEF (s390_vflpsb, absv4sf2, 0, B_VXE, 0, BT_FN_V4SF_V4SF)
B_DEF (s390_vflpdb, absv2df2, 0, B_VX, 0, BT_FN_V2DF_V2DF)
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 57a9d20..8824c4f 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -1191,10 +1191,29 @@
"vlc<bhfgq>\t%v0,%v1"
[(set_attr "op_type" "VRR")])
-; vlpb, vlph, vlpf, vlpg
-(define_insn "abs<mode>2"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (abs:VI (match_operand:VI 1 "register_operand" "v")))]
+(define_expand "abs<mode>2"
+ [(set (match_operand:VIT 0 "register_operand" "=v")
+ (abs:VIT (match_operand:VIT 1 "register_operand" "v")))]
+ "TARGET_VX"
+{
+ // Emulate via vec_sel (op1, -op1, op1 < 0)
+ if ((<MODE>mode == V1TImode || <MODE>mode == TImode) && !TARGET_VXE3)
+ {
+ rtx zero = gen_reg_rtx (<MODE>mode);
+ rtx neg_op1 = gen_reg_rtx (<MODE>mode);
+ rtx lt = gen_reg_rtx (<MODE>mode);
+ emit_move_insn (zero, GEN_INT (0));
+ emit_move_insn (neg_op1, gen_rtx_MINUS (<MODE>mode, zero, operands[1]));
+ s390_expand_vec_compare (lt, LT, operands[1], zero);
+ emit_insn (gen_vec_sel0<mode> (operands[0], operands[1], neg_op1, lt, GEN_INT (0)));
+ DONE;
+ }
+})
+
+; vlpb, vlph, vlpf, vlpg, vlpq
+(define_insn "*abs<mode>2"
+ [(set (match_operand:VIT_VXE3 0 "register_operand" "=v")
+ (abs:VIT_VXE3 (match_operand:VIT_VXE3 1 "register_operand" "v")))]
"TARGET_VX"
"vlp<bhfgq>\t%v0,%v1"
[(set_attr "op_type" "VRR")])
@@ -2430,7 +2449,7 @@
})
; op0 = op3 == 0 ? op1 : op2
-(define_insn "*vec_sel0<mode>"
+(define_insn "vec_sel0<mode>"
[(set (match_operand:VT 0 "register_operand" "=v")
(if_then_else:VT
(eq (match_operand:<TOINTVEC> 3 "register_operand" "v")
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
new file mode 100644
index 0000000..8c1038a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-abs-emu.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mzarch -march=z13 -save-temps" } */
+/* { dg-require-effective-target int128 } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+/* { dg-final { scan-assembler-not {\tvlpq\t} } } */
+
+#include <assert.h>
+
+typedef __attribute__ ((vector_size (16))) signed long long v2di;
+typedef __attribute__ ((vector_size (16))) signed __int128 v1ti;
+
+/*
+** my_abs:
+** vzero %v[0-9]+
+** vchlg %v[0-9]+,%v[0-9]+,%v[0-9]+
+** vceqg %v[0-9]+,%v[0-9]+,%v[0-9]+
+** vpdi %v[0-9]+,%v[0-9]+,%v[0-9]+,4
+** vchg %v[0-9]+,%v[0-9]+,%v[0-9]+
+** vn %v[0-9]+,%v[0-9]+,%v[0-9]+
+** vo %v[0-9]+,%v[0-9]+,%v[0-9]+
+** vrepg %v[0-9]+,%v[0-9]+,1
+** vsq %v[0-9]+,%v[0-9]+,%v[0-9]+
+** vsel %v[0-9]+,%v[0-9]+,%v[0-9]+,%v[0-9]+
+** br %r14
+*/
+__attribute__ ((noipa)) v1ti
+my_abs (v1ti x)
+{
+ return __builtin_s390_vec_abs (x);
+}
+
+int
+main (void)
+{
+ v2di x;
+
+ x = (v2di){ -1, -42 };
+ x = (v2di) my_abs ((v1ti) x);
+ assert (x[0] == 0 && x[1] == 42);
+
+ x = (v2di){ 0, 42 };
+ x = (v2di) my_abs ((v1ti) x);
+ assert (x[0] == 0 && x[1] == 42);
+
+ return 0;
+}