173 lines
4.8 KiB
NASM
173 lines
4.8 KiB
NASM
#*********************************************************************#
|
|
# #
|
|
# Caml Special Light #
|
|
# #
|
|
# Xavier Leroy, projet Cristal, INRIA Rocquencourt #
|
|
# #
|
|
# Copyright 1995 Institut National de Recherche en Informatique et #
|
|
# Automatique. Distributed only by permission. #
|
|
# #
|
|
#*********************************************************************#
|
|
|
|
# $Id$ #
|
|
|
|
# Asm part of the runtime system, Intel 386 processor
|
|
|
|
.comm _young_start, 4
|
|
.comm _young_ptr, 4
|
|
.comm _gc_entry_regs, 4 * 7
|
|
.comm _caml_bottom_of_stack, 4
|
|
.comm _caml_top_of_stack, 4
|
|
.comm _caml_last_return_address, 4
|
|
.comm _remembered_ptr, 4
|
|
.comm _remembered_end, 4
|
|
.comm _caml_exception_pointer, 4
|
|
|
|
# Allocation
|
|
|
|
.text
|
|
.globl _caml_alloc1
|
|
.globl _caml_alloc2
|
|
.globl _caml_alloc3
|
|
.globl _caml_alloc
|
|
.globl _caml_call_gc
|
|
|
|
.align 4
|
|
_caml_alloc1:
|
|
movl _young_ptr, %eax
|
|
subl $8, %eax
|
|
movl %eax, _young_ptr
|
|
cmpl _young_start, %eax
|
|
jb L100
|
|
ret
|
|
L100: movl $8, %eax
|
|
jmp L105
|
|
|
|
.align 4
|
|
_caml_alloc2:
|
|
movl _young_ptr, %eax
|
|
subl $12, %eax
|
|
movl %eax, _young_ptr
|
|
cmpl _young_start, %eax
|
|
jb L101
|
|
ret
|
|
L101: movl $12, %eax
|
|
jmp L105
|
|
|
|
.align 4
|
|
_caml_alloc3:
|
|
movl _young_ptr, %eax
|
|
subl $16, %eax
|
|
movl %eax, _young_ptr
|
|
cmpl _young_start, %eax
|
|
jb L102
|
|
ret
|
|
L102: movl $16, %eax
|
|
jmp L105
|
|
|
|
.align 4
|
|
_caml_alloc:
|
|
pushl %eax
|
|
movl _young_ptr, %eax
|
|
subl (%esp), %eax
|
|
movl %eax, _young_ptr
|
|
cmpl _young_start, %eax
|
|
jb L103
|
|
addl $4, %esp
|
|
ret
|
|
L103: popl %eax
|
|
jmp L105
|
|
|
|
_caml_call_gc:
|
|
# Recover desired size and adjust return address
|
|
popl %eax
|
|
addl $2, %eax
|
|
pushl %eax
|
|
movzwl -2(%eax), %eax
|
|
L105:
|
|
# Record lowest stack address and return address
|
|
popl _caml_last_return_address
|
|
movl %esp, _caml_bottom_of_stack
|
|
# Save all regs used by the code generator
|
|
movl %ebx, _gc_entry_regs + 4
|
|
movl %ecx, _gc_entry_regs + 8
|
|
movl %edx, _gc_entry_regs + 12
|
|
movl %esi, _gc_entry_regs + 16
|
|
movl %edi, _gc_entry_regs + 20
|
|
movl %ebp, _gc_entry_regs + 24
|
|
# Save desired size
|
|
pushl %eax
|
|
# Call the garbage collector
|
|
call _minor_collection
|
|
# Restore all regs used by the code generator
|
|
movl _gc_entry_regs + 4, %ebx
|
|
movl _gc_entry_regs + 8, %ecx
|
|
movl _gc_entry_regs + 12, %edx
|
|
movl _gc_entry_regs + 16, %esi
|
|
movl _gc_entry_regs + 20, %edi
|
|
movl _gc_entry_regs + 24, %ebp
|
|
# Decrement young_ptr by desired size
|
|
popl %eax
|
|
subl %eax, _young_ptr
|
|
# Reload result of allocation in %eax
|
|
movl _young_ptr, %eax
|
|
# Return to caller
|
|
pushl _caml_last_return_address
|
|
ret
|
|
|
|
# Call a C function from Caml
|
|
|
|
.globl _caml_c_call
|
|
|
|
.align 4
|
|
_caml_c_call:
|
|
# Record lowest stack address and return address
|
|
movl (%esp), %edx
|
|
movl %edx, _caml_last_return_address
|
|
leal 4(%esp), %edx
|
|
movl %edx, _caml_bottom_of_stack
|
|
# Free the floating-point register stack
|
|
finit
|
|
# Call the function (address in %eax)
|
|
jmp *%eax
|
|
|
|
# Start the Caml program
|
|
|
|
.globl _caml_start_program
|
|
.align 4
|
|
_caml_start_program:
|
|
# Save callee-save registers
|
|
pushl %ebx
|
|
pushl %esi
|
|
pushl %edi
|
|
pushl %ebp
|
|
# Build an exception handler
|
|
pushl $L104
|
|
pushl $0
|
|
movl %esp, _caml_exception_pointer
|
|
# Record highest stack address
|
|
movl %esp, _caml_top_of_stack
|
|
# Go for it
|
|
call _caml_program
|
|
# Pop handler
|
|
addl $8, %esp
|
|
# Zero return code
|
|
xorl %eax, %eax
|
|
L104:
|
|
# Restore registers and return
|
|
popl %ebp
|
|
popl %edi
|
|
popl %esi
|
|
popl %ebx
|
|
ret
|
|
|
|
# Raise an exception from C
|
|
|
|
.globl _raise_caml_exception
|
|
.align 4
|
|
_raise_caml_exception:
|
|
movl 4(%esp), %eax
|
|
movl _caml_exception_pointer, %esp
|
|
popl _caml_exception_pointer
|
|
ret
|