* src/vm/jit/i386/asmpart.S: Made position independent.
[cacao.git] / src / vm / jit / i386 / asmpart.S
index 297a98cda320df472e71e9e62ebd3ce9c5fe5820..e182ddeeccf9d2e3490309361508a0e57e534c0b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
 
-   Copyright (C) 1996-2005 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
-
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-            Christian Thalinger
-
-   Changes: Joseph Wenninger
-
-   $Id: asmpart.S 3894 2005-12-06 22:30:30Z twisti $
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
 */
 
 
 #include "config.h"
-#include "vm/jit/i386/offsets.h"
-
-#include "vm/jit/methodheader.h"
-
-
-/* define it like the risc way */
-
-#define v0       %eax
-
-#define sp       %esp
-#define bp       %ebp
 
-#define itmp1    %eax
-#define itmp2    %ecx
-#define itmp3    %edx
+#include "md-asm.h"
 
-#define itmp1b   %al
-#define itmp2b   %cl
-#define itmp3b   %dl
+#include "vm/jit/i386/arch.h"
+#include "vm/jit/i386/md-abi.h"
 
-#define xptr     itmp1
-#define xpc      itmp2
+#include "vm/jit/abi-asm.h"
+#include "vm/jit/methodheader.h"
 
 
        .text
 
 
-/********************* exported functions and variables ***********************/
+/* export functions ***********************************************************/
 
-       .globl asm_calljavafunction
-       .globl asm_calljavafunction_int
+       .globl asm_md_init
 
-       .globl asm_calljavafunction2
-       .globl asm_calljavafunction2int
-       .globl asm_calljavafunction2long
-       .globl asm_calljavafunction2float
-       .globl asm_calljavafunction2double
+       .globl asm_vm_call_method
+       .globl asm_vm_call_method_int
+       .globl asm_vm_call_method_long
+       .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_handle_exception
 
-       .globl asm_wrapper_patcher
+       .globl asm_abstractmethoderror
 
        .globl asm_builtin_f2i
        .globl asm_builtin_f2l
        .globl asm_builtin_d2i
        .globl asm_builtin_d2l
 
-       .globl asm_perform_threadswitch
-       .globl asm_initialize_thread_stack
-       .globl asm_switchstackandcall
-       .globl asm_criticalsections
-       .globl asm_getclassvalues_atomic
-
+       .globl asm_compare_and_swap
+       .globl asm_memory_barrier
 
-/********************* function asm_calljavafunction ***************************
-*                                                                              *
-*   This function calls a Java-method (which possibly needs compilation)       *
-*   with up to 4 address parameters.                                           *
-*                                                                              *
-*   This functions calls the JIT-compiler which eventually translates the      *
-*   method into machine code.                                                  *
-*                                                                              *
-*   C-prototype:                                                               *
-*    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
-*         void *arg1, void *arg2, void *arg3, void *arg4);                     *
-*                                                                              *
-*******************************************************************************/
+#if defined(ENABLE_ESCAPE_CHECK)
+       .globl asm_escape_check
+#endif
 
-call_name:
-       .align  8
 
-       .long   0                         /* catch type all                       */
-       .long   calljava_xhandler         /* handler pc                           */
-       .long   calljava_xhandler         /* end pc                               */
-       .long   asm_calljavafunction      /* start pc                             */
-       .long   1                         /* extable size                         */
-       .long   0                         /* line number table start              */
-       .long   0                         /* line number table size               */
-       .long   0                         /* fltsave                              */
-       .long   0                         /* intsave                              */
-       .long   0                         /* isleaf                               */
-       .long   0                         /* IsSync                               */
-       .long   32                        /* frame size                           */
-       .long   0                         /* method pointer (pointer to name)     */
-
-asm_calljavafunction:
-asm_calljavafunction_int:
-       push    %ebp                      /* allocate stack space                 */
-       mov     %esp, %ebp
-
-       push    %ebx                      /* save registers                       */
-       push    %esi
-       push    %edi
-
-
-       sub             $16,%esp                    /* 4 adress parameters * 4 Bytes      */
-       mov     24(%ebp),%eax               /* copy adress parameters to new block*/
-       mov     %eax,12(%esp)
-               
-       mov     20(%ebp),%eax
-       mov     %eax,8(%esp)
+/* asm_md_init *****************************************************************
 
-       mov     16(%ebp),%eax
-       mov     %eax,4(%esp)
+   Initialize machine dependent stuff.
 
-       mov     12(%ebp),%eax
-       mov     %eax,(%esp)
-               
-       mov     8(%ebp),%eax                /* move function pointer to %eax      */
+   See: http://www.srware.com/linux_numerics.txt
 
