* src/vm/jit/i386/asmpart.S: Made position independent.
[cacao.git] / src / vm / jit / i386 / asmpart.S
index 79b1ccda1d7ee3bfb7c8dd5c2e276cef04c790cf..e182ddeeccf9d2e3490309361508a0e57e534c0b 100644 (file)
@@ -1,9 +1,7 @@
-/* vm/jit/i386/asmpart.S - Java-C interface functions for i386
+/* 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 1801 2004-12-21 20:19:19Z jowenn $
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
 */
 
 
 #include "config.h"
-#include "vm/jit/i386/offsets.h"
-#include "vm/jit/i386/asmoffsets.h"
 
+#include "md-asm.h"
+
+#include "vm/jit/i386/arch.h"
+#include "vm/jit/i386/md-abi.h"
+
+#include "vm/jit/abi-asm.h"
+#include "vm/jit/methodheader.h"
 
-#define itmp1    %eax
-#define itmp2    %ecx
-#define itmp3    %edx
 
-#define itmp1b   %al
-#define itmp2b   %cl
-#define itmp3b   %dl
-               
        .text
 
 
-/********************* exported functions and variables ***********************/
+/* export functions ***********************************************************/
+
+       .globl asm_md_init
 
-       .globl asm_calljavafunction
-       .globl calljava_xhandler
-       .globl asm_calljavafunction2
-       .globl asm_calljavafunction2long
-       .globl asm_calljavafunction2double
-       .globl calljava_xhandler2
+       .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_builtin_exception
        .globl asm_handle_nat_exception
        .globl asm_handle_exception
-       .globl asm_check_clinit
-       .globl asm_builtin_checkcast    
-       .globl asm_builtin_checkarraycast
-       .globl asm_builtin_newarray
-       .globl asm_builtin_anewarray
-       .globl asm_builtin_newarray_array
-       .globl asm_builtin_aastore
-       .globl asm_builtin_monitorenter
-       .globl asm_builtin_monitorexit
-       .globl asm_builtin_ldiv
-       .globl asm_builtin_lrem
-    .globl asm_builtin_f2i
-    .globl asm_builtin_f2l
-    .globl asm_builtin_d2i
-    .globl asm_builtin_d2l
-       .globl asm_builtin_arrayinstanceof
-       .globl asm_perform_threadswitch
-       .globl asm_initialize_thread_stack
-       .globl asm_switchstackandcall
-       .globl asm_getcallingmethod
-       .globl asm_builtin_new
-       .globl asm_criticalsections
-       .globl asm_getclassvalues_atomic
-       .globl asm_prepare_native_stackinfo
-       .globl asm_remove_native_stackinfo
-/*************************** imported functions *******************************/
-
-       .globl jit_compile
-       .globl builtin_monitorexit
-       .globl builtin_throw_exception
-       .globl builtin_trace_exception
-       .globl class_java_lang_Object
-       .globl codegen_findmethod
-       .globl callgetexceptionptrptr
-       .globl asm_throw_and_handle_exception
-       .globl asm_throw_and_handle_hardware_arithmetic_exception
 
+       .globl asm_abstractmethoderror
 
-/********************* 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);                     *
-*                                                                              *
-*******************************************************************************/
+       .globl asm_builtin_f2i
+       .globl asm_builtin_f2l
+       .globl asm_builtin_d2i
+       .globl asm_builtin_d2l
 
-call_name:
-       .ascii  "calljavafunction\0\0"
+       .globl asm_compare_and_swap
+       .globl asm_memory_barrier
 
-       .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:
-       push    %ebp                      /* allocate stack space                 */
-       mov     %esp, %ebp
-
-       push    %ebx                      /* save registers                       */
-       push    %esi
-       push    %edi
-        
-       sub     $32,%esp                  /* pass the remaining parameters        */
-       xor     %edx,%edx
-
-       mov     %edx,28(%esp)             /* convert parms to 8 byte              */
-       mov     24(%ebp),%eax
-       mov     %eax,24(%esp)
-               
-       mov     %edx,20(%esp)
-       mov     20(%ebp),%eax
-       mov     %eax,16(%esp)
-
-       mov     %edx,12(%esp)
-       mov     16(%ebp),%eax
-       mov     %eax,8(%esp)
-
-       mov     %edx,4(%esp)
-       mov     12(%ebp),%eax
-       mov     %eax,(%esp)
-
-       mov     8(%ebp),%eax              /* move function pointer to %eax        */
-
-       lea     asm_call_jit_compiler,%edx 
-       call    *%edx                     /* call JIT compiler                    */
-       
-       add     $32,%esp
-       pop     %edi                      /* restore registers                    */
-       pop     %esi
-       pop     %ebx
-       leave
-       ret
+#if defined(ENABLE_ESCAPE_CHECK)
+       .globl asm_escape_check
+#endif
 
-calljava_xhandler:
-       push    %eax                      /* pass exception pointer               */
-       call    builtin_throw_exception
-       add     $4,%esp
 
-       add     $32,%esp
-       pop     %edi                      /* restore registers                    */
-       pop     %esi
-       pop     %ebx
-       leave
+/* asm_md_init *****************************************************************
+
+   Initialize machine dependent stuff.
+
+   See: http://www.srware.com/linux_numerics.txt
+
+   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.
+
+   Fixes: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350729
+
+*******************************************************************************/
+
+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
 
 
@@ -195,236 +103,100 @@ 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:
-       .ascii  "calljavafunction2\0\0"
-
        .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_calljavafunction2double:
