* Removed all Id tags.
[cacao.git] / src / vm / jit / i386 / asmpart.S
index 38b38296886b9c28fe38d7dc0a664038c2845436..179fbd038c0022f442e095b5d74c6d12cdd2aa02 100644 (file)
-/* -*- mode: asm; tab-width: 4 -*- */
-/****************************** asmpart.c **************************************
-*                                                                              *
-*   It contains the Java-C interface functions for i386 processors.            *
-*                                                                              *
-*   Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst              *
-*                                                                              *
-*   See file COPYRIGHT for information on usage and disclaimer of warranties   *
-*                                                                              *
-*   Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at            *
-*            Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at            *
-*            Christian Thalinger                                               *
-*                                                                              *
-*   Last Change: $Id: asmpart.S 685 2003-12-04 01:25:54Z jowenn $        *
-*                                                                              *
-*******************************************************************************/
+/* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
 
-#include "offsets.h"
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
+   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+   J. Wenninger, Institut f. Computersprachen - TU Wien
 
-       .text
+   This file is part of CACAO.
 
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
 
-/********************* exported functions and variables ***********************/
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
 
-       .globl has_no_x_instr_set
-       .globl asm_calljavamethod
-       .globl asm_calljavafunction
-        .globl asm_calljavafunction2
-        .globl asm_calljavafunction2long
-        .globl asm_calljavafunction2double
+   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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-       .globl asm_call_jit_compiler
-       .globl asm_dumpregistersandcall
-       .globl asm_handle_builtin_exception
-       .globl asm_handle_nat_exception
-       .globl asm_handle_exception
-       .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_trace
-    .globl asm_builtin_exittrace
-    
-/*************************** imported functions *******************************/
-
-       .globl jit_compile
-       .globl builtin_monitorexit
-       .globl builtin_throw_exception
-       .globl builtin_trace_exception
-       .globl class_java_lang_Object
-       .globl findmethod
-
-/*********************** function has_no_x_instr_set ***************************
-*                                                                              *
-*   determines if the byte support instruction set (21164a and higher)         *
-*   is available.                                                              *
-*                                                                              *
-*   Use it on i386 architecture to init the fpu.                               *
-*                                                                              *
-*******************************************************************************/
+*/
 
-has_no_x_instr_set:
-               finit                         /* intitialize the fpu                  */
 
-               pushl   $0x027f   /* Round to nearest, 53-bit mode, exceptions masked */
-               fldcw   (%esp)
-               addl    $4,%esp
-               
-               xor             %eax,%eax                               /* result code 0 (not used for i386)  */
-               ret
+#include "config.h"
 
+#include "md-asm.h"
 
-/********************* function asm_calljavamethod *****************************
-*                                                                              *
-*   This function calls a Java-method (which possibly needs compilation)       *
-*   with up to 4 parameters.                                                   *
-*                                                                              *
-*   This functions calls the JIT-compiler which eventually translates the      *
-*   method into machine code.                                                  *
-*                                                                              *
-*   An possibly throwed exception will be returned to the caller as function   *
-*   return value, so the java method cannot return a fucntion value (this      *
-*   function usually calls 'main' and '<clinit>' which do not return a         *
-*   function value).                                                           *
-*                                                                              *
-*   C-prototype:                                                               *
-*    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
-*         void *arg1, void *arg2, void *arg3, void *arg4);                     *
-*                                                                              *
-*******************************************************************************/
+#include "vm/jit/i386/arch.h"
+#include "vm/jit/i386/md-abi.h"
 
-#define        MethodPointer   -4
-#define        FrameSize       -8
-#define     IsSync          -12
-#define     IsLeaf          -16
-#define     IntSave         -20
-#define     FltSave         -24
-#define     ExTableSize     -28
-#define     ExTableStart    -28
-
-#define     ExEntrySize     -16
-#define     ExStartPC       -4
-#define     ExEndPC         -8
-#define     ExHandlerPC     -12
-#define     ExCatchType     -16
-
-call_name:
-       .ascii  "calljavamethod\0\0"
-
-/*     .align  3 */
-       .align  8
-       .long   0                         /* catch type all                       */
-       .long   calljava_xhandler         /* handler pc                           */
-       .long   calljava_xhandler         /* end pc                               */
-       .long   asm_calljavamethod        /* start pc                             */
-       .long   1                         /* extable 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_calljavamethod:
-               pushl   %ebp                  /* allocate stack space                 */
-               movl    %esp, %ebp
-
-        push    %ebx                  /* save registers                       */
-        push    %esi
-        push    %edi
-        
-               subl    $32,%esp              /* pass the remaining parameters        */
-               xorl    %edx,%edx
-
-               movl    %edx,28(%esp)         /* convert parms to 8 byte              */
-               movl    24(%ebp),%eax
-               movl    %eax,24(%esp)
-               
-               movl    %edx,20(%esp)
-               movl    20(%ebp),%eax
-               movl    %eax,16(%esp)
+#include "vm/jit/abi-asm.h"
+#include "vm/jit/methodheader.h"
 
-               movl    %edx,12(%esp)
-               movl    16(%ebp),%eax
-               movl    %eax,8(%esp)
 
-               movl    %edx,4(%esp)
-               movl    12(%ebp),%eax
-               movl    %eax,(%esp)
+       .text
 
-               movl    8(%ebp),%eax          /* move function pointer to %eax        */
 
-               lea             asm_call_jit_compiler,%ecx
-               call    *%ecx                 /* call JIT compiler                    */
-               
-calljava_jit:
-calljava_return:
-calljava_ret:
-        add     $32,%esp
-        pop     %edi                 /* restore registers                     */
-        pop     %esi
-        pop     %ebx
-        
-               xorl    %eax,%eax
-               leave                                             /* free stack space                     */
-               ret
-
-calljava_xhandler:
-               pushl   %eax                              /* pass exception pointer               */
-               call    builtin_throw_exception
-               addl    $4,%esp
-        
-               addl    $32,%esp
-        pop     %edi
-        pop     %esi
-        pop     %ebx
-
-        leave
-               ret
+/* export functions ***********************************************************/
 
+       .globl asm_md_init
 
