===================================================================
@@ -7863,7 +7863,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
&& GET_CODE (SET_SRC (x)) == VEC_SELECT)
{
*total = rtx_cost (SET_DEST (x), code, 0, speed);
- if (!neon_vector_mem_operand (SET_DEST (x), 2))
+ if (!neon_vector_mem_operand (SET_DEST (x), 2, true))
*total += COSTS_N_INSNS (1);
return true;
}
@@ -7874,7 +7874,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
{
rtx mem = XEXP (XEXP (SET_SRC (x), 0), 0);
*total = rtx_cost (mem, code, 0, speed);
- if (!neon_vector_mem_operand (mem, 2))
+ if (!neon_vector_mem_operand (mem, 2, true))
*total += COSTS_N_INSNS (1);
return true;
}
@@ -10046,7 +10046,7 @@ arm_coproc_mem_operand (rtx op, bool wb)
2 - Element/structure loads (vld1)
*/
int
-neon_vector_mem_operand (rtx op, int type)
+neon_vector_mem_operand (rtx op, int type, bool strict)
{
rtx ind;
@@ -10058,7 +10058,7 @@ neon_vector_mem_operand (rtx op, int typ
|| reg_mentioned_p (virtual_outgoing_args_rtx, op)
|| reg_mentioned_p (virtual_stack_dynamic_rtx, op)
|| reg_mentioned_p (virtual_stack_vars_rtx, op)))
- return FALSE;
+ return !strict;
/* Constants are converted into offsets from labels. */
if (!MEM_P (op))
@@ -10168,7 +10168,7 @@ coproc_secondary_reload_class (enum mach
{
if (!TARGET_NEON_FP16)
return GENERAL_REGS;
- if (s_register_operand (x, mode) || neon_vector_mem_operand (x, 2))
+ if (s_register_operand (x, mode) || neon_vector_mem_operand (x, 2, true))
return NO_REGS;
return GENERAL_REGS;
}
===================================================================
@@ -95,7 +95,7 @@ extern enum reg_class coproc_secondary_r
extern bool arm_tls_referenced_p (rtx);
extern int arm_coproc_mem_operand (rtx, bool);
-extern int neon_vector_mem_operand (rtx, int);
+extern int neon_vector_mem_operand (rtx, int, bool);
extern int neon_struct_mem_operand (rtx);
extern int arm_no_early_store_addr_dep (rtx, rtx);
extern int arm_early_store_addr_dep (rtx, rtx);
===================================================================
@@ -241,8 +241,8 @@
})
(define_expand "movmisalign<mode>"
- [(set (match_operand:VDQX 0 "neon_struct_or_register_operand")
- (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_or_register_operand")]
+ [(set (match_operand:VDQX 0 "neon_perm_struct_or_reg_operand")
+ (unspec:VDQX [(match_operand:VDQX 1 "neon_perm_struct_or_reg_operand")]
UNSPEC_MISALIGNED_ACCESS))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
{
@@ -255,7 +255,7 @@
})
(define_insn "*movmisalign<mode>_neon_store"
- [(set (match_operand:VDX 0 "neon_struct_operand" "=Um")
+ [(set (match_operand:VDX 0 "neon_permissive_struct_operand" "=Um")
(unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")]
UNSPEC_MISALIGNED_ACCESS))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
@@ -263,15 +263,16 @@
[(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
(define_insn "*movmisalign<mode>_neon_load"
- [(set (match_operand:VDX 0 "s_register_operand" "=w")
- (unspec:VDX [(match_operand:VDX 1 "neon_struct_operand" " Um")]
+ [(set (match_operand:VDX 0 "s_register_operand" "=w")
+ (unspec:VDX [(match_operand:VDX 1 "neon_permissive_struct_operand"
+ " Um")]
UNSPEC_MISALIGNED_ACCESS))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vld1.<V_sz_elem>\t{%P0}, %A1"
[(set_attr "neon_type" "neon_vld1_1_2_regs")])
(define_insn "*movmisalign<mode>_neon_store"
- [(set (match_operand:VQX 0 "neon_struct_operand" "=Um")
+ [(set (match_operand:VQX 0 "neon_permissive_struct_operand" "=Um")
(unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")]
UNSPEC_MISALIGNED_ACCESS))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
@@ -279,8 +280,9 @@
[(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
(define_insn "*movmisalign<mode>_neon_load"
- [(set (match_operand:VQX 0 "s_register_operand" "=w")
- (unspec:VQX [(match_operand:VQX 1 "neon_struct_operand" " Um")]
+ [(set (match_operand:VQX 0 "s_register_operand" "=w")
+ (unspec:VQX [(match_operand:VQX 1 "neon_permissive_struct_operand"
+ " Um")]
UNSPEC_MISALIGNED_ACCESS))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vld1.<V_sz_elem>\t{%q0}, %A1"
===================================================================
@@ -358,21 +358,21 @@
In ARM/Thumb-2 state a valid address for Neon doubleword vector
load/store instructions."
(and (match_code "mem")
- (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 0)")))
+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 0, true)")))
(define_memory_constraint "Um"
"@internal
In ARM/Thumb-2 state a valid address for Neon element and structure
load/store instructions."
(and (match_code "mem")
- (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)")))
+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, true)")))
(define_memory_constraint "Us"
"@internal
In ARM/Thumb-2 state a valid address for non-offset loads/stores of
quad-word values in four ARM registers."
(and (match_code "mem")
- (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 1)")))
+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 1, true)")))
(define_memory_constraint "Uq"
"@internal
===================================================================
@@ -634,10 +634,14 @@
(define_predicate "neon_struct_operand"
(and (match_code "mem")
- (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)")))
+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, true)")))
-(define_predicate "neon_struct_or_register_operand"
- (ior (match_operand 0 "neon_struct_operand")
+(define_predicate "neon_permissive_struct_operand"
+ (and (match_code "mem")
+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, false)")))
+
+(define_predicate "neon_perm_struct_or_reg_operand"
+ (ior (match_operand 0 "neon_permissive_struct_operand")
(match_operand 0 "s_register_operand")))
(define_special_predicate "add_operator"