-       lea     asm_call_jit_compiler,%edx 
-       call    *%edx                       /* call JIT compiler                  */
+   This puts the X86 FPU in 64-bit precision mode.  The default under
+   Linux is to use 80-bit mode, which produces subtle differences from
+   FreeBSD and other systems, eg, (int)(1000*atof("0.3")) is 300 in
+   64-bit mode, 299 in 80-bit mode.
 
-       add     $16,%esp
-       pop     %edi                        /* restore registers                  */
-       pop     %esi
-       pop     %ebx
-       leave
-       ret
+   Fixes: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350729
 
-calljava_xhandler:
-       push    %eax                        /* pass exception pointer             */
-       call    builtin_throw_exception
-       add     $4,%esp
+*******************************************************************************/
 
-       add     $16,%esp
-       pop     %edi                        /* restore registers                  */
-       pop     %esi
-       pop     %ebx
-       leave
-       xor     v0,v0                       /* return NULL                        */
+asm_md_init:
+       sub     $4,sp                       /* allocate space for the FPU state   */
+       fnstcw  (sp)                        /* get the FPU state                  */
+       mov     (sp),%eax
+       and     $0xfcff,%ax                 /* remove the extended mode flag      */
+       or      $0x0200,%ax                 /* put the double mode flag           */
+       mov     %eax,(sp)                   /* store new FPU state                */
+       fldcw   (sp)                        /* setup new FPU state                */
+       add     $4,sp
        ret
 
 
@@ -181,221 +103,97 @@ calljava_xhandler:
 *   method into machine code.                                                  *
 *                                                                              *
 *   C-prototype:                                                               *
