diff options
Diffstat (limited to 'gcc/config/arm/neon.md')
-rw-r--r-- | gcc/config/arm/neon.md | 1177 |
1 files changed, 555 insertions, 622 deletions
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index aad420ce785..63c327ec68c 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -1,5 +1,5 @@ ;; ARM NEON coprocessor Machine Description -;; Copyright (C) 2006-2014 Free Software Foundation, Inc. +;; Copyright (C) 2006-2015 Free Software Foundation, Inc. ;; Written by CodeSourcery. ;; ;; This file is part of GCC. @@ -296,7 +296,7 @@ UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vld1.<V_sz_elem>\t{%q0}, %A1" - [(set_attr "type" "neon_store1_1reg<q>")]) + [(set_attr "type" "neon_load1_1reg<q>")]) (define_insn "vec_set<mode>_internal" [(set (match_operand:VD 0 "s_register_operand" "=w,w") @@ -629,6 +629,17 @@ [(set_attr "type" "neon_fp_round_<V_elem_ch><q>")] ) +(define_insn "neon_vcvt<NEON_VCVT:nvrint_variant><su_optab><VCVTF:mode><v_cmp_result>" + [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w") + (FIXUORS:<V_cmp_result> (unspec:VCVTF + [(match_operand:VCVTF 1 "register_operand" "w")] + NEON_VCVT)))] + "TARGET_NEON && TARGET_FPU_ARMV8" + "vcvt<nvrint_variant>.<su>32.f32\\t%<V_reg>0, %<V_reg>1" + [(set_attr "type" "neon_fp_to_int_<V_elem_ch><q>") + (set_attr "predicable" "no")] +) + (define_insn "ior<mode>3" [(set (match_operand:VDQ 0 "s_register_operand" "=w,w") (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0") @@ -728,7 +739,7 @@ ;; Compare to *anddi_notdi_di. (define_insn "bicdi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r") + [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r") (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0")) (match_operand:DI 1 "s_register_operand" "w,0,r")))] "TARGET_NEON" @@ -1041,7 +1052,9 @@ } else { - if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1) + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1 + && (!reg_overlap_mentioned_p (operands[0], operands[1]) + || REGNO (operands[0]) == REGNO (operands[1]))) /* This clobbers CC. */ emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1])); else @@ -1141,7 +1154,9 @@ } else { - if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1) + if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1 + && (!reg_overlap_mentioned_p (operands[0], operands[1]) + || REGNO (operands[0]) == REGNO (operands[1]))) /* This clobbers CC. */ emit_insn (gen_arm_<shift>di3_1bit (operands[0], operands[1])); else @@ -1195,7 +1210,7 @@ rtx zero_reg; HOST_WIDE_INT num_bits = INTVAL (operands[2]); const int width = GET_MODE_BITSIZE (<MODE>mode); - const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode; + const machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode; rtx (*gen_ext) (rtx, rtx, rtx, rtx) = (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi; @@ -1223,7 +1238,7 @@ rtx zero_reg; HOST_WIDE_INT num_bits = INTVAL (operands[2]); const int width = GET_MODE_BITSIZE (<MODE>mode); - const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode; + const machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode; rtx (*gen_ext) (rtx, rtx, rtx, rtx) = (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi; @@ -1334,33 +1349,47 @@ ;; Reduction operations -(define_expand "reduc_splus_<mode>" - [(match_operand:VD 0 "s_register_operand" "") +(define_expand "reduc_plus_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VD 1 "s_register_operand" "")] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" { - neon_pairwise_reduce (operands[0], operands[1], <MODE>mode, + rtx vec = gen_reg_rtx (<MODE>mode); + neon_pairwise_reduce (vec, operands[1], <MODE>mode, &gen_neon_vpadd_internal<mode>); + /* The same result is actually computed into every element. */ + emit_insn (gen_vec_extract<mode> (operands[0], vec, const0_rtx)); DONE; }) -(define_expand "reduc_splus_<mode>" - [(match_operand:VQ 0 "s_register_operand" "") +(define_expand "reduc_plus_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VQ 1 "s_register_operand" "")] "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); emit_insn (gen_quad_halves_plus<mode> (step1, operands[1])); - emit_insn (gen_reduc_splus_<V_half> (res_d, step1)); - emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d)); + emit_insn (gen_reduc_plus_scal_<V_half> (operands[0], step1)); DONE; }) -(define_insn "reduc_splus_v2di" +(define_expand "reduc_plus_scal_v2di" + [(match_operand:DI 0 "nonimmediate_operand" "=w") + (match_operand:V2DI 1 "s_register_operand" "")] + "TARGET_NEON && !BYTES_BIG_ENDIAN" +{ + rtx vec = gen_reg_rtx (V2DImode); + + emit_insn (gen_arm_reduc_plus_internal_v2di (vec, operands[1])); + emit_insn (gen_vec_extractv2di (operands[0], vec, const0_rtx)); + + DONE; +}) + +(define_insn "arm_reduc_plus_internal_v2di" [(set (match_operand:V2DI 0 "s_register_operand" "=w") (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")] UNSPEC_VPADD))] @@ -1369,115 +1398,109 @@ [(set_attr "type" "neon_add_q")] ) -;; NEON does not distinguish between signed and unsigned addition except on -;; widening operations. -(define_expand "reduc_uplus_<mode>" - [(match_operand:VDQI 0 "s_register_operand" "") - (match_operand:VDQI 1 "s_register_operand" "")] - "TARGET_NEON && (<Is_d_reg> || !BYTES_BIG_ENDIAN)" -{ - emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1])); - DONE; -}) - -(define_expand "reduc_smin_<mode>" - [(match_operand:VD 0 "s_register_operand" "") +(define_expand "reduc_smin_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VD 1 "s_register_operand" "")] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" { - neon_pairwise_reduce (operands[0], operands[1], <MODE>mode, + rtx vec = gen_reg_rtx (<MODE>mode); + + neon_pairwise_reduce (vec, operands[1], <MODE>mode, &gen_neon_vpsmin<mode>); + /* The result is computed into every element of the vector. */ + emit_insn (gen_vec_extract<mode> (operands[0], vec, const0_rtx)); DONE; }) -(define_expand "reduc_smin_<mode>" - [(match_operand:VQ 0 "s_register_operand" "") +(define_expand "reduc_smin_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VQ 1 "s_register_operand" "")] "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); emit_insn (gen_quad_halves_smin<mode> (step1, operands[1])); - emit_insn (gen_reduc_smin_<V_half> (res_d, step1)); - emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d)); + emit_insn (gen_reduc_smin_scal_<V_half> (operands[0], step1)); DONE; }) -(define_expand "reduc_smax_<mode>" - [(match_operand:VD 0 "s_register_operand" "") +(define_expand "reduc_smax_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VD 1 "s_register_operand" "")] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" { - neon_pairwise_reduce (operands[0], operands[1], <MODE>mode, + rtx vec = gen_reg_rtx (<MODE>mode); + neon_pairwise_reduce (vec, operands[1], <MODE>mode, &gen_neon_vpsmax<mode>); + /* The result is computed into every element of the vector. */ + emit_insn (gen_vec_extract<mode> (operands[0], vec, const0_rtx)); DONE; }) -(define_expand "reduc_smax_<mode>" - [(match_operand:VQ 0 "s_register_operand" "") +(define_expand "reduc_smax_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VQ 1 "s_register_operand" "")] "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); emit_insn (gen_quad_halves_smax<mode> (step1, operands[1])); - emit_insn (gen_reduc_smax_<V_half> (res_d, step1)); - emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d)); + emit_insn (gen_reduc_smax_scal_<V_half> (operands[0], step1)); DONE; }) -(define_expand "reduc_umin_<mode>" - [(match_operand:VDI 0 "s_register_operand" "") +(define_expand "reduc_umin_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VDI 1 "s_register_operand" "")] "TARGET_NEON" { - neon_pairwise_reduce (operands[0], operands[1], <MODE>mode, + rtx vec = gen_reg_rtx (<MODE>mode); + neon_pairwise_reduce (vec, operands[1], <MODE>mode, &gen_neon_vpumin<mode>); + /* The result is computed into every element of the vector. */ + emit_insn (gen_vec_extract<mode> (operands[0], vec, const0_rtx)); DONE; }) -(define_expand "reduc_umin_<mode>" - [(match_operand:VQI 0 "s_register_operand" "") +(define_expand "reduc_umin_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VQI 1 "s_register_operand" "")] "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (<V_HALF>mode); - rtx res_d = gen_reg_rtx (<V_HALF>mode); emit_insn (gen_quad_halves_umin<mode> (step1, operands[1])); - emit_insn (gen_reduc_umin_<V_half> (res_d, step1)); - emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d)); + emit_insn (gen_reduc_umin_scal_<V_half> (operands[0], step1)); DONE; }) -(define_expand "reduc_umax_<mode>" - [(match_operand:VDI 0 "s_register_operand" "") +(define_expand "reduc_umax_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VDI 1 "s_register_operand" "")] "TARGET_NEON" { - neon_pairwise_reduce (operands[0], operands[1], <MODE>mode, + rtx vec = gen_reg_rtx (<MODE>mode); + neon_pairwise_reduce (vec, operands[1], <MODE>mode, &gen_neon_vpumax<mode>); + /* The result is computed into every element of the vector. */ + emit_insn (gen_vec_extract<mode> (operands[0], vec, const0_rtx)); DONE; }) -(define_expand "reduc_umax_<mode>" - [(match_operand:VQI 0 "s_register_operand" "") +(define_expand "reduc_umax_scal_<mode>" + [(match_operand:<V_elem> 0 "nonimmediate_operand" "") (match_operand:VQI 1 "s_register_operand" "")] "TARGET_NEON && !BYTES_BIG_ENDIAN" { rtx step1 = gen_reg_rtx (<V_HALF>mode); - rtx res_d = gen_reg_rtx (<V_HALF>mode); emit_insn (gen_quad_halves_umax<mode> (step1, operands[1])); - emit_insn (gen_reduc_umax_<V_half> (res_d, step1)); - emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d)); + emit_insn (gen_reduc_umax_scal_<V_half> (operands[0], step1)); DONE; }) @@ -1604,17 +1627,14 @@ (match_operand:VDQW 2 "s_register_operand" "")))] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" { - HOST_WIDE_INT magic_word = (<MODE>mode == V2SFmode || <MODE>mode == V4SFmode) - ? 3 : 1; - rtx magic_rtx = GEN_INT (magic_word); int inverse = 0; int use_zero_form = 0; int swap_bsl_operands = 0; rtx mask = gen_reg_rtx (<V_cmp_result>mode); rtx tmp = gen_reg_rtx (<V_cmp_result>mode); - rtx (*base_comparison) (rtx, rtx, rtx, rtx); - rtx (*complimentary_comparison) (rtx, rtx, rtx, rtx); + rtx (*base_comparison) (rtx, rtx, rtx); + rtx (*complimentary_comparison) (rtx, rtx, rtx); switch (GET_CODE (operands[3])) { @@ -1701,9 +1721,9 @@ } if (!inverse) - emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx)); + emit_insn (base_comparison (mask, operands[4], operands[5])); else - emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx)); + emit_insn (complimentary_comparison (mask, operands[5], operands[4])); break; case UNLT: case UNLE: @@ -1723,9 +1743,9 @@ a NE b -> !(a EQ b) */ if (inverse) - emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx)); + emit_insn (base_comparison (mask, operands[4], operands[5])); else - emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx)); + emit_insn (complimentary_comparison (mask, operands[5], operands[4])); swap_bsl_operands = 1; break; @@ -1734,8 +1754,8 @@ true iff !(a != b && a ORDERED b), swapping the operands to BSL will then give us (a == b || a UNORDERED b) as intended. */ - emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5], magic_rtx)); - emit_insn (gen_neon_vcgt<mode> (tmp, operands[5], operands[4], magic_rtx)); + emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5])); + emit_insn (gen_neon_vcgt<mode> (tmp, operands[5], operands[4])); emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp)); swap_bsl_operands = 1; break; @@ -1745,8 +1765,8 @@ swap_bsl_operands = 1; /* Fall through. */ case ORDERED: - emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5], magic_rtx)); - emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4], magic_rtx)); + emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5])); + emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4])); emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp)); break; default: @@ -1785,41 +1805,33 @@ switch (GET_CODE (operands[3])) { case GEU: - emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5], - const0_rtx)); + emit_insn (gen_neon_vcgeu<mode> (mask, operands[4], operands[5])); break; case GTU: - emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5], - const0_rtx)); + emit_insn (gen_neon_vcgtu<mode> (mask, operands[4], operands[5])); break; case EQ: - emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5], - const0_rtx)); + emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5])); break; case LEU: if (immediate_zero) - emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5], - const0_rtx)); + emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5])); else - emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4], - const0_rtx)); + emit_insn (gen_neon_vcgeu<mode> (mask, operands[5], operands[4])); break; case LTU: if (immediate_zero) - emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5], - const0_rtx)); + emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5])); else - emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4], - const0_rtx)); + emit_insn (gen_neon_vcgtu<mode> (mask, operands[5], operands[4])); break; case NE: - emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5], - const0_rtx)); + emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5])); inverse = 1; break; @@ -1842,10 +1854,9 @@ ; good for plain vadd, vaddq. (define_expand "neon_vadd<mode>" - [(match_operand:VDQX 0 "s_register_operand" "=w") - (match_operand:VDQX 1 "s_register_operand" "w") - (match_operand:VDQX 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + [(match_operand:VCVTF 0 "s_register_operand" "=w") + (match_operand:VCVTF 1 "s_register_operand" "w") + (match_operand:VCVTF 2 "s_register_operand" "w")] "TARGET_NEON" { if (!<Is_float_mode> || flag_unsafe_math_optimizations) @@ -1869,9 +1880,9 @@ ; Used for intrinsics when flag_unsafe_math_optimizations is false. (define_insn "neon_vadd<mode>_unspec" - [(set (match_operand:VDQX 0 "s_register_operand" "=w") - (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w") - (match_operand:VDQX 2 "s_register_operand" "w")] + [(set (match_operand:VCVTF 0 "s_register_operand" "=w") + (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w") + (match_operand:VCVTF 2 "s_register_operand" "w")] UNSPEC_VADD))] "TARGET_NEON" "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" @@ -1881,77 +1892,66 @@ (const_string "neon_add<q>")))] ) -; operand 3 represents in bits: -; bit 0: signed (vs unsigned). -; bit 1: rounding (vs none). - -(define_insn "neon_vaddl<mode>" +(define_insn "neon_vaddl<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w") - (match_operand:VDI 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VADDL))] + (match_operand:VDI 2 "s_register_operand" "w")] + VADDL))] "TARGET_NEON" - "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2" + "vaddl.<sup>%#<V_sz_elem>\t%q0, %P1, %P2" [(set_attr "type" "neon_add_long")] ) -(define_insn "neon_vaddw<mode>" +(define_insn "neon_vaddw<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w") - (match_operand:VDI 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VADDW))] + (match_operand:VDI 2 "s_register_operand" "w")] + VADDW))] "TARGET_NEON" - "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2" + "vaddw.<sup>%#<V_sz_elem>\t%q0, %q1, %P2" [(set_attr "type" "neon_add_widen")] ) ; vhadd and vrhadd. -(define_insn "neon_vhadd<mode>" +(define_insn "neon_v<r>hadd<sup><mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:VDQIW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VHADD))] + (match_operand:VDQIW 2 "s_register_operand" "w")] + VHADD))] "TARGET_NEON" - "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "v<r>hadd.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_add_halve_q")] ) -(define_insn "neon_vqadd<mode>" +(define_insn "neon_vqadd<sup><mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w") - (match_operand:VDQIX 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VQADD))] + (match_operand:VDQIX 2 "s_register_operand" "w")] + VQADD))] "TARGET_NEON" - "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "vqadd.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_qadd<q>")] ) -(define_insn "neon_vaddhn<mode>" +(define_insn "neon_v<r>addhn<mode>" [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w") (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w") - (match_operand:VN 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VADDHN))] + (match_operand:VN 2 "s_register_operand" "w")] + VADDHN))] "TARGET_NEON" - "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2" + "v<r>addhn.<V_if_elem>\t%P0, %q1, %q2" [(set_attr "type" "neon_add_halve_narrow_q")] ) -;; We cannot replace this unspec with mul<mode>3 because of the odd -;; polynomial multiplication case that can specified by operand 3. -(define_insn "neon_vmul<mode>" - [(set (match_operand:VDQW 0 "s_register_operand" "=w") - (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] +;; Polynomial and Float multiplication. +(define_insn "neon_vmul<pf><mode>" + [(set (match_operand:VPF 0 "s_register_operand" "=w") + (unspec:VPF [(match_operand:VPF 1 "s_register_operand" "w") + (match_operand:VPF 2 "s_register_operand" "w")] UNSPEC_VMUL))] "TARGET_NEON" - "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "vmul.<pf>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_mul_s<q>") @@ -1962,8 +1962,7 @@ [(match_operand:VDQW 0 "s_register_operand" "=w") (match_operand:VDQW 1 "s_register_operand" "0") (match_operand:VDQW 2 "s_register_operand" "w") - (match_operand:VDQW 3 "s_register_operand" "w") - (match_operand:SI 4 "immediate_operand" "i")] + (match_operand:VDQW 3 "s_register_operand" "w")] "TARGET_NEON" { if (!<Is_float_mode> || flag_unsafe_math_optimizations) @@ -1979,8 +1978,7 @@ [(match_operand:VCVTF 0 "s_register_operand") (match_operand:VCVTF 1 "s_register_operand") (match_operand:VCVTF 2 "s_register_operand") - (match_operand:VCVTF 3 "s_register_operand") - (match_operand:SI 4 "immediate_operand")] + (match_operand:VCVTF 3 "s_register_operand")] "TARGET_NEON && TARGET_FMA" { emit_insn (gen_fma<mode>4_intrinsic (operands[0], operands[2], operands[3], @@ -1992,8 +1990,7 @@ [(match_operand:VCVTF 0 "s_register_operand") (match_operand:VCVTF 1 "s_register_operand") (match_operand:VCVTF 2 "s_register_operand") - (match_operand:VCVTF 3 "s_register_operand") - (match_operand:SI 4 "immediate_operand")] + (match_operand:VCVTF 3 "s_register_operand")] "TARGET_NEON && TARGET_FMA" { emit_insn (gen_fmsub<mode>4_intrinsic (operands[0], operands[2], operands[3], @@ -2017,15 +2014,14 @@ (const_string "neon_mla_<V_elem_ch><q>")))] ) -(define_insn "neon_vmlal<mode>" +(define_insn "neon_vmlal<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0") (match_operand:VW 2 "s_register_operand" "w") - (match_operand:VW 3 "s_register_operand" "w") - (match_operand:SI 4 "immediate_operand" "i")] - UNSPEC_VMLAL))] + (match_operand:VW 3 "s_register_operand" "w")] + VMLAL))] "TARGET_NEON" - "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3" + "vmlal.<sup>%#<V_sz_elem>\t%q0, %P2, %P3" [(set_attr "type" "neon_mla_<V_elem_ch>_long")] ) @@ -2033,8 +2029,7 @@ [(match_operand:VDQW 0 "s_register_operand" "=w") (match_operand:VDQW 1 "s_register_operand" "0") (match_operand:VDQW 2 "s_register_operand" "w") - (match_operand:VDQW 3 "s_register_operand" "w") - (match_operand:SI 4 "immediate_operand" "i")] + (match_operand:VDQW 3 "s_register_operand" "w")] "TARGET_NEON" { if (!<Is_float_mode> || flag_unsafe_math_optimizations) @@ -2062,26 +2057,25 @@ (const_string "neon_mla_<V_elem_ch><q>")))] ) -(define_insn "neon_vmlsl<mode>" +(define_insn "neon_vmlsl<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0") (match_operand:VW 2 "s_register_operand" "w") - (match_operand:VW 3 "s_register_operand" "w") - (match_operand:SI 4 "immediate_operand" "i")] - UNSPEC_VMLSL))] + (match_operand:VW 3 "s_register_operand" "w")] + VMLSL))] "TARGET_NEON" - "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3" + "vmlsl.<sup>%#<V_sz_elem>\t%q0, %P2, %P3" [(set_attr "type" "neon_mla_<V_elem_ch>_long")] ) -(define_insn "neon_vqdmulh<mode>" +;; vqdmulh, vqrdmulh +(define_insn "neon_vq<r>dmulh<mode>" [(set (match_operand:VMDQI 0 "s_register_operand" "=w") (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w") - (match_operand:VMDQI 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VQDMULH))] + (match_operand:VMDQI 2 "s_register_operand" "w")] + VQDMULH))] "TARGET_NEON" - "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "vq<r>dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_sat_mul_<V_elem_ch><q>")] ) @@ -2089,8 +2083,7 @@ [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0") (match_operand:VMDI 2 "s_register_operand" "w") - (match_operand:VMDI 3 "s_register_operand" "w") - (match_operand:SI 4 "immediate_operand" "i")] + (match_operand:VMDI 3 "s_register_operand" "w")] UNSPEC_VQDMLAL))] "TARGET_NEON" "vqdmlal.<V_s_elem>\t%q0, %P2, %P3" @@ -2101,30 +2094,27 @@ [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0") (match_operand:VMDI 2 "s_register_operand" "w") - (match_operand:VMDI 3 "s_register_operand" "w") - (match_operand:SI 4 "immediate_operand" "i")] + (match_operand:VMDI 3 "s_register_operand" "w")] UNSPEC_VQDMLSL))] "TARGET_NEON" "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3" [(set_attr "type" "neon_sat_mla_<V_elem_ch>_long")] ) -(define_insn "neon_vmull<mode>" +(define_insn "neon_vmull<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w") - (match_operand:VW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VMULL))] + (match_operand:VW 2 "s_register_operand" "w")] + VMULL))] "TARGET_NEON" - "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2" + "vmull.<sup>%#<V_sz_elem>\t%q0, %P1, %P2" [(set_attr "type" "neon_mul_<V_elem_ch>_long")] ) (define_insn "neon_vqdmull<mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w") - (match_operand:VMDI 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VMDI 2 "s_register_operand" "w")] UNSPEC_VQDMULL))] "TARGET_NEON" "vqdmull.<V_s_elem>\t%q0, %P1, %P2" @@ -2132,10 +2122,9 @@ ) (define_expand "neon_vsub<mode>" - [(match_operand:VDQX 0 "s_register_operand" "=w") - (match_operand:VDQX 1 "s_register_operand" "w") - (match_operand:VDQX 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + [(match_operand:VCVTF 0 "s_register_operand" "=w") + (match_operand:VCVTF 1 "s_register_operand" "w") + (match_operand:VCVTF 2 "s_register_operand" "w")] "TARGET_NEON" { if (!<Is_float_mode> || flag_unsafe_math_optimizations) @@ -2149,9 +2138,9 @@ ; Used for intrinsics when flag_unsafe_math_optimizations is false. (define_insn "neon_vsub<mode>_unspec" - [(set (match_operand:VDQX 0 "s_register_operand" "=w") - (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w") - (match_operand:VDQX 2 "s_register_operand" "w")] + [(set (match_operand:VCVTF 0 "s_register_operand" "=w") + (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w") + (match_operand:VCVTF 2 "s_register_operand" "w")] UNSPEC_VSUB))] "TARGET_NEON" "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" @@ -2161,58 +2150,53 @@ (const_string "neon_sub<q>")))] ) -(define_insn "neon_vsubl<mode>" +(define_insn "neon_vsubl<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w") - (match_operand:VDI 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VSUBL))] + (match_operand:VDI 2 "s_register_operand" "w")] + VSUBL))] "TARGET_NEON" - "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2" + "vsubl.<sup>%#<V_sz_elem>\t%q0, %P1, %P2" [(set_attr "type" "neon_sub_long")] ) -(define_insn "neon_vsubw<mode>" +(define_insn "neon_vsubw<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w") - (match_operand:VDI 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VSUBW))] + (match_operand:VDI 2 "s_register_operand" "w")] + VSUBW))] "TARGET_NEON" - "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2" + "vsubw.<sup>%#<V_sz_elem>\t%q0, %q1, %P2" [(set_attr "type" "neon_sub_widen")] ) -(define_insn "neon_vqsub<mode>" +(define_insn "neon_vqsub<sup><mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w") - (match_operand:VDQIX 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VQSUB))] + (match_operand:VDQIX 2 "s_register_operand" "w")] + VQSUB))] "TARGET_NEON" - "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "vqsub.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_qsub<q>")] ) -(define_insn "neon_vhsub<mode>" +(define_insn "neon_vhsub<sup><mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:VDQIW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VHSUB))] + (match_operand:VDQIW 2 "s_register_operand" "w")] + VHSUB))] "TARGET_NEON" - "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "vhsub.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_sub_halve<q>")] ) -(define_insn "neon_vsubhn<mode>" +(define_insn "neon_v<r>subhn<mode>" [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w") (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w") - (match_operand:VN 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VSUBHN))] + (match_operand:VN 2 "s_register_operand" "w")] + VSUBHN))] "TARGET_NEON" - "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2" + "v<r>subhn.<V_if_elem>\t%P0, %q1, %q2" [(set_attr "type" "neon_sub_halve_narrow_q")] ) @@ -2220,8 +2204,7 @@ [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w") (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w,w") - (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz") - (match_operand:SI 3 "immediate_operand" "i,i")] + (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")] UNSPEC_VCEQ))] "TARGET_NEON" "@ @@ -2239,13 +2222,12 @@ [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w") (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w,w") - (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz") - (match_operand:SI 3 "immediate_operand" "i,i")] + (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")] UNSPEC_VCGE))] "TARGET_NEON" "@ - vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2 - vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0" + vcge.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2 + vcge.<V_s_elem>\t%<V_reg>0, %<V_reg>1, #0" [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_compare_s<q>") @@ -2258,11 +2240,10 @@ [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w") (unspec:<V_cmp_result> [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:VDQIW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VDQIW 2 "s_register_operand" "w")] UNSPEC_VCGEU))] "TARGET_NEON" - "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "vcge.u%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_compare<q>")] ) @@ -2270,13 +2251,12 @@ [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w") (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w,w") - (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz") - (match_operand:SI 3 "immediate_operand" "i,i")] + (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")] UNSPEC_VCGT))] "TARGET_NEON" "@ - vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2 - vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0" + vcgt.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2 + vcgt.<V_s_elem>\t%<V_reg>0, %<V_reg>1, #0" [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_compare_s<q>") @@ -2289,11 +2269,10 @@ [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w") (unspec:<V_cmp_result> [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:VDQIW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VDQIW 2 "s_register_operand" "w")] UNSPEC_VCGTU))] "TARGET_NEON" - "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "vcgt.u%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_compare<q>")] ) @@ -2304,11 +2283,10 @@ [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w") (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "zero_operand" "Dz") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VDQW 2 "zero_operand" "Dz")] UNSPEC_VCLE))] "TARGET_NEON" - "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0" + "vcle.<V_s_elem>\t%<V_reg>0, %<V_reg>1, #0" [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_compare_s<q>") @@ -2321,11 +2299,10 @@ [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w") (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "zero_operand" "Dz") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VDQW 2 "zero_operand" "Dz")] UNSPEC_VCLT))] "TARGET_NEON" - "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0" + "vclt.<V_s_elem>\t%<V_reg>0, %<V_reg>1, #0" [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_compare_s<q>") @@ -2337,8 +2314,7 @@ (define_insn "neon_vcage<mode>" [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w") (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w") - (match_operand:VCVTF 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VCVTF 2 "s_register_operand" "w")] UNSPEC_VCAGE))] "TARGET_NEON" "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" @@ -2348,8 +2324,7 @@ (define_insn "neon_vcagt<mode>" [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w") (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w") - (match_operand:VCVTF 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VCVTF 2 "s_register_operand" "w")] UNSPEC_VCAGT))] "TARGET_NEON" "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" @@ -2359,96 +2334,89 @@ (define_insn "neon_vtst<mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:VDQIW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VDQIW 2 "s_register_operand" "w")] UNSPEC_VTST))] "TARGET_NEON" "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_tst<q>")] ) -(define_insn "neon_vabd<mode>" - [(set (match_operand:VDQW 0 "s_register_operand" "=w") - (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VABD))] +(define_insn "neon_vabd<sup><mode>" + [(set (match_operand:VDQIW 0 "s_register_operand" "=w") + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") + (match_operand:VDQIW 2 "s_register_operand" "w")] + VABD))] "TARGET_NEON" - "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "type") - (if_then_else (match_test "<Is_float_mode>") - (const_string "neon_fp_abd_s<q>") - (const_string "neon_abd<q>")))] + "vabd.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + [(set_attr "type" "neon_abd<q>")] ) -(define_insn "neon_vabdl<mode>" +(define_insn "neon_vabdf<mode>" + [(set (match_operand:VCVTF 0 "s_register_operand" "=w") + (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w") + (match_operand:VCVTF 2 "s_register_operand" "w")] + UNSPEC_VABD_F))] + "TARGET_NEON" + "vabd.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + [(set_attr "type" "neon_fp_abd_s<q>")] +) + +(define_insn "neon_vabdl<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w") - (match_operand:VW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VABDL))] + (match_operand:VW 2 "s_register_operand" "w")] + VABDL))] "TARGET_NEON" - "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2" + "vabdl.<sup>%#<V_sz_elem>\t%q0, %P1, %P2" [(set_attr "type" "neon_abd_long")] ) -(define_insn "neon_vaba<mode>" +(define_insn "neon_vaba<sup><mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") (plus:VDQIW (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w") - (match_operand:VDQIW 3 "s_register_operand" "w") - (match_operand:SI 4 "immediate_operand" "i")] - UNSPEC_VABD) + (match_operand:VDQIW 3 "s_register_operand" "w")] + VABD) (match_operand:VDQIW 1 "s_register_operand" "0")))] "TARGET_NEON" - "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3" + "vaba.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3" [(set_attr "type" "neon_arith_acc<q>")] ) -(define_insn "neon_vabal<mode>" +(define_insn "neon_vabal<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (plus:<V_widen> (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w") - (match_operand:VW 3 "s_register_operand" "w") - (match_operand:SI 4 "immediate_operand" "i")] - UNSPEC_VABDL) + (match_operand:VW 3 "s_register_operand" "w")] + VABDL) (match_operand:<V_widen> 1 "s_register_operand" "0")))] "TARGET_NEON" - "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3" + "vabal.<sup>%#<V_sz_elem>\t%q0, %P2, %P3" [(set_attr "type" "neon_arith_acc<q>")] ) -(define_insn "neon_vmax<mode>" - [(set (match_operand:VDQW 0 "s_register_operand" "=w") - (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VMAX))] +(define_insn "neon_v<maxmin><sup><mode>" + [(set (match_operand:VDQIW 0 "s_register_operand" "=w") + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") + (match_operand:VDQIW 2 "s_register_operand" "w")] + VMAXMIN))] "TARGET_NEON" - "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "type") - (if_then_else (match_test "<Is_float_mode>") - (const_string "neon_fp_minmax_s<q>") - (const_string "neon_minmax<q>")))] + "v<maxmin>.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + [(set_attr "type" "neon_minmax<q>")] ) -(define_insn "neon_vmin<mode>" - [(set (match_operand:VDQW 0 "s_register_operand" "=w") - (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VMIN))] +(define_insn "neon_v<maxmin>f<mode>" + [(set (match_operand:VCVTF 0 "s_register_operand" "=w") + (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w") + (match_operand:VCVTF 2 "s_register_operand" "w")] + VMAXMINF))] "TARGET_NEON" - "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "type") - (if_then_else (match_test "<Is_float_mode>") - (const_string "neon_fp_minmax_s<q>") - (const_string "neon_minmax<q>")))] + "v<maxmin>.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + [(set_attr "type" "neon_fp_minmax_s<q>")] ) (define_expand "neon_vpadd<mode>" [(match_operand:VD 0 "s_register_operand" "=w") (match_operand:VD 1 "s_register_operand" "w") - (match_operand:VD 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VD 2 "s_register_operand" "w")] "TARGET_NEON" { emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1], @@ -2456,60 +2424,49 @@ DONE; }) -(define_insn "neon_vpaddl<mode>" +(define_insn "neon_vpaddl<sup><mode>" [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w") - (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] - UNSPEC_VPADDL))] + (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")] + VPADDL))] "TARGET_NEON" - "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1" + "vpaddl.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1" [(set_attr "type" "neon_reduc_add_long")] ) -(define_insn "neon_vpadal<mode>" +(define_insn "neon_vpadal<sup><mode>" [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w") (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0") - (match_operand:VDQIW 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VPADAL))] + (match_operand:VDQIW 2 "s_register_operand" "w")] + VPADAL))] "TARGET_NEON" - "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2" + "vpadal.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2" [(set_attr "type" "neon_reduc_add_acc")] ) -(define_insn "neon_vpmax<mode>" - [(set (match_operand:VD 0 "s_register_operand" "=w") - (unspec:VD [(match_operand:VD 1 "s_register_operand" "w") - (match_operand:VD 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VPMAX))] +(define_insn "neon_vp<maxmin><sup><mode>" + [(set (match_operand:VDI 0 "s_register_operand" "=w") + (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w") + (match_operand:VDI 2 "s_register_operand" "w")] + VPMAXMIN))] "TARGET_NEON" - "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "type") - (if_then_else (match_test "<Is_float_mode>") - (const_string "neon_fp_reduc_minmax_s<q>") - (const_string "neon_reduc_minmax<q>")))] + "vp<maxmin>.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + [(set_attr "type" "neon_reduc_minmax<q>")] ) -(define_insn "neon_vpmin<mode>" - [(set (match_operand:VD 0 "s_register_operand" "=w") - (unspec:VD [(match_operand:VD 1 "s_register_operand" "w") - (match_operand:VD 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VPMIN))] +(define_insn "neon_vp<maxmin>f<mode>" + [(set (match_operand:VCVTF 0 "s_register_operand" "=w") + (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w") + (match_operand:VCVTF 2 "s_register_operand" "w")] + VPMAXMINF))] "TARGET_NEON" - "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "type") - (if_then_else (match_test "<Is_float_mode>") - (const_string "neon_fp_reduc_minmax_s<q>") - (const_string "neon_reduc_minmax<q>")))] + "vp<maxmin>.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + [(set_attr "type" "neon_fp_reduc_minmax_s<q>")] ) (define_insn "neon_vrecps<mode>" [(set (match_operand:VCVTF 0 "s_register_operand" "=w") (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w") - (match_operand:VCVTF 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VCVTF 2 "s_register_operand" "w")] UNSPEC_VRECPS))] "TARGET_NEON" "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" @@ -2519,8 +2476,7 @@ (define_insn "neon_vrsqrts<mode>" [(set (match_operand:VCVTF 0 "s_register_operand" "=w") (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w") - (match_operand:VCVTF 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:VCVTF 2 "s_register_operand" "w")] UNSPEC_VRSQRTS))] "TARGET_NEON" "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" @@ -2529,8 +2485,7 @@ (define_expand "neon_vabs<mode>" [(match_operand:VDQW 0 "s_register_operand" "") - (match_operand:VDQW 1 "s_register_operand" "") - (match_operand:SI 2 "immediate_operand" "")] + (match_operand:VDQW 1 "s_register_operand" "")] "TARGET_NEON" { emit_insn (gen_abs<mode>2 (operands[0], operands[1])); @@ -2539,28 +2494,60 @@ (define_insn "neon_vqabs<mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") - (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")] UNSPEC_VQABS))] "TARGET_NEON" "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1" [(set_attr "type" "neon_qabs<q>")] ) +(define_insn "neon_bswap<mode>" + [(set (match_operand:VDQHSD 0 "register_operand" "=w") + (bswap:VDQHSD (match_operand:VDQHSD 1 "register_operand" "w")))] + "TARGET_NEON" + "vrev<V_sz_elem>.8\\t%<V_reg>0, %<V_reg>1" + [(set_attr "type" "neon_rev<q>")] +) + (define_expand "neon_vneg<mode>" [(match_operand:VDQW 0 "s_register_operand" "") - (match_operand:VDQW 1 "s_register_operand" "") - (match_operand:SI 2 "immediate_operand" "")] + (match_operand:VDQW 1 "s_register_operand" "")] "TARGET_NEON" { emit_insn (gen_neg<mode>2 (operands[0], operands[1])); DONE; }) +(define_expand "neon_copysignf<mode>" + [(match_operand:VCVTF 0 "register_operand") + (match_operand:VCVTF 1 "register_operand") + (match_operand:VCVTF 2 "register_operand")] + "TARGET_NEON" + "{ + rtx v_bitmask_cast; + rtx v_bitmask = gen_reg_rtx (<VCVTF:V_cmp_result>mode); + int i, n_elt = GET_MODE_NUNITS (<MODE>mode); + rtvec v = rtvec_alloc (n_elt); + + /* Create bitmask for vector select. */ + for (i = 0; i < n_elt; ++i) + RTVEC_ELT (v, i) = GEN_INT (0x80000000); + + emit_move_insn (v_bitmask, + gen_rtx_CONST_VECTOR (<VCVTF:V_cmp_result>mode, v)); + emit_move_insn (operands[0], operands[2]); + v_bitmask_cast = simplify_gen_subreg (<MODE>mode, v_bitmask, + <VCVTF:V_cmp_result>mode, 0); + emit_insn (gen_neon_vbsl<mode> (operands[0], v_bitmask_cast, operands[0], + operands[1])); + + DONE; + }" +) + (define_insn "neon_vqneg<mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") - (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")] UNSPEC_VQNEG))] "TARGET_NEON" "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1" @@ -2569,8 +2556,7 @@ (define_insn "neon_vcls<mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") - (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")] UNSPEC_VCLS))] "TARGET_NEON" "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1" @@ -2587,8 +2573,7 @@ (define_expand "neon_vclz<mode>" [(match_operand:VDQIW 0 "s_register_operand" "") - (match_operand:VDQIW 1 "s_register_operand" "") - (match_operand:SI 2 "immediate_operand" "")] + (match_operand:VDQIW 1 "s_register_operand" "")] "TARGET_NEON" { emit_insn (gen_clz<mode>2 (operands[0], operands[1])); @@ -2605,8 +2590,7 @@ (define_expand "neon_vcnt<mode>" [(match_operand:VE 0 "s_register_operand" "=w") - (match_operand:VE 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (match_operand:VE 1 "s_register_operand" "w")] "TARGET_NEON" { emit_insn (gen_popcount<mode>2 (operands[0], operands[1])); @@ -2615,8 +2599,7 @@ (define_insn "neon_vrecpe<mode>" [(set (match_operand:V32 0 "s_register_operand" "=w") - (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")] UNSPEC_VRECPE))] "TARGET_NEON" "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1" @@ -2625,8 +2608,7 @@ (define_insn "neon_vrsqrte<mode>" [(set (match_operand:V32 0 "s_register_operand" "=w") - (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")] UNSPEC_VRSQRTE))] "TARGET_NEON" "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1" @@ -2635,8 +2617,7 @@ (define_expand "neon_vmvn<mode>" [(match_operand:VDQIW 0 "s_register_operand" "") - (match_operand:VDQIW 1 "s_register_operand" "") - (match_operand:SI 2 "immediate_operand" "")] + (match_operand:VDQIW 1 "s_register_operand" "")] "TARGET_NEON" { emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1])); @@ -2738,13 +2719,9 @@ (define_expand "neon_vget_lane<mode>" [(match_operand:<V_ext> 0 "s_register_operand" "") (match_operand:VDQW 1 "s_register_operand" "") - (match_operand:SI 2 "immediate_operand" "") - (match_operand:SI 3 "immediate_operand" "")] + (match_operand:SI 2 "immediate_operand" "")] "TARGET_NEON" { - HOST_WIDE_INT magic = INTVAL (operands[3]); - rtx insn; - neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode)); if (BYTES_BIG_ENDIAN) @@ -2761,29 +2738,50 @@ operands[2] = GEN_INT (elt); } - if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32) - insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]); + if (GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32) + emit_insn (gen_vec_extract<mode> (operands[0], operands[1], operands[2])); else + emit_insn (gen_neon_vget_lane<mode>_sext_internal (operands[0], + operands[1], + operands[2])); + DONE; +}) + +(define_expand "neon_vget_laneu<mode>" + [(match_operand:<V_ext> 0 "s_register_operand" "") + (match_operand:VDQIW 1 "s_register_operand" "") + (match_operand:SI 2 "immediate_operand" "")] + "TARGET_NEON" +{ + neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode)); + + if (BYTES_BIG_ENDIAN) { - if ((magic & 1) != 0) - insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1], - operands[2]); - else - insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1], - operands[2]); + /* The intrinsics are defined in terms of a model where the + element ordering in memory is vldm order, whereas the generic + RTL is defined in terms of a model where the element ordering + in memory is array order. Convert the lane number to conform + to this model. */ + unsigned int elt = INTVAL (operands[2]); + unsigned int reg_nelts + = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)); + elt ^= reg_nelts - 1; + operands[2] = GEN_INT (elt); } - emit_insn (insn); + + if (GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32) + emit_insn (gen_vec_extract<mode> (operands[0], operands[1], operands[2])); + else + emit_insn (gen_neon_vget_lane<mode>_zext_internal (operands[0], + operands[1], + operands[2])); DONE; }) -; Operand 3 (info word) is ignored because it does nothing useful with 64-bit -; elements. - (define_expand "neon_vget_lanedi" [(match_operand:DI 0 "s_register_operand" "=r") (match_operand:DI 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:SI 2 "immediate_operand" "")] "TARGET_NEON" { neon_lane_bounds (operands[2], 0, 1); @@ -2794,8 +2792,7 @@ (define_expand "neon_vget_lanev2di" [(match_operand:DI 0 "s_register_operand" "") (match_operand:V2DI 1 "s_register_operand" "") - (match_operand:SI 2 "immediate_operand" "") - (match_operand:SI 3 "immediate_operand" "")] + (match_operand:SI 2 "immediate_operand" "")] "TARGET_NEON" { switch (INTVAL (operands[2])) @@ -3052,23 +3049,21 @@ [(set_attr "type" "neon_fp_to_int_<V_elem_ch><q>")] ) -(define_insn "neon_vcvt<mode>" +(define_insn "neon_vcvt<sup><mode>" [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w") - (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] - UNSPEC_VCVT))] + (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")] + VCVT_US))] "TARGET_NEON" - "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1" + "vcvt.<sup>%#32.f32\t%<V_reg>0, %<V_reg>1" [(set_attr "type" "neon_fp_to_int_<V_elem_ch><q>")] ) -(define_insn "neon_vcvt<mode>" +(define_insn "neon_vcvt<sup><mode>" [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w") - (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] - UNSPEC_VCVT))] + (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")] + VCVT_US))] "TARGET_NEON" - "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1" + "vcvt.f32.<sup>%#32\t%<V_reg>0, %<V_reg>1" [(set_attr "type" "neon_int_to_fp_<V_elem_ch><q>")] ) @@ -3090,71 +3085,65 @@ [(set_attr "type" "neon_fp_cvt_narrow_s_q")] ) -(define_insn "neon_vcvt_n<mode>" +(define_insn "neon_vcvt<sup>_n<mode>" [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w") (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VCVT_N))] + (match_operand:SI 2 "immediate_operand" "i")] + VCVT_US_N))] "TARGET_NEON" { neon_const_bounds (operands[2], 1, 33); - return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2"; + return "vcvt.<sup>%#32.f32\t%<V_reg>0, %<V_reg>1, %2"; } [(set_attr "type" "neon_fp_to_int_<V_elem_ch><q>")] ) -(define_insn "neon_vcvt_n<mode>" +(define_insn "neon_vcvt<sup>_n<mode>" [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w") (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VCVT_N))] + (match_operand:SI 2 "immediate_operand" "i")] + VCVT_US_N))] "TARGET_NEON" { neon_const_bounds (operands[2], 1, 33); - return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2"; + return "vcvt.f32.<sup>%#32\t%<V_reg>0, %<V_reg>1, %2"; } [(set_attr "type" "neon_int_to_fp_<V_elem_ch><q>")] ) (define_insn "neon_vmovn<mode>" [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w") - (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")] UNSPEC_VMOVN))] "TARGET_NEON" "vmovn.<V_if_elem>\t%P0, %q1" [(set_attr "type" "neon_shift_imm_narrow_q")] ) -(define_insn "neon_vqmovn<mode>" +(define_insn "neon_vqmovn<sup><mode>" [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w") - (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] - UNSPEC_VQMOVN))] + (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")] + VQMOVN))] "TARGET_NEON" - "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1" + "vqmovn.<sup>%#<V_sz_elem>\t%P0, %q1" [(set_attr "type" "neon_sat_shift_imm_narrow_q")] ) (define_insn "neon_vqmovun<mode>" [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w") - (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")] UNSPEC_VQMOVUN))] "TARGET_NEON" "vqmovun.<V_s_elem>\t%P0, %q1" [(set_attr "type" "neon_sat_shift_imm_narrow_q")] ) -(define_insn "neon_vmovl<mode>" +(define_insn "neon_vmovl<sup><mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") - (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] - UNSPEC_VMOVL))] + (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")] + VMOVL))] "TARGET_NEON" - "vmovl.%T2%#<V_sz_elem>\t%q0, %P1" + "vmovl.<sup>%#<V_sz_elem>\t%q0, %P1" [(set_attr "type" "neon_shift_imm_long")] ) @@ -3163,8 +3152,7 @@ (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w") (match_operand:VMD 2 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 3 "immediate_operand" "i") - (match_operand:SI 4 "immediate_operand" "i")] + (match_operand:SI 3 "immediate_operand" "i")] UNSPEC_VMUL_LANE))] "TARGET_NEON" { @@ -3182,8 +3170,7 @@ (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w") (match_operand:<V_HALF> 2 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 3 "immediate_operand" "i") - (match_operand:SI 4 "immediate_operand" "i")] + (match_operand:SI 3 "immediate_operand" "i")] UNSPEC_VMUL_LANE))] "TARGET_NEON" { @@ -3196,18 +3183,17 @@ (const_string "neon_mul_<V_elem_ch>_scalar<q>")))] ) -(define_insn "neon_vmull_lane<mode>" +(define_insn "neon_vmull<sup>_lane<mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w") (match_operand:VMDI 2 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 3 "immediate_operand" "i") - (match_operand:SI 4 "immediate_operand" "i")] - UNSPEC_VMULL_LANE))] + (match_operand:SI 3 "immediate_operand" "i")] + VMULL_LANE))] "TARGET_NEON" { neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); - return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]"; + return "vmull.<sup>%#<V_sz_elem>\t%q0, %P1, %P2[%c3]"; } [(set_attr "type" "neon_mul_<V_elem_ch>_scalar_long")] ) @@ -3217,8 +3203,7 @@ (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w") (match_operand:VMDI 2 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 3 "immediate_operand" "i") - (match_operand:SI 4 "immediate_operand" "i")] + (match_operand:SI 3 "immediate_operand" "i")] UNSPEC_VQDMULL_LANE))] "TARGET_NEON" { @@ -3228,34 +3213,32 @@ [(set_attr "type" "neon_sat_mul_<V_elem_ch>_scalar_long")] ) -(define_insn "neon_vqdmulh_lane<mode>" +(define_insn "neon_vq<r>dmulh_lane<mode>" [(set (match_operand:VMQI 0 "s_register_operand" "=w") (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w") (match_operand:<V_HALF> 2 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 3 "immediate_operand" "i") - (match_operand:SI 4 "immediate_operand" "i")] - UNSPEC_VQDMULH_LANE))] + (match_operand:SI 3 "immediate_operand" "i")] + VQDMULH_LANE))] "TARGET_NEON" { neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); - return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]"; + return "vq<r>dmulh.<V_s_elem>\t%q0, %q1, %P2[%c3]"; } [(set_attr "type" "neon_sat_mul_<V_elem_ch>_scalar_q")] ) -(define_insn "neon_vqdmulh_lane<mode>" +(define_insn "neon_vq<r>dmulh_lane<mode>" [(set (match_operand:VMDI 0 "s_register_operand" "=w") (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w") (match_operand:VMDI 2 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 3 "immediate_operand" "i") - (match_operand:SI 4 "immediate_operand" "i")] - UNSPEC_VQDMULH_LANE))] + (match_operand:SI 3 "immediate_operand" "i")] + VQDMULH_LANE))] "TARGET_NEON" { neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); - return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]"; + return "vq<r>dmulh.<V_s_elem>\t%P0, %P1, %P2[%c3]"; } [(set_attr "type" "neon_sat_mul_<V_elem_ch>_scalar_q")] ) @@ -3266,8 +3249,7 @@ (match_operand:VMD 2 "s_register_operand" "w") (match_operand:VMD 3 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 4 "immediate_operand" "i") - (match_operand:SI 5 "immediate_operand" "i")] + (match_operand:SI 4 "immediate_operand" "i")] UNSPEC_VMLA_LANE))] "TARGET_NEON" { @@ -3286,8 +3268,7 @@ (match_operand:VMQ 2 "s_register_operand" "w") (match_operand:<V_HALF> 3 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 4 "immediate_operand" "i") - (match_operand:SI 5 "immediate_operand" "i")] + (match_operand:SI 4 "immediate_operand" "i")] UNSPEC_VMLA_LANE))] "TARGET_NEON" { @@ -3300,19 +3281,18 @@ (const_string "neon_mla_<V_elem_ch>_scalar<q>")))] ) -(define_insn "neon_vmlal_lane<mode>" +(define_insn "neon_vmlal<sup>_lane<mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0") (match_operand:VMDI 2 "s_register_operand" "w") (match_operand:VMDI 3 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 4 "immediate_operand" "i") - (match_operand:SI 5 "immediate_operand" "i")] - UNSPEC_VMLAL_LANE))] + (match_operand:SI 4 "immediate_operand" "i")] + VMLAL_LANE))] "TARGET_NEON" { neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); - return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]"; + return "vmlal.<sup>%#<V_sz_elem>\t%q0, %P2, %P3[%c4]"; } [(set_attr "type" "neon_mla_<V_elem_ch>_scalar_long")] ) @@ -3323,8 +3303,7 @@ (match_operand:VMDI 2 "s_register_operand" "w") (match_operand:VMDI 3 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 4 "immediate_operand" "i") - (match_operand:SI 5 "immediate_operand" "i")] + (match_operand:SI 4 "immediate_operand" "i")] UNSPEC_VQDMLAL_LANE))] "TARGET_NEON" { @@ -3340,8 +3319,7 @@ (match_operand:VMD 2 "s_register_operand" "w") (match_operand:VMD 3 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 4 "immediate_operand" "i") - (match_operand:SI 5 "immediate_operand" "i")] + (match_operand:SI 4 "immediate_operand" "i")] UNSPEC_VMLS_LANE))] "TARGET_NEON" { @@ -3360,8 +3338,7 @@ (match_operand:VMQ 2 "s_register_operand" "w") (match_operand:<V_HALF> 3 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 4 "immediate_operand" "i") - (match_operand:SI 5 "immediate_operand" "i")] + (match_operand:SI 4 "immediate_operand" "i")] UNSPEC_VMLS_LANE))] "TARGET_NEON" { @@ -3374,19 +3351,18 @@ (const_string "neon_mla_<V_elem_ch>_scalar<q>")))] ) -(define_insn "neon_vmlsl_lane<mode>" +(define_insn "neon_vmlsl<sup>_lane<mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0") (match_operand:VMDI 2 "s_register_operand" "w") (match_operand:VMDI 3 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 4 "immediate_operand" "i") - (match_operand:SI 5 "immediate_operand" "i")] - UNSPEC_VMLSL_LANE))] + (match_operand:SI 4 "immediate_operand" "i")] + VMLSL_LANE))] "TARGET_NEON" { neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); - return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]"; + return "vmlsl.<sup>%#<V_sz_elem>\t%q0, %P2, %P3[%c4]"; } [(set_attr "type" "neon_mla_<V_elem_ch>_scalar_long")] ) @@ -3397,8 +3373,7 @@ (match_operand:VMDI 2 "s_register_operand" "w") (match_operand:VMDI 3 "s_register_operand" "<scalar_mul_constraint>") - (match_operand:SI 4 "immediate_operand" "i") - (match_operand:SI 5 "immediate_operand" "i")] + (match_operand:SI 4 "immediate_operand" "i")] UNSPEC_VQDMLSL_LANE))] "TARGET_NEON" { @@ -3418,84 +3393,117 @@ (define_expand "neon_vmul_n<mode>" [(match_operand:VMD 0 "s_register_operand" "") (match_operand:VMD 1 "s_register_operand" "") - (match_operand:<V_elem> 2 "s_register_operand" "") - (match_operand:SI 3 "immediate_operand" "")] + (match_operand:<V_elem> 2 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx)); emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp, - const0_rtx, const0_rtx)); + const0_rtx)); DONE; }) (define_expand "neon_vmul_n<mode>" [(match_operand:VMQ 0 "s_register_operand" "") (match_operand:VMQ 1 "s_register_operand" "") - (match_operand:<V_elem> 2 "s_register_operand" "") - (match_operand:SI 3 "immediate_operand" "")] + (match_operand:<V_elem> 2 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<V_HALF>mode); emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx)); emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp, - const0_rtx, const0_rtx)); + const0_rtx)); + DONE; +}) + +(define_expand "neon_vmulls_n<mode>" + [(match_operand:<V_widen> 0 "s_register_operand" "") + (match_operand:VMDI 1 "s_register_operand" "") + (match_operand:<V_elem> 2 "s_register_operand" "")] + "TARGET_NEON" +{ + rtx tmp = gen_reg_rtx (<MODE>mode); + emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx)); + emit_insn (gen_neon_vmulls_lane<mode> (operands[0], operands[1], tmp, + const0_rtx)); DONE; }) -(define_expand "neon_vmull_n<mode>" +(define_expand "neon_vmullu_n<mode>" [(match_operand:<V_widen> 0 "s_register_operand" "") (match_operand:VMDI 1 "s_register_operand" "") - (match_operand:<V_elem> 2 "s_register_operand" "") - (match_operand:SI 3 "immediate_operand" "")] + (match_operand:<V_elem> 2 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx)); - emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp, - const0_rtx, operands[3])); + emit_insn (gen_neon_vmullu_lane<mode> (operands[0], operands[1], tmp, + const0_rtx)); DONE; }) (define_expand "neon_vqdmull_n<mode>" [(match_operand:<V_widen> 0 "s_register_operand" "") (match_operand:VMDI 1 "s_register_operand" "") - (match_operand:<V_elem> 2 "s_register_operand" "") - (match_operand:SI 3 "immediate_operand" "")] + (match_operand:<V_elem> 2 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx)); emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp, - const0_rtx, const0_rtx)); + const0_rtx)); DONE; }) (define_expand "neon_vqdmulh_n<mode>" [(match_operand:VMDI 0 "s_register_operand" "") (match_operand:VMDI 1 "s_register_operand" "") - (match_operand:<V_elem> 2 "s_register_operand" "") - (match_operand:SI 3 "immediate_operand" "")] + (match_operand:<V_elem> 2 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx)); emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp, - const0_rtx, operands[3])); + const0_rtx)); + DONE; +}) + +(define_expand "neon_vqrdmulh_n<mode>" + [(match_operand:VMDI 0 "s_register_operand" "") + (match_operand:VMDI 1 "s_register_operand" "") + (match_operand:<V_elem> 2 "s_register_operand" "")] + "TARGET_NEON" +{ + rtx tmp = gen_reg_rtx (<MODE>mode); + emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx)); + emit_insn (gen_neon_vqrdmulh_lane<mode> (operands[0], operands[1], tmp, + const0_rtx)); DONE; }) (define_expand "neon_vqdmulh_n<mode>" [(match_operand:VMQI 0 "s_register_operand" "") (match_operand:VMQI 1 "s_register_operand" "") - (match_operand:<V_elem> 2 "s_register_operand" "") - (match_operand:SI 3 "immediate_operand" "")] + (match_operand:<V_elem> 2 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<V_HALF>mode); emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx)); emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp, - const0_rtx, operands[3])); + const0_rtx)); + DONE; +}) + +(define_expand "neon_vqrdmulh_n<mode>" + [(match_operand:VMQI 0 "s_register_operand" "") + (match_operand:VMQI 1 "s_register_operand" "") + (match_operand:<V_elem> 2 "s_register_operand" "")] + "TARGET_NEON" +{ + rtx tmp = gen_reg_rtx (<V_HALF>mode); + emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx)); + emit_insn (gen_neon_vqrdmulh_lane<mode> (operands[0], operands[1], tmp, + const0_rtx)); DONE; }) @@ -3503,14 +3511,13 @@ [(match_operand:VMD 0 "s_register_operand" "") (match_operand:VMD 1 "s_register_operand" "") (match_operand:VMD 2 "s_register_operand" "") - (match_operand:<V_elem> 3 "s_register_operand" "") - (match_operand:SI 4 "immediate_operand" "")] + (match_operand:<V_elem> 3 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx)); emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2], - tmp, const0_rtx, operands[4])); + tmp, const0_rtx)); DONE; }) @@ -3518,29 +3525,41 @@ [(match_operand:VMQ 0 "s_register_operand" "") (match_operand:VMQ 1 "s_register_operand" "") (match_operand:VMQ 2 "s_register_operand" "") - (match_operand:<V_elem> 3 "s_register_operand" "") - (match_operand:SI 4 "immediate_operand" "")] + (match_operand:<V_elem> 3 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<V_HALF>mode); emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx)); emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2], - tmp, const0_rtx, operands[4])); + tmp, const0_rtx)); + DONE; +}) + +(define_expand "neon_vmlals_n<mode>" + [(match_operand:<V_widen> 0 "s_register_operand" "") + (match_operand:<V_widen> 1 "s_register_operand" "") + (match_operand:VMDI 2 "s_register_operand" "") + (match_operand:<V_elem> 3 "s_register_operand" "")] + "TARGET_NEON" +{ + rtx tmp = gen_reg_rtx (<MODE>mode); + emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx)); + emit_insn (gen_neon_vmlals_lane<mode> (operands[0], operands[1], operands[2], + tmp, const0_rtx)); DONE; }) -(define_expand "neon_vmlal_n<mode>" +(define_expand "neon_vmlalu_n<mode>" [(match_operand:<V_widen> 0 "s_register_operand" "") (match_operand:<V_widen> 1 "s_register_operand" "") (match_operand:VMDI 2 "s_register_operand" "") - (match_operand:<V_elem> 3 "s_register_operand" "") - (match_operand:SI 4 "immediate_operand" "")] + (match_operand:<V_elem> 3 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx)); - emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2], - tmp, const0_rtx, operands[4])); + emit_insn (gen_neon_vmlalu_lane<mode> (operands[0], operands[1], operands[2], + tmp, const0_rtx)); DONE; }) @@ -3548,14 +3567,13 @@ [(match_operand:<V_widen> 0 "s_register_operand" "") (match_operand:<V_widen> 1 "s_register_operand" "") (match_operand:VMDI 2 "s_register_operand" "") - (match_operand:<V_elem> 3 "s_register_operand" "") - (match_operand:SI 4 "immediate_operand" "")] + (match_operand:<V_elem> 3 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx)); emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2], - tmp, const0_rtx, operands[4])); + tmp, const0_rtx)); DONE; }) @@ -3563,14 +3581,13 @@ [(match_operand:VMD 0 "s_register_operand" "") (match_operand:VMD 1 "s_register_operand" "") (match_operand:VMD 2 "s_register_operand" "") - (match_operand:<V_elem> 3 "s_register_operand" "") - (match_operand:SI 4 "immediate_operand" "")] + (match_operand:<V_elem> 3 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx)); emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2], - tmp, const0_rtx, operands[4])); + tmp, const0_rtx)); DONE; }) @@ -3578,29 +3595,41 @@ [(match_operand:VMQ 0 "s_register_operand" "") (match_operand:VMQ 1 "s_register_operand" "") (match_operand:VMQ 2 "s_register_operand" "") - (match_operand:<V_elem> 3 "s_register_operand" "") - (match_operand:SI 4 "immediate_operand" "")] + (match_operand:<V_elem> 3 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<V_HALF>mode); emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx)); emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2], - tmp, const0_rtx, operands[4])); + tmp, const0_rtx)); DONE; }) -(define_expand "neon_vmlsl_n<mode>" +(define_expand "neon_vmlsls_n<mode>" [(match_operand:<V_widen> 0 "s_register_operand" "") (match_operand:<V_widen> 1 "s_register_operand" "") (match_operand:VMDI 2 "s_register_operand" "") - (match_operand:<V_elem> 3 "s_register_operand" "") - (match_operand:SI 4 "immediate_operand" "")] + (match_operand:<V_elem> 3 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx)); - emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2], - tmp, const0_rtx, operands[4])); + emit_insn (gen_neon_vmlsls_lane<mode> (operands[0], operands[1], operands[2], + tmp, const0_rtx)); + DONE; +}) + +(define_expand "neon_vmlslu_n<mode>" + [(match_operand:<V_widen> 0 "s_register_operand" "") + (match_operand:<V_widen> 1 "s_register_operand" "") + (match_operand:VMDI 2 "s_register_operand" "") + (match_operand:<V_elem> 3 "s_register_operand" "")] + "TARGET_NEON" +{ + rtx tmp = gen_reg_rtx (<MODE>mode); + emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx)); + emit_insn (gen_neon_vmlslu_lane<mode> (operands[0], operands[1], operands[2], + tmp, const0_rtx)); DONE; }) @@ -3608,14 +3637,13 @@ [(match_operand:<V_widen> 0 "s_register_operand" "") (match_operand:<V_widen> 1 "s_register_operand" "") (match_operand:VMDI 2 "s_register_operand" "") - (match_operand:<V_elem> 3 "s_register_operand" "") - (match_operand:SI 4 "immediate_operand" "")] + (match_operand:<V_elem> 3 "s_register_operand" "")] "TARGET_NEON" { rtx tmp = gen_reg_rtx (<MODE>mode); emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx)); emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2], - tmp, const0_rtx, operands[4])); + tmp, const0_rtx)); DONE; }) @@ -3635,8 +3663,7 @@ (define_insn "neon_vrev64<mode>" [(set (match_operand:VDQ 0 "s_register_operand" "=w") - (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")] UNSPEC_VREV64))] "TARGET_NEON" "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1" @@ -3645,8 +3672,7 @@ (define_insn "neon_vrev32<mode>" [(set (match_operand:VX 0 "s_register_operand" "=w") - (unspec:VX [(match_operand:VX 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")] UNSPEC_VREV32))] "TARGET_NEON" "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1" @@ -3655,8 +3681,7 @@ (define_insn "neon_vrev16<mode>" [(set (match_operand:VE 0 "s_register_operand" "=w") - (unspec:VE [(match_operand:VE 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i")] + (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")] UNSPEC_VREV16))] "TARGET_NEON" "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1" @@ -3697,80 +3722,80 @@ operands[1] = gen_lowpart (<MODE>mode, operands[1]); }) -(define_insn "neon_vshl<mode>" +;; vshl, vrshl +(define_insn "neon_v<shift_op><sup><mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w") - (match_operand:VDQIX 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VSHL))] + (match_operand:VDQIX 2 "s_register_operand" "w")] + VSHL))] "TARGET_NEON" - "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "v<shift_op>.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_shift_imm<q>")] ) -(define_insn "neon_vqshl<mode>" +;; vqshl, vqrshl +(define_insn "neon_v<shift_op><sup><mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w") - (match_operand:VDQIX 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VQSHL))] + (match_operand:VDQIX 2 "s_register_operand" "w")] + VQSHL))] "TARGET_NEON" - "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" + "v<shift_op>.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" [(set_attr "type" "neon_sat_shift_imm<q>")] ) -(define_insn "neon_vshr_n<mode>" +;; vshr_n, vrshr_n +(define_insn "neon_v<shift_op><sup>_n<mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VSHR_N))] + (match_operand:SI 2 "immediate_operand" "i")] + VSHR_N))] "TARGET_NEON" { neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1); - return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2"; + return "v<shift_op>.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2"; } [(set_attr "type" "neon_shift_imm<q>")] ) -(define_insn "neon_vshrn_n<mode>" +;; vshrn_n, vrshrn_n +(define_insn "neon_v<shift_op>_n<mode>" [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w") (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VSHRN_N))] + (match_operand:SI 2 "immediate_operand" "i")] + VSHRN_N))] "TARGET_NEON" { neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1); - return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2"; + return "v<shift_op>.<V_if_elem>\t%P0, %q1, %2"; } [(set_attr "type" "neon_shift_imm_narrow_q")] ) -(define_insn "neon_vqshrn_n<mode>" +;; vqshrn_n, vqrshrn_n +(define_insn "neon_v<shift_op><sup>_n<mode>" [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w") (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VQSHRN_N))] + (match_operand:SI 2 "immediate_operand" "i")] + VQSHRN_N))] "TARGET_NEON" { neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1); - return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2"; + return "v<shift_op>.<sup>%#<V_sz_elem>\t%P0, %q1, %2"; } [(set_attr "type" "neon_sat_shift_imm_narrow_q")] ) -(define_insn "neon_vqshrun_n<mode>" +;; vqshrun_n, vqrshrun_n +(define_insn "neon_v<shift_op>_n<mode>" [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w") (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VQSHRUN_N))] + (match_operand:SI 2 "immediate_operand" "i")] + VQSHRUN_N))] "TARGET_NEON" { neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1); - return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2"; + return "v<shift_op>.<V_s_elem>\t%P0, %q1, %2"; } [(set_attr "type" "neon_sat_shift_imm_narrow_q")] ) @@ -3778,8 +3803,7 @@ (define_insn "neon_vshl_n<mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VSHL_N))] "TARGET_NEON" { @@ -3789,16 +3813,15 @@ [(set_attr "type" "neon_shift_imm<q>")] ) -(define_insn "neon_vqshl_n<mode>" +(define_insn "neon_vqshl_<sup>_n<mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VQSHL_N))] + (match_operand:SI 2 "immediate_operand" "i")] + VQSHL_N))] "TARGET_NEON" { neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode)); - return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2"; + return "vqshl.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2"; } [(set_attr "type" "neon_sat_shift_imm<q>")] ) @@ -3806,43 +3829,41 @@ (define_insn "neon_vqshlu_n<mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] + (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VQSHLU_N))] "TARGET_NEON" { neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode)); - return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2"; + return "vqshlu.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %2"; } [(set_attr "type" "neon_sat_shift_imm<q>")] ) -(define_insn "neon_vshll_n<mode>" +(define_insn "neon_vshll<sup>_n<mode>" [(set (match_operand:<V_widen> 0 "s_register_operand" "=w") (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w") - (match_operand:SI 2 "immediate_operand" "i") - (match_operand:SI 3 "immediate_operand" "i")] - UNSPEC_VSHLL_N))] + (match_operand:SI 2 "immediate_operand" "i")] + VSHLL_N))] "TARGET_NEON" { /* The boundaries are: 0 < imm <= size. */ neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1); - return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2"; + return "vshll.<sup>%#<V_sz_elem>\t%q0, %P1, %2"; } [(set_attr "type" "neon_shift_imm_long")] ) -(define_insn "neon_vsra_n<mode>" +;; vsra_n, vrsra_n +(define_insn "neon_v<shift_op><sup>_n<mode>" [(set (match_operand:VDQIX 0 "s_register_operand" "=w") (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0") (match_operand:VDQIX 2 "s_register_operand" "w") - (match_operand:SI 3 "immediate_operand" "i") - (match_operand:SI 4 "immediate_operand" "i")] - UNSPEC_VSRA_N))] + (match_operand:SI 3 "immediate_operand" "i")] + VSRA_N))] "TARGET_NEON" { neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1); - return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3"; + return "v<shift_op>.<sup>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3"; } [(set_attr "type" "neon_shift_acc<q>")] ) @@ -4140,17 +4161,6 @@ [(set_attr "type" "neon_permute<q>")] ) -(define_expand "neon_vtrn<mode>" - [(match_operand:SI 0 "s_register_operand" "r") - (match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "s_register_operand" "w")] - "TARGET_NEON" -{ - neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal, - operands[0], operands[1], operands[2]); - DONE; -}) - (define_expand "neon_vzip<mode>_internal" [(parallel [(set (match_operand:VDQW 0 "s_register_operand" "") @@ -4177,17 +4187,6 @@ [(set_attr "type" "neon_zip<q>")] ) -(define_expand "neon_vzip<mode>" - [(match_operand:SI 0 "s_register_operand" "r") - (match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "s_register_operand" "w")] - "TARGET_NEON" -{ - neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal, - operands[0], operands[1], operands[2]); - DONE; -}) - (define_expand "neon_vuzp<mode>_internal" [(parallel [(set (match_operand:VDQW 0 "s_register_operand" "") @@ -4214,17 +4213,6 @@ [(set_attr "type" "neon_zip<q>")] ) -(define_expand "neon_vuzp<mode>" - [(match_operand:SI 0 "s_register_operand" "r") - (match_operand:VDQW 1 "s_register_operand" "w") - (match_operand:VDQW 2 "s_register_operand" "w")] - "TARGET_NEON" -{ - neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal, - operands[0], operands[1], operands[2]); - DONE; -}) - (define_expand "neon_vreinterpretv8qi<mode>" [(match_operand:V8QI 0 "s_register_operand" "") (match_operand:VDX 1 "s_register_operand" "")] @@ -5357,61 +5345,6 @@ [(set_attr "type" "neon_store4_4reg<q>")] ) -(define_expand "neon_vand<mode>" - [(match_operand:VDQX 0 "s_register_operand" "") - (match_operand:VDQX 1 "s_register_operand" "") - (match_operand:VDQX 2 "neon_inv_logic_op2" "") - (match_operand:SI 3 "immediate_operand" "")] - "TARGET_NEON" -{ - emit_insn (gen_and<mode>3 (operands[0], operands[1], operands[2])); - DONE; -}) - -(define_expand "neon_vorr<mode>" - [(match_operand:VDQX 0 "s_register_operand" "") - (match_operand:VDQX 1 "s_register_operand" "") - (match_operand:VDQX 2 "neon_logic_op2" "") - (match_operand:SI 3 "immediate_operand" "")] - "TARGET_NEON" -{ - emit_insn (gen_ior<mode>3 (operands[0], operands[1], operands[2])); - DONE; -}) - -(define_expand "neon_veor<mode>" - [(match_operand:VDQX 0 "s_register_operand" "") - (match_operand:VDQX 1 "s_register_operand" "") - (match_operand:VDQX 2 "s_register_operand" "") - (match_operand:SI 3 "immediate_operand" "")] - "TARGET_NEON" -{ - emit_insn (gen_xor<mode>3 (operands[0], operands[1], operands[2])); - DONE; -}) - -(define_expand "neon_vbic<mode>" - [(match_operand:VDQX 0 "s_register_operand" "") - (match_operand:VDQX 1 "s_register_operand" "") - (match_operand:VDQX 2 "neon_logic_op2" "") - (match_operand:SI 3 "immediate_operand" "")] - "TARGET_NEON" -{ - emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2])); - DONE; -}) - -(define_expand "neon_vorn<mode>" - [(match_operand:VDQX 0 "s_register_operand" "") - (match_operand:VDQX 1 "s_register_operand" "") - (match_operand:VDQX 2 "neon_inv_logic_op2" "") - (match_operand:SI 3 "immediate_operand" "")] - "TARGET_NEON" -{ - emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2])); - DONE; -}) - (define_insn "neon_vec_unpack<US>_lo_<mode>" [(set (match_operand:<V_unpack> 0 "register_operand" "=w") (SE:<V_unpack> (vec_select:<V_HALF> |