From 9a0f9994ed4ba01258a54525b6c9a3ee2d29ad5e Mon Sep 17 00:00:00 2001 From: Dmytro Meleshko Date: Tue, 7 Nov 2023 17:03:40 +0100 Subject: [PATCH] rewrite inline asm blocks with single instructions Apparently Clang actually parses them, so perhaps let's make its job a little bit easier. --- src/stmes/kernel/task.c | 24 ++++++++++------ src/stmes/main.c | 23 ++++++++------- src/stmes/utils.h | 62 ----------------------------------------- 3 files changed, 29 insertions(+), 80 deletions(-) diff --git a/src/stmes/kernel/task.c b/src/stmes/kernel/task.c index 70cef49..366bd42 100644 --- a/src/stmes/kernel/task.c +++ b/src/stmes/kernel/task.c @@ -385,12 +385,16 @@ static void syscall_handler_entry(usize arg1, usize arg2, usize arg3, enum Sysca // largely to be a barrier for debugger's stack trace unwinder (by being // implemented in assembly and having no hint directives whatsoever). static __NO_RETURN __NAKED void task_launchpad(__UNUSED void* user_data, __UNUSED TaskFn* func) { - // Call the function passed in the second parameter with the user data as its - // first parameter which is already in r0. - __ASM volatile("blx r1"); - __ASM volatile("bl %0" ::"i"(&task_exit)); - // The task has been terminated, a return here must cause a fault. - __ASM volatile("udf #0"); + __ASM volatile( // + // Call the function passed in the second parameter with the user data as + // its first parameter which is already in r0. + "blx r1\n\t" + // Call task_exit() if the task function has returned. + "bl %0\n\t" + // The task has been terminated, a return here must cause a fault. + "udf #0" :: // + "i"(&task_exit) + ); } void task_spawn(struct Task* task, const struct TaskParams* params) { @@ -637,8 +641,12 @@ static __NAKED void context_switch(__UNUSED enum Syscall syscall_nr) { __NAKED void PendSV_Handler(void) { // The PendSV handler effectively emulates the DEFERRED_YIELD syscall. - __ASM volatile("movs r0, %0" ::"n"(SYSCALL_DEFERRED_YIELD)); - __ASM volatile("b %0" ::"i"(&context_switch)); + __ASM volatile( // + "movs r0, %0\n\t" + "b %1" :: // + "n"(SYSCALL_DEFERRED_YIELD), + "i"(&context_switch) + ); } __NAKED void SVC_Handler(void) { diff --git a/src/stmes/main.c b/src/stmes/main.c index 2e23e14..3d13993 100644 --- a/src/stmes/main.c +++ b/src/stmes/main.c @@ -43,13 +43,16 @@ int main(void) { // functions can be executed on boot right away, however, some setup needs to // be done first before we can reach main(). __NAKED void Reset_Handler(void) { - // Pass the initial stack pointer as the first argument (the need to be able - // to read it is the reason for writing the reset handler in assembly). - __ASM volatile("mov r0, sp"); - // Call the prestart() function. - __ASM volatile("bl %0" ::"i"(&prestart)); - // Execution should never return here, trigger an exception if it did. - __ASM volatile("udf #0"); + __ASM volatile( // + // Pass the initial stack pointer as the first argument (the need to be + // able to read it is the reason for writing the reset handler in assembly) + "mov r0, sp\n\t" + // Call the prestart() function. + "bl %0\n\t" + // Execution should never return here, trigger an exception if it did. + "udf #0" :: // + "i"(&prestart) + ); } // Performs the early boot sequence and eventually calls main(). @@ -129,10 +132,10 @@ static __NAKED void main_task_launcher(__UNUSED void* initial_stack_ptr) { "msr msp, r0\n\t" // MSP = initial_stack_ptr; "isb\n\t" // apply the changes "cpsie i\n\t" // __enable_irq(); + // And now, tail-call main() (this is the reason for writing this wrapper + // in assembly: to not waste any stack space before even entering main()). + "b %0" ::"i"(&main) ); - // And now the main() can be tail-called (this is the reason for writing this - // wrapper in assembly: to not waste any stack space before entering main()). - __ASM volatile("b %0" ::"i"(&main)); } void HAL_MspInit(void) { diff --git a/src/stmes/utils.h b/src/stmes/utils.h index d734410..109a108 100644 --- a/src/stmes/utils.h +++ b/src/stmes/utils.h @@ -82,68 +82,6 @@ void fast_memcpy_u32(u32* dst, const u32* src, usize n); #define WAIT_FOR_EVENT() __WFE() #define WAIT_FOR_INTERRUPT() __WFI() -#define __ldmia2(ptr, r1, r2, a, b) \ - do { \ - register u32 __a __ASM(r1); \ - register u32 __b __ASM(r2); \ - register u32* __ptr = *(ptr); \ - __ASM("ldmia %0!, {%1, %2}" : "+r"(__ptr), "=r"(__a), "=r"(__b) : "m"(*(u32(*)[2])__ptr)); \ - *(ptr) = __ptr, *(a) = __a, *(b) = __b; \ - } while (0) - -#define __ldmia4(ptr, r1, r2, r3, r4, a, b, c, d) \ - do { \ - register u32 __a __ASM(r1); \ - register u32 __b __ASM(r2); \ - register u32 __c __ASM(r3); \ - register u32 __d __ASM(r4); \ - register u32* __ptr = *(ptr); \ - __ASM("ldmia %0!, {%1, %2, %3, %4}" \ - : "+r"(__ptr), "=r"(__a), "=r"(__b), "=r"(__c), "=r"(__d) \ - : "m"(*(u32(*)[4])__ptr)); \ - *(ptr) = __ptr, *(a) = __a, *(b) = __b, *(c) = __c, *(d) = __d; \ - } while (0) - -#define __ldmia8(ptr, r1, r2, r3, r4, r5, r6, r7, r8, a, b, c, d, e, f, g, h) \ - do { \ - register u32 __a __ASM(r1); \ - register u32 __b __ASM(r2); \ - register u32 __c __ASM(r3); \ - register u32 __d __ASM(r4); \ - register u32 __e __ASM(r5); \ - register u32 __f __ASM(r6); \ - register u32 __g __ASM(r7); \ - register u32 __h __ASM(r8); \ - register u32* __ptr = *(ptr); \ - __ASM("ldmia %0!, {%1, %2, %3, %4, %5, %6, %7, %8}" \ - : "+r"(__ptr), \ - "=r"(__a), \ - "=r"(__b), \ - "=r"(__c), \ - "=r"(__d), \ - "=r"(__e), \ - "=r"(__f), \ - "=r"(__g), \ - "=r"(__h) \ - : "m"(*(u32(*)[8])__ptr)); \ - *(ptr) = __ptr; \ - *(a) = __a, *(b) = __b, *(c) = __c, *(d) = __d; \ - *(e) = __e, *(f) = __f, *(g) = __g, *(h) = __h; \ - } while (0) - -#define __stmia4(ptr, r1, r2, r3, r4, a, b, c, d) \ - do { \ - register u32 __a __ASM(r1) = (a); \ - register u32 __b __ASM(r2) = (b); \ - register u32 __c __ASM(r3) = (c); \ - register u32 __d __ASM(r4) = (d); \ - register u32* __ptr = *(ptr); \ - __ASM("stmia %1!, {%2, %3, %4, %5}" \ - : "=m"(*(u32(*)[4])__ptr), "+r"(__ptr) \ - : "r"(__a), "r"(__b), "r"(__c), "r"(__d)); \ - *(ptr) = __ptr; \ - } while (0) - #define BITBAND_ADDR(base, bb_base, addr, bit) \ ((volatile u32*)(bb_base + 32ul * ((usize)(addr) - (base)) + 4ul * (bit))) #define SRAM1_BITBAND_ADDR(addr, bit) BITBAND_ADDR(SRAM1_BASE, SRAM1_BB_BASE, addr, bit)