-/********************* 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_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
 
-call_name2:
-       .ascii  "calljavafunction\0\0"
+       .globl asm_call_jit_compiler
+       .globl asm_handle_nat_exception
+       .globl asm_handle_exception
 
-/*     .align  3 */
-       .align  8
-       .long   0                         /* catch type all                       */
-       .long   calljava_xhandler2        /* handler pc                           */
-       .long   calljava_xhandler2        /* end pc                               */
-       .long   asm_calljavafunction      /* start pc                             */
-       .long   1                         /* extable 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:
-               pushl   %ebp                  /* allocate stack space                 */
-               movl    %esp, %ebp
-
-        push    %ebx                  /* save registers                       */
-        push    %esi
-        push    %edi
-        
-               subl    $32,%esp              /* pass the remaining parameters        */
-               xorl    %edx,%edx
-
-               movl    %edx,28(%esp)         /* convert parms to 8 byte              */
-               movl    24(%ebp),%eax
-               movl    %eax,24(%esp)
-               
-               movl    %edx,20(%esp)
-               movl    20(%ebp),%eax
-               movl    %eax,16(%esp)
-
-               movl    %edx,12(%esp)
-               movl    16(%ebp),%eax
-               movl    %eax,8(%esp)
-
-               movl    %edx,4(%esp)
-               movl    12(%ebp),%eax
-               movl    %eax,(%esp)
-
-               movl    8(%ebp),%eax          /* move function pointer to %eax        */
-
-               lea             asm_call_jit_compiler,%ecx 
-               call    *%ecx                 /* call JIT compiler                    */
-       
-calljava_jit2:
-calljava_return2:
-calljava_ret2:
-        add     $32,%esp
-        pop     %edi                 /* restore registers                     */
-        pop     %esi
-        pop     %ebx
-               leave
-               ret
-
-calljava_xhandler2:
-               pushl   %eax                              /* pass exception pointer               */
-               call    builtin_throw_exception
-               addl    $4,%esp
-
-               addl    $32,%esp
-        pop     %edi                 /* restore registers                     */
-        pop     %esi
-        pop     %ebx
-        leave
-               ret
-                                               
+       .globl asm_abstractmethoderror
 
+       .globl asm_patcher_wrapper
 
-/********************* 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_REPLACEMENT)
+       .globl asm_replacement_out
+       .globl asm_replacement_in
+#endif
 
-call_name3:
-       .ascii  "calljavafunction2\0\0"
+       .globl asm_builtin_f2i
+       .globl asm_builtin_f2l
+       .globl asm_builtin_d2i
+       .globl asm_builtin_d2l
 
-/*     .align  3 */
-       .align  8
-       .long   0                         /* catch type all                       */
-       .long   calljava_xhandler3        /* handler pc                           */
-       .long   calljava_xhandler3        /* end pc                               */
-       .long   asm_calljavafunction2      /* start pc                             */
-       .long   1                         /* extable size                         */
-       .long   0                         /* fltsave                              */
-       .long   0                         /* intsave                              */
-       .long   0                         /* isleaf                               */
-       .long   0                         /* IsSync                               */
-       .long   32                        /* frame size                           */
-                       .long   0                         /* method pointer (pointer to name)     */
+       .globl asm_compare_and_swap
+       .globl asm_memory_barrier
+
+       .globl asm_get_cycle_count
+
+
+/* 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
 
-/********************* 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);                     *
-*                                                                              *
 *******************************************************************************/
 
-call_name4:
-       .ascii  "calljavafunction2double\0\0"
+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
 
-/*     .align  3 */
-       .align  8
-       .long   0                         /* catch type all                       */
-       .long   calljava_xhandler3        /* handler pc                           */
-       .long   calljava_xhandler3        /* end pc                               */
-       .long   asm_calljavafunction2double      /* start pc                             */
-       .long   1                         /* extable size                         */
-       .long   0                         /* fltsave                              */
-       .long   0                         /* intsave                              */
-       .long   0                         /* isleaf                               */
-       .long   0                         /* IsSync                               */
-       .long   32                        /* frame size                           */
-                       .long   0                         /* method pointer (pointer to name)     */
 
 /********************* function asm_calljavafunction ***************************
 *                                                                              *
@@ -352,898 +111,563 @@ call_name4:
 *   method into machine code.                                                  *
 *                                                                              *
 *   C-prototype:                                                               *
-*    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
-*         void *arg1, void *arg2, void *arg3, void *arg4);                     *
+*    javaobject_header *asm_vm_call_method(methodinfo *m,                      *
+*         u4 count, u4 size, void *callblock);                                 *
 *                                                                              *
 *******************************************************************************/
 
-call_name5:
-       .ascii  "calljavafunction2long\0\0"
-
-/*     .align  3 */
        .align  8
-       .long   0                         /* catch type all                       */
-       .long   calljava_xhandler3        /* handler pc                           */
-       .long   calljava_xhandler3        /* end pc                               */
-       .long   asm_calljavafunction2long      /* start pc                             */
-       .long   1                         /* extable 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:
-               pushl   %ebp                  /* save ebp */
-               
-
-               movl    %esp,%eax /*save stackptr*/
-               movl    20(%esp),%ebp
-               subl    $32,%esp
-
-                movl    sizejniblock*3+offjniitem+4(%ebp),%ebx
-                movl    %ebx,28(%esp)
-                movl    sizejniblock*3+offjniitem(%ebp),%ebx
-                movl    %ebx,24(%esp)
-
-                movl    sizejniblock*2+offjniitem+4(%ebp),%ebx
-                movl    %ebx,20(%esp)
-                movl    sizejniblock*2+offjniitem(%ebp),%ebx
-                movl    %ebx,16(%esp)
 
+       .long   0                           /* catch type all                     */
+       .long   0                           /* handler pc                         */
+       .long   0                           /* end pc                             */
+       .long   0                           /* 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   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 stackptr                      */
+       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
+
+asm_vm_call_method_exception_handler:
+       push    xptr                        /* pass exception pointer             */
+       call    builtin_throw_exception
+       add     $4,sp
+asm_vm_call_method_end:
+       jmp     L_asm_vm_call_method_return
+
+
+/* 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.
 
-                movl    sizejniblock+offjniitem+4(%ebp),%ebx
-                movl    %ebx,12(%esp)
-                movl    sizejniblock+offjniitem(%ebp),%ebx
-                movl    %ebx,8(%esp)
-
-                movl    offjniitem+4(%ebp),%ebx
-                movl    %ebx,4(%esp)
-                movl    offjniitem(%ebp),%ebx
-                movl    %ebx,0(%esp)
-
-               movl    %eax,%ebp       
-               movl    8(%ebp),%eax          /* move function pointer to %eax        */
+*******************************************************************************/
 