-asm_calljavafunction2long:
-       push    %ebp
-       mov     %esp,%ebp                 /* save stackptr                        */
-
-       push    %ebx                      /* save registers                       */
-       push    %esi
-       push    %edi
-
-       mov     20(%ebp),%eax             /* pointer to arg block                 */
-       mov     12(%ebp),%ecx             /* arg count                            */
-       test    %ecx,%ecx                 /* maybe we have no args                */
-       jle     calljava_copydone
-
-       mov     %ecx,%edx                 /* calculate stack size                 */
-       shl     $3,%edx
-       mov     %edx,%esi                 /* save in callee saved register        */
-       sub     %esi,%esp                 /* stack frame for arguments            */
-       mov     %esp,%edi
-
-calljava_copyloop:
-    mov     offjniitem(%eax),%edx
-    mov     %edx,0(%edi)
-    mov     offjniitem+4(%eax),%edx
-    mov     %edx,4(%edi)
-
-       sub     $1,%ecx                   /* are there any args left?             */
-       test    %ecx,%ecx
-       jle     calljava_copydone
-
-       add     $sizejniblock,%eax        /* goto next argument block             */
-    add     $8,%edi                   /* increase sp to next argument         */
-       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                    */
-       
-calljava_return2:
-       add     %esi,%esp                 /* remove arg stack frame               */
-       pop     %edi                      /* restore registers                    */
-       pop     %esi
-       pop     %ebx
-       leave
-       ret
 
-calljava_xhandler2:
-       push    %eax                      /* 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
+       .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
+
        leave
        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:
-       push    %ebx                /* save register                              */
-    push    %ebp
-                       
-       mov     8(%esp),%ebp        /* get return address (2 push)                */
-       mov     -1(%ebp),%bl        /* get function code                          */
-       cmp     $0xd1,%bl           /* called with `call *REG_ITMP2' (%ecx)?      */
-       jne             L_not_static_special
-
-       sub     $6,%ebp             /* calculate address of immediate             */
-       jmp             L_call_jit_compile
-               
-L_not_static_special:
-       cmp     $0xd0,%bl           /* called with `call *REG_ITMP1' (%eax)       */
-       jne             L_not_virtual_interface
-       
-       sub     $6,%ebp             /* calculate address of offset                */
-       mov     (%ebp),%ebp         /* get offset                                 */
-       add     itmp2,%ebp          /* add base address to get method address     */
-       jmp             L_call_jit_compile
-
-L_not_virtual_interface:        /* a call from asm_calljavafunction           */
-       xor     %ebp,%ebp
-               
-L_call_jit_compile:
-       push    %ebp                /* save address for method pointer            */
-
-       push    %eax                /* push methodpointer on stack                */
-       call    jit_compile
-       add     $4,%esp
-
-       pop     %ebp                /* restore address for method pointer         */
-
-       test    %eax,%eax           /* check for exception                        */
-       je      L_exception
-
-       test    %ebp,%ebp           /* is address == 0 (asm_calljavafunction)     */
-       je              L_call_method
-       
-       mov     %eax,(%ebp)         /* and now save the new pointer               */
-
-L_call_method:
-       pop     %ebp                /* restore registers                          */
-       pop     %ebx
-               
-       jmp             *%eax               /* ...and now call the new method             */
-
-L_exception:
-       pop     %ebp                /* restore registers                          */
+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
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       call    builtin_asm_get_exceptionptrptr
-       mov     %eax,%ecx
-       mov     (%ecx),%eax         /* get the exception pointer                  */
-       movl    $0,(%ecx)           /* clear the exception pointer                */
+       add     $12, %esp
 #else
-       lea     _exceptionptr,%ecx
-       mov     (%ecx),%eax         /* get the exception pointer                  */
-       movl    $0,(%ecx)           /* clear the exception pointer                */
+       call    builtin_throw_exception
 #endif
+       add     $4,sp
+asm_vm_call_method_end:
+       jmp     L_asm_vm_call_method_return
+
 
-       pop     %ecx                /* delete return address                      */
-       sub     $2,%ecx             /* faulting address is return adress - 2      */
-
-L_refillinStacktrace:               /*a compilation error should cause a stacktrace
-                                    which starts at the method call, which caused
-                                    the compilation of the new function. Until this
-                                    point the trace is invalid anyways, since it is
-                                    not complete. Compared to other runtimes it will
-                                    not be correct either, since we report eg class
-                                    not found errors too early, since we always
-                                    compile methods completely. The native info
-                                    should be moved around the jit call to get
-                                    a more compliant trace for the "exception in
-                                    initializer" case*/
-       push %ecx               /* store fault adress */
-       push %eax               /* temporarily save exception pointer*/
-       push $0                 /* internal function */
-       call builtin_asm_get_stackframeinfo
-       push %eax       /* save location of thread specific stack info head pointer */
-       mov (%eax),%ecx /* save old value of pointer*/
-       push %ecx
-       mov %esp,(%eax) /*store pointer to this structure*/
-       mov 12(%esp),%eax  /* get the exception pointer again*/
-       movl $0,12(%esp) /*java stack begins just above structure*/
-       push $0 /*used for the jni_callblock structure*/
-       push %eax /*save eax for later */
-       /* get fillInStackTrace method*/
-       push utf_fillInStackTrace_desc
-       push utf_fillInStackTrace_name
-       mov offobjvftbl(%eax),%ecx
-       mov offclass(%ecx),%eax
-       push %eax
-       call class_resolvemethod
-       add $12,%esp
-       push $0
-       push $4 /*TYPE_ADR*/
-       push %esp
-       push $sizejniblock
-       push $1
-       push %eax
-       call asm_calljavafunction2
-       add $24,%esp
-
-       /*remove native stack info */
-       mov 8(%esp),%ecx
-       mov 12(%esp),%eax
-       mov %ecx,(%eax)
-       mov (%esp),%eax
-       add $24,%esp
-       pop %ecx
-
-       
-       jmp     asm_handle_exception
-
-
-/********************* function asm_handle_exception ***************************
+/* asm_handle_exception ********************************************************
 *                                                                              *
 *   This function handles an exception. It does not use the usual calling      *
 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
@@ -432,424 +204,176 @@ L_refillinStacktrace:               /*a compilation error should cause a stacktr
 *   the local exception table for a handler. If no one is found, it unwinds    *
 *   stacks and continues searching the callers.                                *
 *                                                                              *
-*   void asm_handle_exception (exceptionptr, exceptionpc);                     *
-*                                                                              *
 *******************************************************************************/
 
 asm_handle_nat_exception:
