aboutsummaryrefslogtreecommitdiff
path: root/lib/arch/arm/yield.s
diff options
context:
space:
mode:
Diffstat (limited to 'lib/arch/arm/yield.s')
-rw-r--r--lib/arch/arm/yield.s32
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/arch/arm/yield.s b/lib/arch/arm/yield.s
new file mode 100644
index 0000000..de9d604
--- /dev/null
+++ b/lib/arch/arm/yield.s
@@ -0,0 +1,32 @@
+# Copyright (c) 2021 Johannes Stoelp
+
+ .arch armv7-a
+ .section .text, "ax", %progbits
+
+ # extern "C" void yield(const void* new_stack, void** old_stack);
+ # ^^^^^^^^^ ^^^^^^^^^
+ # x0 x1
+ .global yield
+ .type yield, %function
+yield:
+ .cfi_startproc
+ // prologue
+ push {fp, lr}
+ mov fp, sp
+
+ // push callee saved registers
+ push {r4-r11}
+
+ // arg0: r0 holds new stack
+ // arg1: r1 holds addr to location current stack must be saved
+ mov r2, sp
+ str r2, [r1] // save current stack ptr
+ mov sp, r0 // switch to new stack ptr
+
+ // pop callee saved registers
+ pop {r4-r11}
+
+ // epilogue
+ pop {fp, pc}
+ .cfi_endproc
+ .size yield, .-yield