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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
/*
* QuickThreads -- Threads-building toolkit.
* Copyright (c) 1993 by David Keppel
*
* Permission to use, copy, modify and distribute this software and
* its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice and this notice
* appear in all copies. This software is provided as a
* proof-of-concept and for demonstration purposes; there is no
* representation about the suitability of this software for any
* purpose.
*/
/* axp.s -- assembly support. */
.text
.align 4
.file 2 "axp.s"
.globl qt_block
.globl qt_blocki
.globl qt_abort
.globl qt_start
.globl qt_vstart
/*
** $16: ptr to function to call once curr is suspended
** and control is on r19's stack.
** $17: 1'th arg to (*$16)(...).
** $18: 2'th arg to (*$16)(...).
** $19: sp of thread to resume.
**
** The helper routine returns a value that is passed on as the
** return value from the blocking routine. Since we don't
** touch r0 between the helper's return and the end of
** function, we get this behavior for free.
*/
.ent qt_blocki
qt_blocki:
subq $30,80, $30 /* Allocate save area. */
stq $26, 0($30) /* Save registers. */
stq $9, 8($30)
stq $10,16($30)
stq $11,24($30)
stq $12,32($30)
stq $13,40($30)
stq $14,48($30)
stq $15,56($30)
stq $29,64($30)
.end qt_blocki
.ent qt_abort
qt_abort:
addq $16,$31, $27 /* Put argument function in PV. */
addq $30,$31, $16 /* Save stack ptr in outgoing arg. */
addq $19,$31, $30 /* Set new stack pointer. */
jsr $26,($27),0 /* Call helper function. */
ldq $26, 0($30) /* Restore registers. */
ldq $9, 8($30)
ldq $10,16($30)
ldq $11,24($30)
ldq $12,32($30)
ldq $13,40($30)
ldq $14,48($30)
ldq $15,56($30)
ldq $29,64($30)
addq $30,80, $30 /* Deallocate save area. */
ret $31,($26),1 /* Return, predict===RET. */
.end qt_abort
/*
** Non-varargs thread startup.
*/
.ent qt_start
qt_start:
addq $9,$31, $16 /* Load up `qu'. */
addq $10,$31, $17 /* ... user function's `pt'. */
addq $11,$31, $18 /* ... user function's `userf'. */
addq $12,$31, $27 /* ... set procedure value to `only'. */
jsr $26,($27),0 /* Call `only'. */
jsr $26,qt_error /* `only' erroniously returned. */
.end qt_start
.ent qt_vstart:
qt_vstart:
/* Call startup function. */
addq $9,$31, $16 /* Arg0 to `startup'. */
addq $12,$31, $27 /* Set procedure value. */
jsr $26,($27),0 /* Call `startup'. */
/* Call user function. */
ldt $f16, 0($30) /* Load fp arg regs. */
ldt $f17, 8($30)
ldt $f18,16($30)
ldt $f19,24($30)
ldt $f20,32($30)
ldt $f21,40($30)
ldq $16,48($30) /* And integer arg regs. */
ldq $17,56($30)
ldq $18,64($30)
ldq $19,72($30)
ldq $20,80($30)
ldq $21,88($30)
addq $30,96 $30 /* Pop 6*2*8 saved arg regs. */
addq $11,$31, $27 /* Set procedure value. */
jsr $26,($27),0 /* Call `vuserf'. */
/* Call cleanup. */
addq $9,$31, $16 /* Arg0 to `cleanup'. */
addq $0,$31, $17 /* Users's return value is arg1. */
addq $10,$31, $27 /* Set procedure value. */
jsr $26,($27),0 /* Call `cleanup'. */
jsr $26,qt_error /* Cleanup erroniously returned. */
.end qt_start
/*
** Save calle-save floating-point regs $f2..$f9.
** Also save return pc from whomever called us.
**
** Return value from `qt_block' is the same as the return from
** `qt_blocki'. We get that for free since we don't touch $0
** between the return from `qt_blocki' and the return from
** `qt_block'.
*/
.ent qt_block
qt_block:
subq $30,80, $30 /* Allocate a save space. */
stq $26, 0($30) /* Save registers. */
stt $f2, 8($30)
stt $f3,16($30)
stt $f4,24($30)
stt $f5,32($30)
stt $f6,40($30)
stt $f7,48($30)
stt $f8,56($30)
stt $f9,64($30)
jsr $26,qt_blocki /* Call helper. */
/* .. who will also restore $gp. */
ldq $26, 0($30) /* restore registers. */
ldt $f2, 8($30)
ldt $f3,16($30)
ldt $f4,24($30)
ldt $f5,32($30)
ldt $f6,40($30)
ldt $f7,48($30)
ldt $f8,56($30)
ldt $f9,64($30)
addq $30,80, $30 /* Deallcate save space. */
ret $31,($26),1 /* Return, predict===RET. */
.end qt_block
|