diff options
author | Wolfgang Gellerich <gellerich@de.ibm.com> | 2007-04-18 11:51:06 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel1@de.ibm.com> | 2007-04-18 11:51:06 +0000 |
commit | 91bfe2f3e1d19b22d5f750e80d70578655c323d7 (patch) | |
tree | ba2f886e6343b6e3376a4be454b1121c0bfd4751 | |
parent | 44fee7bd340e695133a30a344450b158eaea5f30 (diff) |
2007-04-18 Wolfgang Gellerich <gellerich@de.ibm.com>
* config/s390/s390.h (S390_TDC_POSITIVE_ZERO): New constant.
(S390_TDC_NEGATIVE_ZERO): New constant.
(S390_TDC_POSITIVE_NORMALIZED_NUMBER): New constant.
(S390_TDC_NEGATIVE_NORMALIZED_NUMBER): New constant.
(S390_TDC_POSITIVE_DENORMALIZED_NUMBER): New constant.
(S390_TDC_NEGATIVE_DENORMALIZED_NUMBER): New constant.
(S390_TDC_POSITIVE_INFINITY): New constant.
(S390_TDC_NEGATIVE_INFINITY): New constant.
(S390_TDC_POSITIVE_QUIET_NAN): New constant.
(S390_TDC_NEGATIVE_QUIET_NAN): New constant.
(S390_TDC_POSITIVE_SIGNALING_NAN): New constant.
(S390_TDC_NEGATIVE_SIGNALING_NAN): New constant.
(S390_TDC_INFINITY): New constant.
* config/s390/s390.c (s390_canonicalize_comparison): Renamed
UNSPEC_CMPINT to UNSPEC_CCU_TO_INT, added a UNSPEC_CCU_TO_INT-like
optimization for UNSPEC_CCZ_TO_INT.
* config/s390/s390.md ("*TDC_insn_<mode>"): New insn.
("*ccz_to_int"): New insn.
("isinf<mode>2"): New insn.
(UNSPEC_CMPINT): Renamed to UNSPEC_CCU_TO_INT.
(UNSPEC_CCU_TO_INT): New constant, replaces UNSPEC_CMPINT.
(UNSPEC_CCZ_TO_INT): New constant.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@123947 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 25 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 29 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 16 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 63 |
4 files changed, 121 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fdde4316d49..b2339bfb7fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2007-04-18 Wolfgang Gellerich <gellerich@de.ibm.com> + + * config/s390/s390.h (S390_TDC_POSITIVE_ZERO): New constant. + (S390_TDC_NEGATIVE_ZERO): New constant. + (S390_TDC_POSITIVE_NORMALIZED_NUMBER): New constant. + (S390_TDC_NEGATIVE_NORMALIZED_NUMBER): New constant. + (S390_TDC_POSITIVE_DENORMALIZED_NUMBER): New constant. + (S390_TDC_NEGATIVE_DENORMALIZED_NUMBER): New constant. + (S390_TDC_POSITIVE_INFINITY): New constant. + (S390_TDC_NEGATIVE_INFINITY): New constant. + (S390_TDC_POSITIVE_QUIET_NAN): New constant. + (S390_TDC_NEGATIVE_QUIET_NAN): New constant. + (S390_TDC_POSITIVE_SIGNALING_NAN): New constant. + (S390_TDC_NEGATIVE_SIGNALING_NAN): New constant. + (S390_TDC_INFINITY): New constant. + * config/s390/s390.c (s390_canonicalize_comparison): Renamed + UNSPEC_CMPINT to UNSPEC_CCU_TO_INT, added a UNSPEC_CCU_TO_INT-like + optimization for UNSPEC_CCZ_TO_INT. + * config/s390/s390.md ("*TDC_insn_<mode>"): New insn. + ("*ccz_to_int"): New insn. + ("isinf<mode>2"): New insn. + (UNSPEC_CMPINT): Renamed to UNSPEC_CCU_TO_INT. + (UNSPEC_CCU_TO_INT): New constant, replaces UNSPEC_CMPINT. + (UNSPEC_CCZ_TO_INT): New constant. + 2007-04-18 Richard Guenther <rguenther@suse.de> PR tree-optimization/19431 diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 1bb9a3cda20..bd88512cc03 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -699,10 +699,9 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1) *op1 = constm1_rtx; } - - /* Remove redundant UNSPEC_CMPINT conversions if possible. */ + /* Remove redundant UNSPEC_CCU_TO_INT conversions if possible. */ if (GET_CODE (*op0) == UNSPEC - && XINT (*op0, 1) == UNSPEC_CMPINT + && XINT (*op0, 1) == UNSPEC_CCU_TO_INT && XVECLEN (*op0, 0) == 1 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode && GET_CODE (XVECEXP (*op0, 0, 0)) == REG @@ -728,6 +727,30 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1) } } + /* Remove redundant UNSPEC_CCZ_TO_INT conversions if possible. */ + if (GET_CODE (*op0) == UNSPEC + && XINT (*op0, 1) == UNSPEC_CCZ_TO_INT + && XVECLEN (*op0, 0) == 1 + && GET_MODE (XVECEXP (*op0, 0, 0)) == CCZmode + && GET_CODE (XVECEXP (*op0, 0, 0)) == REG + && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM + && *op1 == const0_rtx) + { + enum rtx_code new_code = UNKNOWN; + switch (*code) + { + case EQ: new_code = EQ; break; + case NE: new_code = NE; break; + default: break; + } + + if (new_code != UNKNOWN) + { + *op0 = XVECEXP (*op0, 0, 0); + *code = new_code; + } + } + /* Simplify cascaded EQ, NE with const0_rtx. */ if ((*code == NE || *code == EQ) && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE) diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index a495bc75834..8f004a39468 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -146,6 +146,22 @@ extern enum processor_flags s390_arch_flags; /* Frame pointer is not used for debugging. */ #define CAN_DEBUG_WITHOUT_FP +/* 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_NUMBER (1 << 9) +#define S390_TDC_NEGATIVE_NORMALIZED_NUMBER (1 << 8) +#define S390_TDC_POSITIVE_DENORMALIZED_NUMBER (1 << 7) +#define S390_TDC_NEGATIVE_DENORMALIZED_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) + +#define S390_TDC_INFINITY (S390_TDC_POSITIVE_INFINITY \ + | S390_TDC_NEGATIVE_INFINITY ) /* In libgcc2, determine target settings as compile-time constants. */ #ifdef IN_LIBGCC2 diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 949d94e53a1..4acba12674e 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -59,7 +59,8 @@ (define_constants [; Miscellaneous (UNSPEC_ROUND 1) - (UNSPEC_CMPINT 2) + (UNSPEC_CCU_TO_INT 2) + (UNSPEC_CCZ_TO_INT 3) (UNSPEC_ICM 10) ; GOT/PLT and lt-relative accesses @@ -93,13 +94,16 @@ ; String Functions (UNSPEC_SRST 600) (UNSPEC_MVST 601) - + ; Stack Smashing Protector (UNSPEC_SP_SET 700) (UNSPEC_SP_TEST 701) ; Copy sign instructions (UNSPEC_COPYSIGN 800) + + ; Test Data Class (TDC) + (UNSPEC_TDC_INSN 900) ]) ;; @@ -2090,7 +2094,7 @@ (use (reg:SI 0))]) (parallel [(set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CMPINT)) + (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CCU_TO_INT)) (clobber (reg:CC CC_REGNUM))])] "" { @@ -2288,6 +2292,47 @@ [(set_attr "length" "8") (set_attr "type" "vs")]) + +; +; Test data class. +; + +(define_expand "isinf<mode>2" + [(set (reg:CCZ CC_REGNUM) + (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") + (match_dup 2)] + UNSPEC_TDC_INSN)) + (set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" +{ + operands[2] = GEN_INT (S390_TDC_INFINITY); +}) + +; This insn is used to generate all variants of the Test Data Class +; instruction, namely tcxb, tcdb, and tceb. The insn's first operand +; is the register to be tested and the second one is the bit mask +; specifying the required test(s). +; +(define_insn "*TDC_insn_<mode>" + [(set (reg:CCZ CC_REGNUM) + (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f") + (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "tc<xde>b\t%0,%1" + [(set_attr "op_type" "RXE") + (set_attr "type" "fsimp<mode>")]) + +(define_insn_and_split "*ccz_to_int" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:CCZ 1 "register_operand" "0")] + UNSPEC_CCZ_TO_INT))] + "" + "#" + "reload_completed" + [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))]) + + ; ; setmemM instruction pattern(s). ; @@ -2564,7 +2609,7 @@ (define_insn_and_split "cmpint" [(set (match_operand:SI 0 "register_operand" "=d") (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CMPINT)) + UNSPEC_CCU_TO_INT)) (clobber (reg:CC CC_REGNUM))] "" "#" @@ -2577,10 +2622,10 @@ (define_insn_and_split "*cmpint_cc" [(set (reg CC_REGNUM) (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CMPINT) + UNSPEC_CCU_TO_INT) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))] + (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT))] "s390_match_ccmode (insn, CCSmode)" "#" "&& reload_completed" @@ -2597,7 +2642,7 @@ (define_insn_and_split "*cmpint_sign" [(set (match_operand:DI 0 "register_operand" "=d") (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CMPINT))) + UNSPEC_CCU_TO_INT))) (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" "#" @@ -2611,11 +2656,11 @@ [(set (reg CC_REGNUM) (compare (ashiftrt:DI (ashift:DI (subreg:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CMPINT) 0) + UNSPEC_CCU_TO_INT) 0) (const_int 32)) (const_int 32)) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CMPINT)))] + (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT)))] "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT" "#" "&& reload_completed" |