* Added Array.{map2,fold_left2,fold_right2} (from stdlib2)
[ocaml.git] / asmrun / mips.s
blob03fd623435ce6d2b3d072f88fbd054d4d8299189
1 /***********************************************************************/
2 /* */
3 /* Objective Caml */
4 /* */
5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
6 /* */
7 /* Copyright 1996 Institut National de Recherche en Informatique et */
8 /* en Automatique. All rights reserved. This file is distributed */
9 /* under the terms of the GNU Library General Public License, with */
10 /* the special exception on linking described in file ../LICENSE. */
11 /* */
12 /***********************************************************************/
14 /* $Id$ */
16 /* Asm part of the runtime system, Mips processor, IRIX n32 conventions */
18 /* Allocation */
20 .text
22 .globl caml_call_gc
23 .ent caml_call_gc
25 caml_call_gc:
26 /* Reserve stack space for registers and saved $gp */
27 /* 32 * 8 = 0x100 for float regs
28 22 * 4 = 0x58 for integer regs
29 8 = 0x8 for saved $gp ====> 0x160 total */
30 subu $sp, $sp, 0x160
31 /* Reinit $gp */
32 .cpsetup $25, 0x158, caml_call_gc
33 /* Record return address */
34 sw $31, caml_last_return_address
35 /* Record lowest stack address */
36 addu $24, $sp, 0x160
37 sw $24, caml_bottom_of_stack
38 /* Save pointer to register array */
39 addu $24, $sp, 0x100
40 sw $24, caml_gc_regs
41 /* Save current allocation pointer for debugging purposes */
42 sw $22, caml_young_ptr
43 /* Save the exception handler (if e.g. a sighandler raises) */
44 sw $30, caml_exception_pointer
45 /* Save all regs used by the code generator on the stack */
46 sw $2, 2 * 4($24)
47 sw $3, 3 * 4($24)
48 sw $4, 4 * 4($24)
49 sw $5, 5 * 4($24)
50 sw $6, 6 * 4($24)
51 sw $7, 7 * 4($24)
52 sw $8, 8 * 4($24)
53 sw $9, 9 * 4($24)
54 sw $10, 10 * 4($24)
55 sw $11, 11 * 4($24)
56 sw $12, 12 * 4($24)
57 sw $13, 13 * 4($24)
58 sw $14, 14 * 4($24)
59 sw $15, 15 * 4($24)
60 sw $16, 16 * 4($24)
61 sw $17, 17 * 4($24)
62 sw $18, 18 * 4($24)
63 sw $19, 19 * 4($24)
64 sw $20, 20 * 4($24)
65 sw $21, 21 * 4($24)
66 s.d $f0, 0 * 8($sp)
67 s.d $f1, 1 * 8($sp)
68 s.d $f2, 2 * 8($sp)
69 s.d $f3, 3 * 8($sp)
70 s.d $f4, 4 * 8($sp)
71 s.d $f5, 5 * 8($sp)
72 s.d $f6, 6 * 8($sp)
73 s.d $f7, 7 * 8($sp)
74 s.d $f8, 8 * 8($sp)
75 s.d $f9, 9 * 8($sp)
76 s.d $f10, 10 * 8($sp)
77 s.d $f11, 11 * 8($sp)
78 s.d $f12, 12 * 8($sp)
79 s.d $f13, 13 * 8($sp)
80 s.d $f14, 14 * 8($sp)
81 s.d $f15, 15 * 8($sp)
82 s.d $f16, 16 * 8($sp)
83 s.d $f17, 17 * 8($sp)
84 s.d $f18, 18 * 8($sp)
85 s.d $f19, 19 * 8($sp)
86 s.d $f20, 20 * 8($sp)
87 s.d $f21, 21 * 8($sp)
88 s.d $f22, 22 * 8($sp)
89 s.d $f23, 23 * 8($sp)
90 s.d $f24, 24 * 8($sp)
91 s.d $f25, 25 * 8($sp)
92 s.d $f26, 26 * 8($sp)
93 s.d $f27, 27 * 8($sp)
94 s.d $f28, 28 * 8($sp)
95 s.d $f29, 29 * 8($sp)
96 s.d $f30, 30 * 8($sp)
97 s.d $f31, 31 * 8($sp)
98 /* Call the garbage collector */
99 jal caml_garbage_collection
100 /* Restore all regs used by the code generator */
101 addu $24, $sp, 0x100
102 lw $2, 2 * 4($24)
103 lw $3, 3 * 4($24)
104 lw $4, 4 * 4($24)
105 lw $5, 5 * 4($24)
106 lw $6, 6 * 4($24)
107 lw $7, 7 * 4($24)
108 lw $8, 8 * 4($24)
109 lw $9, 9 * 4($24)
110 lw $10, 10 * 4($24)
111 lw $11, 11 * 4($24)
112 lw $12, 12 * 4($24)
113 lw $13, 13 * 4($24)
114 lw $14, 14 * 4($24)
115 lw $15, 15 * 4($24)
116 lw $16, 16 * 4($24)
117 lw $17, 17 * 4($24)
118 lw $18, 18 * 4($24)
119 lw $19, 19 * 4($24)
120 lw $20, 20 * 4($24)
121 lw $21, 21 * 4($24)
122 l.d $f0, 0 * 8($sp)
123 l.d $f1, 1 * 8($sp)
124 l.d $f2, 2 * 8($sp)
125 l.d $f3, 3 * 8($sp)
126 l.d $f4, 4 * 8($sp)
127 l.d $f5, 5 * 8($sp)
128 l.d $f6, 6 * 8($sp)
129 l.d $f7, 7 * 8($sp)
130 l.d $f8, 8 * 8($sp)
131 l.d $f9, 9 * 8($sp)
132 l.d $f10, 10 * 8($sp)
133 l.d $f11, 11 * 8($sp)
134 l.d $f12, 12 * 8($sp)
135 l.d $f13, 13 * 8($sp)
136 l.d $f14, 14 * 8($sp)
137 l.d $f15, 15 * 8($sp)
138 l.d $f16, 16 * 8($sp)
139 l.d $f17, 17 * 8($sp)
140 l.d $f18, 18 * 8($sp)
141 l.d $f19, 19 * 8($sp)
142 l.d $f20, 20 * 8($sp)
143 l.d $f21, 21 * 8($sp)
144 l.d $f22, 22 * 8($sp)
145 l.d $f23, 23 * 8($sp)
146 l.d $f24, 24 * 8($sp)
147 l.d $f25, 25 * 8($sp)
148 l.d $f26, 26 * 8($sp)
149 l.d $f27, 27 * 8($sp)
150 l.d $f28, 28 * 8($sp)
151 l.d $f29, 29 * 8($sp)
152 l.d $f30, 30 * 8($sp)
153 l.d $f31, 31 * 8($sp)
154 /* Reload new allocation pointer and allocation limit */
155 lw $22, caml_young_ptr
156 lw $23, caml_young_limit
157 /* Reload return address */
158 lw $31, caml_last_return_address
159 /* Say that we are back into Caml code */
160 sw $0, caml_last_return_address
161 /* Adjust return address to restart the allocation sequence */
162 subu $31, $31, 16
163 /* Return */
164 .cpreturn
165 addu $sp, $sp, 0x160
166 j $31
168 .end caml_call_gc
170 /* Call a C function from Caml */
172 .globl caml_c_call
173 .ent caml_c_call
175 caml_c_call:
176 /* Function to call is in $24 */
177 /* Set up $gp, saving caller's $gp in callee-save register $19 */
178 .cpsetup $25, $19, caml_c_call
179 /* Preload addresses of interesting global variables
180 in callee-save registers */
181 la $16, caml_last_return_address
182 la $17, caml_young_ptr
183 /* Save return address, bottom of stack, alloc ptr, exn ptr */
184 sw $31, 0($16) /* caml_last_return_address */
185 sw $sp, caml_bottom_of_stack
186 sw $22, 0($17) /* caml_young_ptr */
187 sw $30, caml_exception_pointer
188 /* Call C function */
189 move $25, $24
190 jal $24
191 /* Reload return address, alloc ptr, alloc limit */
192 lw $31, 0($16) /* caml_last_return_address */
193 lw $22, 0($17) /* caml_young_ptr */
194 lw $23, caml_young_limit /* caml_young_limit */
195 /* Zero caml_last_return_address, indicating we're back in Caml code */
196 sw $0, 0($16) /* caml_last_return_address */
197 /* Restore $gp and return */
198 move $gp, $19
199 j $31
200 .end caml_c_call
202 /* Start the Caml program */
204 .globl caml_start_program
205 .globl stray_exn_handler
206 .ent caml_start_program
207 caml_start_program:
208 /* Reserve space for callee-save registers */
209 subu $sp, $sp, 0x90
210 /* Setup $gp */
211 .cpsetup $25, 0x80, caml_start_program
212 /* Load in $24 the code address to call */
213 la $24, caml_program
214 /* Code shared with caml_callback* */
215 $103:
216 /* Save return address */
217 sd $31, 0x88($sp)
218 /* Save all callee-save registers */
219 sd $16, 0x0($sp)
220 sd $17, 0x8($sp)
221 sd $18, 0x10($sp)
222 sd $19, 0x18($sp)
223 sd $20, 0x20($sp)
224 sd $21, 0x28($sp)
225 sd $22, 0x30($sp)
226 sd $23, 0x38($sp)
227 sd $30, 0x40($sp)
228 s.d $f20, 0x48($sp)
229 s.d $f22, 0x50($sp)
230 s.d $f24, 0x58($sp)
231 s.d $f26, 0x60($sp)
232 s.d $f28, 0x68($sp)
233 s.d $f30, 0x70($sp)
234 /* Set up a callback link on the stack. */
235 subu $sp, $sp, 16
236 lw $2, caml_bottom_of_stack
237 sw $2, 0($sp)
238 lw $3, caml_last_return_address
239 sw $3, 4($sp)
240 lw $4, caml_gc_regs
241 sw $4, 8($sp)
242 /* Set up a trap frame to catch exceptions escaping the Caml code */
243 subu $sp, $sp, 16
244 lw $30, caml_exception_pointer
245 sw $30, 0($sp)
246 la $2, $105
247 sw $2, 4($sp)
248 sw $gp, 8($sp)
249 move $30, $sp
250 /* Reload allocation pointers */
251 lw $22, caml_young_ptr
252 lw $23, caml_young_limit
253 /* Say that we are back into Caml code */
254 sw $0, caml_last_return_address
255 /* Call the Caml code */
256 move $25, $24
257 jal $24
258 $104:
259 /* Pop the trap frame, restoring caml_exception_pointer */
260 lw $24, 0($sp)
261 sw $24, caml_exception_pointer
262 addu $sp, $sp, 16
263 $106:
264 /* Pop the callback link, restoring the global variables */
265 lw $24, 0($sp)
266 sw $24, caml_bottom_of_stack
267 lw $25, 4($sp)
268 sw $25, caml_last_return_address
269 lw $24, 8($sp)
270 sw $24, caml_gc_regs
271 addu $sp, $sp, 16
272 /* Update allocation pointer */
273 sw $22, caml_young_ptr
274 /* Reload callee-save registers and return */
275 ld $31, 0x88($sp)
276 ld $16, 0x0($sp)
277 ld $17, 0x8($sp)
278 ld $18, 0x10($sp)
279 ld $19, 0x18($sp)
280 ld $20, 0x20($sp)
281 ld $21, 0x28($sp)
282 ld $22, 0x30($sp)
283 ld $23, 0x38($sp)
284 ld $30, 0x40($sp)
285 l.d $f20, 0x48($sp)
286 l.d $f22, 0x50($sp)
287 l.d $f24, 0x58($sp)
288 l.d $f26, 0x60($sp)
289 l.d $f28, 0x68($sp)
290 l.d $f30, 0x70($sp)
291 .cpreturn
292 addu $sp, $sp, 0x90
293 j $31
295 /* The trap handler: encode exception bucket as an exception result
296 and return it */
297 $105:
298 sw $30, caml_exception_pointer
299 or $2, $2, 2
300 b $106
302 .end caml_start_program
304 /* Raise an exception from C */
306 .globl caml_raise_exception
307 .ent caml_raise_exception
308 caml_raise_exception:
309 /* Setup $gp, discarding caller's $gp (we won't return) */
310 .cpsetup $25, $24, caml_raise_exception
311 /* Branch to exn handler */
312 move $2, $4
313 lw $22, caml_young_ptr
314 lw $23, caml_young_limit
315 lw $sp, caml_exception_pointer
316 lw $30, 0($sp)
317 lw $24, 4($sp)
318 lw $gp, 8($sp)
319 addu $sp, $sp, 16
320 j $24
322 .end caml_raise_exception
324 /* Callback from C to Caml */
326 .globl caml_callback_exn
327 .ent caml_callback_exn
328 caml_callback_exn:
329 subu $sp, $sp, 0x90
330 .cpsetup $25, 0x80, caml_callback_exn
331 /* Initial shuffling of arguments */
332 move $9, $4 /* closure */
333 move $8, $5 /* argument */
334 lw $24, 0($4) /* code pointer */
335 b $103
336 .end caml_callback_exn
338 .globl caml_callback2_exn
339 .ent caml_callback2_exn
340 caml_callback2_exn:
341 subu $sp, $sp, 0x90
342 .cpsetup $25, 0x80, caml_callback2_exn
343 /* Initial shuffling of arguments */
344 move $10, $4 /* closure */
345 move $8, $5 /* first argument */
346 move $9, $6 /* second argument */
347 la $24, caml_apply2 /* code pointer */
348 b $103
350 .end caml_callback2_exn
352 .globl caml_callback3_exn
353 .ent caml_callback3_exn
354 caml_callback3_exn:
355 subu $sp, $sp, 0x90
356 .cpsetup $25, 0x80, caml_callback3_exn
357 /* Initial shuffling of arguments */
358 move $11, $4 /* closure */
359 move $8, $5 /* first argument */
360 move $9, $6 /* second argument */
361 move $10, $7 /* third argument */
362 la $24, caml_apply3 /* code pointer */
363 b $103
365 .end caml_callback3_exn
367 /* Glue code to call [caml_array_bound_error] */
369 .globl caml_ml_array_bound_error
370 .ent caml_ml_array_bound_error
372 caml_ml_array_bound_error:
373 /* Setup $gp, discarding caller's $gp (we won't return) */
374 .cpsetup $25, $24, caml_ml_array_bound_error
375 la $24, caml_array_bound_error
376 jal caml_c_call /* never returns */
378 .end caml_ml_array_bound_error
380 .rdata
381 .globl caml_system__frametable
382 caml_system__frametable:
383 .word 1 /* one descriptor */
384 .word $104 /* return address into callback */
385 .half -1 /* negative frame size => use callback link */
386 .half 0 /* no roots here */