summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-07 13:35:54 +0000
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-07 13:35:54 +0000
commit8ee7dc6fa1a663c9eea8043f84951c1e073468ff (patch)
tree011f8c6e98d98baf6e4d2487e289d39bb5600254
parent2dfe32eb0a6a1ce8181dca89c0e46ee5699b9df8 (diff)
downloadgcc-8ee7dc6fa1a663c9eea8043f84951c1e073468ff.tar.gz
gcc/
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. gcc/testsuite 2013-06-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> PR target/56315 * gcc.target/arm/xordi3-opt.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199814 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/arm/arm.c1
-rw-r--r--gcc/config/arm/arm.md48
-rw-r--r--gcc/config/arm/constraints.md6
-rw-r--r--gcc/config/arm/neon.md17
-rw-r--r--gcc/config/arm/predicates.md5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/xordi3-opt.c9
8 files changed, 77 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0c66239556a..39775f966f6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
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.
Clean up alternatives.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 033e8bf0f3c..6fc307e7709 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -2687,6 +2687,7 @@ const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code code)
{
case AND:
case IOR:
+ case XOR:
return (const_ok_for_op (hi_val, code) || hi_val == 0xFFFFFFFF)
&& (const_ok_for_op (lo_val, code) || lo_val == 0xFFFFFFFF);
case PLUS:
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index dc62caa5669..3f0e021f3ed 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -3181,19 +3181,49 @@
(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"
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index 53cbff6421b..7cd8e31c97f 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -266,6 +266,12 @@
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, IOR)")))
+(define_constraint "Dg"
+ "@internal
+ In ARM/Thumb-2 state a const_int that can be used by insn xordi."
+ (and (match_code "const_int")
+ (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, XOR)")))
+
(define_constraint "Di"
"@internal
In ARM/Thumb-2 state a const_int or const_double where both the high
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 1697008531e..e814df0d264 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -782,21 +782,6 @@
[(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")))]
@@ -5605,7 +5590,7 @@
(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;
})
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 3cec5690193..d169cb27035 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -179,6 +179,11 @@
(match_test "const_ok_for_dimode_op (INTVAL (op), IOR)"))
(match_operand 0 "neon_logic_op2")))
+(define_predicate "arm_xordi_operand"
+ (ior (match_operand 0 "s_register_operand")
+ (and (match_code "const_int")
+ (match_test "const_ok_for_dimode_op (INTVAL (op), XOR)"))))
+
(define_predicate "arm_adddi_operand"
(ior (match_operand 0 "s_register_operand")
(and (match_code "const_int")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b39ac889448..9c2ff38c111 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/56315
+ * gcc.target/arm/xordi3-opt.c: New test.
+
2013-06-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* gcc.dg/debug/dwarf2/discriminator.c: Fix wording.
diff --git a/gcc/testsuite/gcc.target/arm/xordi3-opt.c b/gcc/testsuite/gcc.target/arm/xordi3-opt.c
new file mode 100644
index 00000000000..7e031c3af2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/xordi3-opt.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+unsigned long long xor64 (unsigned long long input)
+{
+ return input ^ 0x200000004ULL;
+}
+
+/* { dg-final { scan-assembler-not "mov\[\\t \]+.+,\[\\t \]*.+" } } */