diff options
author | Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> | 2025-01-24 12:53:44 +0100 |
---|---|---|
committer | Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> | 2025-01-24 12:53:44 +0100 |
commit | b00bd29286345cc90afc61dcb16d1fa44976dae6 (patch) | |
tree | 297785f30b1fe4c5f5e7bf80f290efd1b3a25108 /gcc/config | |
parent | dc1e1b38ce60cd1da781c7dcd97a36add5482a00 (diff) | |
download | gcc-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.h | 31 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 114 | ||||
-rw-r--r-- | gcc/config/s390/vector.md | 42 |
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 |