+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
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));
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));
{
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
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. */
; 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")]
(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")]
;; 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")