diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2009-05-12 09:43:48 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2009-05-12 09:43:48 +0000 |
commit | f90b7a5a7913cc7239cce42f6ca328b9a741b387 (patch) | |
tree | 06c940a96a184a178bfadd53e04213225655a68d /gcc/config/mmix | |
parent | b7a0af68063c79655c561750e9863799bf846cae (diff) | |
download | gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.zip gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.gz gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.bz2 |
Merge cond-optab branch.
From-SVN: r147425
Diffstat (limited to 'gcc/config/mmix')
-rw-r--r-- | gcc/config/mmix/mmix-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/mmix/mmix.c | 62 | ||||
-rw-r--r-- | gcc/config/mmix/mmix.h | 5 | ||||
-rw-r--r-- | gcc/config/mmix/mmix.md | 250 | ||||
-rw-r--r-- | gcc/config/mmix/predicates.md | 5 |
5 files changed, 71 insertions, 252 deletions
diff --git a/gcc/config/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.h index d71064a..d294d8f 100644 --- a/gcc/config/mmix/mmix-protos.h +++ b/gcc/config/mmix/mmix-protos.h @@ -96,7 +96,6 @@ extern void mmix_setup_frame_addresses (void); /* Needs to be ifdef:d for sake of enum rtx_code. */ extern enum machine_mode mmix_select_cc_mode (enum rtx_code, rtx, rtx); extern void mmix_canonicalize_comparison (enum rtx_code *, rtx *, rtx *); -extern int mmix_valid_comparison (enum rtx_code, enum machine_mode, rtx); extern rtx mmix_gen_compare_reg (enum rtx_code, rtx, rtx); #endif diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index ceed8db..6ced05c 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -2359,70 +2359,14 @@ mmix_shiftable_wyde_value (unsigned HOST_WIDEST_INT value) return 1; } -/* Returns zero if code and mode is not a valid condition from a - compare-type insn. Nonzero if it is. The parameter op, if non-NULL, - is the comparison of mode is CC-somethingmode. */ - -int -mmix_valid_comparison (RTX_CODE code, enum machine_mode mode, rtx op) -{ - if (mode == VOIDmode && op != NULL_RTX) - mode = GET_MODE (op); - - /* We don't care to look at these, they should always be valid. */ - if (mode == CCmode || mode == CC_UNSmode || mode == DImode) - return 1; - - if ((mode == CC_FPmode || mode == DFmode) - && (code == GT || code == LT)) - return 1; - - if ((mode == CC_FPEQmode || mode == DFmode) - && (code == EQ || code == NE)) - return 1; - - if ((mode == CC_FUNmode || mode == DFmode) - && (code == ORDERED || code == UNORDERED)) - return 1; - - return 0; -} - -/* X and Y are two things to compare using CODE. Emit a compare insn if - possible and return the rtx for the cc-reg in the proper mode, or - NULL_RTX if this is not a valid comparison. */ +/* X and Y are two things to compare using CODE. Return the rtx for + the cc-reg in the proper mode. */ rtx mmix_gen_compare_reg (RTX_CODE code, rtx x, rtx y) { enum machine_mode ccmode = SELECT_CC_MODE (code, x, y); - rtx cc_reg; - - /* FIXME: Do we get constants here? Of double mode? */ - enum machine_mode mode - = GET_MODE (x) == VOIDmode - ? GET_MODE (y) - : GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT ? DFmode : DImode; - - if (! mmix_valid_comparison (code, mode, x)) - return NULL_RTX; - - cc_reg = gen_reg_rtx (ccmode); - - /* FIXME: Can we avoid emitting a compare insn here? */ - if (! REG_P (x) && ! REG_P (y)) - x = force_reg (mode, x); - - /* If it's not quite right yet, put y in a register. */ - if (! REG_P (y) - && (GET_CODE (y) != CONST_INT - || ! CONST_OK_FOR_LETTER_P (INTVAL (y), 'I'))) - y = force_reg (mode, y); - - emit_insn (gen_rtx_SET (VOIDmode, cc_reg, - gen_rtx_COMPARE (ccmode, x, y))); - - return cc_reg; + return gen_reg_rtx (ccmode); } /* Local (static) helper functions. */ diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h index a7fb6e5..5a0582d 100644 --- a/gcc/config/mmix/mmix.h +++ b/gcc/config/mmix/mmix.h @@ -81,11 +81,6 @@ along with GCC; see the file COPYING3. If not see #define MMIX_FUNCTION_ARG_SIZE(MODE, TYPE) \ ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE)) -/* Declarations for helper variables that are not tied to a particular - target macro. */ -extern GTY(()) rtx mmix_compare_op0; -extern GTY(()) rtx mmix_compare_op1; - /* Per-function machine data. This is normally an opaque type just defined and used in the tm.c file, but we need to see the definition in mmix.md too. */ diff --git a/gcc/config/mmix/mmix.md b/gcc/config/mmix/mmix.md index aa878af..44263e47 100644 --- a/gcc/config/mmix/mmix.md +++ b/gcc/config/mmix/mmix.md @@ -440,30 +440,6 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") "" "NOR %0,%1,0") -;; Since we don't have cc0, we do what is recommended in the manual; -;; store away the operands for use in the branch, scc or movcc insn. -(define_expand "cmpdi" - [(match_operand:DI 0 "register_operand" "") - (match_operand:DI 1 "mmix_reg_or_8bit_operand" "")] - "" - " -{ - mmix_compare_op0 = operands[0]; - mmix_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpdf" - [(match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "register_operand" "")] - "" - " -{ - mmix_compare_op0 = operands[0]; - mmix_compare_op1 = operands[1]; - DONE; -}") - ;; When the user-patterns expand, the resulting insns will match the ;; patterns below. @@ -474,7 +450,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") ;; unsigned, so that has to be done another way. ;; FIXME: Perhaps a peep2 changing CCcode to a new code, that ;; gets folded here. -(define_insn "*cmpcc_folded" +(define_insn "*cmpdi_folded" [(set (match_operand:CC 0 "register_operand" "=r") (compare:CC (match_operand:DI 1 "register_operand" "r") @@ -485,7 +461,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") && REGNO (operands[1]) == REGNO (operands[0])" "%% folded: cmp %0,%1,0") -(define_insn "*cmpcc" +(define_insn "*cmps" [(set (match_operand:CC 0 "register_operand" "=r") (compare:CC (match_operand:DI 1 "register_operand" "r") @@ -724,7 +700,8 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") ;; 0 to use in movdfcc. (define_expand "movdfcc" - [(set (match_operand:DF 0 "register_operand" "") + [(set (match_dup 4) (match_dup 5)) + (set (match_operand:DF 0 "register_operand" "") (if_then_else:DF (match_operand 1 "comparison_operator" "") (match_operand:DF 2 "mmix_reg_or_0_operand" "") @@ -733,15 +710,20 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") " { enum rtx_code code = GET_CODE (operands[1]); - rtx cc_reg = mmix_gen_compare_reg (code, mmix_compare_op0, - mmix_compare_op1); - if (cc_reg == NULL_RTX) + if (code == LE || code == GE) FAIL; - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx); + + operands[4] = mmix_gen_compare_reg (code, XEXP (operands[1], 0), + XEXP (operands[1], 1)); + operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), + XEXP (operands[1], 0), + XEXP (operands[1], 1)); + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx); }") (define_expand "movdicc" - [(set (match_operand:DI 0 "register_operand" "") + [(set (match_dup 4) (match_dup 5)) + (set (match_operand:DI 0 "register_operand" "") (if_then_else:DI (match_operand 1 "comparison_operator" "") (match_operand:DI 2 "mmix_reg_or_8bit_operand" "") @@ -750,11 +732,15 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") " { enum rtx_code code = GET_CODE (operands[1]); - rtx cc_reg = mmix_gen_compare_reg (code, mmix_compare_op0, - mmix_compare_op1); - if (cc_reg == NULL_RTX) + if (code == LE || code == GE) FAIL; - operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx); + + operands[4] = mmix_gen_compare_reg (code, XEXP (operands[1], 0), + XEXP (operands[1], 1)); + operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), + XEXP (operands[1], 0), + XEXP (operands[1], 1)); + operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx); }") ;; FIXME: Is this the right way to do "folding" of CCmode -> DImode? @@ -854,175 +840,65 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") CS%d2 %0,%3,%1 ZS%d2 %0,%3,%1") -;; FIXME: scc patterns will probably help, I just skip them +;; FIXME: scc insns will probably help, I just skip them ;; right now. Revisit. -(define_expand "beq" - [(set (pc) - (if_then_else (eq (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (EQ, mmix_compare_op0, mmix_compare_op1); -}") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] +(define_expand "cbranchdi4" + [(set (match_dup 4) + (match_op_dup 5 + [(match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "mmix_reg_or_8bit_operand" "")])) + (set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" + [(match_dup 4) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] "" " { - operands[1] - = mmix_gen_compare_reg (NE, mmix_compare_op0, mmix_compare_op1); + operands[4] = mmix_gen_compare_reg (GET_CODE (operands[0]), + operands[1], operands[2]); + operands[5] = gen_rtx_fmt_ee (COMPARE, + GET_MODE (operands[4]), + operands[1], operands[2]); }") -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] +(define_expand "cbranchdf4" + [(set (match_dup 4) + (match_op_dup 5 + [(match_operand:DF 1 "register_operand" "") + (match_operand:DF 2 "register_operand" "")])) + (set (pc) + (if_then_else + (match_operator 0 "float_comparison_operator" + [(match_dup 4) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] "" " { - operands[1] - = mmix_gen_compare_reg (GT, mmix_compare_op0, mmix_compare_op1); -}") - -(define_expand "ble" - [(set (pc) - (if_then_else (le (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (LE, mmix_compare_op0, mmix_compare_op1); - /* The head comment of optabs.c:can_compare_p says we're required to implement this, so we have to clean up the mess here. */ - if (operands[1] == NULL_RTX) + if (GET_CODE (operands[0]) == LE || GET_CODE (operands[0]) == GE) { - /* FIXME: Watch out for sharing/unsharing of rtx:es. */ - emit_jump_insn ((*bcc_gen_fctn[(int) LT]) (operands[0])); - emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (operands[0])); + enum rtx_code ltgt_code = GET_CODE (operands[0]) == LE ? LT : GT; + emit_cmp_and_jump_insns (operands[1], operands[2], ltgt_code, NULL_RTX, + DFmode, 0, operands[3]); + emit_cmp_and_jump_insns (operands[1], operands[2], EQ, NULL_RTX, + DFmode, 0, operands[3]); DONE; } -}") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (GE, mmix_compare_op0, mmix_compare_op1); - /* The head comment of optabs.c:can_compare_p says we're required to - implement this, so we have to clean up the mess here. */ - if (operands[1] == NULL_RTX) - { - /* FIXME: Watch out for sharing/unsharing of rtx:es. */ - emit_jump_insn ((*bcc_gen_fctn[(int) GT]) (operands[0])); - emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (operands[0])); - DONE; - } + operands[4] = mmix_gen_compare_reg (GET_CODE (operands[0]), + operands[1], operands[2]); + operands[5] = gen_rtx_fmt_ee (COMPARE, + GET_MODE (operands[4]), + operands[1], operands[2]); }") -(define_expand "blt" - [(set (pc) - (if_then_else (lt (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (LT, mmix_compare_op0, mmix_compare_op1); -}") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (GTU, mmix_compare_op0, mmix_compare_op1); -}") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (LEU, mmix_compare_op0, mmix_compare_op1); -}") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (GEU, mmix_compare_op0, mmix_compare_op1); -}") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (LTU, mmix_compare_op0, mmix_compare_op1); -}") - -(define_expand "bunordered" - [(set (pc) - (if_then_else (unordered (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (UNORDERED, mmix_compare_op0, mmix_compare_op1); - - if (operands[1] == NULL_RTX) - FAIL; -}") - -(define_expand "bordered" - [(set (pc) - (if_then_else (ordered (match_dup 1) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] - = mmix_gen_compare_reg (ORDERED, mmix_compare_op0, mmix_compare_op1); -}") ;; FIXME: we can emit an unordered-or-*not*-equal compare in one insn, but ;; there's no RTL code for it. Maybe revisit in future. diff --git a/gcc/config/mmix/predicates.md b/gcc/config/mmix/predicates.md index 5c5792e..b5773b8 100644 --- a/gcc/config/mmix/predicates.md +++ b/gcc/config/mmix/predicates.md @@ -17,6 +17,11 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +;; Return 1 if OP is a valid comparison operator for "cbranch" instructions. +;; LE and GE are further lowered by the cbranchdf4 pattern. +(define_predicate "float_comparison_operator" + (match_code "ne, eq, le, ge, lt, gt, ordered, unordered")) + ;; True if this is a foldable comparison operator ;; - one where a the result of (compare:CC (reg) (const_int 0)) can be ;; replaced by (reg). */ |