-               add     $4,%esp                                         /* clear return address of native stub */
+       add     $4,sp                       /* clear return address of native stub*/
                
 asm_handle_exception:
-asm_handle_exception_loop:
-               push    %ebp
-               mov     %esp,%ebp
-        
-               push    %eax                                            /* save exception pointer         */
-               push    %ecx                        /* save exception pc              */
-
-               call    codegen_findmethod          /* get the data segment ptr       */
-               mov     %eax,%edx
-                       
-               mov     -4(%ebp),%eax
-               mov     -8(%ebp),%ecx               /* could be changed in findmethod */
-
-               push    %edx                                            /* save data segment pointer      */
-               push    %ebx
-               push    %esi
-               push    %edi
-               
-ex_stack_loop:
-               sub     $20,%esp
-               mov     %eax,(%esp)                                     /* exception pointer              */
-               mov     MethodPointer(%edx),%eax        /* method pointer                 */
-               mov     %eax,4(%esp)
-               mov     %ecx,8(%esp)                            /* exception pc                   */
-               movl    $0,12(%esp)                 /* line number                    */
-               movl    $1,16(%esp)                                     /* set no unwind flag             */
-               call    builtin_trace_exception
-               add     $20,%esp
-               mov     -12(%ebp),%esi                          /* %esi = data segment pointer    */
-               mov     ExTableSize(%esi),%ecx          /* %ecx = exception table size    */
-               test    %ecx,%ecx                                       /* if empty table skip            */
-               je      empty_table
-
-               lea             ExTableStart(%esi),%edi         /* %edi = start of exception table*/
-               mov     -4(%ebp),%eax               /* get xptr                       */
-               
-ex_table_loop:
-               mov     -8(%ebp),%edx                           /* get xpc                        */
-
-               mov     ExStartPC(%edi),%ebx            /* %ebx = exception start pc      */
-               cmp     %edx,%ebx                                       /* %ebx = (startpc <= xpc)        */
-               jg      ex_table_cont                           /* if (false) continue            */
-               mov     ExEndPC(%edi),%ebx                      /* %ebx = exception end pc        */
-               cmp     %ebx,%edx                                       /* %ebx = (xpc < endpc)           */
-               jge     ex_table_cont                           /* if (false) continue            */
-               mov     ExCatchType(%edi),%ebx          /* arg1 = exception catch type    */
-               test    %ebx,%ebx                                       /* NULL catches everything        */
-               je      ex_handle_it
-
-       cmpl    $0,offclassloaded(%ebx)     /* check if class is loaded           */
-       jne     L_class_loaded
-
-       sub     $3*4,%esp
-       mov     %eax,1*4(%esp)              /* save not callee saved regs         */
-       mov     %ecx,2*4(%esp)
-
-       mov     %ebx,0*4(%esp)              /* exception class is argument        */
-       call    class_load
-
-       mov     0*4(%esp),%ebx
-       mov     1*4(%esp),%eax
-       mov     2*4(%esp),%ecx
-       add     $3*4,%esp
-
-L_class_loaded:
-       cmpl    $0,offclasslinked(%ebx)
-       jne     L_class_linked
-
-       sub     $3*4,%esp
-       mov     %eax,1*4(%esp)              /* save not callee saved regs         */
-       mov     %ecx,2*4(%esp)
-
-       mov     %ebx,0*4(%esp)              /* exception class is argument        */
-       call    class_link
-
-       mov     0*4(%esp),%ebx
-       mov     1*4(%esp),%eax
-       mov     2*4(%esp),%ecx
-       add     $3*4,%esp
-
-L_class_linked:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       push    %ebx
-
-_crit_restart1:
-       mov     0(%esp),%ebx
+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     $(12*4),sp                  /* keep stack 16-byte aligned         */
+       mov     xptr,4*4(sp)                /* save exception pointer             */
+       mov     xpc,5*4(sp)                 /* save exception pc                  */
+       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                  */
+#if defined(ENABLE_PIC_ASM)
+       call    .GETPC
+       add     $_GLOBAL_OFFSET_TABLE_, %ebx
+       call    methodtree_find@PLT
+#else
+       call    methodtree_find
 #endif
