aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2019-08-30 10:38:37 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2019-08-30 10:38:37 +0000
commit3eefaaa9fe42837b1debc49575b4a5405bf0af3b (patch)
tree4a1679083c849ce6bccb64801bd4910aa7b79344
parentbb4d170d7b43be4b28ef20978ab2b453f6f2c55d (diff)
downloadgcc-3eefaaa9fe42837b1debc49575b4a5405bf0af3b.zip
gcc-3eefaaa9fe42837b1debc49575b4a5405bf0af3b.tar.gz
gcc-3eefaaa9fe42837b1debc49575b4a5405bf0af3b.tar.bz2
arm.md (unaligned_loaddi, [...]): New unspec insn patterns.
2019-08-30 Bernd Edlinger <bernd.edlinger@hotmail.de> * 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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/arm/arm.c19
-rw-r--r--gcc/config/arm/arm.md22
-rw-r--r--gcc/config/arm/neon.md10
4 files changed, 55 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 57811a5..f902b55 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2019-08-30 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * 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 <mjambor@suse.cz>
tree-optimization/91579
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a34cb74..eb8bf13 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 0be7a01..e49e0d5 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 a5aa8d6..6a0ee28 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<mode>"
[(set (match_operand:VDX 0 "nonimmediate_operand"
"=w,Un,w, w, w, ?r,?w,?r, ?Us,*r")