From 3eefaaa9fe42837b1debc49575b4a5405bf0af3b Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Fri, 30 Aug 2019 10:38:37 +0000 Subject: [PATCH] arm.md (unaligned_loaddi, [...]): New unspec insn patterns. 2019-08-30 Bernd Edlinger * config/arm/arm.md (unaligned_loaddi, unaligned_storedi): New unspec insn patterns. * config/arm/neon.md (unaligned_storev8qi): Likewise. * config/arm/arm.c (gen_cpymem_ldrd_strd): Use unaligned_loaddi and unaligned_storedi for 4-byte aligned memory. (arm_block_set_aligned_vect): Use unaligned_storev8qi for 4-byte aligned memory. From-SVN: r275063 --- gcc/ChangeLog | 10 ++++++++++ gcc/config/arm/arm.c | 19 +++++++++++++------ gcc/config/arm/arm.md | 22 ++++++++++++++++++++++ gcc/config/arm/neon.md | 10 ++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57811a5f946..f902b554286 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-08-30 Bernd Edlinger + + * config/arm/arm.md (unaligned_loaddi, + unaligned_storedi): New unspec insn patterns. + * config/arm/neon.md (unaligned_storev8qi): Likewise. + * config/arm/arm.c (gen_cpymem_ldrd_strd): Use unaligned_loaddi + and unaligned_storedi for 4-byte aligned memory. + (arm_block_set_aligned_vect): Use unaligned_storev8qi for + 4-byte aligned memory. + 2019-08-30 Martin Jambor tree-optimization/91579 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index a34cb7495f0..eb8bf13414f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -14578,8 +14578,10 @@ gen_cpymem_ldrd_strd (rtx *operands) low_reg = gen_lowpart (SImode, reg0); hi_reg = gen_highpart_mode (SImode, DImode, reg0); } - if (src_aligned) - emit_move_insn (reg0, src); + if (MEM_ALIGN (src) >= 2 * BITS_PER_WORD) + emit_move_insn (reg0, src); + else if (src_aligned) + emit_insn (gen_unaligned_loaddi (reg0, src)); else { emit_insn (gen_unaligned_loadsi (low_reg, src)); @@ -14587,8 +14589,10 @@ gen_cpymem_ldrd_strd (rtx *operands) emit_insn (gen_unaligned_loadsi (hi_reg, src)); } - if (dst_aligned) - emit_move_insn (dst, reg0); + if (MEM_ALIGN (dst) >= 2 * BITS_PER_WORD) + emit_move_insn (dst, reg0); + else if (dst_aligned) + emit_insn (gen_unaligned_storedi (dst, reg0)); else { emit_insn (gen_unaligned_storesi (dst, low_reg)); @@ -30197,7 +30201,10 @@ arm_block_set_aligned_vect (rtx dstbase, { addr = plus_constant (Pmode, dst, i); mem = adjust_automodify_address (dstbase, mode, addr, offset + i); - emit_move_insn (mem, reg); + if (MEM_ALIGN (mem) >= 2 * BITS_PER_WORD) + emit_move_insn (mem, reg); + else + emit_insn (gen_unaligned_storev8qi (mem, reg)); } /* Handle single word leftover by shifting 4 bytes back. We can @@ -30211,7 +30218,7 @@ arm_block_set_aligned_vect (rtx dstbase, if (align > UNITS_PER_WORD) set_mem_align (mem, BITS_PER_UNIT * UNITS_PER_WORD); - emit_move_insn (mem, reg); + emit_insn (gen_unaligned_storev8qi (mem, reg)); } /* Handle (0, 4), (4, 8) bytes leftover by shifting bytes back. We have to use unaligned access for this case. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 0be7a018eed..e49e0d579c9 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3963,6 +3963,17 @@ ; ARMv6+ unaligned load/store instructions (used for packed structure accesses). +(define_insn "unaligned_loaddi" + [(set (match_operand:DI 0 "s_register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] + UNSPEC_UNALIGNED_LOAD))] + "TARGET_32BIT && TARGET_LDRD" + "* + return output_move_double (operands, true, NULL); + " + [(set_attr "length" "8") + (set_attr "type" "load_8")]) + (define_insn "unaligned_loadsi" [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")] @@ -4008,6 +4019,17 @@ (set_attr "predicable_short_it" "no,yes,no") (set_attr "type" "load_byte")]) +(define_insn "unaligned_storedi" + [(set (match_operand:DI 0 "memory_operand" "=m") + (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")] + UNSPEC_UNALIGNED_STORE))] + "TARGET_32BIT && TARGET_LDRD" + "* + return output_move_double (operands, true, NULL); + " + [(set_attr "length" "8") + (set_attr "type" "store_8")]) + (define_insn "unaligned_storesi" [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m") (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")] diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index a5aa8d68e62..6a0ee28efc9 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -23,6 +23,16 @@ ;; type attribute definitions. (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd")) +(define_insn "unaligned_storev8qi" + [(set (match_operand:V8QI 0 "memory_operand" "=Un") + (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")] + UNSPEC_UNALIGNED_STORE))] + "TARGET_NEON" + "* + return output_move_neon (operands); + " + [(set_attr "type" "neon_store1_1reg")]) + (define_insn "*neon_mov" [(set (match_operand:VDX 0 "nonimmediate_operand" "=w,Un,w, w, w, ?r,?w,?r, ?Us,*r") -- 2.30.2