Use $(GCC_CFLAGS) for `-Werror' et al. so that it's not used to compile
[bpt/guile.git] / qt / md / mips-irix5.s
CommitLineData
24a647d7
MD
1/* mips.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 $16-$23, $30-$31.
17 *
18 * $25 is used as a procedure value pointer, used to discover constants
19 * in a callee. Thus, each caller here sets $25 before the call.
20 *
21 * On startup, restore regs so retpc === call to a function to start.
22 * We're going to call a function ($4) from within this routine.
23 * We're passing 3 args, therefore need to allocate 12 extra bytes on
24 * the stack for a save area. The start routine needs a like 16-byte
25 * save area. Must be doubleword aligned (_mips r3000 risc
26 * architecture_, gerry kane, pg d-23).
27 */
28
29/*
30 * Modified by Assar Westerlund <assar@sics.se> to support Irix 5.x
31 * calling conventions for dynamically-linked code.
32 */
33
34 /* Make this position-independent code. */
35 .option pic2
36
37 .globl qt_block
38 .globl qt_blocki
39 .globl qt_abort
40 .globl qt_start
41 .globl qt_vstart
42
43 /*
44 ** $4: ptr to function to call once curr is suspended
45 ** and control is on $7's stack.
46 ** $5: 1'th arg to $4.
47 ** $6: 2'th arg to $4
48 ** $7: sp of thread to suspend.
49 **
50 ** Totally gross hack: The MIPS calling convention reserves
51 ** 4 words on the stack for a0..a3. This routine "ought" to
52 ** allocate space for callee-save registers plus 4 words for
53 ** the helper function, but instead we use the 4 words
54 ** provided by the function that called us (we don't need to
55 ** save our argument registers). So what *appears* to be
56 ** allocating only 40 bytes is actually allocating 56, by
57 ** using the caller's 16 bytes.
58 **
59 ** The helper routine returns a value that is passed on as the
60 ** return value from the blocking routine. Since we don't
61 ** touch $2 between the helper's return and the end of
62 ** function, we get this behavior for free.
63 */
64qt_blocki:
65 sub $sp,$sp,40 /* Allocate reg save space. */
66 sw $16, 0+16($sp)
67 sw $17, 4+16($sp)
68 sw $18, 8+16($sp)
69 sw $19,12+16($sp)
70 sw $20,16+16($sp)
71 sw $21,20+16($sp)
72 sw $22,24+16($sp)
73 sw $23,28+16($sp)
74 sw $30,32+16($sp)
75 sw $31,36+16($sp)
76 add $2, $sp,$0 /* $2 <= old sp to pass to func@$4. */
77qt_abort:
78 add $sp, $7,$0 /* $sp <= new sp. */
79 .set noreorder
80 add $25, $4,$0 /* Set helper function procedure value. */
81 jal $31,$25 /* Call helper func@$4 . */
82 add $4, $2,$0 /* $a0 <= pass old sp as a parameter. */
83 .set reorder
84 lw $31,36+16($sp) /* Restore callee-save regs... */
85 lw $30,32+16($sp)
86 lw $23,28+16($sp)
87 lw $22,24+16($sp)
88 lw $21,20+16($sp)
89 lw $20,16+16($sp)
90 lw $19,12+16($sp)
91 lw $18, 8+16($sp)
92 lw $17, 4+16($sp)
93 lw $16, 0+16($sp) /* Restore callee-save */
94
95 add $sp,$sp,40 /* Deallocate reg save space. */
96 j $31 /* Return to caller. */
97
98 /*
99 ** Non-varargs thread startup.
100 ** Note: originally, 56 bytes were allocated on the stack.
101 ** The thread restore routine (_blocki/_abort) removed 40
102 ** of them, which means there is still 16 bytes for the
103 ** argument area required by the MIPS calling convention.
104 */
105qt_start:
106 add $4, $16,$0 /* Load up user function pu. */
107 add $5, $17,$0 /* ... user function pt. */
108 add $6, $18,$0 /* ... user function userf. */
109 add $25, $19,$0 /* Set `only' procedure value. */
110 jal $31,$25 /* Call `only'. */
111 la $25,qt_error /* Set `qt_error' procedure value. */
112 j $25
113
114
115 /*
116 ** Save calle-save floating-point regs $f20-$f30
117 ** See comment in `qt_block' about calling conventinos and
118 ** reserved space. Use the same trick here, but here we
119 ** actually have to allocate all the bytes since we have to
120 ** leave 4 words leftover for `qt_blocki'.
121 **
122 ** Return value from `qt_block' is the same as the return from
123 ** `qt_blocki'. We get that for free since we don't touch $2
124 ** between the return from `qt_blocki' and the return from
125 ** `qt_block'.
126 */
127qt_block:
128 sub $sp, $sp,56 /* 6 8-byte regs, saved ret pc, aligned. */
129 swc1 $f20, 0+16($sp)
130 swc1 $f22, 8+16($sp)
131 swc1 $f24, 16+16($sp)
132 swc1 $f26, 24+16($sp)
133 swc1 $f28, 32+16($sp)
134 swc1 $f30, 40+16($sp)
135 sw $31, 48+16($sp)
136 jal qt_blocki
137 lwc1 $f20, 0+16($sp)
138 lwc1 $f22, 8+16($sp)
139 lwc1 $f24, 16+16($sp)
140 lwc1 $f26, 24+16($sp)
141 lwc1 $f28, 32+16($sp)
142 lwc1 $f30, 40+16($sp)
143 lw $31, 48+16($sp)
144 add $sp, $sp,56
145 j $31
146
147
148 /*
149 ** First, call `startup' with the `pt' argument.
150 **
151 ** Next, call the user's function with all arguments.
152 ** Note that we don't know whether args were passed in
153 ** integer regs, fp regs, or on the stack (See Gerry Kane
154 ** "MIPS R2000 RISC Architecture" pg D-22), so we reload
155 ** all the registers, possibly with garbage arguments.
156 **
157 ** Finally, call `cleanup' with the `pt' argument and with
158 ** the return value from the user's function. It is an error
159 ** for `cleanup' to return.
160 */
161qt_vstart:
162 add $4, $17,$0 /* `pt' is arg0 to `startup'. */
163 add $25, $18,$0 /* Set `startup' procedure value. */
164 jal $31, $25 /* Call `startup'. */
165
166 add $sp, $sp,16 /* Free extra save space. */
167 lw $4, 0($sp) /* Load up args. */
168 lw $5, 4($sp)
169 lw $6, 8($sp)
170 lw $7, 12($sp)
171 lwc1 $f12, 0($sp) /* Load up fp args. */
172 lwc1 $f14, 8($sp)
173 add $25, $19,$0 /* Set `userf' procedure value. */
174 jal $31,$25 /* Call `userf'. */
175
176 add $4, $17,$0 /* `pt' is arg0 to `cleanup'. */
177 add $5, $2,$0 /* Ret. val is arg1 to `cleanup'. */
178 add $25, $16,$0 /* Set `cleanup' procedure value. */
179 jal $31, $25 /* Call `cleanup'. */
180
181 la $25,qt_error /* Set `qt_error' procedure value. */
182 j $25