mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 18:31:10 +08:00
[ARM] Cleanup logical DImode operations
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. Codegeneration 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 OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57 gcc/ * 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. From-SVN: r274823
This commit is contained in:
parent
203ef022c6
commit
cdfc0e863a
@ -1,3 +1,39 @@
|
||||
2019-08-22 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.
|
||||
|
||||
2019-08-22 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* config/arm/arm.md (iorsi3_compare0): Add alternative for 16-bit thumb
|
||||
|
@ -2198,19 +2198,17 @@
|
||||
"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.
|
||||
;; Avoid splitting IWMMXT instructions.
|
||||
(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)]))]
|
||||
@ -2225,167 +2223,21 @@
|
||||
}"
|
||||
)
|
||||
|
||||
;; Split DImode not (needed for atomic operations in arm_split_atomic_op).
|
||||
;; Unconditionally split since there is no SIMD DImode NOT pattern.
|
||||
(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")))]
|
||||
[(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_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))]
|
||||
[(set (match_dup 0) (not:SI (match_dup 1)))
|
||||
(set (match_dup 2) (not:SI (match_dup 3)))]
|
||||
"
|
||||
{
|
||||
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")))]
|
||||
"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))]
|
||||
"
|
||||
{
|
||||
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"
|
||||
@ -2967,105 +2819,6 @@
|
||||
(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"))
|
||||
@ -3165,101 +2918,6 @@
|
||||
(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")
|
||||
@ -3368,103 +3026,6 @@
|
||||
(set_attr "type" "logics_imm,logics_reg,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")
|
||||
@ -5054,56 +4615,6 @@
|
||||
"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")))]
|
||||
|
@ -273,24 +273,6 @@
|
||||
(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
|
||||
|
@ -55,45 +55,36 @@
|
||||
)
|
||||
|
||||
(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"
|
||||
|
@ -838,46 +838,6 @@
|
||||
[(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 @@
|
||||
[(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")
|
||||
|
@ -201,23 +201,6 @@
|
||||
(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")
|
||||
|
@ -1476,103 +1476,6 @@
|
||||
(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"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user