Home | History | Annotate | Line # | Download | only in lib
      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