Revision 134512c2fd71ff4df56a8fb781bd58ce373f7bad authored by Xavier Leroy on 15 March 1996, 16:01:15 UTC, committed by Xavier Leroy on 15 March 1996, 16:01:15 UTC
le stocke a la position du premier identificateur, et les clients vont
le chercher a la position du second.


git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@702 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
1 parent b9788cd
Raw File
i386.S
/***********************************************************************/
/*                                                                     */
/*                         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 */
/* Must be preprocessed by cpp */

/* Linux with ELF binaries does not prefix identifiers with _.
   Linux with a.out binaries, FreeBSD, and NextStep do. */

#ifdef SYS_linux_elf
#define G(x) x
#define FUNCTION_ALIGN 16
#else
#define G(x) _##x
#define FUNCTION_ALIGN 4
#endif

        .comm   G(young_limit), 4
        .comm   G(young_ptr), 4
        .comm   G(gc_entry_regs), 4 * 7
        .comm   G(caml_bottom_of_stack), 4
        .comm   G(caml_top_of_stack), 4
        .comm   G(caml_last_return_address), 4
        .comm   G(caml_exception_pointer), 4

/* Allocation */

        .text
        .globl  G(caml_alloc1)
        .globl  G(caml_alloc2)
        .globl  G(caml_alloc3)
        .globl  G(caml_alloc)
	.globl  G(caml_call_gc)

        .align  FUNCTION_ALIGN
G(caml_alloc1):
        movl    G(young_ptr), %eax
        subl    $8, %eax
        movl    %eax, G(young_ptr)
        cmpl    G(young_limit), %eax
        jb      L100
        ret
L100:   movl    $8, %eax
        jmp     L105

        .align  FUNCTION_ALIGN
G(caml_alloc2):
        movl    G(young_ptr), %eax
        subl    $12, %eax
        movl    %eax, G(young_ptr)
        cmpl    G(young_limit), %eax
        jb      L101
        ret
L101:   movl    $12, %eax
        jmp     L105

        .align  FUNCTION_ALIGN
G(caml_alloc3):
        movl    G(young_ptr), %eax
        subl    $16, %eax
        movl    %eax, G(young_ptr)
        cmpl    G(young_limit), %eax
        jb      L102
        ret
L102:   movl    $16, %eax
        jmp     L105

        .align  FUNCTION_ALIGN
G(caml_alloc):
        pushl   %eax
        movl    G(young_ptr), %eax
        subl    (%esp), %eax
        movl    %eax, G(young_ptr)
        cmpl    G(young_limit), %eax
        jb      L103
        addl    $4, %esp
        ret
L103:   popl    %eax
        jmp     L105

G(caml_call_gc):
    /* Adjust return address and recover desired size in %eax */
        popl    %eax
        addl    $2, %eax
        pushl   %eax
        movzwl  -2(%eax), %eax
L105:
    /* Record lowest stack address and return address */
        popl    G(caml_last_return_address)
        movl    %esp, G(caml_bottom_of_stack)
    /* Save all regs used by the code generator */
        movl    %ebx, G(gc_entry_regs) + 4
        movl    %ecx, G(gc_entry_regs) + 8
        movl    %edx, G(gc_entry_regs) + 12
        movl    %esi, G(gc_entry_regs) + 16
        movl    %edi, G(gc_entry_regs) + 20
        movl    %ebp, G(gc_entry_regs) + 24
    /* Save desired size */
        pushl   %eax
    /* Call the garbage collector */
        call    G(garbage_collection)
    /* Restore all regs used by the code generator */
        movl    G(gc_entry_regs) + 4, %ebx
        movl    G(gc_entry_regs) + 8, %ecx
        movl    G(gc_entry_regs) + 12, %edx
        movl    G(gc_entry_regs) + 16, %esi
        movl    G(gc_entry_regs) + 20, %edi
        movl    G(gc_entry_regs) + 24, %ebp
    /* Recover desired size */
        popl    %eax
    /* Decrement young_ptr by desired size */
        subl    %eax, G(young_ptr)
    /* Reload result of allocation in %eax */
        movl    G(young_ptr), %eax
    /* Return to caller */
        pushl   G(caml_last_return_address)
        ret

