Several SME patterns only needed C output blocks in order to compute the
last element of an assembler range. For example, patterns that print a
range such as:
0:<last>
were first calculating <last> in C, storing it in a temporary operand, and
then returning an otherwise fixed output string.
With the new named output modifiers we can keep those patterns as normal
templates. This patch adds internal AArch64 print operands for the SME
range cases and uses them from aarch64-sme.md. For example:
0:%[SME_VG_END]0
%1:%[SME_RANGE_END3]1
The first form prints the end of a vector-group range. The second prints
operand 1 plus 3, which is the inclusive end used by the corresponding SME
assembler syntax. The names are intentionally internal-only: they make
the machine descriptions clearer, but they are not new user asm
modifiers.
The result is that the SME patterns describe the instruction text directly
again, while the target hook keeps the small amount of range arithmetic in
one place.
Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.
OK for master?
Thanks,
Tamar
gcc/ChangeLog:
* config/aarch64/aarch64.cc (A64_PRINT_sme_vg_end): New print code.
(A64_PRINT_sme_range_end): Likewise.
(operands_cache_initializer): Register SME range operands.
(aarch64_print_operand): Handle them.
* config/aarch64/aarch64-sme.md
(@aarch64_sme_<optab><mode><mode>): Use SME_VG_END and
SME_RANGE_END* print operands in all definitions.
(*aarch64_sme_zero_za_slices<mode>_plus): Likewise.
(*aarch64_sme_<optab><VNx4SI_ONLY:mode><SVE_FULL_BHI:mode>_plus):
Likewise.
(*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>_plus):
Likewise.
(*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>_plus):
Likewise.
(*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx124:mode>):
Likewise.
(*aarch64_sme_<optab><VNx2DI_ONLY:mode><VNx8HI_ONLY:mode>_plus):
Likewise.
(*aarch64_sme_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>_plus):
Likewise.
(*aarch64_sme_single_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>_plus):
Likewise.
(*aarch64_sme_lane_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx124:mode>):
Likewise.
(*aarch64_sme_<optab><VNx4SI_ONLY:mode><SVE_FULL_HF:mode>_plus):
Likewise.
(*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>_plus):
Likewise.
(*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>_plus):
Likewise.
(*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx124:mode>):
Likewise.
(*aarch64_sme_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x24:mode>_plus):
Likewise.
(*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x24:mode>_plus):
Likewise.
(*aarch64_sme_<optab><VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>_plus):
Likewise.
(*aarch64_sme_<optab><VNx4SI_ONLY:mode><VNx16QI_ONLY:mode>_plus):
Likewise.
(*aarch64_sme_single_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x24:mode>_plus):
Likewise.
(*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x24:mode>_plus):
Likewise.
(*aarch64_sme_lane_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x124:mode>):
Likewise.
(*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x124:mode>):
Likewise.
---
diff --git a/gcc/config/aarch64/aarch64-sme.md
b/gcc/config/aarch64/aarch64-sme.md
index
0ad32f33273ec3d41be0d157f182246524d69ea1..60ea0668b97d9eea4034e9c021929a58f8cffcc6
100644
--- a/gcc/config/aarch64/aarch64-sme.md
+++ b/gcc/config/aarch64/aarch64-sme.md
@@ -856,10 +856,7 @@ (define_insn "@aarch64_sme_<optab><mode><mode>"
(match_operand:SI 2 "register_operand" "Ucj")]
SME_READ_HV))]
"TARGET_STREAMING_SME2"
- {
- operands[3] = GEN_INT (<vector_count> - 1);
- return "mova\t%0, za%1<hv>.<Vetype>[%w2, 0:%3]";
- }
+ "mova\t%0, za%1<hv>.<Vetype>[%w2, 0:%[SME_VG_END:0]]"
)
(define_insn "*aarch64_sme_<optab><mode><mode>_plus"
@@ -899,10 +896,7 @@ (define_insn "@aarch64_sme_<optab><mode><mode>"
(const_int 1)]
SME_READZ_HV))]
"TARGET_STREAMING_SME2p1"
- {
- operands[3] = GEN_INT (<vector_count> - 1);
- return "movaz\t%0, za%1<hv>.<Vetype>[%w2, 0:%3]";
- }
+ "movaz\t%0, za%1<hv>.<Vetype>[%w2, 0:%[SME_VG_END:0]]"
)
(define_insn "*aarch64_sme_<optab><mode><mode>_plus"
@@ -1008,10 +1002,7 @@ (define_insn "@aarch64_sme_<optab><mode><mode>"
(match_operand:SVE_FULLx24 2 "aligned_register_operand"
"Uw<vector_count>")]
SME_WRITE_HV))]
"TARGET_STREAMING_SME2"
- {
- operands[3] = GEN_INT (<vector_count> - 1);
- return "mova\tza%0<hv>.<Vetype>[%w1, 0:%3], %2";
- }
+ "mova\tza%0<hv>.<Vetype>[%w1, 0:%[SME_VG_END:2]], %2"
)
(define_insn "*aarch64_sme_<optab><mode><mode>_plus"
@@ -1147,10 +1138,7 @@ (define_insn "*aarch64_sme_zero_za_slices<mode>_plus"
(match_operand:SI 1 "const_<za32_offset_range>_operand"))]
UNSPEC_SME_ZERO_SLICES))]
"TARGET_STREAMING_SME2p1"
- {
- operands[2] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "zero\tza.d[%w0, %1:%2<vg_modifier>]";
- }
+ "zero\tza.d[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1]<vg_modifier>]"
)
(define_insn "aarch64_sme_zero_zt0"
@@ -1509,10 +1497,7 @@ (define_insn
"*aarch64_sme_<optab><VNx4SI_ONLY:mode><SVE_FULL_BHI:mode>_plus"
(match_operand:SVE_FULL_BHI 3 "register_operand" "x")]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "<optab><za32_long>\tza.s[%w0, %1:%4], %2.<SVE_FULL_BHI:Vetype>,
%3.<SVE_FULL_BHI:Vetype>";
- }
+ "<optab><za32_long>\tza.s[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1]],
%2.<SVE_FULL_BHI:Vetype>, %3.<SVE_FULL_BHI:Vetype>"
)
(define_insn "@aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>"
@@ -1539,10 +1524,7 @@ (define_insn
"*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>_plus"
(match_operand:SME_ZA_BHIx24 3 "aligned_register_operand"
"Uw<vector_count>")]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "<optab><za32_long>\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<optab><za32_long>\tza.s[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1],
vgx<vector_count>], %2, %3"
)
(define_insn
"@aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>"
@@ -1571,10 +1553,7 @@ (define_insn
"*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>_
(match_operand:<SME_ZA_BHIx24:VSINGLE> 3 "register_operand" "x"))]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "<optab><za32_long>\tza.s[%w0, %1:%4, vgx<vector_count>], %2,
%3.<SME_ZA_BHIx24:Vetype>";
- }
+ "<optab><za32_long>\tza.s[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1],
vgx<vector_count>], %2, %3.<SME_ZA_BHIx24:Vetype>"
)
(define_insn "@aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx124:mode>"
@@ -1607,10 +1586,7 @@ (define_insn
"*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx124:mode>"
UNSPEC_SVE_LANE_SELECT)]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "<optab><za32_long>\tza.s[%w0, %1:%5<vg_modifier>], %2<z_suffix>,
%3.<SME_ZA_BHIx124:Vetype>[%4]";
- }
+ "<optab><za32_long>\tza.s[%w0,
%1:%[SME_RANGE_END<za32_last_offset>:1]<vg_modifier>], %2<z_suffix>,
%3.<SME_ZA_BHIx124:Vetype>[%4]"
)
(define_insn "@aarch64_sme_<optab><VNx2DI_ONLY:mode><VNx8HI_ONLY:mode>"
@@ -1637,10 +1613,7 @@ (define_insn
"*aarch64_sme_<optab><VNx2DI_ONLY:mode><VNx8HI_ONLY:mode>_plus"
(match_operand:VNx8HI_ONLY 3 "register_operand" "x")]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2 && TARGET_SME_I16I64"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>ll\tza.d[%w0, %1:%4], %2.h, %3.h";
- }
+ "<optab>ll\tza.d[%w0, %1:%[SME_RANGE_END3:1]], %2.h, %3.h"
)
(define_insn "@aarch64_sme_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>"
@@ -1667,10 +1640,7 @@ (define_insn
"*aarch64_sme_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>_plus"
(match_operand:SME_ZA_HIx24 3 "aligned_register_operand"
"Uw<vector_count>")]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2 && TARGET_SME_I16I64"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>ll\tza.d[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<optab>ll\tza.d[%w0, %1:%[SME_RANGE_END3:1], vgx<vector_count>], %2, %3"
)
(define_insn "@aarch64_sme_single_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>"
@@ -1699,10 +1669,7 @@ (define_insn
"*aarch64_sme_single_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>_p
(match_operand:<SME_ZA_HIx24:VSINGLE> 3 "register_operand" "x"))]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2 && TARGET_SME_I16I64"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>ll\tza.d[%w0, %1:%4, vgx<vector_count>], %2, %3.h";
- }
+ "<optab>ll\tza.d[%w0, %1:%[SME_RANGE_END3:1], vgx<vector_count>], %2, %3.h"
)
(define_insn "@aarch64_sme_lane_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx124:mode>"
@@ -1735,10 +1702,7 @@ (define_insn
"*aarch64_sme_lane_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx124:mode>"
UNSPEC_SVE_LANE_SELECT)]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2 && TARGET_SME_I16I64"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>ll\tza.d[%w0, %1:%5<vg_modifier>], %2<z_suffix>, %3.h[%4]";
- }
+ "<optab>ll\tza.d[%w0, %1:%[SME_RANGE_END3:1]<vg_modifier>], %2<z_suffix>,
%3.h[%4]"
)
;; -------------------------------------------------------------------------
@@ -2443,10 +2407,7 @@ (define_insn
"*aarch64_sme_<optab><VNx4SI_ONLY:mode><SVE_FULL_HF:mode>_plus"
(match_operand:SVE_FULL_HF 3 "register_operand" "x")]
SME_FP_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<b><optab>l\tza.s[%w0, %1:%4], %2.h, %3.h";
- }
+ "<b><optab>l\tza.s[%w0, %1:%[SME_RANGE_END1:1]], %2.h, %3.h"
)
(define_insn "@aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>"
@@ -2473,10 +2434,7 @@ (define_insn
"*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>_plus"
(match_operand:SME_ZA_HFx24 3 "aligned_register_operand"
"Uw<vector_count>")]
SME_FP_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<b><optab>l\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<b><optab>l\tza.s[%w0, %1:%[SME_RANGE_END1:1], vgx<vector_count>], %2, %3"
)
(define_insn "@aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>"
@@ -2505,10 +2463,7 @@ (define_insn
"*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>_p
(match_operand:<SME_ZA_HFx24:VSINGLE> 3 "register_operand" "x"))]
SME_FP_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<b><optab>l\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3.h";
- }
+ "<b><optab>l\tza.s[%w0, %1:%[SME_RANGE_END1:1], vgx<vector_count>], %2, %3.h"
)
(define_insn "@aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx124:mode>"
@@ -2541,10 +2496,7 @@ (define_insn
"*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx124:mode>"
UNSPEC_SVE_LANE_SELECT)]
SME_FP_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<b><optab>l\tza.s[%w0, %1:%5<vg_modifier>], %2<z_suffix>,
%3.h[%4]";
- }
+ "<b><optab>l\tza.s[%w0, %1:%[SME_RANGE_END1:1]<vg_modifier>], %2<z_suffix>,
%3.h[%4]"
)
;; svmla_za16[_mf8]_vg2x2_fpm, svmla_za16[_mf8]_vg2x4_fpm
@@ -2576,10 +2528,7 @@ (define_insn
"*aarch64_sme_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x24:mode>_plus"
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F16"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<optab>\tza.h[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<optab>\tza.h[%w0, %1:%[SME_RANGE_END1:1], vgx<vector_count>], %2, %3"
)
;; svmla_za32[_mf8]_vg4x2_fpm, svmla_za32[_mf8]_vg4x4_fpm (slice variable +
offset)
@@ -2595,10 +2544,7 @@ (define_insn
"*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x24:mode>_plus"
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F32"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>l\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<optab>l\tza.s[%w0, %1:%[SME_RANGE_END3:1], vgx<vector_count>], %2, %3"
)
;; svmla_za16[_mf8]_vg2x1_fpm, svmla_za32[_mf8]_vg4x1_fpm
@@ -2629,10 +2575,7 @@ (define_insn
"*aarch64_sme_<optab><VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>_plus"
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F16"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<optab>\tza.h[%w0, %1:%4<vg_modifier>], %2.b, %3.b";
- }
+ "<optab>\tza.h[%w0, %1:%[SME_RANGE_END1:1]<vg_modifier>], %2.b, %3.b"
)
;; svmla_za32[_mf8]_vg4x1_fpm (slice variable + offset)
@@ -2648,10 +2591,7 @@ (define_insn
"*aarch64_sme_<optab><VNx4SI_ONLY:mode><VNx16QI_ONLY:mode>_plus"
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F32"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>l\tza.s[%w0, %1:%4<vg_modifier>], %2.b, %3.b";
- }
+ "<optab>l\tza.s[%w0, %1:%[SME_RANGE_END3:1]<vg_modifier>], %2.b, %3.b"
)
;; svmla[_single]_za16[_mf8]_vg2x2_fpm, svmla[_single]_za16[_mf8]_vg2x4_fpm,
@@ -2685,10 +2625,7 @@ (define_insn
"*aarch64_sme_single_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x24:mode>
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F16"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<optab>\tza.h[%w0, %1:%4, vgx<vector_count>], %2, %3.b";
- }
+ "<optab>\tza.h[%w0, %1:%[SME_RANGE_END1:1], vgx<vector_count>], %2, %3.b"
)
;; svmla[_single]_za32[_mf8]_vg4x2_fpm, svmla[_single]_za32[_mf8]_vg4x4_fpm
(slice variable + offset)
@@ -2705,10 +2642,7 @@ (define_insn
"*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x24:mode>
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F32"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>l\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3.b";
- }
+ "<optab>l\tza.s[%w0, %1:%[SME_RANGE_END3:1], vgx<vector_count>], %2, %3.b"
)
;; svmla_lane_za16[_mf8]_vg2x1_fpm, svmla_lane_za32[_mf8]_vg4x1_fpm,
@@ -2747,11 +2681,8 @@ (define_insn
"*aarch64_sme_lane_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x124:mode>"
UNSPEC_SVE_LANE_SELECT)
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
- "TARGET_STREAMING_SME_F8F16"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<optab>\tza.h[%w0, %1:%5<SME_ZA_FP8_x124:vg_modifier>],
%2<SME_ZA_FP8_x124:z_suffix>, %3.b[%4]";
- }
+ "TARGET_STREAMING_SME_F8F16"
+ "<optab>\tza.h[%w0, %1:%[SME_RANGE_END1:1]<SME_ZA_FP8_x124:vg_modifier>],
%2<SME_ZA_FP8_x124:z_suffix>, %3.b[%4]"
)
;; svmla_lane_za32[_mf8]_vg4x1_fpm, svmla_lane_za32[_mf8]_vg4x2_fpm,
@@ -2770,11 +2701,8 @@ (define_insn
"*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x124:mode>"
UNSPEC_SVE_LANE_SELECT)
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
- "TARGET_STREAMING_SME_F8F32"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>l\tza.s[%w0, %1:%5<SME_ZA_FP8_x124:vg_modifier>],
%2<z_suffix>, %3.b[%4]";
- }
+ "TARGET_STREAMING_SME_F8F32"
+ "<optab>l\tza.s[%w0, %1:%[SME_RANGE_END3:1]<SME_ZA_FP8_x124:vg_modifier>],
%2<z_suffix>, %3.b[%4]"
)
;; -------------------------------------------------------------------------
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index
603e0dea43073abf33f606441a7f7b106115c608..70d739f9b9ac56dec02de4cde5ea2a87f75f64af
100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -13263,6 +13263,10 @@ typedef enum aarch64_print_operands {
A64_PRINT_addr_ldp_stp_np,
/* Output address of a typical LDP or STP. */
A64_PRINT_addr_ldp_stp,
+ /* Print the final element offset for an SME vector group. */
+ A64_PRINT_sme_vg_end,
+ /* Print the inclusive end of an SME slice range. */
+ A64_PRINT_sme_range_end,
/* Unknown print operand. */
A64_PRINT_UNKNOWN
} aarch64_print_operands_t;
@@ -13325,6 +13329,9 @@ struct operands_cache_initializer
DEF_PUBLIC_OPERAND (X, A64_PRINT_bottom_16bits);
DEF_PUBLIC_OPERAND (y, A64_PRINT_addr_ldp_stp_np);
DEF_PUBLIC_OPERAND (z, A64_PRINT_addr_ldp_stp);
+ DEF_PRIVATE_OPERAND (SME_VG_END, A64_PRINT_sme_vg_end);
+ DEF_PRIVATE_OPERAND_EXT (SME_RANGE_END1, A64_PRINT_sme_range_end, 1);
+ DEF_PRIVATE_OPERAND_EXT (SME_RANGE_END3, A64_PRINT_sme_range_end, 3);
#undef DEF_PUBLIC_OPERAND
#undef DEF_PRIVATE_OPERAND
@@ -13888,6 +13895,31 @@ aarch64_print_operand (FILE *f, rtx x, int code)
}
break;
+ case A64_PRINT_sme_vg_end:
+ if (!REG_P (x) || !FP_REGNUM_P (REGNO (x)))
+ {
+ output_operand_lossage ("invalid operand for '%%%s'",
+ token.c_str ());
+ return;
+ }
+ asm_fprintf (f, "%d", REG_NREGS (x) - 1);
+ break;
+
+ case A64_PRINT_sme_range_end:
+ {
+ uintptr_t range_len = (uintptr_t) print_info.extra;
+
+ if (range_len == 0 || !CONST_INT_P (x))
+ {
+ output_operand_lossage ("invalid operand for '%%%s'",
+ token.c_str ());
+ return;
+ }
+
+ asm_fprintf (f, "%wd", INTVAL (x) + range_len);
+ }
+ break;
+
default:
output_operand_lossage ("invalid operand prefix '%%%s'",
token.c_str ());
--
diff --git a/gcc/config/aarch64/aarch64-sme.md b/gcc/config/aarch64/aarch64-sme.md
index 0ad32f33273ec3d41be0d157f182246524d69ea1..60ea0668b97d9eea4034e9c021929a58f8cffcc6 100644
--- a/gcc/config/aarch64/aarch64-sme.md
+++ b/gcc/config/aarch64/aarch64-sme.md
@@ -856,10 +856,7 @@ (define_insn "@aarch64_sme_<optab><mode><mode>"
(match_operand:SI 2 "register_operand" "Ucj")]
SME_READ_HV))]
"TARGET_STREAMING_SME2"
- {
- operands[3] = GEN_INT (<vector_count> - 1);
- return "mova\t%0, za%1<hv>.<Vetype>[%w2, 0:%3]";
- }
+ "mova\t%0, za%1<hv>.<Vetype>[%w2, 0:%[SME_VG_END:0]]"
)
(define_insn "*aarch64_sme_<optab><mode><mode>_plus"
@@ -899,10 +896,7 @@ (define_insn "@aarch64_sme_<optab><mode><mode>"
(const_int 1)]
SME_READZ_HV))]
"TARGET_STREAMING_SME2p1"
- {
- operands[3] = GEN_INT (<vector_count> - 1);
- return "movaz\t%0, za%1<hv>.<Vetype>[%w2, 0:%3]";
- }
+ "movaz\t%0, za%1<hv>.<Vetype>[%w2, 0:%[SME_VG_END:0]]"
)
(define_insn "*aarch64_sme_<optab><mode><mode>_plus"
@@ -1008,10 +1002,7 @@ (define_insn "@aarch64_sme_<optab><mode><mode>"
(match_operand:SVE_FULLx24 2 "aligned_register_operand" "Uw<vector_count>")]
SME_WRITE_HV))]
"TARGET_STREAMING_SME2"
- {
- operands[3] = GEN_INT (<vector_count> - 1);
- return "mova\tza%0<hv>.<Vetype>[%w1, 0:%3], %2";
- }
+ "mova\tza%0<hv>.<Vetype>[%w1, 0:%[SME_VG_END:2]], %2"
)
(define_insn "*aarch64_sme_<optab><mode><mode>_plus"
@@ -1147,10 +1138,7 @@ (define_insn "*aarch64_sme_zero_za_slices<mode>_plus"
(match_operand:SI 1 "const_<za32_offset_range>_operand"))]
UNSPEC_SME_ZERO_SLICES))]
"TARGET_STREAMING_SME2p1"
- {
- operands[2] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "zero\tza.d[%w0, %1:%2<vg_modifier>]";
- }
+ "zero\tza.d[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1]<vg_modifier>]"
)
(define_insn "aarch64_sme_zero_zt0"
@@ -1509,10 +1497,7 @@ (define_insn "*aarch64_sme_<optab><VNx4SI_ONLY:mode><SVE_FULL_BHI:mode>_plus"
(match_operand:SVE_FULL_BHI 3 "register_operand" "x")]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "<optab><za32_long>\tza.s[%w0, %1:%4], %2.<SVE_FULL_BHI:Vetype>, %3.<SVE_FULL_BHI:Vetype>";
- }
+ "<optab><za32_long>\tza.s[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1]], %2.<SVE_FULL_BHI:Vetype>, %3.<SVE_FULL_BHI:Vetype>"
)
(define_insn "@aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>"
@@ -1539,10 +1524,7 @@ (define_insn "*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>_plus"
(match_operand:SME_ZA_BHIx24 3 "aligned_register_operand" "Uw<vector_count>")]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "<optab><za32_long>\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<optab><za32_long>\tza.s[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1], vgx<vector_count>], %2, %3"
)
(define_insn "@aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>"
@@ -1571,10 +1553,7 @@ (define_insn "*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx24:mode>_
(match_operand:<SME_ZA_BHIx24:VSINGLE> 3 "register_operand" "x"))]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "<optab><za32_long>\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3.<SME_ZA_BHIx24:Vetype>";
- }
+ "<optab><za32_long>\tza.s[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1], vgx<vector_count>], %2, %3.<SME_ZA_BHIx24:Vetype>"
)
(define_insn "@aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx124:mode>"
@@ -1607,10 +1586,7 @@ (define_insn "*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_BHIx124:mode>"
UNSPEC_SVE_LANE_SELECT)]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + <za32_last_offset>);
- return "<optab><za32_long>\tza.s[%w0, %1:%5<vg_modifier>], %2<z_suffix>, %3.<SME_ZA_BHIx124:Vetype>[%4]";
- }
+ "<optab><za32_long>\tza.s[%w0, %1:%[SME_RANGE_END<za32_last_offset>:1]<vg_modifier>], %2<z_suffix>, %3.<SME_ZA_BHIx124:Vetype>[%4]"
)
(define_insn "@aarch64_sme_<optab><VNx2DI_ONLY:mode><VNx8HI_ONLY:mode>"
@@ -1637,10 +1613,7 @@ (define_insn "*aarch64_sme_<optab><VNx2DI_ONLY:mode><VNx8HI_ONLY:mode>_plus"
(match_operand:VNx8HI_ONLY 3 "register_operand" "x")]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2 && TARGET_SME_I16I64"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>ll\tza.d[%w0, %1:%4], %2.h, %3.h";
- }
+ "<optab>ll\tza.d[%w0, %1:%[SME_RANGE_END3:1]], %2.h, %3.h"
)
(define_insn "@aarch64_sme_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>"
@@ -1667,10 +1640,7 @@ (define_insn "*aarch64_sme_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>_plus"
(match_operand:SME_ZA_HIx24 3 "aligned_register_operand" "Uw<vector_count>")]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2 && TARGET_SME_I16I64"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>ll\tza.d[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<optab>ll\tza.d[%w0, %1:%[SME_RANGE_END3:1], vgx<vector_count>], %2, %3"
)
(define_insn "@aarch64_sme_single_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>"
@@ -1699,10 +1669,7 @@ (define_insn "*aarch64_sme_single_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx24:mode>_p
(match_operand:<SME_ZA_HIx24:VSINGLE> 3 "register_operand" "x"))]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2 && TARGET_SME_I16I64"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>ll\tza.d[%w0, %1:%4, vgx<vector_count>], %2, %3.h";
- }
+ "<optab>ll\tza.d[%w0, %1:%[SME_RANGE_END3:1], vgx<vector_count>], %2, %3.h"
)
(define_insn "@aarch64_sme_lane_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx124:mode>"
@@ -1735,10 +1702,7 @@ (define_insn "*aarch64_sme_lane_<optab><VNx2DI_ONLY:mode><SME_ZA_HIx124:mode>"
UNSPEC_SVE_LANE_SELECT)]
SME_INT_TERNARY_SLICE))]
"TARGET_STREAMING_SME2 && TARGET_SME_I16I64"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>ll\tza.d[%w0, %1:%5<vg_modifier>], %2<z_suffix>, %3.h[%4]";
- }
+ "<optab>ll\tza.d[%w0, %1:%[SME_RANGE_END3:1]<vg_modifier>], %2<z_suffix>, %3.h[%4]"
)
;; -------------------------------------------------------------------------
@@ -2443,10 +2407,7 @@ (define_insn "*aarch64_sme_<optab><VNx4SI_ONLY:mode><SVE_FULL_HF:mode>_plus"
(match_operand:SVE_FULL_HF 3 "register_operand" "x")]
SME_FP_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<b><optab>l\tza.s[%w0, %1:%4], %2.h, %3.h";
- }
+ "<b><optab>l\tza.s[%w0, %1:%[SME_RANGE_END1:1]], %2.h, %3.h"
)
(define_insn "@aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>"
@@ -2473,10 +2434,7 @@ (define_insn "*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>_plus"
(match_operand:SME_ZA_HFx24 3 "aligned_register_operand" "Uw<vector_count>")]
SME_FP_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<b><optab>l\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<b><optab>l\tza.s[%w0, %1:%[SME_RANGE_END1:1], vgx<vector_count>], %2, %3"
)
(define_insn "@aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>"
@@ -2505,10 +2463,7 @@ (define_insn "*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx24:mode>_p
(match_operand:<SME_ZA_HFx24:VSINGLE> 3 "register_operand" "x"))]
SME_FP_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<b><optab>l\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3.h";
- }
+ "<b><optab>l\tza.s[%w0, %1:%[SME_RANGE_END1:1], vgx<vector_count>], %2, %3.h"
)
(define_insn "@aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx124:mode>"
@@ -2541,10 +2496,7 @@ (define_insn "*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_HFx124:mode>"
UNSPEC_SVE_LANE_SELECT)]
SME_FP_TERNARY_SLICE))]
"TARGET_STREAMING_SME2"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<b><optab>l\tza.s[%w0, %1:%5<vg_modifier>], %2<z_suffix>, %3.h[%4]";
- }
+ "<b><optab>l\tza.s[%w0, %1:%[SME_RANGE_END1:1]<vg_modifier>], %2<z_suffix>, %3.h[%4]"
)
;; svmla_za16[_mf8]_vg2x2_fpm, svmla_za16[_mf8]_vg2x4_fpm
@@ -2576,10 +2528,7 @@ (define_insn "*aarch64_sme_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x24:mode>_plus"
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F16"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<optab>\tza.h[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<optab>\tza.h[%w0, %1:%[SME_RANGE_END1:1], vgx<vector_count>], %2, %3"
)
;; svmla_za32[_mf8]_vg4x2_fpm, svmla_za32[_mf8]_vg4x4_fpm (slice variable + offset)
@@ -2595,10 +2544,7 @@ (define_insn "*aarch64_sme_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x24:mode>_plus"
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F32"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>l\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3";
- }
+ "<optab>l\tza.s[%w0, %1:%[SME_RANGE_END3:1], vgx<vector_count>], %2, %3"
)
;; svmla_za16[_mf8]_vg2x1_fpm, svmla_za32[_mf8]_vg4x1_fpm
@@ -2629,10 +2575,7 @@ (define_insn "*aarch64_sme_<optab><VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>_plus"
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F16"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<optab>\tza.h[%w0, %1:%4<vg_modifier>], %2.b, %3.b";
- }
+ "<optab>\tza.h[%w0, %1:%[SME_RANGE_END1:1]<vg_modifier>], %2.b, %3.b"
)
;; svmla_za32[_mf8]_vg4x1_fpm (slice variable + offset)
@@ -2648,10 +2591,7 @@ (define_insn "*aarch64_sme_<optab><VNx4SI_ONLY:mode><VNx16QI_ONLY:mode>_plus"
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F32"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>l\tza.s[%w0, %1:%4<vg_modifier>], %2.b, %3.b";
- }
+ "<optab>l\tza.s[%w0, %1:%[SME_RANGE_END3:1]<vg_modifier>], %2.b, %3.b"
)
;; svmla[_single]_za16[_mf8]_vg2x2_fpm, svmla[_single]_za16[_mf8]_vg2x4_fpm,
@@ -2685,10 +2625,7 @@ (define_insn "*aarch64_sme_single_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x24:mode>
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F16"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<optab>\tza.h[%w0, %1:%4, vgx<vector_count>], %2, %3.b";
- }
+ "<optab>\tza.h[%w0, %1:%[SME_RANGE_END1:1], vgx<vector_count>], %2, %3.b"
)
;; svmla[_single]_za32[_mf8]_vg4x2_fpm, svmla[_single]_za32[_mf8]_vg4x4_fpm (slice variable + offset)
@@ -2705,10 +2642,7 @@ (define_insn "*aarch64_sme_single_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x24:mode>
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
"TARGET_STREAMING_SME_F8F32"
- {
- operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>l\tza.s[%w0, %1:%4, vgx<vector_count>], %2, %3.b";
- }
+ "<optab>l\tza.s[%w0, %1:%[SME_RANGE_END3:1], vgx<vector_count>], %2, %3.b"
)
;; svmla_lane_za16[_mf8]_vg2x1_fpm, svmla_lane_za32[_mf8]_vg4x1_fpm,
@@ -2747,11 +2681,8 @@ (define_insn "*aarch64_sme_lane_<optab><VNx8HI_ONLY:mode><SME_ZA_FP8_x124:mode>"
UNSPEC_SVE_LANE_SELECT)
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
- "TARGET_STREAMING_SME_F8F16"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + 1);
- return "<optab>\tza.h[%w0, %1:%5<SME_ZA_FP8_x124:vg_modifier>], %2<SME_ZA_FP8_x124:z_suffix>, %3.b[%4]";
- }
+ "TARGET_STREAMING_SME_F8F16"
+ "<optab>\tza.h[%w0, %1:%[SME_RANGE_END1:1]<SME_ZA_FP8_x124:vg_modifier>], %2<SME_ZA_FP8_x124:z_suffix>, %3.b[%4]"
)
;; svmla_lane_za32[_mf8]_vg4x1_fpm, svmla_lane_za32[_mf8]_vg4x2_fpm,
@@ -2770,11 +2701,8 @@ (define_insn "*aarch64_sme_lane_<optab><VNx4SI_ONLY:mode><SME_ZA_FP8_x124:mode>"
UNSPEC_SVE_LANE_SELECT)
(reg:DI FPM_REGNUM)]
SME_FP8_TERNARY_SLICE))]
- "TARGET_STREAMING_SME_F8F32"
- {
- operands[5] = GEN_INT (INTVAL (operands[1]) + 3);
- return "<optab>l\tza.s[%w0, %1:%5<SME_ZA_FP8_x124:vg_modifier>], %2<z_suffix>, %3.b[%4]";
- }
+ "TARGET_STREAMING_SME_F8F32"
+ "<optab>l\tza.s[%w0, %1:%[SME_RANGE_END3:1]<SME_ZA_FP8_x124:vg_modifier>], %2<z_suffix>, %3.b[%4]"
)
;; -------------------------------------------------------------------------
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 603e0dea43073abf33f606441a7f7b106115c608..70d739f9b9ac56dec02de4cde5ea2a87f75f64af 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -13263,6 +13263,10 @@ typedef enum aarch64_print_operands {
A64_PRINT_addr_ldp_stp_np,
/* Output address of a typical LDP or STP. */
A64_PRINT_addr_ldp_stp,
+ /* Print the final element offset for an SME vector group. */
+ A64_PRINT_sme_vg_end,
+ /* Print the inclusive end of an SME slice range. */
+ A64_PRINT_sme_range_end,
/* Unknown print operand. */
A64_PRINT_UNKNOWN
} aarch64_print_operands_t;
@@ -13325,6 +13329,9 @@ struct operands_cache_initializer
DEF_PUBLIC_OPERAND (X, A64_PRINT_bottom_16bits);
DEF_PUBLIC_OPERAND (y, A64_PRINT_addr_ldp_stp_np);
DEF_PUBLIC_OPERAND (z, A64_PRINT_addr_ldp_stp);
+ DEF_PRIVATE_OPERAND (SME_VG_END, A64_PRINT_sme_vg_end);
+ DEF_PRIVATE_OPERAND_EXT (SME_RANGE_END1, A64_PRINT_sme_range_end, 1);
+ DEF_PRIVATE_OPERAND_EXT (SME_RANGE_END3, A64_PRINT_sme_range_end, 3);
#undef DEF_PUBLIC_OPERAND
#undef DEF_PRIVATE_OPERAND
@@ -13888,6 +13895,31 @@ aarch64_print_operand (FILE *f, rtx x, int code)
}
break;
+ case A64_PRINT_sme_vg_end:
+ if (!REG_P (x) || !FP_REGNUM_P (REGNO (x)))
+ {
+ output_operand_lossage ("invalid operand for '%%%s'",
+ token.c_str ());
+ return;
+ }
+ asm_fprintf (f, "%d", REG_NREGS (x) - 1);
+ break;
+
+ case A64_PRINT_sme_range_end:
+ {
+ uintptr_t range_len = (uintptr_t) print_info.extra;
+
+ if (range_len == 0 || !CONST_INT_P (x))
+ {
+ output_operand_lossage ("invalid operand for '%%%s'",
+ token.c_str ());
+ return;
+ }
+
+ asm_fprintf (f, "%wd", INTVAL (x) + range_len);
+ }
+ break;
+
default:
output_operand_lossage ("invalid operand prefix '%%%s'",
token.c_str ());