-*    javaobject_header *asm_calljavafunction2(methodinfo *m,                   *
+*    javaobject_header *asm_vm_call_method(methodinfo *m,                      *
 *         u4 count, u4 size, void *callblock);                                 *
 *                                                                              *
 *******************************************************************************/
 
-call_name2:
        .align  8
 
-       .long   0                         /* catch type all                       */
-       .long   calljava_xhandler2        /* handler pc                           */
-       .long   calljava_xhandler2        /* end pc                               */
-       .long   asm_calljavafunction2     /* start pc                             */
-       .long   1                         /* extable size                         */
-       .long   0                         /* line number table start              */
-       .long   0                         /* line number table size               */
-       .long   0                         /* fltsave                              */
-       .long   0                         /* intsave                              */
-       .long   0                         /* isleaf                               */
-       .long   0                         /* IsSync                               */
-       .long   32                        /* frame size                           */
-       .long   0                         /* method pointer (pointer to name)     */
-
-asm_calljavafunction2:
-asm_calljavafunction2int:
-asm_calljavafunction2long:
-asm_calljavafunction2float:
-asm_calljavafunction2double:
-       push    %ebp
-       mov     %esp,%ebp                 /* save stackptr                        */
-
-       push    %ebx                      /* save registers                       */
-       push    %esi
-       push    %edi
-
-       mov     20(%ebp),%eax             /* pointer to arg block (4(push)+4(return)+4+4+4)*/
-       mov     12(%ebp),%ecx             /* arg count            (4(push)+4(return)+4     */
-
-       xor     %esi,%esi                 /* clear stackframe size (MUST be       */
-                                         /* before args check, may be zero!!!)   */
-       test    %ecx,%ecx                 /* maybe we have no args                */
-       jle     calljava_copydone
-
-       mov     %ecx,%edx                 /* calculate stack size                 */
-       mov     %eax,%edi                 /* save pointer to arg block            */
-
-calljava_calcstacksize:
-       mov     offjniitemtype(%eax),%ebx
-       test    $1,%ebx                   /* two word type?                       */
-       jz      calljava_onewordtype
-       add     $4,%esi                   /* add 1 slot to stackframe size        */
-
-calljava_onewordtype:
-       add     $4,%esi                   /* add 1 slot to stackframe size        */
-       sub     $1,%edx
-       test    %edx,%edx                 /* any args left?                       */
-       jz      calljava_setstack
-       add     $sizejniblock,%eax        /* goto next argument block             */
-       jmp     calljava_calcstacksize
-               
-calljava_setstack:                             
-       mov     %edi,%eax                 /* restore pointer to arg block         */
-       sub     %esi,%esp                 /* create stackframe for arguments      */
-       mov     %esp,%edi                 /* move stackpointer into temp variable */
-
-calljava_copyloop:
-       mov     offjniitem(%eax),%edx     /* copy 4 Byte of Argument              */
-       mov     %edx,(%edi)
-       add     $4,%edi                   /* increase sp to next argument         */
-       mov     offjniitemtype(%eax),%ebx /* type -> ebx                          */
-       test    $1,%ebx                   /* Two Word Type?                       */
-       jz      calljava_copynext
-
-       mov     offjniitem+4(%eax),%edx   /* copy upper 4 Byte of 2 Word Type     */
-       mov     %edx,(%edi)                     
-       add     $4,%edi                   /* increase sp to next argument         */
-
-calljava_copynext:             
-       sub     $1,%ecx                   /* are there any args left?             */
-       test    %ecx,%ecx
-       jle     calljava_copydone
-
-       add     $sizejniblock,%eax        /* goto next argument block             */
-       jmp     calljava_copyloop
-
-calljava_copydone:
-       mov     8(%ebp),%eax              /* move function pointer to %eax        */
-
-       lea     asm_call_jit_compiler,%edx 
-       call    *%edx                     /* call JIT compiler                    */
-       
-       add     %esi,%esp                 /* remove arg stack frame               */
-       pop     %edi                      /* restore registers                    */
-       pop     %esi
-       pop     %ebx
-       leave
-       ret
+       .long   0                           /* fltsave                            */
+       .long   0                           /* intsave                            */
+       .long   0                           /* isleaf                             */
+       .long   0                           /* frame size                         */
+       .long   0                           /* codeinfo pointer                   */
+
+asm_vm_call_method:
+asm_vm_call_method_int:
+asm_vm_call_method_long:
+asm_vm_call_method_float:
+asm_vm_call_method_double:
+       push    bp
+       mov     sp,bp                       /* save stack pointer                 */
+       sub     $(4*4),sp                   /* create stackframe                  */
+       and     $0xfffffff0,sp              /* align stack to 16-byte             */
+
+       mov     t0,0*4(sp)                  /* save registers                     */
+       mov     s1,1*4(sp)
+       mov     s2,2*4(sp)
+
+       mov     sp,s1                       /* save stack pointer                 */
+
+       mov     3*4(bp),t0                  /* address of data structure          */
+       mov     4*4(bp),itmp1               /* number of stack arguments          */
+
+       cmp     $0,itmp1
+       je      L_asm_vm_call_method_stack_copy_done
+
+       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            */
+
+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)
+
+       sub     $1,itmp1                    /* subtract 1 argument                */
+       add     $8,t0                       /* set address of next argument       */
+       add     $8,itmp2                    /* increase SP                        */
+
+       cmp     $0,itmp1
+       jg      L_asm_vm_call_method_stack_copy_loop
+
+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.                            */
+
+       mov     (0*4+256)(mptr),itmp3       /* method call as in Java             */
+       call    *itmp3                      /* call JIT compiler                  */
+
+L_asm_vm_call_method_return:
+       mov     s1,sp                       /* restore stackpointer               */
+
+       mov     0*4(sp),t0                  /* restore registers                  */
+       mov     1*4(sp),s1
+       mov     2*4(sp),s2
 
-calljava_xhandler2:
-       push    xptr                      /* pass exception pointer               */
-       call    builtin_throw_exception
-       add     $4,%esp
-    
-       add     %esi,%esp                 /* remove arg stack frame               */
-       pop     %edi                      /* restore registers                    */
-       pop     %esi
-       pop     %ebx
        leave
-       xor     v0,v0                     /* return NULL                          */
        ret
 
