machine_mode mode = GET_MODE (x);
rtx x1;
+ /* Matches all instructions which can do .f and clobbers only Z flag. */
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && y == const0_rtx
+ && GET_CODE (x) == MULT
+ && (op == EQ || op == NE))
+ return CC_Zmode;
+
/* For an operation that sets the condition codes as a side-effect, the
C and V flags is not set as for cmp, so we can only use comparisons where
this doesn't matter. (For LT and GE we can use "mi" and "pl"
(set_attr "cond" "set_zn")
(set_attr "length" "*,4,4,4,8")])
-;; The next two patterns are for plos, ior, xor, and, and mult.
+(define_insn "*mulsi3_cmp0"
+ [(set (reg:CC_Z CC_REG)
+ (compare:CC_Z
+ (mult:SI
+ (match_operand:SI 1 "register_operand" "%r,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "rL,I,i"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (mult:SI (match_dup 1) (match_dup 2)))]
+ "TARGET_MPY"
+ "mpy%?.f\\t%0,%1,%2"
+ [(set_attr "length" "4,4,8")
+ (set_attr "type" "multi")])
+
+(define_insn "*mulsi3_cmp0_noout"
+ [(set (reg:CC_Z CC_REG)
+ (compare:CC_Z
+ (mult:SI
+ (match_operand:SI 0 "register_operand" "%r,r,r")
+ (match_operand:SI 1 "nonmemory_operand" "rL,I,i"))
+ (const_int 0)))]
+ "TARGET_MPY"
+ "mpy%?.f\\t0,%0,%1"
+ [(set_attr "length" "4,4,8")
+ (set_attr "type" "multi")])
+
+;; The next two patterns are for plus, ior, xor, and.
(define_insn "*commutative_binary_cmp0_noout"
[(set (match_operand 0 "cc_set_register" "")
(match_operator 4 "zn_compare_operator"
- [(match_operator:SI 3 "commutative_operator"
+ [(match_operator:SI 3 "commutative_operator_sans_mult"
[(match_operand:SI 1 "register_operand" "%r,r")
(match_operand:SI 2 "nonmemory_operand" "rL,Cal")])
(const_int 0)]))]
(define_insn "*commutative_binary_cmp0"
[(set (match_operand 3 "cc_set_register" "")
(match_operator 5 "zn_compare_operator"
- [(match_operator:SI 4 "commutative_operator"
+ [(match_operator:SI 4 "commutative_operator_sans_mult"
[(match_operand:SI 1 "register_operand" "%0, 0,r,r")
(match_operand:SI 2 "nonmemory_operand" "rL,rI,r,Cal")])
(const_int 0)]))
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* mpy.f r1,r0,r1
+ mov_s r0,5 ;3
+ j_s.d [blink]
+ mov.ne r0,r1 */
+unsigned int
+ubar (unsigned int a, unsigned int b)
+{
+ unsigned int c = a * b;
+ if (c == 0)
+ {
+ return 5;
+ }
+ return c;
+}
+
+/* mpy.f r1,r0,r1
+ mov_s r0,5 ;3
+ j_s.d [blink]
+ mov.ne r0,r1 */
+signed int
+bar (signed int a, signed int b)
+{
+ signed int c = a * b;
+ if (c == 0)
+ {
+ return 5;
+ }
+ return c;
+}
+
+/* mpy.f 0,r0,r1
+ mov_s r0,1 ;3
+ j_s.d [blink]
+ mov.eq r0,5 */
+unsigned int
+ufoo (unsigned int a, unsigned int b)
+{
+ if (a * b == 0)
+ {
+ return 5;
+ }
+ return 1;
+}
+
+/* mpy.f 0,r0,r1
+ mov_s r0,1 ;3
+ j_s.d [blink]
+ mov.eq r0,5 */
+unsigned int
+foo (signed int a, signed int b)
+{
+ if (a * b == 0)
+ {
+ return 5;
+ }
+ return 1;
+}
+
+/* { dg-final { scan-assembler-times "mpy\\.f\\s+0" 2 } } */
+/* { dg-final { scan-assembler-times "mov\\.ne\\s+" 2 } } */
+/* { dg-final { scan-assembler-times "mpy\\.f\\s+r" 2 } } */
+/* { dg-final { scan-assembler-times "mov\\.eq\\s+" 2 } } */
+