diff options
author | Julian Brown <julian@codesourcery.com> | 2011-07-08 17:30:43 +0000 |
---|---|---|
committer | Julian Brown <jules@gcc.gnu.org> | 2011-07-08 17:30:43 +0000 |
commit | 0094f21b6186ed0ba4d580889164fb7ffd15b51f (patch) | |
tree | 4a47a99f3d86585455aa3623bed18af2e1685eff /gcc/config | |
parent | f8501f04ea07e18d68979c129d1ff2b1001e918d (diff) | |
download | gcc-0094f21b6186ed0ba4d580889164fb7ffd15b51f.zip gcc-0094f21b6186ed0ba4d580889164fb7ffd15b51f.tar.gz gcc-0094f21b6186ed0ba4d580889164fb7ffd15b51f.tar.bz2 |
neon.md (vec_shr_<mode>, [...]): Disable in big-endian mode.
gcc/
* config/arm/neon.md (vec_shr_<mode>, vec_shl_<mode>): Disable in
big-endian mode.
(reduc_splus_<mode>, reduc_uplus_<mode>, reduc_smin_<mode>)
(reduc_smax_<mode>, reduc_umin_<mode>, reduc_umax_<mode>)
(neon_vec_unpack<US>_lo_<mode>, neon_vec_unpack<US>_hi_<mode>)
(vec_unpack<US>_hi_<mode>, vec_unpack<US>_lo_<mode>)
(neon_vec_<US>mult_lo_<mode>, vec_widen_<US>mult_lo_<mode>)
(neon_vec_<US>mult_hi_<mode>, vec_widen_<US>mult_hi_<mode>)
(vec_pack_trunc_<mode>, neon_vec_pack_trunc_<mode>): Disable for Q
registers in big-endian mode.
gcc/testsuite/
* lib/target-supports.exp
(check_effective_target_arm_little_endian): New.
(check_effective_target_vect_pack_trunc): Use above.
(check_effective_target_vect_unpack): Likewise.
(check_effective_target_vect_element_align): Test
check_effective_target_arm_vect_no_misalign for ARM.
From-SVN: r176050
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/arm/neon.md | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 2c109e0..becb524 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -1116,11 +1116,14 @@ ;; shift-count granularity. That's good enough for the middle-end's current ;; needs. +;; Note that it's not safe to perform such an operation in big-endian mode, +;; due to element-ordering issues. + (define_expand "vec_shr_<mode>" [(match_operand:VDQ 0 "s_register_operand" "") (match_operand:VDQ 1 "s_register_operand" "") (match_operand:SI 2 "const_multiple_of_8_operand" "")] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtx zero_reg; HOST_WIDE_INT num_bits = INTVAL (operands[2]); @@ -1148,7 +1151,7 @@ [(match_operand:VDQ 0 "s_register_operand" "") (match_operand:VDQ 1 "s_register_operand" "") (match_operand:SI 2 "const_multiple_of_8_operand" "")] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtx zero_reg; HOST_WIDE_INT num_bits = INTVAL (operands[2]); @@ -1344,7 +1347,8 @@ (define_expand "reduc_splus_<mode>" [(match_operand:VQ 0 "s_register_operand" "") (match_operand:VQ 1 "s_register_operand" "")] - "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" + "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations) + && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (<V_HALF>mode); rtx res_d = gen_reg_rtx (<V_HALF>mode); @@ -1360,7 +1364,7 @@ [(set (match_operand:V2DI 0 "s_register_operand" "=w") (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")] UNSPEC_VPADD))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vadd.i64\t%e0, %e1, %f1" [(set_attr "neon_type" "neon_int_1")] ) @@ -1370,7 +1374,7 @@ (define_expand "reduc_uplus_<mode>" [(match_operand:VDQI 0 "s_register_operand" "") (match_operand:VDQI 1 "s_register_operand" "")] - "TARGET_NEON" + "TARGET_NEON && (<Is_d_reg> || !BYTES_BIG_ENDIAN)" { emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1])); DONE; @@ -1389,7 +1393,8 @@ (define_expand "reduc_smin_<mode>" [(match_operand:VQ 0 "s_register_operand" "") (match_operand:VQ 1 "s_register_operand" "")] - "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" + "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations) + && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (<V_HALF>mode); rtx res_d = gen_reg_rtx (<V_HALF>mode); @@ -1414,7 +1419,8 @@ (define_expand "reduc_smax_<mode>" [(match_operand:VQ 0 "s_register_operand" "") (match_operand:VQ 1 "s_register_operand" "")] - "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" + "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations) + && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (<V_HALF>mode); rtx res_d = gen_reg_rtx (<V_HALF>mode); @@ -1439,7 +1445,7 @@ (define_expand "reduc_umin_<mode>" [(match_operand:VQI 0 "s_register_operand" "") (match_operand:VQI 1 "s_register_operand" "")] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (<V_HALF>mode); rtx res_d = gen_reg_rtx (<V_HALF>mode); @@ -1464,7 +1470,7 @@ (define_expand "reduc_umax_<mode>" [(match_operand:VQI 0 "s_register_operand" "") (match_operand:VQI 1 "s_register_operand" "")] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (<V_HALF>mode); rtx res_d = gen_reg_rtx (<V_HALF>mode); @@ -5423,7 +5429,7 @@ (SE:<V_unpack> (vec_select:<V_HALF> (match_operand:VU 1 "register_operand" "w") (match_operand:VU 2 "vect_par_constant_low" ""))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovl.<US><V_sz_elem> %q0, %e1" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5433,7 +5439,7 @@ (SE:<V_unpack> (vec_select:<V_HALF> (match_operand:VU 1 "register_operand" "w") (match_operand:VU 2 "vect_par_constant_high" ""))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovl.<US><V_sz_elem> %q0, %f1" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5441,7 +5447,7 @@ (define_expand "vec_unpack<US>_hi_<mode>" [(match_operand:<V_unpack> 0 "register_operand" "") (SE:<V_unpack> (match_operand:VU 1 "register_operand"))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtvec v = rtvec_alloc (<V_mode_nunits>/2) ; rtx t1; @@ -5460,7 +5466,7 @@ (define_expand "vec_unpack<US>_lo_<mode>" [(match_operand:<V_unpack> 0 "register_operand" "") (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtvec v = rtvec_alloc (<V_mode_nunits>/2) ; rtx t1; @@ -5483,7 +5489,7 @@ (SE:<V_unpack> (vec_select:<V_HALF> (match_operand:VU 3 "register_operand" "w") (match_dup 2)))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmull.<US><V_sz_elem> %q0, %e1, %e3" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5492,7 +5498,7 @@ [(match_operand:<V_unpack> 0 "register_operand" "") (SE:<V_unpack> (match_operand:VU 1 "register_operand" "")) (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtvec v = rtvec_alloc (<V_mode_nunits>/2) ; rtx t1; @@ -5517,7 +5523,7 @@ (SE:<V_unpack> (vec_select:<V_HALF> (match_operand:VU 3 "register_operand" "w") (match_dup 2)))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmull.<US><V_sz_elem> %q0, %f1, %f3" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5526,7 +5532,7 @@ [(match_operand:<V_unpack> 0 "register_operand" "") (SE:<V_unpack> (match_operand:VU 1 "register_operand" "")) (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtvec v = rtvec_alloc (<V_mode_nunits>/2) ; rtx t1; @@ -5620,6 +5626,10 @@ } ) +; FIXME: These instruction patterns can't be used safely in big-endian mode +; because the ordering of vector elements in Q registers is different from what +; the semantics of the instructions require. + (define_insn "vec_pack_trunc_<mode>" [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w") (vec_concat:<V_narrow_pack> @@ -5627,7 +5637,7 @@ (match_operand:VN 1 "register_operand" "w")) (truncate:<V_narrow> (match_operand:VN 2 "register_operand" "w"))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2" [(set_attr "neon_type" "neon_shift_1") (set_attr "length" "8")] @@ -5637,7 +5647,7 @@ (define_insn "neon_vec_pack_trunc_<mode>" [(set (match_operand:<V_narrow> 0 "register_operand" "=w") (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovn.i<V_sz_elem>\t%P0, %q1" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5646,7 +5656,7 @@ [(match_operand:<V_narrow_pack> 0 "register_operand" "") (match_operand:VSHFT 1 "register_operand" "") (match_operand:VSHFT 2 "register_operand")] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode); |