-
-/****************** function asm_call_jit_compiler *****************************
-*                                                                              *
-*   invokes the compiler for untranslated JavaVM methods.                      *
-*                                                                              *
-*   Register R0 contains a pointer to the method info structure (prepared      *
-*   by createcompilerstub). Using the return address in R26 and the            *
-*   offset in the LDA instruction or using the value in methodptr R28 the      *
-*   patching address for storing the method address can be computed:           *
-*                                                                              *
-*   method address was either loaded using                                     *
-*                                                                              *
-*   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
-*   i386_call_reg(REG_ITMP2)                                                   *
-*                                                                              *
-*   or                                                                         *
-*                                                                              *
-*   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface    *
-*   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)                *
-*   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \                *
-*       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
-*   i386_call_reg(REG_ITMP1)                                                   *
-*                                                                              *
-*   in the static case the method pointer can be computed using the            *
-*   return address and the lda function following the jmp instruction          *
-*                                                                              *
-*******************************************************************************/
-
-asm_call_jit_compiler:
-       sub     $((4+2)*4+sizestackframeinfo),sp /* create stack frame            */
-       mov     itmp1,(4+0)*4(sp)           /* save method pointer                */
-                       
-       mov     (4+2)*4+sizestackframeinfo(sp),itmp3 /* get return address        */
-       mov     -1(itmp3),itmp1b            /* get function code                  */
-       cmp     $0xd1,itmp1b                /* called with `call *REG_ITMP2'?     */
-       jne             L_not_static_special
-
-       sub     $6,itmp3                    /* calculate address of immediate     */
-       jmp             L_call_jit_compile
-               
-L_not_static_special:
-       cmp     $0xd0,itmp1b                /* called with `call *REG_ITMP1'      */
-       jne             L_not_virtual_interface
-       
-       sub     $6,itmp3                    /* calculate address of offset        */
-       mov     (itmp3),itmp3               /* get offset                         */
-       add     itmp2,itmp3                 /* add base address to get method adr */
-       jmp             L_call_jit_compile
-
-L_not_virtual_interface:
-       xor     itmp3,itmp3                 /* a call from asm_calljavafunction   */
-               
-L_call_jit_compile:
-       mov     itmp3,(4+1)*4(sp)           /* save address for method pointer    */
-
-       mov     sp,itmp1                    /* create stackframe info             */
-       add     $((4+2)*4),itmp1
-       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
-       movl    $0,1*4(sp)                  /* if pv is NULL, use findmethod      */
-       mov     sp,itmp2
-       add     $((1+4+2)*4+sizestackframeinfo),itmp2 /* pass java sp             */
-       mov     itmp2,2*4(sp)
-       mov     ((0+4+2)*4+sizestackframeinfo)(sp),itmp3 /* pass java ra          */
-       mov     itmp3,3*4(sp)
-       call    stacktrace_create_inline_stackframeinfo
-
-       mov     (4+0)*4(sp),itmp1           /* pass method pointer                */
-       mov     itmp1,0*4(sp)
-       call    jit_compile
-       mov     v0,(4+0)*4(sp)              /* save return value                  */
-
-       mov     sp,itmp1                    /* remove stackframe info             */
-       add     $((4+2)*4),itmp1
-       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
-       call    stacktrace_remove_stackframeinfo
-
-       mov     (4+0)*4(sp),v0              /* restore return value               */
-       mov     (4+1)*4(sp),itmp3           /* restore address for method pointer */
-
-       add     $((4+2)*4+sizestackframeinfo),sp /* remove stack frame            */
-
-       test    v0,v0                       /* check for exception                */
-       je      L_asm_call_jit_compiler_exception
-
-       test    itmp3,itmp3                 /* was this a JIT call?               */
-       je              L_call_method
-       
-       mov     v0,(itmp3)                  /* save the new method pointer        */
-
-L_call_method:
-       jmp             *v0                         /* ...and now call the new method     */
-
-L_asm_call_jit_compiler_exception:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       call    builtin_asm_get_exceptionptrptr
-       mov     v0,itmp2                    /* v0 == itmp1                        */
+asm_vm_call_method_exception_handler:
+#if defined(ENABLE_PIC_ASM)
+       sub     $12, %esp
+       push    %ebx
+#endif
+       push    xptr                        /* pass exception pointer             */
+#if defined(ENABLE_PIC_ASM)
+       call    .GETPC
+       add     $_GLOBAL_OFFSET_TABLE_, %ebx
+       call    builtin_throw_exception@PLT
+       pop     %ebx
+       add     $12, %esp
 #else
-       lea     _exceptionptr,itmp2
+       call    builtin_throw_exception
 #endif
-       mov     (itmp2),xptr                /* get the exception pointer          */
-       movl    $0,(itmp2)                  /* clear the exception pointer        */
-
-       pop     xpc                         /* get return address                 */
-       sub     $2,xpc                      /* faulting address is ra - 2         */
-       jmp     asm_handle_exception
+       add     $4,sp
+asm_vm_call_method_end:
+       jmp     L_asm_vm_call_method_return
 
 
 /* asm_handle_exception ********************************************************
@@ -412,22 +210,32 @@ asm_handle_nat_exception:
        add     $4,sp                       /* clear return address of native stub*/
                
 asm_handle_exception:
-#if 0
-       xor     %edi,%edi                   /* clear indent flag (only first time)*/
-#endif
+L_asm_handle_exception:                 /* required for PIC code              */
+       sub     $((ARG_CNT+TMP_CNT+3)*4),sp /* keep stack 16-byte aligned         */
+
+       SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
+       SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
+
+       mov     $((ARG_CNT+TMP_CNT+3)*4),itmp3 /* prepare a3 for handle_exception */
+       mov     $1,t0                       /* set maybe-leaf flag                */
 
 L_asm_handle_exception_stack_loop:
