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 /*********************************************************************/
14 /* $Id: power-rhapsody.S 7812 2007-01-29 12:11:18Z xleroy $ */
24 #define lgu X(lwzu,ldu)
25 #define stg X(stw,std)
26 #define stgu X(stwu,stdu)
27 #define gdata X(.long,.quad)
29 .macro Addrglobal /* reg, glob */
33 .macro Loadglobal /* reg,glob,tmp */
37 .macro Storeglobal /* reg,glob,tmp */
44 /* Invoke the garbage collector. */
48 /* Set up stack frame */
49 #define FRAMESIZE (32*WORD + 32*8 + 32)
50 stwu r1, -FRAMESIZE(r1)
51 /* Record return address into Caml code */
53 Storeglobal r0, _caml_last_return_address, r11
54 /* Record lowest stack address */
55 addi r0, r1, FRAMESIZE
56 Storeglobal r0, _caml_bottom_of_stack, r11
57 /* Record pointer to register array */
58 addi r0, r1, 8*32 + 32
59 Storeglobal r0, _caml_gc_regs, r11
60 /* Save current allocation pointer for debugging purposes */
61 Storeglobal r31, _caml_young_ptr, r11
62 /* Save exception pointer (if e.g. a sighandler raises) */
63 Storeglobal r29, _caml_exception_pointer, r11
64 /* Save all registers used by the code generator */
65 addi r11, r1, 8*32 + 32 - WORD
122 bl _caml_garbage_collection
123 /* Reload new allocation pointer and allocation limit */
124 Loadglobal r31, _caml_young_ptr, r11
125 Loadglobal r30, _caml_young_limit, r11
126 /* Restore all regs used by the code generator */
127 addi r11, r1, 8*32 + 32 - WORD
183 /* Return to caller, restarting the allocation */
184 Loadglobal r0, _caml_last_return_address, r11
185 addic r0, r0, -16 /* Restart the allocation (4 instructions) */
187 /* Say we are back into Caml code */
189 Storeglobal r12, _caml_last_return_address, r11
190 /* Deallocate stack frame */
191 addi r1, r1, FRAMESIZE
196 /* Call a C function from Caml */
200 /* Save return address */
202 /* Get ready to call C function (address in 11) */
204 /* Record lowest stack address and return address */
205 Storeglobal r1, _caml_bottom_of_stack, r12
206 Storeglobal r25, _caml_last_return_address, r12
207 /* Make the exception handler and alloc ptr available to the C code */
208 Storeglobal r31, _caml_young_ptr, r11
209 Storeglobal r29, _caml_exception_pointer, r11
210 /* Call the function (address in link register) */
212 /* Restore return address (in 25, preserved by the C function) */
214 /* Reload allocation pointer and allocation limit*/
215 Loadglobal r31, _caml_young_ptr, r11
216 Loadglobal r30, _caml_young_limit, r11
217 /* Say we are back into Caml code */
219 Storeglobal r12, _caml_last_return_address, r11
220 /* Return to caller */
223 /* Raise an exception from Caml */
224 .globl _caml_raise_exn
226 addis r11, 0, ha16(_caml_backtrace_active)
227 lwz r11, lo16(_caml_backtrace_active)(r11)
237 /* Branch to handler */
241 mr r28, r3 /* preserve exn bucket in callee-save */
242 /* arg 1: exception bucket (already in r3) */
243 mflr r4 /* arg 2: PC of raise */
244 mr r5, r1 /* arg 3: SP of raise */
245 mr r6, r29 /* arg 4: SP of handler */
246 addi r1, r1, -(16*WORD) /* reserve stack space for C call */
247 bl _caml_stash_backtrace
251 /* Raise an exception from C */
253 .globl _caml_raise_exception
254 _caml_raise_exception:
255 addis r11, 0, ha16(_caml_backtrace_active)
256 lwz r11, lo16(_caml_backtrace_active)(r11)
260 /* Reload Caml global registers */
261 Loadglobal r1, _caml_exception_pointer, r11
262 Loadglobal r31, _caml_young_ptr, r11
263 Loadglobal r30, _caml_young_limit, r11
264 /* Say we are back into Caml code */
266 Storeglobal r0, _caml_last_return_address, r11
272 /* Branch to handler */
275 mr r28, r3 /* preserve exn bucket in callee-save */
276 /* arg 1: exception bucket (already in r3) */
277 Loadglobal r4, _caml_last_return_address, r11 /* arg 2: PC of raise */
278 Loadglobal r5, _caml_bottom_of_stack, r11 /* arg 3: SP of raise */
279 Loadglobal r6, _caml_exception_pointer, r11 /* arg 4: SP of handler */
280 addi r1, r1, -(16*WORD) /* reserve stack space for C call */
281 bl _caml_stash_backtrace
285 /* Start the Caml program */
287 .globl _caml_start_program
289 Addrglobal r12, _caml_program
291 /* Code shared between caml_start_program and caml_callback */
293 /* Allocate and link stack frame */
294 #define FRAMESIZE (16 + 20*WORD + 18*8)
295 stgu r1, -FRAMESIZE(r1)
296 /* Save return address */
299 /* Save all callee-save registers */
300 /* GPR14 ... GPR31, then FPR14 ... FPR31 starting at sp+16 */
301 addi r11, r1, 16-WORD
338 /* Set up a callback link */
340 Loadglobal r9, _caml_bottom_of_stack, r11
341 Loadglobal r10, _caml_last_return_address, r11
342 Loadglobal r11, _caml_gc_regs, r11
346 /* Build an exception handler to catch exceptions escaping out of Caml */
353 Loadglobal r11, _caml_exception_pointer, r11
356 /* Reload allocation pointers */
357 Loadglobal r31, _caml_young_ptr, r11
358 Loadglobal r30, _caml_young_limit, r11
359 /* Say we are back into Caml code */
361 Storeglobal r0, _caml_last_return_address, r11
362 /* Call the Caml code */
366 /* Pop the trap frame, restoring caml_exception_pointer */
368 Storeglobal r9, _caml_exception_pointer, r11
370 /* Pop the callback link, restoring the global variables */
375 Storeglobal r9, _caml_bottom_of_stack, r12
376 Storeglobal r10, _caml_last_return_address, r12
377 Storeglobal r11, _caml_gc_regs, r12
379 /* Update allocation pointer */
380 Storeglobal r31, _caml_young_ptr, r11
381 /* Restore callee-save registers */
382 addi r11, r1, 16-WORD
419 /* Reload return address */
423 addi r1, r1, FRAMESIZE
426 /* The trap handler: */
428 /* Update caml_exception_pointer */
429 Storeglobal r29, _caml_exception_pointer, r11
430 /* Encode exception bucket as an exception result and return it */
435 /* Callback from C to Caml */
437 .globl _caml_callback_exn
439 /* Initial shuffling of arguments */
440 mr r0, r3 /* Closure */
441 mr r3, r4 /* Argument */
443 lg r12, 0(r4) /* Code pointer */
446 .globl _caml_callback2_exn
448 mr r0, r3 /* Closure */
449 mr r3, r4 /* First argument */
450 mr r4, r5 /* Second argument */
452 Addrglobal r12, _caml_apply2
455 .globl _caml_callback3_exn
457 mr r0, r3 /* Closure */
458 mr r3, r4 /* First argument */
459 mr r4, r5 /* Second argument */
460 mr r5, r6 /* Third argument */
462 Addrglobal r12, _caml_apply3
468 .globl _caml_system__frametable
469 _caml_system__frametable:
470 gdata 1 /* one descriptor */
471 gdata L105 + 4 /* return address into callback */
472 .short -1 /* negative size count => use callback link */
473 .short 0 /* no roots here */