1 # Copyright 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 # Support routines for aarch64 scalable extension tests 17 18 # Load generic aarch64 test dependencies. 19 load_lib aarch64.exp 20 21 # 22 # Return a regular expression that matches what gdb would print for a 23 # SVE Z register of length VL in state STATE. The Z register should be filled 24 # with BYTE_SVE and the FPSIMD registers should be filled with BYTE_FPSIMD. 25 # 26 # The pattern is of the form 27 # 28 # {BYTE_FPSIMD <repeats 16 times>} 29 # 30 # or 31 # 32 # {BYTE_FPSIMD <repeats 16 times>, 0 <repeats ... times>} 33 # 34 # or 35 # 36 # {BYTE_SVE <repeats VL times>} 37 # 38 proc sve_value_pattern { state vl byte_fpsimd byte_sve } { 39 set brace_open "{" 40 set brace_close "}" 41 42 append data $brace_open 43 if { $state == "fpsimd" || $state == "za" } { 44 if { $vl > 16 } { 45 set sve_repeat_count [expr $vl - 16] 46 append data "$byte_fpsimd <repeats 16 times>, 0 <repeats $sve_repeat_count times>" 47 } else { 48 append data "$byte_fpsimd <repeats 16 times>" 49 } 50 } else { 51 append data "$byte_sve <repeats $vl times>" 52 } 53 append data $brace_close 54 55 verbose -log "sve_value_pattern pattern string is..." 56 verbose -log $data 57 return $data 58 } 59 60 # 61 # Return the SVCR value based on STATE. 62 # SVCR is only available when SME is available. 63 # 64 proc get_svcr_value { state } { 65 if { $state == "ssve" } { 66 return "= \\\[ SM \\\]" 67 } elseif { $state == "za" } { 68 return "= \\\[ ZA \\\]" 69 } elseif { $state == "za_ssve" } { 70 return "= \\\[ SM ZA \\\]" 71 } 72 73 return "= \\\[ \\\]" 74 } 75 76 # 77 # Return the state string based on STATE 78 # 79 proc state_id_to_state_string { state } { 80 if {$state == 0} { 81 return "fpsimd" 82 } elseif {$state == 1} { 83 return "sve" 84 } elseif {$state == 2} { 85 return "ssve" 86 } elseif {$state == 3} { 87 return "za" 88 } elseif {$state == 4} { 89 return "za_ssve" 90 } 91 } 92 93 # 94 # Given a test ID, return the string representing the register state. 95 # The state is one of fpsimd, sve, ssve, za and za_ssve. 96 # 97 proc test_id_to_state { id } { 98 set state [expr $id / 25] 99 100 return [state_id_to_state_string $state] 101 } 102 103 # 104 # Given a test ID, return the associated vector length. 105 # 106 proc test_id_to_vl { id } { 107 return [expr 16 << (($id / 5) % 5)] 108 } 109 110 # 111 # Given a test ID, return the associated streaming vector length. 112 # 113 proc test_id_to_svl { id } { 114 return [expr 16 << ($id % 5)] 115 } 116 117 # 118 # Validate the values of the SVE registers. 119 # 120 proc check_sve_regs { byte state vl svl } { 121 122 # If streaming mode is enabled, the vector length is the streaming 123 # vector length. 124 set z_pattern "" 125 set z_size 0 126 if {$state == "ssve" || $state == "za_ssve"} { 127 set z_pattern [string_to_regexp [1d_array_value_pattern $byte $svl]] 128 set z_size $svl 129 } else { 130 set z_size $vl 131 132 if {$state == "fpsimd" || $state == "za"} { 133 # If there is no SVE/SSVE state, the contents of the Z/P/FFR registers 134 # are zero. 135 if {$vl == 16} { 136 set z_pattern [string_to_regexp [1d_array_value_pattern $byte $vl]] 137 } else { 138 set z_repeats [expr $vl - 16] 139 set z_pattern [string_to_regexp "{$byte <repeats 16 times>, 0 <repeats $z_repeats times>}"] 140 } 141 } else { 142 set z_pattern [string_to_regexp [1d_array_value_pattern $byte $vl]] 143 } 144 } 145 set p_size [expr $z_size / 8] 146 147 # If there is no SVE/SSVE state, the contents of the Z/P/FFR registers 148 # are zero. 149 set p_byte $byte 150 if {$state == "fpsimd" || $state == "za"} { 151 set p_byte 0 152 } 153 set p_pattern [string_to_regexp [1d_array_value_pattern $p_byte $p_size]] 154 155 for {set number 0} {$number < 32} {incr number} { 156 set register_name "\$z${number}\.b\.u" 157 gdb_test "print sizeof $register_name" " = $z_size" 158 gdb_test "print $register_name" $z_pattern 159 } 160 161 for {set number 0} {$number < 16} {incr number} { 162 set register_name "\$p${number}" 163 gdb_test "print sizeof $register_name" " = $p_size" 164 gdb_test "print $register_name" $p_pattern 165 } 166 167 gdb_test "print \$ffr" $p_pattern 168 } 169 170 # 171 # Validate the values of the SME registers. 172 # 173 proc check_sme_regs { byte state svl } { 174 # ZA contents are only available when the ZA state is enabled. Otherwise 175 # the ZA contents are unavailable (zeroed out). 176 set za_pattern "" 177 set expected_za_size [expr $svl * $svl] 178 179 if {$state != "za" && $state != "za_ssve"} { 180 set byte 0 181 } 182 183 set za_pattern [string_to_regexp [2d_array_value_pattern $byte $svl $svl]] 184 185 gdb_test "print sizeof \$za" " = $expected_za_size" 186 gdb_test "print \$za" $za_pattern 187 } 188 189 # 190 # Validate the values of the SME2 registers. 191 # 192 proc check_sme2_regs { byte } { 193 # The size of the ZT registers should always be fixed to 64 bytes. 194 set zt_size 64 195 gdb_test "print sizeof \$zt0" " = $zt_size" 196 # Check that we have the expected pattern of bytes for the ZT registers. 197 set zt_pattern [string_to_regexp [1d_array_value_pattern $byte $zt_size]] 198 gdb_test "print \$zt0" $zt_pattern 199 } 200 201 # 202 # With register STATE, vector length VL and streaming vector length SVL, 203 # run some register state checks to make sure the values are the expected 204 # ones 205 # 206 proc check_state { state vl svl } { 207 # The FPSIMD registers are initialized with a value of 0x55 (85) 208 # for each byte. 209 # 210 # The SVE registers are initialized with a value of 0xff (255) for each 211 # byte, including the predicate registers and FFR. 212 # 213 # The SME (ZA) register is initialized with a value of 0xaa (170) for 214 # each byte. 215 # 216 # The SME2 (ZT) registers are initialized with a value of 0xff (255) for 217 # each byte. 218 219 # Check VG to make sure it is correct 220 set expected_vg [expr $vl / 8] 221 # If streaming mode is enabled, then vg is actually svg. 222 if {$state == "ssve" || $state == "za_ssve"} { 223 set expected_vg [expr $svl / 8] 224 } 225 gdb_test "print \$vg" " = ${expected_vg}" 226 227 # Check SVG to make sure it is correct 228 set expected_svg [expr $svl / 8] 229 gdb_test "print \$svg" " = ${expected_svg}" 230 231 # Check the value of SVCR. 232 gdb_test "print \$svcr" [get_svcr_value $state] 233 234 # When we have any SVE or SSVE state, the FPSIMD registers will have 235 # the same values as the SVE/SSVE Z registers. 236 set fpsimd_byte 85 237 if {$state == "sve" || $state == "ssve" || $state == "za_ssve"} { 238 set fpsimd_byte 255 239 } 240 241 set sve_byte 255 242 if {$state == "fpsimd" || $state == "za"} { 243 set sve_byte 85 244 } 245 246 # Check FPSIMD registers 247 check_fpsimd_regs $fpsimd_byte $state $vl $svl 248 # Check SVE registers 249 check_sve_regs $sve_byte $state $vl $svl 250 # Check SME registers 251 check_sme_regs 170 $state $svl 252 253 # Check SME2 registers 254 if [is_sme2_available] { 255 # The SME2 ZT0 register will always be zero, except when ZA is active. 256 set sme2_byte 0 257 if {$state == "za" || $state == "za_ssve"} { 258 set sme2_byte 255 259 } 260 261 # The target supports SME2, so check the ZT register values. 262 check_sme2_regs $sme2_byte 263 } 264 } 265 266 # 267 # Return 1 if SME2 is available (meaning the ZT0 register exists). 268 # Return 0 otherwise. 269 # 270 proc is_sme2_available { } { 271 272 # Does the ZT0 register exist? 273 gdb_test_multiple "print \$zt0" "" { 274 -re " = void.*${::gdb_prompt} $" { 275 # SME2 is not available. 276 return 0 277 } 278 -re " = {.*}\r\n${::gdb_prompt} $" { 279 # SME2 is available. 280 return 1 281 } 282 } 283 } 284