1/* m88k.s -- assembly support. */
2
3/*
4 * QuickThreads -- Threads-building toolkit.
5 * Copyright (c) 1993 by David Keppel
6 *
7 * Permission to use, copy, modify and distribute this software and
8 * its documentation for any purpose and without fee is hereby
9 * granted, provided that the above copyright notice and this notice
10 * appear in all copies.  This software is provided as a
11 * proof-of-concept and for demonstration purposes; there is no
12 * representation about the suitability of this software for any
13 * purpose.
14 */
15
16/* Callee-save r14..r25, r31(sp), r30(fp).  r1 === return pc.
17 * Argument registers r2..r9, return value r2..r3.
18 *
19 * On startup, restore regs so retpc === call to a function to start.
20 *
21 * We're going to call a function (r2) from within the context switch
22 * routine.  Call it on the new thread's stack on behalf of the old
23 * thread.
24 */
25
26	.globl _qt_block
27	.globl _qt_blocki
28	.globl _qt_abort
29	.globl _qt_start
30	.globl _qt_vstart
31
32	/*
33	** r2: ptr to function to call once curr is suspended
34	**	and control is on r5's stack.
35	** r3: 1'th arg to *r2.
36	** r4: 2'th arg to *r2.
37	** r5: sp of thread to suspend.
38	**
39	** The helper routine returns a value that is passed on as the
40	** return value from the blocking routine.  Since we don't
41	** touch r2 between the helper's return and the end of
42	** function, we get this behavior for free.
43	**
44	** Same entry for integer-only and floating-point, since there
45	** are no separate integer and floating-point registers.
46	**
47	** Each procedure call sets aside a ``home region'' of 8 regs
48	** for r2-r9 for varargs.  For context switches we don't use
49	** the ``home region'' for varargs so use it to save regs.
50	** Allocate 64 bytes of save space -- use 32 bytes of register
51	** save area passed in to us plus 32 bytes we allcated, use
52	** the other 32 bytes for save area for a save area to call
53	** the helper function.
54	*/
55_qt_block:
56_qt_blocki:
57	sub r31, r31,64		/* Allocate reg save space. */
58	st r1, r31,8+32		/* Save callee-save registers. */
59	st r14, r31,12+32
60	st.d r15, r31,16+32
61	st.d r17, r31,24+32
62	st.d r19, r31,32+32
63	st.d r21, r31,40+32
64	st.d r23, r31,48+32
65	st r25, r31,56+32
66	st r30, r31,60+32
67
68_qt_abort:
69	addu r14, r31,0		/* Remember old sp. */
70	addu r31, r5,0		/* Set new sp. */
71	jsr.n r2		/* Call helper. */
72	addu r2, r14,0		/* Pass old sp as an arg0 to helper. */
73
74	ld r1, r31,8+32		/* Restore callee-save registers. */
75	ld r14, r31,12+32
76	ld.d r15, r31,16+32
77	ld.d r17, r31,24+32
78	ld.d r19, r31,32+32
79	ld.d r21, r31,40+32
80	ld.d r23, r31,48+32
81	ld r25, r31,56+32
82	ld r30, r31,60+32
83
84	jmp.n r1		/* Return to new thread's caller. */
85	addu r31, r31,64	/* Free register save space. */
86
87
88	/*
89	** Non-varargs thread startup.
90	** See `m88k.h' for register use conventions.
91	*/
92_qt_start:
93	addu r2, r14,0		/* Set user arg `pu'. */
94	addu r3, r15,0		/* ... user function pt. */
95	jsr.n r17		/* Call `only'. */
96	addu r4, r16,0		/* ... user function userf. */
97
98	bsr _qt_error		/* `only' erroniously returned. */
99
100
101	/*
102	** Varargs thread startup.
103	** See `m88k.h' for register use conventions.
104	**
105	** Call the `startup' function with just argument `pt'.
106	** Then call `vuserf' with 8 register args plus any
107	** stack args.
108	** Then call `cleanup' with `pt' and the return value
109	** from `vuserf'.
110	*/
111_qt_vstart:
112	addu r18, r30,0		/* Remember arg7 to `vuserf'. */
113	addu r30, r0,0		/* Null-terminate call chain. */
114
115	jsr.n r17		/* Call `startup'. */
116	addu r2, r15,0		/* `pt' is arg0 to `startup'. */
117
118	addu r2, r19,0		/* Set arg0. */
119	addu r3, r20,0		/* Set arg1. */
120	addu r4, r21,0		/* Set arg2. */
121	addu r5, r22,0		/* Set arg3. */
122	addu r6, r23,0		/* Set arg4. */
123	addu r7, r24,0		/* Set arg5. */
124	addu r8, r25,0		/* Set arg6. */
125	jsr.n r16		/* Call `vuserf'. */
126	addu r9, r18,0		/* Set arg7. */
127
128	addu r3, r2,0		/* Ret. value is arg1 to `cleanup'. */
129	jsr.n r14		/* Call `cleanup'. */
130	addu r2, r15,0		/* `pt' is arg0 to `cleanup'. */
131
132	bsr _qt_error		/* `cleanup' erroniously returned. */
133