diff options
Diffstat (limited to 'ocaml-binary-annot/asmrun/i386nt.asm')
| -rw-r--r-- | ocaml-binary-annot/asmrun/i386nt.asm | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/ocaml-binary-annot/asmrun/i386nt.asm b/ocaml-binary-annot/asmrun/i386nt.asm new file mode 100644 index 0000000000..711449cfbb --- /dev/null +++ b/ocaml-binary-annot/asmrun/i386nt.asm @@ -0,0 +1,322 @@ +;********************************************************************* +; +; Objective Caml +; +; 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 Library General Public License, with +; the special exception on linking described in file ../LICENSE. +; +;********************************************************************* + +; $Id$ + +; Asm part of the runtime system, Intel 386 processor, Intel syntax + + .386 + .MODEL FLAT + + EXTERN _caml_garbage_collection: PROC + EXTERN _caml_apply2: PROC + EXTERN _caml_apply3: PROC + EXTERN _caml_program: PROC + EXTERN _caml_array_bound_error: PROC + EXTERN _caml_young_limit: DWORD + EXTERN _caml_young_ptr: DWORD + EXTERN _caml_bottom_of_stack: DWORD + EXTERN _caml_last_return_address: DWORD + EXTERN _caml_gc_regs: DWORD + EXTERN _caml_exception_pointer: DWORD + EXTERN _caml_backtrace_active: DWORD + EXTERN _caml_stash_backtrace: PROC + +; Allocation + + .CODE + PUBLIC _caml_alloc1 + PUBLIC _caml_alloc2 + PUBLIC _caml_alloc3 + PUBLIC _caml_allocN + PUBLIC _caml_call_gc + +_caml_call_gc: + ; Record lowest stack address and return address + mov eax, [esp] + mov _caml_last_return_address, eax + lea eax, [esp+4] + mov _caml_bottom_of_stack, eax + ; Save all regs used by the code generator +L105: push ebp + push edi + push esi + push edx + push ecx + push ebx + push eax + mov _caml_gc_regs, esp + ; Call the garbage collector + call _caml_garbage_collection + ; Restore all regs used by the code generator + pop eax + pop ebx + pop ecx + pop edx + pop esi + pop edi + pop ebp + ; Return to caller + ret + + ALIGN 4 +_caml_alloc1: + mov eax, _caml_young_ptr + sub eax, 8 + mov _caml_young_ptr, eax + cmp eax, _caml_young_limit + jb L100 + ret +L100: mov eax, [esp] + mov _caml_last_return_address, eax + lea eax, [esp+4] + mov _caml_bottom_of_stack, eax + call L105 + jmp _caml_alloc1 + + ALIGN 4 +_caml_alloc2: + mov eax, _caml_young_ptr + sub eax, 12 + mov _caml_young_ptr, eax + cmp eax, _caml_young_limit + jb L101 + ret +L101: mov eax, [esp] + mov _caml_last_return_address, eax + lea eax, [esp+4] + mov _caml_bottom_of_stack, eax + call L105 + jmp _caml_alloc2 + + ALIGN 4 +_caml_alloc3: + mov eax, _caml_young_ptr + sub eax, 16 + mov _caml_young_ptr, eax + cmp eax, _caml_young_limit + jb L102 + ret +L102: mov eax, [esp] + mov _caml_last_return_address, eax + lea eax, [esp+4] + mov _caml_bottom_of_stack, eax + call L105 + jmp _caml_alloc3 + + ALIGN 4 +_caml_allocN: + sub eax, _caml_young_ptr ; eax = size - young_ptr + neg eax ; eax = young_ptr - size + cmp eax, _caml_young_limit + jb L103 + mov _caml_young_ptr, eax + ret +L103: sub eax, _caml_young_ptr ; eax = - size + neg eax ; eax = size + push eax ; save desired size + sub _caml_young_ptr, eax ; must update young_ptr + mov eax, [esp+4] + mov _caml_last_return_address, eax + lea eax, [esp+8] + mov _caml_bottom_of_stack, eax + call L105 + pop eax ; recover desired size + jmp _caml_allocN + +; Call a C function from Caml + + PUBLIC _caml_c_call + ALIGN 4 +_caml_c_call: + ; Record lowest stack address and return address + mov edx, [esp] + mov _caml_last_return_address, edx + lea edx, [esp+4] + mov _caml_bottom_of_stack, edx + ; Call the function (address in %eax) + jmp eax + +; Start the Caml program + + PUBLIC _caml_start_program + ALIGN 4 +_caml_start_program: + ; Save callee-save registers + push ebx + push esi + push edi + push ebp + ; Initial code pointer is caml_program + mov esi, offset _caml_program + +; Code shared between caml_start_program and callback* + +L106: + ; Build a callback link + push _caml_gc_regs + push _caml_last_return_address + push _caml_bottom_of_stack + ; Build an exception handler + push L108 + push _caml_exception_pointer + mov _caml_exception_pointer, esp + ; Call the Caml code + call esi +L107: + ; Pop the exception handler + pop _caml_exception_pointer + pop esi ; dummy register +L109: + ; Pop the callback link, restoring the global variables + ; used by caml_c_call + pop _caml_bottom_of_stack + pop _caml_last_return_address + pop _caml_gc_regs + ; Restore callee-save registers. + pop ebp + pop edi + pop esi + pop ebx + ; Return to caller. + ret +L108: + ; Exception handler + ; Mark the bucket as an exception result and return it + or eax, 2 + jmp L109 + +; Raise an exception for Caml + + PUBLIC _caml_raise_exn + ALIGN 4 +_caml_raise_exn: + test _caml_backtrace_active, 1 + jne L110 + mov esp, _caml_exception_pointer + pop _caml_exception_pointer + ret +L110: + 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 + +; Raise an exception from C + + PUBLIC _caml_raise_exception + ALIGN 4 +_caml_raise_exception: + test _caml_backtrace_active, 1 + jne L111 + mov eax, [esp+4] + mov esp, _caml_exception_pointer + pop _caml_exception_pointer + ret +L111: + 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 + +; Callback from C to Caml + + PUBLIC _caml_callback_exn + ALIGN 4 +_caml_callback_exn: + ; Save callee-save registers + push ebx + push esi + push edi + push ebp + ; Initial loading of arguments + mov ebx, [esp+20] ; closure + mov eax, [esp+24] ; argument + mov esi, [ebx] ; code pointer + jmp L106 + + PUBLIC _caml_callback2_exn + ALIGN 4 +_caml_callback2_exn: + ; Save callee-save registers + push ebx + push esi + push edi + push ebp + ; Initial loading of arguments + 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 + + PUBLIC _caml_callback3_exn + ALIGN 4 +_caml_callback3_exn: + ; Save callee-save registers + push ebx + push esi + push edi + push ebp + ; Initial loading of arguments + 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 + + PUBLIC _caml_ml_array_bound_error + ALIGN 4 +_caml_ml_array_bound_error: + ; 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) + ; Branch to caml_array_bound_error + mov eax, offset _caml_array_bound_error + jmp _caml_c_call + + .DATA + PUBLIC _caml_system__frametable +_caml_system__frametable LABEL DWORD + DWORD 1 ; one descriptor + DWORD L107 ; return address into callback + WORD -1 ; negative frame size => use callback link + WORD 0 ; no roots here + + PUBLIC _caml_extra_params +_caml_extra_params LABEL DWORD + BYTE 64 DUP (?) + + END |
