summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/qt/md/m88k.s
blob: 42467e8d5ab709023403c5a888fe246695704e54 (plain)
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
/* m88k.s -- assembly support. */

/*
 * 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.
 */

/* Callee-save r14..r25, r31(sp), r30(fp).  r1 === return pc.
 * Argument registers r2..r9, return value r2..r3.
 *
 * On startup, restore regs so retpc === call to a function to start.
 *
 * We're going to call a function (r2) from within the context switch
 * routine.  Call it on the new thread's stack on behalf of the old
 * thread.
 */

	.globl _qt_block
	.globl _qt_blocki
	.globl _qt_abort
	.globl _qt_start
	.globl _qt_vstart

	/*
	** r2: ptr to function to call once curr is suspended
	**	and control is on r5's stack.
	** r3: 1'th arg to *r2.
	** r4: 2'th arg to *r2.
	** r5: sp of thread to suspend.
	**
	** The helper routine returns a value that is passed on as the
	** return value from the blocking routine.  Since we don't
	** touch r2 between the helper's return and the end of
	** function, we get this behavior for free.
	**
	** Same entry for integer-only and floating-point, since there
	** are no separate integer and floating-point registers.
	**
	** Each procedure call sets aside a ``home region'' of 8 regs
	** for r2-r9 for varargs.  For context switches we don't use
	** the ``home region'' for varargs so use it to save regs.
	** Allocate 64 bytes of save space -- use 32 bytes of register
	** save area passed in to us plus 32 bytes we allcated, use
	** the other 32 bytes for save area for a save area to call
	** the helper function.
	*/
_qt_block:
_qt_blocki:
	sub r31, r31,64		/* Allocate reg save space. */
	st r1, r31,8+32		/* Save callee-save registers. */
	st r14, r31,12+32
	st.d r15, r31,16+32
	st.d r17, r31,24+32
	st.d r19, r31,32+32
	st.d r21, r31,40+32
	st.d r23, r31,48+32
	st r25, r31,56+32
	st r30, r31,60+32

_qt_abort:
	addu r14, r31,0		/* Remember old sp. */
	addu r31, r5,0		/* Set new sp. */
	jsr.n r2		/* Call helper. */
	addu r2, r14,0		/* Pass old sp as an arg0 to helper. */

	ld r1, r31,8+32		/* Restore callee-save registers. */
	ld r14, r31,12+32
	ld.d r15, r31,16+32
	ld.d r17, r31,24+32
	ld.d r19, r31,32+32
	ld.d r21, r31,40+32
	ld.d r23, r31,48+32
	ld r25, r31,56+32
	ld r30, r31,60+32

	jmp.n r1		/* Return to new thread's caller. */
	addu r31, r31,64	/* Free register save space. */


	/*
	** Non-varargs thread startup.
	** See `m88k.h' for register use conventions.
	*/
_qt_start:
	addu r2, r14,0		/* Set user arg `pu'. */
	addu r3, r15,0		/* ... user function pt. */
	jsr.n r17		/* Call `only'. */
	addu r4, r16,0		/* ... user function userf. */

	bsr _qt_error		/* `only' erroniously returned. */


	/*
	** Varargs thread startup.
	** See `m88k.h' for register use conventions.
	**
	** Call the `startup' function with just argument `pt'.
	** Then call `vuserf' with 8 register args plus any
	** stack args.
	** Then call `cleanup' with `pt' and the return value
	** from `vuserf'.
	*/
_qt_vstart:
	addu r18, r30,0		/* Remember arg7 to `vuserf'. */
	addu r30, r0,0		/* Null-terminate call chain. */

	jsr.n r17		/* Call `startup'. */
	addu r2, r15,0		/* `pt' is arg0 to `startup'. */

	addu r2, r19,0		/* Set arg0. */
	addu r3, r20,0		/* Set arg1. */
	addu r4, r21,0		/* Set arg2. */
	addu r5, r22,0		/* Set arg3. */
	addu r6, r23,0		/* Set arg4. */
	addu r7, r24,0		/* Set arg5. */
	addu r8, r25,0		/* Set arg6. */
	jsr.n r16		/* Call `vuserf'. */
	addu r9, r18,0		/* Set arg7. */

	addu r3, r2,0		/* Ret. value is arg1 to `cleanup'. */
	jsr.n r14		/* Call `cleanup'. */
	addu r2, r15,0		/* `pt' is arg0 to `cleanup'. */

	bsr _qt_error		/* `cleanup' erroniously returned. */