-       sub     $(10*4),sp                   /* create stackframe                  */
+       sub     $(12*4),sp                  /* keep stack 16-byte aligned         */
        mov     xptr,4*4(sp)                /* save exception pointer             */
        mov     xpc,5*4(sp)                 /* save exception pc                  */
-
-#if 0
-       mov     %ebx,7*4(sp)                /* save registers (non-callee)        */
-       mov     %ebp,8*4(sp)
-#endif
+       add     sp,itmp3                    /* calculate Java sp into a3...       */
+       add     $(12*4),itmp3
+       mov     itmp3,7*4(sp)               /* ...and save it                     */
+       mov     t0,8*4(sp)                  /* save maybe-leaf flag               */
 
        mov     xpc,0*4(sp)                 /* pass exception pc                  */
-       call    codegen_findmethod
+#if defined(ENABLE_PIC_ASM)
+       call    .GETPC
+       add     $_GLOBAL_OFFSET_TABLE_, %ebx
+       call    methodtree_find@PLT
+#else
+       call    methodtree_find
+#endif
        mov     v0,6*4(sp)                  /* save data segment pointer          */
 
        mov     4*4(sp),itmp3               /* pass exception pointer             */
@@ -435,155 +243,136 @@ L_asm_handle_exception_stack_loop:
        mov     5*4(sp),itmp3               /* pass exception pc                  */
        mov     itmp3,1*4(sp)
        mov     v0,2*4(sp)                  /* pass data segment pointer          */
-       mov     sp,itmp3                    /* pass Java stack pointer            */
-       add     $(10*4),itmp3
+       mov     7*4(sp),itmp3               /* pass Java stack pointer            */
        mov     itmp3,3*4(sp)
+#if defined(ENABLE_PIC_ASM)
+       /* GOT still in %ebx */
+       call    exceptions_handle_exception@PLT
+#else
        call    exceptions_handle_exception
+#endif
 
        test    v0,v0
        jz      L_asm_handle_exception_not_catched
 
        mov     v0,xpc                      /* move handlerpc into xpc            */
        mov     4*4(sp),xptr                /* restore exception pointer          */
-#if 0
-       mov     7*4(sp),%ebx                /* restore registers (non-callee)     */
-       mov     8*4(sp),%ebp
-#endif
-       add     $(10*4),sp                   /* free stackframe                    */
+       mov     8*4(sp),t0                  /* get maybe-leaf flag                */
+       add     $(12*4),sp                  /* free stackframe                    */
 
+       test    t0,t0                       /* test for maybe-leaf flag           */
+       jz      L_asm_handle_exception_no_leaf
+
+       RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
+       RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
+
+       add     $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe       */
+
+L_asm_handle_exception_no_leaf:
        jmp     *xpc                        /* jump to exception handler          */
 
 L_asm_handle_exception_not_catched:
        mov     4*4(sp),xptr                /* restore exception pointer          */
        mov     6*4(sp),itmp3               /* restore data segment pointer       */
-#if 0
-       mov     7*4(sp),%ebx                /* restore registers (non-callee)     */
-       mov     8*4(sp),%ebp
-#endif
-       add     $(10*4),sp                   /* free stackframe                    */
+       mov     8*4(sp),t0                  /* get maybe-leaf flag                */
+       add     $(12*4),sp                  /* free stackframe                    */
 
+       test    t0,t0
+       jz      L_asm_handle_exception_no_leaf_stack
+
+       add     $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe       */
+       xor     t0,t0                       /* clear the maybe-leaf flag          */
+
+L_asm_handle_exception_no_leaf_stack:
        mov     FrameSize(itmp3),itmp2      /* get frame size                     */
-       add     itmp2,sp                    /* unwind stack                       */
-       mov     sp,itmp2                    /* pointer to save area               */
+       add     sp,itmp2                    /* pointer to save area               */
 
-       mov     IntSave(itmp3),%ebx         /* %ecx = saved int register count    */
-       test    %ebx,%ebx
+       push    xptr                        /* we are out of registers            */
+
+       mov     IntSave(itmp3),itmp1        /* itmp1 = saved int register count   */
+       test    itmp1,itmp1
        je      noint
 
-       cmp     $1,%ebx
+       cmp     $1,itmp1
        je      int1
-       cmp     $2,%ebx
+       cmp     $2,itmp1
        je      int2
 
-       mov     -12(itmp2),%ebp
+       mov     -4-3*8(itmp2),s0
 int2:  
-       mov     -8(itmp2),%esi
+       mov     -4-2*8(itmp2),s1
 int1:  
-       mov     -4(itmp2),%edi
+       mov     -4-1*8(itmp2),s2
 
