Merge new optabs with the existing implementations for signbit and
isinf.

gcc/ChangeLog:

        * config/s390/s390.h (S390_TDC_POSITIVE_ZERO): Remove.
        (S390_TDC_NEGATIVE_ZERO): Remove.
        (S390_TDC_POSITIVE_NORMALIZED_BFP_NUMBER): Remove.
        (S390_TDC_NEGATIVE_NORMALIZED_BFP_NUMBER): Remove.
        (S390_TDC_POSITIVE_DENORMALIZED_BFP_NUMBER): Remove.
        (S390_TDC_NEGATIVE_DENORMALIZED_BFP_NUMBER): Remove.
        (S390_TDC_POSITIVE_INFINITY): Remove.
        (S390_TDC_NEGATIVE_INFINITY): Remove.
        (S390_TDC_POSITIVE_QUIET_NAN): Remove.
        (S390_TDC_NEGATIVE_QUIET_NAN): Remove.
        (S390_TDC_POSITIVE_SIGNALING_NAN): Remove.
        (S390_TDC_NEGATIVE_SIGNALING_NAN): Remove.
        (S390_TDC_POSITIVE_DENORMALIZED_DFP_NUMBER): Remove.
        (S390_TDC_NEGATIVE_DENORMALIZED_DFP_NUMBER): Remove.
        (S390_TDC_POSITIVE_NORMALIZED_DFP_NUMBER): Remove.
        (S390_TDC_NEGATIVE_NORMALIZED_DFP_NUMBER): Remove.
        (S390_TDC_SIGNBIT_SET): Remove.
        (S390_TDC_INFINITY): Remove.
        * config/s390/s390.md (signbit<mode>2<tf_fpr>): Merge this one
        (isinf<mode>2<tf_fpr>): and this one into
        (<TDC_CLASS:tdc_insn><mode>2<tf_fpr>): new expander.
        (isnormal<mode>2<tf_fpr>): New BFP expander.
        (isnormal<mode>2): New DFP expander.
        * config/s390/vector.md (signbittf2_vr): Merge this one
        (isinftf2_vr): and this one into
        (<tdc_insn>tf2_vr): new expander.
        (signbittf2): Merge this one
        (isinftf2): and this one into
        (<tdc_insn>tf2): new expander.

gcc/testsuite/ChangeLog:

        * gcc.target/s390/isfinite-isinf-isnormal-signbit-1.c: New test.
        * gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c: New test.
        * gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c: New test.
        * gcc.target/s390/isfinite-isinf-isnormal-signbit.h: New test.
---
 Bootstrap and regtest are running.  About to push if they succeed and
 there are no comments.

 gcc/config/s390/s390.h                        |  31 -----
 gcc/config/s390/s390.md                       | 114 +++++++++++++++---
 gcc/config/s390/vector.md                     |  42 ++-----
 .../s390/isfinite-isinf-isnormal-signbit-1.c  |  62 ++++++++++
 .../s390/isfinite-isinf-isnormal-signbit-2.c  |  13 ++
 .../s390/isfinite-isinf-isnormal-signbit-3.c  |  13 ++
 .../s390/isfinite-isinf-isnormal-signbit.h    |  23 ++++
 7 files changed, 215 insertions(+), 83 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-1.c
 create mode 100644 
gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c
 create mode 100644 
gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c
 create mode 100644 
gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit.h

diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 4a4dde1a9ba..9a4ddfe7f63 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -288,37 +288,6 @@ extern const char *s390_host_detect_local_cpu (int argc, 
const char **argv);
   "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}",            \
   "%{!march=*:-march=z900}"
 
