1/* 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2021 Warner Losh 5 * Copyright (c) 2023 Stormshield 6 * Copyright (c) 2023 Klara, Inc. 7 */ 8 9#include <sys/syscall.h> 10 11#define STDOUT_FILENO 1 12#define SWP_MAGIC 0xffc0 13#define SWPB_MAGIC 0xc0c0 14 15 .text 16 .file "swp_test.S" 17 .syntax unified 18 .globl main 19 .p2align 2 20 .type main,%function 21 .code 32 22 23main: 24 sub sp, #0x04 25 /* r4 is our failed test counter */ 26 mov r4, #0 27 /* r6 is our current teset counter */ 28 mov r6, #1 29 30 movw r0, :lower16:.L.testheader 31 movt r0, :upper16:.L.testheader 32 ldr r1, =(.L.testheaderEnd - .L.testheader - 1) 33 bl print 34 35 /* eq */ 36 bl reset 37 mov r1, #SWP_MAGIC 38 cmp r1, r1 39 swpeq r0, r1, [r0] 40 bl expect_success 41 42 /* Returned 0 (bad) or 1 (ok) */ 43 cmp r0, #0 44 beq 1f 45 46 /* !eq */ 47 bl reset 48 mov r1, #SWP_MAGIC 49 mov r2, #0 50 cmp r1, r2 51 swpeq r0, r1, [r0] 52 bl expect_fail 53 54 /* Don't care about the return of the second one, just print */ 551: 56 movw r0, :lower16:.L.eq 57 movt r0, :upper16:.L.eq 58 ldr r1, =(.L.eqEnd - .L.eq - 1) 59 bl print_result 60 add r6, r6, #1 /* Next test */ 61 62 /* cs */ 63 bl reset 64 mov r1, #SWP_MAGIC 65 movw r3, #0xffff 66 movt r3, #0xffff 67 /* Overflow */ 68 adds r2, r3, r3 69 swpcs r0, r1, [r0] 70 bl expect_success 71 72 /* Returned 0 (bad) or 1 (ok) */ 73 cmp r0, #0 74 beq 2f 75 76 /* !cs */ 77 bl reset 78 mov r1, #SWP_MAGIC 79 mov r3, #0x00 80 adds r2, r3, #0x08 81 swpcs r0, r1, [r0] 82 bl expect_fail 83 84 /* Don't care about the return of the second one, just print */ 852: 86 movw r0, :lower16:.L.cs 87 movt r0, :upper16:.L.cs 88 ldr r1, =(.L.csEnd - .L.cs - 1) 89 bl print_result 90 add r6, r6, #1 /* Next test */ 91 92 /* mi */ 93 bl reset 94 mov r1, #SWP_MAGIC 95 mov r2, #0 96 /* Underflow */ 97 subs r2, r2, #0x05 98 swpmi r0, r1, [r0] 99 bl expect_success 100 101 /* Returned 0 (bad) or 1 (ok) */ 102 cmp r0, #0 103 beq 3f 104 105 /* !mi */ 106 bl reset 107 mov r1, #SWP_MAGIC 108 mov r2, #0x10 109 subs r2, r2, #0x08 110 swpmi r0, r1, [r0] 111 bl expect_fail 112 113 /* Don't care about the return of the second one, just print */ 1143: 115 movw r0, :lower16:.L.mi 116 movt r0, :upper16:.L.mi 117 ldr r1, =(.L.miEnd - .L.mi - 1) 118 bl print_result 119 add r6, r6, #1 /* Next test */ 120 121 /* vs */ 122 bl reset 123 mov r1, #SWP_MAGIC 124 movw r3, #0xffff 125 movt r3, #0x7fff 126 /* Overflow */ 127 adds r2, r3, #0x10 128 swpvs r0, r1, [r0] 129 bl expect_success 130 131 /* Returned 0 (bad) or 1 (ok) */ 132 cmp r0, #0 133 beq 4f 134 135 /* !vs */ 136 bl reset 137 mov r1, #SWP_MAGIC 138 mov r3, #0x00 139 adds r2, r3, #0x08 140 swpvs r0, r1, [r0] 141 bl expect_fail 142 143 /* Don't care about the return of the second one, just print */ 1444: 145 movw r0, :lower16:.L.vs 146 movt r0, :upper16:.L.vs 147 ldr r1, =(.L.vsEnd - .L.vs - 1) 148 bl print_result 149 add r6, r6, #1 /* Next test */ 150 151 /* hi */ 152 bl reset 153 mov r1, #SWP_MAGIC 154 mov r2, #0x00 155 mov r3, #0x01 156 cmp r3, r2 157 swphi r0, r1, [r0] 158 bl expect_success 159 160 /* Returned 0 (bad) or 1 (ok) */ 161 cmp r0, #0 162 beq 5f 163 164 /* !hi */ 165 bl reset 166 mov r1, #SWP_MAGIC 167 mov r2, #0x00 168 mov r3, #0x01 169 cmp r2, r3 170 swphi r0, r1, [r0] 171 bl expect_fail 172 173 /* Don't care about the return of the second one, just print */ 1745: 175 movw r0, :lower16:.L.hi 176 movt r0, :upper16:.L.hi 177 ldr r1, =(.L.hiEnd - .L.hi - 1) 178 bl print_result 179 add r6, r6, #1 /* Next test */ 180 181 /* ge */ 182 bl reset 183 mov r1, #SWP_MAGIC 184 mov r2, #0x01 185 cmp r2, r2 186 swpge r0, r1, [r0] 187 bl expect_success 188 189 /* Returned 0 (bad) or 1 (ok) */ 190 cmp r0, #0 191 beq 6f 192 193 /* !ge */ 194 bl reset 195 mov r1, #SWP_MAGIC 196 mov r2, #0x00 197 mov r3, #0x01 198 cmp r2, r3 199 swpge r0, r1, [r0] 200 bl expect_fail 201 202 /* Don't care about the return of the second one, just print */ 2036: 204 movw r0, :lower16:.L.ge 205 movt r0, :upper16:.L.ge 206 ldr r1, =(.L.geEnd - .L.ge - 1) 207 bl print_result 208 add r6, r6, #1 /* Next test */ 209 210 /* gt */ 211 bl reset 212 mov r1, #SWP_MAGIC 213 mov r2, #0x00 214 mov r3, #0x01 215 cmp r3, r2 216 swpgt r0, r1, [r0] 217 bl expect_success 218 219 /* Returned 0 (bad) or 1 (ok) */ 220 cmp r0, #0 221 beq 7f 222 223 /* !ge */ 224 bl reset 225 mov r1, #SWP_MAGIC 226 mov r2, #0x00 227 mov r3, #0x01 228 cmp r2, r3 229 swpgt r0, r1, [r0] 230 bl expect_fail 231 232 /* Don't care about the return of the second one, just print */ 2337: 234 movw r0, :lower16:.L.gt 235 movt r0, :upper16:.L.gt 236 ldr r1, =(.L.gtEnd - .L.gt - 1) 237 bl print_result 238 add r6, r6, #1 /* Next test */ 239 240 mov r0, r4 /* retval */ 241 ldr r7, =SYS_exit 242 swi 0 243 244 .p2align 2 245 .type print_result,%function 246 .code 32 247print_result: 248 push {r4, r5, lr} 249 /* Save the label, size for our result */ 250 mov r4, r0 251 mov r5, r1 252 253 movw r0, :lower16:.L.ok 254 movt r0, :upper16:.L.ok 255 ldr r1, =(.L.okEnd - .L.ok - 1) 256 bl print 257 mov r0, r6 258 add r0, #0x30 /* "0" + test number */ 259 mov r1, #0x01 260 str r0, [sp] 261 mov r0, sp 262 bl print 263 movw r0, :lower16:.L.swp 264 movt r0, :upper16:.L.swp 265 ldr r1, =(.L.swpEnd - .L.swp - 1) 266 bl print 267 mov r0, r4 268 mov r1, r5 269 bl print 270 movw r0, :lower16:.L.term 271 movt r0, :upper16:.L.term 272 ldr r1, =(.L.termEnd - .L.term - 1) 273 bl print 274 275 pop {r4, r5, lr} 276 bx lr 277 278 .p2align 2 279 .type reset,%function 280 .code 32 281reset: 282 /* Reset sp[0] and return the address used */ 283 mov r0, #0x03 284 str r0, [sp] 285 mov r0, sp 286 bx lr 287 288 .p2align 2 289 .type expect_fail,%function 290 .code 32 291expect_fail: 292 /* Just check the stack value */ 293 ldr r0, [sp] 294 mov r1, #0x03 295 cmp r0, r1 296 bne 1f 297 298 /* Success (not swapped) */ 299 mov r0, #1 300 bx lr 301 3021: 303 /* Fail (swapped) */ 304 /* Print the "not" part */ 305 movw r0, :lower16:.L.not 306 movt r0, :upper16:.L.not 307 ldr r1, =(.L.notEnd - .L.not - 1) 308 push {lr} 309 bl print 310 pop {lr} 311 312 /* Failed */ 313 add r4, r4, #1 314 mov r0, #0 315 bx lr 316 317 .p2align 2 318 .type expect_success,%function 319 .code 32 320expect_success: 321 /* Old value should be 3 */ 322 cmp r0, #0x03 323 beq 1f 324 b 3f 325 3261: 327 /* Check stack value */ 328 ldr r0, [sp] 329 mov r1, #SWP_MAGIC 330 cmp r0, r1 331 beq 2f 332 b 3f 333 3342: 335 mov r0, #1 336 bx lr 337 3383: 339 /* Print the "not" part */ 340 movw r0, :lower16:.L.not 341 movt r0, :upper16:.L.not 342 ldr r1, =(.L.notEnd - .L.not - 1) 343 push {lr} 344 bl print 345 pop {lr} 346 347 /* Failed */ 348 add r4, r4, #1 349 mov r0, #0 350 bx lr 351 352 .p2align 2 353 .type print,%function 354 .code 32 355print: 356 /* r0 - string, r1 = size */ 357 mov r2, r1 358 mov r1, r0 359 ldr r0, =STDOUT_FILENO 360 ldr r7, =SYS_write 361 swi 0 362 363 bx lr 364 365.L.testheader: 366 .asciz "1..7\n" 367.L.testheaderEnd: 368 .size .L.testheader, .L.testheaderEnd - .L.testheader 369 370.L.not: 371 .asciz "not " 372.L.notEnd: 373 .size .L.not, .L.notEnd - .L.not 374.L.ok: 375 .asciz "ok " 376.L.okEnd: 377 .size .L.ok, .L.okEnd - .L.ok 378.L.swp: 379 .asciz " - swp" 380.L.swpEnd: 381 .size .L.swp, .L.swpEnd - .L.swp 382.L.eq: 383 .asciz "eq" 384.L.eqEnd: 385 .size .L.eq, .L.eqEnd - .L.eq 386.L.cs: 387 .asciz "cs" 388.L.csEnd: 389 .size .L.cs, .L.csEnd - .L.cs 390.L.mi: 391 .asciz "mi" 392.L.miEnd: 393 .size .L.mi, .L.miEnd - .L.mi 394.L.vs: 395 .asciz "vs" 396.L.vsEnd: 397 .size .L.vs, .L.vsEnd - .L.vs 398.L.hi: 399 .asciz "hi" 400.L.hiEnd: 401 .size .L.hi, .L.hiEnd - .L.hi 402.L.ge: 403 .asciz "ge" 404.L.geEnd: 405 .size .L.ge, .L.geEnd - .L.ge 406.L.gt: 407 .asciz "gt" 408.L.gtEnd: 409 .size .L.gt, .L.gtEnd - .L.gt 410.L.term: 411 .asciz "\n" 412.L.termEnd: 413 .size .L.term, .L.termEnd - .L.term 414