-       shl     $2,%ebx                     /* multiply by 4 bytes                */
-       sub     %ebx,itmp2
+       shl     $2,itmp1                    /* multiply by 4 bytes                */
+       sub     itmp1,itmp2
                
 noint:
-       mov     FltSave(itmp3),%ebx         /* %ecx = saved flt register count    */
-       test    %ebx,%ebx
+#if 0
+       mov     FltSave(itmp3),itmp1        /* itmp1 = saved flt register count   */
+       test    itmp1,itmp1
        je      noflt
 
-       cmp     $1,%ebx
+       cmp     $1,itmp1
        je      flt1
-       cmp     $2,%ebx
+       cmp     $2,itmp1
        je      flt2
-       cmp     $3,%ebx
+       cmp     $3,itmp1
        je      flt3
                
-       fldl    -32(itmp2)
+       fldl    -4*8(itmp2)
        fstp    %st(1)
 flt3:
-       fldl    -24(itmp2)
+       fldl    -3*8(itmp2)
        fstp    %st(2)
 flt2:
-       fldl    -16(itmp2)
+       fldl    -2*8(itmp2)
        fstp    %st(3)
 flt1:
-       fldl    -8(itmp2)
+       fldl    -1*8(itmp2)
        fstp    %st(4)
                
 noflt:
-                                           /* exception pointer is still set     */
+#endif
+       pop     xptr                        /* restore exception pointer          */
+       mov     FrameSize(itmp3),itmp2      /* get frame size                     */
+       add     itmp2,sp                    /* unwind stack                       */
+
        pop     xpc                         /* the new xpc is return address      */
        sub     $2,xpc                      /* subtract 2-bytes for call          */
 
-#if 0
-       mov     $1,%edi                     /* set indent flag                    */
-#endif
+       xor     itmp3,itmp3                 /* prepare a3 for handle_exception    */
 
        jmp     L_asm_handle_exception_stack_loop
                
 
-/* asm_wrapper_patcher *********************************************************
-
-   XXX
+/* asm_abstractmethoderror *****************************************************
 
-   Stack layout:
-     20   return address
-     16   pointer to virtual java_objectheader
-     12   last byte of machine code (xmcode)
-      8   machine code (which is patched back later)
-      4   unresolved field reference
-      0   patcher function pointer to call
+   Creates and throws an AbstractMethodError.
 
 *******************************************************************************/
 
-asm_wrapper_patcher:
-       sub     $((2+4)*4+sizestackframeinfo),sp /* create stack frame            */
-
-       mov     itmp1,(0+4)*4(sp)           /* save itmp1 and itmp2               */
-       mov     itmp2,(1+4)*4(sp)           /* may be used by some instructions   */
-
-       mov     sp,itmp1                    /* create stackframe info             */
-       add     $((2+4)*4),itmp1
-       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
-       movl    $0,1*4(sp)                  /* if pv is NULL, use findmethod      */
-       mov     sp,itmp2
-       add     $((6+2+4)*4+sizestackframeinfo),itmp2
-       mov     itmp2,2*4(sp)
-       mov     ((5+2+4)*4+sizestackframeinfo)(sp),itmp3
-       mov     itmp3,3*4(sp)
-       call    stacktrace_create_inline_stackframeinfo
-
-       mov     sp,itmp1                    /* pass stack pointer                 */
-       add     $((1+2+4)*4+sizestackframeinfo),itmp1  /* skip function pointer   */
+asm_abstractmethoderror:
+       sub     $(3*4),sp                   /* keep stack 16-byte aligned         */
+       mov     sp,itmp1                    /* pass java sp                       */
+       add     $((1+3)*4),itmp1
        mov     itmp1,0*4(sp)
-       mov     (0+2+4)*4+sizestackframeinfo(sp),itmp1 /* get function pointer    */
-       call    *itmp1                      /* call the patcher function          */
-       mov     v0,1*4(sp)                  /* save return value                  */
-
-       mov     sp,itmp1                    /* remove stackframe info             */
-       add     $((2+4)*4),itmp1
-       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
-       call    stacktrace_remove_stackframeinfo
-
-       mov     (0+4)*4(sp),itmp1           /* restore itmp1 and itmp2            */
-       mov     (1+4)*4(sp),itmp2           /* may be used by some instructions   */
-       mov     1*4(sp),itmp3               /* restore return value               */
-
-       add     $((5+2+4)*4+sizestackframeinfo),sp /* remove stack frame, keep ra */
-       test    itmp3,itmp3                 /* exception thrown?                  */
-       jz      L_asm_wrapper_patcher_exception
-       ret                                 /* call new patched code              */
-
-L_asm_wrapper_patcher_exception:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       call    builtin_asm_get_exceptionptrptr
-       mov     v0,itmp2
+       mov     3*4(sp),itmp2               /* pass exception address             */
+       sub     $2,itmp2
+       mov     itmp2,1*4(sp)
+#if defined(ENABLE_PIC_ASM)
+       call    .GETPC
+       add     $_GLOBAL_OFFSET_TABLE_, %ebx
+       call    exceptions_asm_new_abstractmethoderror@PLT
 #else