-/* Constants needed to control the TEST DATA CLASS (TDC) instruction.  */
-#define S390_TDC_POSITIVE_ZERO                     (1 << 11)
-#define S390_TDC_NEGATIVE_ZERO                     (1 << 10)
-#define S390_TDC_POSITIVE_NORMALIZED_BFP_NUMBER    (1 << 9)
-#define S390_TDC_NEGATIVE_NORMALIZED_BFP_NUMBER    (1 << 8)
-#define S390_TDC_POSITIVE_DENORMALIZED_BFP_NUMBER  (1 << 7)
-#define S390_TDC_NEGATIVE_DENORMALIZED_BFP_NUMBER  (1 << 6)
-#define S390_TDC_POSITIVE_INFINITY                 (1 << 5)
-#define S390_TDC_NEGATIVE_INFINITY                 (1 << 4)
-#define S390_TDC_POSITIVE_QUIET_NAN                (1 << 3)
-#define S390_TDC_NEGATIVE_QUIET_NAN                (1 << 2)
-#define S390_TDC_POSITIVE_SIGNALING_NAN            (1 << 1)
-#define S390_TDC_NEGATIVE_SIGNALING_NAN            (1 << 0)
-
-/* The following values are different for DFP.  */
-#define S390_TDC_POSITIVE_DENORMALIZED_DFP_NUMBER (1 << 9)
-#define S390_TDC_NEGATIVE_DENORMALIZED_DFP_NUMBER (1 << 8)
-#define S390_TDC_POSITIVE_NORMALIZED_DFP_NUMBER   (1 << 7)
-#define S390_TDC_NEGATIVE_NORMALIZED_DFP_NUMBER   (1 << 6)
-
-/* For signbit, the BFP-DFP-difference makes no difference. */
-#define S390_TDC_SIGNBIT_SET (S390_TDC_NEGATIVE_ZERO \
-                         | S390_TDC_NEGATIVE_NORMALIZED_BFP_NUMBER \
-                         | S390_TDC_NEGATIVE_DENORMALIZED_BFP_NUMBER\
-                         | S390_TDC_NEGATIVE_INFINITY \
-                         | S390_TDC_NEGATIVE_QUIET_NAN \
-                         | S390_TDC_NEGATIVE_SIGNALING_NAN )
-
-#define S390_TDC_INFINITY (S390_TDC_POSITIVE_INFINITY \
-                         | S390_TDC_NEGATIVE_INFINITY )
-
 /* Target machine storage layout.  */
 
 /* Everything is big-endian.  */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 3d5759d6252..d2c8c2a1b7d 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -432,6 +432,81 @@
 (define_constants [(TBEGIN_MASK  65292)]) ; 0xff0c
 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
 
+;; TEST DATA CLASS
+
+; Data class bitmap:
+;
+; positive zero                    11
+; negative zero                    10
+; positive normalized bfp number    9
+; negative normalized bfp number    8
+; positive denormalized bfp number  7
+; negative denormalized bfp number  6
+; positive infinity                 5
+; negative infinity                 4
+; positive quiet nan                3
+; negative quiet nan                2
+; positive signaling nan            1
+; negative signaling nan            0
+;
+; The following values are different for DFP:
+;
+; positive denormalized dfp number  9
+; negative denormalized dfp number  8
+; positive normalized dfp number    7
+; negative normalized dfp number    6
+
+; For signbit, the BFP-DFP-difference makes no difference.
+; S390_TDC_SIGNBIT_SET = negative_zero
+;                        | negative_normalized_bfp_number
+;                        | negative_denormalized_bfp_number
+;                        | negative_infinity
+;                        | negative_quiet_nan
+;                        | negative_signaling_nan
+;                      = 1365
+;
+; For finite, the BFP-DFP-difference makes no difference.
+; S390_TDC_FINITE = positive_zero
+;                   | negative_zero
+;                   | positive_normalized_bfp_number
+;                   | negative_normalized_bfp_number
+;                   | positive_denormalized_bfp_number
+;                   | negative_denormalized_bfp_number
+;                 = 4032
+;
+; S390_TDC_INFINITY = positive_infinity
+;                     | negative_infinity
+;                   = 48
+;
+; S390_TDC_NORMAL_BFP = positive_normalized_bfp_number
+;                       | negative_normalized_bfp_number
+;                     = 768
+;
+; S390_TDC_NORMAL_DFP = positive_normalized_dfp_number
+;                       | negative_normalized_dfp_number
+;                     = 192
+
+(define_constants [(S390_TDC_SIGNBIT_SET 1365)
+                  (S390_TDC_FINITE 4032)
+                  (S390_TDC_INFINITY 48)
+                  (S390_TDC_NORMAL_BFP 768)
+                  (S390_TDC_NORMAL_DFP 192)])
+
+(define_int_iterator TDC_CLASS [S390_TDC_SIGNBIT_SET
+                               S390_TDC_FINITE
+                               S390_TDC_INFINITY])
+
+(define_int_iterator TDC_CLASS_BFP [S390_TDC_SIGNBIT_SET
+                                   S390_TDC_FINITE
+                                   S390_TDC_INFINITY
+                                   S390_TDC_NORMAL_BFP])
+
+(define_int_attr tdc_insn [(S390_TDC_SIGNBIT_SET "signbit")
+                          (S390_TDC_FINITE "isfinite")
+                          (S390_TDC_INFINITY "isinf")
+                          (S390_TDC_NORMAL_BFP "isnormal")
+                          (S390_TDC_NORMAL_DFP "isnormal")])
+
 ;; Instruction operand type as used in the Principles of Operation.
 ;; Used to determine defaults for length and other attribute values.
 
@@ -3549,29 +3624,32 @@
 ; Test data class.
 ;
 
