Hi,
As subject, this patch rewrites [su]mlsl_high_lane[q] Neon intrinsics to use
RTL builtins rather than inline assembly code, allowing for better scheduling
and optimization.
Regression tested and bootstrapped on aarch64-none-linux-gnu and
aarch64_be-none-elf - no issues.
Ok for master?
Thanks,
Jonathan
---
gcc/ChangeLog:
2021-02-02 Jonathan Wright
* config/aarch64/aarch64-simd-builtins.def: Add
[su]mlsl_hi_lane[q] builtin macro generators.
* config/aarch64/aarch64-simd.md
(aarch64_mlsl_hi_lane_insn): Define.
(aarch64_mlsl_hi_lane): Define.
(aarch64_mlsl_hi_laneq_insn): Define.
(aarch64_mlsl_hi_laneq): Define.
* config/aarch64/arm_neon.h (vmlsl_high_lane_s16): Use RTL
builtin instead of inline asm.
(vmlsl_high_lane_s32): Likewise.
(vmlsl_high_lane_u16): Likewise.
(vmlsl_high_lane_u32): Likewise.
(vmlsl_high_laneq_s16): Likewise.
(vmlsl_high_laneq_s32): Likewise.
(vmlsl_high_laneq_u16): Likewise.
(vmlsl_high_laneq_u32): Likewise.
(vmlal_high_laneq_u32): Likewise.
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def
index 152c2e6d361bdab0275e3b38759723fd2a3ffee5..76ab021725900b249ecabf3f8df2167169a263e9 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -305,6 +305,11 @@
BUILTIN_VQ_HSI (QUADOPU_LANE, umlal_hi_lane, 0, NONE)
BUILTIN_VQ_HSI (QUADOPU_LANE, umlal_hi_laneq, 0, NONE)
+ BUILTIN_VQ_HSI (QUADOP_LANE, smlsl_hi_lane, 0, NONE)
+ BUILTIN_VQ_HSI (QUADOP_LANE, smlsl_hi_laneq, 0, NONE)
+ BUILTIN_VQ_HSI (QUADOPU_LANE, umlsl_hi_lane, 0, NONE)
+ BUILTIN_VQ_HSI (QUADOPU_LANE, umlsl_hi_laneq, 0, NONE)
+
BUILTIN_VSD_HSI (BINOP, sqdmull, 0, NONE)
BUILTIN_VSD_HSI (TERNOP_LANE, sqdmull_lane, 0, NONE)
BUILTIN_VSD_HSI (TERNOP_LANE, sqdmull_laneq, 0, NONE)
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index e741b656cb081e26b9e6e262ae50fab3716e1ed4..2e347b92b79cb0c1dfef710034602d8f61f62173 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -2270,6 +2270,78 @@
[(set_attr "type" "neon_mla__scalar_long")]
)
+(define_insn "aarch64_mlsl_hi_lane_insn"
+ [(set (match_operand: 0 "register_operand" "=w")
+ (minus:
+ (match_operand: 1 "register_operand" "0")
+ (mult:
+ (ANY_EXTEND: (vec_select:
+ (match_operand:VQ_HSI 2 "register_operand" "w")
+ (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
+ (ANY_EXTEND: (vec_duplicate:
+ (vec_select:
+ (match_operand: 4 "register_operand" "")
+ (parallel [(match_operand:SI 5 "immediate_operand" "i")]
+ )))]
+ "TARGET_SIMD"
+ {
+operands[5] = aarch64_endian_lane_rtx (mode, INTVAL (operands[5]));
+return "mlsl2\\t%0., %2., %4.[%5]";
+ }
+ [(set_attr "type" "neon_mla__scalar_long")]
+)
+
+(define_expand "aarch64_mlsl_hi_lane"
+ [(match_operand: 0 "register_operand")
+ (match_operand: 1 "register_operand")
+ (ANY_EXTEND:(match_operand:VQ_HSI 2 "register_operand"))
+ (match_operand: 3 "register_operand")
+ (match_operand:SI 4 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ rtx p = aarch64_simd_vect_par_cnst_half (mode, , true);
+ emit_insn (gen_aarch64_mlsl_hi_lane_insn (operands[0],
+ operands[1], operands[2], p, operands[3], operands[4]));
+ DONE;
+}
+)
+
+(define_insn "aarch64_mlsl_hi_laneq_insn"
+ [(set (match_operand: 0 "register_operand" "=w")
+ (minus:
+ (match_operand: 1 "register_operand" "0")
+ (mult:
+ (ANY_EXTEND: (vec_select:
+ (match_operand:VQ_HSI 2 "register_operand" "w")
+ (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
+ (ANY_EXTEND: (vec_duplicate:
+ (vec_select:
+ (match_operand: 4 "register_operand" "")
+ (parallel [(match_operand:SI 5 "immediate_operand" "i")]
+ )))]
+ "TARGET_SIMD"
+ {
+operands[5] = aarch64_endian_lane_rtx (mode, INTVAL (operands[5]));
+return "mlsl2\\t%0., %2., %4.[%5]";
+ }
+ [(set_attr "type" "neon_mla__scalar_long")]
+)
+
+(define_expand "aarch64_mlsl_hi_laneq"
+ [(match_operand: 0 "register_operand")
+ (match_operand: 1 "register_operand")
+ (ANY_EXTEND:(match_operand:VQ_HSI 2 "register_operand"))
+ (match_operand: 3 "register_operand")
+ (match_operand:SI 4 "immediate_operand")]
+ "TARGET_SIMD"
+{
+ rtx p = aarch64_simd_vect_par_cnst_half (mode, , true);
+ emit_insn (gen_aarch64_mlsl_hi_laneq_insn (operands[0],
+ operands[1], operands[2], p, operands[3], operands[4]));
+ DONE;
+}
+)
+
;; FP vector operations.
;; AArch64 AdvSIMD supports single-precision (32-bit) and
;; double-precision (64-bit) floating-point data types and arithmetic as
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index ee68240f0d019a4a3be89e1e923cb14ee8026468..7b99e16b53cae27f6d2e7a29985cb4963d74739e 100644
--- a/gcc/config/aarch64/arm_neon.h