;; The last constraint is due to that after reload, the '%' is not
;; honored, and canonicalization doesn't care about keeping the same
;; register as in destination. This will happen after insn splitting.
-;; gcc <= 2.7.2. FIXME: Check for gcc-2.9x
""
{
[(set_attr "slottable" "yes")
(set_attr "cc" "none")])
+;; This pattern is usually generated after reload, so a '%' is
+;; ineffective; use explicit combinations.
+(define_insn "*addi_b_<mode>"
+ [(set (match_operand:BWD 0 "register_operand" "=r,r")
+ (plus:BWD
+ (match_operand:BWD 1 "register_operand" "0,r")
+ (match_operand:BWD 2 "register_operand" "r,0")))]
+ ""
+ "@
+ addi %2.b,%0
+ addi %1.b,%0"
+ [(set_attr "slottable" "yes")])
+
+;; Strip the dccr clobber from addM3 with register operands, if the
+;; next instruction isn't using it.
+;; Not clobbering dccr may let cmpelim match a later compare with a
+;; previous operation of interest. This has to run before cmpelim so it
+;; can't be a peephole2. See gcc.target/cris/pr93372-45.c for a
+;; test-case.
+(define_split ;; "*add<mode>3_addi"
+ [(parallel
+ [(set (match_operand:BWD 0 "register_operand")
+ (plus:BWD
+ (match_operand:BWD 1 "register_operand")
+ (match_operand:BWD 2 "register_operand")))
+ (clobber (reg:CC CRIS_CC0_REGNUM))])]
+ "reload_completed"
+ [(set (match_dup 0) (plus:BWD (match_dup 1) (match_dup 2)))]
+{
+ rtx reg = operands[0];
+ rtx_insn *i = next_nonnote_nondebug_insn_bb (curr_insn);
+
+ while (i != NULL_RTX && (!INSN_P (i) || DEBUG_INSN_P (i)))
+ i = next_nonnote_nondebug_insn_bb (i);
+
+ if (i == NULL_RTX || reg_mentioned_p (reg, i) || BARRIER_P (i))
+ FAIL;
+})
+
(define_insn "<u>mul<s><mode>3"
[(set (match_operand:WD 0 "register_operand" "=r")
(mult:WD
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not {\tcmp|\ttest} } } */
+
+extern void foo(void);
+unsigned int x (unsigned int b, unsigned int a, unsigned int *c)
+{
+ unsigned int y = a & 15;
+ unsigned int z = y + b;
+ if (y == 0)
+ *c = z;
+ return z;
+}