* Removed all Id tags.
[cacao.git] / src / vm / jit / i386 / asmpart.S
index 706b2a6c03236c8221a15dfa27e9c4a2da9fe25c..179fbd038c0022f442e095b5d74c6d12cdd2aa02 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-            Christian Thalinger
-
-   Changes: Joseph Wenninger
-            Edwin Steiner
-
-   $Id: asmpart.S 5256 2006-08-21 15:25:59Z twisti $
-
 */
 
 
@@ -42,7 +31,6 @@
 
 #include "vm/jit/i386/arch.h"
 #include "vm/jit/i386/md-abi.h"
-#include "vm/jit/i386/offsets.h"
 
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/methodheader.h"
@@ -61,6 +49,7 @@
        .globl asm_vm_call_method_float
        .globl asm_vm_call_method_double
        .globl asm_vm_call_method_exception_handler
+       .globl asm_vm_call_method_end
 
        .globl asm_call_jit_compiler
        .globl asm_handle_nat_exception
 
        .globl asm_patcher_wrapper
 
+#if defined(ENABLE_REPLACEMENT)
        .globl asm_replacement_out
        .globl asm_replacement_in
+#endif
 
        .globl asm_builtin_f2i
        .globl asm_builtin_f2l
        .globl asm_builtin_d2i
        .globl asm_builtin_d2l
 
-       .globl asm_criticalsections
-       .globl asm_getclassvalues_atomic
+       .globl asm_compare_and_swap
+       .globl asm_memory_barrier
 
        .globl asm_get_cycle_count
 
@@ -155,65 +146,36 @@ asm_vm_call_method_double:
        mov     s1,1*4(sp)
        mov     s2,2*4(sp)
 
-       mov     4*4(bp),itmp1               /* pointer to arg block (4(push)+4(return)+4+4)*/
-       mov     3*4(bp),itmp2               /* arg count            (4(push)+4(return)+4 */
-
-       mov     sp,s1                       /* save the stackpointer              */
+       mov     sp,s1                       /* save stack pointer                 */
 
-       test    itmp2,itmp2                 /* maybe we have no args              */
-       jle     L_asm_vm_call_method_copy_done
+       mov     3*4(bp),t0                  /* address of data structure          */
+       mov     4*4(bp),itmp1               /* number of stack arguments          */
 
-       mov     itmp2,itmp3                 /* calculate stack size               */
-       mov     itmp1,%edi                  /* save pointer to arg block          */
+       cmp     $0,itmp1
+       je      L_asm_vm_call_method_stack_copy_done
 
-calljava_calcstacksize:
-       mov     offvmargtype(itmp1),t0
-       test    $1,t0                       /* two word type?                     */
-       jz      calljava_onewordtype
-
-       sub     $4,sp                       /* add 1 slot to stackframe size      */
-
-calljava_onewordtype:
-       sub     $4,sp                       /* add 1 slot to stackframe size      */
-       sub     $1,itmp3
-       test    itmp3,itmp3                 /* any args left?                     */
-       jz      calljava_setstack
-
-       add     $sizevmarg,itmp1            /* goto next argument block           */
-       jmp     calljava_calcstacksize
-               
-calljava_setstack:                             
-       mov     %edi,itmp1                  /* restore pointer to arg block       */
-       and     $0xfffffff0,sp              /* align stack to 16-byte             */
-       mov     sp,itmp3                    /* initialize pointer for copying     */
+       mov     itmp1,itmp2
+       add     $1,itmp2                    /* keep stack 16-byte aligned         */
+       and     $0xfffffffe,itmp2
+       shl     $3,itmp2                    /* calculate stack size               */
+       sub     itmp2,sp                    /* create stack frame                 */
+       mov     sp,itmp2                    /* temporary stack pointer            */
 
-calljava_copyloop:
-       mov     offvmargdata(itmp1),t0      /* get 4-bytes of argument            */
-       mov     t0,(itmp3)                  /* and store them on the stack        */
-       add     $4,itmp3                    /* increase sp to next argument       */
+L_asm_vm_call_method_stack_copy_loop:
+       mov     0(t0),itmp3                 /* load argument                      */
+       mov     itmp3,0(itmp2)              /* store argument on stack            */
+       mov     4(t0),itmp3
+       mov     itmp3,4(itmp2)
 
-       mov     offvmargtype(itmp1),t0      /* get the argument type              */
-       test    $1,t0                       /* two word type?                     */
-       jz      calljava_copynext
+       sub     $1,itmp1                    /* subtract 1 argument                */
+       add     $8,t0                       /* set address of next argument       */
+       add     $8,itmp2                    /* increase SP                        */
 