/* Call a C function from Caml */

        .globl  G(caml_c_call)

        .align  FUNCTION_ALIGN
G(caml_c_call):
    /* Record lowest stack address and return address */
    /* In parallel, free the floating point registers */
    /* (Pairing is expected on the Pentium.) */
        movl    (%esp), %edx
        ffree   %st(0)
        movl    %edx, G(caml_last_return_address)
        ffree   %st(1)
        leal    4(%esp), %edx
        ffree   %st(2)
        movl    %edx, G(caml_bottom_of_stack)
        ffree   %st(3)
    /* Call the function (address in %eax) */
        jmp     *%eax

/* Start the Caml program */

        .globl  G(caml_start_program)
        .align  FUNCTION_ALIGN
G(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, G(caml_exception_pointer)
    /* Record highest stack address */
        movl    %esp, G(caml_top_of_stack)
    /* Go for it */
        call    G(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  G(raise_caml_exception)
        .align  FUNCTION_ALIGN
G(raise_caml_exception):
        movl    4(%esp), %eax
        movl    G(caml_exception_pointer), %esp
        popl    G(caml_exception_pointer)
        ret

/* Callback from C to Caml */

        .globl  G(callback)
        .align  FUNCTION_ALIGN
G(callback):
    /* Save callee-save registers */
        pushl   %ebx
        pushl   %esi
        pushl   %edi
        pushl   %ebp
    /* Initial loading of arguments */
        movl    20(%esp), %ebx   /* closure */
        movl    24(%esp), %eax   /* argument */
        movl    0(%ebx), %esi    /* code pointer */
L106:
    /* Build a callback link */
        pushl   G(caml_last_return_address)
        pushl   G(caml_bottom_of_stack)
    /* Build an exception handler */
        pushl   $L108
        pushl   G(caml_exception_pointer)
        movl    %esp, G(caml_exception_pointer)
    /* Call the Caml code */
        call    *%esi
L107:
    /* Pop the exception handler */
        popl    G(caml_exception_pointer)
        popl    %esi    /* dummy register */
    /* Pop the callback link, restoring the global variables
       used by caml_c_call */
        popl    G(caml_bottom_of_stack)
        popl    G(caml_last_return_address)
    /* Restore callee-save registers.
       In parallel, free the floating-point registers
       that may have been used by Caml. */
        popl    %ebp
        ffree   %st(0)
        popl    %edi
        ffree   %st(1)
        popl    %esi
        ffree   %st(2)
        popl    %ebx
        ffree   %st(3)
    /* Return to caller. */
        ret
L108:
    /* Exception handler*/
    /* Pop the callback link, restoring the global variables
       used by caml_c_call */
        popl    G(caml_bottom_of_stack)
        popl    G(caml_last_return_address)
    /* Re-raise the exception through mlraise,
       so that local C roots are cleaned up correctly. */
        pushl   %eax            /* exn bucket is the argument */
        call    G(mlraise)      /* never returns */

        .globl  G(callback2)
        .align  FUNCTION_ALIGN
G(callback2):
    /* Save callee-save registers */
        pushl   %ebx
        pushl   %esi
        pushl   %edi
        pushl   %ebp
    /* Initial loading of arguments */
        movl    20(%esp), %ecx   /* closure */
        movl    24(%esp), %eax   /* first argument */
        movl    28(%esp), %ebx   /* second argument */
        movl    $ G(caml_apply2), %esi   /* code pointer */
        jmp     L106

        .globl  G(callback3)
        .align  FUNCTION_ALIGN
G(callback3):
    /* Save callee-save registers */
        pushl   %ebx
        pushl   %esi
        pushl   %edi
        pushl   %ebp
    /* Initial loading of arguments */
        movl    20(%esp), %edx   /* closure */
        movl    24(%esp), %eax   /* first argument */
        movl    28(%esp), %ebx   /* second argument */
        movl    32(%esp), %ecx   /* third argument */
        movl    $ G(caml_apply3), %esi   /* code pointer */
        jmp     L106

        .data
        .globl  G(system_frametable)
G(system_frametable):
        .long   1               /* one descriptor */
        .long   L107            /* return address into callback */
        .word   -1              /* negative frame size => use callback link */
        .word   0               /* no roots here */
back to top