Hi This is the third part of the patches that deals with 64bit xor. It extends the patterns xordi3, xordi3_insn and xordi3_neon to handle 64bit constant operands.
Tested on arm qemu without regression. OK for trunk? thanks Carrot 2012-05-30 Wei Guozhi <car...@google.com> PR target/53447 * gcc.target/arm/pr53447-3.c: New testcase. 2012-05-30 Wei Guozhi <car...@google.com> PR target/53447 * config/arm/arm.md (xordi3): Extend it to handle 64bit constants. (xordi3_insn): Likewise. * config/arm/neon.md (xordi3_neon): Likewise. Index: testsuite/gcc.target/arm/pr53447-3.c =================================================================== --- testsuite/gcc.target/arm/pr53447-3.c (revision 0) +++ testsuite/gcc.target/arm/pr53447-3.c (revision 0) @@ -0,0 +1,8 @@ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-final { scan-assembler-not "mov" } } */ + +void t0p(long long * p) +{ + *p ^= 0x100000003; +} Index: config/arm/neon.md =================================================================== --- config/arm/neon.md (revision 187998) +++ config/arm/neon.md (working copy) @@ -878,18 +878,20 @@ ) (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")))] + [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w,?&r,?&r") + (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r,w,0,r") + (match_operand:DI 2 "arm_di_operand" "w,r,r,w,Di,Di")))] "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" "nota8,*,*,onlya8")] + veor\t%P0, %P1, %P2 + # + #" + [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*") + (set_attr "length" "*,8,8,*,8,8") + (set_attr "arch" "nota8,*,*,onlya8,*,*")] ) (define_insn "one_cmpl<mode>2" Index: config/arm/arm.md =================================================================== --- config/arm/arm.md (revision 187998) +++ config/arm/arm.md (working copy) @@ -2994,17 +2994,38 @@ (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_di_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")))] +(define_insn_and_split "*xordi3_insn" + [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r") + (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r,0,r") + (match_operand:DI 2 "arm_di_operand" "r,r,Di,Di")))] "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON" "#" + "TARGET_32BIT && !TARGET_IWMMXT && reload_completed" + [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) (xor:SI (match_dup 4) (match_dup 5)))] + " + { + operands[3] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[1] = gen_lowpart (SImode, operands[1]); + if (GET_CODE (operands[2]) == CONST_INT) + { + HOST_WIDE_INT v = INTVAL (operands[2]); + operands[5] = GEN_INT (ARM_SIGN_EXTEND ((v >> 32) & 0xFFFFFFFF)); + operands[2] = GEN_INT (ARM_SIGN_EXTEND (v & 0xFFFFFFFF)); + } + else + { + operands[5] = gen_highpart (SImode, operands[2]); + operands[2] = gen_lowpart (SImode, operands[2]); + } + }" [(set_attr "length" "8") (set_attr "predicable" "yes")] )