-               
-_crit_begin1:
-       mov     offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr)              */
-       mov     offclassvftbl(%ebx),%ebx    /* %ebx = vftblptr(catchtype) class (not obj) */
-       mov     offbaseval(%esi),%esi           /* %esi = baseval(xptr)               */
-       mov     offbaseval(%ebx),%edx           /* %edx = baseval(catchtype)          */
-       mov     offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype)          */
-_crit_end1:
-       sub     %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       add     $4,%esp
+       mov     v0,6*4(sp)                  /* save data segment pointer          */
+
+       mov     4*4(sp),itmp3               /* pass exception pointer             */
+       mov     itmp3,0*4(sp)
+       mov     5*4(sp),itmp3               /* pass exception pc                  */
+       mov     itmp3,1*4(sp)
+       mov     v0,2*4(sp)                  /* pass data segment pointer          */
+       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
-        
-       cmp     %ebx,%esi                                       /* xptr is instanceof catchtype       */
-       ja      ex_table_cont
-               
-ex_handle_it:
-               mov     ExHandlerPC(%edi),%edx
-               
-               pop     %edi                        /* restore registers              */
-               pop     %esi
-               pop     %ebx
-        add     $8,%esp                     /* suck %ecx, %edx                */
-        pop     %eax                        /* restore xptr                   */
-
-               leave
-               jmp             *%edx                       /* jump to exception handler      */
-
-ex_table_cont:
-               lea     ExEntrySize(%edi),%edi
-               dec     %ecx
-               test    %ecx,%ecx
-               jg      ex_table_loop
-               
-empty_table:
-        pop     %edi
-        pop     %esi
-        pop     %ebx
-        pop     %edx                        /* restore data segment pointer   */
-        pop     %ecx
-        pop     %eax
-        pop     %ebp
-
-        push    %eax                        /* save exception pointer         */
-        
-ex_already_cleared:
-               mov     IsSync(%edx),%eax                       /* %eax = SyncOffset              */
-               test    %eax,%eax                                       /* if zero no monitorexit         */
-               je      no_monitor_exit
-
-        add     %esp,%eax
-        mov     -4(%eax),%eax               /* we have the xptr on the stack  */
-        push    %edx                        /* save regs                      */
-        push    %eax
-               call    builtin_monitorexit
-               add     $4,%esp
-        pop     %edx                        /* restore regs                   */
-        
-no_monitor_exit:
-        mov     %esp,%eax
-        add     FrameSize(%edx),%eax        /* %eax = frame size              */
-        add     $4,%eax                     /* we have the xptr on the stack  */
-        
-               mov     IntSave(%edx),%ecx          /* %ecx = saved int register count*/
-               test    %ecx,%ecx
-               je      noint
-               cmp     $1,%ecx
-               je      int1
-               cmp     $2,%ecx
-               je      int2
-               cmp     $3,%ecx
-               je      int3
-
-int4:  
-               mov     -32(%eax),%ebx
-
-int3:  
-               mov     -24(%eax),%ebp
-
-int2:  
-               mov     -16(%eax),%esi
 
-int1:  
-               mov     -8(%eax),%edi
-
-               shl     $3,%ecx                                         /* multiply by 8 bytes             */
-               sub     %ecx,%eax
-               
-noint:
-               mov     FltSave(%edx),%ecx                      /* %ecx = saved flt register count */
-               test    %ecx,%ecx
-               je      noflt
-               cmp     $1,%ecx
-               je      flt1
-               cmp     $2,%ecx
-               je      flt2
-               cmp     $3,%ecx
-               je      flt3
-               
-flt4:  
-               fldl    -32(%eax)
-               fstp    %st(1)
+       test    v0,v0
+       jz      L_asm_handle_exception_not_catched
 
-flt3:  
-               fldl    -24(%eax)
-               fstp    %st(2)
-               
-flt2:  
-               fldl    -16(%eax)
-               fstp    %st(3)
-               
-flt1:  
-               fldl    -8(%eax)
-               fstp    %st(4)
-               
-noflt:
-        pop     %eax                        /* restore exception pointer      */
-        
-        mov     FrameSize(%edx),%ecx        /* %ecx = frame size              */
-        add     %ecx,%esp                   /* unwind stack                   */
-        
-               pop     %ecx                        /* the new xpc is return address  */
-               sub     $2,%ecx
-               
-               jmp             asm_handle_exception_loop
-               
+       mov     v0,xpc                      /* move handlerpc into xpc            */
+       mov     4*4(sp),xptr                /* restore exception pointer          */
+       mov     8*4(sp),t0                  /* get maybe-leaf flag                */
+       add     $(12*4),sp                  /* free stackframe                    */
 
-/* asm_check_clinit ************************************************************
+       test    t0,t0                       /* test for maybe-leaf flag           */
+       jz      L_asm_handle_exception_no_leaf
 
-   DOCUMENT ME!!!
+       RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
+       RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
 
-   Stack layout:
+       add     $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe       */
 
-       16  ra      ; return address of patched call in java machine code
-       12  xmcode  ; additional machine code (only for i386 and x86_64)
-       8   mcode   ; machine code to patch back in
-       4   class   ; pointer to class
-       0   sp      ; stack pointer of java stack frame + return address
+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       */
+       mov     8*4(sp),t0                  /* get maybe-leaf flag                */
+       add     $(12*4),sp                  /* free stackframe                    */
 
