From: Hans-Peter Nilsson Date: Mon, 10 Feb 2020 22:55:32 +0000 (+0100) Subject: cris: Introduce CC_NZVCmode and CC_NZmode. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b3e01c3d1b61ecc903b577920ca43804a2cb5497;p=gcc.git cris: Introduce CC_NZVCmode and CC_NZmode. This is just the framework bits of splitting CCmode into classes where the cc-setter can merge mode (CCmode), classes where the cc-setter must set V and C "usefully" (as well as N and Z flags) and classes where the cc-setter is something like an arithmetic instruction, where N and Z are valid but C and V reflect the operation rather than a compare of the result with zero. This should yield identical or near-identical code. The old split of conditions into the ncond and ocond sets took into account the transformations done by final.c:alter_cond from cc_status.flags & CC_NO_OVERFLOW, and wasn't a reflection of the hardware description of the conditions (i.e. whether V mattered or not). gcc: Prepare for cmpelim pass to eliminate redundant compare insns. * config/cris/cris-modes.def: New file. * config/cris/cris-protos.h (cris_select_cc_mode): Declare. (cris_notice_update_cc): Remove left-over declaration. * config/cris/cris.c (TARGET_CC_MODES_COMPATIBLE): Define. (cris_select_cc_mode, cris_cc_modes_compatible): New functions. * config/cris/cris.h (SELECT_CC_MODE): Define. * config/cris/cris.md (NZSET, NZUSE, NZVCSET, NZVCUSE): New mode_iterators. (cond): New code_iterator. (nzcond): Replacement for incorrect ncond. All callers changed. (nzvccond): Replacement for ocond. All callers changed. (rnzcond): Replacement for rcond. All callers changed. (xCC): New code_attr. (cmp_op1c, cmp_op0c): Renumber from cmp_op1c and cmp_op2c. All users changed. ("*cmpdi"): Rename from "*cmpdi". Replace CCmode with iteration over NZVCSET. ("*cmp_ext"): Similarly; rename from "*cmp_ext". ("*cmpsi"): Similarly, from "*cmpsi". ("*cmp"): Similarly from "*cmp". ("*btst"): Similarly, from "*btst". ("*cbranch4"): Rename from "*cbranch4", iterating over cond instead of matching the comparison with ordered_comparison_operator. ("*cbranch4_btstq"): Correct label operand number. ("b"): Rename from "b", iterating over NZUSE. ("b"): Similarly from "b", over NZVCUSE. Remove FIXME. ("*b_reversed"): Similarly from "*b_reversed", over NZUSE. ("*b_reversed"): Similarly from "*b_reversed", over NZVCUSE. Remove FIXME. ("b"): Similarly from "b", over NZUSE. Reinstate "b" vs. "b" mnemonic choice, depending on CC_NZmode vs. CCmode. Remove FIXME. ("*b_reversed"): Similarly from "*b_reversed", over NZUSE. ("*cstore4"): Rename from "*cstore4", iterating over cond instead of matching the comparison with ordered_comparison_operator. ("*s"): Rename from "*s", iterating over NZUSE. ("*s"): Similar from "*s", over NZUSE. Reinstate "b" vs. "b" mnemonic choice, depending on CC_NZmode vs. CCmode. ("*s"): Simlar from "*s", over NZVCUSE. Remove FIXME. --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b6f7d46adeb..31241541b67 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -52,6 +52,57 @@ ("*mov_fromzero_split"): New split. ("*mov_fromzero"): New insn. + Prepare for cmpelim pass to eliminate redundant compare insns. + * config/cris/cris-modes.def: New file. + * config/cris/cris-protos.h (cris_select_cc_mode): Declare. + (cris_notice_update_cc): Remove left-over declaration. + * config/cris/cris.c (TARGET_CC_MODES_COMPATIBLE): Define. + (cris_select_cc_mode, cris_cc_modes_compatible): New functions. + * config/cris/cris.h (SELECT_CC_MODE): Define. + * config/cris/cris.md (NZSET, NZUSE, NZVCSET, NZVCUSE): New + mode_iterators. + (cond): New code_iterator. + (nzcond): Replacement for incorrect ncond. All callers changed. + (nzvccond): Replacement for ocond. All callers changed. + (rnzcond): Replacement for rcond. All callers changed. + (xCC): New code_attr. + (cmp_op1c, cmp_op0c): Renumber from cmp_op1c and cmp_op2c. All + users changed. + ("*cmpdi"): Rename from "*cmpdi". Replace + CCmode with iteration over NZVCSET. + ("*cmp_ext"): Similarly; rename from + "*cmp_ext". + ("*cmpsi"): Similarly, from "*cmpsi". + ("*cmp"): Similarly from "*cmp". + ("*btst"): Similarly, from "*btst". + ("*cbranch4"): Rename from "*cbranch4", + iterating over cond instead of matching the comparison with + ordered_comparison_operator. + ("*cbranch4_btstq"): Correct label operand number. + ("b"): Rename from "b", iterating + over NZUSE. + ("b"): Similarly from "b", over + NZVCUSE. Remove FIXME. + ("*b_reversed"): Similarly from + "*b_reversed", over NZUSE. + ("*b_reversed"): Similarly from + "*b_reversed", over NZVCUSE. Remove FIXME. + ("b"): Similarly from "b", + over NZUSE. Reinstate "b" vs. "b" mnemonic choice, + depending on CC_NZmode vs. CCmode. Remove FIXME. + ("*b_reversed"): Similarly from + "*b_reversed", over NZUSE. + ("*cstore4"): Rename from "*cstore4", + iterating over cond instead of matching the comparison with + ordered_comparison_operator. + ("*s"): Rename from "*s", + iterating over NZUSE. + ("*s"): Similar from "*s", over + NZUSE. Reinstate "b" vs. "b" mnemonic choice, + depending on CC_NZmode vs. CCmode. + ("*s"): Simlar from "*s", over + NZVCUSE. Remove FIXME. + 2020-05-08 Vladimir Makarov * ira-color.c (update_costs_from_allocno): Remove diff --git a/gcc/config/cris/cris-modes.def b/gcc/config/cris/cris-modes.def new file mode 100644 index 00000000000..1e72b539caf --- /dev/null +++ b/gcc/config/cris/cris-modes.def @@ -0,0 +1,54 @@ +/* Definitions of target machine for GNU compiler, for CRIS. + Copyright (C) 2002-2020 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Node: Condition Code */ + +/* The mode used for condition-codes depends on both the way the + condition-codes are generated (the CC-setter, typically the compare + instruction), and used (the CC-user, typically a branch). For CRIS, we + have ordinary compares and incidental condition-code settings from + preceding instructions, setting a subset of N, Z, V and C to usable + values, from the perspective of comparing the result against zero + (fpcraz). The two subsets meaningful to gcc are all of N, Z, V, C + versus just N, Z; some CC-users care only about N and/or Z and some + that care about at least one of those flags together with V and/or C. + (FIXME: the result of testing a single bit using the btst instruction + should be described as a separate mode.) + + The plain "CC_MODE (CC)" (which is always present in gcc), is used to + reflect the "unoptimized" state, where the CC-setter is a compare + against zero and the CC-user is any branch or s instruction, + before reload. After reload, a need for C or V is reflected as + CC_NZVCmode in both setters and users, and others remain CCmode, until + or if optimization of CC-setter and CC-users, when CCmode setters can + be changed or replaced by either CC_NZmode or CC_NZVCmode. To wit, all + users that require CC_NZVCmode must match only that mode at any time. + All other users must match all CCmodes. All setters that set only + CC_NZmode must set only that mode. All other setters must match + setting all CCmodes. */ + +/* Z and N flags only. For a condition-code setter: only the Z and N + flags are set to usable values, fpcraz. For a condition-code user: the + operation using the condition codes only care about the Z and N flags. */ +CC_MODE (CC_NZ); + +/* Z and N *and* V and C flags. For a condition-code setter: all flags + are set to usable values, fpcraz. For a condition-code user: at least + one of V and C are used and possibly N and Z too. */ +CC_MODE (CC_NZVC); diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h index 4d8e76f6e39..2db1ea1b8bc 100644 --- a/gcc/config/cris/cris-protos.h +++ b/gcc/config/cris/cris-protos.h @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see extern bool cris_simple_epilogue (void); #ifdef RTX_CODE extern const char *cris_op_str (rtx); -extern void cris_notice_update_cc (rtx, rtx_insn *); +extern machine_mode cris_select_cc_mode (enum rtx_code, rtx, rtx); extern bool cris_reload_address_legitimized (rtx, machine_mode, int, int, int); extern int cris_side_effect_mode_ok (enum rtx_code, rtx *, int, int, int, int, int); diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index eecda83845c..04c80c314a3 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -133,6 +133,7 @@ static reg_class_t cris_preferred_reload_class (rtx, reg_class_t); static int cris_register_move_cost (machine_mode, reg_class_t, reg_class_t); static int cris_memory_move_cost (machine_mode, reg_class_t, bool); +static machine_mode cris_cc_modes_compatible (machine_mode, machine_mode); static bool cris_rtx_costs (rtx, machine_mode, int, int, int *, bool); static int cris_address_cost (rtx, machine_mode, addr_space_t, bool); static bool cris_pass_by_reference (cumulative_args_t, @@ -226,6 +227,9 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; nothing. Beware of changes to its usage; it may make sense to enable "later". */ +#undef TARGET_CC_MODES_COMPATIBLE +#define TARGET_CC_MODES_COMPATIBLE cris_cc_modes_compatible + #undef TARGET_FLAGS_REGNUM #define TARGET_FLAGS_REGNUM CRIS_CC0_REGNUM @@ -1509,6 +1513,73 @@ cris_memory_move_cost (machine_mode mode, return 6; } +/* Worker function for SELECT_CC_MODE. */ + +machine_mode +cris_select_cc_mode (enum rtx_code op, rtx x, rtx y) +{ + /* We have different sets of patterns before and after + reload_completed, and everything before reload_completed is CCmode. + At the time of this writing, this function isn't called before that + time, so let's just gcc_assert on that assumption rather than doing + "if (!reload_completed) return CCmode;". */ + gcc_assert (reload_completed); + + /* For float mode or comparisons with something other than 0, we + always go with CCmode. */ + if (GET_MODE_CLASS (GET_MODE (x)) != MODE_INT || y != const0_rtx) + return CCmode; + + /* If we have a comparison that doesn't have to look at V or C, check + operand x; if it looks like a binary operator, return CC_NZmode, + else CCmode, so we only use CC_NZmode for the cases where we don't + actually have both V and C valid. */ + if (op == EQ || op == NE || op == GTU || op == LEU + || op == LT || op == GE) + { + enum rtx_code e = GET_CODE (x); + + /* Mentioning the rtx_code here is required but not sufficient: the + insn also needs to be decorated with (and the + anonymization prefix for a named pattern). */ + return e == PLUS || e == MINUS || e == MULT || e == NOT + ? CC_NZmode : CCmode; + } + + /* We should only get here for comparison operators. */ + gcc_assert (op == GEU || op == LTU || op == GT || op == LE); + + return CC_NZVCmode; +} + +/* Worker function for TARGET_CC_MODES_COMPATIBLE. + We start with CCmode for most comparisons, which merges and yields to + CC_NZmode or CC_NZVCmode. The exceptions have CC_NZVCmode and can't do with + another mode. */ + +static machine_mode +cris_cc_modes_compatible (machine_mode m1, machine_mode m2) +{ + if (m1 == CC_NZVCmode) + { + if (m2 == CC_NZVCmode || m2 == CCmode) + return CC_NZVCmode; + return VOIDmode; + } + + if (m2 == CC_NZVCmode) + { + if (m1 == CC_NZVCmode || m1 == CCmode) + return CC_NZVCmode; + return VOIDmode; + } + + if (m1 != m2) + return CC_NZmode; + + return m1; +} + /* Return != 0 if the return sequence for the current function is short, like "ret" or "jump [sp+]". Prior to reloading, we can't tell if registers must be saved, so return 0 then. */ diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index bc07dd5418d..2a938fe2026 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -699,7 +699,9 @@ struct cum_args {int regs;}; /* Node: Condition Code */ /* FIXME: Maybe define TARGET_CANONICALIZE_COMPARISON later, when - playing with optimizations. Definitely define SELECT_CC_MODE. */ + playing with optimizations. */ + +#define SELECT_CC_MODE(op, x, y) cris_select_cc_mode(op, x, y) #define REVERSIBLE_CC_MODE(MODE) true diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index bf2cf966387..362d63f6dc5 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -179,16 +179,51 @@ (define_code_attr shlr [(ashiftrt "ashr") (lshiftrt "lshr") (ashift "ashl")]) (define_code_attr slr [(ashiftrt "asr") (lshiftrt "lsr") (ashift "lsl")]) +;; Compares, branches, cbranch, cstore. Conditions gt and le are CC_NZVC. +;; Others start out as CCmode and can degenerate to CC_NZmode. +;; Incidental setters are either CC_NZVCmode or CC_NZmode. See also +;; cris-modes.def. +(define_mode_iterator NZSET [CC_NZ]) +(define_mode_iterator NZUSE [CC CC_NZ CC_NZVC]) +(define_mode_iterator NZVCSET [CC CC_NZVC CC_NZ]) +(define_mode_iterator NZVCUSE [CC_NZVC]) + +;; All conditions. +(define_code_iterator cond [eq ne gtu ltu geu leu gt le lt ge]) + +;; Just equal and not equal. (define_code_iterator zcond [eq ne]) -(define_code_iterator ncond [eq ne gtu ltu geu leu]) -(define_code_iterator ocond [gt le]) -(define_code_iterator rcond [lt ge]) + +;; Conditions that look only at Z and/or N (or can do with that). +(define_code_iterator nzcond [eq ne gtu leu lt ge]) + +;; The complement of nzcond within cond; conditions that look (also) on V +;; or C. +(define_code_iterator nzvccond [geu ltu gt le]) + +;; Within nzcond, those that give different opcodes when operands are +;; reversed or that can ignore V or C. Also, the complement of zcond +;; within nzcond. +(define_code_iterator rnzcond [gtu leu lt ge]) + +;; CRIS condition mnemonic. (define_code_attr CC [(eq "eq") (ne "ne") (gt "gt") (gtu "hi") (lt "lt") (ltu "lo") (ge "ge") (geu "hs") (le "le") (leu "ls")]) + +;; CRIS reverse condition mnemonic. (define_code_attr rCC [(eq "ne") (ne "eq") (gt "le") (gtu "ls") (lt "ge") (ltu "hs") (ge "lt") (geu "lo") (le "gt") (leu "hi")]) -(define_code_attr oCC [(lt "mi") (ge "pl")]) -(define_code_attr roCC [(lt "pl") (ge "mi")]) + +;; Mnemomic for the CRIS condition when V or C can be ignored. +(define_code_attr oCC [(lt "mi") (ge "pl") (gtu "eq") (ltu "ne")]) + +;; Reverse of oCC. +(define_code_attr roCC [(lt "pl") (ge "mi") (gtu "eq") (ltu "ne")]) + +;; Required unoptimized CCmode, different for nzcond and nzvccond. +(define_code_attr xCC [(eq "CC") (ne "CC") (gtu "CC") (ltu "CC_NZVC") + (geu "CC_NZVC") (leu "CC") (lt "CC") (ge "CC") + (gt "CC_NZVC") (le "CC_NZVC")]) ;; Operand and operator predicates. @@ -209,9 +244,9 @@ ;; (It shouldn't be; it should be done as part of register allocation.) (define_mode_attr sCC_destc [(DI "r, r,r,r,r,r,r") (SI "r,r, r, r,r,r") (HI "r, r, r,r") (QI "r, r, r,r")]) -(define_mode_attr cmp_op1c +(define_mode_attr cmp_op0c [(DI "rm,r,r,r,r,r,r") (SI "r,r, rQ>,r,r,m") (HI "r, rQ>,r,m") (QI "r, rQ>,r,m")]) -(define_mode_attr cmp_op2c +(define_mode_attr cmp_op1c [(DI "M,Kc,I,P,n,r,o") (SI "I,rQ>,M, P,g,M") (HI "rQ>,M, g,M") (QI "rQ>,M, g,M")]) ;; We could optimize the sizes of the immediate operands for various @@ -219,10 +254,11 @@ ;; DImode for anything else but a structure/block-mode. Just do the ;; obvious stuff for the straight-forward constraint letters. -(define_insn "*cmpdi" - [(set (reg:CC CRIS_CC0_REGNUM) - (compare:CC (match_operand:DI_ 0 "nonimmediate_operand" "") - (match_operand:DI_ 1 "general_operand" "")))] +(define_insn "*cmpdi" + [(set (reg:NZVCSET CRIS_CC0_REGNUM) + (compare:NZVCSET + (match_operand:DI_ 0 "nonimmediate_operand" "") + (match_operand:DI_ 1 "general_operand" "")))] "reload_completed" "@ test.d %M0\;ax\;test.d %H0 @@ -252,9 +288,9 @@ ;; constants, but sometimes gcc will find its way to use it for other ;; (memory) operands. Avoid side-effect patterns, though (see above). -(define_insn "*cmp_ext" - [(set (reg:CC CRIS_CC0_REGNUM) - (compare:CC +(define_insn "*cmp_ext" + [(set (reg:NZVCSET CRIS_CC0_REGNUM) + (compare:NZVCSET (match_operand:SI 0 "register_operand" "r,r") (match_operator:SI 2 "cris_extend_operator" [(match_operand:BW 1 "memory_operand" "Q>,m")])))] @@ -265,11 +301,11 @@ ;; The "normal" compare patterns, from SI on. Special-cases with zero ;; are covered above. -(define_insn "*cmpsi" - [(set (reg:CC CRIS_CC0_REGNUM) - (compare:CC - (match_operand:SI_ 0 "nonimmediate_operand" "") - (match_operand:SI_ 1 "general_operand" "")))] +(define_insn "*cmpsi" + [(set (reg:NZVCSET CRIS_CC0_REGNUM) + (compare:NZVCSET + (match_operand:SI_ 0 "nonimmediate_operand" "") + (match_operand:SI_ 1 "general_operand" "")))] "reload_completed" "@ cmpq %1,%0 @@ -280,10 +316,11 @@ test.d %0" [(set_attr "slottable" "yes,yes,yes,no,no,no")]) -(define_insn "*cmp" - [(set (reg:CC CRIS_CC0_REGNUM) - (compare:CC (match_operand:BW 0 "nonimmediate_operand" "") - (match_operand:BW 1 "general_operand" "")))] +(define_insn "*cmp" + [(set (reg:NZVCSET CRIS_CC0_REGNUM) + (compare:NZVCSET + (match_operand:BW 0 "nonimmediate_operand" "") + (match_operand:BW 1 "general_operand" "")))] "reload_completed" "@ cmp %1,%0 @@ -299,9 +336,9 @@ ;; SImode. This mode is the only one needed, since gcc automatically ;; extends subregs for lower-size modes. FIXME: Add testcase. -(define_insn "*btst" - [(set (reg:CC CRIS_CC0_REGNUM) - (compare:CC +(define_insn "*btst" + [(set (reg:NZVCSET CRIS_CC0_REGNUM) + (compare:NZVCSET (zero_extract:SI (match_operand:SI 0 "nonmemory_operand" "r, r,r, r,r, r,Kp") (match_operand:SI 1 "const_int_operand" "Kc,n,Kc,n,Kc,n,n") @@ -1978,22 +2015,23 @@ "" "cris_reduce_compare (&operands[0], &operands[1], &operands[2]);") -(define_insn_and_split "*cbranch4" +(define_insn_and_split "*cbranch4" [(set (pc) (if_then_else - (match_operator 0 "ordered_comparison_operator" - [(match_operand:BWDD 1 "nonimmediate_operand" "") - (match_operand:BWDD 2 "general_operand" "")]) - (label_ref (match_operand 3 "")) + (cond + (match_operand:BWDD 0 "nonimmediate_operand" "") + (match_operand:BWDD 1 "general_operand" "")) + (label_ref (match_operand 2 "")) (pc))) (clobber (reg:CC CRIS_CC0_REGNUM))] "" "#" "&& reload_completed" - [(set (reg:CC CRIS_CC0_REGNUM) (compare:CC (match_dup 1) (match_dup 2))) + [(set (reg: CRIS_CC0_REGNUM) + (compare: (match_dup 0) (match_dup 1))) (set (pc) - (if_then_else (match_op_dup 0 [(reg:CC CRIS_CC0_REGNUM) (const_int 0)]) - (label_ref (match_dup 3)) + (if_then_else (cond (reg: CRIS_CC0_REGNUM) (const_int 0)) + (label_ref (match_dup 2)) (pc)))] "") @@ -2019,7 +2057,7 @@ (const_int 0))) (set (pc) (if_then_else (zcond (reg:CC CRIS_CC0_REGNUM) (const_int 0)) - (label_ref (match_dup 3)) + (label_ref (match_dup 2)) (pc)))] "") @@ -2028,9 +2066,9 @@ ;; e.g. m68k, so we have to check if overflow bit is set on all "signed" ;; conditions. -(define_insn "b" +(define_insn "b" [(set (pc) - (if_then_else (ncond (reg:CC CRIS_CC0_REGNUM) + (if_then_else (zcond (reg:NZUSE CRIS_CC0_REGNUM) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] @@ -2038,33 +2076,33 @@ "b %l0%#" [(set_attr "slottable" "has_slot")]) -(define_insn "b" +(define_insn "b" [(set (pc) - (if_then_else (ocond (reg:CC CRIS_CC0_REGNUM) + (if_then_else (nzvccond (reg:NZVCUSE CRIS_CC0_REGNUM) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "reload_completed" - ;; FIXME: optimize out the compare and handle CC_NO_OVERFLOW. "b %l0%#" [(set_attr "slottable" "has_slot")]) -(define_insn "b" +(define_insn "b" [(set (pc) - (if_then_else (rcond (reg:CC CRIS_CC0_REGNUM) + (if_then_else (rnzcond (reg:NZUSE CRIS_CC0_REGNUM) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "reload_completed" - ;; FIXME: optimize out the compare and handle CC_NO_OVERFLOW. - "b %l0%#" +{ + return mode == CC_NZmode ? "b %l0%#": "b %l0%#"; +} [(set_attr "slottable" "has_slot")]) ;; Reversed anonymous patterns to the ones above, as mandated. -(define_insn "*b_reversed" +(define_insn "*b_reversed" [(set (pc) - (if_then_else (ncond (reg:CC CRIS_CC0_REGNUM) + (if_then_else (nzcond (reg:NZUSE CRIS_CC0_REGNUM) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] @@ -2072,26 +2110,26 @@ "b %l0%#" [(set_attr "slottable" "has_slot")]) -(define_insn "*b_reversed" +(define_insn "*b_reversed" [(set (pc) - (if_then_else (ocond (reg:CC CRIS_CC0_REGNUM) + (if_then_else (nzvccond (reg:NZVCUSE CRIS_CC0_REGNUM) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "reload_completed" - ;; FIXME: optimize out the compare and handle CC_NO_OVERFLOW. "b %l0%#" [(set_attr "slottable" "has_slot")]) -(define_insn "*b_reversed" +(define_insn "*b_reversed" [(set (pc) - (if_then_else (rcond (reg:CC CRIS_CC0_REGNUM) + (if_then_else (rnzcond (reg:NZUSE CRIS_CC0_REGNUM) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "reload_completed" - ;; FIXME: optimize out the compare and handle CC_NO_OVERFLOW. - "b %l0%#" +{ + return mode == CC_NZmode ? "b %l0%#" : "b %l0%#"; +} [(set_attr "slottable" "has_slot")]) ;; Set on condition: sCC. @@ -2106,46 +2144,46 @@ "" "cris_reduce_compare (&operands[1], &operands[2], &operands[3]);") -(define_insn_and_split "*cstore4" +(define_insn_and_split "*cstore4" [(set (match_operand:SI 0 "register_operand" "=") - (match_operator:SI 1 "ordered_comparison_operator" - [(match_operand:BWDD 2 "nonimmediate_operand" "") - (match_operand:BWDD 3 "general_operand" "")])) + (cond:SI + (match_operand:BWDD 1 "nonimmediate_operand" "") + (match_operand:BWDD 2 "general_operand" ""))) (clobber (reg:CC CRIS_CC0_REGNUM))] "" "#" "&& reload_completed" - [(set (reg:CC CRIS_CC0_REGNUM) (compare:CC (match_dup 2) (match_dup 3))) - (set (match_operand:SI 0 "register_operand") - (match_operator:SI 1 "ordered_comparison_operator" - [(reg:CC CRIS_CC0_REGNUM) (const_int 0)]))] + [(set (reg: CRIS_CC0_REGNUM) + (compare: (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (cond:SI (reg: CRIS_CC0_REGNUM) (const_int 0)))] "") ;; Like bCC, we have to check the overflow bit for ;; signed conditions. -(define_insn "*s" +(define_insn "*s" [(set (match_operand:SI 0 "register_operand" "=r") - (ncond:SI (reg:CC CRIS_CC0_REGNUM) (const_int 0)))] + (nzcond:SI (reg:NZUSE CRIS_CC0_REGNUM) (const_int 0)))] "reload_completed" "s %0" [(set_attr "slottable" "yes") (set_attr "cc" "none")]) -(define_insn "*s" +(define_insn "*s" [(set (match_operand:SI 0 "register_operand" "=r") - (rcond:SI (reg:CC CRIS_CC0_REGNUM) (const_int 0)))] + (rnzcond:SI (reg:NZUSE CRIS_CC0_REGNUM) (const_int 0)))] "reload_completed" - ;; FIXME: optimize out the compare and handle CC_NO_OVERFLOW. - "s %0" +{ + return mode == CC_NZmode ? "s %0" : "s %0"; +} [(set_attr "slottable" "yes") (set_attr "cc" "none")]) -(define_insn "*s" +(define_insn "*s" [(set (match_operand:SI 0 "register_operand" "=r") - (ocond:SI (reg:CC CRIS_CC0_REGNUM) (const_int 0)))] + (nzvccond:SI (reg:NZVCUSE CRIS_CC0_REGNUM) (const_int 0)))] "reload_completed" - ;; FIXME: optimize out the compare and handle CC_NO_OVERFLOW. "s %0" [(set_attr "slottable" "yes") (set_attr "cc" "none")])