asm: refactor to use thumb2 instructions

This commit is contained in:
anna 2021-08-01 01:16:13 +02:00
parent a78a8ba59b
commit 8f424d49e8
Signed by: fef
GPG key ID: EC22E476DC2D3D84
3 changed files with 28 additions and 91 deletions

View file

@ -1,24 +1,13 @@
/* See the end of this file for copyright, license, and warranty information. */ /* See the end of this file for copyright, license, and warranty information. */
.syntax unified .include "asm.S"
.thumb
.text .text
.extern sched_process_switch .extern sched_process_switch
.thumb_func
.global irq_pend_sv
.type irq_pend_sv, %function
/* void irq_pend_sv(void); */ /* void irq_pend_sv(void); */
irq_pend_sv: func_begin 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.
*/
/* /*
* Some registers have already been saved by hardware at this point, * 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 * 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: * The stuff we push onto the stack manually looks about like this:
* *
* <<< stack grow direction (decreasing addresses) <<< * <<< 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 */ push {r4-r11,lr}
mov r3, r8
mov r4, r9
mov r5, r10
mov r6, r11
mov r7, lr
push {r3-r7} /* r8-r11, lr */
/* /*
* Now that our stack is completely saved, we can proceed to call the * Now that our stack is completely saved, we can proceed to call the
@ -54,23 +36,11 @@ irq_pend_sv:
* just in reverse order. * just in reverse order.
*/ */
pop {r3-r7} /* r8-r11, lr */ pop {r4-r11,lr}
mov lr, r7
mov r11, r6
mov r10, r5
mov r9, r4
mov r8, r3
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 bx lr
.size irq_pend_sv, .-irq_pend_sv func_end irq_pend_sv
/* /*
* This file is part of Ardix. * This file is part of Ardix.

View file

@ -1,18 +1,13 @@
/* See the end of this file for copyright, license, and warranty information. */ /* See the end of this file for copyright, license, and warranty information. */
.syntax unified .include "asm.S"
.thumb
.text .text
.extern arch_enter .extern arch_enter
.thumb_func
.global irq_svc
.type irq_svc, %function
/* void irq_svc(void); */ /* void irq_svc(void); */
irq_svc: func_begin irq_svc
/* /*
* Syscalls on Cortex-M use the following parameter calling convention: * 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 * like in irq_pend_sv, we save everything on the stack to make early
* process switching possible in case the syscall is blocking. * process switching possible in case the syscall is blocking.
*/ */
push {r4-r7} /* r4-r7 */ push {r3-r11,lr} /* r4-r7 */
mov r3, r8
mov r4, r9
mov r5, r10
mov r6, r11
mov r7, lr
push {r3-r7} /* r8-r11, lr */
mov r0, sp mov r0, sp
bl arch_enter /* arch_enter(sp); */ bl arch_enter /* arch_enter(sp); */
pop {r3-r7} /* r8-r11, lr */ pop {r3-r11,lr}
mov lr, r7
mov r11, r6
mov r10, r5
mov r9, r4
mov r8, r3
pop {r4-r7} /* r4-r7 */
bx lr bx lr
.size irq_svc, .-irq_svc func_end irq_svc
/* /*
* This file is part of Ardix. * This file is part of Ardix.

View file

@ -1,45 +1,31 @@
/* See the end of this file for copyright, license, and warranty information. */ /* See the end of this file for copyright, license, and warranty information. */
.syntax unified .include "asm.S"
.thumb
/* this is only invoked from user space, obviously */ /* this is only invoked from user space, obviously */
.section .text.shared .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); */ /* int syscall(int number, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6); */
syscall: func_begin syscall
push {r4-r5,r7}
/* /*
* I HAVE NO IDEA WHY THE F U C K GCC THINKS I CAN'T MOV TWO LOW REGS * arg | syscall | AAPCS
* 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 * number | r7 | r0
* BOTHER WITH WHATEVER SHITTY COMPILE OPTION OR PREPROCESSOR DIRECTIVE * arg1 | r0 | r1
* I HAVE TO TURN ON IN ORDER FOR THIS PIECE OF SHIT THAT DARES CALLING * arg2 | r1 | r2
* ITSELF A COMPILER TO EAT MY SHIT CODE AND SHIT OUT THE SHITTY BINARY * arg3 | r2 | r3
* I WANT. FUCK YOU, SYSCALLS WILL JUST TAKE 8 INSTRUCTIONS MORE. * arg4 | r3 | sp + 0
* arg5 | r4 | sp + 4
* arg6 | r5 | sp + 8
*/ */
mov r4, r12 push {r4-r5,r7}
push {r4}
mov r12, r0 /* syscall number */ mov r7, r0 /* number */
mov r7, r12 mov r0, r1 /* arg1 */
mov r1, r2 /* arg2 */
mov r12, r1 /* arg1 */ mov r2, r3 /* arg3 */
mov r0, r12
mov r12, r2 /* arg2 */
mov r1, r12
mov r12, r3 /* arg3 */
mov r2, r12
pop {r4}
mov r12, r4
/* stack params begin at 12 bytes offset because we already pushed three registers */ /* stack params begin at 12 bytes offset because we already pushed three registers */
ldr r3, [sp, #12] /* arg4 */ ldr r3, [sp, #12] /* arg4 */
@ -53,7 +39,7 @@ syscall:
/* r0 (return value) is set by the kernel */ /* r0 (return value) is set by the kernel */
bx lr bx lr
.size syscall, .-syscall func_end syscall
/* /*
* This file is part of Ardix. * This file is part of Ardix.