-       lea     _exceptionptr,itmp2
+       call    exceptions_asm_new_abstractmethoderror
 #endif
-       mov     (itmp2),xptr                /* get the exception pointer          */
-       movl    $0,(itmp2)                  /* clear the exception pointer        */
+                                           /* exception pointer is return value  */
+       add     $(3*4),sp                   /* remove stack frame                 */
 
-       pop     xpc                         /* get and remove return address      */
-       jmp     asm_handle_exception
+       pop     xpc                         /* get exception address              */
+       sub     $2,xpc                      /* exception address is ra - 2        */
+       jmp     L_asm_handle_exception
 
 
 /************************ function asm_builtin_x2x *****************************
@@ -592,180 +381,148 @@ L_asm_wrapper_patcher_exception:
 *                                                                              *
 *******************************************************************************/
 
+#if defined(ENABLE_PIC_ASM)
+.GETPC:
+       mov     (%esp), %ebx
+       ret
+#endif
+
 asm_builtin_f2i:
-       sub     $4,%esp
+       sub     $(3*4),%esp
+#if defined(ENABLE_PIC_ASM)
+       sub     $12, %esp
+       push    %ebx
+       fsts    (%esp)
+       call    .GETPC
+       add     $_GLOBAL_OFFSET_TABLE_, %ebx
+       call    builtin_f2i@PLT
+       pop     %ebx
+       add     $12, %esp
+#else
        fsts    (%esp)
        call    builtin_f2i
-       add     $4,%esp
+#endif
+       add     $(3*4),%esp
        ret
 
 asm_builtin_d2i:
-       sub     $8,%esp
+       sub     $(3*4),%esp
+#if defined(ENABLE_PIC_ASM)
+       sub     $12, %esp
+       push    %ebx
+       fstl    (%esp)
+       call    .GETPC
+       add     $_GLOBAL_OFFSET_TABLE_, %ebx
+       call    builtin_d2i@PLT
+       pop     %ebx
+       add     $12, %esp
+#else
        fstl    (%esp)
        call    builtin_d2i
-       add     $8,%esp
+#endif
+       add     $(3*4),%esp
        ret
 
 asm_builtin_f2l:
-       sub     $4,%esp
+       sub     $(3*4),%esp
+#if defined(ENABLE_PIC_ASM)
+       sub     $12, %esp
+       push    %ebx
+       fsts    (%esp)
+       call    .GETPC
+       add     $_GLOBAL_OFFSET_TABLE_, %ebx
+       call    builtin_f2l@PLT
+       pop     %ebx
+       add     $12, %esp
+#else
        fsts    (%esp)
        call    builtin_f2l
-       add     $4,%esp
+#endif
+       add     $(3*4),%esp
        ret
 
 asm_builtin_d2l:
-       sub     $8,%esp
+       sub     $(3*4),%esp
+#if defined(ENABLE_PIC_ASM)
+       sub     $12, %esp
+       push    %ebx
+       fstl    (%esp)
+       call    .GETPC
+       add     $_GLOBAL_OFFSET_TABLE_, %ebx
+       call    builtin_d2l@PLT
+       pop     %ebx
+       add     $12, %esp
+#else
        fstl    (%esp)
        call    builtin_d2l
-       add     $8,%esp
+#endif
+       add     $(3*4),%esp
        ret
 
 
-/******************* function asm_initialize_thread_stack **********************
-*                                                                              *
-* initialized a thread stack                                                   *
-* (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
-*                                                                              *
-*******************************************************************************/
+/* asm_compare_and_swap ********************************************************
+
+   Does an atomic compare and swap.  Required for the lock
+   implementation.
+
+   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
+
+   long compare_and_swap(volatile long *p, long oldval, long newval);
 
-asm_initialize_thread_stack:
-               mov             8(%esp),%eax            /* (to)->stackEnd                     */
-               sub             $36,%eax                /* 4 bytes * 8 regs + 4 bytes func    */
-                               
-               xor             %edx,%edx
-               mov             %edx,0(%eax)
-               mov             %edx,4(%eax)
-               mov             %edx,8(%eax)
-               mov             %edx,12(%eax)
-               mov             %edx,16(%eax)
-               mov             %edx,20(%eax)
-               mov     %edx,24(%eax)
-               mov     %edx,28(%eax)
-                               
-               mov     4(%esp),%edx            /* save (u1*) (func)                  */
-               mov     %edx,32(%eax)
-
-               ret                             /* return restorepoint in %eax        */
-
-
-/******************* function asm_perform_threadswitch *************************
-*                                                                              *
-*   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
-*                                                                              *
-*   performs a threadswitch                                                    *
-*                                                                              *
 *******************************************************************************/
 