-asm_check_clinit:
-       mov     4(%esp),%eax                /* get fieldinfo's class pointer      */
-       mov     offclassinit(%eax),%eax     /* get initialized flag               */
-       test    %eax,%eax
-       jnz     L_is_initialized
-
-       /*3*4 bytes*/
-       mov 16(%esp),itmp1
-       push itmp1                        /*return adress into java machine code */
-       mov 4(%esp),itmp1
-       push itmp1                        /*begin of java stack frame*/
-       pushl $0                           /*internal (invisible) method*/
-       call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
-                                               data onto the stack */
-
-       sub     $4,%esp
-       mov     20+4+4(%esp),itmp1          /* get class pointer                  */
-       mov     itmp1,(%esp)                /* store class pointer as a0          */
-       call    class_init                  /* call class_init function           */
-       add     $4,%esp
-
-       call asm_remove_native_stackinfo  /* removes 4* 4 bytes and leaves ret
-                                                into java machine code on stack  */
-       add     $4,%esp                   /* ret address no longer needed, is still
-                                               on stack a few bytes above */
-
-       test    %eax,%eax                   /* we had an exception                */
-       je      L_initializererror
-
-L_is_initialized:
-       mov     16(%esp),itmp1              /* get return address                 */
-       sub     $5,itmp1                    /* remove size of `call rel32'        */
-
-       mov     12(%esp),itmp2              /* get xmcode machine code            */
-       movb    itmp2b,(itmp1)              /* patch back in 1 byte               */
-       mov     8(%esp),itmp2               /* get mcode machine code             */
-       mov     itmp2,1(itmp1)              /* patch back in 4 bytes              */
-
-       add     $(5*4),%esp                 /* remove stub stack frame incl. ra   */
-
-       jmp     *itmp1                      /* jump to patched code an execute it */
-
-L_initializererror:
-       add     $(4*4),%esp                 /* remove stub stack frame            */
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       call    builtin_asm_get_exceptionptrptr
-       mov     %eax,%ecx
-       mov     (%ecx),%eax                 /* get the exception pointer          */
-       movl    $0,(%ecx)                   /* clear the exception pointer        */
-#else
-       lea     _exceptionptr,%ecx
-       mov     (%ecx),%eax                 /* get the exception pointer          */
-       movl    $0,(%ecx)                   /* clear the exception pointer        */
-#endif
+       test    t0,t0
+       jz      L_asm_handle_exception_no_leaf_stack
 
-       pop     itmp2                       /* get and delete ra                  */
-       sub     $5,itmp2                    /* faulting address is ra - 5         */
+       add     $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe       */
+       xor     t0,t0                       /* clear the maybe-leaf flag          */
 
-       jmp     asm_handle_exception
+L_asm_handle_exception_no_leaf_stack:
+       mov     FrameSize(itmp3),itmp2      /* get frame size                     */
+       add     sp,itmp2                    /* pointer to save area               */
 
+       push    xptr                        /* we are out of registers            */
 
-/********************* function asm_builtin_monitorenter ***********************
-*                                                                              *
-*   Does null check and calls monitorenter or throws an exception              *
-*                                                                              *
-*******************************************************************************/
+       mov     IntSave(itmp3),itmp1        /* itmp1 = saved int register count   */
+       test    itmp1,itmp1
+       je      noint
 
-asm_builtin_monitorenter:
-       cmpl    $0,4(%esp)
-       je      nb_monitorenter             /* if (null) throw exception          */
-       jmp             builtin_monitorenter        /* else call builtin_monitorenter     */
+       cmp     $1,itmp1
+       je      int1
+       cmp     $2,itmp1
+       je      int2
 
-nb_monitorenter:
-        mov string_java_lang_NullPointerException,%eax
-        pop %ecx
-        sub $2,%ecx
-        jmp asm_throw_and_handle_exception
+       mov     -4-3*8(itmp2),s0
+int2:  
+       mov     -4-2*8(itmp2),s1
+int1:  
+       mov     -4-1*8(itmp2),s2
 
+       shl     $2,itmp1                    /* multiply by 4 bytes                */
+       sub     itmp1,itmp2
+               
+noint:
 #if 0
-       push    string_java_lang_NullPointerException
-       call    new_exception
-       add     $(1*4),%esp
-       
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-#endif         
-
-/********************* function asm_builtin_monitorexit ************************
-*                                                                              *
-*   Does null check and calls monitorexit or throws an exception               *
-*                                                                              *
-*******************************************************************************/
+       mov     FltSave(itmp3),itmp1        /* itmp1 = saved flt register count   */
+       test    itmp1,itmp1
+       je      noflt
+
+       cmp     $1,itmp1
+       je      flt1
+       cmp     $2,itmp1
+       je      flt2
+       cmp     $3,itmp1
+       je      flt3
+               
+       fldl    -4*8(itmp2)
+       fstp    %st(1)
+flt3:
+       fldl    -3*8(itmp2)
+       fstp    %st(2)
+flt2:
+       fldl    -2*8(itmp2)
+       fstp    %st(3)
+flt1:
+       fldl    -1*8(itmp2)
+       fstp    %st(4)
+               
+noflt:
+#endif
+       pop     xptr                        /* restore exception pointer          */
+       mov     FrameSize(itmp3),itmp2      /* get frame size                     */
+       add     itmp2,sp                    /* unwind stack                       */
 
-asm_builtin_monitorexit:
-       mov     4(%esp),%eax
-    test    %eax,%eax
-       je      nb_monitorexit              /* if (null) throw exception          */
-    push    %ecx                        /* save registers which could be used */
-    push    %edx
-    push    %eax
-       call    builtin_monitorexit         /* else call builtin_monitorenter     */
-    add     $4,%esp
-    pop     %edx                        /* restore registers which could be used */
-    pop     %ecx
-    ret
-
-nb_monitorexit:
-        mov string_java_lang_NullPointerException,%eax
-        pop %ecx
-        sub $2,%ecx
-        jmp asm_throw_and_handle_exception
+       pop     xpc                         /* the new xpc is return address      */
+       sub     $2,xpc                      /* subtract 2-bytes for call          */
 