-(define_expand "signbit<mode>2<tf_fpr>"
+(define_expand "<TDC_CLASS:tdc_insn><mode>2<tf_fpr>"
   [(set (reg:CCZ CC_REGNUM)
-        (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
-                     (match_dup 2)]
-                     UNSPEC_TDC_INSN))
+       (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
+                    (const_int TDC_CLASS)]
+                    UNSPEC_TDC_INSN))
    (set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
-  "TARGET_HARD_FLOAT"
-{
-  operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
-})
+       (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
+  "TARGET_HARD_FLOAT")
 
-(define_expand "isinf<mode>2<tf_fpr>"
+(define_expand "isnormal<mode>2<tf_fpr>"
   [(set (reg:CCZ CC_REGNUM)
-        (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
-                     (match_dup 2)]
-                     UNSPEC_TDC_INSN))
+       (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f")
+                    (const_int S390_TDC_NORMAL_BFP)]
+                    UNSPEC_TDC_INSN))
    (set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
-  "TARGET_HARD_FLOAT"
-{
-  operands[2] = GEN_INT (S390_TDC_INFINITY);
-})
+       (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
+  "TARGET_HARD_FLOAT")
+
+(define_expand "isnormal<mode>2"
+  [(set (reg:CCZ CC_REGNUM)
+       (unspec:CCZ [(match_operand:DFP_ALL 1 "register_operand" "f")
+                    (const_int S390_TDC_NORMAL_DFP)]
+                    UNSPEC_TDC_INSN))
+   (set (match_operand:SI 0 "register_operand" "=d")
+       (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
+  "TARGET_HARD_DFP")
 
 ; This extracts CC into a GPR properly shifted.  The actual IPM
 ; instruction will be issued by reload.  The constraint of operand 1
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index a75b7cb5825..b3e14601dbd 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -3064,11 +3064,11 @@
 
 ; test data class
 
-(define_expand "signbittf2_vr"
+(define_expand "<tdc_insn>tf2_vr"
   [(parallel
     [(set (reg:CCRAW CC_REGNUM)
          (unspec:CCRAW [(match_operand:TF 1 "register_operand" "")
-                        (match_dup        2)]
+                        (const_int TDC_CLASS_BFP)]
                        UNSPEC_VEC_VFTCICC))
      (clobber (scratch:V1TI))])
    (set (match_operand:SI                  0 "register_operand" "")
@@ -3077,40 +3077,14 @@
        (if_then_else:SI (eq (reg:CCRAW CC_REGNUM) (const_int 8))
                         (const_int 1)
                         (match_dup        0)))]
-  "TARGET_VXE"
-{
-  operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
-})
-
-(define_expand "signbittf2"
-  [(match_operand:SI 0 "register_operand" "")
-   (match_operand:TF 1 "register_operand" "")]
-  "HAVE_TF (signbittf2)"
-  { EXPAND_TF (signbittf2, 2); })
-
-(define_expand "isinftf2_vr"
-  [(parallel
-    [(set (reg:CCRAW CC_REGNUM)
-         (unspec:CCRAW [(match_operand:TF 1 "register_operand" "")
-                        (match_dup        2)]
-                       UNSPEC_VEC_VFTCICC))
-     (clobber (scratch:V1TI))])
-   (set (match_operand:SI                  0 "register_operand" "")
-       (const_int 0))
-   (set (match_dup                         0)
-       (if_then_else:SI (eq (reg:CCRAW CC_REGNUM) (const_int 8))
-                        (const_int 1)
-                        (match_dup        0)))]
-  "TARGET_VXE"
-{
-  operands[2] = GEN_INT (S390_TDC_INFINITY);
-})
+  "TARGET_VXE")
 
-(define_expand "isinftf2"
+(define_expand "<tdc_insn>tf2"
   [(match_operand:SI 0 "register_operand" "")
-   (match_operand:TF 1 "register_operand" "")]
-  "HAVE_TF (isinftf2)"
-  { EXPAND_TF (isinftf2, 2); })
+   (match_operand:TF 1 "register_operand" "")
+   (const_int TDC_CLASS_BFP)]
+  "HAVE_TF (<tdc_insn>tf2)"
+  { EXPAND_TF (<tdc_insn>tf2, 2); })
 
 ;
 ; Vector byte swap patterns
diff --git a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-1.c 
b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-1.c
new file mode 100644
index 00000000000..a832036c88d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-1.c
@@ -0,0 +1,62 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z9-ec -mzarch" } */
+
+#define SIGNBIT(T) \
+  int signbit_##T (T x) { return __builtin_signbit (x); }
+
+SIGNBIT (float)
+/* { dg-final { scan-assembler-times {tceb\t%f[0-9]+,1365} 1 } } */
+
+SIGNBIT (double)
+/* { dg-final { scan-assembler-times {tcdb\t%f[0-9]+,1365} 1 } } */
+
+SIGNBIT (_Decimal32)
+/* { dg-final { scan-assembler-times {tdcet\t%f[0-9]+,1365} 1 } } */
+
+SIGNBIT (_Decimal64)
+/* { dg-final { scan-assembler-times {tdcdt\t%f[0-9]+,1365} 1 } } */
+
+#define ISFINITE(T) \
+  int isfinite_##T (T x) { return __builtin_isfinite (x); }
+
+ISFINITE (float)
+/* { dg-final { scan-assembler-times {tceb\t%f[0-9]+,4032} 1 } } */
+
+ISFINITE (double)
+/* { dg-final { scan-assembler-times {tcdb\t%f[0-9]+,4032} 1 } } */
+
+ISFINITE (_Decimal32)
+/* { dg-final { scan-assembler-times {tdcet\t%f[0-9]+,4032} 1 } } */
+
+ISFINITE (_Decimal64)
+/* { dg-final { scan-assembler-times {tdcdt\t%f[0-9]+,4032} 1 } } */
+
+#define ISINF(T) \
+  int isinf_##T (T x) { return __builtin_isinf (x); }
+
+ISINF (float)
+/* { dg-final { scan-assembler-times {tceb\t%f[0-9]+,48} 1 } } */
+
+ISINF (double)
+/* { dg-final { scan-assembler-times {tcdb\t%f[0-9]+,48} 1 } } */
+
+ISINF (_Decimal32)
+/* { dg-final { scan-assembler-times {tdcet\t%f[0-9]+,48} 1 } } */
+
+ISINF (_Decimal64)
+/* { dg-final { scan-assembler-times {tdcdt\t%f[0-9]+,48} 1 } } */
+
+#define ISNORMAL(T) \
+  int isnormal_##T (T x) { return __builtin_isnormal (x); }
+
+ISNORMAL (float)
+/* { dg-final { scan-assembler-times {tceb\t%f[0-9]+,768} 1 } } */
+
+ISNORMAL (double)
+/* { dg-final { scan-assembler-times {tcdb\t%f[0-9]+,768} 1 } } */
+
+ISNORMAL (_Decimal32)
+/* { dg-final { scan-assembler-times {tdcet\t%f[0-9]+,192} 1 } } */
+
+ISNORMAL (_Decimal64)
+/* { dg-final { scan-assembler-times {tdcdt\t%f[0-9]+,192} 1 } } */
diff --git a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c 
b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c
new file mode 100644
index 00000000000..2ff5a37c0f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+
+#include "isfinite-isinf-isnormal-signbit.h"
+
+/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,1365} 1 } } SIGNBIT long 
double */
+/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 } } SIGNBIT 
_Decimal128 */
+/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,4032} 1 } } ISFINITE long 
double */
+/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,4032} 1 } } ISFINITE 
_Decimal128 */
+/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,48} 1 } } ISINF long 
double */
+/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,48} 1 } } ISINF 
_Decimal128 */
+/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,768} 1 } } ISNORMAL long 
double */
+/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,192} 1 } } ISNORMAL 
_Decimal128 */
diff --git a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c 
b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c
new file mode 100644
index 00000000000..8f67553c7da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z14 -mzarch" } */
+
+#include "isfinite-isinf-isnormal-signbit.h"
+
+/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,1365} 1 } } */
+/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 } } */
+/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,4032} 1 } } */
+/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,4032} 1 } } */
+/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,48} 1 } } */
+/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,48} 1 } } */
+/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,768} 1 } } */
+/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,192} 1 } } */
diff --git a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit.h 
b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit.h
new file mode 100644
index 00000000000..9195f7c5f67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit.h
@@ -0,0 +1,23 @@
+#define SIGNBIT(T, U) \
+  int signbit_##U (T x) { return __builtin_signbit (x); }
+
+SIGNBIT (long double, long_double)
+SIGNBIT (_Decimal128, _Decimal128)
+
+#define ISFINITE(T, U) \
+  int isfinite_##U (T x) { return __builtin_isfinite (x); }
+
+ISFINITE (long double, long_double)
+ISFINITE (_Decimal128, _Decimal128)
+
+#define ISINF(T, U) \
+  int isinf_##U (T x) { return __builtin_isinf (x); }
+
+ISINF (long double, long_double)
+ISINF (_Decimal128, _Decimal128)
+
+#define ISNORMAL(T, U) \
+  int isnormal_##U (T x) { return __builtin_isnormal (x); }
+
+ISNORMAL (long double, long_double)
+ISNORMAL (_Decimal128, _Decimal128)
-- 
2.47.0

Reply via email to