-               lea             asm_call_jit_compiler,%ecx 
-               call    *%ecx                 /* call JIT compiler                    */
-       
-calljava_jit3:
-calljava_return3:
-calljava_ret3:
-               leave
-               ret
+asm_call_jit_compiler:
+L_asm_call_jit_compiler:                /* required for PIC code              */
+       sub     $(4*4),sp                   /* keep stack 16-byte aligned         */
 
-calljava_xhandler3:
-               pushl   %eax                              /* pass exception pointer               */
-               call    builtin_throw_exception
-               addl    $4,%esp
-               addl    $32,%esp
-               popl    %ebp
-               ret
+       mov     itmp1,0*4(sp)               /* pass methodinfo pointer            */
+       mov     mptr,1*4(sp)                /* pass method pointer                */
+       mov     sp,itmp2                    /* pass java sp                       */
+       add     $((1+4)*4),itmp2
+       mov     itmp2,2*4(sp)
+       mov     4*4(sp),itmp3               /* pass java ra                       */
+       mov     itmp3,3*4(sp)
+       call    jit_asm_compile
 
+       add     $(4*4),sp                   /* remove stack frame                 */
 
+       test    v0,v0                       /* check for exception                */
+       je      L_asm_call_jit_compiler_exception
 
+       jmp             *v0                         /* ...and now call the new method     */
 
+L_asm_call_jit_compiler_exception:
+       call    exceptions_get_and_clear_exception
+                                           /* v0 == xptr                         */
+       pop     xpc                         /* get return address                 */
+       sub     $2,xpc                      /* faulting address is ra - 2         */
+       jmp     L_asm_handle_exception
 
 
-/****************** 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)                                                   *
+/* asm_handle_exception ********************************************************
 *                                                                              *
-*   in the static case the method pointer can be computed using the            *
-*   return address and the lda function following the jmp instruction          *
+*   This function handles an exception. It does not use the usual calling      *
+*   conventions. The exception pointer is passed in REG_ITMP1 and the          *
+*   pc from the exception raising position is passed in REG_ITMP2. It searches *
+*   the local exception table for a handler. If no one is found, it unwinds    *
+*   stacks and continues searching the callers.                                *
 *                                                                              *
 *******************************************************************************/
 
-
-asm_call_jit_compiler:
-        push    %ecx
-               push    %ebx            /* save register                              */
-        push    %ebp
-                               
-               mov     12(%esp),%ebp   /* get return address (2 push)                */
-               mov     -1(%ebp),%bl    /* get function code                          */
-               cmp     $0xd2,%bl               /* called with `call *REG_ITMP2' (%edx)?      */
-               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
+asm_handle_nat_exception:
+       add     $4,sp                       /* clear return address of native stub*/
                
-               sub     $6,%ebp         /* calculate address of offset                */
-               mov     (%ebp),%ebp     /* get offset                                 */
-               add     %edx,%ebp       /* add base address to get method address     */
-               jmp             L_call_jit_compile
+asm_handle_exception:
+L_asm_handle_exception:                 /* required for PIC code              */
+       sub     $((ARG_CNT+TMP_CNT+3)*4),sp /* keep stack 16-byte aligned         */
 
-L_not_virtual_interface:        /* a call from asm_calljavamethod             */
-               xor     %ebp,%ebp
-               
-L_call_jit_compile:
-               push    %ebp            /* save address for method pointer            */
+       SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
+       SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
 
-               push    %eax                    /* push methodpointer on stack                */
-               call    jit_compile
-               add     $4,%esp
+       mov     $((ARG_CNT+TMP_CNT+3)*4),itmp3 /* prepare a3 for handle_exception */
+       mov     $1,t0                       /* set maybe-leaf flag                */
 
-               pop     %ebp            /* restore address for method pointer         */
-               test    %ebp,%ebp               /* is address == 0 (asm_calljavamethod)       */
-               je              L_call_method
-               
-               mov     %eax,(%ebp)             /* and now save the new pointer               */
+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               */
 
-L_call_method:
-        pop     %ebp
-               pop     %ebx            /* restore registers                          */
-        pop     %ecx
-                       
-               jmp             *%eax                   /* ...and now call the new method             */
+       mov     xpc,0*4(sp)                 /* pass exception pc                  */
+       call    codegen_get_pv_from_pc
+       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)
+       call    exceptions_handle_exception
 
+       test    v0,v0
+       jz      L_asm_handle_exception_not_catched
 
-/****************** function asm_dumpregistersandcall **************************
-*                                                                              *
-*   This funtion saves all callee saved registers and calls the function       *
-*   which is passed as parameter.                                              *
-*                                                                              *
-*   This function is needed by the garbage collector, which needs to access    *
-*   all registers which are stored on the stack. Unused registers are          *
-*   cleared to avoid interferances with the GC.                                *
-*                                                                              *
-*   void asm_dumpregistersandcall (functionptr f);                             *
-*                                                                              *
-*******************************************************************************/
+       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_dumpregistersandcall:
-        xor     %eax,%eax
-        mov     %eax,(%eax)
-        
-               push    %ebx
-               push    %ebp
-               push    %esi
-               push    %edi
-                               
-               mov     8(%ebp),%eax            /* load function pointer */
-               call    *%eax                           /* call function */
-
-               pop             %edi
-               pop             %esi
-               pop             %ebp
-               pop             %ebx
-               
-               ret
-        
+       test    t0,t0                       /* test for maybe-leaf flag           */
+       jz      L_asm_handle_exception_no_leaf
 
-/********************* function 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          *
-*   pc from the exception raising position is passed in REG_ITMP2. It searches *
-*   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);                     *
-*                                                                              *
-*******************************************************************************/
+       RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
+       RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
 
-asm_handle_builtin_exception:
-        add     $4,%esp                                                /* clear return address of this call */
-        mov     (%esp),%eax                 /* get exceptionptr               */
-        leave                               /* leave builtin function         */
-        mov     (%esp),%edx                 /* get exceptionpc                */
-        sub     $2,%edx                     /* size of builtin call           */
-        jmp     asm_handle_exception
-        
-asm_handle_nat_exception:
-               add     $4,%esp                                         /* clear return address of native stub */
-               
-asm_handle_exception:
-               push    %eax
-               push    %edx                                            /* get the data segment ptr       */
-               call    findmethod
-               mov     %eax,%ecx
-               pop     %edx
-               pop     %eax
-
-               push    %ebp
-               mov     %esp,%ebp
-
-               push    %eax                                            /* save exception pointer         */
-/*             subl    $2,%edx */
-               push    %edx                                            /* save exception pc              */
-               push    %ecx                                            /* save data segment pointer      */
-        
-               push    %ebx
-               push    %esi
-               push    %edi
-               
-ex_stack_loop:
-               sub     $16,%esp
+       add     $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe       */
 
-               movl    %eax,(%esp)                                     /* exception pointer */
+L_asm_handle_exception_no_leaf:
+       jmp     *xpc                        /* jump to exception handler          */
 
-               movl    MethodPointer(%ecx),%eax        /* method pointer */
-               movl    %eax,4(%esp)
-               
-               movl    %edx,8(%esp)                            /* exception pc */
-               movl    $1,12(%esp)                                     /* set no unwind flag */
-               call    builtin_trace_exception
+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                    */
 
-               addl    $16,%esp
+       test    t0,t0
+       jz      L_asm_handle_exception_no_leaf_stack
 
-               movl    -12(%ebp),%esi                          /* %esi = data segment pointer */
-               movl    ExTableSize(%esi),%ecx          /* %ecx = exception table size */
-               test    %ecx,%ecx                                       /* if empty table skip */
-               je              empty_table
+       add     $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe       */
+       xor     t0,t0                       /* clear the maybe-leaf flag          */
 
-               lea             ExTableStart(%esi),%edi         /* %edi = start of exception table */
-               movl    -4(%ebp),%eax                           /* get xptr */
-               
-ex_table_loop:
-               movl    -8(%ebp),%edx                           /* get xpc */
-               
-               movl    ExStartPC(%edi),%ebx            /* %ebx = exception start pc */
-               cmpl    %edx,%ebx                                       /* %ebx = (startpc <= xpc) */
-               jg              ex_table_cont                           /* if (false) continue */
-               movl    ExEndPC(%edi),%ebx                      /* %ebx = exception end pc */
-               cmpl    %ebx,%edx                                       /* %ebx = (xpc < endpc) */
-               jge             ex_table_cont                           /* if (false) continue */
-               movl    ExCatchType(%edi),%ebx          /* arg1 = exception catch type */
-               test    %ebx,%ebx                                       /* NULL catches everything */
-               je              ex_handle_it
-
-               movl    offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr) */
-               movl    offclassvftbl(%ebx),%ebx                /* %ebx = vftblptr(catchtype) class (not obj) */
-               movl    offbaseval(%esi),%esi           /* %esi = baseval(xptr) */
-               movl    offbaseval(%ebx),%edx           /* %edx = baseval(catchtype) */
-               movl    offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype) */
-               subl    %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
-               cmpl    %ebx,%esi                                       /* xptr is instanceof catchtype */
-               ja              ex_table_cont
-               
-ex_handle_it:
-               movl    ExHandlerPC(%edi),%edx
-               
-               popl    %edi
-               popl    %esi
-               popl    %ebx
-        
-        popl    %eax                        /* pop %ecx (dummy) */
-        popl    %eax                        /* pop %edx (dummy) */
-        popl    %eax                        /* pop %eax */
-        
-               leave
-
-               jmp             *%edx
-
-ex_table_cont:
-               lea             ExEntrySize(%edi),%edi
-               decl    %ecx
-               test    %ecx,%ecx
-               jg              ex_table_loop
-               
-empty_table:
-               popl    %edi
-               popl    %esi
-               popl    %ebx
-               popl    %ecx                                            /* restore data segment pointer   */
-               popl    %edx
-               popl    %eax                                            /* restore exception pointer      */
-               popl    %ebp
-
-               movl    %eax,%edi                                       /* save exception pointer         */
-                               
-ex_already_cleared:            
-               movl    IsSync(%ecx),%eax                       /* %eax = SyncOffset              */
-               test    %eax,%eax                                       /* if zero no monitorexit         */
-               je              no_monitor_exit
-               
-               addl    %esp,%eax
-               movl    -8(%eax),%eax
-        pusha                               /* save regs                      */
-               pushl   %eax
-               call    builtin_monitorexit
-               addl    $4,%esp
-        popa                                /* restore regs                   */
-        
-no_monitor_exit:
-               movl    FrameSize(%ecx),%eax            /* %eax = frame size              */
-               addl    %eax,%esp                                       /* unwind stack                   */
-               movl    %esp,%eax                                       /* %eax = pointer to save area    */
-
-               movl    IntSave(%ecx),%edx                      /* %edx = saved int register count */
-               test    %edx,%edx
-               je              noint
-               cmpl    $1,%edx
-               je              int1
-               
-int2:  
-               movl    -16(%eax),%ebx
+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            */
+
+       mov     IntSave(itmp3),itmp1        /* itmp1 = saved int register count   */
+       test    itmp1,itmp1
+       je      noint
 
+       cmp     $1,itmp1
+       je      int1
+       cmp     $2,itmp1
+       je      int2
+
+       mov     -3*8(itmp2),s0
+int2:  
+       mov     -2*8(itmp2),s1
 int1:  
-               movl    -8(%eax),%ebp
+       mov     -1*8(itmp2),s2
 
-               shll    $3,%edx                                         /* multiply by 8 bytes             */
-               subl    %edx,%eax
+       shl     $2,itmp1                    /* multiply by 4 bytes                */
+       sub     itmp1,itmp2
                
 noint:
-               movl    FltSave(%ecx),%edx                      /* %edx = saved flt register count */
-               test    %edx,%edx
-               je              noflt
-               cmpl    $1,%edx
-               je              flt1
-               cmpl    $2,%edx
-               je              flt2
-               cmpl    $3,%edx
-               je              flt3
-               
-flt4:  
-               fldl    -32(%eax)
-               fstp    %st(1)
+#if 0
+       mov     FltSave(itmp3),itmp1        /* itmp1 = saved flt register count   */
+       test    itmp1,itmp1
+       je      noflt
 
-flt3:  
-               fldl    -24(%eax)
-               fstp    %st(2)
-               
-flt2:  
-               fldl    -16(%eax)
-               fstp    %st(3)
-               
-flt1:  
-               fldl    -8(%eax)
-               fstp    %st(4)
-               
-noflt:                                 
-               popl    %edx                                            /* the new xpc is return address  */
-               subl    $2,%edx
-               
-               pushl   %edx
-               pushl   %ebx
-               pushl   %ebp
-               pushl   %esi
-               pushl   %edi
-                                                               
-               pushl   %edx                                            /* get the new data segment ptr   */
-               call    findmethod
-               movl    %eax,%ecx
-               addl    $4,%esp
-
-               popl    %edi
-               popl    %esi
-               popl    %ebp
-               popl    %ebx
-               popl    %edx
+       cmp     $1,itmp1
+       je      flt1
+       cmp     $2,itmp1
+       je      flt2
+       cmp     $3,itmp1
+       je      flt3
                
-               movl    %edi,%eax                                       /* restore saved exception pointer */
-                               
-               pushl   %ebp
-               movl    %esp,%ebp
-
-               pushl   %eax                                            /* save exception pointer         */
-               pushl   %edx                                            /* save exception pc              */
-               pushl   %ecx                                            /* save data segment pointer      */
-               pushl   %ebx
-               pushl   %esi
-               pushl   %edi
-               
-               jmp             ex_stack_loop
+       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                       */
 
-/********************* function asm_builtin_monitorenter ***********************
-*                                                                              *
-*   Does null check and calls monitorenter or throws an exception              *
-*                                                                              *
-*******************************************************************************/
+       pop     xpc                         /* the new xpc is return address      */
+       sub     $2,xpc                      /* subtract 2-bytes for call          */
 
-asm_builtin_monitorenter:
-               cmpl    $0,4(%esp)
-               je              nb_monitorenter                 /* if (null) throw exception          */
-               jmp             builtin_monitorenter    /* else call builtin_monitorenter     */
+       xor     itmp3,itmp3                 /* prepare a3 for handle_exception    */
 
-nb_monitorenter:
-               popl    %edx                                    /* delete return address */
-               subl    $2,%edx                                 /* faulting address is return adress - 2 */
-               movl    proto_java_lang_NullPointerException,%eax
-               jmp             asm_handle_exception
+       jmp     L_asm_handle_exception_stack_loop
                
 
-/********************* function asm_builtin_monitorexit ************************
-*                                                                              *
-*   Does null check and calls monitorexit or throws an exception               *
-*                                                                              *
+/* asm_abstractmethoderror *****************************************************
+
+   Creates and throws an AbstractMethodError.
+
 *******************************************************************************/
 
-asm_builtin_monitorexit:
-               cmpl    $0,4(%esp)
-               je              nb_monitorexit                  /* if (null) throw exception          */
-               jmp             builtin_monitorexit             /* else call builtin_monitorenter     */
+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)
+       call    exceptions_asm_new_abstractmethoderror
+                                           /* exception pointer is return value  */
+       add     $(3*4),sp                   /* remove stack frame                 */
 
-nb_monitorexit:
-               popl    %edx                                    /* delete return address */
-               subl    $2,%edx                                 /* faulting address is return adress - 2 */
-               movl    proto_java_lang_NullPointerException,%eax
-               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_ldiv ****************************
-*                                                                              *
-*   Does null check and calls ldiv or throws an exception                      *
-*                                                                              *
+/* asm_patcher_wrapper *********************************************************
+
+   XXX
+
+   Stack layout:
+     24   return address
+     20   REG_ITMP3
+     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
+
 *******************************************************************************/
 
-asm_builtin_ldiv:
-               movl    12(%esp),%eax
-               orl             16(%esp),%eax
-               test    %eax,%eax                               /* if (null) throw exception */
-               je              nb_ldiv
+asm_patcher_wrapper:
+       sub     $((1+4+4)*4),sp             /* keep stack 16-byte aligned         */
 
-               jmp             builtin_ldiv
+       mov     itmp1,(0+4)*4(sp)           /* save itmp1 and itmp2               */
+       mov     itmp2,(1+4)*4(sp)
 
-nb_ldiv:
-               popl    %edx                                    /* delete return address */
-               subl    $2,%edx                                 /* faulting address is return adress - 2 */
-               
-               movl    proto_java_lang_ArithmeticException,%eax
-               jmp             asm_handle_exception
-                               
+       mov     sp,itmp1                    /* pass SP of patcher stub            */
+       add     $((1+4+4)*4),itmp1
+       mov     itmp1,0*4(sp)
+       movl    $0,1*4(sp)                  /* pass PV (if NULL, use findmethod)  */
+       movl    $0,2*4(sp)                  /* pass RA (it's on the stack)        */
+       call    patcher_wrapper
+       mov     v0,itmp3                    /* save return value                  */
 
-/************************ function asm_builtin_lrem ****************************
-*                                                                              *
-*   Does null check and calls lrem or throws an exception                      *
-*                                                                              *
-*******************************************************************************/
+       mov     (0+4)*4(sp),itmp1           /* restore itmp1 and itmp2            */
+       mov     (1+4)*4(sp),itmp2
 
-asm_builtin_lrem:
-               movl    12(%esp),%eax
-               orl             16(%esp),%eax
-               test    %eax,%eax                               /* if (null) throw exception */
-               je              nb_lrem
+       test    itmp3,itmp3                 /* exception thrown?                  */
+       jne     L_asm_patcher_wrapper_exception
 
-               jmp             builtin_lrem
+       mov     (5+1+4+4)*4(sp),itmp3       /* restore itmp3                      */
+       add     $((6+1+4+4)*4),sp           /* remove stack frame, keep RA        */
 
-nb_lrem:
-               popl    %edx                                    /* delete return address */
-               subl    $2,%edx                                 /* faulting address is return adress - 2 */
-               
-               movl    proto_java_lang_ArithmeticException,%eax
-               jmp             asm_handle_exception
-               
+       ret                                 /* jump to new patched code           */
 
-/************************ function asm_builtin_x2x *****************************
-*                                                                              *
-*   Wrapper functions for corner cases                                         *
-*                                                                              *
-*******************************************************************************/
+L_asm_patcher_wrapper_exception:
+       add     $((6+1+4+4)*4),sp           /* remove stack frame, keep RA        */
+       mov     itmp3,xptr                  /* get exception                      */
+       pop     xpc                         /* get and remove return address      */
+       jmp     L_asm_handle_exception
 
-asm_builtin_f2i:
-        sub     $4,%esp
-        fsts    (%esp)
-        call    builtin_f2i
-        add     $4,%esp
-        ret            
+#if defined(ENABLE_REPLACEMENT)
 
-asm_builtin_d2i:
-        sub     $8,%esp
-        fstl    (%esp)
-        call    builtin_d2i
-        add     $8,%esp
-        ret            
+/* asm_replacement_out *********************************************************
 
-asm_builtin_f2l:
-        sub     $4,%esp
-        fsts    (%esp)
-        call    builtin_f2l
-        add     $4,%esp
-        ret            
+   This code is jumped to from the replacement-out stubs that are executed
+   when a thread reaches an activated replacement point.
 
-asm_builtin_d2l:
-        sub     $8,%esp
-        fstl    (%esp)
-        call    builtin_d2l
-        add     $8,%esp
-        ret            
-
-        
-/*********************** function new_builtin_checkcast ************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
-*******************************************************************************/
+   The purpose of asm_replacement_out is to read out the parts of the
+   execution state that cannot be accessed from C code, store this state,
+   and then call the C function replace_me.
 
-asm_builtin_checkcast:
-               xorl    %eax,%eax
-               movl    $0,(%eax)
-               ret
+   Stack layout:
+      4                 start of stack inside method to replace
+      0   rplpoint *    info on the replacement point that was reached
 
-               
-/******************* function asm_builtin_checkarraycast ***********************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
 *******************************************************************************/
 
-asm_builtin_checkarraycast:
-               subl    $8,%esp                                 /* build stack frame (2 * 4 bytes)    */
+/* some room to accomodate changes of the stack frame size during replacement */
+       /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM  512
 
-               movl    12(%esp),%eax           /* 8 (frame) + 4 (return)             */
-               movl    %eax,(%esp)                             /* save object pointer                */
+asm_replacement_out:
+    /* create stack frame */
+       sub     $(sizeexecutionstate + REPLACEMENT_ROOM),sp
 
-               movl    20(%esp),%eax
-               movl    %eax,4(%esp)
+       /* save registers in execution state */
+       mov     %eax,(EAX*4+offes_intregs)(sp)
+       mov     %ebx,(EBX*4+offes_intregs)(sp)
+       mov     %ecx,(ECX*4+offes_intregs)(sp)
+       mov     %edx,(EDX*4+offes_intregs)(sp)
+       mov     %esi,(ESI*4+offes_intregs)(sp)
+       mov     %edi,(EDI*4+offes_intregs)(sp)
+       mov     %ebp,(EBP*4+offes_intregs)(sp)
+       movl    $0  ,(ESP*4+offes_intregs)(sp) /* not used */
 
-               call    builtin_checkarraycast  /* builtin_checkarraycast             */
-       
-               test    %eax,%eax               /* if (false) throw exception         */
-               je              nb_carray_throw
+       /* calculate sp of method */
+       mov     sp,itmp1
+       add     $(sizeexecutionstate + REPLACEMENT_ROOM + 4),itmp1
+       mov     itmp1,(offes_sp)(sp)
 
-               movl    12(%esp),%eax                   /* return object pointer              */
-               addl    $8,%esp
-               ret
+       /* pv must be looked up via AVL tree */
+       movl    $0,(offes_pv)(sp)
 
-nb_carray_throw:
-               addl    $8,%esp
-               
-               popl    %edx                                    /* delete return address              */
-               subl    $2,%edx                                 /* faulting address is return adress - 2 */
-               
-               movl    proto_java_lang_ClassCastException,%eax
-               jmp             asm_handle_exception
+       /* call replace_me */
+       mov     -4(itmp1),itmp1             /* rplpoint *                         */
+    push    sp                          /* arg1: execution state              */
+    push    itmp1                       /* arg0: replacement point            */
+    call    replace_me                  /* call C function replace_me         */
 
-               
-/******************* function asm_builtin_newarray *****************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
-*******************************************************************************/
 
-asm_builtin_newarray:
-               subl    $8,%esp                                 /* build stack frame (2 * 4 bytes) */
+/* asm_replacement_in **********************************************************
 
-               movl    12(%esp),%eax
-               movl    %eax,(%esp)
+   This code writes the given execution state and jumps to the replacement
+   code.
 
-               movl    20(%esp),%eax
-               movl    %eax,4(%esp)
+   This function never returns!
 
-               call    builtin_newarray
-       
-               addl    $8,%esp
-               ret
+   C prototype:
+      void asm_replacement_in(executionstate *es, replace_safestack_t *st);
 
-               
-/******************* function asm_builtin_aastore ******************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
 *******************************************************************************/
 
-asm_builtin_aastore:
-               subl    $12,%esp                                /* build stack frame (3 * 4 bytes)    */
+asm_replacement_in:
+       /* get arguments */
+       mov     8(sp),%esi                  /* replace_safestack_t *st            */
+       mov     4(sp),%ebp                  /* executionstate *es == safe stack   */
 
-               movl    16(%esp),%eax           /* 12 (frame) + 4 (return)            */
-               test    %eax,%eax                               /* if null pointer throw exception    */
-               je              nb_aastore_null
+       /* switch to the safe stack and build a stack frame */
+       mov     %ebp,sp
+       sub             $(1*4),sp
 
-               movl    offarraysize(%eax),%edx /* load size                          */
-               movl    24(%esp),%ecx                   /* index                              */
-               cmpl    %edx,%ecx                               /* do bound check                     */
-               ja              nb_aastore_bound                /* if out of bounds throw exception   */
+       /* call replace_build_execution_state(st) */
+       mov             %esi,(0*4)(sp)
+       call    replace_build_execution_state
 