-       mov     offvmargdata+4(itmp1),t0    /* get upper 4-bytes of 2 word type   */
-       mov     t0,(itmp3)                      
-       add     $4,itmp3                    /* increase sp to next argument       */
+       cmp     $0,itmp1
+       jg      L_asm_vm_call_method_stack_copy_loop
 
-calljava_copynext:             
-       sub     $1,itmp2                    /* are there any args left?           */
-       test    itmp2,itmp2
-       jle     L_asm_vm_call_method_copy_done
-
-       add     $sizevmarg,itmp1            /* goto next argument block           */
-       jmp     calljava_copyloop
-
-L_asm_vm_call_method_copy_done:
-       mov     2*4(bp),itmp1               /* move function pointer to itmp1     */
-
-       lea     L_asm_call_jit_compiler,mptr
-       mov     mptr,3*4(s1)
-       lea     (3*4-256)(s1),mptr          /* We subtract 256 to force the next  */
+L_asm_vm_call_method_stack_copy_done:
+       lea     (2*4-256)(bp),mptr          /* We subtract 256 to force the next  */
                                            /* move instruction to have a 32-bit  */
                                            /* offset.                            */
 
@@ -234,6 +196,7 @@ asm_vm_call_method_exception_handler:
        push    xptr                        /* pass exception pointer             */
        call    builtin_throw_exception
        add     $4,sp
+asm_vm_call_method_end:
        jmp     L_asm_vm_call_method_return
 
 
@@ -383,11 +346,11 @@ L_asm_handle_exception_no_leaf_stack:
        cmp     $2,itmp1
        je      int2
 
-       mov     -3*4(itmp2),s0
+       mov     -3*8(itmp2),s0
 int2:  
-       mov     -2*4(itmp2),s1
+       mov     -2*8(itmp2),s1
 int1:  
-       mov     -1*4(itmp2),s2
+       mov     -1*8(itmp2),s2
 
        shl     $2,itmp1                    /* multiply by 4 bytes                */
        sub     itmp1,itmp2
@@ -500,6 +463,7 @@ L_asm_patcher_wrapper_exception:
        pop     xpc                         /* get and remove return address      */
        jmp     L_asm_handle_exception
 
+#if defined(ENABLE_REPLACEMENT)
 
 /* asm_replacement_out *********************************************************
 
@@ -525,26 +489,14 @@ asm_replacement_out:
        sub     $(sizeexecutionstate + REPLACEMENT_ROOM),sp
 
        /* save registers in execution state */
-       mov     %eax,(EAX*8+offes_intregs)(sp)
-       mov     %ebx,(EBX*8+offes_intregs)(sp)
-       mov     %ecx,(ECX*8+offes_intregs)(sp)
-       mov     %edx,(EDX*8+offes_intregs)(sp)
-       mov     %esi,(ESI*8+offes_intregs)(sp)
-       mov     %edi,(EDI*8+offes_intregs)(sp)
-       mov     %ebp,(EBP*8+offes_intregs)(sp)
-       movl    $0  ,(ESP*8+offes_intregs)(sp) /* not used */
-
-#ifndef NDEBUG
-       /* clear high 32bit */
-       movl    $0,(4+0*8+offes_intregs)(sp)
-       movl    $0,(4+1*8+offes_intregs)(sp)
-       movl    $0,(4+2*8+offes_intregs)(sp)
-       movl    $0,(4+3*8+offes_intregs)(sp)
-       movl    $0,(4+4*8+offes_intregs)(sp)
-       movl    $0,(4+5*8+offes_intregs)(sp)
-       movl    $0,(4+6*8+offes_intregs)(sp)
-       movl    $0,(4+7*8+offes_intregs)(sp)
-#endif
+       mov     %eax,(EAX*4+offes_intregs)(sp)
+       mov     %ebx,(EBX*4+offes_intregs)(sp)
+       mov     %ecx,(ECX*4+offes_intregs)(sp)
+       mov     %edx,(EDX*4+offes_intregs)(sp)
+       mov     %esi,(ESI*4+offes_intregs)(sp)
+       mov     %edi,(EDI*4+offes_intregs)(sp)
+       mov     %ebp,(EBP*4+offes_intregs)(sp)
+       movl    $0  ,(ESP*4+offes_intregs)(sp) /* not used */
 
        /* calculate sp of method */
        mov     sp,itmp1
@@ -569,32 +521,55 @@ asm_replacement_out:
    This function never returns!
 
    C prototype:
-      void asm_replacement_in(executionstate *es);
+      void asm_replacement_in(executionstate *es, replace_safestack_t *st);
 
 *******************************************************************************/
 
 asm_replacement_in:
-       mov     4(sp),%ebp                  /* executionstate *es                 */
+       /* get arguments */
+       mov     8(sp),%esi                  /* replace_safestack_t *st            */
+       mov     4(sp),%ebp                  /* executionstate *es == safe stack   */
+
+       /* switch to the safe stack and build a stack frame */
+       mov     %ebp,sp
+       sub             $(1*4),sp
+
+       /* call replace_build_execution_state(st) */
+       mov             %esi,(0*4)(sp)
+       call    replace_build_execution_state
 
        /* set new sp */
