summaryrefslogtreecommitdiff
path: root/config/aix/rswitch.s
diff options
context:
space:
mode:
Diffstat (limited to 'config/aix/rswitch.s')
-rw-r--r--config/aix/rswitch.s52
1 files changed, 52 insertions, 0 deletions
diff --git a/config/aix/rswitch.s b/config/aix/rswitch.s
new file mode 100644
index 0000000..45a1341
--- /dev/null
+++ b/config/aix/rswitch.s
@@ -0,0 +1,52 @@
+# coswitch(old, new, first)
+# GPR3 GPR4 GPR5
+
+ .file "rswitch.s"
+ .extern .new_context{PR}
+ .extern .syserr{PR}
+ .globl .coswitch[PR]
+ .csect .coswitch[PR]
+
+ .set r0, 0
+ .set SP, 1
+ .set TOC, 2
+ .set OLD, 3
+ .set NEW, 4
+ .set FIRST, 5
+ .set RSIZE, 80 # room for regs 13-31, rounded up mod16
+
+.coswitch:
+ stu SP, -RSIZE(SP) # allocate stack frame
+
+ # Save Old Context:
+ st SP, 0(OLD) # SP
+ st TOC, 4(OLD) # TOC
+ mflr r0
+ st r0, 8(OLD) # LR (return address)
+ mfcr r0
+ st r0, 12(OLD) # CR
+ stm 13, -RSIZE(SP) # GPRs 13-31 (save on stack)
+
+ cmpi 0, FIRST, 0
+ beq first # if first time
+
+ # Restore new context:
+ l SP, 0(NEW) # SP
+ l TOC, 4(NEW) # TOC
+ l r0, 8(NEW) # LR
+ mtlr r0
+ l r0, 12(NEW) # CR
+ mtcr r0
+ lm 13, -RSIZE(SP) # GPRs 13-31 (from stack)
+
+ ai SP, SP, RSIZE # deallocate stack frame
+ brl # return into new context
+
+first: # First-time call:
+ l SP, 0(NEW) # SP as figured by Icon
+ ai SP, SP, -64(SP) # save area for callee
+ cal OLD, 0(r0) # arg1
+ cal NEW, 0(r0) # arg2
+ bl .new_context{PR} # new_context(0,0)
+ cal OLD, 0(r0)
+ bl .syserr{PR}