aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2003-10-14 22:55:36 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2003-10-14 22:55:36 +0000
commite69166de8e13bd1ec9c30d1871d03cb4b3616f1d (patch)
tree23b9501ea321a423f08d0d2971a3f6a84cc84f74
parent7903cebc8d5da0ff4b9b21942e44563e400290b5 (diff)
downloadgcc-e69166de8e13bd1ec9c30d1871d03cb4b3616f1d.zip
gcc-e69166de8e13bd1ec9c30d1871d03cb4b3616f1d.tar.gz
gcc-e69166de8e13bd1ec9c30d1871d03cb4b3616f1d.tar.bz2
s390-protos.h (s390_alc_comparison): Add prototype.
* config/s390/s390-protos.h (s390_alc_comparison): Add prototype. (s390_slb_comparison): Likewise. * config/s390/s390.c (s390_alc_comparison, s390_slb_comparison): New functions. * config/s390/s390.h (PREDICATE_CODES): Add s390_alc_comparison and s390_slb_comparison. * config/s390/s390.md ("*adddi3_31", "*subdi3_31"): Do not use on zSeries machines. ("*adddi3_31z", "*subdi3_31z"): New insns. ("*adddi3_alc_cc", "*adddi3_alc", "*subdi3_slb_cc", "*subdi3_slb", "*addsi3_alc_cc", "*addsi3_alc", "*subsi3_slb_cc", "*subsi3_slb"): New insns. From-SVN: r72505
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/s390/s390-protos.h2
-rw-r--r--gcc/config/s390/s390.c84
-rw-r--r--gcc/config/s390/s390.h4
-rw-r--r--gcc/config/s390/s390.md175
5 files changed, 277 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8e7e28c..7302097 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2003-10-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_alc_comparison): Add prototype.
+ (s390_slb_comparison): Likewise.
+ * config/s390/s390.c (s390_alc_comparison, s390_slb_comparison):
+ New functions.
+ * config/s390/s390.h (PREDICATE_CODES): Add s390_alc_comparison
+ and s390_slb_comparison.
+ * config/s390/s390.md ("*adddi3_31", "*subdi3_31"): Do not use on
+ zSeries machines.
+ ("*adddi3_31z", "*subdi3_31z"): New insns.
+ ("*adddi3_alc_cc", "*adddi3_alc", "*subdi3_slb_cc", "*subdi3_slb",
+ "*addsi3_alc_cc", "*addsi3_alc", "*subsi3_slb_cc", "*subsi3_slb"):
+ New insns.
+
2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
* configure.in: Clean up some feedback echoes.
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 40026d3..76ceccd 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -49,6 +49,8 @@ extern int tls_symbolic_operand (rtx);
extern int s390_match_ccmode (rtx, enum machine_mode);
extern enum machine_mode s390_tm_ccmode (rtx, rtx, int);
extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx);
+extern int s390_alc_comparison (rtx op, enum machine_mode mode);
+extern int s390_slb_comparison (rtx op, enum machine_mode mode);
extern int symbolic_reference_mentioned_p (rtx);
extern int tls_symbolic_reference_mentioned_p (rtx);
extern rtx s390_tls_get_offset (void);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index cf68a52..6d56b02 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -447,6 +447,90 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
}
}
+/* Return nonzero if OP is a valid comparison operator
+ for an ALC condition in mode MODE. */
+
+int
+s390_alc_comparison (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+ return 0;
+
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != CC_REGNUM
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ switch (GET_MODE (XEXP (op, 0)))
+ {
+ case CCL1mode:
+ return GET_CODE (op) == LTU;
+
+ case CCL2mode:
+ return GET_CODE (op) == LEU;
+
+ case CCUmode:
+ return GET_CODE (op) == GTU;
+
+ case CCURmode:
+ return GET_CODE (op) == LTU;
+
+ case CCSmode:
+ return GET_CODE (op) == UNGT;
+
+ case CCSRmode:
+ return GET_CODE (op) == UNLT;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return nonzero if OP is a valid comparison operator
+ for an SLB condition in mode MODE. */
+
+int
+s390_slb_comparison (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+ return 0;
+
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != CC_REGNUM
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ switch (GET_MODE (XEXP (op, 0)))
+ {
+ case CCL1mode:
+ return GET_CODE (op) == GEU;
+
+ case CCL2mode:
+ return GET_CODE (op) == GTU;
+
+ case CCUmode:
+ return GET_CODE (op) == LEU;
+
+ case CCURmode:
+ return GET_CODE (op) == GEU;
+
+ case CCSmode:
+ return GET_CODE (op) == LE;
+
+ case CCSRmode:
+ return GET_CODE (op) == GE;
+
+ default:
+ return 0;
+ }
+}
+
/* Return branch condition mask to implement a branch
specified by CODE. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 0a60550..1c3241c 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -1030,7 +1030,9 @@ do { \
{"const0_operand", { CONST_INT, CONST_DOUBLE }}, \
{"consttable_operand", { SYMBOL_REF, LABEL_REF, CONST, \
CONST_INT, CONST_DOUBLE }}, \
- {"s390_plus_operand", { PLUS }},
+ {"s390_plus_operand", { PLUS }}, \
+ {"s390_alc_comparison", { LTU, GTU, LEU, GEU }}, \
+ {"s390_slb_comparison", { LTU, GTU, LEU, GEU }},
/* Specify the machine mode that this machine uses for the index in the
tablejump instruction. */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 9cdce81..5f49e6a 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3254,12 +3254,37 @@
ag\t%0,%2"
[(set_attr "op_type" "RRE,RI,RXY")])
+(define_insn_and_split "*adddi3_31z"
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
+ (match_operand:DI 2 "general_operand" "do") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCL1 33)
+ (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
+ (match_dup 7)))
+ (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
+ (parallel
+ [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
+ (ltu:SI (reg:CCL1 33) (const_int 0))))
+ (clobber (reg:CC 33))])]
+ "operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[2], 0, 0, DImode);
+ operands[6] = operand_subword (operands[0], 1, 0, DImode);
+ operands[7] = operand_subword (operands[1], 1, 0, DImode);
+ operands[8] = operand_subword (operands[2], 1, 0, DImode);"
+ [(set_attr "op_type" "NN")])
+
(define_insn_and_split "*adddi3_31"
[(set (match_operand:DI 0 "register_operand" "=&d")
(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
(match_operand:DI 2 "general_operand" "do") ) )
(clobber (reg:CC 33))]
- "!TARGET_64BIT"
+ "!TARGET_CPU_ZARCH"
"#"
"&& reload_completed"
[(parallel
@@ -3804,12 +3829,37 @@
sg\t%0,%2"
[(set_attr "op_type" "RRE,RRE")])
+(define_insn_and_split "*subdi3_31z"
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (minus:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:DI 2 "general_operand" "do") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCL2 33)
+ (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
+ (match_dup 7)))
+ (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
+ (parallel
+ [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
+ (gtu:SI (reg:CCL2 33) (const_int 0))))
+ (clobber (reg:CC 33))])]
+ "operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[2], 0, 0, DImode);
+ operands[6] = operand_subword (operands[0], 1, 0, DImode);
+ operands[7] = operand_subword (operands[1], 1, 0, DImode);
+ operands[8] = operand_subword (operands[2], 1, 0, DImode);"
+ [(set_attr "op_type" "NN")])
+
(define_insn_and_split "*subdi3_31"
[(set (match_operand:DI 0 "register_operand" "=&d")
(minus:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "general_operand" "do") ) )
(clobber (reg:CC 33))]
- "!TARGET_64BIT"
+ "!TARGET_CPU_ZARCH"
"#"
"&& reload_completed"
[(parallel
@@ -4058,6 +4108,127 @@
;;
+;;- Conditional add/subtract instructions.
+;;
+
+;
+; adddicc instruction pattern(s).
+;
+
+(define_insn "*adddi3_alc_cc"
+ [(set (reg 33)
+ (compare
+ (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_alc_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (plus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "@
+ alcgr\\t%0,%2
+ alcg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_alc"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_alc_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ alcgr\\t%0,%2
+ alcg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_slb_cc"
+ [(set (reg 33)
+ (compare
+ (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_slb_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (minus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "@
+ slbgr\\t%0,%2
+ slbg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_slb"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_slb_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ slbgr\\t%0,%2
+ slbg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+;
+; addsicc instruction pattern(s).
+;
+
+(define_insn "*addsi3_alc_cc"
+ [(set (reg 33)
+ (compare
+ (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_alc_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "@
+ alcr\\t%0,%2
+ alc\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*addsi3_alc"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_alc_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
+ "@
+ alcr\\t%0,%2
+ alc\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subsi3_slb_cc"
+ [(set (reg 33)
+ (compare
+ (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_slb_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "@
+ slbr\\t%0,%2
+ slb\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subsi3_slb"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_slb_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
+ "@
+ slbr\\t%0,%2
+ slb\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+
+;;
;;- Multiply instructions.
;;