While working on another patch, I noticed that the new misaligned load/store patterns allow REG+CONST addresses before reload, even though the instruction (and its constraints) don't.
This patch tightens the predicatese to match the existing vstN patterns. It depends on: http://gcc.gnu.org/ml/gcc-patches/2011-07/msg00795.html which I've justed applied. The patch also makes neon_struct_operand a normal predicate instead of a special predicate. That was a cut-&-pasto of mine, sorry. Tested on arm-linux-gnueabi. OK to install? Richard gcc/ * config/arm/predicates.md (neon_struct_operand): Make a normal predicate. (neon_struct_or_register_operand): New predicate. * config/arm/neon.md (movmisalign<mode>): Replace predicates with neon_struct_or_register_operand. (*movmisalign<mode>_neon_store, *movmisalign<mode>_neon_load): Use neon_struct_operand instead of memory_operand. Index: gcc/config/arm/predicates.md =================================================================== --- gcc/config/arm/predicates.md 2011-07-11 11:29:58.000000000 +0100 +++ gcc/config/arm/predicates.md 2011-07-11 13:14:25.000000000 +0100 @@ -732,9 +732,13 @@ (define_special_predicate "vect_par_cons return true; }) -(define_special_predicate "neon_struct_operand" +(define_predicate "neon_struct_operand" (and (match_code "mem") (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)"))) +(define_predicate "neon_struct_or_register_operand" + (ior (match_operand 0 "neon_struct_operand") + (match_operand 0 "s_register_operand"))) + (define_special_predicate "add_operator" (match_code "plus")) Index: gcc/config/arm/neon.md =================================================================== --- gcc/config/arm/neon.md 2011-07-11 12:21:19.000000000 +0100 +++ gcc/config/arm/neon.md 2011-07-11 13:14:25.000000000 +0100 @@ -372,8 +372,8 @@ (define_split }) (define_expand "movmisalign<mode>" - [(set (match_operand:VDQX 0 "nonimmediate_operand" "") - (unspec:VDQX [(match_operand:VDQX 1 "general_operand" "")] + [(set (match_operand:VDQX 0 "neon_struct_or_register_operand") + (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_or_register_operand")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" { @@ -386,7 +386,7 @@ (define_expand "movmisalign<mode>" }) (define_insn "*movmisalign<mode>_neon_store" - [(set (match_operand:VDX 0 "memory_operand" "=Um") + [(set (match_operand:VDX 0 "neon_struct_operand" "=Um") (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" @@ -394,15 +394,15 @@ (define_insn "*movmisalign<mode>_neon_st [(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 "memory_operand" " Um")] + [(set (match_operand:VDX 0 "s_register_operand" "=w") + (unspec:VDX [(match_operand:VDX 1 "neon_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 "memory_operand" "=Um") + [(set (match_operand:VQX 0 "neon_struct_operand" "=Um") (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" @@ -410,8 +410,8 @@ (define_insn "*movmisalign<mode>_neon_st [(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 "memory_operand" " Um")] + [(set (match_operand:VQX 0 "s_register_operand" "=w") + (unspec:VQX [(match_operand:VQX 1 "neon_struct_operand" " Um")] UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vld1.<V_sz_elem>\t{%q0}, %A1"