1998-10-10 07:56:53 -07:00
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
2011-07-27 07:17:02 -07:00
|
|
|
/* OCaml */
|
1998-10-10 07:56:53 -07:00
|
|
|
/* */
|
2012-02-04 02:15:24 -08:00
|
|
|
/* Benedikt Meurer, University of Siegen */
|
1998-10-10 07:56:53 -07:00
|
|
|
/* */
|
2012-02-05 00:47:16 -08:00
|
|
|
/* Copyright 1998 Institut National de Recherche en Informatique */
|
|
|
|
/* et en Automatique. Copyright 2012 Benedikt Meurer. All rights */
|
|
|
|
/* reserved. This file is distributed under the terms of the GNU */
|
|
|
|
/* Library General Public License, with the special exception on */
|
|
|
|
/* linking described in file ../LICENSE. */
|
1998-10-10 07:56:53 -07:00
|
|
|
/* */
|
|
|
|
/***********************************************************************/
|
|
|
|
|
|
|
|
/* Asm part of the runtime system, ARM processor */
|
2012-02-04 02:15:24 -08:00
|
|
|
/* Must be preprocessed by cpp */
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.syntax unified
|
1998-10-10 07:56:53 -07:00
|
|
|
.text
|
2012-10-23 23:20:45 -07:00
|
|
|
#if defined(SYS_linux_eabihf) && defined(MODEL_armv6)
|
|
|
|
.arch armv6
|
|
|
|
.fpu vfpv2
|
|
|
|
.arm
|
|
|
|
|
|
|
|
/* Compatibility macros */
|
|
|
|
.macro cbz reg, lbl
|
|
|
|
cmp \reg, #0
|
|
|
|
beq \lbl
|
|
|
|
.endm
|
|
|
|
#elif defined(SYS_linux_eabihf)
|
2012-02-04 02:15:24 -08:00
|
|
|
.arch armv7-a
|
|
|
|
.fpu vfpv3-d16
|
|
|
|
.thumb
|
|
|
|
#elif defined(SYS_linux_eabi)
|
|
|
|
.arch armv4t
|
|
|
|
.arm
|
|
|
|
|
|
|
|
/* Compatibility macros */
|
|
|
|
.macro blx reg
|
|
|
|
mov lr, pc
|
|
|
|
bx \reg
|
|
|
|
.endm
|
|
|
|
.macro cbz reg, lbl
|
|
|
|
cmp \reg, #0
|
|
|
|
beq \lbl
|
|
|
|
.endm
|
|
|
|
.macro vpop regs
|
|
|
|
.endm
|
|
|
|
.macro vpush regs
|
|
|
|
.endm
|
|
|
|
#endif
|
|
|
|
|
|
|
|
trap_ptr .req r8
|
|
|
|
alloc_ptr .req r10
|
|
|
|
alloc_limit .req r11
|
|
|
|
|
|
|
|
/* Support for profiling with gprof */
|
|
|
|
|
|
|
|
#if defined(PROFILING) && (defined(SYS_linux_eabihf) || defined(SYS_linux_eabi))
|
|
|
|
#define PROFILE \
|
|
|
|
push {lr}; \
|
|
|
|
bl __gnu_mcount_nc
|
|
|
|
#else
|
|
|
|
#define PROFILE
|
|
|
|
#endif
|
1998-10-10 07:56:53 -07:00
|
|
|
|
|
|
|
/* Allocation functions and GC interface */
|
|
|
|
|
2012-02-17 02:12:09 -08:00
|
|
|
.globl caml_system__code_begin
|
|
|
|
caml_system__code_begin:
|
2012-07-30 11:04:46 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_call_gc
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_call_gc, %function
|
1998-10-10 07:56:53 -07:00
|
|
|
caml_call_gc:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
/* Record return address */
|
|
|
|
ldr r12, =caml_last_return_address
|
|
|
|
str lr, [r12]
|
|
|
|
.Lcaml_call_gc:
|
|
|
|
/* Record lowest stack address */
|
|
|
|
ldr r12, =caml_bottom_of_stack
|
|
|
|
str sp, [r12]
|
|
|
|
/* Save caller floating-point registers on the stack */
|
|
|
|
vpush {d0-d7}
|
|
|
|
/* Save integer registers and return address on the stack */
|
|
|
|
push {r0-r7,r12,lr}
|
|
|
|
/* Store pointer to saved integer registers in caml_gc_regs */
|
|
|
|
ldr r12, =caml_gc_regs
|
|
|
|
str sp, [r12]
|
|
|
|
/* Save current allocation pointer for debugging purposes */
|
|
|
|
ldr alloc_limit, =caml_young_ptr
|
|
|
|
str alloc_ptr, [alloc_limit]
|
|
|
|
/* Save trap pointer in case an exception is raised during GC */
|
|
|
|
ldr r12, =caml_exception_pointer
|
|
|
|
str trap_ptr, [r12]
|
|
|
|
/* Call the garbage collector */
|
|
|
|
bl caml_garbage_collection
|
|
|
|
/* Restore integer registers and return address from the stack */
|
|
|
|
pop {r0-r7,r12,lr}
|
|
|
|
/* Restore floating-point registers from the stack */
|
|
|
|
vpop {d0-d7}
|
|
|
|
/* Reload new allocation pointer and limit */
|
|
|
|
/* alloc_limit still points to caml_young_ptr */
|
|
|
|
ldr r12, =caml_young_limit
|
|
|
|
ldr alloc_ptr, [alloc_limit]
|
|
|
|
ldr alloc_limit, [r12]
|
|
|
|
/* Return to caller */
|
2009-05-04 06:46:46 -07:00
|
|
|
bx lr
|
2012-02-04 02:15:24 -08:00
|
|
|
.type caml_call_gc, %function
|
|
|
|
.size caml_call_gc, .-caml_call_gc
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_alloc1
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_alloc1, %function
|
1998-10-10 07:56:53 -07:00
|
|
|
caml_alloc1:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
.Lcaml_alloc1:
|
|
|
|
sub alloc_ptr, alloc_ptr, 8
|
2009-05-04 06:46:46 -07:00
|
|
|
cmp alloc_ptr, alloc_limit
|
2012-02-04 02:15:24 -08:00
|
|
|
bcc 1f
|
|
|
|
bx lr
|
|
|
|
1: /* Record return address */
|
|
|
|
ldr r7, =caml_last_return_address
|
|
|
|
str lr, [r7]
|
|
|
|
/* Call GC (preserves r7) */
|
|
|
|
bl .Lcaml_call_gc
|
|
|
|
/* Restore return address */
|
|
|
|
ldr lr, [r7]
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Try again */
|
2012-02-04 02:15:24 -08:00
|
|
|
b .Lcaml_alloc1
|
|
|
|
.type caml_alloc1, %function
|
|
|
|
.size caml_alloc1, .-caml_alloc1
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_alloc2
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_alloc2, %function
|
1998-10-10 07:56:53 -07:00
|
|
|
caml_alloc2:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
.Lcaml_alloc2:
|
|
|
|
sub alloc_ptr, alloc_ptr, 12
|
2009-05-04 06:46:46 -07:00
|
|
|
cmp alloc_ptr, alloc_limit
|
2012-02-04 02:15:24 -08:00
|
|
|
bcc 1f
|
|
|
|
bx lr
|
|
|
|
1: /* Record return address */
|
|
|
|
ldr r7, =caml_last_return_address
|
|
|
|
str lr, [r7]
|
|
|
|
/* Call GC (preserves r7) */
|
|
|
|
bl .Lcaml_call_gc
|
|
|
|
/* Restore return address */
|
|
|
|
ldr lr, [r7]
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Try again */
|
2012-02-04 02:15:24 -08:00
|
|
|
b .Lcaml_alloc2
|
|
|
|
.type caml_alloc2, %function
|
|
|
|
.size caml_alloc2, .-caml_alloc2
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_alloc3
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_alloc3, %function
|
1998-10-10 07:56:53 -07:00
|
|
|
caml_alloc3:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
.Lcaml_alloc3:
|
|
|
|
sub alloc_ptr, alloc_ptr, 16
|
2009-05-04 06:46:46 -07:00
|
|
|
cmp alloc_ptr, alloc_limit
|
2012-02-04 02:15:24 -08:00
|
|
|
bcc 1f
|
|
|
|
bx lr
|
|
|
|
1: /* Record return address */
|
|
|
|
ldr r7, =caml_last_return_address
|
|
|
|
str lr, [r7]
|
|
|
|
/* Call GC (preserves r7) */
|
|
|
|
bl .Lcaml_call_gc
|
|
|
|
/* Restore return address */
|
|
|
|
ldr lr, [r7]
|
1998-10-15 09:10:53 -07:00
|
|
|
/* Try again */
|
2012-02-04 02:15:24 -08:00
|
|
|
b .Lcaml_alloc3
|
|
|
|
.type caml_alloc3, %function
|
|
|
|
.size caml_alloc3, .-caml_alloc3
|
1998-10-15 09:10:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_allocN
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_allocN, %function
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_allocN:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
.Lcaml_allocN:
|
|
|
|
sub alloc_ptr, alloc_ptr, r7
|
2009-05-04 06:46:46 -07:00
|
|
|
cmp alloc_ptr, alloc_limit
|
2012-02-04 02:15:24 -08:00
|
|
|
bcc 1f
|
|
|
|
bx lr
|
|
|
|
1: /* Record return address */
|
|
|
|
ldr r12, =caml_last_return_address
|
|
|
|
str lr, [r12]
|
|
|
|
/* Call GC (preserves r7) */
|
|
|
|
bl .Lcaml_call_gc
|
|
|
|
/* Restore return address */
|
|
|
|
ldr r12, =caml_last_return_address
|
|
|
|
ldr lr, [r12]
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Try again */
|
2012-02-04 02:15:24 -08:00
|
|
|
b .Lcaml_allocN
|
|
|
|
.type caml_allocN, %function
|
|
|
|
.size caml_allocN, .-caml_allocN
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-10 08:15:24 -08:00
|
|
|
/* Call a C function from OCaml */
|
2012-02-04 02:15:24 -08:00
|
|
|
/* Function to call is in r7 */
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_c_call
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_c_call, %function
|
1998-10-10 07:56:53 -07:00
|
|
|
caml_c_call:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
/* Record lowest stack address and return address */
|
|
|
|
ldr r5, =caml_last_return_address
|
|
|
|
ldr r6, =caml_bottom_of_stack
|
|
|
|
str lr, [r5]
|
|
|
|
str sp, [r6]
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Preserve return address in callee-save register r4 */
|
|
|
|
mov r4, lr
|
2012-02-04 02:15:24 -08:00
|
|
|
/* Make the exception handler alloc ptr available to the C code */
|
|
|
|
ldr r5, =caml_young_ptr
|
|
|
|
ldr r6, =caml_exception_pointer
|
|
|
|
str alloc_ptr, [r5]
|
|
|
|
str trap_ptr, [r6]
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Call the function */
|
2012-02-04 02:15:24 -08:00
|
|
|
blx r7
|
2009-05-04 06:46:46 -07:00
|
|
|
/* Reload alloc ptr and alloc limit */
|
2012-02-04 02:15:24 -08:00
|
|
|
ldr r6, =caml_young_limit
|
|
|
|
ldr alloc_ptr, [r5] /* r5 still points to caml_young_ptr */
|
|
|
|
ldr alloc_limit, [r6]
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Return */
|
2009-05-04 06:46:46 -07:00
|
|
|
bx r4
|
2012-02-04 02:15:24 -08:00
|
|
|
.type caml_c_call, %function
|
|
|
|
.size caml_c_call, .-caml_c_call
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-10 08:15:24 -08:00
|
|
|
/* Start the OCaml program */
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_start_program
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_start_program, %function
|
1998-10-10 07:56:53 -07:00
|
|
|
caml_start_program:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
ldr r12, =caml_program
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2003-12-31 06:20:40 -08:00
|
|
|
/* Code shared with caml_callback* */
|
2012-02-10 08:15:24 -08:00
|
|
|
/* Address of OCaml code to call is in r12 */
|
|
|
|
/* Arguments to the OCaml code are in r0...r3 */
|
1998-10-10 07:56:53 -07:00
|
|
|
|
|
|
|
.Ljump_to_caml:
|
|
|
|
/* Save return address and callee-save registers */
|
2012-02-04 02:15:24 -08:00
|
|
|
vpush {d8-d15}
|
|
|
|
push {r4-r8,r10,r11,lr} /* 8-byte alignment */
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Setup a callback link on the stack */
|
2012-02-04 02:15:24 -08:00
|
|
|
sub sp, sp, 4*4 /* 8-byte alignment */
|
|
|
|
ldr r4, =caml_bottom_of_stack
|
|
|
|
ldr r5, =caml_last_return_address
|
|
|
|
ldr r6, =caml_gc_regs
|
|
|
|
ldr r4, [r4]
|
|
|
|
ldr r5, [r5]
|
|
|
|
ldr r6, [r6]
|
|
|
|
str r4, [sp, 0]
|
|
|
|
str r5, [sp, 4]
|
|
|
|
str r6, [sp, 8]
|
2012-02-10 08:15:24 -08:00
|
|
|
/* Setup a trap frame to catch exceptions escaping the OCaml code */
|
2012-02-04 02:15:24 -08:00
|
|
|
sub sp, sp, 2*4
|
|
|
|
ldr r6, =caml_exception_pointer
|
|
|
|
ldr r5, =.Ltrap_handler
|
|
|
|
ldr r4, [r6]
|
|
|
|
str r4, [sp, 0]
|
|
|
|
str r5, [sp, 4]
|
2000-04-05 11:30:22 -07:00
|
|
|
mov trap_ptr, sp
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Reload allocation pointers */
|
2012-02-04 02:15:24 -08:00
|
|
|
ldr r4, =caml_young_ptr
|
|
|
|
ldr alloc_ptr, [r4]
|
|
|
|
ldr r4, =caml_young_limit
|
|
|
|
ldr alloc_limit, [r4]
|
2012-02-10 08:15:24 -08:00
|
|
|
/* Call the OCaml code */
|
2012-02-04 02:15:24 -08:00
|
|
|
blx r12
|
1998-10-10 07:56:53 -07:00
|
|
|
.Lcaml_retaddr:
|
|
|
|
/* Pop the trap frame, restoring caml_exception_pointer */
|
2012-02-04 02:15:24 -08:00
|
|
|
ldr r4, =caml_exception_pointer
|
|
|
|
ldr r5, [sp, 0]
|
|
|
|
str r5, [r4]
|
|
|
|
add sp, sp, 2*4
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Pop the callback link, restoring the global variables */
|
1999-02-14 08:48:25 -08:00
|
|
|
.Lreturn_result:
|
2012-02-04 02:15:24 -08:00
|
|
|
ldr r4, =caml_bottom_of_stack
|
|
|
|
ldr r5, [sp, 0]
|
|
|
|
str r5, [r4]
|
|
|
|
ldr r4, =caml_last_return_address
|
|
|
|
ldr r5, [sp, 4]
|
|
|
|
str r5, [r4]
|
|
|
|
ldr r4, =caml_gc_regs
|
|
|
|
ldr r5, [sp, 8]
|
|
|
|
str r5, [r4]
|
|
|
|
add sp, sp, 4*4
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Update allocation pointer */
|
2012-02-04 02:15:24 -08:00
|
|
|
ldr r4, =caml_young_ptr
|
|
|
|
str alloc_ptr, [r4]
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Reload callee-save registers and return */
|
2012-02-04 02:15:24 -08:00
|
|
|
pop {r4-r8,r10,r11,lr}
|
|
|
|
vpop {d8-d15}
|
|
|
|
bx lr
|
|
|
|
.type .Lcaml_retaddr, %function
|
|
|
|
.size .Lcaml_retaddr, .-.Lcaml_retaddr
|
|
|
|
.type caml_start_program, %function
|
|
|
|
.size caml_start_program, .-caml_start_program
|
|
|
|
|
|
|
|
/* The trap handler */
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
1998-10-10 07:56:53 -07:00
|
|
|
.Ltrap_handler:
|
1999-11-18 06:42:01 -08:00
|
|
|
/* Save exception pointer */
|
2012-02-04 02:15:24 -08:00
|
|
|
ldr r12, =caml_exception_pointer
|
|
|
|
str trap_ptr, [r12]
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Encode exception bucket as an exception result */
|
2012-02-04 02:15:24 -08:00
|
|
|
orr r0, r0, 2
|
1999-02-14 08:48:25 -08:00
|
|
|
/* Return it */
|
|
|
|
b .Lreturn_result
|
2012-02-04 02:15:24 -08:00
|
|
|
.type .Ltrap_handler, %function
|
|
|
|
.size .Ltrap_handler, .-.Ltrap_handler
|
|
|
|
|
2012-02-10 08:15:24 -08:00
|
|
|
/* Raise an exception from OCaml */
|
2012-02-04 02:15:24 -08:00
|
|
|
|
|
|
|
.align 2
|
|
|
|
.globl caml_raise_exn
|
|
|
|
caml_raise_exn:
|
|
|
|
PROFILE
|
|
|
|
/* Test if backtrace is active */
|
|
|
|
ldr r1, =caml_backtrace_active
|
|
|
|
ldr r1, [r1]
|
|
|
|
cbz r1, 1f
|
|
|
|
/* Preserve exception bucket in callee-save register r4 */
|
|
|
|
mov r4, r0
|
|
|
|
/* Stash the backtrace */
|
|
|
|
mov r1, lr /* arg2: pc of raise */
|
|
|
|
mov r2, sp /* arg3: sp of raise */
|
|
|
|
mov r3, trap_ptr /* arg4: sp of handler */
|
|
|
|
bl caml_stash_backtrace
|
|
|
|
/* Restore exception bucket */
|
|
|
|
mov r0, r4
|
|
|
|
1: /* Cut stack at current trap handler */
|
|
|
|
mov sp, trap_ptr
|
|
|
|
/* Pop previous handler and addr of trap, and jump to it */
|
|
|
|
pop {trap_ptr, pc}
|
|
|
|
.type caml_raise_exn, %function
|
|
|
|
.size caml_raise_exn, .-caml_raise_exn
|
1998-10-10 07:56:53 -07:00
|
|
|
|
|
|
|
/* Raise an exception from C */
|
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_raise_exception
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_raise_exception, %function
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_raise_exception:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
/* Reload trap ptr, alloc ptr and alloc limit */
|
|
|
|
ldr trap_ptr, =caml_exception_pointer
|
|
|
|
ldr alloc_ptr, =caml_young_ptr
|
|
|
|
ldr alloc_limit, =caml_young_limit
|
|
|
|
ldr trap_ptr, [trap_ptr]
|
|
|
|
ldr alloc_ptr, [alloc_ptr]
|
|
|
|
ldr alloc_limit, [alloc_limit]
|
|
|
|
/* Test if backtrace is active */
|
|
|
|
ldr r1, =caml_backtrace_active
|
|
|
|
ldr r1, [r1]
|
|
|
|
cbz r1, 1f
|
|
|
|
/* Preserve exception bucket in callee-save register r4 */
|
|
|
|
mov r4, r0
|
|
|
|
ldr r1, =caml_last_return_address /* arg2: pc of raise */
|
|
|
|
ldr r1, [r1]
|
|
|
|
ldr r2, =caml_bottom_of_stack /* arg3: sp of raise */
|
|
|
|
ldr r2, [r2]
|
|
|
|
mov r3, trap_ptr /* arg4: sp of handler */
|
|
|
|
bl caml_stash_backtrace
|
|
|
|
/* Restore exception bucket */
|
|
|
|
mov r0, r4
|
|
|
|
1: /* Cut stack at current trap handler */
|
|
|
|
mov sp, trap_ptr
|
1998-10-15 09:10:53 -07:00
|
|
|
/* Pop previous handler and addr of trap, and jump to it */
|
2012-02-04 02:15:24 -08:00
|
|
|
pop {trap_ptr, pc}
|
|
|
|
.type caml_raise_exception, %function
|
|
|
|
.size caml_raise_exception, .-caml_raise_exception
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-10 08:15:24 -08:00
|
|
|
/* Callback from C to OCaml */
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_callback_exn
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_callback_exn, %function
|
2003-12-31 06:20:40 -08:00
|
|
|
caml_callback_exn:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Initial shuffling of arguments (r0 = closure, r1 = first arg) */
|
2009-05-04 06:46:46 -07:00
|
|
|
mov r12, r0
|
2012-02-04 02:15:24 -08:00
|
|
|
mov r0, r1 /* r0 = first arg */
|
|
|
|
mov r1, r12 /* r1 = closure environment */
|
|
|
|
ldr r12, [r12] /* code pointer */
|
1998-10-10 07:56:53 -07:00
|
|
|
b .Ljump_to_caml
|
2012-02-04 02:15:24 -08:00
|
|
|
.type caml_callback_exn, %function
|
|
|
|
.size caml_callback_exn, .-caml_callback_exn
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_callback2_exn
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_callback2_exn, %function
|
2003-12-31 06:20:40 -08:00
|
|
|
caml_callback2_exn:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Initial shuffling of arguments (r0 = closure, r1 = arg1, r2 = arg2) */
|
2009-05-04 06:46:46 -07:00
|
|
|
mov r12, r0
|
2012-02-04 02:15:24 -08:00
|
|
|
mov r0, r1 /* r0 = first arg */
|
|
|
|
mov r1, r2 /* r1 = second arg */
|
|
|
|
mov r2, r12 /* r2 = closure environment */
|
|
|
|
ldr r12, =caml_apply2
|
1998-10-10 07:56:53 -07:00
|
|
|
b .Ljump_to_caml
|
2012-02-04 02:15:24 -08:00
|
|
|
.type caml_callback2_exn, %function
|
|
|
|
.size caml_callback2_exn, .-caml_callback2_exn
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_callback3_exn
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_callback3_exn, %function
|
2003-12-31 06:20:40 -08:00
|
|
|
caml_callback3_exn:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
1998-10-10 07:56:53 -07:00
|
|
|
/* Initial shuffling of arguments */
|
|
|
|
/* (r0 = closure, r1 = arg1, r2 = arg2, r3 = arg3) */
|
2009-05-04 06:46:46 -07:00
|
|
|
mov r12, r0
|
1998-10-10 07:56:53 -07:00
|
|
|
mov r0, r1 /* r0 = first arg */
|
|
|
|
mov r1, r2 /* r1 = second arg */
|
1998-10-15 09:10:53 -07:00
|
|
|
mov r2, r3 /* r2 = third arg */
|
2009-05-04 06:46:46 -07:00
|
|
|
mov r3, r12 /* r3 = closure environment */
|
2012-02-04 02:15:24 -08:00
|
|
|
ldr r12, =caml_apply3
|
1998-10-10 07:56:53 -07:00
|
|
|
b .Ljump_to_caml
|
2012-02-04 02:15:24 -08:00
|
|
|
.type caml_callback3_exn, %function
|
|
|
|
.size caml_callback3_exn, .-caml_callback3_exn
|
1998-10-10 07:56:53 -07:00
|
|
|
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_ml_array_bound_error
|
2012-03-08 11:52:03 -08:00
|
|
|
.type caml_ml_array_bound_error, %function
|
2004-01-01 08:42:43 -08:00
|
|
|
caml_ml_array_bound_error:
|
2012-02-04 02:15:24 -08:00
|
|
|
PROFILE
|
|
|
|
/* Load address of [caml_array_bound_error] in r7 */
|
|
|
|
ldr r7, =caml_array_bound_error
|
1998-11-11 07:35:48 -08:00
|
|
|
/* Call that function */
|
|
|
|
b caml_c_call
|
2012-02-04 02:15:24 -08:00
|
|
|
.type caml_ml_array_bound_error, %function
|
|
|
|
.size caml_ml_array_bound_error, .-caml_ml_array_bound_error
|
2008-02-29 06:21:22 -08:00
|
|
|
|
2012-02-17 02:12:09 -08:00
|
|
|
.globl caml_system__code_end
|
|
|
|
caml_system__code_end:
|
|
|
|
|
1998-10-10 07:56:53 -07:00
|
|
|
/* GC roots for callback */
|
|
|
|
|
|
|
|
.data
|
2012-02-04 02:15:24 -08:00
|
|
|
.align 2
|
|
|
|
.globl caml_system__frametable
|
2004-01-03 04:51:20 -08:00
|
|
|
caml_system__frametable:
|
1998-10-10 07:56:53 -07:00
|
|
|
.word 1 /* one descriptor */
|
|
|
|
.word .Lcaml_retaddr /* return address into callback */
|
|
|
|
.short -1 /* negative frame size => use callback link */
|
|
|
|
.short 0 /* no roots */
|
|
|
|
.align 2
|
2012-02-04 02:15:24 -08:00
|
|
|
.type caml_system__frametable, %object
|
|
|
|
.size caml_system__frametable, .-caml_system__frametable
|