From cd5fb1eea736456e34ad9ac4da23f4b5f7cc8637 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Wed, 8 Feb 1995 20:07:24 +0000 Subject: [PATCH] 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 --- gcc/config/sparc/sparc.c | 18 +++++- gcc/config/sparc/sparc.md | 133 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 2 deletions(-) diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 842276e0b2c..f93f7940474 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 223740a126f..31f034f2532 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") -- 2.30.2