Message ID | 20240510052408.2173579-4-thiago.bauermann@linaro.org |
---|---|
State | New |
Headers | show |
Series | Add support for AArch64 MOPS instructions | expand |
Thanks. Just a nit below. I'll set something up on my end to give these tests a try. On 5/10/24 06:24, Thiago Jung Bauermann wrote: > Test behaviour of watchpoints triggered by MOPS instructions. This test > is similar to gdb.base/memops-watchpoint.exp, but specifically for MOPS > instructions rather than whatever instructions are used in the libc's > implementation of memset/memcpy/memmove. > > There's a separate watched variable for each set of instructions so that > the testcase can test whether GDB correctly identified the watchpoint > that triggered in each case. > --- > .../gdb.arch/aarch64-mops-watchpoint.c | 66 ++++++++++++++++ > .../gdb.arch/aarch64-mops-watchpoint.exp | 79 +++++++++++++++++++ > gdb/testsuite/lib/gdb.exp | 61 ++++++++++++++ > 3 files changed, 206 insertions(+) > create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c > create mode 100644 gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp > > No change since v1. > > diff --git a/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c > new file mode 100644 > index 000000000000..b981f033d210 > --- /dev/null > +++ b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c > @@ -0,0 +1,66 @@ > +/* This test program is part of GDB, the GNU debugger. > + > + Copyright 2024 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/>. */ > + > +int > +main (void) > +{ > + char source[40] __attribute__ ((aligned (8))) > + = "This is a relatively long string..."; > + char a[40] __attribute__ ((aligned (8))) > + = "String to be overwritten with zeroes"; > + char b[40] __attribute__ ((aligned (8))) > + = "Another string to be memcopied..."; > + char c[40] __attribute__ ((aligned (8))) > + = "Another string to be memmoved..."; > + char *p, *q; > + long size, zero; > + > + /* Break here. */ > + p = a; > + size = sizeof (a); > + zero = 0; > + /* memset implemented in MOPS instructions. */ > + __asm__ volatile ("setp [%0]!, %1!, %2\n\t" > + "setm [%0]!, %1!, %2\n\t" > + "sete [%0]!, %1!, %2\n\t" > + : "+&r"(p), "+&r"(size) > + : "r"(zero) > + : "memory"); > + > + p = b; > + q = source; > + size = sizeof (b); > + /* memmove implemented in MOPS instructions. */ > + __asm__ volatile ("cpyp [%0]!, [%1]!, %2!\n\t" > + "cpym [%0]!, [%1]!, %2!\n\t" > + "cpye [%0]!, [%1]!, %2!\n\t" > + : "+&r" (p), "+&r" (q), "+&r" (size) > + : > + : "memory"); > + p = c; > + q = source; > + size = sizeof (c); > + /* memcpy implemented in MOPS instructions. */ > + __asm__ volatile ("cpyfp [%0]!, [%1]!, %2!\n\t" > + "cpyfm [%0]!, [%1]!, %2!\n\t" > + "cpyfe [%0]!, [%1]!, %2!\n\t" > + : "+&r" (p), "+&r" (q), "+&r" (size) > + : > + : "memory"); > + > + return 0; > +} > diff --git a/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp > new file mode 100644 > index 000000000000..9e210602d800 > --- /dev/null > +++ b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp > @@ -0,0 +1,79 @@ > +# Copyright 2024 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/>. > + > +# Test a binary that uses MOPS (Memory Operations) instructions. > +# This test is similar to gdb.base/memops-watchpoint.exp, but specifically > +# tests MOPS instructions rather than whatever instructions are used in the > +# system libc's implementation of memset/memcpy/memmove. > + > +require allow_hw_watchpoint_tests allow_aarch64_mops_tests > + > +standard_testfile > + > +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ > + [list debug additional_flags=-march=armv9.3-a]] } { > + return -1 > +} > + > +set linespec ${srcfile}:[gdb_get_line_number "Break here"] > +if ![runto ${linespec}] { > + return -1 > +} > + > +gdb_test "watch -location a\[28\]" \ > + "(Hardware w|W)atchpoint ${decimal}: -location a\\\[28\\\]" \ > + "set watch on a" > +gdb_test "watch -location b\[28\]" \ > + "(Hardware w|W)atchpoint ${decimal}: -location b\\\[28\\\]" \ > + "set watchpoint on b" > +gdb_test "watch -location c\[28\]" \ > + "(Hardware w|W)atchpoint ${decimal}: -location c\\\[28\\\]" \ > + "set watchpoint on c" > + > +gdb_test "continue" \ > + [multi_line \ > + "Continuing\\." \ > + "" \ > + "Hardware watchpoint ${decimal}: -location a\\\[28\\\]" \ > + "" \ > + "Old value = 104 'h'" \ > + "New value = 0 '\\\\000'" \ > + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ > + "${decimal}\\s+__asm__ volatile \\(\"setp.*\\\\n\\\\t\""] \ > + "continue until set watchpoint hits" > + > +gdb_test "continue" \ > + [multi_line \ > + "Continuing\\." \ > + "" \ > + "Hardware watchpoint ${decimal}: -location b\\\[28\\\]" \ > + "" \ > + "Old value = 101 'e'" \ > + "New value = 114 'r'" \ > + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ > + "${decimal}\\s+__asm__ volatile \\(\"cpyp.*\\\\n\\\\t\""] \ > + "continue until cpy watchpoint hits" > + > +gdb_test "continue" \ > + [multi_line \ > + "Continuing\\." \ > + "" \ > + "Hardware watchpoint ${decimal}: -location c\\\[28\\\]" \ > + "" \ > + "Old value = 100 'd'" \ > + "New value = 114 'r'" \ > + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ > + "${decimal}\\s+__asm__ volatile \\(\"cpyfp.*\\\\n\\\\t\""] \ > + "continue until cpyf watchpoint hits" > diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp > index 0d78691c381b..25b272fdaabc 100644 > --- a/gdb/testsuite/lib/gdb.exp > +++ b/gdb/testsuite/lib/gdb.exp > @@ -4497,6 +4497,67 @@ proc aarch64_supports_sme_svl { length } { > return 1 > } > > +# Run a test on the target to see if it supports Aarch64 MOPS (Memory s/Aarch64/AArch64 > +# Operations) extensions. Return 0 if so, 1 if it does not. Note this causes > +# a restart of GDB. > + > +gdb_caching_proc allow_aarch64_mops_tests {} { > + global srcdir subdir gdb_prompt inferior_exited_re > + > + set me "allow_aarch64_mops_tests" > + > + if { ![is_aarch64_target]} { > + return 0 > + } > + > + # ARMv9.3-A contains the MOPS extension. The test program doesn't use it, > + # but take the opportunity to check whether the toolchain knows about MOPS. > + set compile_flags "{additional_flags=-march=armv9.3-a}" > + > + # Compile a program that tests the MOPS feature. > + set src { > + #include <stdbool.h> > + #include <sys/auxv.h> > + > + #ifndef HWCAP2_MOPS > + #define HWCAP2_MOPS (1UL << 43) > + #endif > + > + int main() { > + bool mops_supported = getauxval (AT_HWCAP2) & HWCAP2_MOPS; > + > + return !mops_supported; > + } > + } > + > + 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 ".*$inferior_exited_re with code 01.*${gdb_prompt} $" { > + verbose -log "\n$me mops support not detected" > + set allow_mops_tests 0 > + } > + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" { > + verbose -log "\n$me: mops support detected" > + set allow_mops_tests 1 > + } > + default { > + warning "\n$me: default case taken" > + set allow_mops_tests 0 > + } > + } > + gdb_exit > + remote_file build delete $obj > + > + verbose "$me: returning $allow_mops_tests" 2 > + return $allow_mops_tests > +} > + > # A helper that compiles a test case to see if __int128 is supported. > proc gdb_int128_helper {lang} { > return [gdb_can_simple_compile "i128-for-$lang" {
Luis Machado <luis.machado@arm.com> writes: > Thanks. > > Just a nit below. I'll set something up on my end to give these tests a try. Thanks! > On 5/10/24 06:24, Thiago Jung Bauermann wrote: >> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp >> index 0d78691c381b..25b272fdaabc 100644 >> --- a/gdb/testsuite/lib/gdb.exp >> +++ b/gdb/testsuite/lib/gdb.exp >> @@ -4497,6 +4497,67 @@ proc aarch64_supports_sme_svl { length } { >> return 1 >> } >> >> +# Run a test on the target to see if it supports Aarch64 MOPS (Memory > > s/Aarch64/AArch64 Thanks. Fixed in v4. >> +# Operations) extensions. Return 0 if so, 1 if it does not. Note this causes >> +# a restart of GDB. >> + >> +gdb_caching_proc allow_aarch64_mops_tests {} { >> + global srcdir subdir gdb_prompt inferior_exited_re >> + >> + set me "allow_aarch64_mops_tests" >> + >> + if { ![is_aarch64_target]} { >> + return 0 >> + }
diff --git a/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c new file mode 100644 index 000000000000..b981f033d210 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c @@ -0,0 +1,66 @@ +/* This test program is part of GDB, the GNU debugger. + + Copyright 2024 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/>. */ + +int +main (void) +{ + char source[40] __attribute__ ((aligned (8))) + = "This is a relatively long string..."; + char a[40] __attribute__ ((aligned (8))) + = "String to be overwritten with zeroes"; + char b[40] __attribute__ ((aligned (8))) + = "Another string to be memcopied..."; + char c[40] __attribute__ ((aligned (8))) + = "Another string to be memmoved..."; + char *p, *q; + long size, zero; + + /* Break here. */ + p = a; + size = sizeof (a); + zero = 0; + /* memset implemented in MOPS instructions. */ + __asm__ volatile ("setp [%0]!, %1!, %2\n\t" + "setm [%0]!, %1!, %2\n\t" + "sete [%0]!, %1!, %2\n\t" + : "+&r"(p), "+&r"(size) + : "r"(zero) + : "memory"); + + p = b; + q = source; + size = sizeof (b); + /* memmove implemented in MOPS instructions. */ + __asm__ volatile ("cpyp [%0]!, [%1]!, %2!\n\t" + "cpym [%0]!, [%1]!, %2!\n\t" + "cpye [%0]!, [%1]!, %2!\n\t" + : "+&r" (p), "+&r" (q), "+&r" (size) + : + : "memory"); + p = c; + q = source; + size = sizeof (c); + /* memcpy implemented in MOPS instructions. */ + __asm__ volatile ("cpyfp [%0]!, [%1]!, %2!\n\t" + "cpyfm [%0]!, [%1]!, %2!\n\t" + "cpyfe [%0]!, [%1]!, %2!\n\t" + : "+&r" (p), "+&r" (q), "+&r" (size) + : + : "memory"); + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp new file mode 100644 index 000000000000..9e210602d800 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp @@ -0,0 +1,79 @@ +# Copyright 2024 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/>. + +# Test a binary that uses MOPS (Memory Operations) instructions. +# This test is similar to gdb.base/memops-watchpoint.exp, but specifically +# tests MOPS instructions rather than whatever instructions are used in the +# system libc's implementation of memset/memcpy/memmove. + +require allow_hw_watchpoint_tests allow_aarch64_mops_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + [list debug additional_flags=-march=armv9.3-a]] } { + return -1 +} + +set linespec ${srcfile}:[gdb_get_line_number "Break here"] +if ![runto ${linespec}] { + return -1 +} + +gdb_test "watch -location a\[28\]" \ + "(Hardware w|W)atchpoint ${decimal}: -location a\\\[28\\\]" \ + "set watch on a" +gdb_test "watch -location b\[28\]" \ + "(Hardware w|W)atchpoint ${decimal}: -location b\\\[28\\\]" \ + "set watchpoint on b" +gdb_test "watch -location c\[28\]" \ + "(Hardware w|W)atchpoint ${decimal}: -location c\\\[28\\\]" \ + "set watchpoint on c" + +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Hardware watchpoint ${decimal}: -location a\\\[28\\\]" \ + "" \ + "Old value = 104 'h'" \ + "New value = 0 '\\\\000'" \ + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ + "${decimal}\\s+__asm__ volatile \\(\"setp.*\\\\n\\\\t\""] \ + "continue until set watchpoint hits" + +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Hardware watchpoint ${decimal}: -location b\\\[28\\\]" \ + "" \ + "Old value = 101 'e'" \ + "New value = 114 'r'" \ + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ + "${decimal}\\s+__asm__ volatile \\(\"cpyp.*\\\\n\\\\t\""] \ + "continue until cpy watchpoint hits" + +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Hardware watchpoint ${decimal}: -location c\\\[28\\\]" \ + "" \ + "Old value = 100 'd'" \ + "New value = 114 'r'" \ + "$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \ + "${decimal}\\s+__asm__ volatile \\(\"cpyfp.*\\\\n\\\\t\""] \ + "continue until cpyf watchpoint hits" diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 0d78691c381b..25b272fdaabc 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -4497,6 +4497,67 @@ proc aarch64_supports_sme_svl { length } { return 1 } +# Run a test on the target to see if it supports Aarch64 MOPS (Memory +# Operations) extensions. Return 0 if so, 1 if it does not. Note this causes +# a restart of GDB. + +gdb_caching_proc allow_aarch64_mops_tests {} { + global srcdir subdir gdb_prompt inferior_exited_re + + set me "allow_aarch64_mops_tests" + + if { ![is_aarch64_target]} { + return 0 + } + + # ARMv9.3-A contains the MOPS extension. The test program doesn't use it, + # but take the opportunity to check whether the toolchain knows about MOPS. + set compile_flags "{additional_flags=-march=armv9.3-a}" + + # Compile a program that tests the MOPS feature. + set src { + #include <stdbool.h> + #include <sys/auxv.h> + + #ifndef HWCAP2_MOPS + #define HWCAP2_MOPS (1UL << 43) + #endif + + int main() { + bool mops_supported = getauxval (AT_HWCAP2) & HWCAP2_MOPS; + + return !mops_supported; + } + } + + 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 ".*$inferior_exited_re with code 01.*${gdb_prompt} $" { + verbose -log "\n$me mops support not detected" + set allow_mops_tests 0 + } + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" { + verbose -log "\n$me: mops support detected" + set allow_mops_tests 1 + } + default { + warning "\n$me: default case taken" + set allow_mops_tests 0 + } + } + gdb_exit + remote_file build delete $obj + + verbose "$me: returning $allow_mops_tests" 2 + return $allow_mops_tests +} + # A helper that compiles a test case to see if __int128 is supported. proc gdb_int128_helper {lang} { return [gdb_can_simple_compile "i128-for-$lang" {