-asm_perform_threadswitch:
-       sub     $36,%esp
-          
-       mov     %eax,0(%esp)
-       mov     %ecx,4(%esp)
-       mov     %edx,8(%esp)
-       mov     %ebx,12(%esp)
-       mov     %esp,16(%esp)
-       mov     %ebp,20(%esp)
-       mov     %esi,24(%esp)
-       mov     %edi,28(%esp)
-          
-       mov     36(%esp),%eax         /* save current return address              */
-       mov     %eax,32(%esp)
-          
-       mov     40(%esp),%eax         /* first argument **from                    */
-       mov     %esp,0(%eax)
-          
-       mov     48(%esp),%eax         /* third argument **stackTop                */
-       mov     %esp,0(%eax)
-          
-       mov     44(%esp),%eax         /* second argument **to                     */
-       mov     0(%eax),%esp          /* load new stack pointer                   */
-          
-       mov     0(%esp),%eax
-       mov     4(%esp),%ecx
-       mov     8(%esp),%edx
-       mov     12(%esp),%ebx
-                                     /* skip stack pointer                       */
-       mov     20(%esp),%ebp
-       mov     24(%esp),%esi
-       mov     28(%esp),%edi
-          
-       add     $32,%esp              /* leave return address on stack            */
+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
-               
 
-/********************* function asm_switchstackandcall *************************
-*                                                                              *
-*  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
-*                                     void *p);                                       *
-*                                                                              *
-*   Switches to a new stack, calls a function and switches back.               *
-*       a0      new stack pointer                                              *
-*       a1      function pointer                                               *
-*              a2              pointer to variable where stack top should be stored           *
-*       a3      pointer to user data, is passed to the function                *
-*                                                                              *
+
+/* asm_memory_barrier **********************************************************
+
+   A memory barrier for the Java Memory Model.
+
 *******************************************************************************/
 
-asm_switchstackandcall:
-       mov     4(%esp),%edx          /* first argument *stack                    */
-       sub     $8,%edx               /* allocate new stack                       */
+asm_memory_barrier:
+       lock; add $0,0(sp)
+       ret
 
-       mov     (%esp),%eax           /* save return address on new stack         */
-       mov     %eax,(%edx)
 
-       mov     %esp,4(%edx)          /* save old stack pointer on new stack      */
+#if defined(ENABLE_ESCAPE_CHECK)
+asm_escape_check:
+       sub     $24,%esp
 
-       mov     12(%esp),%eax         /* third argument **stacktopsave            */
-       mov     %esp,(%eax)           /* save old stack pointer to variable       */
+       mov     t0, 4(%esp)
+       mov     itmp1, 8(%esp)
+       mov     itmp2, 12(%esp)
+       mov     itmp3, 16(%esp)
 
-       mov     8(%esp),%eax          /* load function pointer                    */
-       mov     16(%esp),%ecx         /* fourth argument *p                       */
-       
-       mov     %edx,%esp             /* switch to new stack                      */
+       mov     28(%esp), itmp1
+       mov     itmp1, (%esp)
 
-       sub     $4,%esp
-       mov     %ecx,0(%esp)          /* pass pointer                             */
-       call    *%eax                 /* and call function                        */
-       add     $4,%esp
+       call    escape_analysis_escape_check
 
-       mov     (%esp),%edx           /* load return address                      */
-       mov     4(%esp),%esp          /* switch to old stack                      */
-       mov     %edx,(%esp)
-       ret
+       mov     4(%esp), t0
+       mov     8(%esp), itmp1
+       mov     12(%esp), itmp2
+       mov     16(%esp), itmp3
 
-               
-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
+       add     $24,sp
        ret
+#endif
 
-       .data
 
-asm_criticalsections:
-#if defined(USE_THREADS) && defined(NATIVE_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
+/* disable exec-stacks ********************************************************/
 
+#if defined(__linux__) && defined(__ELF__)
+       .section .note.GNU-stack,"",%progbits
+#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.
@@ -778,4 +535,5 @@ asm_criticalsections:
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */