summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/qt/md/mips-irix5.s
blob: 234a953ed6a31195fd56e799d9e548dac9b991db (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
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* mips.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 $16-$23, $30-$31.
 *
 * $25 is used as a procedure value pointer, used to discover constants
 * in a callee.  Thus, each caller here sets $25 before the call.
 *
 * On startup, restore regs so retpc === call to a function to start.
 * We're going to call a function ($4) from within this routine.
 * We're passing 3 args, therefore need to allocate 12 extra bytes on
 * the stack for a save area.  The start routine needs a like 16-byte
 * save area.  Must be doubleword aligned (_mips r3000 risc
 * architecture_, gerry kane, pg d-23).
 */

/*
 * Modified by Assar Westerlund <assar@sics.se> to support Irix 5.x
 * calling conventions for dynamically-linked code.
 */

	/* Make this position-independent code. */
	.option pic2

	.globl qt_block
	.globl qt_blocki
	.globl qt_abort
	.globl qt_start
	.globl qt_vstart

	/*
	** $4: ptr to function to call once curr is suspended
	**	and control is on $7's stack.
	** $5: 1'th arg to $4.
	** $6: 2'th arg to $4
	** $7: sp of thread to suspend.
	**
	** Totally gross hack: The MIPS calling convention reserves
	** 4 words on the stack for a0..a3.  This routine "ought" to
	** allocate space for callee-save registers plus 4 words for
	** the helper function, but instead we use the 4 words
	** provided by the function that called us (we don't need to
	** save our argument registers).  So what *appears* to be
	** allocating only 40 bytes is actually allocating 56, by
	** using the caller's 16 bytes.
	**
	** The helper routine returns a value that is passed on as the
	** return value from the blocking routine.  Since we don't
	** touch $2 between the helper's return and the end of
	** function, we get this behavior for free.
	*/
qt_blocki:
	sub $sp,$sp,40		/* Allocate reg save space. */
	sw $16, 0+16($sp)
	sw $17, 4+16($sp)
	sw $18, 8+16($sp)
	sw $19,12+16($sp)
	sw $20,16+16($sp)
	sw $21,20+16($sp)
	sw $22,24+16($sp)
	sw $23,28+16($sp)
	sw $30,32+16($sp)
	sw $31,36+16($sp)
	add $2, $sp,$0		/* $2 <= old sp to pass to func@$4. */
qt_abort:
	add $sp, $7,$0		/* $sp <= new sp. */
	.set noreorder
	add $25, $4,$0		/* Set helper function procedure value. */
	jal $31,$25		/* Call helper func@$4 . */
	add $4, $2,$0		/* $a0 <= pass old sp as a parameter. */
	.set reorder
	lw $31,36+16($sp)	/* Restore callee-save regs... */
	lw $30,32+16($sp)
	lw $23,28+16($sp)
	lw $22,24+16($sp)
	lw $21,20+16($sp)
	lw $20,16+16($sp)
	lw $19,12+16($sp)
	lw $18, 8+16($sp)
	lw $17, 4+16($sp)
	lw $16, 0+16($sp)	/* Restore callee-save */

	add $sp,$sp,40		/* Deallocate reg save space. */
	j $31			/* Return to caller. */

	/*
	** Non-varargs thread startup.
	** Note: originally, 56 bytes were allocated on the stack.
	** The thread restore routine (_blocki/_abort) removed 40
	** of them, which means there is still 16 bytes for the
	** argument area required by the MIPS calling convention.
	*/
qt_start:
	add $4, $16,$0		/* Load up user function pu. */
	add $5, $17,$0		/* ... user function pt. */
	add $6, $18,$0		/* ... user function userf. */
	add $25, $19,$0		/* Set `only' procedure value. */
	jal $31,$25		/* Call `only'. */
	la $25,qt_error		/* Set `qt_error' procedure value. */
	j $25


	/*
	** Save calle-save floating-point regs $f20-$f30
	** See comment in `qt_block' about calling conventinos and
	** reserved space.  Use the same trick here, but here we
	** actually have to allocate all the bytes since we have to
	** leave 4 words leftover for `qt_blocki'.
	**
	** Return value from `qt_block' is the same as the return from
	** `qt_blocki'.  We get that for free since we don't touch $2
	** between the return from `qt_blocki' and the return from
	** `qt_block'.
	*/
qt_block:
	sub $sp, $sp,56		/* 6 8-byte regs, saved ret pc, aligned. */
	swc1 $f20,  0+16($sp)
	swc1 $f22,  8+16($sp)
	swc1 $f24, 16+16($sp)
	swc1 $f26, 24+16($sp)
	swc1 $f28, 32+16($sp)
	swc1 $f30, 40+16($sp)
	sw $31, 48+16($sp)
	jal qt_blocki
	lwc1 $f20,  0+16($sp)
	lwc1 $f22,  8+16($sp)
	lwc1 $f24, 16+16($sp)
	lwc1 $f26, 24+16($sp)
	lwc1 $f28, 32+16($sp)
	lwc1 $f30, 40+16($sp)
	lw $31, 48+16($sp)
	add $sp, $sp,56
	j $31


	/*
	** First, call `startup' with the `pt' argument.
	**
	** Next, call the user's function with all arguments.
	** Note that we don't know whether args were passed in
	** integer regs, fp regs, or on the stack (See Gerry Kane
	** "MIPS R2000 RISC Architecture" pg D-22), so we reload
	** all the registers, possibly with garbage arguments.
	**
	** Finally, call `cleanup' with the `pt' argument and with
	** the return value from the user's function.  It is an error
	** for `cleanup' to return.
	*/
qt_vstart:
	add $4, $17,$0		/* `pt' is arg0 to `startup'. */
	add $25, $18,$0		/* Set `startup' procedure value. */
	jal $31, $25		/* Call `startup'. */

	add $sp, $sp,16		/* Free extra save space. */
	lw $4,  0($sp)		/* Load up args. */
	lw $5,  4($sp)
	lw $6,  8($sp)
	lw $7, 12($sp)
	lwc1 $f12, 0($sp)	/* Load up fp args. */
	lwc1 $f14, 8($sp)
	add $25, $19,$0		/* Set `userf' procedure value. */
	jal $31,$25		/* Call `userf'. */

	add $4, $17,$0		/* `pt' is arg0 to `cleanup'. */
	add $5, $2,$0		/* Ret. val is arg1 to `cleanup'. */
	add $25, $16,$0		/* Set `cleanup' procedure value. */
	jal $31, $25		/* Call `cleanup'. */

	la $25,qt_error		/* Set `qt_error' procedure value. */
	j $25