Home | History | Annotate | Line # | Download | only in gdb.arch
      1 # Copyright (C) 2023-2024 Free Software Foundation, Inc.
      2 
      3 # This program is free software; you can redistribute it and/or modify
      4 # it under the terms of the GNU General Public License as published by
      5 # the Free Software Foundation; either version 3 of the License, or
      6 # (at your option) any later version.
      7 #
      8 # This program is distributed in the hope that it will be useful,
      9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 # GNU General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU General Public License
     14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 
     16 # Exercise reading/writing ZA registers when there is ZA state.
     17 # Exercise reading/writing to ZT0 when there is ZA state available.
     18 
     19 load_lib aarch64-scalable.exp
     20 
     21 require is_aarch64_target
     22 require allow_aarch64_sve_tests
     23 require allow_aarch64_sme_tests
     24 
     25 # Remote targets can't communicate vector length (vl or svl) changes
     26 # to GDB via the RSP.
     27 require !gdb_protocol_is_remote
     28 
     29 #
     30 # Cycle through all ZA registers and pseudo-registers and validate that their
     31 # contents are available for vector length SVL.
     32 #
     33 # Make sure reading/writing to ZA registers work as expected.
     34 #
     35 proc check_regs { mode vl svl } {
     36     # Check VG to make sure it is correct
     37     set expected_vg [expr $vl / 8]
     38     gdb_test "print \$vg" "= ${expected_vg}"
     39 
     40     # Check SVG to make sure it is correct
     41     set expected_svg [expr $svl / 8]
     42     gdb_test "print \$svg" "= ${expected_svg}"
     43 
     44     # If svl is adjusted by prctl, we will have ZA enabled.  If gdb is
     45     # adjusting svl, ZA will not be enabled by default.  It will only be
     46     # enabled when ZA is written to.
     47     set za_state "= \\\[ ZA \\\]"
     48     if {$mode == "gdb"} {
     49 	set za_state "= \\\[ \\\]"
     50     }
     51 
     52     # Check SVCR.
     53     if [gdb_test "print \$svcr" $za_state "svcr before assignments" ] {
     54 	fail "incorrect za state"
     55 	return -1
     56     }
     57 
     58     # Check the size of ZA.
     59     set expected_za_size [expr $svl * $svl]
     60     gdb_test "print sizeof \$za" " = $expected_za_size"
     61 
     62     # Check the size of Z0.
     63     gdb_test "print sizeof \$z0" " = $vl"
     64 
     65     # Exercise reading/writing from/to ZA.
     66     initialize_2d_array "\$za" 255 $svl $svl
     67     set pattern [string_to_regexp [2d_array_value_pattern 255 $svl $svl]]
     68     gdb_test "print \$za" " = $pattern" "read back from za"
     69 
     70     # Exercise reading/writing from/to the tile pseudo-registers.
     71     set last_tile 1
     72     set expected_size [expr $svl * $svl]
     73     set tile_svl $svl
     74     set za_state "= \\\[ ZA \\\]"
     75     foreach_with_prefix granularity {"b" "h" "s" "d" "q"} {
     76 	for {set tile 0} {$tile < $last_tile} {incr tile} {
     77 	    set register_name "\$za${tile}${granularity}"
     78 
     79 	    # Test the size.
     80 	    gdb_test "print sizeof ${register_name}" " = ${expected_size}"
     81 
     82 	    # Test reading/writing
     83 	    initialize_2d_array $register_name 255 $tile_svl $tile_svl
     84 
     85 	    # Make sure we have ZA state.
     86 	    if [gdb_test "print \$svcr" $za_state "svcr after assignment to ${register_name}" ] {
     87 		fail "incorrect za state"
     88 		return -1
     89 	    }
     90 
     91 	    set pattern [string_to_regexp [2d_array_value_pattern 255 $tile_svl $tile_svl]]
     92 	    gdb_test "print $register_name" " = $pattern" "read back from $register_name"
     93 	}
     94 	set last_tile [expr $last_tile * 2]
     95 	set expected_size [expr $expected_size / 2]
     96 	set tile_svl [expr $tile_svl / 2]
     97     }
     98 
     99     # Exercise reading/writing from/to the tile slice pseudo-registers.
    100     set last_tile 1
    101     set last_slice $svl
    102     set expected_size $svl
    103     set num_elements $svl
    104     foreach_with_prefix granularity {"b" "h" "s" "d" "q"} {
    105 	for {set tile 0} {$tile < $last_tile} {incr tile} {
    106 	    for {set slice 0} {$slice < $last_slice} {incr slice} {
    107 		foreach_with_prefix direction {"h" "v"} {
    108 		    set register_name "\$za${tile}${direction}${granularity}${slice}"
    109 
    110 		    # Test the size.
    111 		    gdb_test "print sizeof ${register_name}" " = ${expected_size}"
    112 
    113 		    # Test reading/writing
    114 		    initialize_1d_array $register_name 255 $num_elements
    115 
    116 		    # Make sure we have ZA state.
    117 		    if [gdb_test "print \$svcr" $za_state "svcr after assignment of ${register_name}" ] {
    118 			fail "incorrect za state"
    119 			return -1
    120 		    }
    121 
    122 		    set pattern [string_to_regexp [1d_array_value_pattern 255 $num_elements]]
    123 		    gdb_test "print $register_name" " = $pattern" "read back from $register_name"
    124 		}
    125 	    }
    126 	}
    127 	set last_tile [expr $last_tile * 2]
    128 	set last_slice [expr ($last_slice / 2)]
    129 	set num_elements [expr $num_elements / 2]
    130     }
    131 
    132     # Exercise reading/writing from/to SME2 registers.
    133     if [is_sme2_available] {
    134       # The target supports SME2.
    135       set zt_size 64
    136       gdb_test "print sizeof \$zt0" " = $zt_size"
    137 
    138       # Initially, when ZA is activated, ZT0 will be all zeroes.
    139       set zt_pattern [string_to_regexp [1d_array_value_pattern 0 $zt_size]]
    140       gdb_test "print \$zt0" " = $zt_pattern" "validate zeroed zt0"
    141 
    142       # Validate that writing to ZT0 does the right thing.
    143       initialize_1d_array "\$zt0" 255 $zt_size
    144       set zt_pattern [string_to_regexp [1d_array_value_pattern 255 $zt_size]]
    145       gdb_test "print \$zt0" " = $zt_pattern" "read back from zt0"
    146     }
    147 }
    148 
    149 #
    150 # Cycle through all ZA registers and pseudo-registers and validate their
    151 # contents.
    152 #
    153 proc test_sme_registers_available { id_start id_end } {
    154 
    155     set compile_flags {"debug" "macros"}
    156     lappend compile_flags "additional_flags=-DID_START=${id_start}"
    157     lappend compile_flags "additional_flags=-DID_END=${id_end}"
    158 
    159     standard_testfile ${::srcdir}/${::subdir}/aarch64-sme-regs-available.c
    160     set executable "${::testfile}-${id_start}-${id_end}"
    161     if {[prepare_for_testing "failed to prepare" ${executable} ${::srcfile} ${compile_flags}]} {
    162 	return -1
    163     }
    164     set binfile [standard_output_file ${executable}]
    165 
    166     if ![runto_main] {
    167 	untested "could not run to main"
    168 	return -1
    169     }
    170 
    171     gdb_test_no_output "set print repeats 1"
    172 
    173     set prctl_breakpoint "stop 1"
    174     gdb_breakpoint [gdb_get_line_number $prctl_breakpoint]
    175 
    176     for {set id $id_start} {$id <= $id_end} {incr id} {
    177 	set vl [test_id_to_vl $id]
    178 	set svl [test_id_to_svl $id]
    179 
    180 	set skip_unsupported 0
    181 	if {![aarch64_supports_sve_vl $vl]
    182 	    || ![aarch64_supports_sme_svl $svl]} {
    183 	    # We have a vector length or streaming vector length that
    184 	    # is not supported by this target.  Skip to the next iteration
    185 	    # since it is no use running tests for an unsupported vector
    186 	    # length.
    187 	    if {![aarch64_supports_sve_vl $vl]} {
    188 		verbose -log "SVE vector length $vl not supported."
    189 	    } elseif {![aarch64_supports_sme_svl $svl]} {
    190 		verbose -log "SME streaming vector length $svl not supported."
    191 	    }
    192 	    verbose -log "Skipping test."
    193 	    set skip_unsupported 1
    194 	}
    195 
    196 	set mode "prctl"
    197 	with_test_prefix "$mode, vl=${vl} svl=${svl}" {
    198 	    # If the SVE or SME vector length is not supported, just skip
    199 	    # these next tests.
    200 	    if {$skip_unsupported} {
    201 		untested "unsupported configuration on target"
    202 		continue
    203 	    }
    204 
    205 	    # Run the program until it has adjusted svl.
    206 	    gdb_continue_to_breakpoint $prctl_breakpoint
    207 	    check_regs $mode $vl $svl
    208 	}
    209     }
    210 
    211     set non_prctl_breakpoint "stop 2"
    212     gdb_breakpoint [gdb_get_line_number $non_prctl_breakpoint]
    213 
    214     for {set id $id_start} {$id <= $id_end} {incr id} {
    215 	set vl [test_id_to_vl $id]
    216 	set svl [test_id_to_svl $id]
    217 
    218 	set skip_unsupported 0
    219 	if {![aarch64_supports_sve_vl $vl]
    220 	    || ![aarch64_supports_sme_svl $svl]} {
    221 	    # We have a vector length or streaming vector length that
    222 	    # is not supported by this target.  Skip to the next iteration
    223 	    # since it is no use running tests for an unsupported vector
    224 	    # length.
    225 	    if {![aarch64_supports_sve_vl $vl]} {
    226 		verbose -log "SVE vector length $vl not supported."
    227 	    } elseif {![aarch64_supports_sme_svl $svl]} {
    228 		verbose -log "SME streaming vector length $svl not supported."
    229 	    }
    230 	    verbose -log "Skipping test."
    231 	    set skip_unsupported 1
    232 	}
    233 
    234 	set mode "gdb"
    235 	with_test_prefix "$mode, vl=${vl} svl=${svl}" {
    236 	    # If the SVE or SME vector length is not supported, just skip
    237 	    # these next tests.
    238 	    if {$skip_unsupported} {
    239 		untested "unsupported configuration on target"
    240 		continue
    241 	    }
    242 
    243 	    # Run the program until we stop at the point where gdb should
    244 	    # adjust the SVE and SME vector lengths.
    245 	    gdb_continue_to_breakpoint $non_prctl_breakpoint
    246 
    247 	    # Adjust svl via gdb.
    248 	    set vg_value [expr $vl / 8]
    249 	    set svg_value [expr $svl / 8]
    250 	    gdb_test_no_output "set \$vg = ${vg_value}"
    251 	    gdb_test_no_output "set \$svg = ${svg_value}"
    252 
    253 	    check_regs $mode $vl $svl
    254 	}
    255     }
    256 }
    257 
    258 test_sme_registers_available $id_start $id_end
    259