sme: Add SVE/SME testcases
Add 5 SVE/SME tests to exercise all the new features like reading/writing registers, pseudo-registers, signal frames and core files. - Sanity check for SME: Gives a brief smoke test to make sure the most basic of features are working correctly. - ZA unavailability tests: Validates the behavior/content of the ZA register is correct when no payload is available. It also exercises changing the vector lengths. - ZA availability tests: These tests exercise reading/writing to all the possible ZA pseudo-registers, and validates the state is correct. - Core file tests: Validates that core file reading and writing works correctly and that all state dumped/loaded is sane. This is exercised for both Linux Kernel core files and gcore core files. - Signal frame tests: Validates the correct restoration of SME/SVE/FPSIMD values across signal frames. Since some of these tests are very lengthy and take a little while to run (under QEMU at the moment), I decided to parallelize them into smaller chunks so we can throw some more CPU power at them so they run faster. I'd still like to add a few more tests to give the testsuite more coverage in the areas of SME/SVE. Hopefully in the near future that will happen. Just a reminder that these SME tests are currently unsupported when gdb is connected to a remote target. That's because the RSP doesn't support communicating changes in vector lenghts mid-execution, so gdb will always get wrong state from the remote target. Co-Authored-By: Ezra Sitorus <ezra.sitorus@arm.com> Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
This commit is contained in:
parent
69bfb2b6d0
commit
16582a51c6
45 changed files with 3778 additions and 0 deletions
23
gdb/testsuite/gdb.arch/aarch64-sme-core-0.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-core-0.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: FPSIMD
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (0 ~ 24) out of 125 tests.
|
||||
set id_start 0
|
||||
set id_end 24
|
||||
source $srcdir/$subdir/aarch64-sme-core.exp.tcl
|
23
gdb/testsuite/gdb.arch/aarch64-sme-core-1.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-core-1.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: SVE
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (25 ~ 49) out of 125 tests.
|
||||
set id_start 25
|
||||
set id_end 49
|
||||
source $srcdir/$subdir/aarch64-sme-core.exp.tcl
|
23
gdb/testsuite/gdb.arch/aarch64-sme-core-2.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-core-2.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: SSVE
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (50 ~ 74) out of 125 tests.
|
||||
set id_start 50
|
||||
set id_end 74
|
||||
source $srcdir/$subdir/aarch64-sme-core.exp.tcl
|
23
gdb/testsuite/gdb.arch/aarch64-sme-core-3.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-core-3.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: ZA only
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (75 ~ 99) out of 125 tests.
|
||||
set id_start 75
|
||||
set id_end 99
|
||||
source $srcdir/$subdir/aarch64-sme-core.exp.tcl
|
23
gdb/testsuite/gdb.arch/aarch64-sme-core-4.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-core-4.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: ZA + SSVE
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (100 ~ 124) out of 125 tests.
|
||||
set id_start 100
|
||||
set id_end 124
|
||||
source $srcdir/$subdir/aarch64-sme-core.exp.tcl
|
372
gdb/testsuite/gdb.arch/aarch64-sme-core.c
Normal file
372
gdb/testsuite/gdb.arch/aarch64-sme-core.c
Normal file
|
@ -0,0 +1,372 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Exercise AArch64's Scalable Vector/Matrix Extension core file generation
|
||||
for GDB. This includes reading Linux Kernel-generated core files and
|
||||
writing GDB core files via the gcore command and making sure the contents
|
||||
are sane. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef HWCAP_SVE
|
||||
#define HWCAP_SVE (1 << 22)
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP2_SME
|
||||
#define HWCAP2_SME (1 << 23)
|
||||
#endif
|
||||
|
||||
#ifndef PR_SVE_SET_VL
|
||||
#define PR_SVE_SET_VL 50
|
||||
#define PR_SVE_GET_VL 51
|
||||
#define PR_SVE_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
#ifndef PR_SME_SET_VL
|
||||
#define PR_SME_SET_VL 63
|
||||
#define PR_SME_GET_VL 64
|
||||
#define PR_SME_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
static void
|
||||
enable_za ()
|
||||
{
|
||||
/* smstart za */
|
||||
__asm __volatile (".word 0xD503457F");
|
||||
}
|
||||
|
||||
static void
|
||||
disable_za ()
|
||||
{
|
||||
/* smstop za */
|
||||
__asm __volatile (".word 0xD503447F");
|
||||
}
|
||||
|
||||
static void
|
||||
enable_sm ()
|
||||
{
|
||||
/* smstart sm */
|
||||
__asm __volatile (".word 0xD503437F");
|
||||
}
|
||||
|
||||
static void
|
||||
disable_sm ()
|
||||
{
|
||||
/* smstop sm */
|
||||
__asm __volatile (".word 0xD503427F");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_fpsimd_state ()
|
||||
{
|
||||
char buffer[16];
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
buffer[i] = 0x55;
|
||||
|
||||
__asm __volatile ("mov x0, %0\n\t" \
|
||||
: : "r" (buffer));
|
||||
|
||||
__asm __volatile ("ldr q0, [x0]");
|
||||
__asm __volatile ("ldr q1, [x0]");
|
||||
__asm __volatile ("ldr q2, [x0]");
|
||||
__asm __volatile ("ldr q3, [x0]");
|
||||
__asm __volatile ("ldr q4, [x0]");
|
||||
__asm __volatile ("ldr q5, [x0]");
|
||||
__asm __volatile ("ldr q6, [x0]");
|
||||
__asm __volatile ("ldr q7, [x0]");
|
||||
__asm __volatile ("ldr q8, [x0]");
|
||||
__asm __volatile ("ldr q9, [x0]");
|
||||
__asm __volatile ("ldr q10, [x0]");
|
||||
__asm __volatile ("ldr q11, [x0]");
|
||||
__asm __volatile ("ldr q12, [x0]");
|
||||
__asm __volatile ("ldr q13, [x0]");
|
||||
__asm __volatile ("ldr q14, [x0]");
|
||||
__asm __volatile ("ldr q15, [x0]");
|
||||
__asm __volatile ("ldr q16, [x0]");
|
||||
__asm __volatile ("ldr q17, [x0]");
|
||||
__asm __volatile ("ldr q18, [x0]");
|
||||
__asm __volatile ("ldr q19, [x0]");
|
||||
__asm __volatile ("ldr q20, [x0]");
|
||||
__asm __volatile ("ldr q21, [x0]");
|
||||
__asm __volatile ("ldr q22, [x0]");
|
||||
__asm __volatile ("ldr q23, [x0]");
|
||||
__asm __volatile ("ldr q24, [x0]");
|
||||
__asm __volatile ("ldr q25, [x0]");
|
||||
__asm __volatile ("ldr q26, [x0]");
|
||||
__asm __volatile ("ldr q27, [x0]");
|
||||
__asm __volatile ("ldr q28, [x0]");
|
||||
__asm __volatile ("ldr q29, [x0]");
|
||||
__asm __volatile ("ldr q30, [x0]");
|
||||
__asm __volatile ("ldr q31, [x0]");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_za_state ()
|
||||
{
|
||||
/* zero za */
|
||||
__asm __volatile (".word 0xC00800FF");
|
||||
|
||||
char buffer[256];
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
buffer[i] = 0xaa;
|
||||
|
||||
__asm __volatile ("mov x0, %0\n\t" \
|
||||
: : "r" (buffer));
|
||||
|
||||
/* Initialize loop boundaries. */
|
||||
__asm __volatile ("mov w12, 0");
|
||||
__asm __volatile ("mov w17, 256");
|
||||
|
||||
/* loop: ldr za[w12, 0], [x0] */
|
||||
__asm __volatile ("loop: .word 0xe1000000");
|
||||
__asm __volatile ("add w12, w12, 1");
|
||||
__asm __volatile ("cmp w12, w17");
|
||||
__asm __volatile ("bne loop");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_tpidr2 ()
|
||||
{
|
||||
__asm __volatile ("mov x0, #0xffffffffffffffff");
|
||||
|
||||
/* Write x0 to tpidr2. */
|
||||
__asm __volatile (".word 0xd51bd0a0");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_sve_state ()
|
||||
{
|
||||
__asm __volatile ("dup z0.b, -1");
|
||||
__asm __volatile ("dup z1.b, -1");
|
||||
__asm __volatile ("dup z2.b, -1");
|
||||
__asm __volatile ("dup z3.b, -1");
|
||||
__asm __volatile ("dup z4.b, -1");
|
||||
__asm __volatile ("dup z5.b, -1");
|
||||
__asm __volatile ("dup z6.b, -1");
|
||||
__asm __volatile ("dup z7.b, -1");
|
||||
__asm __volatile ("dup z8.b, -1");
|
||||
__asm __volatile ("dup z9.b, -1");
|
||||
__asm __volatile ("dup z10.b, -1");
|
||||
__asm __volatile ("dup z11.b, -1");
|
||||
__asm __volatile ("dup z12.b, -1");
|
||||
__asm __volatile ("dup z13.b, -1");
|
||||
__asm __volatile ("dup z14.b, -1");
|
||||
__asm __volatile ("dup z15.b, -1");
|
||||
__asm __volatile ("dup z16.b, -1");
|
||||
__asm __volatile ("dup z17.b, -1");
|
||||
__asm __volatile ("dup z18.b, -1");
|
||||
__asm __volatile ("dup z19.b, -1");
|
||||
__asm __volatile ("dup z20.b, -1");
|
||||
__asm __volatile ("dup z21.b, -1");
|
||||
__asm __volatile ("dup z22.b, -1");
|
||||
__asm __volatile ("dup z23.b, -1");
|
||||
__asm __volatile ("dup z24.b, -1");
|
||||
__asm __volatile ("dup z25.b, -1");
|
||||
__asm __volatile ("dup z26.b, -1");
|
||||
__asm __volatile ("dup z27.b, -1");
|
||||
__asm __volatile ("dup z28.b, -1");
|
||||
__asm __volatile ("dup z29.b, -1");
|
||||
__asm __volatile ("dup z30.b, -1");
|
||||
__asm __volatile ("dup z31.b, -1");
|
||||
__asm __volatile ("ptrue p0.b");
|
||||
__asm __volatile ("ptrue p1.b");
|
||||
__asm __volatile ("ptrue p2.b");
|
||||
__asm __volatile ("ptrue p3.b");
|
||||
__asm __volatile ("ptrue p4.b");
|
||||
__asm __volatile ("ptrue p5.b");
|
||||
__asm __volatile ("ptrue p6.b");
|
||||
__asm __volatile ("ptrue p7.b");
|
||||
__asm __volatile ("ptrue p8.b");
|
||||
__asm __volatile ("ptrue p9.b");
|
||||
__asm __volatile ("ptrue p10.b");
|
||||
__asm __volatile ("ptrue p11.b");
|
||||
__asm __volatile ("ptrue p12.b");
|
||||
__asm __volatile ("ptrue p13.b");
|
||||
__asm __volatile ("ptrue p14.b");
|
||||
__asm __volatile ("ptrue p15.b");
|
||||
__asm __volatile ("setffr");
|
||||
}
|
||||
|
||||
static int get_vl_size ()
|
||||
{
|
||||
int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SVE_GET_VL (%d)", res);
|
||||
return -1;
|
||||
}
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int get_svl_size ()
|
||||
{
|
||||
int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SME_GET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int set_vl_size (int new_vl)
|
||||
{
|
||||
int res = prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SVE_SET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = get_vl_size ();
|
||||
if (res != new_vl)
|
||||
{
|
||||
printf ("Unexpected VL value (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int set_svl_size (int new_svl)
|
||||
{
|
||||
int res = prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SME_SET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = get_svl_size ();
|
||||
if (res != new_svl)
|
||||
{
|
||||
printf ("Unexpected SVL value (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Enable register states based on STATE.
|
||||
|
||||
0 - FPSIMD
|
||||
1 - SVE
|
||||
2 - SSVE
|
||||
3 - ZA
|
||||
4 - ZA and SSVE. */
|
||||
|
||||
void enable_states (int state)
|
||||
{
|
||||
disable_za ();
|
||||
disable_sm ();
|
||||
initialize_fpsimd_state ();
|
||||
|
||||
if (state == 1)
|
||||
{
|
||||
initialize_sve_state ();
|
||||
}
|
||||
else if (state == 2)
|
||||
{
|
||||
enable_sm ();
|
||||
initialize_sve_state ();
|
||||
}
|
||||
else if (state == 3)
|
||||
{
|
||||
enable_za ();
|
||||
initialize_za_state ();
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
enable_za ();
|
||||
enable_sm ();
|
||||
initialize_sve_state ();
|
||||
initialize_za_state ();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_state (int id)
|
||||
{
|
||||
return id / 25;
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_vl (int id)
|
||||
{
|
||||
return 16 << ((id / 5) % 5);
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_svl (int id)
|
||||
{
|
||||
return 16 << (id % 5);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (argc > 2)
|
||||
printf ("Incorrect number of arguments passed to test.\n");
|
||||
|
||||
if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME)
|
||||
{
|
||||
long test_id = 0;
|
||||
|
||||
/* If we have a test id passed as argument, read it now. */
|
||||
if (argc == 2)
|
||||
test_id = strtol (argv[1], NULL, 0);
|
||||
|
||||
dummy (); /* stop to initialize test_id */
|
||||
|
||||
int state = test_id_to_state (test_id);
|
||||
int vl = test_id_to_vl (test_id);
|
||||
int svl = test_id_to_svl (test_id);
|
||||
|
||||
if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1)
|
||||
return -1;
|
||||
|
||||
enable_states (state);
|
||||
|
||||
/* Also set the TPIDR2 register so we can test dumping its contents
|
||||
to a core file. */
|
||||
initialize_tpidr2 ();
|
||||
|
||||
char *p = 0x0;
|
||||
*p = 0xff; /* crash point */
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
184
gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl
Normal file
184
gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl
Normal file
|
@ -0,0 +1,184 @@
|
|||
# Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Exercise core file reading/writing in the presence of SME support.
|
||||
# This test exercises GDB's dumping/loading capability for Linux
|
||||
# Kernel core files and for gcore core files.
|
||||
|
||||
load_lib aarch64-scalable.exp
|
||||
|
||||
#
|
||||
# Validate that CORE_FILENAME can be read correctly and that the register
|
||||
# state is sane.
|
||||
#
|
||||
proc check_sme_core_file { core_filename state vl svl } {
|
||||
# Load the core file.
|
||||
if [gdb_test "core $core_filename" \
|
||||
[multi_line \
|
||||
"Core was generated by.*\." \
|
||||
"Program terminated with signal SIGSEGV, Segmentation fault\." \
|
||||
"#0 ${::hex} in main \\(.*\\) at .*" \
|
||||
".*p = 0xff;.* crash point .*"] \
|
||||
"load core file"] {
|
||||
untested "failed to generate core file"
|
||||
return -1
|
||||
}
|
||||
|
||||
check_state $state $vl $svl
|
||||
|
||||
# Check the value of TPIDR2 in the core file.
|
||||
gdb_test "print/x \$tpidr2" " = 0xffffffffffffffff" \
|
||||
"tpidr2 contents from core file"
|
||||
}
|
||||
|
||||
#
|
||||
# Generate two core files for EXECUTABLE, BINFILE with a test id of ID.
|
||||
# STATE is the register state, VL is the SVE vector length and SVL is the
|
||||
# SME vector length.
|
||||
# One of the core files is generated by the kernel and the other by the
|
||||
# gcore command.
|
||||
#
|
||||
proc generate_sme_core_files { executable binfile id state vl svl} {
|
||||
# Run the program until the point where we need to adjust the
|
||||
# test id.
|
||||
set init_breakpoint "stop to initialize test_id"
|
||||
gdb_breakpoint [gdb_get_line_number $init_breakpoint]
|
||||
gdb_continue_to_breakpoint $init_breakpoint
|
||||
gdb_test_no_output "set test_id = $id"
|
||||
|
||||
# Run the program until just before the crash.
|
||||
set crash_breakpoint "crash point"
|
||||
gdb_breakpoint [gdb_get_line_number $crash_breakpoint]
|
||||
gdb_continue_to_breakpoint $crash_breakpoint
|
||||
gdb_test_no_output "set print repeats 1" "adjust repeat count pre-crash"
|
||||
|
||||
# Adjust the register to custom values that we will check later when
|
||||
# loading the core files.
|
||||
check_state $state $vl $svl
|
||||
|
||||
# Continue until a crash.
|
||||
gdb_test "continue" \
|
||||
[multi_line \
|
||||
"Program received signal SIGSEGV, Segmentation fault\." \
|
||||
"${::hex} in main \\(.*\\) at .*" \
|
||||
".*p = 0xff;.* crash point .*"] \
|
||||
"run to crash"
|
||||
|
||||
# Generate the gcore core file.
|
||||
set gcore_filename [standard_output_file "${executable}-${id}-${state}-${vl}-${svl}.gcore"]
|
||||
set gcore_generated [gdb_gcore_cmd "$gcore_filename" "generate gcore file"]
|
||||
|
||||
# Generate a native core file.
|
||||
set core_filename [core_find ${binfile} {} $id]
|
||||
set core_generated [expr {$core_filename != ""}]
|
||||
set native_core_name "${binfile}-${id}-${state}-${vl}-${svl}.core"
|
||||
remote_exec build "mv $core_filename ${native_core_name}"
|
||||
set core_filename ${native_core_name}
|
||||
|
||||
# At this point we have a couple core files, the gcore one generated by GDB
|
||||
# and the native one generated by the Linux Kernel. Make sure GDB can read
|
||||
# both correctly.
|
||||
if {$gcore_generated} {
|
||||
clean_restart ${binfile}
|
||||
gdb_test_no_output "set print repeats 1" \
|
||||
"adjust repeat count post-crash gcore"
|
||||
|
||||
with_test_prefix "gcore corefile" {
|
||||
check_sme_core_file $gcore_filename $state $vl $svl
|
||||
}
|
||||
} else {
|
||||
fail "gcore corefile not generated"
|
||||
}
|
||||
|
||||
if {$core_generated} {
|
||||
clean_restart ${binfile}
|
||||
|
||||
gdb_test_no_output "set print repeats 1" \
|
||||
"adjust repeat count post-crash native core"
|
||||
|
||||
with_test_prefix "native corefile" {
|
||||
check_sme_core_file $core_filename $state $vl $svl
|
||||
}
|
||||
} else {
|
||||
untested "native corefile not generated"
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Exercise core file reading (kernel-generated core files) and writing
|
||||
# (gcore command) for test id's ID_START through ID_END.
|
||||
#
|
||||
proc test_sme_core_file { id_start id_end } {
|
||||
set compile_flags {"debug" "macros" "additional_flags=-march=armv8.5-a+sve"}
|
||||
standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-core.c
|
||||
set executable "${::testfile}"
|
||||
if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} {
|
||||
return -1
|
||||
}
|
||||
set binfile [standard_output_file ${executable}]
|
||||
|
||||
for {set id $id_start} {$id <= $id_end} {incr id} {
|
||||
set state [test_id_to_state $id]
|
||||
set vl [test_id_to_vl $id]
|
||||
set svl [test_id_to_svl $id]
|
||||
|
||||
set skip_unsupported 0
|
||||
if {![aarch64_supports_sve_vl $vl]
|
||||
|| ![aarch64_supports_sme_svl $svl]} {
|
||||
# We have a vector length or streaming vector length that
|
||||
# is not supported by this target. Skip to the next iteration
|
||||
# since it is no use running tests for an unsupported vector
|
||||
# length.
|
||||
if {![aarch64_supports_sve_vl $vl]} {
|
||||
verbose -log "SVE vector length $vl not supported."
|
||||
} elseif {![aarch64_supports_sme_svl $svl]} {
|
||||
verbose -log "SME streaming vector length $svl not supported."
|
||||
}
|
||||
verbose -log "Skipping test."
|
||||
set skip_unsupported 1
|
||||
}
|
||||
|
||||
with_test_prefix "state=${state} vl=${vl} svl=${svl}" {
|
||||
# If the SVE or SME vector length is not supported, just skip
|
||||
# these next tests.
|
||||
if {$skip_unsupported} {
|
||||
untested "unsupported configuration on target"
|
||||
continue
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
untested "could not run to main"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Check if we are talking to a remote target. If so, bail out,
|
||||
# as right now remote targets can't communicate vector length (vl
|
||||
# or svl) changes to gdb via the RSP. When this restriction is
|
||||
# lifted, we can remove this guard.
|
||||
if {[gdb_is_target_remote]} {
|
||||
unsupported "aarch64 sve/sme tests not supported for remote targets"
|
||||
return -1
|
||||
}
|
||||
|
||||
generate_sme_core_files ${executable} ${binfile} $id $state $vl $svl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require is_aarch64_target
|
||||
require allow_aarch64_sve_tests
|
||||
require allow_aarch64_sme_tests
|
||||
|
||||
test_sme_core_file $id_start $id_end
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-0.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-0.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 16
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (0 ~ 3) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 0
|
||||
set id_end 3
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-1.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-1.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 16
|
||||
# SVL: 256
|
||||
# This set covers 1 (4) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 4
|
||||
set id_end 4
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-2.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-2.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 32
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (5 ~ 8) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 5
|
||||
set id_end 8
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-3.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-3.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 32
|
||||
# SVL: 256
|
||||
# This set covers 1 (9) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 9
|
||||
set id_end 9
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-4.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-4.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 64
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (10 ~ 13) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 10
|
||||
set id_end 13
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-5.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-5.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 64
|
||||
# SVL: 256
|
||||
# This set covers 1 (14) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 14
|
||||
set id_end 14
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-6.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-6.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 128
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (15 ~ 18) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 15
|
||||
set id_end 18
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-7.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-7.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 128
|
||||
# SVL: 256
|
||||
# This set covers 1 (19) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 19
|
||||
set id_end 19
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-8.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-8.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 256
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (20 ~ 23) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 20
|
||||
set id_end 23
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-9.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-available-9.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 256
|
||||
# SVL: 256
|
||||
# This set covers 1 (24) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 24
|
||||
set id_end 24
|
||||
source $srcdir/$subdir/aarch64-sme-regs-available.exp.tcl
|
178
gdb/testsuite/gdb.arch/aarch64-sme-regs-available.c
Normal file
178
gdb/testsuite/gdb.arch/aarch64-sme-regs-available.c
Normal file
|
@ -0,0 +1,178 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Exercise various cases of reading/writing ZA contents for AArch64's
|
||||
Scalable Matrix Extension. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef HWCAP_SVE
|
||||
#define HWCAP_SVE (1 << 22)
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP2_SME
|
||||
#define HWCAP2_SME (1 << 23)
|
||||
#endif
|
||||
|
||||
#ifndef PR_SVE_SET_VL
|
||||
#define PR_SVE_SET_VL 50
|
||||
#define PR_SVE_GET_VL 51
|
||||
#define PR_SVE_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
#ifndef PR_SME_SET_VL
|
||||
#define PR_SME_SET_VL 63
|
||||
#define PR_SME_GET_VL 64
|
||||
#define PR_SME_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
static void
|
||||
enable_za ()
|
||||
{
|
||||
/* smstart za */
|
||||
__asm __volatile (".word 0xD503457F");
|
||||
}
|
||||
|
||||
static void
|
||||
disable_za ()
|
||||
{
|
||||
/* smstop za */
|
||||
__asm __volatile (".word 0xD503447F");
|
||||
}
|
||||
|
||||
static int get_vl_size ()
|
||||
{
|
||||
int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SVE_GET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int get_svl_size ()
|
||||
{
|
||||
int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SME_GET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int set_vl_size (int new_vl)
|
||||
{
|
||||
int res = prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SVE_SET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = get_vl_size ();
|
||||
if (res != new_vl)
|
||||
{
|
||||
printf ("Unexpected VL value (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int set_svl_size (int new_svl)
|
||||
{
|
||||
int res = prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SME_SET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = get_svl_size ();
|
||||
if (res != new_svl)
|
||||
{
|
||||
printf ("Unexpected SVL value (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_vl (int id)
|
||||
{
|
||||
return 16 << ((id / 5) % 5);
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_svl (int id)
|
||||
{
|
||||
return 16 << (id % 5);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME)
|
||||
{
|
||||
int id_start = ID_START;
|
||||
int id_end = ID_END;
|
||||
|
||||
for (int id = id_start; id <= id_end; id++)
|
||||
{
|
||||
int vl = test_id_to_vl (id);
|
||||
int svl = test_id_to_svl (id);
|
||||
|
||||
if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1)
|
||||
continue;
|
||||
|
||||
enable_za ();
|
||||
dummy (); /* stop 1 */
|
||||
}
|
||||
|
||||
for (int id = id_start; id <= id_end; id++)
|
||||
{
|
||||
int vl = test_id_to_vl (id);
|
||||
int svl = test_id_to_svl (id);
|
||||
|
||||
if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1)
|
||||
continue;
|
||||
|
||||
disable_za ();
|
||||
dummy (); /* stop 2 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
245
gdb/testsuite/gdb.arch/aarch64-sme-regs-available.exp.tcl
Normal file
245
gdb/testsuite/gdb.arch/aarch64-sme-regs-available.exp.tcl
Normal file
|
@ -0,0 +1,245 @@
|
|||
# Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Exercise reading/writing ZA registers when there is ZA state.
|
||||
|
||||
load_lib aarch64-scalable.exp
|
||||
|
||||
#
|
||||
# Cycle through all ZA registers and pseudo-registers and validate that their
|
||||
# contents are available for vector length SVL.
|
||||
#
|
||||
# Make sure reading/writing to ZA registers work as expected.
|
||||
#
|
||||
proc check_regs { mode vl svl } {
|
||||
# Check VG to make sure it is correct
|
||||
set expected_vg [expr $vl / 8]
|
||||
gdb_test "print \$vg" "= ${expected_vg}"
|
||||
|
||||
# Check SVG to make sure it is correct
|
||||
set expected_svg [expr $svl / 8]
|
||||
gdb_test "print \$svg" "= ${expected_svg}"
|
||||
|
||||
# If svl is adjusted by prctl, we will have ZA enabled. If gdb is
|
||||
# adjusting svl, ZA will not be enabled by default. It will only be
|
||||
# enabled when ZA is written to.
|
||||
set za_state "= \\\[ ZA \\\]"
|
||||
if {$mode == "gdb"} {
|
||||
set za_state "= \\\[ \\\]"
|
||||
}
|
||||
|
||||
# Check SVCR.
|
||||
if [gdb_test "print \$svcr" $za_state "svcr before assignments" ] {
|
||||
fail "incorrect za state"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Check the size of ZA.
|
||||
set expected_za_size [expr $svl * $svl]
|
||||
gdb_test "print sizeof \$za" " = $expected_za_size"
|
||||
|
||||
# Check the size of Z0.
|
||||
gdb_test "print sizeof \$z0" " = $vl"
|
||||
|
||||
# Exercise reading/writing from/to ZA.
|
||||
initialize_2d_array "\$za" 255 $svl $svl
|
||||
set pattern [string_to_regexp [2d_array_value_pattern 255 $svl $svl]]
|
||||
gdb_test "print \$za" " = $pattern" "read back from za"
|
||||
|
||||
# Exercise reading/writing from/to the tile pseudo-registers.
|
||||
set last_tile 1
|
||||
set expected_size [expr $svl * $svl]
|
||||
set tile_svl $svl
|
||||
set za_state "= \\\[ ZA \\\]"
|
||||
foreach_with_prefix granularity {"b" "h" "s" "d" "q"} {
|
||||
for {set tile 0} {$tile < $last_tile} {incr tile} {
|
||||
set register_name "\$za${tile}${granularity}"
|
||||
|
||||
# Test the size.
|
||||
gdb_test "print sizeof ${register_name}" " = ${expected_size}"
|
||||
|
||||
# Test reading/writing
|
||||
initialize_2d_array $register_name 255 $tile_svl $tile_svl
|
||||
|
||||
# Make sure we have ZA state.
|
||||
if [gdb_test "print \$svcr" $za_state "svcr after assignment to ${register_name}" ] {
|
||||
fail "incorrect za state"
|
||||
return -1
|
||||
}
|
||||
|
||||
set pattern [string_to_regexp [2d_array_value_pattern 255 $tile_svl $tile_svl]]
|
||||
gdb_test "print $register_name" " = $pattern" "read back from $register_name"
|
||||
}
|
||||
set last_tile [expr $last_tile * 2]
|
||||
set expected_size [expr $expected_size / 2]
|
||||
set tile_svl [expr $tile_svl / 2]
|
||||
}
|
||||
|
||||
# Exercise reading/writing from/to the tile slice pseudo-registers.
|
||||
set last_tile 1
|
||||
set last_slice $svl
|
||||
set expected_size $svl
|
||||
set num_elements $svl
|
||||
foreach_with_prefix granularity {"b" "h" "s" "d" "q"} {
|
||||
for {set tile 0} {$tile < $last_tile} {incr tile} {
|
||||
for {set slice 0} {$slice < $last_slice} {incr slice} {
|
||||
foreach_with_prefix direction {"h" "v"} {
|
||||
set register_name "\$za${tile}${direction}${granularity}${slice}"
|
||||
|
||||
# Test the size.
|
||||
gdb_test "print sizeof ${register_name}" " = ${expected_size}"
|
||||
|
||||
# Test reading/writing
|
||||
initialize_1d_array $register_name 255 $num_elements
|
||||
|
||||
# Make sure we have ZA state.
|
||||
if [gdb_test "print \$svcr" $za_state "svcr after assignment of ${register_name}" ] {
|
||||
fail "incorrect za state"
|
||||
return -1
|
||||
}
|
||||
|
||||
set pattern [string_to_regexp [1d_array_value_pattern 255 $num_elements]]
|
||||
gdb_test "print $register_name" " = $pattern" "read back from $register_name"
|
||||
}
|
||||
}
|
||||
}
|
||||
set last_tile [expr $last_tile * 2]
|
||||
set last_slice [expr ($last_slice / 2)]
|
||||
set num_elements [expr $num_elements / 2]
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Cycle through all ZA registers and pseudo-registers and validate their
|
||||
# contents.
|
||||
#
|
||||
proc test_sme_registers_available { id_start id_end } {
|
||||
|
||||
set compile_flags {"debug" "macros"}
|
||||
lappend compile_flags "additional_flags=-DID_START=${id_start}"
|
||||
lappend compile_flags "additional_flags=-DID_END=${id_end}"
|
||||
|
||||
standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-regs-available.c
|
||||
set executable "${::testfile}-${id_start}-${id_end}"
|
||||
if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} {
|
||||
return -1
|
||||
}
|
||||
set binfile [standard_output_file ${executable}]
|
||||
|
||||
if ![runto_main] {
|
||||
untested "could not run to main"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Check if we are talking to a remote target. If so, bail out, as right now
|
||||
# remote targets can't communicate vector length (vl or svl) changes to gdb
|
||||
# via the RSP. When this restriction is lifted, we can remove this guard.
|
||||
if {[gdb_is_target_remote]} {
|
||||
unsupported "aarch64 sve/sme tests not supported for remote targets"
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_test_no_output "set print repeats 1"
|
||||
|
||||
set prctl_breakpoint "stop 1"
|
||||
gdb_breakpoint [gdb_get_line_number $prctl_breakpoint]
|
||||
|
||||
for {set id $id_start} {$id <= $id_end} {incr id} {
|
||||
set vl [test_id_to_vl $id]
|
||||
set svl [test_id_to_svl $id]
|
||||
|
||||
set skip_unsupported 0
|
||||
if {![aarch64_supports_sve_vl $vl]
|
||||
|| ![aarch64_supports_sme_svl $svl]} {
|
||||
# We have a vector length or streaming vector length that
|
||||
# is not supported by this target. Skip to the next iteration
|
||||
# since it is no use running tests for an unsupported vector
|
||||
# length.
|
||||
if {![aarch64_supports_sve_vl $vl]} {
|
||||
verbose -log "SVE vector length $vl not supported."
|
||||
} elseif {![aarch64_supports_sme_svl $svl]} {
|
||||
verbose -log "SME streaming vector length $svl not supported."
|
||||
}
|
||||
verbose -log "Skipping test."
|
||||
set skip_unsupported 1
|
||||
}
|
||||
|
||||
set mode "prctl"
|
||||
with_test_prefix "$mode, vl=${vl} svl=${svl}" {
|
||||
# If the SVE or SME vector length is not supported, just skip
|
||||
# these next tests.
|
||||
if {$skip_unsupported} {
|
||||
untested "unsupported configuration on target"
|
||||
continue
|
||||
}
|
||||
|
||||
# Run the program until it has adjusted svl.
|
||||
gdb_continue_to_breakpoint $prctl_breakpoint
|
||||
check_regs $mode $vl $svl
|
||||
}
|
||||
}
|
||||
|
||||
set non_prctl_breakpoint "stop 2"
|
||||
gdb_breakpoint [gdb_get_line_number $non_prctl_breakpoint]
|
||||
|
||||
for {set id $id_start} {$id <= $id_end} {incr id} {
|
||||
set vl [test_id_to_vl $id]
|
||||
set svl [test_id_to_svl $id]
|
||||
|
||||
set skip_unsupported 0
|
||||
if {![aarch64_supports_sve_vl $vl]
|
||||
|| ![aarch64_supports_sme_svl $svl]} {
|
||||
# We have a vector length or streaming vector length that
|
||||
# is not supported by this target. Skip to the next iteration
|
||||
# since it is no use running tests for an unsupported vector
|
||||
# length.
|
||||
if {![aarch64_supports_sve_vl $vl]} {
|
||||
verbose -log "SVE vector length $vl not supported."
|
||||
} elseif {![aarch64_supports_sme_svl $svl]} {
|
||||
verbose -log "SME streaming vector length $svl not supported."
|
||||
}
|
||||
verbose -log "Skipping test."
|
||||
set skip_unsupported 1
|
||||
}
|
||||
|
||||
set mode "gdb"
|
||||
with_test_prefix "$mode, vl=${vl} svl=${svl}" {
|
||||
# If the SVE or SME vector length is not supported, just skip
|
||||
# these next tests.
|
||||
if {$skip_unsupported} {
|
||||
untested "unsupported configuration on target"
|
||||
continue
|
||||
}
|
||||
|
||||
# Run the program until we stop at the point where gdb should
|
||||
# adjust the SVE and SME vector lengths.
|
||||
gdb_continue_to_breakpoint $non_prctl_breakpoint
|
||||
|
||||
# Adjust svl via gdb.
|
||||
set vg_value [expr $vl / 8]
|
||||
set svg_value [expr $svl / 8]
|
||||
gdb_test_no_output "set \$vg = ${vg_value}"
|
||||
gdb_test_no_output "set \$svg = ${svg_value}"
|
||||
|
||||
check_regs $mode $vl $svl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require is_aarch64_target
|
||||
require allow_aarch64_sve_tests
|
||||
require allow_aarch64_sme_tests
|
||||
|
||||
test_sme_registers_available $id_start $id_end
|
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-0.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-0.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: FPSIMD
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (0 ~ 24) out of 125 tests.
|
||||
set id_start 0
|
||||
set id_end 24
|
||||
source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl
|
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-1.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-1.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: SVE
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (25 ~ 49) out of 125 tests.
|
||||
set id_start 25
|
||||
set id_end 49
|
||||
source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl
|
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-2.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-2.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: SSVE
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (50 ~ 74) out of 125 tests.
|
||||
set id_start 50
|
||||
set id_end 74
|
||||
source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl
|
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-3.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-3.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: ZA only
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (75 ~ 99) out of 125 tests.
|
||||
set id_start 75
|
||||
set id_end 99
|
||||
source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl
|
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-4.exp
Normal file
23
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe-4.exp
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# state: ZA + SSVE
|
||||
# VL: 16, 32, 64, 128, 256
|
||||
# SVL: 16, 32, 64, 128, 256
|
||||
# This set covers 25 (100 ~ 124) out of 125 tests.
|
||||
set id_start 100
|
||||
set id_end 124
|
||||
source $srcdir/$subdir/aarch64-sme-regs-sigframe.exp.tcl
|
366
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.c
Normal file
366
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.c
Normal file
|
@ -0,0 +1,366 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Exercise AArch64's Scalable Vector/Matrix Extension signal frame handling
|
||||
for GDB. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef HWCAP_SVE
|
||||
#define HWCAP_SVE (1 << 22)
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP2_SME
|
||||
#define HWCAP2_SME (1 << 23)
|
||||
#endif
|
||||
|
||||
#ifndef PR_SVE_SET_VL
|
||||
#define PR_SVE_SET_VL 50
|
||||
#define PR_SVE_GET_VL 51
|
||||
#define PR_SVE_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
#ifndef PR_SME_SET_VL
|
||||
#define PR_SME_SET_VL 63
|
||||
#define PR_SME_GET_VL 64
|
||||
#define PR_SME_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
static int count = 0;
|
||||
|
||||
static void
|
||||
handler (int sig)
|
||||
{
|
||||
count++; /* handler */
|
||||
}
|
||||
|
||||
static void
|
||||
enable_za ()
|
||||
{
|
||||
/* smstart za */
|
||||
__asm __volatile (".word 0xD503457F");
|
||||
}
|
||||
|
||||
static void
|
||||
disable_za ()
|
||||
{
|
||||
/* smstop za */
|
||||
__asm __volatile (".word 0xD503447F");
|
||||
}
|
||||
|
||||
static void
|
||||
enable_sm ()
|
||||
{
|
||||
/* smstart sm */
|
||||
__asm __volatile (".word 0xD503437F");
|
||||
}
|
||||
|
||||
static void
|
||||
disable_sm ()
|
||||
{
|
||||
/* smstop sm */
|
||||
__asm __volatile (".word 0xD503427F");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_fpsimd_state ()
|
||||
{
|
||||
char buffer[16];
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
buffer[i] = 0x55;
|
||||
|
||||
__asm __volatile ("mov x0, %0\n\t" \
|
||||
: : "r" (buffer));
|
||||
|
||||
__asm __volatile ("ldr q0, [x0]");
|
||||
__asm __volatile ("ldr q1, [x0]");
|
||||
__asm __volatile ("ldr q2, [x0]");
|
||||
__asm __volatile ("ldr q3, [x0]");
|
||||
__asm __volatile ("ldr q4, [x0]");
|
||||
__asm __volatile ("ldr q5, [x0]");
|
||||
__asm __volatile ("ldr q6, [x0]");
|
||||
__asm __volatile ("ldr q7, [x0]");
|
||||
__asm __volatile ("ldr q8, [x0]");
|
||||
__asm __volatile ("ldr q9, [x0]");
|
||||
__asm __volatile ("ldr q10, [x0]");
|
||||
__asm __volatile ("ldr q11, [x0]");
|
||||
__asm __volatile ("ldr q12, [x0]");
|
||||
__asm __volatile ("ldr q13, [x0]");
|
||||
__asm __volatile ("ldr q14, [x0]");
|
||||
__asm __volatile ("ldr q15, [x0]");
|
||||
__asm __volatile ("ldr q16, [x0]");
|
||||
__asm __volatile ("ldr q17, [x0]");
|
||||
__asm __volatile ("ldr q18, [x0]");
|
||||
__asm __volatile ("ldr q19, [x0]");
|
||||
__asm __volatile ("ldr q20, [x0]");
|
||||
__asm __volatile ("ldr q21, [x0]");
|
||||
__asm __volatile ("ldr q22, [x0]");
|
||||
__asm __volatile ("ldr q23, [x0]");
|
||||
__asm __volatile ("ldr q24, [x0]");
|
||||
__asm __volatile ("ldr q25, [x0]");
|
||||
__asm __volatile ("ldr q26, [x0]");
|
||||
__asm __volatile ("ldr q27, [x0]");
|
||||
__asm __volatile ("ldr q28, [x0]");
|
||||
__asm __volatile ("ldr q29, [x0]");
|
||||
__asm __volatile ("ldr q30, [x0]");
|
||||
__asm __volatile ("ldr q31, [x0]");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_za_state ()
|
||||
{
|
||||
/* zero za */
|
||||
__asm __volatile (".word 0xC00800FF");
|
||||
|
||||
char buffer[256];
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
buffer[i] = 0xaa;
|
||||
|
||||
__asm __volatile ("mov x0, %0\n\t" \
|
||||
: : "r" (buffer));
|
||||
|
||||
/* Initialize loop boundaries. */
|
||||
__asm __volatile ("mov w12, 0");
|
||||
__asm __volatile ("mov w17, 256");
|
||||
|
||||
/* loop: ldr za[w12, 0], [x0] */
|
||||
__asm __volatile ("loop: .word 0xe1000000");
|
||||
__asm __volatile ("add w12, w12, 1");
|
||||
__asm __volatile ("cmp w12, w17");
|
||||
__asm __volatile ("bne loop");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_sve_state ()
|
||||
{
|
||||
__asm __volatile ("dup z0.b, -1");
|
||||
__asm __volatile ("dup z1.b, -1");
|
||||
__asm __volatile ("dup z2.b, -1");
|
||||
__asm __volatile ("dup z3.b, -1");
|
||||
__asm __volatile ("dup z4.b, -1");
|
||||
__asm __volatile ("dup z5.b, -1");
|
||||
__asm __volatile ("dup z6.b, -1");
|
||||
__asm __volatile ("dup z7.b, -1");
|
||||
__asm __volatile ("dup z8.b, -1");
|
||||
__asm __volatile ("dup z9.b, -1");
|
||||
__asm __volatile ("dup z10.b, -1");
|
||||
__asm __volatile ("dup z11.b, -1");
|
||||
__asm __volatile ("dup z12.b, -1");
|
||||
__asm __volatile ("dup z13.b, -1");
|
||||
__asm __volatile ("dup z14.b, -1");
|
||||
__asm __volatile ("dup z15.b, -1");
|
||||
__asm __volatile ("dup z16.b, -1");
|
||||
__asm __volatile ("dup z17.b, -1");
|
||||
__asm __volatile ("dup z18.b, -1");
|
||||
__asm __volatile ("dup z19.b, -1");
|
||||
__asm __volatile ("dup z20.b, -1");
|
||||
__asm __volatile ("dup z21.b, -1");
|
||||
__asm __volatile ("dup z22.b, -1");
|
||||
__asm __volatile ("dup z23.b, -1");
|
||||
__asm __volatile ("dup z24.b, -1");
|
||||
__asm __volatile ("dup z25.b, -1");
|
||||
__asm __volatile ("dup z26.b, -1");
|
||||
__asm __volatile ("dup z27.b, -1");
|
||||
__asm __volatile ("dup z28.b, -1");
|
||||
__asm __volatile ("dup z29.b, -1");
|
||||
__asm __volatile ("dup z30.b, -1");
|
||||
__asm __volatile ("dup z31.b, -1");
|
||||
__asm __volatile ("ptrue p0.b");
|
||||
__asm __volatile ("ptrue p1.b");
|
||||
__asm __volatile ("ptrue p2.b");
|
||||
__asm __volatile ("ptrue p3.b");
|
||||
__asm __volatile ("ptrue p4.b");
|
||||
__asm __volatile ("ptrue p5.b");
|
||||
__asm __volatile ("ptrue p6.b");
|
||||
__asm __volatile ("ptrue p7.b");
|
||||
__asm __volatile ("ptrue p8.b");
|
||||
__asm __volatile ("ptrue p9.b");
|
||||
__asm __volatile ("ptrue p10.b");
|
||||
__asm __volatile ("ptrue p11.b");
|
||||
__asm __volatile ("ptrue p12.b");
|
||||
__asm __volatile ("ptrue p13.b");
|
||||
__asm __volatile ("ptrue p14.b");
|
||||
__asm __volatile ("ptrue p15.b");
|
||||
__asm __volatile ("setffr");
|
||||
}
|
||||
|
||||
static int get_vl_size ()
|
||||
{
|
||||
int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SVE_GET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int get_svl_size ()
|
||||
{
|
||||
int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SME_GET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int set_vl_size (int new_vl)
|
||||
{
|
||||
int res = prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SVE_SET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = get_vl_size ();
|
||||
if (res != new_vl)
|
||||
{
|
||||
printf ("Unexpected VL value (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int set_svl_size (int new_svl)
|
||||
{
|
||||
int res = prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SME_SET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = get_svl_size ();
|
||||
if (res != new_svl)
|
||||
{
|
||||
printf ("Unexpected SVL value (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Enable register states based on STATE.
|
||||
|
||||
0 - FPSIMD
|
||||
1 - SVE
|
||||
2 - SSVE
|
||||
3 - ZA
|
||||
4 - ZA and SSVE. */
|
||||
|
||||
void enable_states (int state)
|
||||
{
|
||||
disable_za ();
|
||||
disable_sm ();
|
||||
initialize_fpsimd_state ();
|
||||
|
||||
if (state == 1)
|
||||
{
|
||||
initialize_sve_state ();
|
||||
}
|
||||
else if (state == 2)
|
||||
{
|
||||
enable_sm ();
|
||||
initialize_sve_state ();
|
||||
}
|
||||
else if (state == 3)
|
||||
{
|
||||
enable_za ();
|
||||
initialize_za_state ();
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
enable_za ();
|
||||
enable_sm ();
|
||||
initialize_sve_state ();
|
||||
initialize_za_state ();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_state (int id)
|
||||
{
|
||||
return (id / 25);
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_vl (int id)
|
||||
{
|
||||
return 16 << ((id / 5) % 5);
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_svl (int id)
|
||||
{
|
||||
return 16 << (id % 5);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME)
|
||||
{
|
||||
int id_start = ID_START;
|
||||
int id_end = ID_END;
|
||||
#ifdef SIGILL
|
||||
signal (SIGILL, handler);
|
||||
#endif
|
||||
|
||||
int signal_count = 0;
|
||||
for (int id = id_start; id <= id_end; id++)
|
||||
{
|
||||
int state = test_id_to_state (id);
|
||||
int vl = test_id_to_vl (id);
|
||||
int svl = test_id_to_svl (id);
|
||||
|
||||
if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1)
|
||||
continue;
|
||||
|
||||
signal_count++;
|
||||
enable_states (state);
|
||||
dummy (); /* stop before SIGILL */
|
||||
__asm __volatile (".word 0xDEADBEEF"); /* illegal instruction */
|
||||
while (signal_count != count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
179
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.exp.tcl
Normal file
179
gdb/testsuite/gdb.arch/aarch64-sme-regs-sigframe.exp.tcl
Normal file
|
@ -0,0 +1,179 @@
|
|||
# Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Exercise restoring SME/TPIDR2 state from a signal frame.
|
||||
|
||||
load_lib aarch64-scalable.exp
|
||||
|
||||
#
|
||||
# Validate the state of registers in the signal frame for various states.
|
||||
#
|
||||
proc test_sme_registers_sigframe { id_start id_end } {
|
||||
|
||||
set compile_flags {"debug" "macros"}
|
||||
lappend compile_flags "additional_flags=-march=armv8.5-a+sve"
|
||||
lappend compile_flags "additional_flags=-DID_START=${id_start}"
|
||||
lappend compile_flags "additional_flags=-DID_END=${id_end}"
|
||||
|
||||
standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-regs-sigframe.c
|
||||
set executable "${::testfile}-${id_start}-${id_end}"
|
||||
if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} {
|
||||
return -1
|
||||
}
|
||||
set binfile [standard_output_file ${executable}]
|
||||
|
||||
if ![runto_main] {
|
||||
untested "could not run to main"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Check if we are talking to a remote target. If so, bail out, as right now
|
||||
# remote targets can't communicate vector length (vl or svl) changes to gdb
|
||||
# via the RSP. When this restriction is lifted, we can remove this guard.
|
||||
if {[gdb_is_target_remote]} {
|
||||
unsupported "aarch64 sve/sme tests not supported for remote targets"
|
||||
return -1
|
||||
}
|
||||
|
||||
set sigill_breakpoint "stop before SIGILL"
|
||||
set handler_breakpoint "handler"
|
||||
gdb_breakpoint [gdb_get_line_number $sigill_breakpoint]
|
||||
gdb_breakpoint [gdb_get_line_number $handler_breakpoint]
|
||||
|
||||
for {set id $id_start} {$id <= $id_end} {incr id} {
|
||||
set state [test_id_to_state $id]
|
||||
set vl [test_id_to_vl $id]
|
||||
set svl [test_id_to_svl $id]
|
||||
|
||||
set skip_unsupported 0
|
||||
if {![aarch64_supports_sve_vl $vl]
|
||||
|| ![aarch64_supports_sme_svl $svl]} {
|
||||
# We have a vector length or streaming vector length that
|
||||
# is not supported by this target. Skip to the next iteration
|
||||
# since it is no use running tests for an unsupported vector
|
||||
# length.
|
||||
if {![aarch64_supports_sve_vl $vl]} {
|
||||
verbose -log "SVE vector length $vl not supported."
|
||||
} elseif {![aarch64_supports_sme_svl $svl]} {
|
||||
verbose -log "SME streaming vector length $svl not supported."
|
||||
}
|
||||
verbose -log "Skipping test."
|
||||
set skip_unsupported 1
|
||||
}
|
||||
|
||||
with_test_prefix "state=${state} vl=${vl} svl=${svl}" {
|
||||
|
||||
# If the SVE or SME vector length is not supported, just skip
|
||||
# these next tests.
|
||||
if {$skip_unsupported} {
|
||||
untested "unsupported configuration on target"
|
||||
continue
|
||||
}
|
||||
|
||||
# Run the program until it has adjusted the svl.
|
||||
if [gdb_continue_to_breakpoint $sigill_breakpoint] {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Check SVG to make sure it is correct
|
||||
set expected_svg [expr $svl / 8]
|
||||
gdb_test "print \$svg" "= ${expected_svg}"
|
||||
|
||||
# Check the size of ZA.
|
||||
set expected_za_size [expr $svl * $svl]
|
||||
gdb_test "print sizeof \$za" " = $expected_za_size"
|
||||
|
||||
# Check the value of SVCR.
|
||||
gdb_test "print \$svcr" [get_svcr_value $state] "svcr before signal"
|
||||
|
||||
# Handle SME ZA initialization and state.
|
||||
set byte 0
|
||||
if { $state == "za" || $state == "za_ssve" } {
|
||||
set byte 170
|
||||
}
|
||||
|
||||
# Set the expected ZA pattern.
|
||||
set za_pattern [string_to_regexp [2d_array_value_pattern $byte $svl $svl]]
|
||||
|
||||
# Handle SVE/SSVE initialization and state.
|
||||
set sve_vl $svl
|
||||
if { $state == "ssve" || $state == "za_ssve" } {
|
||||
# SVE state comes from SSVE.
|
||||
set sve_vl $svl
|
||||
} else {
|
||||
# SVE state comes from regular SVE.
|
||||
set sve_vl $vl
|
||||
}
|
||||
|
||||
# Initialize the SVE state.
|
||||
set sve_pattern [string_to_regexp [sve_value_pattern $state $sve_vl 85 255]]
|
||||
for {set row 0} {$row < 32} {incr row} {
|
||||
set register_name "\$z${row}\.b\.u"
|
||||
gdb_test "print sizeof $register_name" " = $sve_vl" "size of $register_name"
|
||||
gdb_test "print $register_name" $sve_pattern "read back from $register_name"
|
||||
}
|
||||
|
||||
# Print ZA to check its value.
|
||||
gdb_test "print \$za" $za_pattern "read back from za"
|
||||
|
||||
# Test TPIDR2 restore from signal frame as well.
|
||||
gdb_test_no_output "set \$tpidr2=0x0102030405060708"
|
||||
|
||||
# Run to the illegal instruction.
|
||||
if [gdb_test "continue" "Continuing\.\r\n\r\nProgram received signal SIGILL, Illegal instruction\..*in main.*"] {
|
||||
return
|
||||
}
|
||||
|
||||
# Skip the illegal instruction. The signal handler will be called after we continue.
|
||||
gdb_test_no_output "set \$pc=\$pc+4"
|
||||
# Continue to the signal handler.
|
||||
if [gdb_continue_to_breakpoint $handler_breakpoint] {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Modify TPIDR2 so it is different from its value past the signal
|
||||
# frame.
|
||||
gdb_test_no_output "set \$tpidr2 = 0x0"
|
||||
|
||||
# Select the frame that contains "main".
|
||||
gdb_test "frame 2" "#2.* main \\\(.*\\\) at.*"
|
||||
|
||||
for {set row 0} {$row < 32} {incr row} {
|
||||
set register_name "\$z${row}\.b\.u"
|
||||
gdb_test "print sizeof $register_name" " = $sve_vl" "size of $register_name in the signal frame"
|
||||
gdb_test "print $register_name" $sve_pattern "$register_name contents from signal frame"
|
||||
}
|
||||
|
||||
# Check the size of ZA in the signal frame.
|
||||
set expected_za_size [expr $svl * $svl]
|
||||
gdb_test "print sizeof \$za" " = $expected_za_size" "size of za in signal frame"
|
||||
|
||||
# Check the value of SVCR in the signal frame.
|
||||
gdb_test "print \$svcr" [get_svcr_value $state] "svcr from signal frame"
|
||||
|
||||
# Check the value of ZA in the signal frame.
|
||||
gdb_test "print \$za" $za_pattern "za contents from signal frame"
|
||||
|
||||
# Check the value of TPIDR2 in the signal frame.
|
||||
gdb_test "print/x \$tpidr2" " = 0x102030405060708" "tpidr2 contents from signal frame"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require is_aarch64_target
|
||||
require allow_aarch64_sve_tests
|
||||
require allow_aarch64_sme_tests
|
||||
|
||||
test_sme_registers_sigframe $id_start $id_end
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-0.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-0.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 16
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (0 ~ 3) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 0
|
||||
set id_end 3
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-1.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-1.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 16
|
||||
# SVL: 256
|
||||
# This set covers 1 (4) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 4
|
||||
set id_end 4
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-2.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-2.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 32
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (5 ~ 8) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 5
|
||||
set id_end 8
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-3.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-3.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 32
|
||||
# SVL: 256
|
||||
# This set covers 1 (9) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 9
|
||||
set id_end 9
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-4.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-4.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 64
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (10 ~ 13) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 10
|
||||
set id_end 13
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-5.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-5.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 64
|
||||
# SVL: 256
|
||||
# This set covers 1 (14) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 14
|
||||
set id_end 14
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-6.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-6.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 128
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (15 ~ 18) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 15
|
||||
set id_end 18
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-7.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-7.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 128
|
||||
# SVL: 256
|
||||
# This set covers 1 (19) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 19
|
||||
set id_end 19
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-8.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-8.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 256
|
||||
# SVL: 16, 32, 64, 128
|
||||
# This set covers 4 (20 ~ 23) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 20
|
||||
set id_end 23
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-9.exp
Normal file
26
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable-9.exp
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Exercise tests with the following parameters:
|
||||
# VL: 256
|
||||
# SVL: 256
|
||||
# This set covers 1 (24) out of 25 tests.
|
||||
#
|
||||
# These tests are split this way for parallelization and for performance
|
||||
# reasons.
|
||||
#
|
||||
set id_start 24
|
||||
set id_end 24
|
||||
source $srcdir/$subdir/aarch64-sme-regs-unavailable.exp.tcl
|
152
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.c
Normal file
152
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Exercise various cases of ZA contents not being available for AArch64's
|
||||
Scalable Matrix Extension. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef HWCAP_SVE
|
||||
#define HWCAP_SVE (1 << 22)
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP2_SME
|
||||
#define HWCAP2_SME (1 << 23)
|
||||
#endif
|
||||
|
||||
#ifndef PR_SVE_SET_VL
|
||||
#define PR_SVE_SET_VL 50
|
||||
#define PR_SVE_GET_VL 51
|
||||
#define PR_SVE_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
#ifndef PR_SME_SET_VL
|
||||
#define PR_SME_SET_VL 63
|
||||
#define PR_SME_GET_VL 64
|
||||
#define PR_SME_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
static int get_vl_size ()
|
||||
{
|
||||
int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SVE_GET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int get_svl_size ()
|
||||
{
|
||||
int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SME_GET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int set_vl_size (int new_vl)
|
||||
{
|
||||
int res = prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SVE_SET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = get_vl_size ();
|
||||
if (res != new_vl)
|
||||
{
|
||||
printf ("Unexpected VL value (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int set_svl_size (int new_svl)
|
||||
{
|
||||
int res = prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0);
|
||||
if (res < 0)
|
||||
{
|
||||
printf ("FAILED to PR_SME_SET_VL (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = get_svl_size ();
|
||||
if (res != new_svl)
|
||||
{
|
||||
printf ("Unexpected SVL value (%d)\n", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_vl (int id)
|
||||
{
|
||||
return 16 << ((id / 5) % 5);
|
||||
}
|
||||
|
||||
static int
|
||||
test_id_to_svl (int id)
|
||||
{
|
||||
return 16 << (id % 5);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME)
|
||||
{
|
||||
int id_start = ID_START;
|
||||
int id_end = ID_END;
|
||||
|
||||
for (int id = id_start; id <= id_end; id++)
|
||||
{
|
||||
int vl = test_id_to_vl (id);
|
||||
int svl = test_id_to_svl (id);
|
||||
|
||||
if (set_vl_size (vl) == -1 || set_svl_size (svl) == -1)
|
||||
continue;
|
||||
|
||||
dummy (); /* stop 1 */
|
||||
}
|
||||
|
||||
dummy (); /* stop 2 */
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
212
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.exp.tcl
Normal file
212
gdb/testsuite/gdb.arch/aarch64-sme-regs-unavailable.exp.tcl
Normal file
|
@ -0,0 +1,212 @@
|
|||
# Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Exercise the following:
|
||||
# - Printing ZA registers when there is no ZA state.
|
||||
# - Setting values of ZA registers when there is no ZA state.
|
||||
# - Validating ZA state is activated when we write to ZA registers.
|
||||
|
||||
load_lib aarch64-scalable.exp
|
||||
|
||||
#
|
||||
# Validate that the ZA registers have the expected state.
|
||||
#
|
||||
proc_with_prefix check_regs { vl svl } {
|
||||
# Check VG to make sure it is correct
|
||||
set expected_vg [expr $vl / 8]
|
||||
gdb_test "print \$vg" "= ${expected_vg}"
|
||||
|
||||
# Check SVG to make sure it is correct
|
||||
set expected_svg [expr $svl / 8]
|
||||
gdb_test "print \$svg" "= ${expected_svg}"
|
||||
|
||||
# Make sure there is no SM or ZA state.
|
||||
if [gdb_test "print \$svcr" "= \\\[ \\\]"] {
|
||||
fail "incorrect ZA state"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Check the size of ZA.
|
||||
set expected_za_size [expr $svl * $svl]
|
||||
gdb_test "print sizeof \$za" " = $expected_za_size"
|
||||
|
||||
# Check the size of Z0.
|
||||
gdb_test "print sizeof \$z0" " = $vl"
|
||||
|
||||
# Set the expected ZA pattern.
|
||||
set za_pattern [string_to_regexp [2d_array_value_pattern 0 $svl $svl]]
|
||||
|
||||
# Check ZA.
|
||||
gdb_test "print \$za" $za_pattern
|
||||
|
||||
# Exercise reading/writing the tile slice pseudo-registers.
|
||||
set last_tile 1
|
||||
set last_slice $svl
|
||||
set elements $svl
|
||||
set expected_size $svl
|
||||
foreach_with_prefix granularity {"b" "h" "s" "d" "q"} {
|
||||
set pattern [string_to_regexp [1d_array_value_pattern 0 $elements]]
|
||||
for {set tile 0} {$tile < $last_tile} {incr tile} {
|
||||
for {set slice 0} {$slice < $last_slice} {incr slice} {
|
||||
foreach_with_prefix direction {"h" "v"} {
|
||||
set register_name "\$za${tile}${direction}${granularity}${slice}"
|
||||
# Test the size.
|
||||
gdb_test "print sizeof ${register_name}" " = ${expected_size}"
|
||||
gdb_test "print ${register_name}" $pattern
|
||||
}
|
||||
}
|
||||
}
|
||||
set last_tile [expr $last_tile * 2]
|
||||
set last_slice [expr ($last_slice / 2)]
|
||||
set elements [expr ($elements / 2)]
|
||||
}
|
||||
|
||||
# Exercise reading/writing the tile pseudo-registers.
|
||||
set last_tile 1
|
||||
set elements $svl
|
||||
set expected_size [expr $svl * $svl]
|
||||
foreach_with_prefix granularity {"b" "h" "s" "d" "q"} {
|
||||
set pattern [string_to_regexp [2d_array_value_pattern 0 $elements $elements]]
|
||||
for {set tile 0} {$tile < $last_tile} {incr tile} {
|
||||
set register_name "\$za${tile}${granularity}"
|
||||
# Test the size.
|
||||
gdb_test "print sizeof ${register_name}" " = ${expected_size}"
|
||||
gdb_test "print ${register_name}" $pattern
|
||||
}
|
||||
set last_tile [expr $last_tile * 2]
|
||||
set expected_size [expr $expected_size / 2]
|
||||
set elements [expr ($elements / 2)]
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Cycle through all ZA registers and pseudo-registers and validate that their
|
||||
# contents are unavailable (zeroed out) for vector length SVL.
|
||||
#
|
||||
proc test_sme_registers_unavailable { id_start id_end } {
|
||||
|
||||
set compile_flags {"debug" "macros"}
|
||||
lappend compile_flags "additional_flags=-DID_START=${id_start}"
|
||||
lappend compile_flags "additional_flags=-DID_END=${id_end}"
|
||||
|
||||
standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-regs-unavailable.c
|
||||
set executable "${::testfile}-${id_start}-${id_end}"
|
||||
if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} {
|
||||
return -1
|
||||
}
|
||||
set binfile [standard_output_file ${executable}]
|
||||
|
||||
if ![runto_main] {
|
||||
untested "could not run to main"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Check if we are talking to a remote target. If so, bail out, as right now
|
||||
# remote targets can't communicate vector length (vl or svl) changes to gdb
|
||||
# via the RSP. When this restriction is lifted, we can remove this guard.
|
||||
if {[gdb_is_target_remote]} {
|
||||
unsupported "aarch64 sve/sme tests not supported for remote targets"
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_test_no_output "set print repeats 1"
|
||||
|
||||
set prctl_breakpoint "stop 1"
|
||||
gdb_breakpoint [gdb_get_line_number $prctl_breakpoint]
|
||||
|
||||
for {set id $id_start} {$id <= $id_end} {incr id} {
|
||||
set vl [test_id_to_vl $id]
|
||||
set svl [test_id_to_svl $id]
|
||||
|
||||
set skip_unsupported 0
|
||||
if {![aarch64_supports_sve_vl $vl]
|
||||
|| ![aarch64_supports_sme_svl $svl]} {
|
||||
# We have a vector length or streaming vector length that
|
||||
# is not supported by this target. Skip to the next iteration
|
||||
# since it is no use running tests for an unsupported vector
|
||||
# length.
|
||||
if {![aarch64_supports_sve_vl $vl]} {
|
||||
verbose -log "SVE vector length $vl not supported."
|
||||
} elseif {![aarch64_supports_sme_svl $svl]} {
|
||||
verbose -log "SME streaming vector length $svl not supported."
|
||||
}
|
||||
verbose -log "Skipping test."
|
||||
set skip_unsupported 1
|
||||
}
|
||||
|
||||
with_test_prefix "prctl, vl=${vl} svl=${svl}" {
|
||||
# If the SVE or SME vector length is not supported, just skip
|
||||
# these next tests.
|
||||
if {$skip_unsupported} {
|
||||
untested "unsupported configuration on target"
|
||||
continue
|
||||
}
|
||||
|
||||
# Run the program until it has adjusted svl.
|
||||
gdb_continue_to_breakpoint $prctl_breakpoint
|
||||
|
||||
check_regs $vl $svl
|
||||
}
|
||||
}
|
||||
|
||||
set non_prctl_breakpoint "stop 2"
|
||||
gdb_breakpoint [gdb_get_line_number $non_prctl_breakpoint]
|
||||
gdb_continue_to_breakpoint $non_prctl_breakpoint
|
||||
|
||||
for {set id $id_start} {$id <= $id_end} {incr id} {
|
||||
set vl [test_id_to_vl $id]
|
||||
set svl [test_id_to_svl $id]
|
||||
|
||||
set skip_unsupported 0
|
||||
if {![aarch64_supports_sve_vl $vl]
|
||||
|| ![aarch64_supports_sme_svl $svl]} {
|
||||
# We have a vector length or streaming vector length that
|
||||
# is not supported by this target. Skip to the next iteration
|
||||
# since it is no use running tests for an unsupported vector
|
||||
# length.
|
||||
if {![aarch64_supports_sve_vl $vl]} {
|
||||
verbose -log "SVE vector length $vl not supported."
|
||||
} elseif {![aarch64_supports_sme_svl $svl]} {
|
||||
verbose -log "SME streaming vector length $svl not supported."
|
||||
}
|
||||
verbose -log "Skipping test."
|
||||
set skip_unsupported 1
|
||||
}
|
||||
|
||||
with_test_prefix "gdb, vl=${vl} svl=${svl}" {
|
||||
|
||||
# If the SVE or SME vector length is not supported, just skip
|
||||
# these next tests.
|
||||
if {$skip_unsupported} {
|
||||
untested "unsupported configuration on target"
|
||||
continue
|
||||
}
|
||||
|
||||
# Adjust vg and svg.
|
||||
set vg_value [expr $vl / 8]
|
||||
set svg_value [expr $svl / 8]
|
||||
gdb_test_no_output "set \$vg = ${vg_value}"
|
||||
gdb_test_no_output "set \$svg = ${svg_value}"
|
||||
|
||||
check_regs $vl $svl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require is_aarch64_target
|
||||
require allow_aarch64_sve_tests
|
||||
require allow_aarch64_sme_tests
|
||||
|
||||
test_sme_registers_unavailable $id_start $id_end
|
249
gdb/testsuite/gdb.arch/aarch64-sme-sanity.c
Normal file
249
gdb/testsuite/gdb.arch/aarch64-sme-sanity.c
Normal file
|
@ -0,0 +1,249 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Sanity test to exercise AArch64's Scalable Vector/Matrix Extension basic
|
||||
functionality. It cycles through different combinations of state and
|
||||
initializes different register sets. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef HWCAP_SVE
|
||||
#define HWCAP_SVE (1 << 22)
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP2_SME
|
||||
#define HWCAP2_SME (1 << 23)
|
||||
#endif
|
||||
|
||||
static void
|
||||
enable_za ()
|
||||
{
|
||||
/* smstart za */
|
||||
__asm __volatile (".word 0xD503457F");
|
||||
}
|
||||
|
||||
static void
|
||||
disable_za ()
|
||||
{
|
||||
/* smstop za */
|
||||
__asm __volatile (".word 0xD503447F");
|
||||
}
|
||||
|
||||
static void
|
||||
enable_sm ()
|
||||
{
|
||||
/* smstart sm */
|
||||
__asm __volatile (".word 0xD503437F");
|
||||
}
|
||||
|
||||
static void
|
||||
disable_sm ()
|
||||
{
|
||||
/* smstop sm */
|
||||
__asm __volatile (".word 0xD503427F");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_fpsimd_state ()
|
||||
{
|
||||
char buffer[16];
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
buffer[i] = 0x55;
|
||||
|
||||
__asm __volatile ("mov x0, %0\n\t" \
|
||||
: : "r" (buffer));
|
||||
|
||||
__asm __volatile ("ldr q0, [x0]");
|
||||
__asm __volatile ("ldr q1, [x0]");
|
||||
__asm __volatile ("ldr q2, [x0]");
|
||||
__asm __volatile ("ldr q3, [x0]");
|
||||
__asm __volatile ("ldr q4, [x0]");
|
||||
__asm __volatile ("ldr q5, [x0]");
|
||||
__asm __volatile ("ldr q6, [x0]");
|
||||
__asm __volatile ("ldr q7, [x0]");
|
||||
__asm __volatile ("ldr q8, [x0]");
|
||||
__asm __volatile ("ldr q9, [x0]");
|
||||
__asm __volatile ("ldr q10, [x0]");
|
||||
__asm __volatile ("ldr q11, [x0]");
|
||||
__asm __volatile ("ldr q12, [x0]");
|
||||
__asm __volatile ("ldr q13, [x0]");
|
||||
__asm __volatile ("ldr q14, [x0]");
|
||||
__asm __volatile ("ldr q15, [x0]");
|
||||
__asm __volatile ("ldr q16, [x0]");
|
||||
__asm __volatile ("ldr q17, [x0]");
|
||||
__asm __volatile ("ldr q18, [x0]");
|
||||
__asm __volatile ("ldr q19, [x0]");
|
||||
__asm __volatile ("ldr q20, [x0]");
|
||||
__asm __volatile ("ldr q21, [x0]");
|
||||
__asm __volatile ("ldr q22, [x0]");
|
||||
__asm __volatile ("ldr q23, [x0]");
|
||||
__asm __volatile ("ldr q24, [x0]");
|
||||
__asm __volatile ("ldr q25, [x0]");
|
||||
__asm __volatile ("ldr q26, [x0]");
|
||||
__asm __volatile ("ldr q27, [x0]");
|
||||
__asm __volatile ("ldr q28, [x0]");
|
||||
__asm __volatile ("ldr q29, [x0]");
|
||||
__asm __volatile ("ldr q30, [x0]");
|
||||
__asm __volatile ("ldr q31, [x0]");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_za_state ()
|
||||
{
|
||||
/* zero za */
|
||||
__asm __volatile (".word 0xC00800FF");
|
||||
|
||||
char buffer[256];
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
buffer[i] = 0xaa;
|
||||
|
||||
__asm __volatile ("mov x0, %0\n\t" \
|
||||
: : "r" (buffer));
|
||||
|
||||
/* Initialize loop boundaries. */
|
||||
__asm __volatile ("mov w12, 0");
|
||||
__asm __volatile ("mov w17, 256");
|
||||
|
||||
/* loop: ldr za[w12, 0], [x0] */
|
||||
__asm __volatile ("loop: .word 0xe1000000");
|
||||
__asm __volatile ("add w12, w12, 1");
|
||||
__asm __volatile ("cmp w12, w17");
|
||||
__asm __volatile ("bne loop");
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_sve_state ()
|
||||
{
|
||||
__asm __volatile ("dup z0.b, -1");
|
||||
__asm __volatile ("dup z1.b, -1");
|
||||
__asm __volatile ("dup z2.b, -1");
|
||||
__asm __volatile ("dup z3.b, -1");
|
||||
__asm __volatile ("dup z4.b, -1");
|
||||
__asm __volatile ("dup z5.b, -1");
|
||||
__asm __volatile ("dup z6.b, -1");
|
||||
__asm __volatile ("dup z7.b, -1");
|
||||
__asm __volatile ("dup z8.b, -1");
|
||||
__asm __volatile ("dup z9.b, -1");
|
||||
__asm __volatile ("dup z10.b, -1");
|
||||
__asm __volatile ("dup z11.b, -1");
|
||||
__asm __volatile ("dup z12.b, -1");
|
||||
__asm __volatile ("dup z13.b, -1");
|
||||
__asm __volatile ("dup z14.b, -1");
|
||||
__asm __volatile ("dup z15.b, -1");
|
||||
__asm __volatile ("dup z16.b, -1");
|
||||
__asm __volatile ("dup z17.b, -1");
|
||||
__asm __volatile ("dup z18.b, -1");
|
||||
__asm __volatile ("dup z19.b, -1");
|
||||
__asm __volatile ("dup z20.b, -1");
|
||||
__asm __volatile ("dup z21.b, -1");
|
||||
__asm __volatile ("dup z22.b, -1");
|
||||
__asm __volatile ("dup z23.b, -1");
|
||||
__asm __volatile ("dup z24.b, -1");
|
||||
__asm __volatile ("dup z25.b, -1");
|
||||
__asm __volatile ("dup z26.b, -1");
|
||||
__asm __volatile ("dup z27.b, -1");
|
||||
__asm __volatile ("dup z28.b, -1");
|
||||
__asm __volatile ("dup z29.b, -1");
|
||||
__asm __volatile ("dup z30.b, -1");
|
||||
__asm __volatile ("dup z31.b, -1");
|
||||
__asm __volatile ("ptrue p0.b");
|
||||
__asm __volatile ("ptrue p1.b");
|
||||
__asm __volatile ("ptrue p2.b");
|
||||
__asm __volatile ("ptrue p3.b");
|
||||
__asm __volatile ("ptrue p4.b");
|
||||
__asm __volatile ("ptrue p5.b");
|
||||
__asm __volatile ("ptrue p6.b");
|
||||
__asm __volatile ("ptrue p7.b");
|
||||
__asm __volatile ("ptrue p8.b");
|
||||
__asm __volatile ("ptrue p9.b");
|
||||
__asm __volatile ("ptrue p10.b");
|
||||
__asm __volatile ("ptrue p11.b");
|
||||
__asm __volatile ("ptrue p12.b");
|
||||
__asm __volatile ("ptrue p13.b");
|
||||
__asm __volatile ("ptrue p14.b");
|
||||
__asm __volatile ("ptrue p15.b");
|
||||
__asm __volatile ("setffr");
|
||||
}
|
||||
|
||||
/* Enable register states based on STATE.
|
||||
|
||||
0 - FPSIMD
|
||||
1 - SVE
|
||||
2 - SSVE
|
||||
3 - ZA
|
||||
4 - ZA and SSVE. */
|
||||
|
||||
void enable_states (int state)
|
||||
{
|
||||
disable_za ();
|
||||
disable_sm ();
|
||||
initialize_fpsimd_state ();
|
||||
|
||||
if (state == 1)
|
||||
{
|
||||
initialize_sve_state ();
|
||||
}
|
||||
else if (state == 2)
|
||||
{
|
||||
enable_sm ();
|
||||
initialize_sve_state ();
|
||||
}
|
||||
else if (state == 3)
|
||||
{
|
||||
enable_za ();
|
||||
initialize_za_state ();
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
enable_za ();
|
||||
enable_sm ();
|
||||
initialize_sve_state ();
|
||||
initialize_za_state ();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void dummy ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (getauxval (AT_HWCAP) & HWCAP_SVE && getauxval (AT_HWCAP2) & HWCAP2_SME)
|
||||
{
|
||||
for (int state = 0; state < 5; state++)
|
||||
{
|
||||
enable_states (state);
|
||||
dummy (); /* stop here */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("SKIP: no HWCAP_SVE or HWCAP2_SME on this system\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
72
gdb/testsuite/gdb.arch/aarch64-sme-sanity.exp
Normal file
72
gdb/testsuite/gdb.arch/aarch64-sme-sanity.exp
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Sanity check for AArch64 Scalable Vector/Matrix Extensions functionality.
|
||||
|
||||
load_lib aarch64-scalable.exp
|
||||
|
||||
#
|
||||
# Run a series of basic checks for SVE/SME states.
|
||||
#
|
||||
proc sanity_check { vl svl } {
|
||||
# Run the program until the point where we start initializing the different
|
||||
# register states.
|
||||
set state_breakpoint "stop here"
|
||||
gdb_breakpoint [gdb_get_line_number $state_breakpoint]
|
||||
|
||||
for {set id 0} {$id < 5} {incr id} {
|
||||
set state [state_id_to_state_string $id]
|
||||
|
||||
with_test_prefix "state=${state} vl=${vl} svl=${svl}" {
|
||||
gdb_continue_to_breakpoint $state_breakpoint
|
||||
check_state $state $vl $svl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require is_aarch64_target
|
||||
require allow_aarch64_sve_tests
|
||||
require allow_aarch64_sme_tests
|
||||
|
||||
set compile_flags {"debug" "macros" "additional_flags=-march=armv8.5-a+sve"}
|
||||
standard_testfile
|
||||
if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} ${compile_flags}]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
if {![runto_main]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Check if we are talking to a remote target. If so, bail out, as right now
|
||||
# remote targets can't communicate vector length (vl or svl) changes to gdb
|
||||
# via the RSP. When this restriction is lifted, we can remove this guard.
|
||||
if {[gdb_is_target_remote]} {
|
||||
unsupported "aarch64 sve/sme tests not supported for remote targets"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Adjust the repeat count for the test.
|
||||
gdb_test_no_output "set print repeats 1" "adjust repeat count"
|
||||
|
||||
# Fetch both the vector length and the streaming vector length the target
|
||||
# system is using. We do not force any vector lengths and do not change
|
||||
# it mid-execution.
|
||||
set vl [expr [get_valueof "" "\$vg" "0" "fetch value of vl"] * 8]
|
||||
set svl [expr [get_valueof "" "\$svg" "0" "fetch value of svl"] * 8]
|
||||
|
||||
# Now we are at the point where we can start checking state and moving the
|
||||
# testcase forward.
|
||||
sanity_check $vl $svl
|
237
gdb/testsuite/lib/aarch64-scalable.exp
Normal file
237
gdb/testsuite/lib/aarch64-scalable.exp
Normal file
|
@ -0,0 +1,237 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Support routines for aarch64 scalable extension tests
|
||||
|
||||
# Load generic aarch64 test dependencies.
|
||||
load_lib aarch64.exp
|
||||
|
||||
#
|
||||
# Return a regular expression that matches what gdb would print for a
|
||||
# SVE Z register of length VL in state STATE. The Z register should be filled
|
||||
# with BYTE_SVE and the FPSIMD registers should be filled with BYTE_FPSIMD.
|
||||
#
|
||||
# The pattern is of the form
|
||||
#
|
||||
# {BYTE_FPSIMD <repeats 16 times>}
|
||||
#
|
||||
# or
|
||||
#
|
||||
# {BYTE_FPSIMD <repeats 16 times>, 0 <repeats ... times>}
|
||||
#
|
||||
# or
|
||||
#
|
||||
# {BYTE_SVE <repeats VL times>}
|
||||
#
|
||||
proc sve_value_pattern { state vl byte_fpsimd byte_sve } {
|
||||
set brace_open "{"
|
||||
set brace_close "}"
|
||||
|
||||
append data $brace_open
|
||||
if { $state == "fpsimd" || $state == "za" } {
|
||||
if { $vl > 16 } {
|
||||
set sve_repeat_count [expr $vl - 16]
|
||||
append data "$byte_fpsimd <repeats 16 times>, 0 <repeats $sve_repeat_count times>"
|
||||
} else {
|
||||
append data "$byte_fpsimd <repeats 16 times>"
|
||||
}
|
||||
} else {
|
||||
append data "$byte_sve <repeats $vl times>"
|
||||
}
|
||||
append data $brace_close
|
||||
|
||||
verbose -log "sve_value_pattern pattern string is..."
|
||||
verbose -log $data
|
||||
return $data
|
||||
}
|
||||
|
||||
#
|
||||
# Return the SVCR value based on STATE.
|
||||
# SVCR is only available when SME is available.
|
||||
#
|
||||
proc get_svcr_value { state } {
|
||||
if { $state == "ssve" } {
|
||||
return "= \\\[ SM \\\]"
|
||||
} elseif { $state == "za" } {
|
||||
return "= \\\[ ZA \\\]"
|
||||
} elseif { $state == "za_ssve" } {
|
||||
return "= \\\[ SM ZA \\\]"
|
||||
}
|
||||
|
||||
return "= \\\[ \\\]"
|
||||
}
|
||||
|
||||
#
|
||||
# Return the state string based on STATE
|
||||
#
|
||||
proc state_id_to_state_string { state } {
|
||||
if {$state == 0} {
|
||||
return "fpsimd"
|
||||
} elseif {$state == 1} {
|
||||
return "sve"
|
||||
} elseif {$state == 2} {
|
||||
return "ssve"
|
||||
} elseif {$state == 3} {
|
||||
return "za"
|
||||
} elseif {$state == 4} {
|
||||
return "za_ssve"
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Given a test ID, return the string representing the register state.
|
||||
# The state is one of fpsimd, sve, ssve, za and za_ssve.
|
||||
#
|
||||
proc test_id_to_state { id } {
|
||||
set state [expr $id / 25]
|
||||
|
||||
return [state_id_to_state_string $state]
|
||||
}
|
||||
|
||||
#
|
||||
# Given a test ID, return the associated vector length.
|
||||
#
|
||||
proc test_id_to_vl { id } {
|
||||
return [expr 16 << (($id / 5) % 5)]
|
||||
}
|
||||
|
||||
#
|
||||
# Given a test ID, return the associated streaming vector length.
|
||||
#
|
||||
proc test_id_to_svl { id } {
|
||||
return [expr 16 << ($id % 5)]
|
||||
}
|
||||
|
||||
#
|
||||
# Validate the values of the SVE registers.
|
||||
#
|
||||
proc check_sve_regs { byte state vl svl } {
|
||||
|
||||
# If streaming mode is enabled, the vector length is the streaming
|
||||
# vector length.
|
||||
set z_pattern ""
|
||||
set z_size 0
|
||||
if {$state == "ssve" || $state == "za_ssve"} {
|
||||
set z_pattern [string_to_regexp [1d_array_value_pattern $byte $svl]]
|
||||
set z_size $svl
|
||||
} else {
|
||||
set z_size $vl
|
||||
|
||||
if {$state == "fpsimd" || $state == "za"} {
|
||||
# If there is no SVE/SSVE state, the contents of the Z/P/FFR registers
|
||||
# are zero.
|
||||
if {$vl == 16} {
|
||||
set z_pattern [string_to_regexp [1d_array_value_pattern $byte $vl]]
|
||||
} else {
|
||||
set z_repeats [expr $vl - 16]
|
||||
set z_pattern [string_to_regexp "{$byte <repeats 16 times>, 0 <repeats $z_repeats times>}"]
|
||||
}
|
||||
} else {
|
||||
set z_pattern [string_to_regexp [1d_array_value_pattern $byte $vl]]
|
||||
}
|
||||
}
|
||||
set p_size [expr $z_size / 8]
|
||||
|
||||
# If there is no SVE/SSVE state, the contents of the Z/P/FFR registers
|
||||
# are zero.
|
||||
set p_byte $byte
|
||||
if {$state == "fpsimd" || $state == "za"} {
|
||||
set p_byte 0
|
||||
}
|
||||
set p_pattern [string_to_regexp [1d_array_value_pattern $p_byte $p_size]]
|
||||
|
||||
for {set number 0} {$number < 32} {incr number} {
|
||||
set register_name "\$z${number}\.b\.u"
|
||||
gdb_test "print sizeof $register_name" " = $z_size"
|
||||
gdb_test "print $register_name" $z_pattern
|
||||
}
|
||||
|
||||
for {set number 0} {$number < 16} {incr number} {
|
||||
set register_name "\$p${number}"
|
||||
gdb_test "print sizeof $register_name" " = $p_size"
|
||||
gdb_test "print $register_name" $p_pattern
|
||||
}
|
||||
|
||||
gdb_test "print \$ffr" $p_pattern
|
||||
}
|
||||
|
||||
#
|
||||
# Validate the values of the SME registers.
|
||||
#
|
||||
proc check_sme_regs { byte state svl } {
|
||||
# ZA contents are only available when the ZA state is enabled. Otherwise
|
||||
# the ZA contents are unavailable (zeroed out).
|
||||
set za_pattern ""
|
||||
set expected_za_size [expr $svl * $svl]
|
||||
|
||||
if {$state != "za" && $state != "za_ssve"} {
|
||||
set byte 0
|
||||
}
|
||||
|
||||
set za_pattern [string_to_regexp [2d_array_value_pattern $byte $svl $svl]]
|
||||
|
||||
gdb_test "print sizeof \$za" " = $expected_za_size"
|
||||
gdb_test "print \$za" $za_pattern
|
||||
}
|
||||
|
||||
#
|
||||
# With register STATE, vector length VL and streaming vector length SVL,
|
||||
# run some register state checks to make sure the values are the expected
|
||||
# ones
|
||||
#
|
||||
proc check_state { state vl svl } {
|
||||
# The FPSIMD registers are initialized with a value of 0x55 (85)
|
||||
# for each byte.
|
||||
#
|
||||
# The SVE registers are initialized with a value of 0xff (255) for each
|
||||
# byte, including the predicate registers and FFR.
|
||||
#
|
||||
# The SME (ZA) register is initialized with a value of 0xaa (170) for
|
||||
# each byte.
|
||||
|
||||
# Check VG to make sure it is correct
|
||||
set expected_vg [expr $vl / 8]
|
||||
# If streaming mode is enabled, then vg is actually svg.
|
||||
if {$state == "ssve" || $state == "za_ssve"} {
|
||||
set expected_vg [expr $svl / 8]
|
||||
}
|
||||
gdb_test "print \$vg" " = ${expected_vg}"
|
||||
|
||||
# Check SVG to make sure it is correct
|
||||
set expected_svg [expr $svl / 8]
|
||||
gdb_test "print \$svg" " = ${expected_svg}"
|
||||
|
||||
# Check the value of SVCR.
|
||||
gdb_test "print \$svcr" [get_svcr_value $state]
|
||||
|
||||
# When we have any SVE or SSVE state, the FPSIMD registers will have
|
||||
# the same values as the SVE/SSVE Z registers.
|
||||
set fpsimd_byte 85
|
||||
if {$state == "sve" || $state == "ssve" || $state == "za_ssve"} {
|
||||
set fpsimd_byte 255
|
||||
}
|
||||
|
||||
set sve_byte 255
|
||||
if {$state == "fpsimd" || $state == "za"} {
|
||||
set sve_byte 85
|
||||
}
|
||||
|
||||
# Check FPSIMD registers
|
||||
check_fpsimd_regs $fpsimd_byte $state $vl $svl
|
||||
# Check SVE registers
|
||||
check_sve_regs $sve_byte $state $vl $svl
|
||||
# Check SME registers
|
||||
check_sme_regs 170 $state $svl
|
||||
}
|
90
gdb/testsuite/lib/aarch64-test-sme.c
Normal file
90
gdb/testsuite/lib/aarch64-test-sme.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* AArch64 SME feature check. This test serves as a way for the GDB testsuite
|
||||
to verify that a target supports SVE at runtime, and also reports data
|
||||
about the various supported SME streaming vector lengths. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef HWCAP2_SME
|
||||
#define HWCAP2_SME (1 << 23)
|
||||
#endif
|
||||
|
||||
#ifndef PR_SME_SET_VL
|
||||
#define PR_SME_SET_VL 63
|
||||
#define PR_SME_GET_VL 64
|
||||
#define PR_SME_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
static int get_svl_size ()
|
||||
{
|
||||
int res = prctl (PR_SME_GET_VL, 0, 0, 0, 0);
|
||||
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
return (res & PR_SME_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int set_svl_size (int new_svl)
|
||||
{
|
||||
if (prctl (PR_SME_SET_VL, new_svl, 0, 0, 0, 0) < 0)
|
||||
return -1;
|
||||
|
||||
if (get_svl_size () != new_svl)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dummy ()
|
||||
{
|
||||
}
|
||||
|
||||
#define SVL_MIN 16
|
||||
#define SVL_MAX 256
|
||||
#define SVL_INCREMENT_POWER 1
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
/* Number of supported SME streaming vector lengths. */
|
||||
size_t supported_svl_count = 0;
|
||||
/* Vector containing the various supported SME streaming vector lengths. */
|
||||
size_t supported_svl[5];
|
||||
|
||||
if (getauxval (AT_HWCAP) & HWCAP2_SME)
|
||||
{
|
||||
for (int svl = SVL_MIN; svl <= SVL_MAX; svl <<= SVL_INCREMENT_POWER)
|
||||
{
|
||||
if (set_svl_size (svl) == 0)
|
||||
{
|
||||
supported_svl[supported_svl_count] = svl;
|
||||
supported_svl_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* stop here */
|
||||
}
|
90
gdb/testsuite/lib/aarch64-test-sve.c
Normal file
90
gdb/testsuite/lib/aarch64-test-sve.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* AArch64 SVE feature check. This test serves as a way for the GDB testsuite
|
||||
to verify that a target supports SVE at runtime, and also reports data
|
||||
about the various supported SVE vector lengths. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef HWCAP_SVE
|
||||
#define HWCAP_SVE (1 << 22)
|
||||
#endif
|
||||
|
||||
#ifndef PR_SVE_SET_VL
|
||||
#define PR_SVE_SET_VL 50
|
||||
#define PR_SVE_GET_VL 51
|
||||
#define PR_SVE_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
static int get_vl_size ()
|
||||
{
|
||||
int res = prctl (PR_SVE_GET_VL, 0, 0, 0, 0);
|
||||
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
return (res & PR_SVE_VL_LEN_MASK);
|
||||
}
|
||||
|
||||
static int set_vl_size (int new_vl)
|
||||
{
|
||||
if (prctl (PR_SVE_SET_VL, new_vl, 0, 0, 0, 0) < 0)
|
||||
return -1;
|
||||
|
||||
if (get_vl_size () != new_vl)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dummy ()
|
||||
{
|
||||
}
|
||||
|
||||
#define VL_MIN 16
|
||||
#define VL_MAX 256
|
||||
#define VL_INCREMENT 16
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
/* Number of supported SVE vector lengths. */
|
||||
size_t supported_vl_count = 0;
|
||||
/* Vector containing the various supported SVE vector lengths. */
|
||||
size_t supported_vl[16];
|
||||
|
||||
if (getauxval (AT_HWCAP) & HWCAP_SVE)
|
||||
{
|
||||
for (int vl = VL_MIN; vl <= VL_MAX; vl += VL_INCREMENT)
|
||||
{
|
||||
if (set_vl_size (vl) == 0)
|
||||
{
|
||||
supported_vl[supported_vl_count] = vl;
|
||||
supported_vl_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* stop here */
|
||||
}
|
153
gdb/testsuite/lib/aarch64.exp
Normal file
153
gdb/testsuite/lib/aarch64.exp
Normal file
|
@ -0,0 +1,153 @@
|
|||
# Copyright 2023 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# Support routines for aarch64-specific tests
|
||||
|
||||
#
|
||||
# Return a regular expression that matches what gdb would print for a
|
||||
# 1-dimension vector containing ELEMENTS elements of value BYTE.
|
||||
#
|
||||
# The pattern is of the form "{BYTE <repeats ELEMENTS times>".
|
||||
#
|
||||
proc 1d_array_value_pattern { byte elements } {
|
||||
set brace_open "{"
|
||||
set brace_close "}"
|
||||
|
||||
append data $brace_open $byte
|
||||
if {$elements > 1} {
|
||||
append data " <repeats $elements times>"
|
||||
}
|
||||
append data $brace_close
|
||||
|
||||
verbose -log "1d_array_value_pattern Pattern string is..."
|
||||
verbose -log $data
|
||||
return $data
|
||||
}
|
||||
|
||||
#
|
||||
# Return a regular expression that matches what gdb would print for a
|
||||
# 2-dimension vector containing ROWS rows and COLUMNS columns of elements
|
||||
# of value BYTE.
|
||||
#
|
||||
# The pattern is of the form
|
||||
# "{{BYTE <repeats COLUMNS times>} <repeats ROWS times>}".
|
||||
#
|
||||
proc 2d_array_value_pattern { byte rows columns } {
|
||||
set brace_open "{"
|
||||
set brace_close "}"
|
||||
|
||||
append data $brace_open [1d_array_value_pattern $byte $columns]
|
||||
if {$rows > 1} {
|
||||
append data " <repeats $rows times>"
|
||||
}
|
||||
append data $brace_close
|
||||
|
||||
verbose -log "2d_array_value_pattern Pattern string is..."
|
||||
verbose -log $data
|
||||
return $data
|
||||
}
|
||||
|
||||
#
|
||||
# Initialize register NAME, a 1-dimension vector, with ELEMENTS elements
|
||||
# by setting all elements to BYTE. ELEMENTS is limited at 256 for memory
|
||||
# usage purposes.
|
||||
#
|
||||
# The initialization is of the form "{BYTE, BYTE, BYTE ...}".
|
||||
#
|
||||
proc initialize_1d_array { name byte elements } {
|
||||
set brace_open "{"
|
||||
set brace_close "}"
|
||||
|
||||
append data $brace_open
|
||||
|
||||
# Build the assignment in a single shot.
|
||||
for {set element 0} {$element < $elements} {incr element} {
|
||||
# Construct the initializer by appending elements to it.
|
||||
append data $byte
|
||||
|
||||
# If this isn't the last element, add a comma.
|
||||
if {[expr $element + 1] < $elements} {
|
||||
append data ", "
|
||||
}
|
||||
}
|
||||
append data $brace_close
|
||||
|
||||
verbose -log "initialization string is..."
|
||||
verbose -log $data
|
||||
gdb_test_no_output "set $name = $data" "write to $name"
|
||||
}
|
||||
|
||||
#
|
||||
# Return an initializer string for a 2-dimension vector with ROWS rows and
|
||||
# COLUMNS columns, initializing all elements to BYTE for register NAME.
|
||||
#
|
||||
# COLUMNS is limited to 256 elements for memory usage purposes.
|
||||
#
|
||||
# The initialization is of the form "{{BYTE, BYTE}, ..., {BYTE, BYTE}}}".
|
||||
#
|
||||
proc initialize_2d_array { name byte rows columns } {
|
||||
set brace_open "{"
|
||||
set brace_close "}"
|
||||
|
||||
if {[expr $rows * $columns] <= 256} {
|
||||
# Build the assignment in a single shot, as we have a maximum of 256
|
||||
# elements.
|
||||
for {set row 0} {$row < $rows} {incr row} {
|
||||
append data $brace_open
|
||||
for {set column 0} {$column < $columns} {incr column} {
|
||||
# Construct the initializer by appending elements to it.
|
||||
append data $byte
|
||||
|
||||
# If this isn't the last column, add a comma.
|
||||
if {[expr $column + 1] < $columns} {
|
||||
append data ", "
|
||||
}
|
||||
}
|
||||
|
||||
append data $brace_close
|
||||
|
||||
# If this isn't the last row, add a comma.
|
||||
if {[expr $row + 1] < $rows} {
|
||||
append data ","
|
||||
}
|
||||
}
|
||||
|
||||
set data $brace_open$data
|
||||
set data $data$brace_close
|
||||
|
||||
verbose -log "initialization string is..."
|
||||
verbose -log $data
|
||||
gdb_test_no_output "set $name = $data" "write to $name"
|
||||
} else {
|
||||
# There are too many elements to initialize (more than 256), so we
|
||||
# will do the initialization row by row.
|
||||
for {set row 0} {$row < $rows} {incr row} {
|
||||
initialize_1d_array "$name\[$row\]" $byte $columns
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Validate the values of the FPSIMD registers.
|
||||
#
|
||||
proc check_fpsimd_regs { byte state vl svl} {
|
||||
set fpsimd_pattern [string_to_regexp [1d_array_value_pattern $byte 16]]
|
||||
|
||||
for {set number 0} {$number < 32} {incr number} {
|
||||
set register_name "\$v${number}\.b\.u"
|
||||
gdb_test "print sizeof $register_name" " = 16"
|
||||
gdb_test "print $register_name" $fpsimd_pattern
|
||||
}
|
||||
}
|
|
@ -4152,10 +4152,259 @@ gdb_caching_proc allow_aarch64_sve_tests {} {
|
|||
gdb_exit
|
||||
remote_file build delete $obj
|
||||
|
||||
# While testing for SVE support, also discover all the supported vector
|
||||
# length values.
|
||||
aarch64_initialize_sve_information
|
||||
|
||||
verbose "$me: returning $allow_sve_tests" 2
|
||||
return $allow_sve_tests
|
||||
}
|
||||
|
||||
# Assuming SVE is supported by the target, run some checks to determine all
|
||||
# the supported vector length values and return an array containing all of those
|
||||
# values. Since this is a gdb_caching_proc, this proc will only be executed
|
||||
# once.
|
||||
#
|
||||
# To check if a particular SVE vector length is supported, the following code
|
||||
# can be used. For instance, for vl == 16:
|
||||
#
|
||||
# if {[aarch64_supports_sve_vl 16]} {
|
||||
# verbose -log "SVE vector length 16 is supported."
|
||||
# }
|
||||
#
|
||||
# This procedure should NEVER be called by hand, as it reinitializes the GDB
|
||||
# session and will derail a test. This should be called automatically as part
|
||||
# of the SVE support test routine allow_aarch64_sve_tests. Users should
|
||||
# restrict themselves to calling the helper proc aarch64_supports_sve_vl.
|
||||
|
||||
gdb_caching_proc aarch64_initialize_sve_information { } {
|
||||
global srcdir
|
||||
|
||||
set src "${srcdir}/lib/aarch64-test-sve.c"
|
||||
set test_exec [standard_temp_file "aarch64-test-sve.x"]
|
||||
set compile_flags "{additional_flags=-march=armv8-a+sve}"
|
||||
array set supported_vl {}
|
||||
|
||||
# Compile the SVE vector length test.
|
||||
set result [gdb_compile $src $test_exec executable [list debug ${compile_flags} nowarnings]]
|
||||
|
||||
if {$result != ""} {
|
||||
verbose -log "Failed to compile SVE information gathering test."
|
||||
return [array get supported_vl]
|
||||
}
|
||||
|
||||
clean_restart $test_exec
|
||||
|
||||
if {![runto_main]} {
|
||||
return [array get supported_vl]
|
||||
}
|
||||
|
||||
set stop_breakpoint "stop here"
|
||||
gdb_breakpoint [gdb_get_line_number $stop_breakpoint $src]
|
||||
gdb_continue_to_breakpoint $stop_breakpoint
|
||||
|
||||
# Go through the data and extract the supported SVE vector lengths.
|
||||
set vl_count [get_valueof "" "supported_vl_count" "0" \
|
||||
"fetch value of supported_vl_count"]
|
||||
verbose -log "Found $vl_count supported SVE vector length values"
|
||||
|
||||
for {set vl_index 0} {$vl_index < $vl_count} {incr vl_index} {
|
||||
set test_vl [get_valueof "" "supported_vl\[$vl_index\]" "0" \
|
||||
"fetch value of supported_vl\[$vl_index\]"]
|
||||
|
||||
# Mark this vector length as supported.
|
||||
if {$test_vl != 0} {
|
||||
verbose -log "Found supported SVE vector length $test_vl"
|
||||
set supported_vl($test_vl) 1
|
||||
}
|
||||
}
|
||||
|
||||
gdb_exit
|
||||
verbose -log "Cleaning up"
|
||||
remote_file build delete $test_exec
|
||||
|
||||
verbose -log "Done gathering information about AArch64 SVE vector lengths."
|
||||
|
||||
# Return the array containing all of the supported SVE vl values.
|
||||
return [array get supported_vl]
|
||||
}
|
||||
|
||||
#
|
||||
# Return 1 if the target supports SVE vl LENGTH
|
||||
# Return 0 otherwise.
|
||||
#
|
||||
|
||||
proc aarch64_supports_sve_vl { length } {
|
||||
|
||||
# Fetch the cached array of supported SVE vl values.
|
||||
array set supported_vl [aarch64_initialize_sve_information]
|
||||
|
||||
# Do we have the global values cached?
|
||||
if {![info exists supported_vl($length)]} {
|
||||
verbose -log "Target does not support SVE vl $length"
|
||||
return 0
|
||||
}
|
||||
|
||||
# The target supports SVE vl LENGTH.
|
||||
return 1
|
||||
}
|
||||
|
||||
# Run a test on the target to see if it supports Aarch64 SME extensions.
|
||||
# Return 0 if so, 1 if it does not. Note this causes a restart of GDB.
|
||||
|
||||
gdb_caching_proc allow_aarch64_sme_tests {} {
|
||||
global srcdir subdir gdb_prompt inferior_exited_re
|
||||
|
||||
set me "allow_aarch64_sme_tests"
|
||||
|
||||
if { ![is_aarch64_target]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
set compile_flags "{additional_flags=-march=armv8-a+sme}"
|
||||
|
||||
# Compile a test program containing SME instructions.
|
||||
set src {
|
||||
int main() {
|
||||
asm volatile ("smstart za");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if {![gdb_simple_compile $me $src executable $compile_flags]} {
|
||||
# Try again, but with a raw hex instruction so we don't rely on
|
||||
# assembler support for SME.
|
||||
|
||||
set compile_flags "{additional_flags=-march=armv8-a}"
|
||||
|
||||
# Compile a test program containing SME instructions.
|
||||
set src {
|
||||
int main() {
|
||||
asm volatile (".word 0xD503457F");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if {![gdb_simple_compile $me $src executable $compile_flags]} {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
# Compilation succeeded so now run it via gdb.
|
||||
clean_restart $obj
|
||||
gdb_run_cmd
|
||||
gdb_expect {
|
||||
-re ".*Illegal instruction.*${gdb_prompt} $" {
|
||||
verbose -log "\n$me sme support not detected"
|
||||
set allow_sme_tests 0
|
||||
}
|
||||
-re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
|
||||
verbose -log "\n$me: sme support detected"
|
||||
set allow_sme_tests 1
|
||||
}
|
||||
default {
|
||||
warning "\n$me: default case taken"
|
||||
set allow_sme_tests 0
|
||||
}
|
||||
}
|
||||
gdb_exit
|
||||
remote_file build delete $obj
|
||||
|
||||
# While testing for SME support, also discover all the supported vector
|
||||
# length values.
|
||||
aarch64_initialize_sme_information
|
||||
|
||||
verbose "$me: returning $allow_sme_tests" 2
|
||||
return $allow_sme_tests
|
||||
}
|
||||
|
||||
# Assuming SME is supported by the target, run some checks to determine all
|
||||
# the supported streaming vector length values and return an array containing
|
||||
# all of those values. Since this is a gdb_caching_proc, this proc will only
|
||||
# be executed once.
|
||||
#
|
||||
# To check if a particular SME streaming vector length is supported, the
|
||||
# following code can be used. For instance, for svl == 32:
|
||||
#
|
||||
# if {[aarch64_supports_sme_svl 32]} {
|
||||
# verbose -log "SME streaming vector length 32 is supported."
|
||||
# }
|
||||
#
|
||||
# This procedure should NEVER be called by hand, as it reinitializes the GDB
|
||||
# session and will derail a test. This should be called automatically as part
|
||||
# of the SME support test routine allow_aarch64_sme_tests. Users should
|
||||
# restrict themselves to calling the helper proc aarch64_supports_sme_svl.
|
||||
|
||||
gdb_caching_proc aarch64_initialize_sme_information { } {
|
||||
global srcdir
|
||||
|
||||
set src "${srcdir}/lib/aarch64-test-sme.c"
|
||||
set test_exec [standard_temp_file "aarch64-test-sme.x"]
|
||||
set compile_flags "{additional_flags=-march=armv8-a+sme}"
|
||||
array set supported_svl {}
|
||||
|
||||
# Compile the SME vector length test.
|
||||
set result [gdb_compile $src $test_exec executable [list debug ${compile_flags} nowarnings]]
|
||||
|
||||
if {$result != ""} {
|
||||
verbose -log "Failed to compile SME information gathering test."
|
||||
return [array get supported_svl]
|
||||
}
|
||||
|
||||
clean_restart $test_exec
|
||||
|
||||
if {![runto_main]} {
|
||||
return [array get supported_svl]
|
||||
}
|
||||
|
||||
set stop_breakpoint "stop here"
|
||||
gdb_breakpoint [gdb_get_line_number $stop_breakpoint $src]
|
||||
gdb_continue_to_breakpoint $stop_breakpoint
|
||||
|
||||
# Go through the data and extract the supported SME vector lengths.
|
||||
set svl_count [get_valueof "" "supported_svl_count" "0" \
|
||||
"fetch value of supported_svl_count"]
|
||||
verbose -log "Found $svl_count supported SME vector length values"
|
||||
|
||||
for {set svl_index 0} {$svl_index < $svl_count} {incr svl_index} {
|
||||
set test_svl [get_valueof "" "supported_svl\[$svl_index\]" "0" \
|
||||
"fetch value of supported_svl\[$svl_index\]"]
|
||||
|
||||
# Mark this streaming vector length as supported.
|
||||
if {$test_svl != 0} {
|
||||
verbose -log "Found supported SME vector length $test_svl"
|
||||
set supported_svl($test_svl) 1
|
||||
}
|
||||
}
|
||||
|
||||
gdb_exit
|
||||
verbose -log "Cleaning up"
|
||||
remote_file build delete $test_exec
|
||||
|
||||
verbose -log "Done gathering information about AArch64 SME vector lengths."
|
||||
|
||||
# Return the array containing all of the supported SME svl values.
|
||||
return [array get supported_svl]
|
||||
}
|
||||
|
||||
#
|
||||
# Return 1 if the target supports SME svl LENGTH
|
||||
# Return 0 otherwise.
|
||||
#
|
||||
|
||||
proc aarch64_supports_sme_svl { length } {
|
||||
|
||||
# Fetch the cached array of supported SME svl values.
|
||||
array set supported_svl [aarch64_initialize_sme_information]
|
||||
|
||||
# Do we have the global values cached?
|
||||
if {![info exists supported_svl($length)]} {
|
||||
verbose -log "Target does not support SME svl $length"
|
||||
return 0
|
||||
}
|
||||
|
||||
# The target supports SME svl LENGTH.
|
||||
return 1
|
||||
}
|
||||
|
||||
# A helper that compiles a test case to see if __int128 is supported.
|
||||
proc gdb_int128_helper {lang} {
|
||||
|
|
Loading…
Add table
Reference in a new issue