1 // SPDX-License-Identifier: GPL-2.0-only 1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (C) 2015-2019 ARM Limited. 2 // Copyright (C) 2015-2019 ARM Limited. 3 // Original author: Dave Martin <Dave.Martin@ar 3 // Original author: Dave Martin <Dave.Martin@arm.com> 4 // 4 // 5 // Simple Scalable Vector Extension context sw 5 // Simple Scalable Vector Extension context switch test 6 // Repeatedly writes unique test patterns into 6 // Repeatedly writes unique test patterns into each SVE register 7 // and reads them back to verify integrity. 7 // and reads them back to verify integrity. 8 // 8 // 9 // for x in `seq 1 NR_CPUS`; do sve-test & pid 9 // for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done 10 // (leave it running for as long as you want.. 10 // (leave it running for as long as you want...) 11 // kill $pids 11 // kill $pids 12 12 13 #include <asm/unistd.h> 13 #include <asm/unistd.h> 14 #include "assembler.h" 14 #include "assembler.h" 15 #include "asm-offsets.h" 15 #include "asm-offsets.h" 16 #include "sme-inst.h" << 17 16 18 #define NZR 32 17 #define NZR 32 19 #define NPR 16 18 #define NPR 16 20 #define MAXVL_B (2048 / 8) 19 #define MAXVL_B (2048 / 8) 21 20 22 .arch_extension sve 21 .arch_extension sve 23 22 24 .macro _sve_ldr_v zt, xn 23 .macro _sve_ldr_v zt, xn 25 ldr z\zt, [x\xn] 24 ldr z\zt, [x\xn] 26 .endm 25 .endm 27 26 28 .macro _sve_str_v zt, xn 27 .macro _sve_str_v zt, xn 29 str z\zt, [x\xn] 28 str z\zt, [x\xn] 30 .endm 29 .endm 31 30 32 .macro _sve_ldr_p pt, xn 31 .macro _sve_ldr_p pt, xn 33 ldr p\pt, [x\xn] 32 ldr p\pt, [x\xn] 34 .endm 33 .endm 35 34 36 .macro _sve_str_p pt, xn 35 .macro _sve_str_p pt, xn 37 str p\pt, [x\xn] 36 str p\pt, [x\xn] 38 .endm 37 .endm 39 38 40 // Generate accessor functions to read/write p 39 // Generate accessor functions to read/write programmatically selected 41 // SVE registers. 40 // SVE registers. 42 // x0 is the register index to access 41 // x0 is the register index to access 43 // x1 is the memory address to read from (getz 42 // x1 is the memory address to read from (getz,setp) or store to (setz,setp) 44 // All clobber x0-x2 43 // All clobber x0-x2 45 define_accessor setz, NZR, _sve_ldr_v 44 define_accessor setz, NZR, _sve_ldr_v 46 define_accessor getz, NZR, _sve_str_v 45 define_accessor getz, NZR, _sve_str_v 47 define_accessor setp, NPR, _sve_ldr_p 46 define_accessor setp, NPR, _sve_ldr_p 48 define_accessor getp, NPR, _sve_str_p 47 define_accessor getp, NPR, _sve_str_p 49 48 50 // Declare some storate space to shadow the SV 49 // Declare some storate space to shadow the SVE register contents: 51 .pushsection .text 50 .pushsection .text 52 .data 51 .data 53 .align 4 52 .align 4 54 zref: 53 zref: 55 .space MAXVL_B * NZR 54 .space MAXVL_B * NZR 56 pref: 55 pref: 57 .space MAXVL_B / 8 * NPR 56 .space MAXVL_B / 8 * NPR 58 ffrref: 57 ffrref: 59 .space MAXVL_B / 8 58 .space MAXVL_B / 8 60 scratch: 59 scratch: 61 .space MAXVL_B 60 .space MAXVL_B 62 .popsection 61 .popsection 63 62 64 // Generate a test pattern for storage in SVE 63 // Generate a test pattern for storage in SVE registers 65 // x0: pid (16 bits) 64 // x0: pid (16 bits) 66 // x1: register number (6 bits) 65 // x1: register number (6 bits) 67 // x2: generation (4 bits) 66 // x2: generation (4 bits) 68 67 69 // These values are used to constuct a 32-bit 68 // These values are used to constuct a 32-bit pattern that is repeated in the 70 // scratch buffer as many times as will fit: 69 // scratch buffer as many times as will fit: 71 // bits 31:28 generation number (increments 70 // bits 31:28 generation number (increments once per test_loop) 72 // bits 27:22 32-bit lane index 71 // bits 27:22 32-bit lane index 73 // bits 21:16 register number 72 // bits 21:16 register number 74 // bits 15: 0 pid 73 // bits 15: 0 pid 75 74 76 function pattern 75 function pattern 77 orr w1, w0, w1, lsl #16 76 orr w1, w0, w1, lsl #16 78 orr w2, w1, w2, lsl #28 77 orr w2, w1, w2, lsl #28 79 78 80 ldr x0, =scratch 79 ldr x0, =scratch 81 mov w1, #MAXVL_B / 4 80 mov w1, #MAXVL_B / 4 82 81 83 0: str w2, [x0], #4 82 0: str w2, [x0], #4 84 add w2, w2, #(1 << 22) 83 add w2, w2, #(1 << 22) 85 subs w1, w1, #1 84 subs w1, w1, #1 86 bne 0b 85 bne 0b 87 86 88 ret 87 ret 89 endfunction 88 endfunction 90 89 91 // Get the address of shadow data for SVE Z-re 90 // Get the address of shadow data for SVE Z-register Z<xn> 92 .macro _adrz xd, xn, nrtmp 91 .macro _adrz xd, xn, nrtmp 93 ldr \xd, =zref 92 ldr \xd, =zref 94 rdvl x\nrtmp, #1 93 rdvl x\nrtmp, #1 95 madd \xd, x\nrtmp, \xn, \xd 94 madd \xd, x\nrtmp, \xn, \xd 96 .endm 95 .endm 97 96 98 // Get the address of shadow data for SVE P-re 97 // Get the address of shadow data for SVE P-register P<xn - NZR> 99 .macro _adrp xd, xn, nrtmp 98 .macro _adrp xd, xn, nrtmp 100 ldr \xd, =pref 99 ldr \xd, =pref 101 rdvl x\nrtmp, #1 100 rdvl x\nrtmp, #1 102 lsr x\nrtmp, x\nrtmp, #3 101 lsr x\nrtmp, x\nrtmp, #3 103 sub \xn, \xn, #NZR 102 sub \xn, \xn, #NZR 104 madd \xd, x\nrtmp, \xn, \xd 103 madd \xd, x\nrtmp, \xn, \xd 105 .endm 104 .endm 106 105 107 // Set up test pattern in a SVE Z-register 106 // Set up test pattern in a SVE Z-register 108 // x0: pid 107 // x0: pid 109 // x1: register number 108 // x1: register number 110 // x2: generation 109 // x2: generation 111 function setup_zreg 110 function setup_zreg 112 mov x4, x30 111 mov x4, x30 113 112 114 mov x6, x1 113 mov x6, x1 115 bl pattern 114 bl pattern 116 _adrz x0, x6, 2 115 _adrz x0, x6, 2 117 mov x5, x0 116 mov x5, x0 118 ldr x1, =scratch 117 ldr x1, =scratch 119 bl memcpy 118 bl memcpy 120 119 121 mov x0, x6 120 mov x0, x6 122 mov x1, x5 121 mov x1, x5 123 bl setz 122 bl setz 124 123 125 ret x4 124 ret x4 126 endfunction 125 endfunction 127 126 128 // Set up test pattern in a SVE P-register 127 // Set up test pattern in a SVE P-register 129 // x0: pid 128 // x0: pid 130 // x1: register number 129 // x1: register number 131 // x2: generation 130 // x2: generation 132 function setup_preg 131 function setup_preg 133 mov x4, x30 132 mov x4, x30 134 133 135 mov x6, x1 134 mov x6, x1 136 bl pattern 135 bl pattern 137 _adrp x0, x6, 2 136 _adrp x0, x6, 2 138 mov x5, x0 137 mov x5, x0 139 ldr x1, =scratch 138 ldr x1, =scratch 140 bl memcpy 139 bl memcpy 141 140 142 mov x0, x6 141 mov x0, x6 143 mov x1, x5 142 mov x1, x5 144 bl setp 143 bl setp 145 144 146 ret x4 145 ret x4 147 endfunction 146 endfunction 148 147 149 // Set up test pattern in the FFR 148 // Set up test pattern in the FFR 150 // x0: pid 149 // x0: pid 151 // x2: generation 150 // x2: generation 152 // 151 // 153 // We need to generate a canonical FFR value, 152 // We need to generate a canonical FFR value, which consists of a number of 154 // low "1" bits, followed by a number of zeros 153 // low "1" bits, followed by a number of zeros. This gives us 17 unique values 155 // per 16 bits of FFR, so we create a 4 bit si 154 // per 16 bits of FFR, so we create a 4 bit signature out of the PID and 156 // generation, and use that as the initial num 155 // generation, and use that as the initial number of ones in the pattern. 157 // We fill the upper lanes of FFR with zeros. 156 // We fill the upper lanes of FFR with zeros. 158 // Beware: corrupts P0. 157 // Beware: corrupts P0. 159 function setup_ffr 158 function setup_ffr 160 #ifndef SSVE << 161 mov x4, x30 159 mov x4, x30 162 160 163 and w0, w0, #0x3 161 and w0, w0, #0x3 164 bfi w0, w2, #2, #2 162 bfi w0, w2, #2, #2 165 mov w1, #1 163 mov w1, #1 166 lsl w1, w1, w0 164 lsl w1, w1, w0 167 sub w1, w1, #1 165 sub w1, w1, #1 168 166 169 ldr x0, =ffrref 167 ldr x0, =ffrref 170 strh w1, [x0], 2 168 strh w1, [x0], 2 171 rdvl x1, #1 169 rdvl x1, #1 172 lsr x1, x1, #3 170 lsr x1, x1, #3 173 sub x1, x1, #2 171 sub x1, x1, #2 174 bl memclr 172 bl memclr 175 173 176 mov x0, #0 174 mov x0, #0 177 ldr x1, =ffrref 175 ldr x1, =ffrref 178 bl setp 176 bl setp 179 177 180 wrffr p0.b 178 wrffr p0.b 181 179 182 ret x4 180 ret x4 183 #else << 184 ret << 185 #endif << 186 endfunction 181 endfunction 187 182 188 // Trivial memory compare: compare x2 bytes st 183 // Trivial memory compare: compare x2 bytes starting at address x0 with 189 // bytes starting at address x1. 184 // bytes starting at address x1. 190 // Returns only if all bytes match; otherwise, 185 // Returns only if all bytes match; otherwise, the program is aborted. 191 // Clobbers x0-x5. 186 // Clobbers x0-x5. 192 function memcmp 187 function memcmp 193 cbz x2, 2f 188 cbz x2, 2f 194 189 195 stp x0, x1, [sp, #-0x20]! 190 stp x0, x1, [sp, #-0x20]! 196 str x2, [sp, #0x10] 191 str x2, [sp, #0x10] 197 192 198 mov x5, #0 193 mov x5, #0 199 0: ldrb w3, [x0, x5] 194 0: ldrb w3, [x0, x5] 200 ldrb w4, [x1, x5] 195 ldrb w4, [x1, x5] 201 add x5, x5, #1 196 add x5, x5, #1 202 cmp w3, w4 197 cmp w3, w4 203 b.ne 1f 198 b.ne 1f 204 subs x2, x2, #1 199 subs x2, x2, #1 205 b.ne 0b 200 b.ne 0b 206 201 207 1: ldr x2, [sp, #0x10] 202 1: ldr x2, [sp, #0x10] 208 ldp x0, x1, [sp], #0x20 203 ldp x0, x1, [sp], #0x20 209 b.ne barf 204 b.ne barf 210 205 211 2: ret 206 2: ret 212 endfunction 207 endfunction 213 208 214 // Verify that a SVE Z-register matches its sh 209 // Verify that a SVE Z-register matches its shadow in memory, else abort 215 // x0: reg number 210 // x0: reg number 216 // Clobbers x0-x7. 211 // Clobbers x0-x7. 217 function check_zreg 212 function check_zreg 218 mov x3, x30 213 mov x3, x30 219 214 220 _adrz x5, x0, 6 215 _adrz x5, x0, 6 221 mov x4, x0 216 mov x4, x0 222 ldr x7, =scratch 217 ldr x7, =scratch 223 218 224 mov x0, x7 219 mov x0, x7 225 mov x1, x6 220 mov x1, x6 226 bl memfill_ae 221 bl memfill_ae 227 222 228 mov x0, x4 223 mov x0, x4 229 mov x1, x7 224 mov x1, x7 230 bl getz 225 bl getz 231 226 232 mov x0, x5 227 mov x0, x5 233 mov x1, x7 228 mov x1, x7 234 mov x2, x6 229 mov x2, x6 235 mov x30, x3 230 mov x30, x3 236 b memcmp 231 b memcmp 237 endfunction 232 endfunction 238 233 239 // Verify that a SVE P-register matches its sh 234 // Verify that a SVE P-register matches its shadow in memory, else abort 240 // x0: reg number 235 // x0: reg number 241 // Clobbers x0-x7. 236 // Clobbers x0-x7. 242 function check_preg 237 function check_preg 243 mov x3, x30 238 mov x3, x30 244 239 245 _adrp x5, x0, 6 240 _adrp x5, x0, 6 246 mov x4, x0 241 mov x4, x0 247 ldr x7, =scratch 242 ldr x7, =scratch 248 243 249 mov x0, x7 244 mov x0, x7 250 mov x1, x6 245 mov x1, x6 251 bl memfill_ae 246 bl memfill_ae 252 247 253 mov x0, x4 248 mov x0, x4 254 mov x1, x7 249 mov x1, x7 255 bl getp 250 bl getp 256 251 257 mov x0, x5 252 mov x0, x5 258 mov x1, x7 253 mov x1, x7 259 mov x2, x6 254 mov x2, x6 260 mov x30, x3 255 mov x30, x3 261 b memcmp 256 b memcmp 262 endfunction 257 endfunction 263 258 264 // Verify that the FFR matches its shadow in m 259 // Verify that the FFR matches its shadow in memory, else abort 265 // Beware -- corrupts P0. 260 // Beware -- corrupts P0. 266 // Clobbers x0-x5. 261 // Clobbers x0-x5. 267 function check_ffr 262 function check_ffr 268 #ifndef SSVE << 269 mov x3, x30 263 mov x3, x30 270 264 271 ldr x4, =scratch 265 ldr x4, =scratch 272 rdvl x5, #1 266 rdvl x5, #1 273 lsr x5, x5, #3 267 lsr x5, x5, #3 274 268 275 mov x0, x4 269 mov x0, x4 276 mov x1, x5 270 mov x1, x5 277 bl memfill_ae 271 bl memfill_ae 278 272 279 rdffr p0.b 273 rdffr p0.b 280 mov x0, #0 274 mov x0, #0 281 mov x1, x4 275 mov x1, x4 282 bl getp 276 bl getp 283 277 284 ldr x0, =ffrref 278 ldr x0, =ffrref 285 mov x1, x4 279 mov x1, x4 286 mov x2, x5 280 mov x2, x5 287 mov x30, x3 281 mov x30, x3 288 b memcmp 282 b memcmp 289 #else << 290 ret << 291 #endif << 292 endfunction 283 endfunction 293 284 294 // Any SVE register modified here can cause co 285 // Any SVE register modified here can cause corruption in the main 295 // thread -- but *only* the registers modified 286 // thread -- but *only* the registers modified here. 296 function irritator_handler 287 function irritator_handler 297 // Increment the irritation signal cou 288 // Increment the irritation signal count (x23): 298 ldr x0, [x2, #ucontext_regs + 8 * 289 ldr x0, [x2, #ucontext_regs + 8 * 23] 299 add x0, x0, #1 290 add x0, x0, #1 300 str x0, [x2, #ucontext_regs + 8 * 291 str x0, [x2, #ucontext_regs + 8 * 23] 301 292 302 // Corrupt some random Z-regs 293 // Corrupt some random Z-regs 303 adr x0, .text + (irritator_handler 294 adr x0, .text + (irritator_handler - .text) / 16 * 16 304 movi v0.8b, #1 295 movi v0.8b, #1 305 movi v9.16b, #2 296 movi v9.16b, #2 306 movi v31.8b, #3 297 movi v31.8b, #3 307 #ifndef SSVE << 308 // And P0 298 // And P0 309 rdffr p0.b 299 rdffr p0.b 310 // And FFR 300 // And FFR 311 wrffr p15.b 301 wrffr p15.b 312 #endif << 313 << 314 ret << 315 endfunction << 316 << 317 function tickle_handler << 318 // Increment the signal count (x23): << 319 ldr x0, [x2, #ucontext_regs + 8 * << 320 add x0, x0, #1 << 321 str x0, [x2, #ucontext_regs + 8 * << 322 302 323 ret 303 ret 324 endfunction 304 endfunction 325 305 326 function terminate_handler 306 function terminate_handler 327 mov w21, w0 307 mov w21, w0 328 mov x20, x2 308 mov x20, x2 329 309 330 puts "Terminated by signal " 310 puts "Terminated by signal " 331 mov w0, w21 311 mov w0, w21 332 bl putdec 312 bl putdec 333 puts ", no error, iterations=" 313 puts ", no error, iterations=" 334 ldr x0, [x20, #ucontext_regs + 8 * 314 ldr x0, [x20, #ucontext_regs + 8 * 22] 335 bl putdec 315 bl putdec 336 puts ", signals=" 316 puts ", signals=" 337 ldr x0, [x20, #ucontext_regs + 8 * 317 ldr x0, [x20, #ucontext_regs + 8 * 23] 338 bl putdecn 318 bl putdecn 339 319 340 mov x0, #0 320 mov x0, #0 341 mov x8, #__NR_exit 321 mov x8, #__NR_exit 342 svc #0 322 svc #0 343 endfunction 323 endfunction 344 324 345 // w0: signal number 325 // w0: signal number 346 // x1: sa_action 326 // x1: sa_action 347 // w2: sa_flags 327 // w2: sa_flags 348 // Clobbers x0-x6,x8 328 // Clobbers x0-x6,x8 349 function setsignal 329 function setsignal 350 str x30, [sp, #-((sa_sz + 15) / 16 330 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]! 351 331 352 mov w4, w0 332 mov w4, w0 353 mov x5, x1 333 mov x5, x1 354 mov w6, w2 334 mov w6, w2 355 335 356 add x0, sp, #16 336 add x0, sp, #16 357 mov x1, #sa_sz 337 mov x1, #sa_sz 358 bl memclr 338 bl memclr 359 339 360 mov w0, w4 340 mov w0, w4 361 add x1, sp, #16 341 add x1, sp, #16 362 str w6, [x1, #sa_flags] 342 str w6, [x1, #sa_flags] 363 str x5, [x1, #sa_handler] 343 str x5, [x1, #sa_handler] 364 mov x2, #0 344 mov x2, #0 365 mov x3, #sa_mask_sz 345 mov x3, #sa_mask_sz 366 mov x8, #__NR_rt_sigaction 346 mov x8, #__NR_rt_sigaction 367 svc #0 347 svc #0 368 348 369 cbz w0, 1f 349 cbz w0, 1f 370 350 371 puts "sigaction failure\n" 351 puts "sigaction failure\n" 372 b .Labort 352 b .Labort 373 353 374 1: ldr x30, [sp], #((sa_sz + 15) / 16 354 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16) 375 ret 355 ret 376 endfunction 356 endfunction 377 357 378 // Main program entry point 358 // Main program entry point 379 .globl _start 359 .globl _start 380 function _start 360 function _start 381 mov x23, #0 // Irritation !! 361 _start: 382 << 383 mov w0, #SIGINT << 384 adr x1, terminate_handler << 385 mov w2, #SA_SIGINFO << 386 bl setsignal << 387 << 388 mov w0, #SIGTERM << 389 adr x1, terminate_handler << 390 mov w2, #SA_SIGINFO << 391 bl setsignal << 392 << 393 mov w0, #SIGUSR1 << 394 adr x1, irritator_handler << 395 mov w2, #SA_SIGINFO << 396 orr w2, w2, #SA_NODEFER << 397 bl setsignal << 398 << 399 mov w0, #SIGUSR2 << 400 adr x1, tickle_handler << 401 mov w2, #SA_SIGINFO << 402 orr w2, w2, #SA_NODEFER << 403 bl setsignal << 404 << 405 #ifdef SSVE << 406 puts "Streaming mode " << 407 smstart_sm << 408 #endif << 409 << 410 // Sanity-check and report the vector 362 // Sanity-check and report the vector length 411 363 412 rdvl x19, #8 364 rdvl x19, #8 413 cmp x19, #128 365 cmp x19, #128 414 b.lo 1f 366 b.lo 1f 415 cmp x19, #2048 367 cmp x19, #2048 416 b.hi 1f 368 b.hi 1f 417 tst x19, #(8 - 1) 369 tst x19, #(8 - 1) 418 b.eq 2f 370 b.eq 2f 419 371 420 1: puts "Bad vector length: " 372 1: puts "Bad vector length: " 421 mov x0, x19 373 mov x0, x19 422 bl putdecn 374 bl putdecn 423 b .Labort 375 b .Labort 424 376 425 2: puts "Vector length:\t" 377 2: puts "Vector length:\t" 426 mov x0, x19 378 mov x0, x19 427 bl putdec 379 bl putdec 428 puts " bits\n" 380 puts " bits\n" 429 381 430 // Obtain our PID, to ensure test patt 382 // Obtain our PID, to ensure test pattern uniqueness between processes 431 383 432 mov x8, #__NR_getpid 384 mov x8, #__NR_getpid 433 svc #0 385 svc #0 434 mov x20, x0 386 mov x20, x0 435 387 436 puts "PID:\t" 388 puts "PID:\t" 437 mov x0, x20 389 mov x0, x20 438 bl putdecn 390 bl putdecn 439 391 440 #ifdef SSVE !! 392 mov x23, #0 // Irritation signal count 441 smstart_sm // syscalls wi !! 393 442 #endif !! 394 mov w0, #SIGINT >> 395 adr x1, terminate_handler >> 396 mov w2, #SA_SIGINFO >> 397 bl setsignal >> 398 >> 399 mov w0, #SIGTERM >> 400 adr x1, terminate_handler >> 401 mov w2, #SA_SIGINFO >> 402 bl setsignal >> 403 >> 404 mov w0, #SIGUSR1 >> 405 adr x1, irritator_handler >> 406 mov w2, #SA_SIGINFO >> 407 orr w2, w2, #SA_NODEFER >> 408 bl setsignal 443 409 444 mov x22, #0 // generation 410 mov x22, #0 // generation number, increments per iteration 445 .Ltest_loop: 411 .Ltest_loop: 446 rdvl x0, #8 412 rdvl x0, #8 447 cmp x0, x19 413 cmp x0, x19 448 b.ne vl_barf 414 b.ne vl_barf 449 415 450 mov x21, #0 // Set up Z-re 416 mov x21, #0 // Set up Z-regs & shadow with test pattern 451 0: mov x0, x20 417 0: mov x0, x20 452 mov x1, x21 418 mov x1, x21 453 and x2, x22, #0xf 419 and x2, x22, #0xf 454 bl setup_zreg 420 bl setup_zreg 455 add x21, x21, #1 421 add x21, x21, #1 456 cmp x21, #NZR 422 cmp x21, #NZR 457 b.lo 0b 423 b.lo 0b 458 424 459 mov x0, x20 // Set up FFR 425 mov x0, x20 // Set up FFR & shadow with test pattern 460 mov x1, #NZR + NPR 426 mov x1, #NZR + NPR 461 and x2, x22, #0xf 427 and x2, x22, #0xf 462 bl setup_ffr 428 bl setup_ffr 463 429 464 0: mov x0, x20 // Set up P-re 430 0: mov x0, x20 // Set up P-regs & shadow with test pattern 465 mov x1, x21 431 mov x1, x21 466 and x2, x22, #0xf 432 and x2, x22, #0xf 467 bl setup_preg 433 bl setup_preg 468 add x21, x21, #1 434 add x21, x21, #1 469 cmp x21, #NZR + NPR 435 cmp x21, #NZR + NPR 470 b.lo 0b 436 b.lo 0b 471 437 472 // Can't do this when SVE state is volatile ac 438 // Can't do this when SVE state is volatile across SVC: 473 // mov x8, #__NR_sched_yield // Enc 439 // mov x8, #__NR_sched_yield // Encourage preemption 474 // svc #0 440 // svc #0 475 441 476 #ifdef SSVE << 477 mrs x0, S3_3_C4_C2_2 // SVC << 478 and x1, x0, #3 << 479 cmp x1, #1 << 480 b.ne svcr_barf << 481 #endif << 482 << 483 mov x21, #0 442 mov x21, #0 484 0: mov x0, x21 443 0: mov x0, x21 485 bl check_zreg 444 bl check_zreg 486 add x21, x21, #1 445 add x21, x21, #1 487 cmp x21, #NZR 446 cmp x21, #NZR 488 b.lo 0b 447 b.lo 0b 489 448 490 0: mov x0, x21 449 0: mov x0, x21 491 bl check_preg 450 bl check_preg 492 add x21, x21, #1 451 add x21, x21, #1 493 cmp x21, #NZR + NPR 452 cmp x21, #NZR + NPR 494 b.lo 0b 453 b.lo 0b 495 454 496 bl check_ffr 455 bl check_ffr 497 456 498 add x22, x22, #1 457 add x22, x22, #1 499 b .Ltest_loop 458 b .Ltest_loop 500 459 501 .Labort: 460 .Labort: 502 mov x0, #0 461 mov x0, #0 503 mov x1, #SIGABRT 462 mov x1, #SIGABRT 504 mov x8, #__NR_kill 463 mov x8, #__NR_kill 505 svc #0 464 svc #0 506 endfunction 465 endfunction 507 466 508 function barf 467 function barf 509 // fpsimd.c acitivty log dump hack 468 // fpsimd.c acitivty log dump hack 510 // ldr w0, =0xdeadc0de 469 // ldr w0, =0xdeadc0de 511 // mov w8, #__NR_exit 470 // mov w8, #__NR_exit 512 // svc #0 471 // svc #0 513 // end hack 472 // end hack 514 mov x10, x0 // expected data 473 mov x10, x0 // expected data 515 mov x11, x1 // actual data 474 mov x11, x1 // actual data 516 mov x12, x2 // data size 475 mov x12, x2 // data size 517 476 518 #ifdef SSVE << 519 mrs x13, S3_3_C4_C2_2 << 520 #endif << 521 << 522 puts "Mismatch: PID=" 477 puts "Mismatch: PID=" 523 mov x0, x20 478 mov x0, x20 524 bl putdec 479 bl putdec 525 puts ", iteration=" 480 puts ", iteration=" 526 mov x0, x22 481 mov x0, x22 527 bl putdec 482 bl putdec 528 puts ", reg=" 483 puts ", reg=" 529 mov x0, x21 484 mov x0, x21 530 bl putdecn 485 bl putdecn 531 puts "\tExpected [" 486 puts "\tExpected [" 532 mov x0, x10 487 mov x0, x10 533 mov x1, x12 488 mov x1, x12 534 bl dumphex 489 bl dumphex 535 puts "]\n\tGot [" 490 puts "]\n\tGot [" 536 mov x0, x11 491 mov x0, x11 537 mov x1, x12 492 mov x1, x12 538 bl dumphex 493 bl dumphex 539 puts "]\n" 494 puts "]\n" 540 495 541 #ifdef SSVE << 542 puts "\tSVCR: " << 543 mov x0, x13 << 544 bl putdecn << 545 #endif << 546 << 547 mov x8, #__NR_getpid 496 mov x8, #__NR_getpid 548 svc #0 497 svc #0 549 // fpsimd.c acitivty log dump hack 498 // fpsimd.c acitivty log dump hack 550 // ldr w0, =0xdeadc0de 499 // ldr w0, =0xdeadc0de 551 // mov w8, #__NR_exit 500 // mov w8, #__NR_exit 552 // svc #0 501 // svc #0 553 // ^ end of hack 502 // ^ end of hack 554 mov x1, #SIGABRT 503 mov x1, #SIGABRT 555 mov x8, #__NR_kill 504 mov x8, #__NR_kill 556 svc #0 505 svc #0 557 // mov x8, #__NR_exit 506 // mov x8, #__NR_exit 558 // mov x1, #1 507 // mov x1, #1 559 // svc #0 508 // svc #0 560 endfunction 509 endfunction 561 510 562 function vl_barf 511 function vl_barf 563 mov x10, x0 512 mov x10, x0 564 513 565 puts "Bad active VL: " 514 puts "Bad active VL: " 566 mov x0, x10 << 567 bl putdecn << 568 << 569 mov x8, #__NR_exit << 570 mov x1, #1 << 571 svc #0 << 572 endfunction << 573 << 574 function svcr_barf << 575 mov x10, x0 << 576 << 577 puts "Bad SVCR: " << 578 mov x0, x10 515 mov x0, x10 579 bl putdecn 516 bl putdecn 580 517 581 mov x8, #__NR_exit 518 mov x8, #__NR_exit 582 mov x1, #1 519 mov x1, #1 583 svc #0 520 svc #0 584 endfunction 521 endfunction
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.