-               shll    $2,%ecx                                 /* index * 4                          */
-               addl    %eax,%ecx                               /* add index * 4 to arrayref          */
-               
-               movl    %ecx,8(%esp)                    /* save store position                */
-               
-               movl    16(%esp),%eax           /* 12 (frame) + 4 (return)            */
-               movl    %eax,(%esp)
+       /* set new sp */
+       mov     (offes_sp)(%ebp),sp
 
-               movl    32(%esp),%eax                   /* object is second argument          */
-               movl    %eax,4(%esp)
-               
-               call    builtin_canstore                /* builtin_canstore(arrayref,object)  */
-
-               test    %eax,%eax                               /* if (false) throw exception         */
-               je              nb_aastore_throw
-
-               movl    32(%esp),%eax
-               movl    8(%esp),%ecx
-               movl    %eax,offobjarrdata(%ecx)/* store objectptr in array           */
-               
-               addl    $12,%esp
-               ret
+       /* push address of new code */
+       push    (offes_pc)(%ebp)
 
-nb_aastore_null:
-               addl    $12,%esp
-               popl    %edx                                    /* delete return address */
-               subl    $2,%edx                                 /* faulting address is return adress - 2 */
-               
-               movl    proto_java_lang_NullPointerException,%eax
-               jmp             asm_handle_exception
+       /* allocate an executionstate_t on the stack */
+       sub             $(sizeexecutionstate),sp
 
-nb_aastore_bound:
-               addl    $12,%esp
-               popl    %edx                                    /* delete return address */
-               subl    $2,%edx                                 /* faulting address is return adress - 2 */
-               
-               movl    proto_java_lang_ArrayIndexOutOfBoundsException,%eax
-               jmp             asm_handle_exception
-               
-nb_aastore_throw:
-               addl    $12,%esp
-               popl    %edx                                    /* delete return address */
-               subl    $2,%edx                                 /* faulting address is return adress - 2 */
-               
-               movl    proto_java_lang_ArrayStoreException,%eax
-               jmp             asm_handle_exception
+       /* call replace_free_safestack(st,& of allocated executionstate_t) */
+       push    sp   /* tmpes */
+       push    %esi /* st    */
+       call    replace_free_safestack
+       add     $(2*4),sp
 
-               
-/******************* function asm_builtin_arrayinstanceof **********************
-*                                                                              *
-*   Does the instanceof check of arrays                                        *
-*                                                                              *
-*******************************************************************************/
+       /* copy registers from execution state */
+       mov     (EAX*4+offes_intregs)(sp),%eax
+       mov     (EBX*4+offes_intregs)(sp),%ebx
+       mov     (ECX*4+offes_intregs)(sp),%ecx
+       mov     (EDX*4+offes_intregs)(sp),%edx
+       mov     (ESI*4+offes_intregs)(sp),%esi
+       mov     (EDI*4+offes_intregs)(sp),%edi
+       mov     (EBP*4+offes_intregs)(sp),%ebp
 
-asm_builtin_arrayinstanceof:
-               subl    $8,%esp                                 /* build stack frame (2 * 4 bytes) */
+       /* pop the execution state off the stack */
+       add             $(sizeexecutionstate),sp
 
-               movl    12(%esp),%eax
-               movl    %eax,(%esp)
+       /* jump to new code, hold your thumbs! ;) */
+       ret
 
-               movl    20(%esp),%eax
-               movl    %eax,4(%esp)
+#endif /* defined(ENABLE_REPLACEMENT) */
 
-               call    builtin_arrayinstanceof
-       
-               addl    $8,%esp
-               ret
 
-               
-/******************* function asm_initialize_thread_stack **********************
+/************************ function asm_builtin_x2x *****************************
 *                                                                              *
-* initialized a thread stack                                                   *
-* (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
+*   Wrapper functions for corner cases                                         *
 *                                                                              *
 *******************************************************************************/
 
-asm_initialize_thread_stack:
-               movl    8(%esp),%eax            /* (to)->stackEnd                     */
-               subl    $36,%eax                                /* 4 bytes * 8 regs + 4 bytes func    */
+asm_builtin_f2i:
+       sub     $(3*4),%esp
+       fsts    (%esp)
+       call    builtin_f2i
+       add     $(3*4),%esp
+       ret
 
-               xorl    %edx,%edx
-               movl    %edx,0(%eax)
-               movl    %edx,4(%eax)
-               movl    %edx,8(%eax)
-               movl    %edx,12(%eax)
-               movl    %edx,16(%eax)
-               movl    %edx,20(%eax)
-               movl    %edx,24(%eax)
-               movl    %edx,28(%eax)
+asm_builtin_d2i:
+       sub     $(3*4),%esp
+       fstl    (%esp)
+       call    builtin_d2i
+       add     $(3*4),%esp
+       ret
 
-               movl    4(%esp),%edx            /* save (u1*) (func)                  */
-               movl    %edx,32(%eax)
+asm_builtin_f2l:
+       sub     $(3*4),%esp
+       fsts    (%esp)
+       call    builtin_f2l
+       add     $(3*4),%esp
+       ret
 
-               ret                             /* return restorepoint in %eax        */
+asm_builtin_d2l:
+       sub     $(3*4),%esp
+       fstl    (%esp)
+       call    builtin_d2l
+       add     $(3*4),%esp
+       ret
 
 
-/******************* function asm_perform_threadswitch *************************
-*                                                                              *
-*   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
-*                                                                              *
-*   performs a threadswitch                                                    *
-*                                                                              *
-*******************************************************************************/
+/* asm_compare_and_swap ********************************************************
 
-asm_perform_threadswitch:
-               subl    $36,%esp
-
-               movl    %eax,0(%esp)
-               movl    %edx,4(%esp)
-               movl    %ecx,8(%esp)
-               movl    %ebx,12(%esp)
-               movl    %esp,16(%esp)
-               movl    %ebp,20(%esp)
-               movl    %esi,24(%esp)
-               movl    %edi,28(%esp)
-
-               movl    36(%esp),%eax                   /* save current return address */
-               movl    %eax,32(%esp)
-
-               movl    40(%esp),%eax                   /* first argument **from */
-               movl    %esp,0(%eax)
-
-               movl    48(%esp),%eax                   /* third argument **stackTop */
-               movl    %esp,0(%eax)
-
-               movl    44(%esp),%eax                   /* second argument **to */
-               movl    0(%eax),%esp                    /* load new stack pointer */
-
-               movl    0(%esp),%eax
-               movl    4(%esp),%edx
-               movl    8(%esp),%ecx
-               movl    12(%esp),%ebx
-                                                                               /* skip stack pointer */
-               movl    20(%esp),%ebp
-               movl    24(%esp),%esi
-               movl    28(%esp),%edi
-
-               addl    $32,%esp                /* leave return address on stack      */
-               ret
-               
+   Does an atomic compare and swap.  Required for the lock
+   implementation.
 
