+2013-06-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/56315
+ * config/arm/arm.md (*xordi3_insn): Change to insn_and_split.
+ (xordi3): Change operand 2 constraint to arm_xordi_operand.
+ * config/arm/arm.c (const_ok_for_dimode_op): Handle XOR.
+ * config/arm/constraints.md (Dg): New constraint.
+ * config/arm/neon.md (xordi3_neon): Remove.
+ (neon_veor<mode>): Generate xordi3 instead of xordi3_neon.
+ * config/arm/predicates.md (arm_xordi_operand): New predicate.
+
2013-06-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.md (anddi3_insn): Remove duplicate alternatives.
(define_expand "xordi3"
[(set (match_operand:DI 0 "s_register_operand" "")
(xor:DI (match_operand:DI 1 "s_register_operand" "")
- (match_operand:DI 2 "s_register_operand" "")))]
+ (match_operand:DI 2 "arm_xordi_operand" "")))]
"TARGET_32BIT"
""
)
-(define_insn "*xordi3_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
- (match_operand:DI 2 "s_register_operand" "r,r")))]
- "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
- "#"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")]
+(define_insn_and_split "*xordi3_insn"
+ [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
+ (xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w")
+ (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
+ "TARGET_32BIT && !TARGET_IWMMXT"
+{
+ switch (which_alternative)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4: /* fall through */
+ return "#";
+ case 0: /* fall through */
+ case 5: return "veor\t%P0, %P1, %P2";
+ default: gcc_unreachable ();
+ }
+}
+ "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
+ && !(IS_VFP_REGNUM (REGNO (operands[0])))"
+ [(set (match_dup 3) (match_dup 4))
+ (set (match_dup 5) (match_dup 6))]
+ "
+ {
+ operands[3] = gen_lowpart (SImode, operands[0]);
+ operands[5] = gen_highpart (SImode, operands[0]);
+
+ operands[4] = simplify_gen_binary (XOR, SImode,
+ gen_lowpart (SImode, operands[1]),
+ gen_lowpart (SImode, operands[2]));
+ operands[6] = simplify_gen_binary (XOR, SImode,
+ gen_highpart (SImode, operands[1]),
+ gen_highpart_mode (SImode, DImode, operands[2]));
+
+ }"
+ [(set_attr "length" "*,8,8,8,8,*")
+ (set_attr "neon_type" "neon_int_1,*,*,*,*,neon_int_1")
+ (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
)
(define_insn "*xordi_zesidi_di"
[(set_attr "neon_type" "neon_int_1")]
)
-(define_insn "xordi3_neon"
- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w")
- (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r,w")
- (match_operand:DI 2 "s_register_operand" "w,r,r,w")))]
- "TARGET_NEON"
- "@
- veor\t%P0, %P1, %P2
- #
- #
- veor\t%P0, %P1, %P2"
- [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1")
- (set_attr "length" "*,8,8,*")
- (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
-)
-
(define_insn "one_cmpl<mode>2"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
(match_operand:SI 3 "immediate_operand" "")]
"TARGET_NEON"
{
- emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
+ emit_insn (gen_xor<mode>3 (operands[0], operands[1], operands[2]));
DONE;
})