-#if 0
-       push    string_java_lang_NullPointerException
-       call    new_exception
-       add     $(1*4),%esp
-       
-       pop     %ecx                    /* delete return address              */
-       sub     $2,%ecx                 /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-#endif
+       xor     itmp3,itmp3                 /* prepare a3 for handle_exception    */
 
-/************************ function asm_builtin_ldiv ****************************
-*                                                                              *
-*   Does null check and calls ldiv or throws an exception                      *
-*                                                                              *
-*******************************************************************************/
+       jmp     L_asm_handle_exception_stack_loop
+               
 
-asm_builtin_ldiv:
-       mov     12(%esp),%eax
-       or      16(%esp),%eax
-       test    %eax,%eax                   /* if (null) throw exception          */
-       je      nb_ldiv
+/* asm_abstractmethoderror *****************************************************
 
-       jmp     builtin_ldiv
+   Creates and throws an AbstractMethodError.
 
-nb_ldiv:
-       pop %ecx
-       sub $2,%ecx
-       jmp asm_throw_and_handle_hardware_arithmetic_exception
-#if 0
-       push    string_java_lang_ArithmeticException_message
-       push    string_java_lang_ArithmeticException
-       call    new_exception_message
-       add     $(2*4),%esp
-       
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-#endif                         
-
-/************************ function asm_builtin_lrem ****************************
-*                                                                              *
-*   Does null check and calls lrem or throws an exception                      *
-*                                                                              *
 *******************************************************************************/
 
-asm_builtin_lrem:
-       mov     12(%esp),%eax
-       or      16(%esp),%eax
-       test    %eax,%eax                   /* if (null) throw exception          */
-       je      nb_lrem
+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     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
+       call    exceptions_asm_new_abstractmethoderror
+#endif
+                                           /* exception pointer is return value  */
+       add     $(3*4),sp                   /* remove stack frame                 */
 
-       jmp     builtin_lrem
+       pop     xpc                         /* get exception address              */
+       sub     $2,xpc                      /* exception address is ra - 2        */
+       jmp     L_asm_handle_exception
 
-nb_lrem:
-       pop %ecx
-       sub $2,%ecx
-       jmp asm_throw_and_handle_hardware_arithmetic_exception
-#if 0
-       push    string_java_lang_ArithmeticException_message
-       push    string_java_lang_ArithmeticException
-       call    new_exception_message
-       add     $(2*4),%esp
-
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-#endif         
 
 /************************ function asm_builtin_x2x *****************************
 *                                                                              *
@@ -857,563 +381,149 @@ nb_lrem:
 *                                                                              *
 *******************************************************************************/
 
+#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
-       ret
-
-
-/******************* function asm_builtin_checkarraycast ***********************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
-*******************************************************************************/
-
-asm_builtin_checkarraycast:
-       sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
-
-       mov             12(%esp),%eax               /* 8 (frame) + 4 (return)             */
-       mov             %eax,(%esp)                 /* save object pointer                */
-
-       mov             20(%esp),%eax
-       mov             %eax,4(%esp)
-
-       call    builtin_checkarraycast      /* builtin_checkarraycast             */
-
-       test    %eax,%eax                   /* if (false) throw exception         */
-       je              nb_carray_throw
-
-       mov             12(%esp),%eax               /* return object pointer              */
-       add             $8,%esp
-       ret
-
-nb_carray_throw:
-       add $8,%esp
-       mov string_java_lang_ClassCastException,%eax
-       pop %ecx
-       sub $2,%ecx
-       jmp asm_throw_and_handle_exception
-#if 0
-       push    string_java_lang_ClassCastException
-       call    new_exception
-       add     $(1*4),%esp
-       
-       add             $8,%esp
-       
-       pop             %ecx                        /* delete return address              */
-       sub             $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp             asm_handle_exception
 #endif
-               
-/******************* function asm_builtin_newarray *****************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
-*******************************************************************************/
-
-asm_builtin_newarray:
-       sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
-
-       mov             12(%esp),%eax
-       mov             %eax,(%esp)
-
-       mov             20(%esp),%eax
-       mov             %eax,4(%esp)
-
-       call    builtin_newarray
-
-       add             $8,%esp
+       add     $(3*4),%esp
        ret
 
