1 /***********************************************************************/
5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
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. */
12 /***********************************************************************/
16 /* Asm part of the runtime system for the Sparc processor. */
17 /* Must be preprocessed by cpp */
19 /* SunOS 4 prefixes identifiers with _ */
21 #if defined(SYS_sunos)
23 #define Caml_young_limit _caml_young_limit
24 #define Caml_young_ptr _caml_young_ptr
25 #define Caml_bottom_of_stack _caml_bottom_of_stack
26 #define Caml_last_return_address _caml_last_return_address
27 #define Caml_gc_regs _caml_gc_regs
28 #define Caml_exception_pointer _caml_exception_pointer
29 #define Caml_allocN _caml_allocN
30 #define Caml_call_gc _caml_call_gc
31 #define Caml_garbage_collection _caml_garbage_collection
32 #define Caml_c_call _caml_c_call
33 #define Caml_start_program _caml_start_program
34 #define Caml_program _caml_program
35 #define Caml_raise_exception _caml_raise_exception
36 #define Caml_callback_exn _caml_callback_exn
37 #define Caml_callback2_exn _caml_callback2_exn
38 #define Caml_callback3_exn _caml_callback3_exn
39 #define Caml_apply2 _caml_apply2
40 #define Caml_apply3 _caml_apply3
41 #define Caml_raise _caml_raise
42 #define Caml_system__frametable _caml_system__frametable
43 #define Caml_ml_array_bound_error _caml_ml_array_bound_error
44 #define Caml_array_bound_error _caml_array_bound_error
48 #define Caml_young_limit caml_young_limit
49 #define Caml_young_ptr caml_young_ptr
50 #define Caml_bottom_of_stack caml_bottom_of_stack
51 #define Caml_last_return_address caml_last_return_address
52 #define Caml_gc_regs caml_gc_regs
53 #define Caml_exception_pointer caml_exception_pointer
54 #define Caml_allocN caml_allocN
55 #define Caml_call_gc caml_call_gc
56 #define Caml_garbage_collection caml_garbage_collection
57 #define Caml_c_call caml_c_call
58 #define Caml_start_program caml_start_program
59 #define Caml_program caml_program
60 #define Caml_raise_exception caml_raise_exception
61 #define Caml_callback_exn caml_callback_exn
62 #define Caml_callback2_exn caml_callback2_exn
63 #define Caml_callback3_exn caml_callback3_exn
64 #define Caml_apply2 caml_apply2
65 #define Caml_apply3 caml_apply3
66 #define Caml_raise caml_raise
67 #define Caml_system__frametable caml_system__frametable
68 #define Caml_ml_array_bound_error caml_ml_array_bound_error
69 #define Caml_array_bound_error caml_array_bound_error
74 #define INDIRECT_LIMIT
79 #define Alloc_limit %l7
81 #define Load(symb,reg) sethi %hi(symb), %g1; ld [%g1 + %lo(symb)], reg
82 #define Store(reg,symb) sethi %hi(symb), %g1; st reg, [%g1 + %lo(symb)]
83 #define Address(symb,reg) sethi %hi(symb), reg; or reg, %lo(symb), reg
85 /* Allocation functions */
91 /* Required size in %g2 */
95 sub Alloc_ptr, %g2, Alloc_ptr
98 sub Alloc_ptr, %g2, Alloc_ptr
99 cmp Alloc_ptr, Alloc_limit
101 /*blu,pt %icc, Caml_call_gc*/
107 /* Required size in %g2 */
109 /* Save exception pointer if GC raises */
110 Store(Exn_ptr, Caml_exception_pointer)
111 /* Save current allocation pointer for debugging purposes */
112 Store(Alloc_ptr, Caml_young_ptr)
113 /* Record lowest stack address */
114 Store(%sp, Caml_bottom_of_stack)
115 /* Record last return address */
116 Store(%o7, Caml_last_return_address)
117 /* Allocate space on stack for caml_context structure and float regs */
118 sub %sp, 20*4 + 15*8, %sp
119 /* Save int regs on stack and save it into caml_gc_regs */
120 L100: add %sp, 96 + 15*8, %g1
140 st %g2, [%g1 + 0x4C] /* Save required size */
142 Store(%g2, Caml_gc_regs)
143 /* Save the floating-point registers */
147 std %f4, [%g1 + 0x10]
148 std %f6, [%g1 + 0x18]
149 std %f8, [%g1 + 0x20]
150 std %f10, [%g1 + 0x28]
151 std %f12, [%g1 + 0x30]
152 std %f14, [%g1 + 0x38]
153 std %f16, [%g1 + 0x40]
154 std %f18, [%g1 + 0x48]
155 std %f20, [%g1 + 0x50]
156 std %f22, [%g1 + 0x58]
157 std %f24, [%g1 + 0x60]
158 std %f26, [%g1 + 0x68]
159 std %f28, [%g1 + 0x70]
160 /* Call the garbage collector */
161 call Caml_garbage_collection
163 /* Restore all regs used by the code generator */
164 add %sp, 96 + 15*8, %g1
184 ld [%g1 + 0x4C], %g2 /* Recover desired size */
188 ldd [%g1 + 0x10], %f4
189 ldd [%g1 + 0x18], %f6
190 ldd [%g1 + 0x20], %f8
191 ldd [%g1 + 0x28], %f10
192 ldd [%g1 + 0x30], %f12
193 ldd [%g1 + 0x38], %f14
194 ldd [%g1 + 0x40], %f16
195 ldd [%g1 + 0x48], %f18
196 ldd [%g1 + 0x50], %f20
197 ldd [%g1 + 0x58], %f22
198 ldd [%g1 + 0x60], %f24
199 ldd [%g1 + 0x68], %f26
200 ldd [%g1 + 0x70], %f28
201 /* Reload alloc ptr */
202 Load(Caml_young_ptr, Alloc_ptr)
203 /* Allocate space for block */
204 #ifdef INDIRECT_LIMIT
205 ld [Alloc_limit], %g1
206 sub Alloc_ptr, %g2, Alloc_ptr
207 cmp Alloc_ptr, %g1 /* Check that we have enough free space */
209 Load(Caml_young_limit,Alloc_limit)
210 sub Alloc_ptr, %g2, Alloc_ptr
211 cmp Alloc_ptr, Alloc_limit
213 blu L100 /* If not, call GC again */
215 /* Return to caller */
216 Load(Caml_last_return_address, %o7)
218 add %sp, 20*4 + 15*8, %sp /* in delay slot */
220 /* Call a C function from Caml */
223 /* Function to call is in %g2 */
225 /* Record lowest stack address and return address */
226 Store(%sp, Caml_bottom_of_stack)
227 Store(%o7, Caml_last_return_address)
228 /* Save the exception handler and alloc pointer */
229 Store(Exn_ptr, Caml_exception_pointer)
230 sethi %hi(Caml_young_ptr), %g1
231 /* Call the C function */
233 st Alloc_ptr, [%g1 + %lo(Caml_young_ptr)] /* in delay slot */
234 /* Reload return address */
235 Load(Caml_last_return_address, %o7)
236 /* Reload alloc pointer */
237 sethi %hi(Caml_young_ptr), %g1
238 /* Return to caller */
240 ld [%g1 + %lo(Caml_young_ptr)], Alloc_ptr /* in delay slot */
242 /* Start the Caml program */
244 .global Caml_start_program
246 /* Save all callee-save registers */
248 /* Address of code to call */
249 Address(Caml_program, %l2)
251 /* Code shared with caml_callback* */
253 /* Set up a callback link on the stack. */
255 Load(Caml_bottom_of_stack, %l0)
256 Load(Caml_last_return_address, %l1)
257 Load(Caml_gc_regs, %l3)
260 /* Set up a trap frame to catch exceptions escaping the Caml code */
265 L111: sub %sp, 8, %sp
266 Load(Caml_exception_pointer, Exn_ptr)
268 st Exn_ptr, [%sp + 100]
270 /* Reload allocation pointers */
271 Load(Caml_young_ptr, Alloc_ptr)
272 #ifdef INDIRECT_LIMIT
273 Address(Caml_young_limit, Alloc_limit)
275 Load(Caml_young_limit, Alloc_limit)
277 /* Call the Caml code */
280 /* Pop trap frame and restore caml_exception_pointer */
281 ld [%sp + 100], Exn_ptr
283 Store(Exn_ptr, Caml_exception_pointer)
284 /* Pop callback link, restoring the global variables */
285 L112: ld [%sp + 96], %l0
288 Store(%l0, Caml_bottom_of_stack)
289 Store(%l1, Caml_last_return_address)
290 Store(%l2, Caml_gc_regs)
292 /* Save allocation pointer */
293 Store(Alloc_ptr, Caml_young_ptr)
294 /* Reload callee-save registers and return */
296 restore %o0, 0, %o0 /* copy %o0 in this window to caller's %o0 */
298 /* The trap handler */
299 Store(Exn_ptr, Caml_exception_pointer)
300 /* Encode exception bucket as an exception result */
304 /* Raise an exception from C */
306 .global Caml_raise_exception
307 Caml_raise_exception:
308 /* Save exception bucket in a register outside the reg windows */
310 /* Load exception pointer in a register outside the reg windows */
311 Load(Caml_exception_pointer, %g3)
312 /* Pop some frames until the trap pointer is in the current frame. */
314 blt L107 /* if Exn_ptr < %fp, over */
317 cmp %fp, %g3 /* if %fp <= Exn_ptr, loop */
321 /* Reload allocation registers */
322 Load(Caml_young_ptr, Alloc_ptr)
323 #ifdef INDIRECT_LIMIT
324 Address(Caml_young_limit, Alloc_limit)
326 Load(Caml_young_limit, Alloc_limit)
328 /* Branch to exception handler */
331 ld [%sp + 100], Exn_ptr
334 /* Restore bucket, in delay slot */
337 /* Callbacks C -> ML */
339 .global Caml_callback_exn
341 /* Save callee-save registers and return address */
343 /* Initial shuffling of arguments */
345 mov %i1, %i0 /* first arg */
346 mov %g1, %i1 /* environment */
348 ld [%g1], %l2 /* code pointer */
350 .global Caml_callback2_exn
352 /* Save callee-save registers and return address */
354 /* Initial shuffling of arguments */
356 mov %i1, %i0 /* first arg */
357 mov %i2, %i1 /* second arg */
358 mov %g1, %i2 /* environment */
359 sethi %hi(Caml_apply2), %l2
361 or %l2, %lo(Caml_apply2), %l2
363 .global Caml_callback3_exn
365 /* Save callee-save registers and return address */
367 /* Initial shuffling of arguments */
369 mov %i1, %i0 /* first arg */
370 mov %i2, %i1 /* second arg */
371 mov %i3, %i2 /* third arg */
372 mov %g1, %i3 /* environment */
373 sethi %hi(Caml_apply3), %l2
375 or %l2, %lo(Caml_apply3), %l2
378 /* Glue code to call [caml_array_bound_error] */
380 .global Caml_ml_array_bound_error
381 Caml_ml_array_bound_error:
382 Address(Caml_array_bound_error, %g2)
392 .global Caml_system__frametable
393 .align 4 /* required for gas? */
394 Caml_system__frametable:
395 .word 1 /* one descriptor */
396 .word L109 /* return address into callback */
397 .half -1 /* negative frame size => use callback link */
398 .half 0 /* no roots */
401 .type Caml_allocN, #function
402 .type Caml_call_gc, #function
403 .type Caml_c_call, #function
404 .type Caml_start_program, #function
405 .type Caml_raise_exception, #function
406 .type Caml_system__frametable, #object