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