2016-02-19 09:13:32 -08:00
|
|
|
;**************************************************************************
|
|
|
|
;* *
|
|
|
|
;* OCaml *
|
|
|
|
;* *
|
|
|
|
;* Xavier Leroy, projet Cristal, INRIA Rocquencourt *
|
|
|
|
;* *
|
|
|
|
;* Copyright 1996 Institut National de Recherche en Informatique et *
|
|
|
|
;* en Automatique. *
|
|
|
|
;* *
|
|
|
|
;* All rights reserved. This file is distributed under the terms of *
|
|
|
|
;* the GNU Lesser General Public License version 2.1, with the *
|
|
|
|
;* special exception on linking described in the file LICENSE. *
|
|
|
|
;* *
|
|
|
|
;**************************************************************************
|
1996-02-21 02:49:46 -08:00
|
|
|
|
|
|
|
; Asm part of the runtime system, Intel 386 processor, Intel syntax
|
|
|
|
|
2012-07-30 11:04:46 -07:00
|
|
|
.386
|
|
|
|
.MODEL FLAT
|
1996-02-21 02:49:46 -08:00
|
|
|
|
2004-05-04 02:02:47 -07:00
|
|
|
EXTERN _caml_garbage_collection: PROC
|
1996-02-21 02:49:46 -08:00
|
|
|
EXTERN _caml_apply2: PROC
|
|
|
|
EXTERN _caml_apply3: PROC
|
|
|
|
EXTERN _caml_program: PROC
|
2004-05-04 02:02:47 -07:00
|
|
|
EXTERN _caml_array_bound_error: PROC
|
|
|
|
EXTERN _caml_young_limit: DWORD
|
|
|
|
EXTERN _caml_young_ptr: DWORD
|
2012-07-30 11:04:46 -07:00
|
|
|
EXTERN _caml_bottom_of_stack: DWORD
|
|
|
|
EXTERN _caml_last_return_address: DWORD
|
|
|
|
EXTERN _caml_gc_regs: DWORD
|
|
|
|
EXTERN _caml_exception_pointer: DWORD
|
2013-10-15 06:09:01 -07:00
|
|
|
EXTERN _caml_backtrace_pos: DWORD
|
2007-01-29 04:11:18 -08:00
|
|
|
EXTERN _caml_backtrace_active: DWORD
|
|
|
|
EXTERN _caml_stash_backtrace: PROC
|
1996-02-21 02:49:46 -08:00
|
|
|
|
2010-01-22 04:48:24 -08:00
|
|
|
; Allocation
|
1996-02-21 02:49:46 -08:00
|
|
|
|
|
|
|
.CODE
|
|
|
|
PUBLIC _caml_alloc1
|
|
|
|
PUBLIC _caml_alloc2
|
|
|
|
PUBLIC _caml_alloc3
|
2004-05-04 02:02:47 -07:00
|
|
|
PUBLIC _caml_allocN
|
2012-07-30 11:04:46 -07:00
|
|
|
PUBLIC _caml_call_gc
|
1996-02-21 02:49:46 -08:00
|
|
|
|
1996-05-16 12:39:26 -07:00
|
|
|
_caml_call_gc:
|
2010-01-22 04:48:24 -08:00
|
|
|
; Record lowest stack address and return address
|
2012-07-30 11:04:46 -07:00
|
|
|
mov eax, [esp]
|
1996-05-16 12:39:26 -07:00
|
|
|
mov _caml_last_return_address, eax
|
|
|
|
lea eax, [esp+4]
|
|
|
|
mov _caml_bottom_of_stack, eax
|
2010-01-22 04:48:24 -08:00
|
|
|
; Save all regs used by the code generator
|
1997-11-27 08:28:40 -08:00
|
|
|
L105: push ebp
|
|
|
|
push edi
|
|
|
|
push esi
|
|
|
|
push edx
|
|
|
|
push ecx
|
|
|
|
push ebx
|
|
|
|
push eax
|
|
|
|
mov _caml_gc_regs, esp
|
2010-01-22 04:48:24 -08:00
|
|
|
; Call the garbage collector
|
2012-07-30 11:04:46 -07:00
|
|
|
call _caml_garbage_collection
|
2010-01-22 04:48:24 -08:00
|
|
|
; Restore all regs used by the code generator
|
2012-07-30 11:04:46 -07:00
|
|
|
pop eax
|
1997-11-27 08:28:40 -08:00
|
|
|
pop ebx
|
|
|
|
pop ecx
|
|
|
|
pop edx
|
|
|
|
pop esi
|
|
|
|
pop edi
|
|
|
|
pop ebp
|
2010-01-22 04:48:24 -08:00
|
|
|
; Return to caller
|
|
|
|
ret
|
1996-05-16 12:39:26 -07:00
|
|
|
|
1996-02-21 02:49:46 -08:00
|
|
|
ALIGN 4
|
|
|
|
_caml_alloc1:
|
2012-07-30 11:04:46 -07:00
|
|
|
mov eax, _caml_young_ptr
|
|
|
|
sub eax, 8
|
|
|
|
mov _caml_young_ptr, eax
|
|
|
|
cmp eax, _caml_young_limit
|
|
|
|
jb L100
|
2010-01-22 04:48:24 -08:00
|
|
|
ret
|
2012-07-30 11:04:46 -07:00
|
|
|
L100: mov eax, [esp]
|
1996-05-16 12:39:26 -07:00
|
|
|
mov _caml_last_return_address, eax
|
|
|
|
lea eax, [esp+4]
|
|
|
|
mov _caml_bottom_of_stack, eax
|
|
|
|
call L105
|
|
|
|
jmp _caml_alloc1
|
1996-02-21 02:49:46 -08:00
|
|
|
|
|
|
|
ALIGN 4
|
|
|
|
_caml_alloc2:
|
2012-07-30 11:04:46 -07:00
|
|
|
mov eax, _caml_young_ptr
|
|
|
|
sub eax, 12
|
|
|
|
mov _caml_young_ptr, eax
|
|
|
|
cmp eax, _caml_young_limit
|
|
|
|
jb L101
|
2010-01-22 04:48:24 -08:00
|
|
|
ret
|
2012-07-30 11:04:46 -07:00
|
|
|
L101: mov eax, [esp]
|
1996-05-16 12:39:26 -07:00
|
|
|
mov _caml_last_return_address, eax
|
|
|
|
lea eax, [esp+4]
|
|
|
|
mov _caml_bottom_of_stack, eax
|
|
|
|
call L105
|
|
|
|
jmp _caml_alloc2
|
1996-02-21 02:49:46 -08:00
|
|
|
|
|
|
|
ALIGN 4
|
|
|
|
_caml_alloc3:
|
2012-07-30 11:04:46 -07:00
|
|
|
mov eax, _caml_young_ptr
|
|
|
|
sub eax, 16
|
|
|
|
mov _caml_young_ptr, eax
|
|
|
|
cmp eax, _caml_young_limit
|
|
|
|
jb L102
|
2010-01-22 04:48:24 -08:00
|
|
|
ret
|
2012-07-30 11:04:46 -07:00
|
|
|
L102: mov eax, [esp]
|
1996-05-16 12:39:26 -07:00
|
|
|
mov _caml_last_return_address, eax
|
|
|
|
lea eax, [esp+4]
|
|
|
|
mov _caml_bottom_of_stack, eax
|
|
|
|
call L105
|
|
|
|
jmp _caml_alloc3
|
1996-02-21 02:49:46 -08:00
|
|
|
|
|
|
|
ALIGN 4
|
2004-05-04 02:02:47 -07:00
|
|
|
_caml_allocN:
|
|
|
|
sub eax, _caml_young_ptr ; eax = size - young_ptr
|
1996-05-16 12:39:26 -07:00
|
|
|
neg eax ; eax = young_ptr - size
|
2004-05-04 02:02:47 -07:00
|
|
|
cmp eax, _caml_young_limit
|
1996-05-16 12:39:26 -07:00
|
|
|
jb L103
|
2004-05-04 02:02:47 -07:00
|
|
|
mov _caml_young_ptr, eax
|
1996-05-16 12:39:26 -07:00
|
|
|
ret
|
2004-05-04 02:02:47 -07:00
|
|
|
L103: sub eax, _caml_young_ptr ; eax = - size
|
1996-05-16 12:39:26 -07:00
|
|
|
neg eax ; eax = size
|
|
|
|
push eax ; save desired size
|
2004-05-04 02:02:47 -07:00
|
|
|
sub _caml_young_ptr, eax ; must update young_ptr
|
2012-07-30 11:04:46 -07:00
|
|
|
mov eax, [esp+4]
|
1996-05-16 12:39:26 -07:00
|
|
|
mov _caml_last_return_address, eax
|
|
|
|
lea eax, [esp+8]
|
|
|
|
mov _caml_bottom_of_stack, eax
|
|
|
|
call L105
|
|
|
|
pop eax ; recover desired size
|
2004-05-04 02:02:47 -07:00
|
|
|
jmp _caml_allocN
|
1996-02-21 02:49:46 -08:00
|
|
|
|
2012-02-10 08:15:24 -08:00
|
|
|
; Call a C function from OCaml
|
1996-02-21 02:49:46 -08:00
|
|
|
|
|
|
|
PUBLIC _caml_c_call
|
|
|
|
ALIGN 4
|
|
|
|
_caml_c_call:
|
2010-01-22 04:48:24 -08:00
|
|
|
; Record lowest stack address and return address
|
2012-07-30 11:04:46 -07:00
|
|
|
mov edx, [esp]
|
|
|
|
mov _caml_last_return_address, edx
|
|
|
|
lea edx, [esp+4]
|
|
|
|
mov _caml_bottom_of_stack, edx
|
2010-01-22 04:48:24 -08:00
|
|
|
; Call the function (address in %eax)
|
2012-07-30 11:04:46 -07:00
|
|
|
jmp eax
|
1996-02-21 02:49:46 -08:00
|
|
|
|
2012-02-10 08:15:24 -08:00
|
|
|
; Start the OCaml program
|
1996-02-21 02:49:46 -08:00
|
|
|
|
|
|
|
PUBLIC _caml_start_program
|
|
|
|
ALIGN 4
|
|
|
|
_caml_start_program:
|
2010-01-22 04:48:24 -08:00
|
|
|
; Save callee-save registers
|
2012-07-30 11:04:46 -07:00
|
|
|
push ebx
|
|
|
|
push esi
|
|
|
|
push edi
|
|
|
|
push ebp
|
1997-03-17 02:17:32 -08:00
|
|
|
; Initial code pointer is caml_program
|
|
|
|
mov esi, offset _caml_program
|
1996-02-21 02:49:46 -08:00
|
|
|
|
1997-03-17 02:17:32 -08:00
|
|
|
; Code shared between caml_start_program and callback*
|
1996-02-21 02:49:46 -08:00
|
|
|
|
|
|
|
L106:
|
2010-01-22 04:48:24 -08:00
|
|
|
; Build a callback link
|
1997-12-01 05:04:05 -08:00
|
|
|
push _caml_gc_regs
|
2012-07-30 11:04:46 -07:00
|
|
|
push _caml_last_return_address
|
|
|
|
push _caml_bottom_of_stack
|
2010-01-22 04:48:24 -08:00
|
|
|
; Build an exception handler
|
2012-07-30 11:04:46 -07:00
|
|
|
push L108
|
|
|
|
push _caml_exception_pointer
|
|
|
|
mov _caml_exception_pointer, esp
|
2012-02-10 08:15:24 -08:00
|
|
|
; Call the OCaml code
|
2012-07-30 11:04:46 -07:00
|
|
|
call esi
|
1996-02-21 02:49:46 -08:00
|
|
|
L107:
|
2010-01-22 04:48:24 -08:00
|
|
|
; Pop the exception handler
|
2012-07-30 11:04:46 -07:00
|
|
|
pop _caml_exception_pointer
|
|
|
|
pop esi ; dummy register
|
1999-02-14 08:48:25 -08:00
|
|
|
L109:
|
1996-02-21 02:49:46 -08:00
|
|
|
; Pop the callback link, restoring the global variables
|
|
|
|
; used by caml_c_call
|
2012-07-30 11:04:46 -07:00
|
|
|
pop _caml_bottom_of_stack
|
|
|
|
pop _caml_last_return_address
|
1997-12-01 05:04:05 -08:00
|
|
|
pop _caml_gc_regs
|
1996-02-21 02:49:46 -08:00
|
|
|
; Restore callee-save registers.
|
2012-07-30 11:04:46 -07:00
|
|
|
pop ebp
|
|
|
|
pop edi
|
|
|
|
pop esi
|
|
|
|
pop ebx
|
2010-01-22 04:48:24 -08:00
|
|
|
; Return to caller.
|
|
|
|
ret
|
1996-02-21 02:49:46 -08:00
|
|
|
L108:
|
|
|
|
; Exception handler
|
1999-02-14 08:48:25 -08:00
|
|
|
; Mark the bucket as an exception result and return it
|
|
|
|
or eax, 2
|
|
|
|
jmp L109
|
1996-02-21 02:49:46 -08:00
|
|
|
|
2012-02-10 08:15:24 -08:00
|
|
|
; Raise an exception for OCaml
|
2007-01-29 04:11:18 -08:00
|
|
|
|
|
|
|
PUBLIC _caml_raise_exn
|
|
|
|
ALIGN 4
|
|
|
|
_caml_raise_exn:
|
|
|
|
test _caml_backtrace_active, 1
|
|
|
|
jne L110
|
2012-07-30 11:04:46 -07:00
|
|
|
mov esp, _caml_exception_pointer
|
|
|
|
pop _caml_exception_pointer
|
2010-01-22 04:48:24 -08:00
|
|
|
ret
|
2007-01-29 04:11:18 -08:00
|
|
|
L110:
|
2013-10-15 06:09:01 -07:00
|
|
|
mov _caml_backtrace_pos, 0
|
|
|
|
L111:
|
2007-01-29 04:11:18 -08:00
|
|
|
mov esi, eax ; Save exception bucket in esi
|
|
|
|
mov edi, _caml_exception_pointer ; SP of handler
|
|
|
|
mov eax, [esp] ; PC of raise
|
|
|
|
lea edx, [esp+4]
|
|
|
|
push edi ; arg 4: SP of handler
|
|
|
|
push edx ; arg 3: SP of raise
|
|
|
|
push eax ; arg 2: PC of raise
|
|
|
|
push esi ; arg 1: exception bucket
|
|
|
|
call _caml_stash_backtrace
|
|
|
|
mov eax, esi ; recover exception bucket
|
|
|
|
mov esp, edi ; cut the stack
|
|
|
|
pop _caml_exception_pointer
|
|
|
|
ret
|
|
|
|
|
2013-10-15 06:09:01 -07:00
|
|
|
PUBLIC _caml_reraise_exn
|
|
|
|
ALIGN 4
|
|
|
|
_caml_reraise_exn:
|
|
|
|
test _caml_backtrace_active, 1
|
|
|
|
jne L111
|
|
|
|
mov esp, _caml_exception_pointer
|
|
|
|
pop _caml_exception_pointer
|
|
|
|
ret
|
|
|
|
|
|
|
|
; Raise an exception from C
|
1997-03-17 02:17:32 -08:00
|
|
|
|
2004-05-04 02:02:47 -07:00
|
|
|
PUBLIC _caml_raise_exception
|
1997-03-17 02:17:32 -08:00
|
|
|
ALIGN 4
|
2004-05-04 02:02:47 -07:00
|
|
|
_caml_raise_exception:
|
2007-01-29 04:11:18 -08:00
|
|
|
test _caml_backtrace_active, 1
|
2013-10-15 06:09:01 -07:00
|
|
|
jne L112
|
2012-07-30 11:04:46 -07:00
|
|
|
mov eax, [esp+4]
|
|
|
|
mov esp, _caml_exception_pointer
|
|
|
|
pop _caml_exception_pointer
|
2010-01-22 04:48:24 -08:00
|
|
|
ret
|
2013-10-15 06:09:01 -07:00
|
|
|
L112:
|
2007-01-29 04:11:18 -08:00
|
|
|
mov esi, [esp+4] ; Save exception bucket in esi
|
|
|
|
push _caml_exception_pointer ; arg 4: SP of handler
|
|
|
|
push _caml_bottom_of_stack ; arg 3: SP of raise
|
|
|
|
push _caml_last_return_address ; arg 2: PC of raise
|
|
|
|
push esi ; arg 1: exception bucket
|
|
|
|
call _caml_stash_backtrace
|
|
|
|
mov eax, esi ; recover exception bucket
|
|
|
|
mov esp, _caml_exception_pointer ; cut the stack
|
|
|
|
pop _caml_exception_pointer
|
|
|
|
ret
|
1997-03-17 02:17:32 -08:00
|
|
|
|
2012-02-10 08:15:24 -08:00
|
|
|
; Callback from C to OCaml
|
1997-03-17 02:17:32 -08:00
|
|
|
|
2004-05-04 02:02:47 -07:00
|
|
|
PUBLIC _caml_callback_exn
|
1997-03-17 02:17:32 -08:00
|
|
|
ALIGN 4
|
2004-05-04 02:02:47 -07:00
|
|
|
_caml_callback_exn:
|
2010-01-22 04:48:24 -08:00
|
|
|
; Save callee-save registers
|
2012-07-30 11:04:46 -07:00
|
|
|
push ebx
|
|
|
|
push esi
|
|
|
|
push edi
|
|
|
|
push ebp
|
2010-01-22 04:48:24 -08:00
|
|
|
; Initial loading of arguments
|
2012-07-30 11:04:46 -07:00
|
|
|
mov ebx, [esp+20] ; closure
|
|
|
|
mov eax, [esp+24] ; argument
|
|
|
|
mov esi, [ebx] ; code pointer
|
1997-03-17 02:17:32 -08:00
|
|
|
jmp L106
|
|
|
|
|
2004-05-04 02:02:47 -07:00
|
|
|
PUBLIC _caml_callback2_exn
|
1996-02-21 02:49:46 -08:00
|
|
|
ALIGN 4
|
2004-05-04 02:02:47 -07:00
|
|
|
_caml_callback2_exn:
|
2010-01-22 04:48:24 -08:00
|
|
|
; Save callee-save registers
|
2012-07-30 11:04:46 -07:00
|
|
|
push ebx
|
|
|
|
push esi
|
|
|
|
push edi
|
|
|
|
push ebp
|
2010-01-22 04:48:24 -08:00
|
|
|
; Initial loading of arguments
|
2012-07-30 11:04:46 -07:00
|
|
|
mov ecx, [esp+20] ; closure
|
|
|
|
mov eax, [esp+24] ; first argument
|
|
|
|
mov ebx, [esp+28] ; second argument
|
|
|
|
mov esi, offset _caml_apply2 ; code pointer
|
|
|
|
jmp L106
|
1996-02-21 02:49:46 -08:00
|
|
|
|
2004-05-04 02:02:47 -07:00
|
|
|
PUBLIC _caml_callback3_exn
|
2012-07-30 11:04:46 -07:00
|
|
|
ALIGN 4
|
2004-05-04 02:02:47 -07:00
|
|
|
_caml_callback3_exn:
|
2010-01-22 04:48:24 -08:00
|
|
|
; Save callee-save registers
|
2012-07-30 11:04:46 -07:00
|
|
|
push ebx
|
|
|
|
push esi
|
|
|
|
push edi
|
|
|
|
push ebp
|
2010-01-22 04:48:24 -08:00
|
|
|
; Initial loading of arguments
|
2012-07-30 11:04:46 -07:00
|
|
|
mov edx, [esp+20] ; closure
|
|
|
|
mov eax, [esp+24] ; first argument
|
|
|
|
mov ebx, [esp+28] ; second argument
|
|
|
|
mov ecx, [esp+32] ; third argument
|
|
|
|
mov esi, offset _caml_apply3 ; code pointer
|
|
|
|
jmp L106
|
1996-02-21 02:49:46 -08:00
|
|
|
|
2004-05-04 02:02:47 -07:00
|
|
|
PUBLIC _caml_ml_array_bound_error
|
2003-06-30 08:39:39 -07:00
|
|
|
ALIGN 4
|
2004-05-04 02:02:47 -07:00
|
|
|
_caml_ml_array_bound_error:
|
2003-06-30 08:39:39 -07:00
|
|
|
; Empty the floating-point stack
|
|
|
|
ffree st(0)
|
|
|
|
ffree st(1)
|
|
|
|
ffree st(2)
|
|
|
|
ffree st(3)
|
|
|
|
ffree st(4)
|
|
|
|
ffree st(5)
|
|
|
|
ffree st(6)
|
|
|
|
ffree st(7)
|
2007-01-29 04:11:18 -08:00
|
|
|
; Branch to caml_array_bound_error
|
|
|
|
mov eax, offset _caml_array_bound_error
|
|
|
|
jmp _caml_c_call
|
2003-06-30 08:39:39 -07:00
|
|
|
|
1996-02-21 02:49:46 -08:00
|
|
|
.DATA
|
2004-05-04 02:02:47 -07:00
|
|
|
PUBLIC _caml_system__frametable
|
|
|
|
_caml_system__frametable LABEL DWORD
|
2010-01-22 04:48:24 -08:00
|
|
|
DWORD 1 ; one descriptor
|
|
|
|
DWORD L107 ; return address into callback
|
|
|
|
WORD -1 ; negative frame size => use callback link
|
|
|
|
WORD 0 ; no roots here
|
1996-02-21 02:49:46 -08:00
|
|
|
|
2004-08-12 07:29:25 -07:00
|
|
|
PUBLIC _caml_extra_params
|
|
|
|
_caml_extra_params LABEL DWORD
|
|
|
|
BYTE 64 DUP (?)
|
2005-10-12 05:56:53 -07:00
|
|
|
|
|
|
|
END
|