-               
-/******************* function asm_builtin_aastore ******************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
-*******************************************************************************/
-
-asm_builtin_aastore:
-       sub     $12,%esp                    /* build stack frame (3 * 4 bytes)    */
-
-       mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
-       test    %eax,%eax                   /* if null pointer throw exception    */
-       je      nb_aastore_null
-
-       mov     offarraysize(%eax),%edx /* load size                          */
-       mov     24(%esp),%ecx               /* index                              */
-       cmp     %edx,%ecx                   /* do bound check                     */
-       jae     nb_aastore_bound            /* if out of bounds throw exception   */
-
-       shl     $2,%ecx                     /* index * 4                          */
-       add     %eax,%ecx                   /* add index * 4 to arrayref          */
-          
-       mov     %ecx,8(%esp)                /* save store position                */
-          
-       mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
-       mov     %eax,(%esp)
-          
-       mov     32(%esp),%eax               /* object is second argument          */
-       mov     %eax,4(%esp)
-       
-       call    builtin_canstore            /* builtin_canstore(arrayref,object)  */
-
-       test    %eax,%eax                   /* if (false) throw exception         */
-       je      nb_aastore_store
-
-       mov     32(%esp),%eax
-       mov     8(%esp),%ecx
-       mov     %eax,offobjarrdata(%ecx)    /* store objectptr in array           */
-       
-       add     $12,%esp
-       ret
-
-nb_aastore_null:
-        add $12,%esp
-        mov string_java_lang_NullPointerException,%eax
-        pop %ecx
-        sub $2,%ecx
-        jmp asm_throw_and_handle_exception
-
-#if 0
-       push    string_java_lang_NullPointerException
-       call    new_exception
-       add     $(1*4),%esp
-       
-       add     $12,%esp
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp             asm_handle_exception
-#endif
-nb_aastore_bound:
-       add     $12,%esp
-       mov     %ecx,%eax                        /* itmp2 contains array index         */
-       pushl   $0  /*directly below return adress*/
-       pushl   $0  /*internal (invisible) method*/
-       call    asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
-
-       push    %eax
-       call    new_arrayindexoutofboundsexception
-       add     $(1*4),%esp
-
-       call    asm_remove_native_stackinfo /*return adress is the first on stack again*/
-
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-               
-nb_aastore_store:
-       add     $12,%esp
-
-        mov string_java_lang_ArrayStoreException,%eax
-        pop %ecx
-        sub $2,%ecx
-        jmp asm_throw_and_handle_exception
-
-#if 0
-       push    string_java_lang_ArrayStoreException
-       call    new_exception
-       add     $(1*4),%esp
-       
-       add     $12,%esp
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-#endif
-               
-/******************* function asm_builtin_arrayinstanceof **********************
-*                                                                              *
-*   Does the instanceof check of arrays                                        *
-*                                                                              *
-*******************************************************************************/
 
-asm_builtin_arrayinstanceof:
-       sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
+/* asm_compare_and_swap ********************************************************
 
-       mov     12(%esp),%eax
-       mov     %eax,(%esp)
+   Does an atomic compare and swap.  Required for the lock
+   implementation.
 
-       mov     20(%esp),%eax
-       mov     %eax,4(%esp)
+   Atomically do the following: Check if the location still contains
+   `oldval`. If so, replace it by `newval` and return `oldval`.
 
-       call    builtin_arrayinstanceof
+   RETURN VALUE:
+       the old value at *p
 
-       add     $8,%esp
-       ret
-
-               
-/******************* function asm_initialize_thread_stack **********************
-*                                                                              *
-* initialized a thread stack                                                   *
-* (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
-*                                                                              *
-*******************************************************************************/
+   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_switchstackandcall:
-       mov     4(%esp),%edx          /* first argument *stack                    */
-       sub     $8,%edx               /* allocate new stack                       */
 
-       mov     (%esp),%eax           /* save return address on new stack         */
-       mov     %eax,(%edx)
+/* asm_memory_barrier **********************************************************
 
-       mov     %esp,4(%edx)          /* save old stack pointer on new stack      */
+   A memory barrier for the Java Memory Model.
 
-       mov     12(%esp),%eax         /* third argument **stacktopsave            */
-       mov     %esp,(%eax)           /* save old stack pointer to variable       */
-
-       mov     8(%esp),%eax          /* load function pointer                    */
-       mov     16(%esp),%ecx         /* fourth argument *p                       */
-       
-       mov     %edx,%esp             /* switch to new stack                      */
-
-       sub     $4,%esp
-       mov     %ecx,0(%esp)          /* pass pointer                             */
-       call    *%eax                 /* and call function                        */
-       add     $4,%esp
+*******************************************************************************/
 
-       mov     (%esp),%edx           /* load return address                      */
-       mov     4(%esp),%esp          /* switch to old stack                      */
-       mov     %edx,(%esp)
+asm_memory_barrier:
+       lock; add $0,0(sp)
        ret
 
-               
-asm_throw_and_handle_exception:
-       push %ecx
-       pushl $0 /* the pushed XPC is directly below the java frame*/
-       pushl $0
-       call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
-       
-       push %eax
-        call new_exception
-       add $4,%esp   /*remove parameter*/
-
-       call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
-
-       pop %ecx
-       jmp asm_handle_exception
-       ret /*should never be reached */
-
-asm_throw_and_handle_hardware_arithmetic_exception:
-       
-       push %ecx
-       pushl $0 /* the pushed XPC is directly below the java frame*/
-       pushl $0
-       call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
-       
-       mov string_java_lang_ArithmeticException_message,%eax
-       push %eax
-       mov string_java_lang_ArithmeticException,%eax
-       push %eax
-
-       call new_exception_message
-       add $8,%esp /*remove parameters */
-
-       call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
-
-       pop %ecx
-       jmp asm_handle_exception
-       ret /*should never be reached */
-
-asm_builtin_new:
-/*optimize a littlebit */
-               mov %esp,%eax
-/*DEBUG*/
-/*             push %eax
-               call i386_native_stub_debug
-               pop %eax */
-               
-               movl 4(%esp),%eax
-               mov     offclassinit(%eax),%ecx     /* get initialized flag           */
-               test    %ecx,%ecx
-               jnz             L_builtin_new_noinit
-
-               mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
-
-               /* 2 *4 bytes, the return adress is used directy */
-               pushl $0  /* the structure is placed directly below the java stackframe*/
-               pushl $0  /* builtin (invisible) method */
-               call  asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
-#if 0
-                sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
-
-                mov             20(%esp),%eax
-                mov             %eax,(%esp)
-
-               call    builtin_asm_get_stackframeinfo
-               movl    $0,12(%esp)
-               mov     %eax,8(%esp)
-               mov     (%eax),%ebx
-               mov     %ebx,4(%esp)
-               mov     %esp,%ecx
-               add     $4,%ecx
-               mov     %ecx,(%eax)
-#endif
-               push    %eax
-                call    builtin_new
-               add     $4,%esp
-
-               call    asm_remove_native_stackinfo /*first element on stack is return adress again*/
-#if 0          
-               call    
-               mov     4(%esp),%ebx
-               mov     8(%esp),%ecx
-               mov     %ebx,(%ecx)
-
-                add             $16,%esp
-#endif
-               jmp L_builtin_new_patch
-
-
-L_builtin_new_noinit:
-               mov 4(%esp),%eax
-               push %eax
-               call builtin_new
-               add $4,%esp
-               /*jmp L_builtin_new_patch*/
 
