From: Julian Brown Date: Fri, 8 Jul 2011 17:30:43 +0000 (+0000) Subject: neon.md (vec_shr_, [...]): Disable in big-endian mode. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0094f21b6186ed0ba4d580889164fb7ffd15b51f;p=gcc.git neon.md (vec_shr_, [...]): Disable in big-endian mode. gcc/ * config/arm/neon.md (vec_shr_, vec_shl_): Disable in big-endian mode. (reduc_splus_, reduc_uplus_, reduc_smin_) (reduc_smax_, reduc_umin_, reduc_umax_) (neon_vec_unpack_lo_, neon_vec_unpack_hi_) (vec_unpack_hi_, vec_unpack_lo_) (neon_vec_mult_lo_, vec_widen_mult_lo_) (neon_vec_mult_hi_, vec_widen_mult_hi_) (vec_pack_trunc_, neon_vec_pack_trunc_): 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60cc66d6f08..52f3d7b1fe6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2011-07-08 Julian Brown + + * config/arm/neon.md (vec_shr_, vec_shl_): Disable in + big-endian mode. + (reduc_splus_, reduc_uplus_, reduc_smin_) + (reduc_smax_, reduc_umin_, reduc_umax_) + (neon_vec_unpack_lo_, neon_vec_unpack_hi_) + (vec_unpack_hi_, vec_unpack_lo_) + (neon_vec_mult_lo_, vec_widen_mult_lo_) + (neon_vec_mult_hi_, vec_widen_mult_hi_) + (vec_pack_trunc_, neon_vec_pack_trunc_): Disable for Q + registers in big-endian mode. + 2011-07-08 Bernd Schmidt * genattrtab.c (evaluate_eq_attr): Allow an attribute to be defined diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 2c109e09ac6..becb5240a32 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_" [(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_" [(match_operand:VQ 0 "s_register_operand" "") (match_operand:VQ 1 "s_register_operand" "")] - "TARGET_NEON && (! || flag_unsafe_math_optimizations)" + "TARGET_NEON && (! || flag_unsafe_math_optimizations) + && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (mode); rtx res_d = gen_reg_rtx (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_" [(match_operand:VDQI 0 "s_register_operand" "") (match_operand:VDQI 1 "s_register_operand" "")] - "TARGET_NEON" + "TARGET_NEON && ( || !BYTES_BIG_ENDIAN)" { emit_insn (gen_reduc_splus_ (operands[0], operands[1])); DONE; @@ -1389,7 +1393,8 @@ (define_expand "reduc_smin_" [(match_operand:VQ 0 "s_register_operand" "") (match_operand:VQ 1 "s_register_operand" "")] - "TARGET_NEON && (! || flag_unsafe_math_optimizations)" + "TARGET_NEON && (! || flag_unsafe_math_optimizations) + && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (mode); rtx res_d = gen_reg_rtx (mode); @@ -1414,7 +1419,8 @@ (define_expand "reduc_smax_" [(match_operand:VQ 0 "s_register_operand" "") (match_operand:VQ 1 "s_register_operand" "")] - "TARGET_NEON && (! || flag_unsafe_math_optimizations)" + "TARGET_NEON && (! || flag_unsafe_math_optimizations) + && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (mode); rtx res_d = gen_reg_rtx (mode); @@ -1439,7 +1445,7 @@ (define_expand "reduc_umin_" [(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 (mode); rtx res_d = gen_reg_rtx (mode); @@ -1464,7 +1470,7 @@ (define_expand "reduc_umax_" [(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 (mode); rtx res_d = gen_reg_rtx (mode); @@ -5423,7 +5429,7 @@ (SE: (vec_select: (match_operand:VU 1 "register_operand" "w") (match_operand:VU 2 "vect_par_constant_low" ""))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovl. %q0, %e1" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5433,7 +5439,7 @@ (SE: (vec_select: (match_operand:VU 1 "register_operand" "w") (match_operand:VU 2 "vect_par_constant_high" ""))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovl. %q0, %f1" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5441,7 +5447,7 @@ (define_expand "vec_unpack_hi_" [(match_operand: 0 "register_operand" "") (SE: (match_operand:VU 1 "register_operand"))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtvec v = rtvec_alloc (/2) ; rtx t1; @@ -5460,7 +5466,7 @@ (define_expand "vec_unpack_lo_" [(match_operand: 0 "register_operand" "") (SE: (match_operand:VU 1 "register_operand" ""))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtvec v = rtvec_alloc (/2) ; rtx t1; @@ -5483,7 +5489,7 @@ (SE: (vec_select: (match_operand:VU 3 "register_operand" "w") (match_dup 2)))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmull. %q0, %e1, %e3" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5492,7 +5498,7 @@ [(match_operand: 0 "register_operand" "") (SE: (match_operand:VU 1 "register_operand" "")) (SE: (match_operand:VU 2 "register_operand" ""))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtvec v = rtvec_alloc (/2) ; rtx t1; @@ -5517,7 +5523,7 @@ (SE: (vec_select: (match_operand:VU 3 "register_operand" "w") (match_dup 2)))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmull. %q0, %f1, %f3" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5526,7 +5532,7 @@ [(match_operand: 0 "register_operand" "") (SE: (match_operand:VU 1 "register_operand" "")) (SE: (match_operand:VU 2 "register_operand" ""))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtvec v = rtvec_alloc (/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_" [(set (match_operand: 0 "register_operand" "=&w") (vec_concat: @@ -5627,7 +5637,7 @@ (match_operand:VN 1 "register_operand" "w")) (truncate: (match_operand:VN 2 "register_operand" "w"))))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovn.i\t%e0, %q1\;vmovn.i\t%f0, %q2" [(set_attr "neon_type" "neon_shift_1") (set_attr "length" "8")] @@ -5637,7 +5647,7 @@ (define_insn "neon_vec_pack_trunc_" [(set (match_operand: 0 "register_operand" "=w") (truncate: (match_operand:VN 1 "register_operand" "w")))] - "TARGET_NEON" + "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovn.i\t%P0, %q1" [(set_attr "neon_type" "neon_shift_1")] ) @@ -5646,7 +5656,7 @@ [(match_operand: 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 (mode); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9393815eab7..b2ba49aea53 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2011-07-08 Julian Brown + + * 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. + 2011-07-08 Jason Merrill PR c++/49673 diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 8b9c386f7a8..6ef87ab13ae 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1899,6 +1899,15 @@ proc check_effective_target_arm_nothumb { } { }] } +# Return 1 if this is a little-endian ARM target +proc check_effective_target_arm_little_endian { } { + return [check_no_compiler_messages arm_little_endian assembly { + #if !defined(__arm__) || !defined(__ARMEL__) + #error FOO + #endif + }] +} + # Return 1 if this is an ARM target that only supports aligned vector accesses proc check_effective_target_arm_vect_no_misalign { } { return [check_no_compiler_messages arm_vect_no_misalign assembly { @@ -2953,7 +2962,8 @@ proc check_effective_target_vect_pack_trunc { } { || [istarget i?86-*-*] || [istarget x86_64-*-*] || [istarget spu-*-*] - || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } { + || ([istarget arm*-*-*] && [check_effective_target_arm_neon] + && [check_effective_target_arm_little_endian]) } { set et_vect_pack_trunc_saved 1 } } @@ -2978,7 +2988,8 @@ proc check_effective_target_vect_unpack { } { || [istarget x86_64-*-*] || [istarget spu-*-*] || [istarget ia64-*-*] - || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } { + || ([istarget arm*-*-*] && [check_effective_target_arm_neon] + && [check_effective_target_arm_little_endian]) } { set et_vect_unpack_saved 1 } } @@ -3164,7 +3175,8 @@ proc check_effective_target_vect_element_align { } { verbose "check_effective_target_vect_element_align: using cached result" 2 } else { set et_vect_element_align 0 - if { [istarget arm*-*-*] + if { ([istarget arm*-*-*] + && ![check_effective_target_arm_vect_no_misalign]) || [check_effective_target_vect_hw_misalign] } { set et_vect_element_align 1 }