1 /* This testcase is part of GDB, the GNU debugger.
3 Copyright 2023-2024 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* Exercise AArch64's Scalable Vector/Matrix Extension signal frame handling
23 #include <sys/prctl.h>
30 #define HWCAP_SVE (1 << 22)
34 #define HWCAP2_SME (1 << 23)
38 #define HWCAP2_SME2 (1UL << 37)
39 #define HWCAP2_SME2P1 (1UL << 38)
43 #define PR_SVE_SET_VL 50
44 #define PR_SVE_GET_VL 51
45 #define PR_SVE_VL_LEN_MASK 0xffff
49 #define PR_SME_SET_VL 63
50 #define PR_SME_GET_VL 64
51 #define PR_SME_VL_LEN_MASK 0xffff
59 count
++; /* handler */
66 __asm
__volatile (".word 0xD503457F");
73 __asm
__volatile (".word 0xD503447F");
80 __asm
__volatile (".word 0xD503437F");
87 __asm
__volatile (".word 0xD503427F");
91 initialize_fpsimd_state ()
95 for (int i
= 0; i
< 16; i
++)
98 __asm
__volatile ("mov x0, %0\n\t" \
101 __asm
__volatile ("ldr q0, [x0]");
102 __asm
__volatile ("ldr q1, [x0]");
103 __asm
__volatile ("ldr q2, [x0]");
104 __asm
__volatile ("ldr q3, [x0]");
105 __asm
__volatile ("ldr q4, [x0]");
106 __asm
__volatile ("ldr q5, [x0]");
107 __asm
__volatile ("ldr q6, [x0]");
108 __asm
__volatile ("ldr q7, [x0]");
109 __asm
__volatile ("ldr q8, [x0]");
110 __asm
__volatile ("ldr q9, [x0]");
111 __asm
__volatile ("ldr q10, [x0]");
112 __asm
__volatile ("ldr q11, [x0]");
113 __asm
__volatile ("ldr q12, [x0]");
114 __asm
__volatile ("ldr q13, [x0]");
115 __asm
__volatile ("ldr q14, [x0]");
116 __asm
__volatile ("ldr q15, [x0]");
117 __asm
__volatile ("ldr q16, [x0]");
118 __asm
__volatile ("ldr q17, [x0]");
119 __asm
__volatile ("ldr q18, [x0]");
120 __asm
__volatile ("ldr q19, [x0]");
121 __asm
__volatile ("ldr q20, [x0]");
122 __asm
__volatile ("ldr q21, [x0]");
123 __asm
__volatile ("ldr q22, [x0]");
124 __asm
__volatile ("ldr q23, [x0]");
125 __asm
__volatile ("ldr q24, [x0]");
126 __asm
__volatile ("ldr q25, [x0]");
127 __asm
__volatile ("ldr q26, [x0]");
128 __asm
__volatile ("ldr q27, [x0]");
129 __asm
__volatile ("ldr q28, [x0]");
130 __asm
__volatile ("ldr q29, [x0]");
131 __asm
__volatile ("ldr q30, [x0]");
132 __asm
__volatile ("ldr q31, [x0]");
136 initialize_za_state ()
139 __asm
__volatile (".word 0xC00800FF");
143 for (int i
= 0; i
< 256; i
++)
146 __asm
__volatile ("mov x0, %0\n\t" \
149 /* Initialize loop boundaries. */
150 __asm
__volatile ("mov w12, 0");
151 __asm
__volatile ("mov w17, 256");
153 /* loop: ldr za[w12, 0], [x0] */
154 __asm
__volatile ("loop: .word 0xe1000000");
155 __asm
__volatile ("add w12, w12, 1");
156 __asm
__volatile ("cmp w12, w17");
157 __asm
__volatile ("bne loop");
161 initialize_zt_state ()
163 unsigned long hwcap2
= getauxval (AT_HWCAP2
);
165 if (!(hwcap2
& HWCAP2_SME2
) && !(hwcap2
& HWCAP2_SME2P1
))
170 for (int i
= 0; i
< 64; i
++)
173 __asm
__volatile ("mov x0, %0\n\t" \
176 /* Initialize ZT0. */
178 __asm
__volatile (".word 0xe11f8000");
182 initialize_sve_state ()
184 __asm
__volatile ("dup z0.b, -1");
185 __asm
__volatile ("dup z1.b, -1");
186 __asm
__volatile ("dup z2.b, -1");
187 __asm
__volatile ("dup z3.b, -1");
188 __asm
__volatile ("dup z4.b, -1");
189 __asm
__volatile ("dup z5.b, -1");
190 __asm
__volatile ("dup z6.b, -1");
191 __asm
__volatile ("dup z7.b, -1");
192 __asm
__volatile ("dup z8.b, -1");
193 __asm
__volatile ("dup z9.b, -1");
194 __asm
__volatile ("dup z10.b, -1");
195 __asm
__volatile ("dup z11.b, -1");
196 __asm
__volatile ("dup z12.b, -1");
197 __asm
__volatile ("dup z13.b, -1");
198 __asm
__volatile ("dup z14.b, -1");
199 __asm
__volatile ("dup z15.b, -1");
200 __asm
__volatile ("dup z16.b, -1");
201 __asm
__volatile ("dup z17.b, -1");
202 __asm
__volatile ("dup z18.b, -1");
203 __asm
__volatile ("dup z19.b, -1");
204 __asm
__volatile ("dup z20.b, -1");
205 __asm
__volatile ("dup z21.b, -1");
206 __asm
__volatile ("dup z22.b, -1");
207 __asm
__volatile ("dup z23.b, -1");
208 __asm
__volatile ("dup z24.b, -1");
209 __asm
__volatile ("dup z25.b, -1");
210 __asm
__volatile ("dup z26.b, -1");
211 __asm
__volatile ("dup z27.b, -1");
212 __asm
__volatile ("dup z28.b, -1");
213 __asm
__volatile ("dup z29.b, -1");
214 __asm
__volatile ("dup z30.b, -1");
215 __asm
__volatile ("dup z31.b, -1");
216 __asm
__volatile ("ptrue p0.b");
217 __asm
__volatile ("ptrue p1.b");
218 __asm
__volatile ("ptrue p2.b");
219 __asm
__volatile ("ptrue p3.b");
220 __asm
__volatile ("ptrue p4.b");
221 __asm
__volatile ("ptrue p5.b");
222 __asm
__volatile ("ptrue p6.b");
223 __asm
__volatile ("ptrue p7.b");
224 __asm
__volatile ("ptrue p8.b");
225 __asm
__volatile ("ptrue p9.b");
226 __asm
__volatile ("ptrue p10.b");
227 __asm
__volatile ("ptrue p11.b");
228 __asm
__volatile ("ptrue p12.b");
229 __asm
__volatile ("ptrue p13.b");
230 __asm
__volatile ("ptrue p14.b");
231 __asm
__volatile ("ptrue p15.b");
232 __asm
__volatile ("setffr");
235 static int get_vl_size ()
237 int res
= prctl (PR_SVE_GET_VL
, 0, 0, 0, 0);
240 printf ("FAILED to PR_SVE_GET_VL (%d)\n", res
);
243 return (res
& PR_SVE_VL_LEN_MASK
);
246 static int get_svl_size ()
248 int res
= prctl (PR_SME_GET_VL
, 0, 0, 0, 0);
251 printf ("FAILED to PR_SME_GET_VL (%d)\n", res
);
254 return (res
& PR_SVE_VL_LEN_MASK
);
257 static int set_vl_size (int new_vl
)
259 int res
= prctl (PR_SVE_SET_VL
, new_vl
, 0, 0, 0, 0);
262 printf ("FAILED to PR_SVE_SET_VL (%d)\n", res
);
266 res
= get_vl_size ();
269 printf ("Unexpected VL value (%d)\n", res
);
276 static int set_svl_size (int new_svl
)
278 int res
= prctl (PR_SME_SET_VL
, new_svl
, 0, 0, 0, 0);
281 printf ("FAILED to PR_SME_SET_VL (%d)\n", res
);
285 res
= get_svl_size ();
288 printf ("Unexpected SVL value (%d)\n", res
);
295 /* Enable register states based on STATE.
301 4 - ZA and SSVE (+ SME2 ZT0). */
303 void enable_states (int state
)
307 initialize_fpsimd_state ();
311 initialize_sve_state ();
316 initialize_sve_state ();
321 initialize_za_state ();
322 initialize_zt_state ();
328 initialize_sve_state ();
329 initialize_za_state ();
330 initialize_zt_state ();
337 test_id_to_state (int id
)
343 test_id_to_vl (int id
)
345 return 16 << ((id
/ 5) % 5);
349 test_id_to_svl (int id
)
351 return 16 << (id
% 5);
360 main (int argc
, char **argv
)
362 if (getauxval (AT_HWCAP
) & HWCAP_SVE
&& getauxval (AT_HWCAP2
) & HWCAP2_SME
)
364 int id_start
= ID_START
;
367 signal (SIGILL
, handler
);
370 int signal_count
= 0;
371 for (int id
= id_start
; id
<= id_end
; id
++)
373 int state
= test_id_to_state (id
);
374 int vl
= test_id_to_vl (id
);
375 int svl
= test_id_to_svl (id
);
377 if (set_vl_size (vl
) == -1 || set_svl_size (svl
) == -1)
381 enable_states (state
);
382 dummy (); /* stop before SIGILL */
383 __asm
__volatile (".word 0xDEADBEEF"); /* illegal instruction */
384 while (signal_count
!= count
);
389 printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n");