-L_builtin_new_patch:
-/*add patching code here */
-               lea builtin_new,%edx
-               mov (%esp),%ecx
-               mov %edx,-6(%ecx)       /*patch calling instruction, t directly call builtin_new the next time*/
-               ret
+#if defined(ENABLE_ESCAPE_CHECK)
+asm_escape_check:
+       sub     $24,%esp
 
+       mov     t0, 4(%esp)
+       mov     itmp1, 8(%esp)
+       mov     itmp2, 12(%esp)
+       mov     itmp3, 16(%esp)
 
+       mov     28(%esp), itmp1
+       mov     itmp1, (%esp)
 
+       call    escape_analysis_escape_check
 
+       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
-
-       .data
-
-asm_criticalsections:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       .long   _crit_begin1
-       .long   _crit_end1
-       .long   _crit_restart1
-       .long   _crit_begin2
-       .long   _crit_end2
-       .long   _crit_restart2
-#endif
-       .long 0
-
-
-
-/************************ function asm_prepare_native_stackinfo ****************************
-*                                                                                          *
-*    creates a stackfame for the begin of a native function (either builtin or not )       *
-*    expected stack at begin of function                                                   *
-*                                        ....                                              *
-*                   address of the jit call which invokes the native                       *
-*                   begin address of stack frame of the java method                        *
-*                   method pointer or 0 (for built ins)                                    *
-*                   return address                                                         *
-*                                                                                          *
-*    at end of function:                                                                   *
-*                                          ...                                             *
-*                   address of the jit call which invokes the native                       *
-*                   begin address of stack frame of the java method                        *
-*                   method pointer or 0 (for built ins)                                    *
-*                   address of thread specific top of native list                          *
-*                   old value of thread specific head                                      *
-*                   return address                                                         *
-*                                                                                          *
-*                                        ....                                              *
-* This thing is less efficient than the original #define (callerside)                      *
-* destroyes REG_ITMP2, keeps REG_ITMP1                                                     *
-********************************************************************************************/
-
-
-asm_prepare_native_stackinfo:
-        sub $8,%esp
-        mov 8(%esp),%ecx
-        mov %ecx,(%esp)
-        push %eax
-        lea     builtin_asm_get_stackframeinfo,%ecx
-        call    *%ecx
-        mov %eax, 12(%esp)
-        mov (%eax),%ecx
-        mov %ecx,8(%esp)
-        mov %esp,%ecx
-        add $8,%ecx
-        mov %ecx,(%eax)
-        pop %eax
-        ret
-#if 0
-#define PREPARE_NATIVE_STACKINFO \
-    i386_push_reg(cd, REG_ITMP1);       /*save itmp1, needed by some stubs */ \
-    i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
-    i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
-    i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/ \
-    i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
-    i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/ \
-    i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/ \
-    i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4);     /* store value on stack */ \
-    i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
-    i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
-    i386_mov_imm_membase(cd, 0,REG_SP, 2*4);    /* builtin */
 #endif
 
 
-/************************ function asm_remove _native_stackinfo *******************************************
-*                                                                                                         *
-*    creates a stackfame for the begin of a native function (either builtin or not)                       *
-*    expected stack at begin of function                                                                  *
-*                   address of the jit call which invokes the native                                      *
-*                   begin address of stack frame of the java method                                       *
-*                   method pointer or 0 (for built ins)                                                   *
-*                   address thread specific top of native list                                            *
-*                   old value of thread specific head                                                     *
-*                   return address                                                                        *
-*                                                                                                         *
-*    at end of function:                                                                                  *
-*                             ....                                                                        *
-*                   return adresss of the jit call which invokes the native                               *
-*                   return address                                                                        *
-*                                                                                                         *
-*                   REG_ITMP2_XPC = address of the jit call which invokes the native                      *
-*                                                                                                         *
-*                                                                                                         *
-* This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1  *
-***********************************************************************************************************/
-
-asm_remove_native_stackinfo:
-        mov 4(%esp),%ecx
-        mov 8(%esp),%edx
-        mov %ecx,(%edx)
-        pop %edx
-        add $16,%esp
-        push %edx
-       ret
+/* disable exec-stacks ********************************************************/
 
-#if 0
-#define REMOVE_NATIVE_STACKINFO \
-    i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
-    i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
-    i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
+#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
@@ -1425,4 +535,5 @@ asm_remove_native_stackinfo:
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */