Path: blob/main/tools/regression/compat32/aarch64/swp_test_impl.S
48255 views
/*1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2021 Warner Losh4* Copyright (c) 2023 Stormshield5* Copyright (c) 2023 Klara, Inc.6*/78#include <sys/syscall.h>910#define STDOUT_FILENO 11112#define MUTEX_LOCKED 0x0113#define MUTEX_UNLOCKED 0x001415#define STACK_SIZE 409616#define TLS_SIZE 40961718.text19.file "swp_test.S"20.syntax unified21.globl main22.p2align 223.type main,%function24.code 322526main:27/*28* Stack slots:29* 0 - Sync word30* 1 - Thread id31* 2 - Shared word32*/33sub sp, sp, #123435/* Print a message */36movw r0, :lower16:.L.mainmsg37movt r0, :upper16:.L.mainmsg38ldr r1, =(.L.mainmsgEnd - .L.mainmsg - 1)39bl print4041/* Create two secondary threads */42mov r0, #143str r0, [sp, #4] /* Thread ID */44movw r0, :lower16:secondary_thread45movt r0, :upper16:secondary_thread46mov r1, sp47movw r2, :lower16:stack148movt r2, :upper16:stack149movw r3, :lower16:tls150movt r3, :upper16:tls151bl create_thr52531:54/*55* Wait for the first new thread to ack its existence by56* incrementing the thread id.57*/58ldr r0, [sp, #4]59cmp r0, #160bne 2f61ldr r7, =SYS_sched_yield62swi 063b 1b64652:66/* Create thread #2 */67movw r0, :lower16:secondary_thread68movt r0, :upper16:secondary_thread69mov r1, sp70movw r2, :lower16:stack271movt r2, :upper16:stack272movw r3, :lower16:tls273movt r3, :upper16:tls274bl create_thr75763:77/*78* Wait for the first new thread to ack its existence by79* incrementing the thread id.80*/81ldr r0, [sp, #4]82cmp r0, #283bne 4f84ldr r7, =SYS_sched_yield85swi 086b 3b8788/* Loop */894:90mov r0, sp91mov r1, #0 /* Thread loop */92add r2, sp, #893bl thread_loop94b 4b9596/* UNREACHABLE */97mov r0, #098ldr r7, =SYS_exit99swi 0100101.p2align 2102.type secondary_thread,%function103.code 32104secondary_thread:105/*106* On entry, r0 is where we stashed our sync word and107* ack word (thread ID).108*109* Stash the sync word in r4, thread ID in r5.110*/111mov r4, r0112ldr r5, [r0, #4]113114/* Print a message */115movw r0, :lower16:.L.secondarymsg116movt r0, :upper16:.L.secondarymsg117ldr r1, =(.L.secondarymsgEnd - .L.secondarymsg - 1)118bl print119120/* Acknowledge that we started */121add r0, r5, #1122str r0, [r4, #4]1231241:125mov r0, r4126mov r1, r5127add r2, r4, #8128bl thread_loop129b 1b130131.p2align 2132.type thread_loop,%function133.code 32134thread_loop:135push {r4, r5, r6, r7, r8, lr}136137/*138* r0 == sync word139* r1 == thread ID140* r2 == shared word141*/142mov r4, r0143mov r5, r1144mov r6, r2145bl lock_mutex_swp146str r5, [r6] /* Write the thread ID */147bl random_cycles148149# Save off the now cycle count */150mov r8, r0151152/* Print the thread ID and cycle count */153mov r0, r5154mov r1, #0155bl printnum156157/* Separator */158movw r0, :lower16:.L.idsep159movt r0, :upper16:.L.idsep160ldr r1, =(.L.idsepEnd - .L.idsep - 1)161bl print162163/* Cycle count */164mov r0, r8165mov r1, #1166bl printnum1671681:169ldr r0, [r6]170cmp r0, r5 /* Check against the thread ID */171bne 2f172str r5, [r6]173174/*175* Check if the count hit 0, otherwise go again.176*/177cmp r8, #0178beq 3f179sub r8, r8, #1180b 1b1811822:183/* exit(1) */184mov r0, #1185ldr r7, =SYS_exit186swi 01871883:189mov r0, r4190bl unlock_mutex_swp191192/*193* Yield to lower the chance that we end up re-acquiring, the other two194* threads are still actively trying to acquire the lock.195*/196ldr r7, =SYS_sched_yield197swi 0198199pop {r4, r5, r6, r7, r8, lr}200bx lr201202.p2align 2203.type random_cycles,%function204.code 32205random_cycles:206/* Return a random number < 4k */207sub sp, sp, #4208mov r0, sp209mov r1, #4210mov r2, #0211ldr r7, =SYS_getrandom212swi 0213214/*215* Just truncate the result of getrandom(2)216* to put us within range. Naive, but functional.217*/218ldr r0, [sp]219mov r1, #0xfff220and r0, r0, r1221add sp, sp, #4222bx lr223224/*225* lock_mutex_swp and unlock_mutex_swp lifted from226* ARM documentation on SWP/SWPB.227*/228.p2align 2229.type lock_mutex_swp,%function230.code 32231lock_mutex_swp:232mov r2, #MUTEX_LOCKED233swp r1, r2, [r0] /* Swap in lock value. */234cmp r1, r2 /* Check if we were locked already. */235beq lock_mutex_swp /* Retry if so */236bx lr /* Return locked */237238.p2align 2239.type unlock_mutex_swp,%function240.code 32241unlock_mutex_swp:242mov r1, #MUTEX_UNLOCKED243str r1, [r0] /* Move in unlocked */244bx lr245246.p2align 2247.type create_thr,%function248.code 32249create_thr:250/*251* r0 == start_func252* r1 == arg253* r2 == stack_base254* r3 == tls_base255*/256sub sp, sp, #56257str r0, [sp, #4] /* start_func */258str r1, [sp, #8] /* arg */259str r2, [sp, #12] /* stack_base */260mov r0, #STACK_SIZE261str r0, [sp, #16] /* stack_size */262str r3, [sp, #20] /* tls_base */263mov r0, #TLS_SIZE264str r0, [sp, #24] /* tls_size */265mov r0, #0266str r0, [sp, #28]267str r0, [sp, #32]268str r0, [sp, #36]269str r0, [sp, #40]270271add r0, sp, #4 /* &thrp */272mov r1, #52 /* sizeof(thrp) */273ldr r7, =SYS_thr_new274swi 0275276add sp, sp, #56277bx lr278279.p2align 2280.type printnum,%function281.code 32282printnum:283push {r4, r5, r6, r7, r8, r10, lr}284sub sp, #4285286/* 1000000000 */287movw r6, #0xca00288movt r6, #0x3b9a289290udiv r5, r0, r6291cmp r5, #9292bhi abort293294/* r4 is our accumulator */295mov r4, r0296/* r5 to be used as our "significant bit" */297mov r5, #0298/* r10 is "output_newline" */299mov r10, r13003011:302cmp r6, #0303beq 4f304305/* Divide by current place */306udiv r0, r4, r6307/* Significant already? print anyways */308cmp r5, #0309bne 2f310311/*312* Not significant, maybe print. If we made it all the way to 1, we313* need to just print the 0 anyways.314*/315cmp r6, #1316beq 2f317318cmp r0, #0319bne 2f320b 3f /* Proceed */321322/* Print */3232:324mov r5, #1325mov r8, r0326add r0, r0, #0x30327str r0, [sp]328mov r0, sp329mov r1, #1330bl print331332/* Multiply back into place and subtract from accumulator */333mul r0, r8, r6334sub r4, r4, r03353363:337mov r3, #10338udiv r6, r6, r3339b 1b3403414:342cmp r10, #0343beq 5f344345/* newline */346mov r0, #0x0a347str r0, [sp]348mov r0, sp349mov r1, #1350bl print3513525:353add sp, sp, #4354pop {r4, r5, r6, r7, r8, r10, lr}355bx lr356357abort:358movw r0, :lower16:.L.badnum359movt r0, :upper16:.L.badnum360ldr r1, =(.L.badnumEnd - .L.badnum - 1)361bl print362363mov r0, #1364ldr r7, =SYS_exit365swi 0366367.p2align 2368.type print,%function369.code 32370print:371/* r0 - string, r1 = size */372mov r2, r1373mov r1, r0374ldr r0, =STDOUT_FILENO375ldr r7, =SYS_write376swi 0377378bx lr379380.L.mainmsg:381.asciz "Main thread\n"382.L.mainmsgEnd:383.size .L.mainmsg, .L.mainmsgEnd - .L.mainmsg384.L.secondarymsg:385.asciz "Secondary thread\n"386.L.secondarymsgEnd:387.size .L.secondarymsg, .L.secondarymsgEnd - .L.secondarymsg388.L.badnum:389.asciz "Bad number\n"390.L.badnumEnd:391.size .L.badnum, .L.badnumEnd - .L.badnum392.L.idsep:393.asciz " - cycles "394.L.idsepEnd:395.size .L.idsep, .L.idsepEnd - .L.idsep396397.type stack1,%object398.local stack1399.comm stack1,STACK_SIZE,1400.type tls1,%object401.local tls1402.comm tls1,TLS_SIZE,1403404.type stack2,%object405.local stack2406.comm stack2,STACK_SIZE,1407.type tls2,%object408.local tls2409.comm tls2,TLS_SIZE,1410411412