-/********************* 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                *
-*                                                                              *
-*******************************************************************************/
+   Atomically do the following: Check if the location still contains
+   `oldval`. If so, replace it by `newval` and return `oldval`.
 
-asm_switchstackandcall:
-               movl    4(%esp),%edx                    /* first argument *stack */
-               subl    $8,%edx                                 /* allocate new stack */
+   RETURN VALUE:
+       the old value at *p
 
-               movl    (%esp),%eax                             /* save return address on new stack */
-               movl    %eax,(%edx)
+   long compare_and_swap(volatile long *p, long oldval, long newval);
 
-               movl    %esp,4(%edx)                    /* save old stack pointer on new stack */
+*******************************************************************************/
 
-               movl    12(%esp),%eax                   /* third argument **stacktopsave */
-               movl    %esp,(%eax)                             /* save old stack pointer to variable */
+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
 
-               movl    8(%esp),%eax                    /* load function pointer */
-               movl    16(%esp),%ecx                   /* fourth argument *p */
-               
-               movl    %edx,%esp                               /* switch to new stack */
 
-               subl    $4,%esp
-               movl    %ecx,0(%esp)                    /* pass pointer */
-               call    *%eax                                   /* and call function */
-               addl    $4,%esp
+/* asm_memory_barrier **********************************************************
 
-               movl    (%esp),%edx                             /* load return address */
-               movl    4(%esp),%esp                    /* switch to old stack */
-               movl    %edx,(%esp)
-               ret
+   A memory barrier for the Java Memory Model.
 
-               
-/********************* function asm_getcallingmethod ***************************
-*                                                                              *
-*   classinfo *asm_getcallingmethod ();                                                                   *
-*                                                                                                                                                         *    
-*   goes back stack frames to get the calling method                                              *       
-*                                                                                                                                                         *    
-*                              t2 .. sp                                                                                                       *
-*                              t3 .. ra                                                                                                       *
-*                              t4 .. pv                                                                                                       *
-*                                                                              *
 *******************************************************************************/
 
-asm_getcallingmethod:
-               xorl    %eax,%eax
-/*             movl    $0,(%eax) */
-               ret
+asm_memory_barrier:
+       lock; add $0,0(sp)
+       ret
 
+               
+/* asm_get_cycle_count *********************************************************
 
-/*********************** function asm_builtin_trace ****************************
-*                                                                              *
-*   Intended to be called from the native stub. Saves all argument registers   *
-*   and calls builtin_trace_args.                                              *
-*                                                                              *
-*******************************************************************************/
+   Get the current time-stamp counter from the CPU.
 
-asm_builtin_trace:
-        pusha
-        subl    $68,%esp                /* 4 + 8 * 4 + 68 = 104 */
-
-        movl    104(%esp),%eax
-        movl    108(%esp),%edx
-        movl    %eax,(%esp)
-        movl    %edx,4(%esp)
-
-        movl    112(%esp),%eax
-        movl    116(%esp),%edx
-        movl    %eax,8(%esp)
-        movl    %edx,12(%esp)
-
-        movl    120(%esp),%eax
-        movl    124(%esp),%edx
-        movl    %eax,16(%esp)
-        movl    %edx,20(%esp)
-
-        movl    128(%esp),%eax
-        movl    132(%esp),%edx
-        movl    %eax,24(%esp)
-        movl    %edx,28(%esp)
-
-        movl    136(%esp),%eax
-        movl    140(%esp),%edx
-        movl    %eax,32(%esp)
-        movl    %edx,36(%esp)
-
-        movl    144(%esp),%eax
-        movl    148(%esp),%edx
-        movl    %eax,40(%esp)
-        movl    %edx,44(%esp)
-
-        movl    152(%esp),%eax
-        movl    156(%esp),%edx
-        movl    %eax,48(%esp)
-        movl    %edx,52(%esp)
-
-        movl    160(%esp),%eax
-        movl    164(%esp),%edx
-        movl    %eax,56(%esp)
-        movl    %edx,60(%esp)
-
-        movl    168(%esp),%eax
-        movl    %eax,64(%esp)
-        
-        call    builtin_trace_args
-        addl    $68,%esp
-
-        popa
-        ret
-
-
-/********************* function asm_builtin_exittrace **************************
-*                                                                              *
-*   Intended to be called from the native stub. Saves return value and calls   *
-*   builtin_displaymethodstop.                                                 *
-*                                                                              *
 *******************************************************************************/
 
-asm_builtin_exittrace:
-        pusha
-        subl    $24,%esp
-        
-        movl    60(%esp),%eax           /* 4 + 8 * 4 + 24 = 60 */
-        movl    %eax,(%esp)
+asm_get_cycle_count:
+       rdtsc
+       ret
 
-        movl    64(%esp),%eax
-        movl    68(%esp),%edx
-        movl    %eax,4(%esp)
-        movl    %edx,8(%esp)
 
-        movl    72(%esp),%eax
-        movl    76(%esp),%edx
-        movl    %eax,12(%esp)
-        movl    %edx,16(%esp)
+/* disable exec-stacks ********************************************************/
 
-        movl    80(%esp),%eax
-        movl    %eax,20(%esp)
+#if defined(__linux__) && defined(__ELF__)
+       .section .note.GNU-stack,"",%progbits
+#endif
 
-        call    builtin_displaymethodstop
-        addl    $24,%esp
 
-        popa
-        ret
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: asm
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */