diff options
Diffstat (limited to 'asmrun/i386.asm')
-rw-r--r-- | asmrun/i386.asm | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/asmrun/i386.asm b/asmrun/i386.asm new file mode 100644 index 000000000..d69c7f78b --- /dev/null +++ b/asmrun/i386.asm @@ -0,0 +1,179 @@ +# 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_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 _caml_call_gc + + .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 _caml_call_gc + + .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 _caml_call_gc + + .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 + +_caml_call_gc: + # 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 + # Pass the desired size as first argument + pushl %eax + # Call the garbage collector + call _garbage_collection + add $4, %esp + # 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 + # Reload result of allocation in %eax + movl _young_ptr, %eax + # Return to caller + pushl _caml_last_return_address + ret + +# Modification + + .globl _caml_modify + .globl _caml_fast_modify + + .align 4 +_caml_modify: + testb $4, -3(%eax) + jz _caml_fast_modify + ret + +_caml_fast_modify: + # Store address of object in remembered set + pushl %eax + movl _remembered_ptr, %eax + popl (%eax) + addl $4, %eax + movl %eax, _remembered_ptr + cmpl _remembered_end, %eax + ja _caml_modify_realloc + ret + +_caml_modify_realloc: + # Reallocate the remembered set while preserving all regs + pushl %ecx + pushl %edx + # (%eax dead, %ebx, %esi, %edi, %ebp preserved by C) + call _realloc_remembered + popl %edx + popl %ecx + ret + +# Call a C function from Caml + + .globl _caml_c_call + + .align 4 +_caml_c_call: + # Record lowest stack address and return address + popl _caml_last_return_address + movl %esp, _caml_bottom_of_stack + # Call the function (address in %eax) + call *%eax + # Return to caller + movl _caml_last_return_address, %edx # %edx dead here + jmp *%edx + +# 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 $0 + pushl $L104 + movl %esp, _caml_exception_pointer + # 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 %edx + popl _caml_exception_pointer + jmp *%edx |