aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Gellerich <gellerich@de.ibm.com>2007-04-18 11:51:06 +0000
committerAndreas Krebbel <krebbel1@de.ibm.com>2007-04-18 11:51:06 +0000
commit91bfe2f3e1d19b22d5f750e80d70578655c323d7 (patch)
treeba2f886e6343b6e3376a4be454b1121c0bfd4751
parent44fee7bd340e695133a30a344450b158eaea5f30 (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/ChangeLog25
-rw-r--r--gcc/config/s390/s390.c29
-rw-r--r--gcc/config/s390/s390.h16
-rw-r--r--gcc/config/s390/s390.md63
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"