Skip to content

Commit

Permalink
rewrite inline asm blocks with single instructions
Browse files Browse the repository at this point in the history
Apparently Clang actually parses them, so perhaps let's make its job a
little bit easier.
  • Loading branch information
dmitmel committed Nov 7, 2023
1 parent 23ce415 commit 9a0f999
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 80 deletions.
24 changes: 16 additions & 8 deletions src/stmes/kernel/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
23 changes: 13 additions & 10 deletions src/stmes/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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().
Expand Down Expand Up @@ -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) {
Expand Down
62 changes: 0 additions & 62 deletions src/stmes/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 9a0f999

Please sign in to comment.