-       mov     (offes_sp)(%ebp),%esp
-       
-       /* store address of new code */
+       mov     (offes_sp)(%ebp),sp
+
+       /* push address of new code */
        push    (offes_pc)(%ebp)
-       
-       /* copy registers from execution state */
-       mov     (EAX*8+offes_intregs)(%ebp),%eax
-       mov     (EBX*8+offes_intregs)(%ebp),%ebx
-       mov     (ECX*8+offes_intregs)(%ebp),%ecx
-       mov     (EDX*8+offes_intregs)(%ebp),%edx
-       mov     (ESI*8+offes_intregs)(%ebp),%esi
-       mov     (EDI*8+offes_intregs)(%ebp),%edi
 
-       mov     (EBP*8+offes_intregs)(%ebp),%ebp
+       /* allocate an executionstate_t on the stack */
+       sub             $(sizeexecutionstate),sp
 
-       /* jump to new code */
+       /* call replace_free_safestack(st,& of allocated executionstate_t) */
+       push    sp   /* tmpes */
+       push    %esi /* st    */
+       call    replace_free_safestack
+       add     $(2*4),sp
+
+       /* copy registers from execution state */
+       mov     (EAX*4+offes_intregs)(sp),%eax
+       mov     (EBX*4+offes_intregs)(sp),%ebx
+       mov     (ECX*4+offes_intregs)(sp),%ecx
+       mov     (EDX*4+offes_intregs)(sp),%edx
+       mov     (ESI*4+offes_intregs)(sp),%esi
+       mov     (EDI*4+offes_intregs)(sp),%edi
+       mov     (EBP*4+offes_intregs)(sp),%ebp
+
+       /* pop the execution state off the stack */
+       add             $(sizeexecutionstate),sp
+
+       /* jump to new code, hold your thumbs! ;) */
        ret
 
+#endif /* defined(ENABLE_REPLACEMENT) */
+
 
 /************************ function asm_builtin_x2x *****************************
 *                                                                              *
@@ -631,46 +606,40 @@ asm_builtin_d2l:
        ret
 
 
-asm_getclassvalues_atomic:
-_crit_restart2:
-       mov     4(%esp),%ecx        /* super */
-       mov     8(%esp),%edx        /* sub */
-_crit_begin2:
-       mov     offbaseval(%ecx),%eax
-       mov     offdiffval(%ecx),%ecx
-       mov     offbaseval(%edx),%edx
-_crit_end2:
-       push    %ebx
-       mov     16(%esp),%ebx      /* out */
-       mov     %eax,offcast_super_baseval(%ebx)
-       mov     %ecx,offcast_super_diffval(%ebx)
-       mov     %edx,offcast_sub_baseval(%ebx)
-       pop     %ebx
-       ret
+/* asm_compare_and_swap ********************************************************
 
-       .data
+   Does an atomic compare and swap.  Required for the lock
+   implementation.
 
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
-#if 0
-       .long   _crit_begin1
-       .long   _crit_end1
-       .long   _crit_restart1
-#endif
-       .long   _crit_begin2
-       .long   _crit_end2
-       .long   _crit_restart2
-#endif
-       .long 0
+   Atomically do the following: Check if the location still contains
+   `oldval`. If so, replace it by `newval` and return `oldval`.
 
+   RETURN VALUE:
+       the old value at *p
 
-/* Disable exec-stacks, required for Gentoo ***********************************/
+   long compare_and_swap(volatile long *p, long oldval, long newval);
+
+*******************************************************************************/
+
+asm_compare_and_swap:
+       mov     1*4(sp),%ecx            /* load p into a register                 */
+       mov     2*4(sp),%eax            /* load oldval into return register       */
+       mov     3*4(sp),%edx            /* load newval into a register            */
+       lock; cmpxchgl %edx,0(%ecx)
+       ret
 
-#if defined(__GCC__) && defined(__ELF__)
-       .section .note.GNU-stack,"",@progbits
-#endif
 
+/* asm_memory_barrier **********************************************************
 
+   A memory barrier for the Java Memory Model.
+
+*******************************************************************************/
+
+asm_memory_barrier:
+       lock; add $0,0(sp)
+       ret
+
+               
 /* asm_get_cycle_count *********************************************************
 
    Get the current time-stamp counter from the CPU.
@@ -682,6 +651,13 @@ asm_get_cycle_count:
        ret
 
 
+/* disable exec-stacks ********************************************************/
+
+#if defined(__linux__) && defined(__ELF__)
+       .section .note.GNU-stack,"",%progbits
+#endif
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where