summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2020-02-10 23:55:32 +0100
committerHans-Peter Nilsson <hp@axis.com>2020-05-09 03:51:34 +0200
commitb3e01c3d1b61ecc903b577920ca43804a2cb5497 (patch)
tree21db75d825f0d3a52c1b992d7ff2f73c0348fc2d /gcc/config
parent12bdaa7d3e94cf30f8ce1750325a245175bdbee5 (diff)
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<NZVCSET:mode>"): Rename from "*cmpdi". Replace CCmode with iteration over NZVCSET. ("*cmp_ext<BW:mode><NZVCSET:mode>"): Similarly; rename from "*cmp_ext<mode>". ("*cmpsi<NZVCSET:mode>"): Similarly, from "*cmpsi". ("*cmp<BW:mode><NZVCSET:mode>"): Similarly from "*cmp<mode>". ("*btst<mode>"): Similarly, from "*btst". ("*cbranch<mode><code>4"): Rename from "*cbranch<mode>4", iterating over cond instead of matching the comparison with ordered_comparison_operator. ("*cbranch<mode>4_btstq<CC>"): Correct label operand number. ("b<zcond:code><mode>"): Rename from "b<ncond:code>", iterating over NZUSE. ("b<nzvccond:code><mode>"): Similarly from "b<ocond:code>", over NZVCUSE. Remove FIXME. ("*b<nzcond:code>_reversed<mode>"): Similarly from "*b<ncond:code>_reversed", over NZUSE. ("*b<nzvccond:code>_reversed<mode>"): Similarly from "*b<ocond:code>_reversed", over NZVCUSE. Remove FIXME. ("b<rnzcond:code><mode>"): Similarly from "b<rcond:code>", over NZUSE. Reinstate "b<oCC>" vs. "b<CC>" mnemonic choice, depending on CC_NZmode vs. CCmode. Remove FIXME. ("*b<rnzcond:code>_reversed<mode>"): Similarly from "*b<rcond:code>_reversed", over NZUSE. ("*cstore<mode><code>4"): Rename from "*cstore<mode>4", iterating over cond instead of matching the comparison with ordered_comparison_operator. ("*s<nzcond:code><mode>"): Rename from "*s<ncond:code>", iterating over NZUSE. ("*s<rnzcond:code><mode>"): Similar from "*s<rcond:code>", over NZUSE. Reinstate "b<oCC>" vs. "b<CC>" mnemonic choice, depending on CC_NZmode vs. CCmode. ("*s<nzvccond:code><mode>"): Simlar from "*s<ocond:code>", over NZVCUSE. Remove FIXME.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/cris/cris-modes.def54
-rw-r--r--gcc/config/cris/cris-protos.h2
-rw-r--r--gcc/config/cris/cris.c71
-rw-r--r--gcc/config/cris/cris.h4
-rw-r--r--gcc/config/cris/cris.md178
5 files changed, 237 insertions, 72 deletions
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
+<http://www.gnu.org/licenses/>. */
+
+/* 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<condition> 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 <setnz> (and the
+ anonymization prefix <anz> 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" "<cmp_op1c>")
- (match_operand:DI_ 1 "general_operand" "<cmp_op2c>")))]
+(define_insn "*cmpdi<NZVCSET:mode>"
+ [(set (reg:NZVCSET CRIS_CC0_REGNUM)
+ (compare:NZVCSET
+ (match_operand:DI_ 0 "nonimmediate_operand" "<cmp_op0c>")
+ (match_operand:DI_ 1 "general_operand" "<cmp_op1c>")))]
"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<mode>"
- [(set (reg:CC CRIS_CC0_REGNUM)
- (compare:CC
+(define_insn "*cmp_ext<BW:mode><NZVCSET:mode>"
+ [(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" "<cmp_op1c>")
- (match_operand:SI_ 1 "general_operand" "<cmp_op2c>")))]
+(define_insn "*cmpsi<NZVCSET:mode>"
+ [(set (reg:NZVCSET CRIS_CC0_REGNUM)
+ (compare:NZVCSET
+ (match_operand:SI_ 0 "nonimmediate_operand" "<cmp_op0c>")
+ (match_operand:SI_ 1 "general_operand" "<cmp_op1c>")))]
"reload_completed"
"@
cmpq %1,%0
@@ -280,10 +316,11 @@
test.d %0"
[(set_attr "slottable" "yes,yes,yes,no,no,no")])
-(define_insn "*cmp<mode>"
- [(set (reg:CC CRIS_CC0_REGNUM)
- (compare:CC (match_operand:BW 0 "nonimmediate_operand" "<cmp_op1c>")
- (match_operand:BW 1 "general_operand" "<cmp_op2c>")))]
+(define_insn "*cmp<BW:mode><NZVCSET:mode>"
+ [(set (reg:NZVCSET CRIS_CC0_REGNUM)
+ (compare:NZVCSET
+ (match_operand:BW 0 "nonimmediate_operand" "<cmp_op0c>")
+ (match_operand:BW 1 "general_operand" "<cmp_op1c>")))]
"reload_completed"
"@
cmp<m> %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<mode>"
+ [(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 "*cbranch<mode>4"
+(define_insn_and_split "*cbranch<mode><code>4"
[(set (pc)
(if_then_else
- (match_operator 0 "ordered_comparison_operator"
- [(match_operand:BWDD 1 "nonimmediate_operand" "<cmp_op1c>")
- (match_operand:BWDD 2 "general_operand" "<cmp_op2c>")])
- (label_ref (match_operand 3 ""))
+ (cond
+ (match_operand:BWDD 0 "nonimmediate_operand" "<cmp_op0c>")
+ (match_operand:BWDD 1 "general_operand" "<cmp_op1c>"))
+ (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:<xCC> CRIS_CC0_REGNUM)
+ (compare:<xCC> (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:<xCC> 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<ncond:code>"
+(define_insn "b<zcond:code><mode>"
[(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<CC> %l0%#"
[(set_attr "slottable" "has_slot")])
-(define_insn "b<ocond:code>"
+(define_insn "b<nzvccond:code><mode>"
[(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<CC> %l0%#"
[(set_attr "slottable" "has_slot")])
-(define_insn "b<rcond:code>"
+(define_insn "b<rnzcond:code><mode>"
[(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<CC> %l0%#"
+{
+ return <MODE>mode == CC_NZmode ? "b<oCC> %l0%#": "b<CC> %l0%#";
+}
[(set_attr "slottable" "has_slot")])
;; Reversed anonymous patterns to the ones above, as mandated.
-(define_insn "*b<ncond:code>_reversed"
+(define_insn "*b<nzcond:code>_reversed<mode>"
[(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<rCC> %l0%#"
[(set_attr "slottable" "has_slot")])
-(define_insn "*b<ocond:code>_reversed"
+(define_insn "*b<nzvccond:code>_reversed<mode>"
[(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<rCC> %l0%#"
[(set_attr "slottable" "has_slot")])
-(define_insn "*b<rcond:code>_reversed"
+(define_insn "*b<rnzcond:code>_reversed<mode>"
[(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<rCC> %l0%#"
+{
+ return <MODE>mode == CC_NZmode ? "b<roCC> %l0%#" : "b<rCC> %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 "*cstore<mode>4"
+(define_insn_and_split "*cstore<mode><code>4"
[(set (match_operand:SI 0 "register_operand" "=<sCC_destc>")
- (match_operator:SI 1 "ordered_comparison_operator"
- [(match_operand:BWDD 2 "nonimmediate_operand" "<cmp_op1c>")
- (match_operand:BWDD 3 "general_operand" "<cmp_op2c>")]))
+ (cond:SI
+ (match_operand:BWDD 1 "nonimmediate_operand" "<cmp_op0c>")
+ (match_operand:BWDD 2 "general_operand" "<cmp_op1c>")))
(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:<xCC> CRIS_CC0_REGNUM)
+ (compare:<xCC> (match_dup 1) (match_dup 2)))
+ (set (match_dup 0)
+ (cond:SI (reg:<xCC> CRIS_CC0_REGNUM) (const_int 0)))]
"")
;; Like bCC, we have to check the overflow bit for
;; signed conditions.
-(define_insn "*s<ncond:code>"
+(define_insn "*s<nzcond:code><mode>"
[(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<CC> %0"
[(set_attr "slottable" "yes")
(set_attr "cc" "none")])
-(define_insn "*s<rcond:code>"
+(define_insn "*s<rnzcond:code><mode>"
[(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<CC> %0"
+{
+ return <MODE>mode == CC_NZmode ? "s<oCC> %0" : "s<CC> %0";
+}
[(set_attr "slottable" "yes")
(set_attr "cc" "none")])
-(define_insn "*s<ocond:code>"
+(define_insn "*s<nzvccond:code><mode>"
[(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<CC> %0"
[(set_attr "slottable" "yes")
(set_attr "cc" "none")])