From 8f424d49e839f2a9bd0b4bba42919fc495e16aac Mon Sep 17 00:00:00 2001 From: fef Date: Sun, 1 Aug 2021 01:16:13 +0200 Subject: [PATCH] asm: refactor to use thumb2 instructions --- arch/at91sam3x8e/irq_pend_sv.S | 42 +++++------------------------ arch/at91sam3x8e/irq_svc.S | 29 ++++---------------- arch/at91sam3x8e/syscall.S | 48 ++++++++++++---------------------- 3 files changed, 28 insertions(+), 91 deletions(-) diff --git a/arch/at91sam3x8e/irq_pend_sv.S b/arch/at91sam3x8e/irq_pend_sv.S index 9466664..ea618ab 100644 --- a/arch/at91sam3x8e/irq_pend_sv.S +++ b/arch/at91sam3x8e/irq_pend_sv.S @@ -1,24 +1,13 @@ /* See the end of this file for copyright, license, and warranty information. */ -.syntax unified -.thumb +.include "asm.S" .text .extern sched_process_switch -.thumb_func -.global irq_pend_sv -.type irq_pend_sv, %function - /* void irq_pend_sv(void); */ -irq_pend_sv: - /* - * There seems to be a limitation in Thumb which prohibits popping to - * any register > r7. Hence, we need to split the PUSHes and POPs into - * multiple operations and MOV register values around. - */ - +func_begin irq_pend_sv /* * Some registers have already been saved by hardware at this point, * we only need to take care of r4-r11 and lr (the latter of which is @@ -26,17 +15,10 @@ irq_pend_sv: * The stuff we push onto the stack manually looks about like this: * * <<< stack grow direction (decreasing addresses) <<< - * r8 r9 r10 r11 lr r4 r5 r6 r7 + * r4 r5 r6 r7 r8 r9 r10 r11 lr */ - push {r4-r7} /* r4-r7 */ - - mov r3, r8 - mov r4, r9 - mov r5, r10 - mov r6, r11 - mov r7, lr - push {r3-r7} /* r8-r11, lr */ + push {r4-r11,lr} /* * Now that our stack is completely saved, we can proceed to call the @@ -54,23 +36,11 @@ irq_pend_sv: * just in reverse order. */ - pop {r3-r7} /* r8-r11, lr */ - mov lr, r7 - mov r11, r6 - mov r10, r5 - mov r9, r4 - mov r8, r3 + pop {r4-r11,lr} - pop {r4-r7} /* r4-r7 */ - - /* - * ... and now get the fuck outta here, hoping I never need to touch - * this again, even though deep inside I know I will return here at some - * point because something broke (or I feel the need to micro-optimize). - */ bx lr -.size irq_pend_sv, .-irq_pend_sv +func_end irq_pend_sv /* * This file is part of Ardix. diff --git a/arch/at91sam3x8e/irq_svc.S b/arch/at91sam3x8e/irq_svc.S index cc318e7..53821ea 100644 --- a/arch/at91sam3x8e/irq_svc.S +++ b/arch/at91sam3x8e/irq_svc.S @@ -1,18 +1,13 @@ /* See the end of this file for copyright, license, and warranty information. */ -.syntax unified -.thumb +.include "asm.S" .text .extern arch_enter -.thumb_func -.global irq_svc -.type irq_svc, %function - /* void irq_svc(void); */ -irq_svc: +func_begin irq_svc /* * Syscalls on Cortex-M use the following parameter calling convention: * @@ -30,30 +25,16 @@ irq_svc: * like in irq_pend_sv, we save everything on the stack to make early * process switching possible in case the syscall is blocking. */ - push {r4-r7} /* r4-r7 */ - - mov r3, r8 - mov r4, r9 - mov r5, r10 - mov r6, r11 - mov r7, lr - push {r3-r7} /* r8-r11, lr */ + push {r3-r11,lr} /* r4-r7 */ mov r0, sp bl arch_enter /* arch_enter(sp); */ - pop {r3-r7} /* r8-r11, lr */ - mov lr, r7 - mov r11, r6 - mov r10, r5 - mov r9, r4 - mov r8, r3 - - pop {r4-r7} /* r4-r7 */ + pop {r3-r11,lr} bx lr -.size irq_svc, .-irq_svc +func_end irq_svc /* * This file is part of Ardix. diff --git a/arch/at91sam3x8e/syscall.S b/arch/at91sam3x8e/syscall.S index 5942f82..b22b597 100644 --- a/arch/at91sam3x8e/syscall.S +++ b/arch/at91sam3x8e/syscall.S @@ -1,45 +1,31 @@ /* See the end of this file for copyright, license, and warranty information. */ -.syntax unified -.thumb +.include "asm.S" /* this is only invoked from user space, obviously */ .section .text.shared -.thumb_func -.global syscall -.type syscall, %function /* int syscall(int number, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6); */ -syscall: - push {r4-r5,r7} +func_begin syscall /* - * I HAVE NO IDEA WHY THE F U C K GCC THINKS I CAN'T MOV TWO LOW REGS - * IN ONE INSTRUCTION WHEN THAT IS L I T E R A L L Y IN THE ASM OUTPUT - * OF GCC WHEN COMPILING SOME C CODE. BUT AT THIS POINT, I WON'T EVEN - * BOTHER WITH WHATEVER SHITTY COMPILE OPTION OR PREPROCESSOR DIRECTIVE - * I HAVE TO TURN ON IN ORDER FOR THIS PIECE OF SHIT THAT DARES CALLING - * ITSELF A COMPILER TO EAT MY SHIT CODE AND SHIT OUT THE SHITTY BINARY - * I WANT. FUCK YOU, SYSCALLS WILL JUST TAKE 8 INSTRUCTIONS MORE. + * arg | syscall | AAPCS + * -------|---------|--------- + * number | r7 | r0 + * arg1 | r0 | r1 + * arg2 | r1 | r2 + * arg3 | r2 | r3 + * arg4 | r3 | sp + 0 + * arg5 | r4 | sp + 4 + * arg6 | r5 | sp + 8 */ - mov r4, r12 - push {r4} + push {r4-r5,r7} - mov r12, r0 /* syscall number */ - mov r7, r12 - - mov r12, r1 /* arg1 */ - mov r0, r12 - - mov r12, r2 /* arg2 */ - mov r1, r12 - - mov r12, r3 /* arg3 */ - mov r2, r12 - - pop {r4} - mov r12, r4 + mov r7, r0 /* number */ + mov r0, r1 /* arg1 */ + mov r1, r2 /* arg2 */ + mov r2, r3 /* arg3 */ /* stack params begin at 12 bytes offset because we already pushed three registers */ ldr r3, [sp, #12] /* arg4 */ @@ -53,7 +39,7 @@ syscall: /* r0 (return value) is set by the kernel */ bx lr -.size syscall, .-syscall +func_end syscall /* * This file is part of Ardix.