This patch adds vec_load_lanes and vec_store_lanes patterns for NEON. They feed directly into the corresponding intrinsic patterns.
Tested on x86_64-linux-gnu and arm-linux-gnueabi. OK to install? Richard gcc/ * config/arm/neon.md (vec_load_lanes<mode><mode>): New expanders, (vec_store_lanes<mode><mode>): Likewise. Index: gcc/config/arm/neon.md =================================================================== --- gcc/config/arm/neon.md 2011-04-12 11:54:04.000000000 +0100 +++ gcc/config/arm/neon.md 2011-04-12 11:55:11.000000000 +0100 @@ -4258,6 +4258,12 @@ (define_expand "neon_vreinterpretv2di<mo DONE; }) +(define_expand "vec_load_lanes<mode><mode>" + [(set (match_operand:VDQX 0 "s_register_operand") + (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand")] + UNSPEC_VLD1))] + "TARGET_NEON") + (define_insn "neon_vld1<mode>" [(set (match_operand:VDQX 0 "s_register_operand" "=w") (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand" "Um")] @@ -4355,6 +4361,12 @@ (define_insn "neon_vld1_dup<mode>" (const_string "neon_vld1_1_2_regs")))] ) +(define_expand "vec_store_lanes<mode><mode>" + [(set (match_operand:VDQX 0 "neon_struct_operand") + (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand")] + UNSPEC_VST1))] + "TARGET_NEON") + (define_insn "neon_vst1<mode>" [(set (match_operand:VDQX 0 "neon_struct_operand" "=Um") (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")] @@ -4411,6 +4423,13 @@ (define_insn "neon_vst1_lane<mode>" [(set_attr "neon_type" "neon_vst1_vst2_lane")] ) +(define_expand "vec_load_lanesti<mode>" + [(set (match_operand:TI 0 "s_register_operand") + (unspec:TI [(match_operand:TI 1 "neon_struct_operand") + (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD2))] + "TARGET_NEON") + (define_insn "neon_vld2<mode>" [(set (match_operand:TI 0 "s_register_operand" "=w") (unspec:TI [(match_operand:TI 1 "neon_struct_operand" "Um") @@ -4429,6 +4448,13 @@ (define_insn "neon_vld2<mode>" (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))] ) +(define_expand "vec_load_lanesoi<mode>" + [(set (match_operand:OI 0 "s_register_operand") + (unspec:OI [(match_operand:OI 1 "neon_struct_operand") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD2))] + "TARGET_NEON") + (define_insn "neon_vld2<mode>" [(set (match_operand:OI 0 "s_register_operand" "=w") (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um") @@ -4511,6 +4537,13 @@ (define_insn "neon_vld2_dup<mode>" (const_string "neon_vld1_1_2_regs")))] ) +(define_expand "vec_store_lanesti<mode>" + [(set (match_operand:TI 0 "neon_struct_operand") + (unspec:TI [(match_operand:TI 1 "s_register_operand") + (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST2))] + "TARGET_NEON") + (define_insn "neon_vst2<mode>" [(set (match_operand:TI 0 "neon_struct_operand" "=Um") (unspec:TI [(match_operand:TI 1 "s_register_operand" "w") @@ -4529,6 +4562,13 @@ (define_insn "neon_vst2<mode>" (const_string "neon_vst1_1_2_regs_vst2_2_regs")))] ) +(define_expand "vec_store_lanesoi<mode>" + [(set (match_operand:OI 0 "neon_struct_operand") + (unspec:OI [(match_operand:OI 1 "s_register_operand") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST2))] + "TARGET_NEON") + (define_insn "neon_vst2<mode>" [(set (match_operand:OI 0 "neon_struct_operand" "=Um") (unspec:OI [(match_operand:OI 1 "s_register_operand" "w") @@ -4594,6 +4634,13 @@ (define_insn "neon_vst2_lane<mode>" [(set_attr "neon_type" "neon_vst1_vst2_lane")] ) +(define_expand "vec_load_lanesei<mode>" + [(set (match_operand:EI 0 "s_register_operand") + (unspec:EI [(match_operand:EI 1 "neon_struct_operand") + (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD3))] + "TARGET_NEON") + (define_insn "neon_vld3<mode>" [(set (match_operand:EI 0 "s_register_operand" "=w") (unspec:EI [(match_operand:EI 1 "neon_struct_operand" "Um") @@ -4612,6 +4659,16 @@ (define_insn "neon_vld3<mode>" (const_string "neon_vld3_vld4")))] ) +(define_expand "vec_load_lanesci<mode>" + [(match_operand:CI 0 "s_register_operand") + (match_operand:CI 1 "neon_struct_operand") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_NEON" +{ + emit_insn (gen_neon_vld3<mode> (operands[0], operands[1])); + DONE; +}) + (define_expand "neon_vld3<mode>" [(match_operand:CI 0 "s_register_operand") (match_operand:CI 1 "neon_struct_operand") @@ -4751,6 +4808,13 @@ (define_insn "neon_vld3_dup<mode>" (const_string "neon_vld3_vld4_all_lanes") (const_string "neon_vld1_1_2_regs")))]) +(define_expand "vec_store_lanesei<mode>" + [(set (match_operand:EI 0 "neon_struct_operand") + (unspec:EI [(match_operand:EI 1 "s_register_operand") + (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST3))] + "TARGET_NEON") + (define_insn "neon_vst3<mode>" [(set (match_operand:EI 0 "neon_struct_operand" "=Um") (unspec:EI [(match_operand:EI 1 "s_register_operand" "w") @@ -4768,6 +4832,16 @@ (define_insn "neon_vst3<mode>" (const_string "neon_vst1_1_2_regs_vst2_2_regs") (const_string "neon_vst2_4_regs_vst3_vst4")))]) +(define_expand "vec_store_lanesci<mode>" + [(match_operand:CI 0 "neon_struct_operand") + (match_operand:CI 1 "s_register_operand") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_NEON" +{ + emit_insn (gen_neon_vst3<mode> (operands[0], operands[1])); + DONE; +}) + (define_expand "neon_vst3<mode>" [(match_operand:CI 0 "neon_struct_operand") (match_operand:CI 1 "s_register_operand") @@ -4879,6 +4953,13 @@ (define_insn "neon_vst3_lane<mode>" } [(set_attr "neon_type" "neon_vst3_vst4_lane")]) +(define_expand "vec_load_lanesoi<mode>" + [(set (match_operand:OI 0 "s_register_operand") + (unspec:OI [(match_operand:OI 1 "neon_struct_operand") + (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VLD4))] + "TARGET_NEON") + (define_insn "neon_vld4<mode>" [(set (match_operand:OI 0 "s_register_operand" "=w") (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um") @@ -4897,6 +4978,16 @@ (define_insn "neon_vld4<mode>" (const_string "neon_vld3_vld4")))] ) +(define_expand "vec_load_lanesxi<mode>" + [(match_operand:XI 0 "s_register_operand") + (match_operand:XI 1 "neon_struct_operand") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_NEON" +{ + emit_insn (gen_neon_vld4<mode> (operands[0], operands[1])); + DONE; +}) + (define_expand "neon_vld4<mode>" [(match_operand:XI 0 "s_register_operand") (match_operand:XI 1 "neon_struct_operand") @@ -5043,6 +5134,13 @@ (define_insn "neon_vld4_dup<mode>" (const_string "neon_vld1_1_2_regs")))] ) +(define_expand "vec_store_lanesoi<mode>" + [(set (match_operand:OI 0 "neon_struct_operand") + (unspec:OI [(match_operand:OI 1 "s_register_operand") + (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_VST4))] + "TARGET_NEON") + (define_insn "neon_vst4<mode>" [(set (match_operand:OI 0 "neon_struct_operand" "=Um") (unspec:OI [(match_operand:OI 1 "s_register_operand" "w") @@ -5061,6 +5159,16 @@ (define_insn "neon_vst4<mode>" (const_string "neon_vst2_4_regs_vst3_vst4")))] ) +(define_expand "vec_store_lanesxi<mode>" + [(match_operand:XI 0 "neon_struct_operand") + (match_operand:XI 1 "s_register_operand") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_NEON" +{ + emit_insn (gen_neon_vst4<mode> (operands[0], operands[1])); + DONE; +}) + (define_expand "neon_vst4<mode>" [(match_operand:XI 0 "neon_struct_operand") (match_operand:XI 1 "s_register_operand")