1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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}
|