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