aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>2025-01-24 12:53:44 +0100
committerStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>2025-01-24 12:53:44 +0100
commitb00bd29286345cc90afc61dcb16d1fa44976dae6 (patch)
tree297785f30b1fe4c5f5e7bf80f290efd1b3a25108 /gcc/config
parentdc1e1b38ce60cd1da781c7dcd97a36add5482a00 (diff)
downloadgcc-b00bd29286345cc90afc61dcb16d1fa44976dae6.zip
gcc-b00bd29286345cc90afc61dcb16d1fa44976dae6.tar.gz
gcc-b00bd29286345cc90afc61dcb16d1fa44976dae6.tar.bz2
s390: Implement isfinite and isnormal optabs
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.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/s390/s390.h31
-rw-r--r--gcc/config/s390/s390.md114
-rw-r--r--gcc/config/s390/vector.md42
3 files changed, 104 insertions, 83 deletions
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 957877b..6f7195d 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -305,37 +305,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 8ce93a0..c164ea7 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -441,6 +441,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.
@@ -3670,29 +3745,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 7247e89..547e6a2 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -3238,11 +3238,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:TI))])
(set (match_operand:SI 0 "register_operand" "")
@@ -3251,40 +3251,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:TI))])
- (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