]> git.donarmstrong.com Git - lilypond.git/blob - guile18/qt/md/mips-irix5.s
New upstream version 2.19.65
[lilypond.git] / guile18 / qt / md / mips-irix5.s
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         */
64 qt_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. */
77 qt_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         */
105 qt_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         */
127 qt_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         */
161 qt_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