* [PATCH][ARM] Cleanup logical DImode operations
@ 2019-07-19 11:35 Wilco Dijkstra
2019-07-31 16:25 ` Wilco Dijkstra
2019-08-22 13:35 ` Kyrill Tkachov
0 siblings, 2 replies; 6+ messages in thread
From: Wilco Dijkstra @ 2019-07-19 11:35 UTC (permalink / raw)
To: GCC Patches; +Cc: nd, Kyrylo Tkachov, Richard Earnshaw
Cleanup the logical DImode operations since the current implementation is way
too complicated. Thumb-1, Thumb-2, VFP/Neon and iwMMXt all work differently,
resulting in a bewildering number of expansions, patterns and splits across
several md files. All this complexity is counterproductive and results in
inefficient code.
A much simpler approach is to split these operations early in the expander
so that optimizations and register allocation are applied on the 32-bit halves.
Code generation is unchanged on Thumb-1 and Arm/Thumb-2 without Neon or iwMMXt
(which already expand these instructions early). With Neon these changes save
~1000 instructions from the PR77308 testcase, mostly by significantly reducing
register pressure and spilling.
Bootstrap & regress OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57
OK for commit?
ChangeLog:
2019-07-18 Wilco Dijkstra <wdijkstr@arm.com>
* config/arm/arm.md (split and/eor/ior): Remove Neon check.
(split not): Add DImode not splitter.
(anddi3): Remove pattern.
(anddi3_insn): Likewise.
(anddi_zesidi_di): Likewise.
(anddi_sesdi_di): Likewise.
(anddi_notdi_di): Likewise.
(anddi_notzesidi_di): Likewise.
(anddi_notsesidi_di): Likewise.
(iordi3): Likewise.
(iordi3_insn): Likewise.
(iordi_zesidi_di): Likewise.
(iordi_sesidi_di): Likewise.
(xordi3): Likewise.
(xordi3_insn): Likewise.
(xordi_sesidi_di): Likewise.
(xordi_zesidi_di): Likewise.
(one_cmpldi2): Likewise.
(one_cmpldi2_insn): Likewise.
* config/arm/constraints.md: Remove De, Df, Dg constraints.
* config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register
alternative.
(iwmmxt_xordi3): Likewise.
(iwmmxt_anddi3): Likewise.
* config/arm/neon.md (orndi3_neon): Remove pattern.
(anddi_notdi_di): Likewise.
* config/arm/predicates.md (arm_anddi_operand_neon): Remove.
(arm_iordi_operand_neon): Likewise.
(arm_xordi_operand_neon): Likewise.
* config/arm/thumb2.md(iordi_notdi_di): Remove pattern.
(iordi_notzesidi_di): Likewise.
(iordi_notdi_zesidi): Likewise.
(iordi_notsesidi_di): Likewise.
---
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8f4a4c26ea849a023f2e63d2efbf327423512dfc..cab59c403b777c37c1e412ab9a69db2c2ec533a2 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2183,19 +2183,16 @@ (define_expand "divdf3"
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
"")
\f
-;; Boolean and,ior,xor insns
-;; Split up double word logical operations
-
-;; Split up simple DImode logical operations. Simply perform the logical
+;; Split DImode and, ior, xor operations. Simply perform the logical
;; operation on the upper and lower halves of the registers.
+;; This is needed for atomic operations in arm_split_atomic_op.
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(match_operator:DI 6 "logical_binary_operator"
[(match_operand:DI 1 "s_register_operand" "")
(match_operand:DI 2 "s_register_operand" "")]))]
"TARGET_32BIT && reload_completed
- && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
&& ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
[(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
(set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
@@ -2210,167 +2207,20 @@ (define_split
}"
)
+;; Split DImode not (needed for atomic operations in arm_split_atomic_op).
(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (match_operator:DI 6 "logical_binary_operator"
- [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")]))]
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
- (set (match_dup 3) (match_op_dup:SI 6
- [(ashiftrt:SI (match_dup 2) (const_int 31))
- (match_dup 4)]))]
- "
- {
- 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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
-;; The zero extend of operand 2 means we can just copy the high part of
-;; operand1 into operand0.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (ior:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
- [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
-)
-
-;; The zero extend of operand 2 means we can just copy the high part of
-;; operand1 into operand0.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (xor:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
- [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
-)
-
-(define_expand "anddi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (and:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "neon_inv_logic_op2")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (AND, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (AND, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*anddi3_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
- (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
- (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
- "TARGET_32BIT && !TARGET_IWMMXT"
-{
- switch (which_alternative)
- {
- case 0: /* fall through */
- case 6: return "vand\t%P0, %P1, %P2";
- case 1: /* fall through */
- case 7: return neon_output_logic_immediate ("vand", &operands[2],
- DImode, 1, VALID_NEON_QREG_MODE (DImode));
- case 2:
- case 3:
- case 4:
- case 5: /* fall through */
- return "#";
- 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 (AND, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- operands[6] = simplify_gen_binary (AND, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode, operands[2]));
-
- }"
- [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
- multiple,multiple,neon_logic,neon_logic")
- (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
- avoid_neon_for_64bits,avoid_neon_for_64bits")
- (set_attr "length" "*,*,8,8,8,8,*,*")
- ]
-)
-
-(define_insn_and_split "*anddi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
+ [(set (match_operand:DI 0 "s_register_operand")
+ (not:DI (match_operand:DI 1 "s_register_operand")))]
"TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- ; The zero extend of operand 2 clears the high word of the output
- ; operand.
- [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (const_int 0))]
+ [(set (match_dup 0) (not:SI (match_dup 1)))
+ (set (match_dup 2) (not:SI (match_dup 3)))]
"
{
- operands[3] = gen_highpart (SImode, operands[0]);
+ operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[3] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
}"
- [(set_attr "length" "8")
- (set_attr "type" "multiple")]
-)
-
-(define_insn "*anddi_sesdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "type" "multiple")]
)
(define_expand "andsi3"
@@ -2952,105 +2802,6 @@ (define_insn "insv_t2"
(set_attr "type" "bfm")]
)
-; constants for op 2 will never be given to these patterns.
-(define_insn_and_split "*anddi_notdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
- (match_operand:DI 2 "s_register_operand" "r,0")))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed
- && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
- && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (and:SI (not: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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notzesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- bic%?\\t%Q0, %Q1, %2
- #"
- ; (not (zero_extend ...)) allows us to just copy the high word from
- ; operand1 to operand0.
- "TARGET_32BIT
- && reload_completed
- && operands[0] != operands[1]"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notdi_zesidi"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
- (zero_extend:DI
- (match_operand:SI 1 "s_register_operand" "r"))))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (const_int 0))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notsesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (and:SI (not:SI
- (ashiftrt:SI (match_dup 2) (const_int 31)))
- (match_dup 4)))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_insn "andsi_notsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
@@ -3150,101 +2901,6 @@ (define_insn "*andsi_notsi_si_compare0_scratch"
(set_attr "type" "logics_shift_reg")]
)
-(define_expand "iordi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (ior:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "neon_logic_op2")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (IOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (IOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*iordi3_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
- (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
- (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
- "TARGET_32BIT && !TARGET_IWMMXT"
- {
- switch (which_alternative)
- {
- case 0: /* fall through */
- case 6: return "vorr\t%P0, %P1, %P2";
- case 1: /* fall through */
- case 7: return neon_output_logic_immediate ("vorr", &operands[2],
- DImode, 0, VALID_NEON_QREG_MODE (DImode));
- case 2:
- case 3:
- case 4:
- case 5:
- return "#";
- 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 (IOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- operands[6] = simplify_gen_binary (IOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode, operands[2]));
-
- }"
- [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
- multiple,neon_logic,neon_logic")
- (set_attr "length" "*,*,8,8,8,8,*,*")
- (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
-)
-
-(define_insn "*iordi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- orr%?\\t%Q0, %Q1, %2
- #"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "logic_reg,multiple")]
-)
-
-(define_insn "*iordi_sesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_expand "iorsi3"
[(set (match_operand:SI 0 "s_register_operand")
(ior:SI (match_operand:SI 1 "s_register_operand")
@@ -3347,103 +3003,6 @@ (define_insn "*iorsi3_compare0_scratch"
(set_attr "type" "logics_imm,logics_reg")]
)
-(define_expand "xordi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (xor:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "arm_xordi_operand")))]
- "TARGET_32BIT"
- {
- /* The iWMMXt pattern for xordi3 accepts only register operands but we want
- to reuse this expander for all TARGET_32BIT targets so just force the
- constants into a register. Unlike for the anddi3 and iordi3 there are
- no NEON instructions that take an immediate. */
- if (TARGET_IWMMXT && !REG_P (operands[2]))
- operands[2] = force_reg (DImode, operands[2]);
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (XOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (XOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- }
-)
-
-(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 "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
- (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
-)
-
-(define_insn "*xordi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- eor%?\\t%Q0, %Q1, %2
- #"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "logic_reg")]
-)
-
-(define_insn "*xordi_sesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_expand "xorsi3"
[(set (match_operand:SI 0 "s_register_operand")
(xor:SI (match_operand:SI 1 "s_register_operand")
@@ -5033,56 +4592,6 @@ (define_expand "sqrtdf2"
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
"")
-(define_expand "one_cmpldi2"
- [(set (match_operand:DI 0 "s_register_operand")
- (not:DI (match_operand:DI 1 "s_register_operand")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_unary (NOT, SImode,
- gen_lowpart (SImode, operands[1]),
- SImode);
- rtx high = simplify_gen_unary (NOT, SImode,
- gen_highpart_mode (SImode, DImode,
- operands[1]),
- SImode);
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*one_cmpldi2_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
- (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
- "TARGET_32BIT"
- "@
- vmvn\t%P0, %P1
- #
- #
- vmvn\t%P0, %P1"
- "TARGET_32BIT && reload_completed
- && arm_general_register_operand (operands[0], DImode)"
- [(set (match_dup 0) (not:SI (match_dup 1)))
- (set (match_dup 2) (not:SI (match_dup 3)))]
- "
- {
- operands[2] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[3] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
- [(set_attr "length" "*,8,8,*")
- (set_attr "predicable" "no,yes,yes,no")
- (set_attr "type" "neon_move,multiple,multiple,neon_move")
- (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
-)
-
(define_expand "one_cmplsi2"
[(set (match_operand:SI 0 "s_register_operand")
(not:SI (match_operand:SI 1 "s_register_operand")))]
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index d4a4c5967aea09816485d77f9ab90020aa085e73..b76de81b85c8ce7a2ca484a750b908b7ca64600a 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -273,24 +273,6 @@ (define_constraint "Dd"
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, PLUS)")))
-(define_constraint "De"
- "@internal
- In ARM/Thumb-2 state a const_int that can be used by insn anddi."
- (and (match_code "const_int")
- (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)")))
-
-(define_constraint "Df"
- "@internal
- In ARM/Thumb-2 state a const_int that can be used by insn iordi."
- (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/iwmmxt.md b/gcc/config/arm/iwmmxt.md
index 310019aa5ceef98047b310284123f66940430095..86158ea4fd278180d5e2321c66c6c2b5e5c460b0 100644
--- a/gcc/config/arm/iwmmxt.md
+++ b/gcc/config/arm/iwmmxt.md
@@ -55,45 +55,36 @@ (define_insn "tbcstv2si"
)
(define_insn "iwmmxt_iordi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (ior:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ior:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wor%?\\t%0, %1, %2
- #
- #"
+ "wor%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wor,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wor")]
)
(define_insn "iwmmxt_xordi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (xor:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (xor:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wxor%?\\t%0, %1, %2
- #
- #"
+ "wxor%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wxor,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wxor")]
)
(define_insn "iwmmxt_anddi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (and:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (and:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wand%?\\t%0, %1, %2
- #
- #"
+ "wand%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wand,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wand")]
)
(define_insn "iwmmxt_nanddi3"
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 6333e0ea3ea68d73bed1f7c4d8ca090090ad68cc..ef73c77abeeaa02947c70ffa435f7bedc431e3be 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -838,46 +838,6 @@ (define_insn "orn<mode>3_neon"
[(set_attr "type" "neon_logic<q>")]
)
-;; TODO: investigate whether we should disable
-;; this and bicdi3_neon for the A8 in line with the other
-;; changes above.
-(define_insn_and_split "orndi3_neon"
- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
- (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
- (match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
- "TARGET_NEON"
- "@
- vorn\t%P0, %P1, %P2
- #
- #
- #"
- "reload_completed &&
- (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
- "
- {
- if (TARGET_THUMB2)
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- operands[5] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }
- else
- {
- emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
- emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
- DONE;
- }
- }"
- [(set_attr "type" "neon_logic,multiple,multiple,multiple")
- (set_attr "length" "*,16,8,8")
- (set_attr "arch" "any,a,t2,t2")]
-)
-
(define_insn "bic<mode>3_neon"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
@@ -887,20 +847,6 @@ (define_insn "bic<mode>3_neon"
[(set_attr "type" "neon_logic<q>")]
)
-;; Compare to *anddi_notdi_di.
-(define_insn "bicdi3_neon"
- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
- (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
- (match_operand:DI 1 "s_register_operand" "w,0,r")))]
- "TARGET_NEON"
- "@
- vbic\t%P0, %P1, %P2
- #
- #"
- [(set_attr "type" "neon_logic,multiple,multiple")
- (set_attr "length" "*,8,8")]
-)
-
(define_insn "xor<mode>3"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index f53378a250edfdd0de467f2abbe08bc933d6d734..af97edd28f27a1d8ab9ac2a63343380236d97603 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -201,23 +201,6 @@ (define_predicate "arm_add_operand"
(ior (match_operand 0 "arm_rhs_operand")
(match_operand 0 "arm_neg_immediate_operand")))
-(define_predicate "arm_anddi_operand_neon"
- (ior (match_operand 0 "s_register_operand")
- (and (match_code "const_int")
- (match_test "const_ok_for_dimode_op (INTVAL (op), AND)"))
- (match_operand 0 "neon_inv_logic_op2")))
-
-(define_predicate "arm_iordi_operand_neon"
- (ior (match_operand 0 "s_register_operand")
- (and (match_code "const_int")
- (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/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index b283a7b656526d3c4719860d10aa1c0550288ba3..78a6ea0b10dab97ed6651ce62e99cfd7a81722ab 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -1478,103 +1478,6 @@ (define_insn "*thumb2_negsi2_short"
(set_attr "type" "alu_sreg")]
)
-; Constants for op 2 will never be given to these patterns.
-(define_insn_and_split "*iordi_notdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
- (match_operand:DI 2 "s_register_operand" "r,0")))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (ior:SI (not: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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notzesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_THUMB2"
- "#"
- ; (not (zero_extend...)) means operand0 will always be 0xffffffff
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (const_int -1))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notdi_zesidi"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
- (zero_extend:DI
- (match_operand:SI 1 "s_register_operand" "r,r"))))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (not:SI (match_dup 4)))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[4] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notsesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (ior:SI (not:SI
- (ashiftrt:SI (match_dup 2) (const_int 31)))
- (match_dup 4)))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
(define_insn "*orsi_notsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][ARM] Cleanup logical DImode operations
2019-07-19 11:35 [PATCH][ARM] Cleanup logical DImode operations Wilco Dijkstra
@ 2019-07-31 16:25 ` Wilco Dijkstra
2019-08-19 16:12 ` Wilco Dijkstra
2019-08-22 13:35 ` Kyrill Tkachov
1 sibling, 1 reply; 6+ messages in thread
From: Wilco Dijkstra @ 2019-07-31 16:25 UTC (permalink / raw)
To: GCC Patches; +Cc: nd, Kyrylo Tkachov, Richard Earnshaw
ping
Cleanup the logical DImode operations since the current implementation is way
too complicated. Thumb-1, Thumb-2, VFP/Neon and iwMMXt all work differently,
resulting in a bewildering number of expansions, patterns and splits across
several md files. All this complexity is counterproductive and results in
inefficient code.
A much simpler approach is to split these operations early in the expander
so that optimizations and register allocation are applied on the 32-bit halves.
Code generation is unchanged on Thumb-1 and Arm/Thumb-2 without Neon or iwMMXt
(which already expand these instructions early). With Neon these changes save
~1000 instructions from the PR77308 testcase, mostly by significantly reducing
register pressure and spilling.
Bootstrap & regress OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57
OK for commit?
ChangeLog:
2019-07-18 Wilco Dijkstra <wdijkstr@arm.com>
* config/arm/arm.md (split and/eor/ior): Remove Neon check.
(split not): Add DImode not splitter.
(anddi3): Remove pattern.
(anddi3_insn): Likewise.
(anddi_zesidi_di): Likewise.
(anddi_sesdi_di): Likewise.
(anddi_notdi_di): Likewise.
(anddi_notzesidi_di): Likewise.
(anddi_notsesidi_di): Likewise.
(iordi3): Likewise.
(iordi3_insn): Likewise.
(iordi_zesidi_di): Likewise.
(iordi_sesidi_di): Likewise.
(xordi3): Likewise.
(xordi3_insn): Likewise.
(xordi_sesidi_di): Likewise.
(xordi_zesidi_di): Likewise.
(one_cmpldi2): Likewise.
(one_cmpldi2_insn): Likewise.
* config/arm/constraints.md: Remove De, Df, Dg constraints.
* config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register
alternative.
(iwmmxt_xordi3): Likewise.
(iwmmxt_anddi3): Likewise.
* config/arm/neon.md (orndi3_neon): Remove pattern.
(anddi_notdi_di): Likewise.
* config/arm/predicates.md (arm_anddi_operand_neon): Remove.
(arm_iordi_operand_neon): Likewise.
(arm_xordi_operand_neon): Likewise.
* config/arm/thumb2.md(iordi_notdi_di): Remove pattern.
(iordi_notzesidi_di): Likewise.
(iordi_notdi_zesidi): Likewise.
(iordi_notsesidi_di): Likewise.
---
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8f4a4c26ea849a023f2e63d2efbf327423512dfc..cab59c403b777c37c1e412ab9a69db2c2ec533a2 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2183,19 +2183,16 @@ (define_expand "divdf3"
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
"")
-;; Boolean and,ior,xor insns
-;; Split up double word logical operations
-
-;; Split up simple DImode logical operations. Simply perform the logical
+;; Split DImode and, ior, xor operations. Simply perform the logical
;; operation on the upper and lower halves of the registers.
+;; This is needed for atomic operations in arm_split_atomic_op.
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(match_operator:DI 6 "logical_binary_operator"
[(match_operand:DI 1 "s_register_operand" "")
(match_operand:DI 2 "s_register_operand" "")]))]
"TARGET_32BIT && reload_completed
- && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
&& ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
[(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
(set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
@@ -2210,167 +2207,20 @@ (define_split
}"
)
+;; Split DImode not (needed for atomic operations in arm_split_atomic_op).
(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (match_operator:DI 6 "logical_binary_operator"
- [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")]))]
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
- (set (match_dup 3) (match_op_dup:SI 6
- [(ashiftrt:SI (match_dup 2) (const_int 31))
- (match_dup 4)]))]
- "
- {
- 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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
-;; The zero extend of operand 2 means we can just copy the high part of
-;; operand1 into operand0.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (ior:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
- [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
-)
-
-;; The zero extend of operand 2 means we can just copy the high part of
-;; operand1 into operand0.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (xor:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
- [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
-)
-
-(define_expand "anddi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (and:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "neon_inv_logic_op2")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (AND, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (AND, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*anddi3_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
- (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
- (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
- "TARGET_32BIT && !TARGET_IWMMXT"
-{
- switch (which_alternative)
- {
- case 0: /* fall through */
- case 6: return "vand\t%P0, %P1, %P2";
- case 1: /* fall through */
- case 7: return neon_output_logic_immediate ("vand", &operands[2],
- DImode, 1, VALID_NEON_QREG_MODE (DImode));
- case 2:
- case 3:
- case 4:
- case 5: /* fall through */
- return "#";
- 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 (AND, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- operands[6] = simplify_gen_binary (AND, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode, operands[2]));
-
- }"
- [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
- multiple,multiple,neon_logic,neon_logic")
- (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
- avoid_neon_for_64bits,avoid_neon_for_64bits")
- (set_attr "length" "*,*,8,8,8,8,*,*")
- ]
-)
-
-(define_insn_and_split "*anddi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
+ [(set (match_operand:DI 0 "s_register_operand")
+ (not:DI (match_operand:DI 1 "s_register_operand")))]
"TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- ; The zero extend of operand 2 clears the high word of the output
- ; operand.
- [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (const_int 0))]
+ [(set (match_dup 0) (not:SI (match_dup 1)))
+ (set (match_dup 2) (not:SI (match_dup 3)))]
"
{
- operands[3] = gen_highpart (SImode, operands[0]);
+ operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[3] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
}"
- [(set_attr "length" "8")
- (set_attr "type" "multiple")]
-)
-
-(define_insn "*anddi_sesdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "type" "multiple")]
)
(define_expand "andsi3"
@@ -2952,105 +2802,6 @@ (define_insn "insv_t2"
(set_attr "type" "bfm")]
)
-; constants for op 2 will never be given to these patterns.
-(define_insn_and_split "*anddi_notdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
- (match_operand:DI 2 "s_register_operand" "r,0")))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed
- && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
- && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (and:SI (not: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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notzesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- bic%?\\t%Q0, %Q1, %2
- #"
- ; (not (zero_extend ...)) allows us to just copy the high word from
- ; operand1 to operand0.
- "TARGET_32BIT
- && reload_completed
- && operands[0] != operands[1]"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notdi_zesidi"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
- (zero_extend:DI
- (match_operand:SI 1 "s_register_operand" "r"))))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (const_int 0))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notsesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (and:SI (not:SI
- (ashiftrt:SI (match_dup 2) (const_int 31)))
- (match_dup 4)))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_insn "andsi_notsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
@@ -3150,101 +2901,6 @@ (define_insn "*andsi_notsi_si_compare0_scratch"
(set_attr "type" "logics_shift_reg")]
)
-(define_expand "iordi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (ior:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "neon_logic_op2")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (IOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (IOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*iordi3_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
- (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
- (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
- "TARGET_32BIT && !TARGET_IWMMXT"
- {
- switch (which_alternative)
- {
- case 0: /* fall through */
- case 6: return "vorr\t%P0, %P1, %P2";
- case 1: /* fall through */
- case 7: return neon_output_logic_immediate ("vorr", &operands[2],
- DImode, 0, VALID_NEON_QREG_MODE (DImode));
- case 2:
- case 3:
- case 4:
- case 5:
- return "#";
- 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 (IOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- operands[6] = simplify_gen_binary (IOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode, operands[2]));
-
- }"
- [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
- multiple,neon_logic,neon_logic")
- (set_attr "length" "*,*,8,8,8,8,*,*")
- (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
-)
-
-(define_insn "*iordi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- orr%?\\t%Q0, %Q1, %2
- #"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "logic_reg,multiple")]
-)
-
-(define_insn "*iordi_sesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_expand "iorsi3"
[(set (match_operand:SI 0 "s_register_operand")
(ior:SI (match_operand:SI 1 "s_register_operand")
@@ -3347,103 +3003,6 @@ (define_insn "*iorsi3_compare0_scratch"
(set_attr "type" "logics_imm,logics_reg")]
)
-(define_expand "xordi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (xor:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "arm_xordi_operand")))]
- "TARGET_32BIT"
- {
- /* The iWMMXt pattern for xordi3 accepts only register operands but we want
- to reuse this expander for all TARGET_32BIT targets so just force the
- constants into a register. Unlike for the anddi3 and iordi3 there are
- no NEON instructions that take an immediate. */
- if (TARGET_IWMMXT && !REG_P (operands[2]))
- operands[2] = force_reg (DImode, operands[2]);
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (XOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (XOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- }
-)
-
-(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 "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
- (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
-)
-
-(define_insn "*xordi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- eor%?\\t%Q0, %Q1, %2
- #"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "logic_reg")]
-)
-
-(define_insn "*xordi_sesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_expand "xorsi3"
[(set (match_operand:SI 0 "s_register_operand")
(xor:SI (match_operand:SI 1 "s_register_operand")
@@ -5033,56 +4592,6 @@ (define_expand "sqrtdf2"
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
"")
-(define_expand "one_cmpldi2"
- [(set (match_operand:DI 0 "s_register_operand")
- (not:DI (match_operand:DI 1 "s_register_operand")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_unary (NOT, SImode,
- gen_lowpart (SImode, operands[1]),
- SImode);
- rtx high = simplify_gen_unary (NOT, SImode,
- gen_highpart_mode (SImode, DImode,
- operands[1]),
- SImode);
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*one_cmpldi2_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
- (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
- "TARGET_32BIT"
- "@
- vmvn\t%P0, %P1
- #
- #
- vmvn\t%P0, %P1"
- "TARGET_32BIT && reload_completed
- && arm_general_register_operand (operands[0], DImode)"
- [(set (match_dup 0) (not:SI (match_dup 1)))
- (set (match_dup 2) (not:SI (match_dup 3)))]
- "
- {
- operands[2] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[3] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
- [(set_attr "length" "*,8,8,*")
- (set_attr "predicable" "no,yes,yes,no")
- (set_attr "type" "neon_move,multiple,multiple,neon_move")
- (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
-)
-
(define_expand "one_cmplsi2"
[(set (match_operand:SI 0 "s_register_operand")
(not:SI (match_operand:SI 1 "s_register_operand")))]
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index d4a4c5967aea09816485d77f9ab90020aa085e73..b76de81b85c8ce7a2ca484a750b908b7ca64600a 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -273,24 +273,6 @@ (define_constraint "Dd"
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, PLUS)")))
-(define_constraint "De"
- "@internal
- In ARM/Thumb-2 state a const_int that can be used by insn anddi."
- (and (match_code "const_int")
- (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)")))
-
-(define_constraint "Df"
- "@internal
- In ARM/Thumb-2 state a const_int that can be used by insn iordi."
- (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/iwmmxt.md b/gcc/config/arm/iwmmxt.md
index 310019aa5ceef98047b310284123f66940430095..86158ea4fd278180d5e2321c66c6c2b5e5c460b0 100644
--- a/gcc/config/arm/iwmmxt.md
+++ b/gcc/config/arm/iwmmxt.md
@@ -55,45 +55,36 @@ (define_insn "tbcstv2si"
)
(define_insn "iwmmxt_iordi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (ior:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ior:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wor%?\\t%0, %1, %2
- #
- #"
+ "wor%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wor,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wor")]
)
(define_insn "iwmmxt_xordi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (xor:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (xor:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wxor%?\\t%0, %1, %2
- #
- #"
+ "wxor%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wxor,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wxor")]
)
(define_insn "iwmmxt_anddi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (and:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (and:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wand%?\\t%0, %1, %2
- #
- #"
+ "wand%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wand,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wand")]
)
(define_insn "iwmmxt_nanddi3"
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 6333e0ea3ea68d73bed1f7c4d8ca090090ad68cc..ef73c77abeeaa02947c70ffa435f7bedc431e3be 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -838,46 +838,6 @@ (define_insn "orn<mode>3_neon"
[(set_attr "type" "neon_logic<q>")]
)
-;; TODO: investigate whether we should disable
-;; this and bicdi3_neon for the A8 in line with the other
-;; changes above.
-(define_insn_and_split "orndi3_neon"
- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
- (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
- (match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
- "TARGET_NEON"
- "@
- vorn\t%P0, %P1, %P2
- #
- #
- #"
- "reload_completed &&
- (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
- "
- {
- if (TARGET_THUMB2)
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- operands[5] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }
- else
- {
- emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
- emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
- DONE;
- }
- }"
- [(set_attr "type" "neon_logic,multiple,multiple,multiple")
- (set_attr "length" "*,16,8,8")
- (set_attr "arch" "any,a,t2,t2")]
-)
-
(define_insn "bic<mode>3_neon"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
@@ -887,20 +847,6 @@ (define_insn "bic<mode>3_neon"
[(set_attr "type" "neon_logic<q>")]
)
-;; Compare to *anddi_notdi_di.
-(define_insn "bicdi3_neon"
- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
- (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
- (match_operand:DI 1 "s_register_operand" "w,0,r")))]
- "TARGET_NEON"
- "@
- vbic\t%P0, %P1, %P2
- #
- #"
- [(set_attr "type" "neon_logic,multiple,multiple")
- (set_attr "length" "*,8,8")]
-)
-
(define_insn "xor<mode>3"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index f53378a250edfdd0de467f2abbe08bc933d6d734..af97edd28f27a1d8ab9ac2a63343380236d97603 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -201,23 +201,6 @@ (define_predicate "arm_add_operand"
(ior (match_operand 0 "arm_rhs_operand")
(match_operand 0 "arm_neg_immediate_operand")))
-(define_predicate "arm_anddi_operand_neon"
- (ior (match_operand 0 "s_register_operand")
- (and (match_code "const_int")
- (match_test "const_ok_for_dimode_op (INTVAL (op), AND)"))
- (match_operand 0 "neon_inv_logic_op2")))
-
-(define_predicate "arm_iordi_operand_neon"
- (ior (match_operand 0 "s_register_operand")
- (and (match_code "const_int")
- (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/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index b283a7b656526d3c4719860d10aa1c0550288ba3..78a6ea0b10dab97ed6651ce62e99cfd7a81722ab 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -1478,103 +1478,6 @@ (define_insn "*thumb2_negsi2_short"
(set_attr "type" "alu_sreg")]
)
-; Constants for op 2 will never be given to these patterns.
-(define_insn_and_split "*iordi_notdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
- (match_operand:DI 2 "s_register_operand" "r,0")))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (ior:SI (not: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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notzesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_THUMB2"
- "#"
- ; (not (zero_extend...)) means operand0 will always be 0xffffffff
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (const_int -1))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notdi_zesidi"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
- (zero_extend:DI
- (match_operand:SI 1 "s_register_operand" "r,r"))))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (not:SI (match_dup 4)))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[4] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notsesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (ior:SI (not:SI
- (ashiftrt:SI (match_dup 2) (const_int 31)))
- (match_dup 4)))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
(define_insn "*orsi_notsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][ARM] Cleanup logical DImode operations
2019-07-31 16:25 ` Wilco Dijkstra
@ 2019-08-19 16:12 ` Wilco Dijkstra
0 siblings, 0 replies; 6+ messages in thread
From: Wilco Dijkstra @ 2019-08-19 16:12 UTC (permalink / raw)
To: GCC Patches; +Cc: nd, Kyrylo Tkachov, Richard Earnshaw
ping
Cleanup the logical DImode operations since the current implementation is way
too complicated. Thumb-1, Thumb-2, VFP/Neon and iwMMXt all work differently,
resulting in a bewildering number of expansions, patterns and splits across
several md files. All this complexity is counterproductive and results in
inefficient code.
A much simpler approach is to split these operations early in the expander
so that optimizations and register allocation are applied on the 32-bit halves.
Code generation is unchanged on Thumb-1 and Arm/Thumb-2 without Neon or iwMMXt
(which already expand these instructions early). With Neon these changes save
~1000 instructions from the PR77308 testcase, mostly by significantly reducing
register pressure and spilling.
Bootstrap & regress OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57
OK for commit?
ChangeLog:
2019-07-18 Wilco Dijkstra <wdijkstr@arm.com>
* config/arm/arm.md (split and/eor/ior): Remove Neon check.
(split not): Add DImode not splitter.
(anddi3): Remove pattern.
(anddi3_insn): Likewise.
(anddi_zesidi_di): Likewise.
(anddi_sesdi_di): Likewise.
(anddi_notdi_di): Likewise.
(anddi_notzesidi_di): Likewise.
(anddi_notsesidi_di): Likewise.
(iordi3): Likewise.
(iordi3_insn): Likewise.
(iordi_zesidi_di): Likewise.
(iordi_sesidi_di): Likewise.
(xordi3): Likewise.
(xordi3_insn): Likewise.
(xordi_sesidi_di): Likewise.
(xordi_zesidi_di): Likewise.
(one_cmpldi2): Likewise.
(one_cmpldi2_insn): Likewise.
* config/arm/constraints.md: Remove De, Df, Dg constraints.
* config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register
alternative.
(iwmmxt_xordi3): Likewise.
(iwmmxt_anddi3): Likewise.
* config/arm/neon.md (orndi3_neon): Remove pattern.
(anddi_notdi_di): Likewise.
* config/arm/predicates.md (arm_anddi_operand_neon): Remove.
(arm_iordi_operand_neon): Likewise.
(arm_xordi_operand_neon): Likewise.
* config/arm/thumb2.md(iordi_notdi_di): Remove pattern.
(iordi_notzesidi_di): Likewise.
(iordi_notdi_zesidi): Likewise.
(iordi_notsesidi_di): Likewise.
---
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8f4a4c26ea849a023f2e63d2efbf327423512dfc..cab59c403b777c37c1e412ab9a69db2c2ec533a2 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2183,19 +2183,16 @@ (define_expand "divdf3"
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
"")
-;; Boolean and,ior,xor insns
-;; Split up double word logical operations
-
-;; Split up simple DImode logical operations. Simply perform the logical
+;; Split DImode and, ior, xor operations. Simply perform the logical
;; operation on the upper and lower halves of the registers.
+;; This is needed for atomic operations in arm_split_atomic_op.
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
(match_operator:DI 6 "logical_binary_operator"
[(match_operand:DI 1 "s_register_operand" "")
(match_operand:DI 2 "s_register_operand" "")]))]
"TARGET_32BIT && reload_completed
- && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
&& ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
[(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
(set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
@@ -2210,167 +2207,20 @@ (define_split
}"
)
+;; Split DImode not (needed for atomic operations in arm_split_atomic_op).
(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (match_operator:DI 6 "logical_binary_operator"
- [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")]))]
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
- (set (match_dup 3) (match_op_dup:SI 6
- [(ashiftrt:SI (match_dup 2) (const_int 31))
- (match_dup 4)]))]
- "
- {
- 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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
-;; The zero extend of operand 2 means we can just copy the high part of
-;; operand1 into operand0.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (ior:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
- [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
-)
-
-;; The zero extend of operand 2 means we can just copy the high part of
-;; operand1 into operand0.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (xor:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
- [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
-)
-
-(define_expand "anddi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (and:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "neon_inv_logic_op2")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (AND, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (AND, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*anddi3_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
- (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
- (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
- "TARGET_32BIT && !TARGET_IWMMXT"
-{
- switch (which_alternative)
- {
- case 0: /* fall through */
- case 6: return "vand\t%P0, %P1, %P2";
- case 1: /* fall through */
- case 7: return neon_output_logic_immediate ("vand", &operands[2],
- DImode, 1, VALID_NEON_QREG_MODE (DImode));
- case 2:
- case 3:
- case 4:
- case 5: /* fall through */
- return "#";
- 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 (AND, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- operands[6] = simplify_gen_binary (AND, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode, operands[2]));
-
- }"
- [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
- multiple,multiple,neon_logic,neon_logic")
- (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
- avoid_neon_for_64bits,avoid_neon_for_64bits")
- (set_attr "length" "*,*,8,8,8,8,*,*")
- ]
-)
-
-(define_insn_and_split "*anddi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
+ [(set (match_operand:DI 0 "s_register_operand")
+ (not:DI (match_operand:DI 1 "s_register_operand")))]
"TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- ; The zero extend of operand 2 clears the high word of the output
- ; operand.
- [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (const_int 0))]
+ [(set (match_dup 0) (not:SI (match_dup 1)))
+ (set (match_dup 2) (not:SI (match_dup 3)))]
"
{
- operands[3] = gen_highpart (SImode, operands[0]);
+ operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[3] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
}"
- [(set_attr "length" "8")
- (set_attr "type" "multiple")]
-)
-
-(define_insn "*anddi_sesdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "type" "multiple")]
)
(define_expand "andsi3"
@@ -2952,105 +2802,6 @@ (define_insn "insv_t2"
(set_attr "type" "bfm")]
)
-; constants for op 2 will never be given to these patterns.
-(define_insn_and_split "*anddi_notdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
- (match_operand:DI 2 "s_register_operand" "r,0")))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed
- && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
- && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (and:SI (not: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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notzesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- bic%?\\t%Q0, %Q1, %2
- #"
- ; (not (zero_extend ...)) allows us to just copy the high word from
- ; operand1 to operand0.
- "TARGET_32BIT
- && reload_completed
- && operands[0] != operands[1]"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notdi_zesidi"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
- (zero_extend:DI
- (match_operand:SI 1 "s_register_operand" "r"))))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (const_int 0))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*anddi_notsesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- "TARGET_32BIT && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (and:SI (not:SI
- (ashiftrt:SI (match_dup 2) (const_int 31)))
- (match_dup 4)))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_insn "andsi_notsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
@@ -3150,101 +2901,6 @@ (define_insn "*andsi_notsi_si_compare0_scratch"
(set_attr "type" "logics_shift_reg")]
)
-(define_expand "iordi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (ior:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "neon_logic_op2")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (IOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (IOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*iordi3_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
- (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
- (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
- "TARGET_32BIT && !TARGET_IWMMXT"
- {
- switch (which_alternative)
- {
- case 0: /* fall through */
- case 6: return "vorr\t%P0, %P1, %P2";
- case 1: /* fall through */
- case 7: return neon_output_logic_immediate ("vorr", &operands[2],
- DImode, 0, VALID_NEON_QREG_MODE (DImode));
- case 2:
- case 3:
- case 4:
- case 5:
- return "#";
- 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 (IOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- operands[6] = simplify_gen_binary (IOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode, operands[2]));
-
- }"
- [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
- multiple,neon_logic,neon_logic")
- (set_attr "length" "*,*,8,8,8,8,*,*")
- (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
-)
-
-(define_insn "*iordi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- orr%?\\t%Q0, %Q1, %2
- #"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "logic_reg,multiple")]
-)
-
-(define_insn "*iordi_sesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_expand "iorsi3"
[(set (match_operand:SI 0 "s_register_operand")
(ior:SI (match_operand:SI 1 "s_register_operand")
@@ -3347,103 +3003,6 @@ (define_insn "*iorsi3_compare0_scratch"
(set_attr "type" "logics_imm,logics_reg")]
)
-(define_expand "xordi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (xor:DI (match_operand:DI 1 "s_register_operand")
- (match_operand:DI 2 "arm_xordi_operand")))]
- "TARGET_32BIT"
- {
- /* The iWMMXt pattern for xordi3 accepts only register operands but we want
- to reuse this expander for all TARGET_32BIT targets so just force the
- constants into a register. Unlike for the anddi3 and iordi3 there are
- no NEON instructions that take an immediate. */
- if (TARGET_IWMMXT && !REG_P (operands[2]))
- operands[2] = force_reg (DImode, operands[2]);
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_binary (XOR, SImode,
- gen_lowpart (SImode, operands[1]),
- gen_lowpart (SImode, operands[2]));
- rtx high = simplify_gen_binary (XOR, SImode,
- gen_highpart (SImode, operands[1]),
- gen_highpart_mode (SImode, DImode,
- operands[2]));
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- }
-)
-
-(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 "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
- (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
-)
-
-(define_insn "*xordi_zesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_32BIT"
- "@
- eor%?\\t%Q0, %Q1, %2
- #"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "type" "logic_reg")]
-)
-
-(define_insn "*xordi_sesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (xor:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_32BIT"
- "#"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "type" "multiple")]
-)
-
(define_expand "xorsi3"
[(set (match_operand:SI 0 "s_register_operand")
(xor:SI (match_operand:SI 1 "s_register_operand")
@@ -5033,56 +4592,6 @@ (define_expand "sqrtdf2"
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
"")
-(define_expand "one_cmpldi2"
- [(set (match_operand:DI 0 "s_register_operand")
- (not:DI (match_operand:DI 1 "s_register_operand")))]
- "TARGET_32BIT"
- "
- if (!TARGET_NEON && !TARGET_IWMMXT)
- {
- rtx low = simplify_gen_unary (NOT, SImode,
- gen_lowpart (SImode, operands[1]),
- SImode);
- rtx high = simplify_gen_unary (NOT, SImode,
- gen_highpart_mode (SImode, DImode,
- operands[1]),
- SImode);
-
- emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
- emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
-
- DONE;
- }
- /* Otherwise expand pattern as above. */
- "
-)
-
-(define_insn_and_split "*one_cmpldi2_insn"
- [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
- (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
- "TARGET_32BIT"
- "@
- vmvn\t%P0, %P1
- #
- #
- vmvn\t%P0, %P1"
- "TARGET_32BIT && reload_completed
- && arm_general_register_operand (operands[0], DImode)"
- [(set (match_dup 0) (not:SI (match_dup 1)))
- (set (match_dup 2) (not:SI (match_dup 3)))]
- "
- {
- operands[2] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[3] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
- [(set_attr "length" "*,8,8,*")
- (set_attr "predicable" "no,yes,yes,no")
- (set_attr "type" "neon_move,multiple,multiple,neon_move")
- (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
-)
-
(define_expand "one_cmplsi2"
[(set (match_operand:SI 0 "s_register_operand")
(not:SI (match_operand:SI 1 "s_register_operand")))]
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index d4a4c5967aea09816485d77f9ab90020aa085e73..b76de81b85c8ce7a2ca484a750b908b7ca64600a 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -273,24 +273,6 @@ (define_constraint "Dd"
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, PLUS)")))
-(define_constraint "De"
- "@internal
- In ARM/Thumb-2 state a const_int that can be used by insn anddi."
- (and (match_code "const_int")
- (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)")))
-
-(define_constraint "Df"
- "@internal
- In ARM/Thumb-2 state a const_int that can be used by insn iordi."
- (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/iwmmxt.md b/gcc/config/arm/iwmmxt.md
index 310019aa5ceef98047b310284123f66940430095..86158ea4fd278180d5e2321c66c6c2b5e5c460b0 100644
--- a/gcc/config/arm/iwmmxt.md
+++ b/gcc/config/arm/iwmmxt.md
@@ -55,45 +55,36 @@ (define_insn "tbcstv2si"
)
(define_insn "iwmmxt_iordi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (ior:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ior:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wor%?\\t%0, %1, %2
- #
- #"
+ "wor%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wor,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wor")]
)
(define_insn "iwmmxt_xordi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (xor:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (xor:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wxor%?\\t%0, %1, %2
- #
- #"
+ "wxor%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wxor,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wxor")]
)
(define_insn "iwmmxt_anddi3"
- [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
- (and:DI (match_operand:DI 1 "register_operand" "%y,0,r")
- (match_operand:DI 2 "register_operand" "y,r,r")))]
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (and:DI (match_operand:DI 1 "register_operand" "%y")
+ (match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
- "@
- wand%?\\t%0, %1, %2
- #
- #"
+ "wand%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "4,8,8")
- (set_attr "type" "wmmx_wand,*,*")]
+ (set_attr "length" "4")
+ (set_attr "type" "wmmx_wand")]
)
(define_insn "iwmmxt_nanddi3"
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 6333e0ea3ea68d73bed1f7c4d8ca090090ad68cc..ef73c77abeeaa02947c70ffa435f7bedc431e3be 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -838,46 +838,6 @@ (define_insn "orn<mode>3_neon"
[(set_attr "type" "neon_logic<q>")]
)
-;; TODO: investigate whether we should disable
-;; this and bicdi3_neon for the A8 in line with the other
-;; changes above.
-(define_insn_and_split "orndi3_neon"
- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
- (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
- (match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
- "TARGET_NEON"
- "@
- vorn\t%P0, %P1, %P2
- #
- #
- #"
- "reload_completed &&
- (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
- "
- {
- if (TARGET_THUMB2)
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- operands[5] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }
- else
- {
- emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
- emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
- DONE;
- }
- }"
- [(set_attr "type" "neon_logic,multiple,multiple,multiple")
- (set_attr "length" "*,16,8,8")
- (set_attr "arch" "any,a,t2,t2")]
-)
-
(define_insn "bic<mode>3_neon"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
@@ -887,20 +847,6 @@ (define_insn "bic<mode>3_neon"
[(set_attr "type" "neon_logic<q>")]
)
-;; Compare to *anddi_notdi_di.
-(define_insn "bicdi3_neon"
- [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
- (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
- (match_operand:DI 1 "s_register_operand" "w,0,r")))]
- "TARGET_NEON"
- "@
- vbic\t%P0, %P1, %P2
- #
- #"
- [(set_attr "type" "neon_logic,multiple,multiple")
- (set_attr "length" "*,8,8")]
-)
-
(define_insn "xor<mode>3"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index f53378a250edfdd0de467f2abbe08bc933d6d734..af97edd28f27a1d8ab9ac2a63343380236d97603 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -201,23 +201,6 @@ (define_predicate "arm_add_operand"
(ior (match_operand 0 "arm_rhs_operand")
(match_operand 0 "arm_neg_immediate_operand")))
-(define_predicate "arm_anddi_operand_neon"
- (ior (match_operand 0 "s_register_operand")
- (and (match_code "const_int")
- (match_test "const_ok_for_dimode_op (INTVAL (op), AND)"))
- (match_operand 0 "neon_inv_logic_op2")))
-
-(define_predicate "arm_iordi_operand_neon"
- (ior (match_operand 0 "s_register_operand")
- (and (match_code "const_int")
- (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/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index b283a7b656526d3c4719860d10aa1c0550288ba3..78a6ea0b10dab97ed6651ce62e99cfd7a81722ab 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -1478,103 +1478,6 @@ (define_insn "*thumb2_negsi2_short"
(set_attr "type" "alu_sreg")]
)
-; Constants for op 2 will never be given to these patterns.
-(define_insn_and_split "*iordi_notdi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
- (match_operand:DI 2 "s_register_operand" "r,0")))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (ior:SI (not: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]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notzesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,?r")))]
- "TARGET_THUMB2"
- "#"
- ; (not (zero_extend...)) means operand0 will always be 0xffffffff
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (const_int -1))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
- [(set_attr "length" "4,8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notdi_zesidi"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
- (zero_extend:DI
- (match_operand:SI 1 "s_register_operand" "r,r"))))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (not:SI (match_dup 4)))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[4] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
-(define_insn_and_split "*iordi_notsesidi_di"
- [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (ior:DI (not:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "r,r")))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
- "TARGET_THUMB2"
- "#"
- "TARGET_THUMB2 && reload_completed"
- [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
- (set (match_dup 3) (ior:SI (not:SI
- (ashiftrt:SI (match_dup 2) (const_int 31)))
- (match_dup 4)))]
- "
- {
- 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]);
- }"
- [(set_attr "length" "8")
- (set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")
- (set_attr "type" "multiple")]
-)
-
(define_insn "*orsi_notsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][ARM] Cleanup logical DImode operations
2019-07-19 11:35 [PATCH][ARM] Cleanup logical DImode operations Wilco Dijkstra
2019-07-31 16:25 ` Wilco Dijkstra
@ 2019-08-22 13:35 ` Kyrill Tkachov
2019-08-26 11:03 ` Christophe Lyon
1 sibling, 1 reply; 6+ messages in thread
From: Kyrill Tkachov @ 2019-08-22 13:35 UTC (permalink / raw)
To: Wilco Dijkstra, GCC Patches; +Cc: nd, Richard Earnshaw
Hi Wilco,
On 7/19/19 12:30 PM, Wilco Dijkstra wrote:
>
> Cleanup the logical DImode operations since the current implementation
> is way
> too complicated. Thumb-1, Thumb-2, VFP/Neon and iwMMXt all work
> differently,
> resulting in a bewildering number of expansions, patterns and splits
> across
> several md files. All this complexity is counterproductive and results in
> inefficient code.
>
> A much simpler approach is to split these operations early in the expander
> so that optimizations and register allocation are applied on the
> 32-bit halves.
> Code generation is unchanged on Thumb-1 and Arm/Thumb-2 without Neon
> or iwMMXt
> (which already expand these instructions early). With Neon these
> changes save
> ~1000 instructions from the PR77308 testcase, mostly by significantly
> reducing
> register pressure and spilling.
>
> Bootstrap & regress OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57
>
> OK for commit?
Ok. Thanks for doing this.
Please keep an eye out for fallout after committing.
Kyrill
>
> ChangeLog:
> 2019-07-18 Wilco Dijkstra <wdijkstr@arm.com>
>
> * config/arm/arm.md (split and/eor/ior): Remove Neon check.
> (split not): Add DImode not splitter.
> (anddi3): Remove pattern.
> (anddi3_insn): Likewise.
> (anddi_zesidi_di): Likewise.
> (anddi_sesdi_di): Likewise.
> (anddi_notdi_di): Likewise.
> (anddi_notzesidi_di): Likewise.
> (anddi_notsesidi_di): Likewise.
> (iordi3): Likewise.
> (iordi3_insn): Likewise.
> (iordi_zesidi_di): Likewise.
> (iordi_sesidi_di): Likewise.
> (xordi3): Likewise.
> (xordi3_insn): Likewise.
> (xordi_sesidi_di): Likewise.
> (xordi_zesidi_di): Likewise.
> (one_cmpldi2): Likewise.
> (one_cmpldi2_insn): Likewise.
> * config/arm/constraints.md: Remove De, Df, Dg constraints.
> * config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register
> alternative.
> (iwmmxt_xordi3): Likewise.
> (iwmmxt_anddi3): Likewise.
> * config/arm/neon.md (orndi3_neon): Remove pattern.
> (anddi_notdi_di): Likewise.
> * config/arm/predicates.md (arm_anddi_operand_neon): Remove.
> (arm_iordi_operand_neon): Likewise.
> (arm_xordi_operand_neon): Likewise.
> * config/arm/thumb2.md(iordi_notdi_di): Remove pattern.
> (iordi_notzesidi_di): Likewise.
> (iordi_notdi_zesidi): Likewise.
> (iordi_notsesidi_di): Likewise.
>
>
> ---
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index
> 8f4a4c26ea849a023f2e63d2efbf327423512dfc..cab59c403b777c37c1e412ab9a69db2c2ec533a2
> 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -2183,19 +2183,16 @@ (define_expand "divdf3"
> Â Â "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
> Â Â "")
>
> -;; Boolean and,ior,xor insns
>
> -;; Split up double word logical operations
> -
> -;; Split up simple DImode logical operations. Simply perform the logical
> +;; Split DImode and, ior, xor operations. Simply perform the logical
> Â ;; operation on the upper and lower halves of the registers.
> +;; This is needed for atomic operations in arm_split_atomic_op.
> Â (define_split
> Â Â [(set (match_operand:DI 0 "s_register_operand" "")
> Â (match_operator:DI 6 "logical_binary_operator"
> Â Â [(match_operand:DI 1 "s_register_operand" "")
> Â Â Â (match_operand:DI 2 "s_register_operand" "")]))]
> Â Â "TARGET_32BIT && reload_completed
> -Â Â && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
> Â Â Â && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
> Â Â [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
> Â Â Â (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
> @@ -2210,167 +2207,20 @@ (define_split
> Â Â }"
> Â )
>
> +;; Split DImode not (needed for atomic operations in
> arm_split_atomic_op).
> Â (define_split
> -Â [(set (match_operand:DI 0 "s_register_operand" "")
> -(match_operator:DI 6 "logical_binary_operator"
> -Â [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
> -Â Â (match_operand:DI 1 "s_register_operand" "")]))]
> -Â "TARGET_32BIT && reload_completed"
> -Â [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
> -Â Â (set (match_dup 3) (match_op_dup:SI 6
> -[(ashiftrt:SI (match_dup 2) (const_int 31))
> - (match_dup 4)]))]
> -Â "
> -Â {
> -Â Â Â 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]);
> -Â Â Â operands[5] = gen_highpart (SImode, operands[2]);
> -Â Â Â operands[2] = gen_lowpart (SImode, operands[2]);
> -Â }"
> -)
> -
> -;; The zero extend of operand 2 means we can just copy the high part of
> -;; operand1 into operand0.
> -(define_split
> -Â [(set (match_operand:DI 0 "s_register_operand" "")
> -(ior:DI
> -Â (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
> -Â (match_operand:DI 1 "s_register_operand" "")))]
> -Â "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
> -Â [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
> -Â Â (set (match_dup 3) (match_dup 4))]
> -Â "
> -Â {
> -Â Â Â operands[4] = gen_highpart (SImode, operands[1]);
> -Â Â Â operands[3] = gen_highpart (SImode, operands[0]);
> -Â Â Â operands[0] = gen_lowpart (SImode, operands[0]);
> -Â Â Â operands[1] = gen_lowpart (SImode, operands[1]);
> -Â }"
> -)
> -
> -;; The zero extend of operand 2 means we can just copy the high part of
> -;; operand1 into operand0.
> -(define_split
> -Â [(set (match_operand:DI 0 "s_register_operand" "")
> -(xor:DI
> -Â (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
> -Â (match_operand:DI 1 "s_register_operand" "")))]
> -Â "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
> -Â [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
> -Â Â (set (match_dup 3) (match_dup 4))]
> -Â "
> -Â {
> -Â Â Â operands[4] = gen_highpart (SImode, operands[1]);
> -Â Â Â operands[3] = gen_highpart (SImode, operands[0]);
> -Â Â Â operands[0] = gen_lowpart (SImode, operands[0]);
> -Â Â Â operands[1] = gen_lowpart (SImode, operands[1]);
> -Â }"
> -)
> -
> -(define_expand "anddi3"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "s_register_operand")
> -(and:DI (match_operand:DI 1 "s_register_operand")
> -(match_operand:DI 2 "neon_inv_logic_op2")))]
> -Â "TARGET_32BIT"
> -Â "
> -Â if (!TARGET_NEON && !TARGET_IWMMXT)
> -Â Â Â {
> -     rtx low = simplify_gen_binary (AND, SImode,
> -Â Â Â Â Â gen_lowpart (SImode, operands[1]),
> -Â Â Â Â Â gen_lowpart (SImode, operands[2]));
> -Â Â Â Â Â rtx high = simplify_gen_binary (AND, SImode,
> -Â Â Â Â Â gen_highpart (SImode, operands[1]),
> -Â Â Â Â Â gen_highpart_mode (SImode, DImode,
> - operands[2]));
> -
> -Â Â Â Â Â emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
> -Â Â Â Â Â emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
> -
> -Â Â Â Â Â DONE;
> -Â Â Â }
> - /* Otherwise expand pattern as above. */
> -Â "
> -)
> -
> -(define_insn_and_split "*anddi3_insn"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "s_register_operand"Â Â Â Â "=w,w
> ,&r,&r,&r,&r,?w,?w")
> -Â Â Â Â Â Â Â (and:DI (match_operand:DI 1 "s_register_operand"Â Â Â Â "%w,0 ,0
> ,r ,0 ,r ,w ,0")
> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r
> ,r ,De,De,w ,DL")))]
> -Â "TARGET_32BIT && !TARGET_IWMMXT"
> -{
> -Â switch (which_alternative)
> -Â Â Â {
> -Â Â Â case 0: /* fall through */
> -Â Â Â case 6: return "vand\t%P0, %P1, %P2";
> -Â Â Â case 1: /* fall through */
> -Â Â Â case 7: return neon_output_logic_immediate ("vand", &operands[2],
> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â DImode, 1, VALID_NEON_QREG_MODE (DImode));
> -Â Â Â case 2:
> -Â Â Â case 3:
> -Â Â Â case 4:
> -Â Â Â case 5: /* fall through */
> -Â Â Â Â Â return "#";
> -Â Â Â 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 (AND, SImode,
> - gen_lowpart (SImode, operands[1]),
> - gen_lowpart (SImode, operands[2]));
> -Â Â Â operands[6] = simplify_gen_binary (AND, SImode,
> - gen_highpart (SImode, operands[1]),
> - gen_highpart_mode (SImode, DImode, operands[2]));
> -
> -Â }"
> -Â [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
> - multiple,multiple,neon_logic,neon_logic")
> -Â Â (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
> - avoid_neon_for_64bits,avoid_neon_for_64bits")
> -Â Â (set_attr "length" "*,*,8,8,8,8,*,*")
> -Â ]
> -)
> -
> -(define_insn_and_split "*anddi_zesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(and:DI (zero_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r"))
> -(match_operand:DI 1 "s_register_operand" "0,r")))]
> +Â [(set (match_operand:DI 0 "s_register_operand")
> +(not:DI (match_operand:DI 1 "s_register_operand")))]
> Â Â "TARGET_32BIT"
> -Â "#"
> -Â "TARGET_32BIT && reload_completed"
> -Â ; The zero extend of operand 2 clears the high word of the output
> -Â ; operand.
> -Â [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
> -Â Â (set (match_dup 3) (const_int 0))]
> +Â [(set (match_dup 0) (not:SI (match_dup 1)))
> +Â Â (set (match_dup 2) (not:SI (match_dup 3)))]
> Â Â "
> Â Â {
> -Â Â Â operands[3] = gen_highpart (SImode, operands[0]);
> +Â Â Â operands[2] = gen_highpart (SImode, operands[0]);
> Â Â Â Â operands[0] = gen_lowpart (SImode, operands[0]);
> +Â Â Â operands[3] = gen_highpart (SImode, operands[1]);
> Â Â Â Â operands[1] = gen_lowpart (SImode, operands[1]);
> Â Â }"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> -(define_insn "*anddi_sesdi_di"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â Â 0 "s_register_operand" "=&r,&r")
> -(and:DI (sign_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r"))
> -(match_operand:DIÂ 1 "s_register_operand" "0,r")))]
> -Â "TARGET_32BIT"
> -Â "#"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "type" "multiple")]
> Â )
>
> Â (define_expand "andsi3"
> @@ -2952,105 +2802,6 @@ (define_insn "insv_t2"
> Â Â Â (set_attr "type" "bfm")]
> Â )
>
> -; constants for op 2 will never be given to these patterns.
> -(define_insn_and_split "*anddi_notdi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
> -(match_operand:DI 2 "s_register_operand" "r,0")))]
> -Â "TARGET_32BIT"
> -Â "#"
> -Â "TARGET_32BIT && reload_completed
> -Â Â && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
> -Â Â && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
> -Â [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
> -Â Â (set (match_dup 3) (and:SI (not: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]);
> -Â Â Â operands[5] = gen_highpart (SImode, operands[2]);
> -Â Â Â operands[2] = gen_lowpart (SImode, operands[2]);
> -Â }"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> -(define_insn_and_split "*anddi_notzesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(and:DI (not:DI (zero_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r")))
> -(match_operand:DI 1 "s_register_operand" "0,?r")))]
> -Â "TARGET_32BIT"
> -Â "@
> -Â Â bic%?\\t%Q0, %Q1, %2
> -Â Â #"
> -Â ; (not (zero_extend ...)) allows us to just copy the high word from
> -Â ; operand1 to operand0.
> -Â "TARGET_32BIT
> -Â Â && reload_completed
> -Â Â && operands[0] != operands[1]"
> -Â [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
> -Â Â (set (match_dup 3) (match_dup 4))]
> -Â "
> -Â {
> -Â Â Â 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]);
> -Â }"
> -Â [(set_attr "length" "4,8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> -(define_insn_and_split "*anddi_notdi_zesidi"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=r")
> -Â Â Â Â Â Â Â (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (zero_extend:DI
> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (match_operand:SI 1 "s_register_operand" "r"))))]
> -Â "TARGET_32BIT"
> -Â "#"
> -Â "TARGET_32BIT && reload_completed"
> -Â [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
> -Â Â (set (match_dup 3) (const_int 0))]
> -Â "
> -Â {
> -Â Â Â operands[3] = gen_highpart (SImode, operands[0]);
> -Â Â Â operands[0] = gen_lowpart (SImode, operands[0]);
> -Â Â Â operands[2] = gen_lowpart (SImode, operands[2]);
> -Â }"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> -(define_insn_and_split "*anddi_notsesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(and:DI (not:DI (sign_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r")))
> -(match_operand:DI 1 "s_register_operand" "0,r")))]
> -Â "TARGET_32BIT"
> -Â "#"
> -Â "TARGET_32BIT && reload_completed"
> -Â [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
> -Â Â (set (match_dup 3) (and:SI (not:SI
> -(ashiftrt:SI (match_dup 2) (const_int 31)))
> -Â Â Â Â Â Â (match_dup 4)))]
> -Â "
> -Â {
> -Â Â Â 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]);
> -Â }"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> Â (define_insn "andsi_notsi_si"
> Â Â [(set (match_operand:SI 0 "s_register_operand" "=r")
> Â (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
> @@ -3150,101 +2901,6 @@ (define_insn "*andsi_notsi_si_compare0_scratch"
> Â Â Â (set_attr "type" "logics_shift_reg")]
> Â )
>
> -(define_expand "iordi3"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "s_register_operand")
> -(ior:DI (match_operand:DI 1 "s_register_operand")
> -(match_operand:DI 2 "neon_logic_op2")))]
> -Â "TARGET_32BIT"
> -Â "
> -Â if (!TARGET_NEON && !TARGET_IWMMXT)
> -Â Â Â {
> -     rtx low = simplify_gen_binary (IOR, SImode,
> -Â Â Â Â Â gen_lowpart (SImode, operands[1]),
> -Â Â Â Â Â gen_lowpart (SImode, operands[2]));
> -Â Â Â Â Â rtx high = simplify_gen_binary (IOR, SImode,
> -Â Â Â Â Â gen_highpart (SImode, operands[1]),
> -Â Â Â Â Â gen_highpart_mode (SImode, DImode,
> - operands[2]));
> -
> -Â Â Â Â Â emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
> -Â Â Â Â Â emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
> -
> -Â Â Â Â Â DONE;
> -Â Â Â }
> - /* Otherwise expand pattern as above. */
> -Â "
> -)
> -
> -(define_insn_and_split "*iordi3_insn"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "s_register_operand"Â Â Â Â "=w,w
> ,&r,&r,&r,&r,?w,?w")
> -(ior:DI (match_operand:DI 1 "s_register_operand"Â Â Â Â "%w,0 ,0 ,r ,0
> ,r ,w ,0")
> -(match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w
> ,Dl")))]
> -Â "TARGET_32BIT && !TARGET_IWMMXT"
> -Â {
> -Â switch (which_alternative)
> -Â Â Â {
> -Â Â Â case 0: /* fall through */
> -Â Â Â case 6: return "vorr\t%P0, %P1, %P2";
> -Â Â Â case 1: /* fall through */
> -Â Â Â case 7: return neon_output_logic_immediate ("vorr", &operands[2],
> -Â Â Â Â DImode, 0, VALID_NEON_QREG_MODE (DImode));
> -Â Â Â case 2:
> -Â Â Â case 3:
> -Â Â Â case 4:
> -Â Â Â case 5:
> -Â Â Â Â Â return "#";
> -Â Â Â 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 (IOR, SImode,
> - gen_lowpart (SImode, operands[1]),
> - gen_lowpart (SImode, operands[2]));
> -Â Â Â operands[6] = simplify_gen_binary (IOR, SImode,
> - gen_highpart (SImode, operands[1]),
> - gen_highpart_mode (SImode, DImode, operands[2]));
> -
> -Â }"
> -Â [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
> - multiple,neon_logic,neon_logic")
> -Â Â (set_attr "length" "*,*,8,8,8,8,*,*")
> -Â Â (set_attr "arch"
> "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
> -)
> -
> -(define_insn "*iordi_zesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(ior:DI (zero_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r"))
> -(match_operand:DI 1 "s_register_operand" "0,?r")))]
> -Â "TARGET_32BIT"
> -Â "@
> -Â Â orr%?\\t%Q0, %Q1, %2
> -Â Â #"
> -Â [(set_attr "length" "4,8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "type" "logic_reg,multiple")]
> -)
> -
> -(define_insn "*iordi_sesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(ior:DI (sign_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r"))
> -(match_operand:DI 1 "s_register_operand" "0,r")))]
> -Â "TARGET_32BIT"
> -Â "#"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> Â (define_expand "iorsi3"
> Â Â [(set (match_operand:SIÂ Â Â Â Â Â Â Â 0 "s_register_operand")
> Â (ior:SI (match_operand:SI 1 "s_register_operand")
> @@ -3347,103 +3003,6 @@ (define_insn "*iorsi3_compare0_scratch"
> Â Â Â (set_attr "type" "logics_imm,logics_reg")]
> Â )
>
> -(define_expand "xordi3"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "s_register_operand")
> -(xor:DI (match_operand:DI 1 "s_register_operand")
> -(match_operand:DI 2 "arm_xordi_operand")))]
> -Â "TARGET_32BIT"
> -Â {
> -Â Â Â /* The iWMMXt pattern for xordi3 accepts only register operands
> but we want
> -Â Â Â Â Â Â to reuse this expander for all TARGET_32BIT targets so just
> force the
> -      constants into a register. Unlike for the anddi3 and iordi3
> there are
> -      no NEON instructions that take an immediate. */
> -Â Â Â if (TARGET_IWMMXT && !REG_P (operands[2]))
> -Â Â Â Â Â operands[2] = force_reg (DImode, operands[2]);
> -Â Â Â if (!TARGET_NEON && !TARGET_IWMMXT)
> -Â Â Â Â Â {
> -rtx low = simplify_gen_binary (XOR, SImode,
> -gen_lowpart (SImode, operands[1]),
> -gen_lowpart (SImode, operands[2]));
> -rtx high = simplify_gen_binary (XOR, SImode,
> -gen_highpart (SImode, operands[1]),
> -gen_highpart_mode (SImode, DImode,
> -Â Â operands[2]));
> -
> -emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
> -emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
> -
> -DONE;
> -Â Â Â Â Â }
> -   /* Otherwise expand pattern as above. */
> -Â }
> -)
> -
> -(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 "type"
> "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
> -Â Â (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
> -)
> -
> -(define_insn "*xordi_zesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(xor:DI (zero_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r"))
> -(match_operand:DI 1 "s_register_operand" "0,?r")))]
> -Â "TARGET_32BIT"
> -Â "@
> -Â Â eor%?\\t%Q0, %Q1, %2
> -Â Â #"
> -Â [(set_attr "length" "4,8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "type" "logic_reg")]
> -)
> -
> -(define_insn "*xordi_sesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(xor:DI (sign_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r"))
> -(match_operand:DI 1 "s_register_operand" "0,r")))]
> -Â "TARGET_32BIT"
> -Â "#"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> Â (define_expand "xorsi3"
> Â Â [(set (match_operand:SIÂ Â Â Â Â Â Â Â 0 "s_register_operand")
> Â (xor:SI (match_operand:SI 1 "s_register_operand")
> @@ -5033,56 +4592,6 @@ (define_expand "sqrtdf2"
> Â Â "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
> Â Â "")
>
> -(define_expand "one_cmpldi2"
> -Â [(set (match_operand:DI 0 "s_register_operand")
> -(not:DI (match_operand:DI 1 "s_register_operand")))]
> -Â "TARGET_32BIT"
> -Â "
> -Â if (!TARGET_NEON && !TARGET_IWMMXT)
> -Â Â Â {
> -     rtx low = simplify_gen_unary (NOT, SImode,
> -Â Â Â Â gen_lowpart (SImode, operands[1]),
> -Â Â Â Â SImode);
> -Â Â Â Â Â rtx high = simplify_gen_unary (NOT, SImode,
> -Â Â Â Â gen_highpart_mode (SImode, DImode,
> -operands[1]),
> -Â Â Â Â SImode);
> -
> -Â Â Â Â Â emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
> -Â Â Â Â Â emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
> -
> -Â Â Â Â Â DONE;
> -Â Â Â }
> - /* Otherwise expand pattern as above. */
> -Â "
> -)
> -
> -(define_insn_and_split "*one_cmpldi2_insn"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
> -(not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
> -Â "TARGET_32BIT"
> -Â "@
> -Â Â vmvn\t%P0, %P1
> -Â Â #
> -Â Â #
> -Â Â vmvn\t%P0, %P1"
> -Â "TARGET_32BIT && reload_completed
> -Â Â && arm_general_register_operand (operands[0], DImode)"
> -Â [(set (match_dup 0) (not:SI (match_dup 1)))
> -Â Â (set (match_dup 2) (not:SI (match_dup 3)))]
> -Â "
> -Â {
> -Â Â Â operands[2] = gen_highpart (SImode, operands[0]);
> -Â Â Â operands[0] = gen_lowpart (SImode, operands[0]);
> -Â Â Â operands[3] = gen_highpart (SImode, operands[1]);
> -Â Â Â operands[1] = gen_lowpart (SImode, operands[1]);
> -Â }"
> -Â [(set_attr "length" "*,8,8,*")
> -Â Â (set_attr "predicable" "no,yes,yes,no")
> -Â Â (set_attr "type" "neon_move,multiple,multiple,neon_move")
> -Â Â (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
> -)
> -
> Â (define_expand "one_cmplsi2"
> Â Â [(set (match_operand:SIÂ Â Â Â Â Â Â Â 0 "s_register_operand")
> Â (not:SI (match_operand:SI 1 "s_register_operand")))]
> diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
> index
> d4a4c5967aea09816485d77f9ab90020aa085e73..b76de81b85c8ce7a2ca484a750b908b7ca64600a
> 100644
> --- a/gcc/config/arm/constraints.md
> +++ b/gcc/config/arm/constraints.md
> @@ -273,24 +273,6 @@ (define_constraint "Dd"
> Â (and (match_code "const_int")
> Â Â Â Â Â Â (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival,
> PLUS)")))
>
> -(define_constraint "De"
> - "@internal
> -Â In ARM/Thumb-2 state a const_int that can be used by insn anddi."
> - (and (match_code "const_int")
> -Â Â Â Â Â (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)")))
> -
> -(define_constraint "Df"
> - "@internal
> -Â In ARM/Thumb-2 state a const_int that can be used by insn iordi."
> - (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/iwmmxt.md b/gcc/config/arm/iwmmxt.md
> index
> 310019aa5ceef98047b310284123f66940430095..86158ea4fd278180d5e2321c66c6c2b5e5c460b0
> 100644
> --- a/gcc/config/arm/iwmmxt.md
> +++ b/gcc/config/arm/iwmmxt.md
> @@ -55,45 +55,36 @@ (define_insn "tbcstv2si"
> Â )
>
> Â (define_insn "iwmmxt_iordi3"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "register_operand" "=y,?&r,?&r")
> -Â Â Â Â Â Â Â (ior:DI (match_operand:DI 1 "register_operand" "%y,0,r")
> -(match_operand:DI 2 "register_operand"Â "y,r,r")))]
> +Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "register_operand" "=y")
> +Â Â Â Â Â Â Â (ior:DI (match_operand:DI 1 "register_operand" "%y")
> +(match_operand:DI 2 "register_operand"Â "y")))]
> Â Â "TARGET_REALLY_IWMMXT"
> -Â "@
> -Â Â wor%?\\t%0, %1, %2
> -Â Â #
> -Â Â #"
> +Â "wor%?\\t%0, %1, %2"
> Â Â [(set_attr "predicable" "yes")
> -Â Â (set_attr "length" "4,8,8")
> -Â Â (set_attr "type" "wmmx_wor,*,*")]
> +Â Â (set_attr "length" "4")
> +Â Â (set_attr "type" "wmmx_wor")]
> Â )
>
> Â (define_insn "iwmmxt_xordi3"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "register_operand" "=y,?&r,?&r")
> -Â Â Â Â Â Â Â (xor:DI (match_operand:DI 1 "register_operand" "%y,0,r")
> -(match_operand:DI 2 "register_operand"Â "y,r,r")))]
> +Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "register_operand" "=y")
> +Â Â Â Â Â Â Â (xor:DI (match_operand:DI 1 "register_operand" "%y")
> +(match_operand:DI 2 "register_operand"Â "y")))]
> Â Â "TARGET_REALLY_IWMMXT"
> -Â "@
> -Â Â wxor%?\\t%0, %1, %2
> -Â Â #
> -Â Â #"
> +Â "wxor%?\\t%0, %1, %2"
> Â Â [(set_attr "predicable" "yes")
> -Â Â (set_attr "length" "4,8,8")
> -Â Â (set_attr "type" "wmmx_wxor,*,*")]
> +Â Â (set_attr "length" "4")
> +Â Â (set_attr "type" "wmmx_wxor")]
> Â )
>
> Â (define_insn "iwmmxt_anddi3"
> -Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "register_operand" "=y,?&r,?&r")
> -Â Â Â Â Â Â Â (and:DI (match_operand:DI 1 "register_operand" "%y,0,r")
> -(match_operand:DI 2 "register_operand"Â "y,r,r")))]
> +Â [(set (match_operand:DIÂ Â Â Â Â Â Â Â 0 "register_operand" "=y")
> +Â Â Â Â Â Â Â (and:DI (match_operand:DI 1 "register_operand" "%y")
> +(match_operand:DI 2 "register_operand"Â "y")))]
> Â Â "TARGET_REALLY_IWMMXT"
> -Â "@
> -Â Â wand%?\\t%0, %1, %2
> -Â Â #
> -Â Â #"
> +Â "wand%?\\t%0, %1, %2"
> Â Â [(set_attr "predicable" "yes")
> -Â Â (set_attr "length" "4,8,8")
> -Â Â (set_attr "type" "wmmx_wand,*,*")]
> +Â Â (set_attr "length" "4")
> +Â Â (set_attr "type" "wmmx_wand")]
> Â )
>
> Â (define_insn "iwmmxt_nanddi3"
> diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
> index
> 6333e0ea3ea68d73bed1f7c4d8ca090090ad68cc..ef73c77abeeaa02947c70ffa435f7bedc431e3be
> 100644
> --- a/gcc/config/arm/neon.md
> +++ b/gcc/config/arm/neon.md
> @@ -838,46 +838,6 @@ (define_insn "orn<mode>3_neon"
> Â Â [(set_attr "type" "neon_logic<q>")]
> Â )
>
> -;; TODO: investigate whether we should disable
> -;; this and bicdi3_neon for the A8 in line with the other
> -;; changes above.
> -(define_insn_and_split "orndi3_neon"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
> -(ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
> -(match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
> -Â "TARGET_NEON"
> -Â "@
> -Â Â vorn\t%P0, %P1, %P2
> -Â Â #
> -Â Â #
> -Â Â #"
> -Â "reload_completed &&
> -Â Â (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
> -Â [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
> -Â Â (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
> -Â "
> -Â {
> -Â Â Â if (TARGET_THUMB2)
> -Â Â Â Â Â {
> -Â Â Â Â Â Â Â operands[3] = gen_highpart (SImode, operands[0]);
> -Â Â Â Â Â Â Â operands[0] = gen_lowpart (SImode, operands[0]);
> -Â Â Â Â Â Â Â operands[4] = gen_highpart (SImode, operands[2]);
> -Â Â Â Â Â Â Â operands[2] = gen_lowpart (SImode, operands[2]);
> -Â Â Â Â Â Â Â operands[5] = gen_highpart (SImode, operands[1]);
> -Â Â Â Â Â Â Â operands[1] = gen_lowpart (SImode, operands[1]);
> -Â Â Â Â Â }
> -Â Â Â else
> -Â Â Â Â Â {
> -Â Â Â Â Â Â Â emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
> -Â Â Â Â Â Â Â emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
> -Â Â Â Â Â Â Â DONE;
> -Â Â Â Â Â }
> -Â }"
> -Â [(set_attr "type" "neon_logic,multiple,multiple,multiple")
> -Â Â (set_attr "length" "*,16,8,8")
> -Â Â (set_attr "arch" "any,a,t2,t2")]
> -)
> -
> Â (define_insn "bic<mode>3_neon"
> Â Â [(set (match_operand:VDQ 0 "s_register_operand" "=w")
> Â (and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
> @@ -887,20 +847,6 @@ (define_insn "bic<mode>3_neon"
> Â Â [(set_attr "type" "neon_logic<q>")]
> Â )
>
> -;; Compare to *anddi_notdi_di.
> -(define_insn "bicdi3_neon"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
> -Â Â Â Â Â Â Â (and:DI (not:DI (match_operand:DI 2 "s_register_operand"
> "w,r,0"))
> -(match_operand:DI 1 "s_register_operand" "w,0,r")))]
> -Â "TARGET_NEON"
> -Â "@
> -Â Â vbic\t%P0, %P1, %P2
> -Â Â #
> -Â Â #"
> -Â [(set_attr "type" "neon_logic,multiple,multiple")
> -Â Â (set_attr "length" "*,8,8")]
> -)
> -
> Â (define_insn "xor<mode>3"
> Â Â [(set (match_operand:VDQ 0 "s_register_operand" "=w")
> Â (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
> diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
> index
> f53378a250edfdd0de467f2abbe08bc933d6d734..af97edd28f27a1d8ab9ac2a63343380236d97603
> 100644
> --- a/gcc/config/arm/predicates.md
> +++ b/gcc/config/arm/predicates.md
> @@ -201,23 +201,6 @@ (define_predicate "arm_add_operand"
> Â Â (ior (match_operand 0 "arm_rhs_operand")
> Â Â Â Â Â Â Â (match_operand 0 "arm_neg_immediate_operand")))
>
> -(define_predicate "arm_anddi_operand_neon"
> -Â (ior (match_operand 0 "s_register_operand")
> -Â Â Â Â Â Â (and (match_code "const_int")
> -Â Â Â (match_test "const_ok_for_dimode_op (INTVAL (op), AND)"))
> -Â Â Â Â Â Â (match_operand 0 "neon_inv_logic_op2")))
> -
> -(define_predicate "arm_iordi_operand_neon"
> -Â (ior (match_operand 0 "s_register_operand")
> -Â Â Â Â Â Â (and (match_code "const_int")
> -Â Â Â (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/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
> index
> b283a7b656526d3c4719860d10aa1c0550288ba3..78a6ea0b10dab97ed6651ce62e99cfd7a81722ab
> 100644
> --- a/gcc/config/arm/thumb2.md
> +++ b/gcc/config/arm/thumb2.md
> @@ -1478,103 +1478,6 @@ (define_insn "*thumb2_negsi2_short"
> Â Â Â (set_attr "type" "alu_sreg")]
> Â )
>
> -; Constants for op 2 will never be given to these patterns.
> -(define_insn_and_split "*iordi_notdi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(ior:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
> -(match_operand:DI 2 "s_register_operand" "r,0")))]
> -Â "TARGET_THUMB2"
> -Â "#"
> -Â "TARGET_THUMB2 && reload_completed"
> -Â [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2)))
> -Â Â (set (match_dup 3) (ior:SI (not: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]);
> -Â Â Â operands[5] = gen_highpart (SImode, operands[2]);
> -Â Â Â operands[2] = gen_lowpart (SImode, operands[2]);
> -Â }"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "predicable_short_it" "no")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> -(define_insn_and_split "*iordi_notzesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(ior:DI (not:DI (zero_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r")))
> -(match_operand:DI 1 "s_register_operand" "0,?r")))]
> -Â "TARGET_THUMB2"
> -Â "#"
> -Â ; (not (zero_extend...)) means operand0 will always be 0xffffffff
> -Â "TARGET_THUMB2 && reload_completed"
> -Â [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
> -Â Â (set (match_dup 3) (const_int -1))]
> -Â "
> -Â {
> -Â Â Â operands[3] = gen_highpart (SImode, operands[0]);
> -Â Â Â operands[0] = gen_lowpart (SImode, operands[0]);
> -Â Â Â operands[1] = gen_lowpart (SImode, operands[1]);
> -Â }"
> -Â [(set_attr "length" "4,8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "predicable_short_it" "no")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> -(define_insn_and_split "*iordi_notdi_zesidi"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
> -(zero_extend:DI
> - (match_operand:SI 1 "s_register_operand" "r,r"))))]
> -Â "TARGET_THUMB2"
> -Â "#"
> -Â "TARGET_THUMB2 && reload_completed"
> -Â [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
> -Â Â (set (match_dup 3) (not:SI (match_dup 4)))]
> -Â "
> -Â {
> -Â Â Â operands[3] = gen_highpart (SImode, operands[0]);
> -Â Â Â operands[0] = gen_lowpart (SImode, operands[0]);
> -Â Â Â operands[1] = gen_lowpart (SImode, operands[1]);
> -Â Â Â operands[4] = gen_highpart (SImode, operands[2]);
> -Â Â Â operands[2] = gen_lowpart (SImode, operands[2]);
> -Â }"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "predicable_short_it" "no")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> -(define_insn_and_split "*iordi_notsesidi_di"
> -Â [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> -(ior:DI (not:DI (sign_extend:DI
> - (match_operand:SI 2 "s_register_operand" "r,r")))
> -(match_operand:DI 1 "s_register_operand" "0,r")))]
> -Â "TARGET_THUMB2"
> -Â "#"
> -Â "TARGET_THUMB2 && reload_completed"
> -Â [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
> -Â Â (set (match_dup 3) (ior:SI (not:SI
> -(ashiftrt:SI (match_dup 2) (const_int 31)))
> -Â Â Â Â Â Â (match_dup 4)))]
> -Â "
> -Â {
> -Â Â Â 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]);
> -Â }"
> -Â [(set_attr "length" "8")
> -Â Â (set_attr "predicable" "yes")
> -Â Â (set_attr "predicable_short_it" "no")
> -Â Â (set_attr "type" "multiple")]
> -)
> -
> Â (define_insn "*orsi_notsi_si"
> Â Â [(set (match_operand:SI 0 "s_register_operand" "=r")
> Â (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][ARM] Cleanup logical DImode operations
2019-08-22 13:35 ` Kyrill Tkachov
@ 2019-08-26 11:03 ` Christophe Lyon
2019-08-28 13:58 ` Wilco Dijkstra
0 siblings, 1 reply; 6+ messages in thread
From: Christophe Lyon @ 2019-08-26 11:03 UTC (permalink / raw)
To: Kyrill Tkachov; +Cc: Wilco Dijkstra, GCC Patches, nd, Richard Earnshaw
On Thu, 22 Aug 2019 at 14:03, Kyrill Tkachov
<kyrylo.tkachov@foss.arm.com> wrote:
>
> Hi Wilco,
>
> On 7/19/19 12:30 PM, Wilco Dijkstra wrote:
> >
> > Cleanup the logical DImode operations since the current implementation
> > is way
> > too complicated. Thumb-1, Thumb-2, VFP/Neon and iwMMXt all work
> > differently,
> > resulting in a bewildering number of expansions, patterns and splits
> > across
> > several md files. All this complexity is counterproductive and results in
> > inefficient code.
> >
> > A much simpler approach is to split these operations early in the expander
> > so that optimizations and register allocation are applied on the
> > 32-bit halves.
> > Code generation is unchanged on Thumb-1 and Arm/Thumb-2 without Neon
> > or iwMMXt
> > (which already expand these instructions early). With Neon these
> > changes save
> > ~1000 instructions from the PR77308 testcase, mostly by significantly
> > reducing
> > register pressure and spilling.
> >
> > Bootstrap & regress OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57
> >
> > OK for commit?
Hi Wilco,
After this was committed (r274823), I've noticed 2 regressions on arm*:
FAIL: gcc.target/arm/pr53447-5.c scan-assembler-times (ldrd|vldr\\.64) 20
FAIL: gcc.target/arm/pr53447-5.c scan-assembler-times (strd|vstr\\.64) 18
Does this test still pass for you?
Thanks,
Christophe
>
> Ok. Thanks for doing this.
>
> Please keep an eye out for fallout after committing.
>
> Kyrill
>
>
> >
> > ChangeLog:
> > 2019-07-18 Wilco Dijkstra <wdijkstr@arm.com>
> >
> > * config/arm/arm.md (split and/eor/ior): Remove Neon check.
> > (split not): Add DImode not splitter.
> > (anddi3): Remove pattern.
> > (anddi3_insn): Likewise.
> > (anddi_zesidi_di): Likewise.
> > (anddi_sesdi_di): Likewise.
> > (anddi_notdi_di): Likewise.
> > (anddi_notzesidi_di): Likewise.
> > (anddi_notsesidi_di): Likewise.
> > (iordi3): Likewise.
> > (iordi3_insn): Likewise.
> > (iordi_zesidi_di): Likewise.
> > (iordi_sesidi_di): Likewise.
> > (xordi3): Likewise.
> > (xordi3_insn): Likewise.
> > (xordi_sesidi_di): Likewise.
> > (xordi_zesidi_di): Likewise.
> > (one_cmpldi2): Likewise.
> > (one_cmpldi2_insn): Likewise.
> > * config/arm/constraints.md: Remove De, Df, Dg constraints.
> > * config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register
> > alternative.
> > (iwmmxt_xordi3): Likewise.
> > (iwmmxt_anddi3): Likewise.
> > * config/arm/neon.md (orndi3_neon): Remove pattern.
> > (anddi_notdi_di): Likewise.
> > * config/arm/predicates.md (arm_anddi_operand_neon): Remove.
> > (arm_iordi_operand_neon): Likewise.
> > (arm_xordi_operand_neon): Likewise.
> > * config/arm/thumb2.md(iordi_notdi_di): Remove pattern.
> > (iordi_notzesidi_di): Likewise.
> > (iordi_notdi_zesidi): Likewise.
> > (iordi_notsesidi_di): Likewise.
> >
> >
> > ---
> > diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> > index
> > 8f4a4c26ea849a023f2e63d2efbf327423512dfc..cab59c403b777c37c1e412ab9a69db2c2ec533a2
> > 100644
> > --- a/gcc/config/arm/arm.md
> > +++ b/gcc/config/arm/arm.md
> > @@ -2183,19 +2183,16 @@ (define_expand "divdf3"
> > "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
> > "")
> >
> > -;; Boolean and,ior,xor insns
> >
> > -;; Split up double word logical operations
> > -
> > -;; Split up simple DImode logical operations. Simply perform the logical
> > +;; Split DImode and, ior, xor operations. Simply perform the logical
> > ;; operation on the upper and lower halves of the registers.
> > +;; This is needed for atomic operations in arm_split_atomic_op.
> > (define_split
> > [(set (match_operand:DI 0 "s_register_operand" "")
> > (match_operator:DI 6 "logical_binary_operator"
> > [(match_operand:DI 1 "s_register_operand" "")
> > (match_operand:DI 2 "s_register_operand" "")]))]
> > "TARGET_32BIT && reload_completed
> > - && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
> > && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
> > [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
> > (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
> > @@ -2210,167 +2207,20 @@ (define_split
> > }"
> > )
> >
> > +;; Split DImode not (needed for atomic operations in
> > arm_split_atomic_op).
> > (define_split
> > - [(set (match_operand:DI 0 "s_register_operand" "")
> > -(match_operator:DI 6 "logical_binary_operator"
> > - [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
> > - (match_operand:DI 1 "s_register_operand" "")]))]
> > - "TARGET_32BIT && reload_completed"
> > - [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
> > - (set (match_dup 3) (match_op_dup:SI 6
> > -[(ashiftrt:SI (match_dup 2) (const_int 31))
> > - (match_dup 4)]))]
> > - "
> > - {
> > - 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]);
> > - operands[5] = gen_highpart (SImode, operands[2]);
> > - operands[2] = gen_lowpart (SImode, operands[2]);
> > - }"
> > -)
> > -
> > -;; The zero extend of operand 2 means we can just copy the high part of
> > -;; operand1 into operand0.
> > -(define_split
> > - [(set (match_operand:DI 0 "s_register_operand" "")
> > -(ior:DI
> > - (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
> > - (match_operand:DI 1 "s_register_operand" "")))]
> > - "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
> > - [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
> > - (set (match_dup 3) (match_dup 4))]
> > - "
> > - {
> > - operands[4] = gen_highpart (SImode, operands[1]);
> > - operands[3] = gen_highpart (SImode, operands[0]);
> > - operands[0] = gen_lowpart (SImode, operands[0]);
> > - operands[1] = gen_lowpart (SImode, operands[1]);
> > - }"
> > -)
> > -
> > -;; The zero extend of operand 2 means we can just copy the high part of
> > -;; operand1 into operand0.
> > -(define_split
> > - [(set (match_operand:DI 0 "s_register_operand" "")
> > -(xor:DI
> > - (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
> > - (match_operand:DI 1 "s_register_operand" "")))]
> > - "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
> > - [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
> > - (set (match_dup 3) (match_dup 4))]
> > - "
> > - {
> > - operands[4] = gen_highpart (SImode, operands[1]);
> > - operands[3] = gen_highpart (SImode, operands[0]);
> > - operands[0] = gen_lowpart (SImode, operands[0]);
> > - operands[1] = gen_lowpart (SImode, operands[1]);
> > - }"
> > -)
> > -
> > -(define_expand "anddi3"
> > - [(set (match_operand:DI 0 "s_register_operand")
> > -(and:DI (match_operand:DI 1 "s_register_operand")
> > -(match_operand:DI 2 "neon_inv_logic_op2")))]
> > - "TARGET_32BIT"
> > - "
> > - if (!TARGET_NEON && !TARGET_IWMMXT)
> > - {
> > - rtx low = simplify_gen_binary (AND, SImode,
> > - gen_lowpart (SImode, operands[1]),
> > - gen_lowpart (SImode, operands[2]));
> > - rtx high = simplify_gen_binary (AND, SImode,
> > - gen_highpart (SImode, operands[1]),
> > - gen_highpart_mode (SImode, DImode,
> > - operands[2]));
> > -
> > - emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
> > - emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
> > -
> > - DONE;
> > - }
> > - /* Otherwise expand pattern as above. */
> > - "
> > -)
> > -
> > -(define_insn_and_split "*anddi3_insn"
> > - [(set (match_operand:DI 0 "s_register_operand" "=w,w
> > ,&r,&r,&r,&r,?w,?w")
> > - (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0
> > ,r ,0 ,r ,w ,0")
> > - (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r
> > ,r ,De,De,w ,DL")))]
> > - "TARGET_32BIT && !TARGET_IWMMXT"
> > -{
> > - switch (which_alternative)
> > - {
> > - case 0: /* fall through */
> > - case 6: return "vand\t%P0, %P1, %P2";
> > - case 1: /* fall through */
> > - case 7: return neon_output_logic_immediate ("vand", &operands[2],
> > - DImode, 1, VALID_NEON_QREG_MODE (DImode));
> > - case 2:
> > - case 3:
> > - case 4:
> > - case 5: /* fall through */
> > - return "#";
> > - 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 (AND, SImode,
> > - gen_lowpart (SImode, operands[1]),
> > - gen_lowpart (SImode, operands[2]));
> > - operands[6] = simplify_gen_binary (AND, SImode,
> > - gen_highpart (SImode, operands[1]),
> > - gen_highpart_mode (SImode, DImode, operands[2]));
> > -
> > - }"
> > - [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
> > - multiple,multiple,neon_logic,neon_logic")
> > - (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
> > - avoid_neon_for_64bits,avoid_neon_for_64bits")
> > - (set_attr "length" "*,*,8,8,8,8,*,*")
> > - ]
> > -)
> > -
> > -(define_insn_and_split "*anddi_zesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(and:DI (zero_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r"))
> > -(match_operand:DI 1 "s_register_operand" "0,r")))]
> > + [(set (match_operand:DI 0 "s_register_operand")
> > +(not:DI (match_operand:DI 1 "s_register_operand")))]
> > "TARGET_32BIT"
> > - "#"
> > - "TARGET_32BIT && reload_completed"
> > - ; The zero extend of operand 2 clears the high word of the output
> > - ; operand.
> > - [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
> > - (set (match_dup 3) (const_int 0))]
> > + [(set (match_dup 0) (not:SI (match_dup 1)))
> > + (set (match_dup 2) (not:SI (match_dup 3)))]
> > "
> > {
> > - operands[3] = gen_highpart (SImode, operands[0]);
> > + operands[2] = gen_highpart (SImode, operands[0]);
> > operands[0] = gen_lowpart (SImode, operands[0]);
> > + operands[3] = gen_highpart (SImode, operands[1]);
> > operands[1] = gen_lowpart (SImode, operands[1]);
> > }"
> > - [(set_attr "length" "8")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > -(define_insn "*anddi_sesdi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(and:DI (sign_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r"))
> > -(match_operand:DI 1 "s_register_operand" "0,r")))]
> > - "TARGET_32BIT"
> > - "#"
> > - [(set_attr "length" "8")
> > - (set_attr "type" "multiple")]
> > )
> >
> > (define_expand "andsi3"
> > @@ -2952,105 +2802,6 @@ (define_insn "insv_t2"
> > (set_attr "type" "bfm")]
> > )
> >
> > -; constants for op 2 will never be given to these patterns.
> > -(define_insn_and_split "*anddi_notdi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
> > -(match_operand:DI 2 "s_register_operand" "r,0")))]
> > - "TARGET_32BIT"
> > - "#"
> > - "TARGET_32BIT && reload_completed
> > - && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
> > - && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
> > - [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
> > - (set (match_dup 3) (and:SI (not: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]);
> > - operands[5] = gen_highpart (SImode, operands[2]);
> > - operands[2] = gen_lowpart (SImode, operands[2]);
> > - }"
> > - [(set_attr "length" "8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > -(define_insn_and_split "*anddi_notzesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(and:DI (not:DI (zero_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r")))
> > -(match_operand:DI 1 "s_register_operand" "0,?r")))]
> > - "TARGET_32BIT"
> > - "@
> > - bic%?\\t%Q0, %Q1, %2
> > - #"
> > - ; (not (zero_extend ...)) allows us to just copy the high word from
> > - ; operand1 to operand0.
> > - "TARGET_32BIT
> > - && reload_completed
> > - && operands[0] != operands[1]"
> > - [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
> > - (set (match_dup 3) (match_dup 4))]
> > - "
> > - {
> > - 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]);
> > - }"
> > - [(set_attr "length" "4,8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > -(define_insn_and_split "*anddi_notdi_zesidi"
> > - [(set (match_operand:DI 0 "s_register_operand" "=r")
> > - (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
> > - (zero_extend:DI
> > - (match_operand:SI 1 "s_register_operand" "r"))))]
> > - "TARGET_32BIT"
> > - "#"
> > - "TARGET_32BIT && reload_completed"
> > - [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
> > - (set (match_dup 3) (const_int 0))]
> > - "
> > - {
> > - operands[3] = gen_highpart (SImode, operands[0]);
> > - operands[0] = gen_lowpart (SImode, operands[0]);
> > - operands[2] = gen_lowpart (SImode, operands[2]);
> > - }"
> > - [(set_attr "length" "8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > -(define_insn_and_split "*anddi_notsesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(and:DI (not:DI (sign_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r")))
> > -(match_operand:DI 1 "s_register_operand" "0,r")))]
> > - "TARGET_32BIT"
> > - "#"
> > - "TARGET_32BIT && reload_completed"
> > - [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
> > - (set (match_dup 3) (and:SI (not:SI
> > -(ashiftrt:SI (match_dup 2) (const_int 31)))
> > - (match_dup 4)))]
> > - "
> > - {
> > - 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]);
> > - }"
> > - [(set_attr "length" "8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > (define_insn "andsi_notsi_si"
> > [(set (match_operand:SI 0 "s_register_operand" "=r")
> > (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
> > @@ -3150,101 +2901,6 @@ (define_insn "*andsi_notsi_si_compare0_scratch"
> > (set_attr "type" "logics_shift_reg")]
> > )
> >
> > -(define_expand "iordi3"
> > - [(set (match_operand:DI 0 "s_register_operand")
> > -(ior:DI (match_operand:DI 1 "s_register_operand")
> > -(match_operand:DI 2 "neon_logic_op2")))]
> > - "TARGET_32BIT"
> > - "
> > - if (!TARGET_NEON && !TARGET_IWMMXT)
> > - {
> > - rtx low = simplify_gen_binary (IOR, SImode,
> > - gen_lowpart (SImode, operands[1]),
> > - gen_lowpart (SImode, operands[2]));
> > - rtx high = simplify_gen_binary (IOR, SImode,
> > - gen_highpart (SImode, operands[1]),
> > - gen_highpart_mode (SImode, DImode,
> > - operands[2]));
> > -
> > - emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
> > - emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
> > -
> > - DONE;
> > - }
> > - /* Otherwise expand pattern as above. */
> > - "
> > -)
> > -
> > -(define_insn_and_split "*iordi3_insn"
> > - [(set (match_operand:DI 0 "s_register_operand" "=w,w
> > ,&r,&r,&r,&r,?w,?w")
> > -(ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0
> > ,r ,w ,0")
> > -(match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w
> > ,Dl")))]
> > - "TARGET_32BIT && !TARGET_IWMMXT"
> > - {
> > - switch (which_alternative)
> > - {
> > - case 0: /* fall through */
> > - case 6: return "vorr\t%P0, %P1, %P2";
> > - case 1: /* fall through */
> > - case 7: return neon_output_logic_immediate ("vorr", &operands[2],
> > - DImode, 0, VALID_NEON_QREG_MODE (DImode));
> > - case 2:
> > - case 3:
> > - case 4:
> > - case 5:
> > - return "#";
> > - 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 (IOR, SImode,
> > - gen_lowpart (SImode, operands[1]),
> > - gen_lowpart (SImode, operands[2]));
> > - operands[6] = simplify_gen_binary (IOR, SImode,
> > - gen_highpart (SImode, operands[1]),
> > - gen_highpart_mode (SImode, DImode, operands[2]));
> > -
> > - }"
> > - [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
> > - multiple,neon_logic,neon_logic")
> > - (set_attr "length" "*,*,8,8,8,8,*,*")
> > - (set_attr "arch"
> > "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
> > -)
> > -
> > -(define_insn "*iordi_zesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(ior:DI (zero_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r"))
> > -(match_operand:DI 1 "s_register_operand" "0,?r")))]
> > - "TARGET_32BIT"
> > - "@
> > - orr%?\\t%Q0, %Q1, %2
> > - #"
> > - [(set_attr "length" "4,8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "type" "logic_reg,multiple")]
> > -)
> > -
> > -(define_insn "*iordi_sesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(ior:DI (sign_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r"))
> > -(match_operand:DI 1 "s_register_operand" "0,r")))]
> > - "TARGET_32BIT"
> > - "#"
> > - [(set_attr "length" "8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > (define_expand "iorsi3"
> > [(set (match_operand:SI 0 "s_register_operand")
> > (ior:SI (match_operand:SI 1 "s_register_operand")
> > @@ -3347,103 +3003,6 @@ (define_insn "*iorsi3_compare0_scratch"
> > (set_attr "type" "logics_imm,logics_reg")]
> > )
> >
> > -(define_expand "xordi3"
> > - [(set (match_operand:DI 0 "s_register_operand")
> > -(xor:DI (match_operand:DI 1 "s_register_operand")
> > -(match_operand:DI 2 "arm_xordi_operand")))]
> > - "TARGET_32BIT"
> > - {
> > - /* The iWMMXt pattern for xordi3 accepts only register operands
> > but we want
> > - to reuse this expander for all TARGET_32BIT targets so just
> > force the
> > - constants into a register. Unlike for the anddi3 and iordi3
> > there are
> > - no NEON instructions that take an immediate. */
> > - if (TARGET_IWMMXT && !REG_P (operands[2]))
> > - operands[2] = force_reg (DImode, operands[2]);
> > - if (!TARGET_NEON && !TARGET_IWMMXT)
> > - {
> > -rtx low = simplify_gen_binary (XOR, SImode,
> > -gen_lowpart (SImode, operands[1]),
> > -gen_lowpart (SImode, operands[2]));
> > -rtx high = simplify_gen_binary (XOR, SImode,
> > -gen_highpart (SImode, operands[1]),
> > -gen_highpart_mode (SImode, DImode,
> > - operands[2]));
> > -
> > -emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
> > -emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
> > -
> > -DONE;
> > - }
> > - /* Otherwise expand pattern as above. */
> > - }
> > -)
> > -
> > -(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 "type"
> > "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
> > - (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
> > -)
> > -
> > -(define_insn "*xordi_zesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(xor:DI (zero_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r"))
> > -(match_operand:DI 1 "s_register_operand" "0,?r")))]
> > - "TARGET_32BIT"
> > - "@
> > - eor%?\\t%Q0, %Q1, %2
> > - #"
> > - [(set_attr "length" "4,8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "type" "logic_reg")]
> > -)
> > -
> > -(define_insn "*xordi_sesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(xor:DI (sign_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r"))
> > -(match_operand:DI 1 "s_register_operand" "0,r")))]
> > - "TARGET_32BIT"
> > - "#"
> > - [(set_attr "length" "8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > (define_expand "xorsi3"
> > [(set (match_operand:SI 0 "s_register_operand")
> > (xor:SI (match_operand:SI 1 "s_register_operand")
> > @@ -5033,56 +4592,6 @@ (define_expand "sqrtdf2"
> > "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
> > "")
> >
> > -(define_expand "one_cmpldi2"
> > - [(set (match_operand:DI 0 "s_register_operand")
> > -(not:DI (match_operand:DI 1 "s_register_operand")))]
> > - "TARGET_32BIT"
> > - "
> > - if (!TARGET_NEON && !TARGET_IWMMXT)
> > - {
> > - rtx low = simplify_gen_unary (NOT, SImode,
> > - gen_lowpart (SImode, operands[1]),
> > - SImode);
> > - rtx high = simplify_gen_unary (NOT, SImode,
> > - gen_highpart_mode (SImode, DImode,
> > -operands[1]),
> > - SImode);
> > -
> > - emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
> > - emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
> > -
> > - DONE;
> > - }
> > - /* Otherwise expand pattern as above. */
> > - "
> > -)
> > -
> > -(define_insn_and_split "*one_cmpldi2_insn"
> > - [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
> > -(not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
> > - "TARGET_32BIT"
> > - "@
> > - vmvn\t%P0, %P1
> > - #
> > - #
> > - vmvn\t%P0, %P1"
> > - "TARGET_32BIT && reload_completed
> > - && arm_general_register_operand (operands[0], DImode)"
> > - [(set (match_dup 0) (not:SI (match_dup 1)))
> > - (set (match_dup 2) (not:SI (match_dup 3)))]
> > - "
> > - {
> > - operands[2] = gen_highpart (SImode, operands[0]);
> > - operands[0] = gen_lowpart (SImode, operands[0]);
> > - operands[3] = gen_highpart (SImode, operands[1]);
> > - operands[1] = gen_lowpart (SImode, operands[1]);
> > - }"
> > - [(set_attr "length" "*,8,8,*")
> > - (set_attr "predicable" "no,yes,yes,no")
> > - (set_attr "type" "neon_move,multiple,multiple,neon_move")
> > - (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
> > -)
> > -
> > (define_expand "one_cmplsi2"
> > [(set (match_operand:SI 0 "s_register_operand")
> > (not:SI (match_operand:SI 1 "s_register_operand")))]
> > diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
> > index
> > d4a4c5967aea09816485d77f9ab90020aa085e73..b76de81b85c8ce7a2ca484a750b908b7ca64600a
> > 100644
> > --- a/gcc/config/arm/constraints.md
> > +++ b/gcc/config/arm/constraints.md
> > @@ -273,24 +273,6 @@ (define_constraint "Dd"
> > (and (match_code "const_int")
> > (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival,
> > PLUS)")))
> >
> > -(define_constraint "De"
> > - "@internal
> > - In ARM/Thumb-2 state a const_int that can be used by insn anddi."
> > - (and (match_code "const_int")
> > - (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)")))
> > -
> > -(define_constraint "Df"
> > - "@internal
> > - In ARM/Thumb-2 state a const_int that can be used by insn iordi."
> > - (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/iwmmxt.md b/gcc/config/arm/iwmmxt.md
> > index
> > 310019aa5ceef98047b310284123f66940430095..86158ea4fd278180d5e2321c66c6c2b5e5c460b0
> > 100644
> > --- a/gcc/config/arm/iwmmxt.md
> > +++ b/gcc/config/arm/iwmmxt.md
> > @@ -55,45 +55,36 @@ (define_insn "tbcstv2si"
> > )
> >
> > (define_insn "iwmmxt_iordi3"
> > - [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
> > - (ior:DI (match_operand:DI 1 "register_operand" "%y,0,r")
> > -(match_operand:DI 2 "register_operand" "y,r,r")))]
> > + [(set (match_operand:DI 0 "register_operand" "=y")
> > + (ior:DI (match_operand:DI 1 "register_operand" "%y")
> > +(match_operand:DI 2 "register_operand" "y")))]
> > "TARGET_REALLY_IWMMXT"
> > - "@
> > - wor%?\\t%0, %1, %2
> > - #
> > - #"
> > + "wor%?\\t%0, %1, %2"
> > [(set_attr "predicable" "yes")
> > - (set_attr "length" "4,8,8")
> > - (set_attr "type" "wmmx_wor,*,*")]
> > + (set_attr "length" "4")
> > + (set_attr "type" "wmmx_wor")]
> > )
> >
> > (define_insn "iwmmxt_xordi3"
> > - [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
> > - (xor:DI (match_operand:DI 1 "register_operand" "%y,0,r")
> > -(match_operand:DI 2 "register_operand" "y,r,r")))]
> > + [(set (match_operand:DI 0 "register_operand" "=y")
> > + (xor:DI (match_operand:DI 1 "register_operand" "%y")
> > +(match_operand:DI 2 "register_operand" "y")))]
> > "TARGET_REALLY_IWMMXT"
> > - "@
> > - wxor%?\\t%0, %1, %2
> > - #
> > - #"
> > + "wxor%?\\t%0, %1, %2"
> > [(set_attr "predicable" "yes")
> > - (set_attr "length" "4,8,8")
> > - (set_attr "type" "wmmx_wxor,*,*")]
> > + (set_attr "length" "4")
> > + (set_attr "type" "wmmx_wxor")]
> > )
> >
> > (define_insn "iwmmxt_anddi3"
> > - [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
> > - (and:DI (match_operand:DI 1 "register_operand" "%y,0,r")
> > -(match_operand:DI 2 "register_operand" "y,r,r")))]
> > + [(set (match_operand:DI 0 "register_operand" "=y")
> > + (and:DI (match_operand:DI 1 "register_operand" "%y")
> > +(match_operand:DI 2 "register_operand" "y")))]
> > "TARGET_REALLY_IWMMXT"
> > - "@
> > - wand%?\\t%0, %1, %2
> > - #
> > - #"
> > + "wand%?\\t%0, %1, %2"
> > [(set_attr "predicable" "yes")
> > - (set_attr "length" "4,8,8")
> > - (set_attr "type" "wmmx_wand,*,*")]
> > + (set_attr "length" "4")
> > + (set_attr "type" "wmmx_wand")]
> > )
> >
> > (define_insn "iwmmxt_nanddi3"
> > diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
> > index
> > 6333e0ea3ea68d73bed1f7c4d8ca090090ad68cc..ef73c77abeeaa02947c70ffa435f7bedc431e3be
> > 100644
> > --- a/gcc/config/arm/neon.md
> > +++ b/gcc/config/arm/neon.md
> > @@ -838,46 +838,6 @@ (define_insn "orn<mode>3_neon"
> > [(set_attr "type" "neon_logic<q>")]
> > )
> >
> > -;; TODO: investigate whether we should disable
> > -;; this and bicdi3_neon for the A8 in line with the other
> > -;; changes above.
> > -(define_insn_and_split "orndi3_neon"
> > - [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
> > -(ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
> > -(match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
> > - "TARGET_NEON"
> > - "@
> > - vorn\t%P0, %P1, %P2
> > - #
> > - #
> > - #"
> > - "reload_completed &&
> > - (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
> > - [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
> > - (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
> > - "
> > - {
> > - if (TARGET_THUMB2)
> > - {
> > - operands[3] = gen_highpart (SImode, operands[0]);
> > - operands[0] = gen_lowpart (SImode, operands[0]);
> > - operands[4] = gen_highpart (SImode, operands[2]);
> > - operands[2] = gen_lowpart (SImode, operands[2]);
> > - operands[5] = gen_highpart (SImode, operands[1]);
> > - operands[1] = gen_lowpart (SImode, operands[1]);
> > - }
> > - else
> > - {
> > - emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
> > - emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
> > - DONE;
> > - }
> > - }"
> > - [(set_attr "type" "neon_logic,multiple,multiple,multiple")
> > - (set_attr "length" "*,16,8,8")
> > - (set_attr "arch" "any,a,t2,t2")]
> > -)
> > -
> > (define_insn "bic<mode>3_neon"
> > [(set (match_operand:VDQ 0 "s_register_operand" "=w")
> > (and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
> > @@ -887,20 +847,6 @@ (define_insn "bic<mode>3_neon"
> > [(set_attr "type" "neon_logic<q>")]
> > )
> >
> > -;; Compare to *anddi_notdi_di.
> > -(define_insn "bicdi3_neon"
> > - [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
> > - (and:DI (not:DI (match_operand:DI 2 "s_register_operand"
> > "w,r,0"))
> > -(match_operand:DI 1 "s_register_operand" "w,0,r")))]
> > - "TARGET_NEON"
> > - "@
> > - vbic\t%P0, %P1, %P2
> > - #
> > - #"
> > - [(set_attr "type" "neon_logic,multiple,multiple")
> > - (set_attr "length" "*,8,8")]
> > -)
> > -
> > (define_insn "xor<mode>3"
> > [(set (match_operand:VDQ 0 "s_register_operand" "=w")
> > (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
> > diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
> > index
> > f53378a250edfdd0de467f2abbe08bc933d6d734..af97edd28f27a1d8ab9ac2a63343380236d97603
> > 100644
> > --- a/gcc/config/arm/predicates.md
> > +++ b/gcc/config/arm/predicates.md
> > @@ -201,23 +201,6 @@ (define_predicate "arm_add_operand"
> > (ior (match_operand 0 "arm_rhs_operand")
> > (match_operand 0 "arm_neg_immediate_operand")))
> >
> > -(define_predicate "arm_anddi_operand_neon"
> > - (ior (match_operand 0 "s_register_operand")
> > - (and (match_code "const_int")
> > - (match_test "const_ok_for_dimode_op (INTVAL (op), AND)"))
> > - (match_operand 0 "neon_inv_logic_op2")))
> > -
> > -(define_predicate "arm_iordi_operand_neon"
> > - (ior (match_operand 0 "s_register_operand")
> > - (and (match_code "const_int")
> > - (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/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
> > index
> > b283a7b656526d3c4719860d10aa1c0550288ba3..78a6ea0b10dab97ed6651ce62e99cfd7a81722ab
> > 100644
> > --- a/gcc/config/arm/thumb2.md
> > +++ b/gcc/config/arm/thumb2.md
> > @@ -1478,103 +1478,6 @@ (define_insn "*thumb2_negsi2_short"
> > (set_attr "type" "alu_sreg")]
> > )
> >
> > -; Constants for op 2 will never be given to these patterns.
> > -(define_insn_and_split "*iordi_notdi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(ior:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
> > -(match_operand:DI 2 "s_register_operand" "r,0")))]
> > - "TARGET_THUMB2"
> > - "#"
> > - "TARGET_THUMB2 && reload_completed"
> > - [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2)))
> > - (set (match_dup 3) (ior:SI (not: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]);
> > - operands[5] = gen_highpart (SImode, operands[2]);
> > - operands[2] = gen_lowpart (SImode, operands[2]);
> > - }"
> > - [(set_attr "length" "8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "predicable_short_it" "no")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > -(define_insn_and_split "*iordi_notzesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(ior:DI (not:DI (zero_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r")))
> > -(match_operand:DI 1 "s_register_operand" "0,?r")))]
> > - "TARGET_THUMB2"
> > - "#"
> > - ; (not (zero_extend...)) means operand0 will always be 0xffffffff
> > - "TARGET_THUMB2 && reload_completed"
> > - [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
> > - (set (match_dup 3) (const_int -1))]
> > - "
> > - {
> > - operands[3] = gen_highpart (SImode, operands[0]);
> > - operands[0] = gen_lowpart (SImode, operands[0]);
> > - operands[1] = gen_lowpart (SImode, operands[1]);
> > - }"
> > - [(set_attr "length" "4,8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "predicable_short_it" "no")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > -(define_insn_and_split "*iordi_notdi_zesidi"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
> > -(zero_extend:DI
> > - (match_operand:SI 1 "s_register_operand" "r,r"))))]
> > - "TARGET_THUMB2"
> > - "#"
> > - "TARGET_THUMB2 && reload_completed"
> > - [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
> > - (set (match_dup 3) (not:SI (match_dup 4)))]
> > - "
> > - {
> > - operands[3] = gen_highpart (SImode, operands[0]);
> > - operands[0] = gen_lowpart (SImode, operands[0]);
> > - operands[1] = gen_lowpart (SImode, operands[1]);
> > - operands[4] = gen_highpart (SImode, operands[2]);
> > - operands[2] = gen_lowpart (SImode, operands[2]);
> > - }"
> > - [(set_attr "length" "8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "predicable_short_it" "no")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > -(define_insn_and_split "*iordi_notsesidi_di"
> > - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
> > -(ior:DI (not:DI (sign_extend:DI
> > - (match_operand:SI 2 "s_register_operand" "r,r")))
> > -(match_operand:DI 1 "s_register_operand" "0,r")))]
> > - "TARGET_THUMB2"
> > - "#"
> > - "TARGET_THUMB2 && reload_completed"
> > - [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
> > - (set (match_dup 3) (ior:SI (not:SI
> > -(ashiftrt:SI (match_dup 2) (const_int 31)))
> > - (match_dup 4)))]
> > - "
> > - {
> > - 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]);
> > - }"
> > - [(set_attr "length" "8")
> > - (set_attr "predicable" "yes")
> > - (set_attr "predicable_short_it" "no")
> > - (set_attr "type" "multiple")]
> > -)
> > -
> > (define_insn "*orsi_notsi_si"
> > [(set (match_operand:SI 0 "s_register_operand" "=r")
> > (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][ARM] Cleanup logical DImode operations
2019-08-26 11:03 ` Christophe Lyon
@ 2019-08-28 13:58 ` Wilco Dijkstra
0 siblings, 0 replies; 6+ messages in thread
From: Wilco Dijkstra @ 2019-08-28 13:58 UTC (permalink / raw)
To: Christophe Lyon, Kyrill Tkachov; +Cc: GCC Patches, nd, Richard Earnshaw
Hi Christophe,
> After this was committed (r274823), I've noticed 2 regressions on arm*:
> FAIL: gcc.target/arm/pr53447-5.c scan-assembler-times (ldrd|vldr\\.64) 20
> FAIL: gcc.target/arm/pr53447-5.c scan-assembler-times (strd|vstr\\.64) 18
>
> Does this test still pass for you?
You're right, this fails for me too when I configure GCC for armv7-a or higher.
It looks like a latent issue in that the Arm backend isn't able to recombine separate
loads/stores into LDRD/STRD - eventhough it should really do that. There is a
workaround - I can add back the logical DImode expanders which split off all
memory operands before the DImode split (rather than the other way around).
Cheers,
Wilco
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-08-28 13:46 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-19 11:35 [PATCH][ARM] Cleanup logical DImode operations Wilco Dijkstra
2019-07-31 16:25 ` Wilco Dijkstra
2019-08-19 16:12 ` Wilco Dijkstra
2019-08-22 13:35 ` Kyrill Tkachov
2019-08-26 11:03 ` Christophe Lyon
2019-08-28 13:58 ` Wilco Dijkstra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).