aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <dje@gnu.org>1995-02-08 20:07:24 +0000
committerDoug Evans <dje@gnu.org>1995-02-08 20:07:24 +0000
commitcd5fb1eea736456e34ad9ac4da23f4b5f7cc8637 (patch)
treee9f55d434d9e5fd066bc47b7745a00e87ecb4fd6
parent5b26b12e46b07208e81d3d1e5ed063b202b75798 (diff)
downloadgcc-cd5fb1eea736456e34ad9ac4da23f4b5f7cc8637.zip
gcc-cd5fb1eea736456e34ad9ac4da23f4b5f7cc8637.tar.gz
gcc-cd5fb1eea736456e34ad9ac4da23f4b5f7cc8637.tar.bz2
sparc.c (v9_regcmp_p): New function.
* sparc/sparc.c (v9_regcmp_p): New function. (v9_regcmp_op): Call it. * sparc/sparc.md (movsicc): New pattern. (movdicc, movsfcc, movdfcc, movtfcc): Likewise. From-SVN: r8895
-rw-r--r--gcc/config/sparc/sparc.c18
-rw-r--r--gcc/config/sparc/sparc.md133
2 files changed, 149 insertions, 2 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 842276e..f93f794 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -187,6 +187,21 @@ sparc64_fpconv_stack_temp ()
return fpconv_stack_temp;
}
+/* Miscellaneous utilities. */
+
+/* Nonzero if CODE, a comparison, is suitable for use in v9 conditional move
+ or branch on register contents instructions. */
+
+int
+v9_regcmp_p (code)
+ enum rtx_code code;
+{
+ return (code == EQ || code == NE || code == GE || code == LT
+ || code == LE || code == GT);
+}
+
+/* Operand constraints. */
+
/* Return non-zero only if OP is a register of mode MODE,
or const0_rtx. */
int
@@ -524,8 +539,7 @@ v9_regcmp_op (op, mode)
if (GET_RTX_CLASS (code) != '<')
return 0;
- return (code == EQ || code == NE || code == GE || code == LT
- || code == LE || code == GT);
+ return v9_regcmp_p (code);
}
/* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 223740a..31f034f 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -2184,6 +2184,139 @@
;; Sparc V9 conditional move instructions.
+;; We can handle larger constants here for some flavors, but for now we play
+;; it safe and only allow those constants supported by all flavours.
+
+(define_expand "movsicc"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:SI 2 "arith10_operand" "")
+ (match_operand:SI 3 "arith10_operand" "")))]
+ "TARGET_V9"
+ "
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+
+ if (sparc_compare_op1 == const0_rtx
+ && GET_CODE (sparc_compare_op0) == REG
+ && GET_MODE (sparc_compare_op0) == DImode
+ && v9_regcmp_p (code))
+ {
+ operands[1] = gen_rtx (code, DImode,
+ sparc_compare_op0, sparc_compare_op1);
+ }
+ else
+ {
+ rtx cc_reg = gen_compare_reg (code,
+ sparc_compare_op0, sparc_compare_op1);
+ operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+ }
+}")
+
+(define_expand "movdicc"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:DI 2 "arith10_operand" "")
+ (match_operand:DI 3 "arith10_operand" "")))]
+ "TARGET_V9"
+ "
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+
+ if (sparc_compare_op1 == const0_rtx
+ && GET_CODE (sparc_compare_op0) == REG
+ && GET_MODE (sparc_compare_op0) == DImode
+ && v9_regcmp_p (code))
+ {
+ operands[1] = gen_rtx (code, DImode,
+ sparc_compare_op0, sparc_compare_op1);
+ }
+ else
+ {
+ rtx cc_reg = gen_compare_reg (code,
+ sparc_compare_op0, sparc_compare_op1);
+ operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+ }
+}")
+
+(define_expand "movsfcc"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:SF 2 "register_operand" "")
+ (match_operand:SF 3 "register_operand" "")))]
+ "TARGET_V9"
+ "
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+
+ if (sparc_compare_op1 == const0_rtx
+ && GET_CODE (sparc_compare_op0) == REG
+ && GET_MODE (sparc_compare_op0) == DImode
+ && v9_regcmp_p (code))
+ {
+ operands[1] = gen_rtx (code, DImode,
+ sparc_compare_op0, sparc_compare_op1);
+ }
+ else
+ {
+ rtx cc_reg = gen_compare_reg (code,
+ sparc_compare_op0, sparc_compare_op1);
+ operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+ }
+}")
+
+(define_expand "movdfcc"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:DF 2 "register_operand" "")
+ (match_operand:DF 3 "register_operand" "")))]
+ "TARGET_V9"
+ "
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+
+ if (sparc_compare_op1 == const0_rtx
+ && GET_CODE (sparc_compare_op0) == REG
+ && GET_MODE (sparc_compare_op0) == DImode
+ && v9_regcmp_p (code))
+ {
+ operands[1] = gen_rtx (code, DImode,
+ sparc_compare_op0, sparc_compare_op1);
+ }
+ else
+ {
+ rtx cc_reg = gen_compare_reg (code,
+ sparc_compare_op0, sparc_compare_op1);
+ operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+ }
+}")
+
+(define_expand "movtfcc"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (if_then_else (match_operand 1 "comparison_operator" "")
+ (match_operand:TF 2 "register_operand" "")
+ (match_operand:TF 3 "register_operand" "")))]
+ "TARGET_V9"
+ "
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+
+ if (sparc_compare_op1 == const0_rtx
+ && GET_CODE (sparc_compare_op0) == REG
+ && GET_MODE (sparc_compare_op0) == DImode
+ && v9_regcmp_p (code))
+ {
+ operands[1] = gen_rtx (code, DImode,
+ sparc_compare_op0, sparc_compare_op1);
+ }
+ else
+ {
+ rtx cc_reg = gen_compare_reg (code,
+ sparc_compare_op0, sparc_compare_op1);
+ operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+ }
+}")
+
; ??? There is not actually a 32 bit version of this instruction.
(define_insn "*movsi_cc_sp64"
[(set (match_operand:SI 0 "register_operand" "=r")