diff options
Diffstat (limited to 'config/aix/rswitch.s')
-rw-r--r-- | config/aix/rswitch.s | 52 |
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} |