* Removed all Id tags.
[cacao.git] / src / vm / jit / x86_64 / asmpart.S
index 425205140b16c651e80c06883f945b75725818f2..58ab38124a894b21f02c4bb48d912dfc5a899660 100644 (file)
@@ -1,9 +1,9 @@
 /* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
 
-   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 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
 
    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:
-
-   $Id: asmpart.S 3910 2005-12-08 14:32:53Z twisti $
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
 */
 
 
 #include "config.h"
 
-#include "md-abi.h"
-#include "md-asm.h"
-
-#include "vm/jit/abi.h"
 #include "vm/jit/x86_64/arch.h"
-#include "vm/jit/x86_64/offsets.h"
+#include "vm/jit/x86_64/md-abi.h"
+#include "vm/jit/x86_64/md-asm.h"
 
+#include "vm/jit/abi-asm.h"
 #include "vm/jit/methodheader.h"
 
 
        .text
 
 
-/********************* exported functions and variables ***********************/
-
-       .globl asm_calljavafunction
-       .globl asm_calljavafunction_int
+/* export functions ***********************************************************/
 
-       .globl asm_calljavafunction2
-       .globl asm_calljavafunction2int
-       .globl asm_calljavafunction2long
-       .globl asm_calljavafunction2float
-       .globl asm_calljavafunction2double
+       .globl asm_vm_call_method
+       .globl asm_vm_call_method_int
+       .globl asm_vm_call_method_long
+       .globl asm_vm_call_method_float
+       .globl asm_vm_call_method_double
+       .globl asm_vm_call_method_exception_handler
+       .globl asm_vm_call_method_end
 
        .globl asm_call_jit_compiler
+
        .globl asm_handle_exception
        .globl asm_handle_nat_exception
 
-       .globl asm_wrapper_patcher
+       .globl asm_abstractmethoderror
+
+       .globl asm_patcher_wrapper
+
+#if defined(ENABLE_REPLACEMENT)
+       .globl asm_replacement_out
+       .globl asm_replacement_in
+#endif
 
        .globl asm_builtin_f2i
        .globl asm_builtin_f2l
        .globl asm_builtin_d2i
        .globl asm_builtin_d2l
 
-       .globl asm_perform_threadswitch
-       .globl asm_initialize_thread_stack
-       .globl asm_switchstackandcall
-       .globl asm_criticalsections
-       .globl asm_getclassvalues_atomic
+       .globl asm_compare_and_swap
+       .globl asm_memory_barrier
 
 
 /********************* function asm_calljavafunction ***************************
        .align  8
 
        .quad   0                           /* catch type all                     */
-       .quad   calljava_xhandler           /* handler pc                         */
-       .quad   calljava_xhandler           /* end pc                             */
-       .quad   asm_calljavafunction        /* start pc                           */
+       .quad   0                           /* handler pc                         */
+       .quad   0                           /* end pc                             */
+       .quad   0                           /* start pc                           */
        .long   1                           /* extable size                       */
-       .long   0                                                                                                                         
-       .quad   0                           /* line number table start            */
-       .quad   0                           /* line number table size             */
-       .long   0                                                                                                                         
-       .long   0                           /* fltsave                            */
-       .long   0                           /* intsave                            */
-       .long   0                           /* isleaf                             */
-       .long   0                           /* IsSync                             */
-       .long   8                           /* frame size                         */
-       .quad   0                           /* method pointer (pointer to name)   */
-
-asm_calljavafunction:
-asm_calljavafunction_int:
-       sub     $(3*8),sp                   /* keep stack 16-byte aligned         */
-       mov     bp,0*8(sp)
-       mov     %rbx,1*8(sp)                /* %rbx is not a callee saved in CACAO*/
-       mov     a0,itmp1                    /* move function pointer to itmp1     */
-                                                                           /* compilerstub uses this             */
-
-       mov     a1,a0                       /* pass remaining parameters          */
-       mov     a2,a1                                                                                                                   
-       mov     a3,a2
-       mov     a4,a3
-
-       lea     asm_call_jit_compiler,itmp3
-       call    *itmp3                      /* call JIT compiler                  */
-
-L_asm_calljavafunction_return:
-       mov     0*8(sp),bp
-       mov             1*8(sp),%rbx                /* %rbx is not a callee saved in CACAO*/
-       add     $(3*8),sp                   /* free stack space                   */
-       ret
-
-calljava_xhandler:
-       mov     xptr,a0                     /* pass exception pointer             */
-       call    builtin_throw_exception
-       xor     v0,v0                       /* return NULL                        */
-       jmp     L_asm_calljavafunction_return
-
-
-/********************* 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);                     *
-*                                                                              *
-*******************************************************************************/
-
-       .align  8
-
-       .quad   0                           /* catch type all                     */
-       .quad   calljava_xhandler2          /* handler pc                         */
-       .quad   calljava_xhandler2          /* end pc                             */
-       .quad   asm_calljavafunction2       /* start pc                           */
-       .long   1                           /* extable size                       */
-       .long   0                                                                                                                        
+       .long   0                           /* ALIGNMENT PADDING                  */
        .quad   0                           /* line number table  start           */
        .quad   0                           /* line number table  size            */
-       .long   0                                                                                                                        
+       .long   0                           /* ALIGNMENT PADDING                  */
        .long   0                           /* fltsave                            */
        .long   0                           /* intsave                            */
        .long   0                           /* isleaf                             */
        .long   0                           /* IsSync                             */
-       .long   24                          /* frame size                         */
-       .quad   0                           /* method pointer (pointer to name)   */
-
-asm_calljavafunction2:
-asm_calljavafunction2int:
-asm_calljavafunction2long:
-asm_calljavafunction2float:
-asm_calljavafunction2double:
+       .long                             /* frame size                         */
+       .quad   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:
        sub     $(7*8),sp                   /* keep stack 16-byte aligned         */
        mov     %rbx,0*8(sp)                /* %rbx is not a callee saved in cacao*/
        mov     s0,1*8(sp)
@@ -185,89 +116,61 @@ asm_calljavafunction2double:
        mov     s3,4*8(sp)
        mov     s4,5*8(sp)
 
-       mov     a0,itmp1                    /* move method pointer for compiler   */
-       xor     %rbp,%rbp                   /* set argument stack frame to zero   */
+       mov     a0,6*8(sp)                  /* store method PV                    */
 
-       test    a1,a1                       /* maybe we have no args...           */
-       jle     L_copy_done
+       mov     sp,s0                       /* save stack pointer                 */
 
-       mov     a1,itmp3                    /* arg count                          */
-       mov     a3,itmp2                    /* pointer to arg block               */
+       mov     a1,t0                       /* address of data structure          */
+       mov     a2,itmp1                    /* number of stack arguments          */
 
-       mov     itmp2,%r14                  /* save argument block pointer        */
-       mov     itmp3,%r15                  /* save argument count                */
+       mov     0*8(t0),a0
+       mov     1*8(t0),a1
+       mov     2*8(t0),a2
+       mov     3*8(t0),a3
+       mov     4*8(t0),a4
+       mov     5*8(t0),a5
 
-       sub     $sizejniblock,itmp2         /* initialize pointer (smaller code)  */
-       add     $1,itmp3                    /* initialize argument count          */
-       xor     %r12,%r12                   /* initialize integer argument counter*/
-       xor     %r13,%r13                   /* initialize float argument counter  */
+       movq    6*8(t0),fa0
+       movq    7*8(t0),fa1
+       movq    8*8(t0),fa2
+       movq    9*8(t0),fa3
+       movq    10*8(t0),fa4
+       movq    11*8(t0),fa5
+       movq    12*8(t0),fa6
+       movq    13*8(t0),fa7
 
-L_register_copy:
-       add     $sizejniblock,itmp2       /* goto next argument block             */
-       dec     itmp3                     /* argument count - 1                   */
-       jz      L_register_copy_done
-       andb    $0x02,offjniitemtype(itmp2) /* is this a float/double type?       */
-       jnz     L_register_handle_float   /* yes, handle it                       */
+       cmp     $0,itmp1l
+       je      L_asm_vm_call_method_stack_copy_done
 
-       cmp     $INT_ARG_CNT,%r12         /* are we out of integer argument       */
-       je      L_register_copy           /* register? yes, next loop             */
+       mov     itmp1,itmp2
+       add     $1,itmp2                    /* keep stack 16-byte aligned         */
+       and     $0xfffffffffffffffe,itmp2
+       shl     $3,itmp2                    /* calculate stack size               */
+       sub     itmp2,sp                    /* create stack frame                 */
+       mov     sp,itmp2                    /* temporary stack pointer            */
 
-       lea     jumptable_integer,%rbp
-       mov     0(%rbp,%r12,8),%rbx
-       inc     %r12                      /* integer argument counter + 1         */
-       jmp     *%rbx
+L_asm_vm_call_method_stack_copy_loop:
+       mov     14*8(t0),itmp3              /* load argument                      */
+       mov     itmp3,0(itmp2)              /* store argument on stack            */
 
-L_register_handle_float:
-       cmp     $FLT_ARG_CNT,%r13         /* are we out of float argument         */
-       je      L_register_copy           /* register? yes, next loop             */
+       sub     $1,itmp1l                   /* subtract 1 argument                */
+       add     $8,t0                       /* set address of next argument       */
+       add     $8,itmp2                    /* increase SP                        */
 
-       lea     jumptable_float,%rbp
-       mov     0(%rbp,%r13,8),%rbx
-       inc     %r13                      /* float argument counter + 1           */
-       jmp     *%rbx
-       
-L_register_copy_done:
-       mov     %r15,%rbp                 /* calculate remaining arguments        */
-       sub     %r12,%rbp                 /* - integer arguments in registers     */
-       sub     %r13,%rbp                 /* - float arguments in registers       */
-       jle     L_copy_done               /* are all assigned to registers?       */
-
-       and     $0xfffffffffffffffe,%rbp  /* keep stack 16-byte aligned           */
-       shl     $3,%rbp                   /* calculate stack size                 */
-       sub     %rbp,sp                 /* stack frame for arguments            */
-       mov     sp,%rbx                 /* use %rbx as temp sp                  */
-
-       sub     $sizejniblock,%r14        /* initialize pointer (smaller code)    */
-       add     $1,%r15                   /* initialize argument count            */
-               
-L_stack_copy_loop:
-       add     $sizejniblock,%r14        /* goto next argument block             */
-       dec     %r15                      /* are there any arguments left?        */
-       jz      L_copy_done               /* no test needed after dec             */
-
-       andb    $0x02,offjniitemtype(%r14) /* is this a float/double type?        */
-       jnz     L_stack_handle_float
-       dec     %r12                      /* arguments assigned to registers      */
-       jge     L_stack_copy_loop
-       jmp     L_stack_copy
-
-L_stack_handle_float:
-       dec     %r13                      /* arguments assigned to registers      */
-       jge     L_stack_copy_loop
-
-L_stack_copy:
-    mov     offjniitem(%r14),itmp3    /* copy s8 argument onto stack          */
-    mov     itmp3,0(%rbx)
-    add     $8,%rbx                   /* increase sp to next argument         */
-       jmp     L_stack_copy_loop
-
-L_copy_done:
-       lea     asm_call_jit_compiler,itmp3 /* %rax still contains method pointer */
-       call    *itmp3                    /* call JIT compiler                    */
-
-       add     bp,sp                     /* remove argument stack frame if any   */
-
-L_asm_calljavafunction2_return:
+       cmp     $0,itmp1l
+       jg      L_asm_vm_call_method_stack_copy_loop
+
+L_asm_vm_call_method_stack_copy_done:
+       lea     (6*8-256)(s0),mptr          /* We subtract 256 to force the next  */
+                                           /* move instruction to have a 32-bit  */
+                                           /* offset.                            */
+
+       mov     (0*8+256)(mptr),itmp3       /* load PV                            */
+       call    *itmp3
+
+       mov     s0,sp                       /* restore SP                         */
+
+L_asm_vm_call_method_return:
        mov     0*8(sp),%rbx                /* restore callee saved registers     */
        mov     1*8(sp),s0
        mov     2*8(sp),s1
@@ -277,75 +180,13 @@ L_asm_calljavafunction2_return:
        add     $(7*8),sp                   /* free stack space                   */
        ret
                
-calljava_xhandler2:
+asm_vm_call_method_exception_handler:
        mov     xptr,a0                     /* pass exception pointer             */
-       call    builtin_throw_exception
-       xor     v0,v0                       /* return NULL                        */
-       jmp     L_asm_calljavafunction2_return
-
-
-jumptable_integer:
-       .quad   handle_a0
-       .quad   handle_a1
-       .quad   handle_a2
-       .quad   handle_a3
-       .quad   handle_a4
-       .quad   handle_a5
-
-handle_a0:
-       mov     offjniitem(itmp2),a0
-       jmp     L_register_copy
-handle_a1:
-       mov     offjniitem(itmp2),a1
-       jmp     L_register_copy
-handle_a2:
-       mov     offjniitem(itmp2),a2
-       jmp     L_register_copy
-handle_a3:
-       mov     offjniitem(itmp2),a3
-       jmp     L_register_copy
-handle_a4:
-       mov     offjniitem(itmp2),a4
-       jmp     L_register_copy
-handle_a5:
-       mov     offjniitem(itmp2),a5
-       jmp     L_register_copy
-
-
-jumptable_float:
-       .quad   handle_fa0
-       .quad   handle_fa1
-       .quad   handle_fa2
-       .quad   handle_fa3
-       .quad   handle_fa4
-       .quad   handle_fa5
-       .quad   handle_fa6
-       .quad   handle_fa7
-
-handle_fa0:
-       movq    offjniitem(itmp2),fa0
-       jmp     L_register_copy
-handle_fa1:
-       movq    offjniitem(itmp2),fa1
-       jmp     L_register_copy
-handle_fa2:
-       movq    offjniitem(itmp2),fa2
-       jmp     L_register_copy
-handle_fa3:
-       movq    offjniitem(itmp2),fa3
-       jmp     L_register_copy
-handle_fa4:
-       movq    offjniitem(itmp2),fa4
-       jmp     L_register_copy
-handle_fa5:
-       movq    offjniitem(itmp2),fa5
-       jmp     L_register_copy
-handle_fa6:
-       movq    offjniitem(itmp2),fa6
-       jmp     L_register_copy
-handle_fa7:
-       movq    offjniitem(itmp2),fa7
-       jmp     L_register_copy
+       call    builtin_throw_exception@PLT
+       jmp     L_asm_vm_call_method_return
+
+asm_vm_call_method_end:
+       nop
 
 
 /****************** function asm_call_jit_compiler *****************************
@@ -376,87 +217,32 @@ handle_fa7:
 *******************************************************************************/
 
 asm_call_jit_compiler:
-                                           /* keep stack 16-byte aligned         */
-       sub     $((3+ARG_CNT)*8+sizestackframeinfo),sp
-
-       mov     t0,0*8(sp)                  /* save register                      */
-
-       mov     (3+ARG_CNT)*8+sizestackframeinfo(sp),itmp3 /* get return address  */
-       mov     -1(itmp3),%bl               /* get function code                  */
-       cmp     $0xd2,%bl                   /* called with `call *REG_ITMP2'?     */
-       jne     L_not_static_special
-
-       sub     $11,itmp3                   /* calculate address of immediate     */
-       jmp     L_call_jit_compile
-               
-L_not_static_special:
-       cmp     $0xd0,%bl                   /* called with `call *REG_ITMP1'      */
-       jne     L_not_virtual_interface
-               
-       sub     $7,itmp3                    /* calculate address of offset        */
-       mov     (itmp3),itmp3l              /* get offset (32-bit)                */
-       add     itmp2,itmp3                 /* add base address to get method addr*/
-       jmp     L_call_jit_compile
+L_asm_call_jit_compiler:                /* required for PIC code              */
+       sub     $(ARG_CNT+1)*8,sp           /* +1: keep stack 16-byte aligned     */
 
-L_not_virtual_interface:                /* a call from asm_calljavamethod     */
-       xor     itmp3,itmp3
-               
-L_call_jit_compile:
-       mov     0*8(sp),t0                  /* restore register                   */
-       mov     itmp3,0*8(sp)               /* save address for method pointer    */
-       mov     itmp1,1*8(sp)               /* save method pointer                */
-
-       SAVE_ARGUMENT_REGISTERS(3)
+       SAVE_ARGUMENT_REGISTERS(0)
 
-       mov     sp,a0                       /* create stackframe info             */
-       add     $((3+ARG_CNT)*8),a0         /* pass sfi                           */
-       xor     a1,a1                       /* if pv is NULL, use findmethod      */
+       mov     itmp1,a0                    /* pass methodinfo pointer            */
+       mov     mptr,a1                     /* pass method pointer                */
        mov     sp,a2                       /* pass java sp                       */
-       add     $((1+3+ARG_CNT)*8+sizestackframeinfo),a2
-                                           /* pass ra to java function           */
-       mov     ((3+ARG_CNT)*8+sizestackframeinfo)(sp),a3
-       mov     a3,a4                       /* xpc is equal to ra                 */
-       call    stacktrace_create_extern_stackframeinfo
-
-       mov     1*8(sp),a0                  /* pass method pointer                */
-       call    jit_compile
-       mov     v0,1*8(sp)                  /* save return value                  */
-
-       mov     sp,a0                       /* remove stackframe info             */
-       add     $((3+ARG_CNT)*8),a0         /* pass sfi                           */
-       call    stacktrace_remove_stackframeinfo
+       add     $(1+ARG_CNT+1)*8,a2
+       mov     (ARG_CNT+1)*8(sp),a3        /* pass ra to java function           */
+       call    jit_asm_compile@PLT
 
-       mov     0*8(sp),itmp3               /* restore address for method pointer */
-       mov     1*8(sp),v0                  /* restore return value               */
-
-       RESTORE_ARGUMENT_REGISTERS(3)
+       RESTORE_ARGUMENT_REGISTERS(0)
 
-       add     $((3+ARG_CNT)*8+sizestackframeinfo),sp /* remove stack frame      */
+       add     $(ARG_CNT+1)*8,sp           /* remove stack frame                 */
 
        test    v0,v0                       /* check for exception                */
        je      L_asm_call_jit_compiler_exception
 
-       test    itmp3,itmp3                 /* is address == 0 (asm_calljavamethod*/
-       je      L_call_method
-
-       mov     v0,(itmp3)                  /* and now save the new pointer       */
-
-L_call_method:
        jmp     *v0                         /* ...and now call the new method     */
 
 L_asm_call_jit_compiler_exception:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       call    builtin_asm_get_exceptionptrptr
-       mov     v0,itmp2                    /* v0 == xptr                         */
-#else
-       lea     _no_threads_exceptionptr,itmp2
-#endif
-       mov     (itmp2),xptr                /* get the exception pointer          */
-       movl    $0,(itmp2)                  /* clear exception pointer            */
-
+       call    exceptions_get_and_clear_exception@PLT
        pop     xpc                         /* delete return address              */
-       sub     $5,xpc                      /* faulting address is ra - 5         */
-       jmp     asm_handle_exception
+       sub     $3,xpc                      /* faulting address is ra - 3         */
+       jmp     L_asm_handle_exception
 
 
 /* asm_handle_exception ********************************************************
@@ -473,13 +259,14 @@ asm_handle_nat_exception:
        add     $8,sp                       /* clear return address of native stub*/
                
 asm_handle_exception:
+L_asm_handle_exception:                 /* required for PIC code              */
        sub     $((ARG_CNT+TMP_CNT)*8),sp   /* create maybe-leaf stackframe       */
 
        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)*8),a3   /* prepare a3 for handle_exception    */
-       mov     $1,a4                       /* set maybe-leaf flag                */
+       mov     $1,t0                       /* set maybe-leaf flag                */
 
 L_asm_handle_exception_stack_loop:
        sub     $(6*8),sp
@@ -488,27 +275,27 @@ L_asm_handle_exception_stack_loop:
        add     sp,a3                       /* calculate Java sp into a3...       */
        add     $(6*8),a3
        mov     a3,3*8(sp)                  /* ...and save it                     */
-       mov     a4,4*8(sp)                  /* save maybe-leaf flag               */
+       mov     t0,4*8(sp)                  /* save maybe-leaf flag               */
 
        mov     xpc,a0                      /* exception pc                       */
-       call    codegen_findmethod
+       call    codegen_get_pv_from_pc@PLT
        mov     v0,2*8(sp)                  /* save data segment pointer          */
         
        mov     0*8(sp),a0                  /* pass exception pointer             */
        mov     1*8(sp),a1                  /* pass exception pc                  */
        mov     v0,a2                       /* pass data segment pointer          */
        mov     3*8(sp),a3                  /* pass Java stack pointer            */
-       call    exceptions_handle_exception
+       call    exceptions_handle_exception@PLT
 
        test    v0,v0
        jz      L_asm_handle_exception_not_catched
 
        mov     v0,xpc                      /* move handlerpc into xpc            */
        mov     0*8(sp),xptr                /* restore exception pointer          */
-       mov     4*8(sp),a4                  /* get maybe-leaf flag                */
+       mov     4*8(sp),t0                  /* get maybe-leaf flag                */
        add     $(6*8),sp                   /* free stack frame                   */
 
-       test    a4,a4                       /* test for maybe-leaf flag           */
+       test    t0,t0                       /* test for maybe-leaf flag           */
        jz      L_asm_handle_exception_no_leaf
 
        RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
@@ -522,71 +309,75 @@ L_asm_handle_exception_no_leaf:
 L_asm_handle_exception_not_catched:
        mov     0*8(sp),xptr                /* restore exception pointer          */
        mov     2*8(sp),itmp3               /* restore data segment pointer       */
-       mov     4*8(sp),a4                  /* get maybe-leaf flag                */
+       mov     4*8(sp),t0                  /* get maybe-leaf flag                */
        add     $(6*8),sp
 
-       test    a4,a4
+       test    t0,t0
        jz      L_asm_handle_exception_no_leaf_stack
 
        add     $((ARG_CNT+TMP_CNT)*8),sp   /* remove maybe-leaf stackframe       */
-       xor     a4,a4                       /* clear the isleaf flags             */
+       xor     t0,t0                       /* clear the isleaf flags             */
 
 L_asm_handle_exception_no_leaf_stack:
        mov     FrameSize(itmp3),itmp2l     /* get frame size                     */
-       add     itmp2,sp                    /* unwind stack                       */
-       mov     sp,itmp2                    /* pointer to save area               */
+       add     sp,itmp2                    /* pointer to save area               */
        
-       mov     IntSave(itmp3),t0l          /* t0l = saved int register count     */
-       test    t0l,t0l
+       mov     IntSave(itmp3),a0l          /* a0l = saved int register count     */
+       test    a0l,a0l
        je      noint
        
-       cmp     $1,t0l
+       cmp     $1,a0l
        je      int1
-       cmp     $2,t0l
+       cmp     $2,a0l
        je      int2
-       cmp     $3,t0l
+       cmp     $3,a0l
        je      int3
-       cmp     $4,t0l
+       cmp     $4,a0l
        je      int4
        
-       mov     -40(itmp2),%rbp
+       mov     -5*8(itmp2),s0
 int4:   
-       mov     -32(itmp2),%r12
+       mov     -4*8(itmp2),s1
 int3:   
-       mov     -24(itmp2),%r13
+       mov     -3*8(itmp2),s2
 int2:   
-       mov     -16(itmp2),%r14
+       mov     -2*8(itmp2),s3
 int1:   
-       mov     -8(itmp2),%r15
+       mov     -1*8(itmp2),s4
 
-       shl     $3,t0l                      /* multiply by 8 bytes                */
-       sub     t0,itmp2
+       shl     $3,a0l                      /* multiply by 8 bytes                */
+       sub     a0,itmp2
                
 noint:
-       mov     FltSave(itmp3),t0l          /* t0l = saved flt register count     */
-       test    t0l,t0l
+#if 0
+       mov     FltSave(itmp3),a0l          /* a0l = saved flt register count     */
+       test    a0l,a0l
        je      noflt
        
-       cmpl    $1,t0l
+       cmpl    $1,a0l
        je      flt1
-       cmpl    $2,t0l
+       cmpl    $2,a0l
        je      flt2
-       cmpl    $3,t0l
+       cmpl    $3,a0l
        je      flt3
-       cmpl    $4,t0l
+       cmpl    $4,a0l
        je      flt4
 
-       movq    -40(itmp2),%xmm11
+       movq    -5*8(itmp2),%xmm11
 flt4:   
-       movq    -32(itmp2),%xmm12
+       movq    -4*8(itmp2),%xmm12
 flt3:   
-       movq    -24(itmp2),%xmm13
+       movq    -3*8(itmp2),%xmm13
 flt2:   
-       movq    -16(itmp2),%xmm14
+       movq    -2*8(itmp2),%xmm14
 flt1:   
-       movq    -8(itmp2),%xmm15
+       movq    -1*8(itmp2),%xmm15
                 
-noflt:                                 
+noflt:
+#endif
+       mov     FrameSize(itmp3),itmp2l     /* get frame size                     */
+       add     itmp2,sp                    /* unwind stack                       */
+
                                            /* exception pointer is still set     */
        pop     xpc                         /* the new xpc is return address      */
        sub     $3,xpc                      /* subtract 3 bytes for call          */
@@ -596,7 +387,25 @@ noflt:
        jmp             L_asm_handle_exception_stack_loop
 
 
-/* asm_wrapper_patcher *********************************************************
+/* asm_abstractmethoderror *****************************************************
+
+   Creates and throws an AbstractMethodError.
+
+*******************************************************************************/
+
+asm_abstractmethoderror:
+       mov     sp,a0                       /* pass java sp                       */
+       add     $1*8,a0
+       mov     0*8(sp),a1                  /* pass exception address             */
+       sub     $3,a1
+       call    exceptions_asm_new_abstractmethoderror@PLT
+                                           /* exception pointer is return value  */
+       pop     xpc                         /* get exception address              */
+       sub     $3,xpc                      /* exception address is ra - 3        */
+       jmp     L_asm_handle_exception
+
+
+/* asm_patcher_wrapper *********************************************************
 
    XXX
 
@@ -611,10 +420,10 @@ noflt:
 
 *******************************************************************************/
 
-asm_wrapper_patcher:
+asm_patcher_wrapper:
        push    bp                          /* save base pointer                  */
        mov     sp,bp                       /* move actual sp to bp               */
-       sub     $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),sp
+       sub     $(3+ARG_CNT+TMP_CNT)*8,sp
        and     $0xfffffffffffffff0,sp      /* align sp to 16-byte (this is for   */
                                            /* leaf functions)                    */
 
@@ -624,25 +433,13 @@ asm_wrapper_patcher:
        mov     itmp1,0*8(sp)               /* save itmp1 and itmp2               */
        mov     itmp2,1*8(sp)               /* can be used by some instructions   */
 
-       mov     sp,a0                       /* create stackframe info             */
-       add     $((3+ARG_CNT+TMP_CNT)*8),a0
-       xor     a1,a1                       /* if pv is NULL, use findmethod      */
-       mov     bp,a2                       /* pass java sp                       */
-       add     $((6+1)*8),a2
-       mov     ((5+1)*8)(bp),a3            /* pass ra to java function           */
-       mov     a3,a4                       /* xpc is equal to ra                 */
-       call    stacktrace_create_extern_stackframeinfo
-
-       mov     bp,a0                       /* pass stack pointer                 */
-       add     $((1+1)*8),a0               /* skip function pointer              */
-       mov     1*8(bp),itmp3               /* get function pointer               */
-       call    *itmp3                      /* call the patcher function          */
+       mov     bp,a0                       /* pass SP of patcher stub            */
+       add     $(1*8),a0
+       mov     $0,a1                       /* pass PV (if NULL, use findmethod)  */
+       mov     $0,a2                       /* pass RA (it's on the stack)        */
+       call    patcher_wrapper@PLT
        mov     v0,2*8(sp)                  /* save return value                  */
 
-       mov     sp,a0                       /* remove stackframe info             */
-       add     $((3+ARG_CNT+TMP_CNT)*8),a0
-       call    stacktrace_remove_stackframeinfo
-
        RESTORE_ARGUMENT_REGISTERS(3)
        RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
 
@@ -652,24 +449,170 @@ asm_wrapper_patcher:
 
        mov     bp,sp                       /* restore original sp                */
        pop     bp                          /* restore bp                         */
-       add     $(5*8),sp                   /* remove patcher stackframe, keep ra */
+       add     $(5*8),sp                   /* remove patcher stackframe, keep RA */
 
        test    itmp3,itmp3                 /* exception thrown?                  */
-       jz      L_asm_wrapper_patcher_exception
+       jne     L_asm_patcher_wrapper_exception
        ret                                 /* call new patched code              */
 
-L_asm_wrapper_patcher_exception:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       call    builtin_asm_get_exceptionptrptr
-       mov     v0,itmp2                    /* v0 == xptr                         */
-#else
-       lea     _no_threads_exceptionptr,itmp2
-#endif
-       mov     (itmp2),xptr                /* get the exception pointer          */
-       movl    $0,(itmp2)                  /* clear exception pointer            */
-
+L_asm_patcher_wrapper_exception:
+       mov     itmp3,xptr                  /* get exception                      */
        pop     xpc                         /* get and remove return address      */
-       jmp     asm_handle_exception
+       jmp     L_asm_handle_exception
+
+#if defined(ENABLE_REPLACEMENT)
+
+/* asm_replacement_out *********************************************************
+
+   This code is jumped to from the replacement-out stubs that are executed
+   when a thread reaches an activated replacement point.
+
+   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.
+
+   Stack layout:
+      8                 start of stack inside method to replace
+      0   rplpoint *    info on the replacement point that was reached
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+       /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM  512
+
+asm_replacement_out:
+    /* create stack frame */
+       sub     $(sizeexecutionstate + REPLACEMENT_ROOM),sp
+
+       /* save registers in execution state */
+       mov     %rax,(RAX*8+offes_intregs)(sp)
+       mov     %rbx,(RBX*8+offes_intregs)(sp)
+       mov     %rcx,(RCX*8+offes_intregs)(sp)
+       mov     %rdx,(RDX*8+offes_intregs)(sp)
+       mov     %rsi,(RSI*8+offes_intregs)(sp)
+       mov     %rdi,(RDI*8+offes_intregs)(sp)
+       mov     %rbp,(RBP*8+offes_intregs)(sp)
+       movq    $0  ,(RSP*8+offes_intregs)(sp) /* not used */
+       mov     %r8 ,(R8 *8+offes_intregs)(sp)
+       mov     %r9 ,(R9 *8+offes_intregs)(sp)
+       mov     %r10,(R10*8+offes_intregs)(sp)
+       mov     %r11,(R11*8+offes_intregs)(sp)
+       mov     %r12,(R12*8+offes_intregs)(sp)
+       mov     %r13,(R13*8+offes_intregs)(sp)
+       mov     %r14,(R14*8+offes_intregs)(sp)
+       mov     %r15,(R15*8+offes_intregs)(sp)
+
+       movq    %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
+       movq    %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
+       movq    %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
+       movq    %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
+       movq    %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
+       movq    %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
+       movq    %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
+       movq    %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
+       movq    %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
+       movq    %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
+       movq    %xmm10,(XMM10*8+offes_fltregs)(sp)
+       movq    %xmm11,(XMM11*8+offes_fltregs)(sp)
+       movq    %xmm12,(XMM12*8+offes_fltregs)(sp)
+       movq    %xmm13,(XMM13*8+offes_fltregs)(sp)
+       movq    %xmm14,(XMM14*8+offes_fltregs)(sp)
+       movq    %xmm15,(XMM15*8+offes_fltregs)(sp)
+
+       /* calculate sp of method */
+       mov     sp,itmp1
+       add     $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
+       mov     itmp1,(offes_sp)(sp)
+
+       /* pv must be looked up via AVL tree */
+       movq    $0,(offes_pv)(sp)
+
+       /* call replace_me */
+       mov     -8(itmp1),a0                /* rplpoint *                         */
+    mov     sp,a1                       /* arg1: execution state              */
+    call    replace_me@PLT              /* call C function replace_me         */
+    call    abort@PLT                   /* NEVER REACHED                      */
+
+/* asm_replacement_in **********************************************************
+
+   This code writes the given execution state and jumps to the replacement
+   code.
+
+   This function never returns!
+
+   C prototype:
+      void asm_replacement_in(executionstate *es, replace_safestack_t *st);
+
+*******************************************************************************/
+
+asm_replacement_in:
+       /* get arguments */
+       mov     a1,s1                       /* replace_safestack_t *st            */
+       mov     a0,%rbp                     /* executionstate *es == safe stack   */
+
+       /* switch to the safe stack */
+       mov     %rbp,sp
+
+       /* call replace_build_execution_state(st) */
+       mov             s1,a0
+       call    replace_build_execution_state@PLT
+
+       /* set new sp */
+       mov     (offes_sp)(%rbp),sp
+
+       /* push address of new code */
+       pushq   (offes_pc)(%rbp)
+
+       /* allocate an executionstate_t on the stack */
+       sub             $(sizeexecutionstate),sp
+
+       /* call replace_free_safestack(st,& of allocated executionstate_t) */
+       mov             sp,a1
+       mov             s1,a0
+       call    replace_free_safestack@PLT
+
+       /* copy registers from execution state */
+       movq    (XMM0 *8+offes_fltregs)(sp),%xmm0
+       movq    (XMM1 *8+offes_fltregs)(sp),%xmm1
+       movq    (XMM2 *8+offes_fltregs)(sp),%xmm2
+       movq    (XMM3 *8+offes_fltregs)(sp),%xmm3
+       movq    (XMM4 *8+offes_fltregs)(sp),%xmm4
+       movq    (XMM5 *8+offes_fltregs)(sp),%xmm5
+       movq    (XMM6 *8+offes_fltregs)(sp),%xmm6
+       movq    (XMM7 *8+offes_fltregs)(sp),%xmm7
+       movq    (XMM8 *8+offes_fltregs)(sp),%xmm8
+       movq    (XMM9 *8+offes_fltregs)(sp),%xmm9
+       movq    (XMM10*8+offes_fltregs)(sp),%xmm10
+       movq    (XMM11*8+offes_fltregs)(sp),%xmm11
+       movq    (XMM12*8+offes_fltregs)(sp),%xmm12
+       movq    (XMM13*8+offes_fltregs)(sp),%xmm13
+       movq    (XMM14*8+offes_fltregs)(sp),%xmm14
+       movq    (XMM15*8+offes_fltregs)(sp),%xmm15
+
+       mov     (RAX*8+offes_intregs)(sp),%rax
+       mov     (RBX*8+offes_intregs)(sp),%rbx
+       mov     (RCX*8+offes_intregs)(sp),%rcx
+       mov     (RDX*8+offes_intregs)(sp),%rdx
+       mov     (RSI*8+offes_intregs)(sp),%rsi
+       mov     (RDI*8+offes_intregs)(sp),%rdi
+       mov     (RBP*8+offes_intregs)(sp),%rbp
+       mov     (R8 *8+offes_intregs)(sp),%r8
+       mov     (R9 *8+offes_intregs)(sp),%r9
+       mov     (R10*8+offes_intregs)(sp),%r10
+       mov     (R11*8+offes_intregs)(sp),%r11
+       mov     (R12*8+offes_intregs)(sp),%r12
+       mov     (R13*8+offes_intregs)(sp),%r13
+       mov     (R14*8+offes_intregs)(sp),%r14
+       mov     (R15*8+offes_intregs)(sp),%r15
+
+       /* pop the execution state off the stack */
+       add             $(sizeexecutionstate),sp
+
+       /* jump to new code */
+       ret
+
+#endif /* defined(ENABLE_REPLACEMENT) */
 
 
 /* asm_builtin_x2x *************************************************************
@@ -684,7 +627,7 @@ asm_builtin_f2i:
        SAVE_ARGUMENT_REGISTERS(0)
        
        movq    ftmp1,fa0
-       call    builtin_f2i
+       call    builtin_f2i@PLT
        
        RESTORE_ARGUMENT_REGISTERS(0)
        
@@ -698,7 +641,7 @@ asm_builtin_f2l:
        SAVE_ARGUMENT_REGISTERS(0)
        
        movq    ftmp1,fa0
-       call    builtin_f2l
+       call    builtin_f2l@PLT
        
        RESTORE_ARGUMENT_REGISTERS(0)
        
@@ -712,7 +655,7 @@ asm_builtin_d2i:
        SAVE_ARGUMENT_REGISTERS(0)
        
        movq    ftmp1,fa0
-       call    builtin_d2i
+       call    builtin_d2i@PLT
        
        RESTORE_ARGUMENT_REGISTERS(0)
        
@@ -726,7 +669,7 @@ asm_builtin_d2l:
        SAVE_ARGUMENT_REGISTERS(0)
        
        movq    ftmp1,fa0
-       call    builtin_d2l
+       call    builtin_d2l@PLT
        
        RESTORE_ARGUMENT_REGISTERS(0)
        
@@ -734,123 +677,35 @@ asm_builtin_d2l:
        ret
 
 
-/******************* function asm_initialize_thread_stack **********************
-*                                                                              *
-* initialized a thread stack                                                   *
-* (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
-*                                                                              *
-*******************************************************************************/
-
-asm_initialize_thread_stack:
-        sub     $(7*8),%rsi
+/* asm_compare_and_swap ********************************************************
 
-        xor     %r10,%r10
-        mov     %r10,0*8(%rsi)
-        mov     %r10,1*8(%rsi)
-        mov     %r10,2*8(%rsi)
-        mov     %r10,3*8(%rsi)
-        mov     %r10,4*8(%rsi)
-        mov     %r10,5*8(%rsi)
+   Does an atomic compare and swap.  Required for the lock
+   implementation.
 
-        mov     %rdi,6*8(%rsi)          /* save (u1*) (func)                  */
-        mov     %rsi,%rax               /* return restorepoint in %rax        */
-        ret
-
-
-/******************* function asm_perform_threadswitch *************************
-*                                                                              *
-*   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
-*                                                                              *
-*   performs a threadswitch                                                    *
-*                                                                              *
 *******************************************************************************/
 
-asm_perform_threadswitch:
-        sub     $(7*8),%rsp             /* allocate stack frame               */
-
-        mov     %rbx,0*8(%rsp)
-        mov     %rbp,1*8(%rsp)
-        mov     %r12,2*8(%rsp)
-        mov     %r13,3*8(%rsp)
-        mov     %r14,4*8(%rsp)
-        mov     %r15,5*8(%rsp)
-
-        mov     7*8(%rsp),%rax                 /* save current return address        */
-        mov     %rax,6*8(%rsp)
-
-        mov     %rsp,(%rdi)                    /* first argument **from              */
-        mov     %rsp,(%rdx)                    /* third argument **stackTop          */
+asm_compare_and_swap:
+       mov     a1,v0                       /* v0 is %rax                         */
+       lock cmpxchg a2,(a0)
+       ret
 
-        mov     (%rsi),%rsp                    /* load new stack pointer             */
 
-        mov     0*8(%rsp),%rbx
-        mov     1*8(%rsp),%rbp
-        mov     2*8(%rsp),%r12
-        mov     3*8(%rsp),%r13
-        mov     4*8(%rsp),%r14
-        mov     5*8(%rsp),%r15
+/* asm_memory_barrier **********************************************************
 
-        mov     6*8(%rsp),%rax          /* restore return address             */
-        add     $(7*8),%rsp             /* free stack frame                   */
-        mov     %rax,(%rsp)
-        ret
-               
+   A memory barrier for the Java Memory Model.
 
-/********************* 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 (%rdi)     new stack pointer                                        *
-*       a1 (%rsi)     function pointer                                         *
-*              a2 (%rdx)     pointer to variable where stack top should be stored     *
-*       a3 (%rcx)     pointer to user data, is passed to the function          *
-*                                                                              *
 *******************************************************************************/
 
-asm_switchstackandcall:
-        sub     $(1*8),%rsp             /* keep stack 16-byte aligned         */
-        sub     $16,%rdi                               /* allocate new stack                 */
-
-        mov     8(%rsp),%rax                   /* save return address on new stack   */
-        mov     %rax,(%rdi)
-        mov     %rsp,8(%rdi)                   /* save old stack pointer on new stack*/
-        mov     %rsp,(%rdx)                            /* save old stack pointer to variable */
-
-        mov     %rdi,%rsp                              /* switch to new stack                */
-
-        mov     %rcx,%rdi                      /* pass pointer                       */
-        call   *%rsi                                   /* and call function                  */
-
-        mov     (%rsp),%r10                            /* load return address                */
-        mov     8(%rsp),%rsp                   /* switch to old stack                */
-        add     $(1*8),%rsp             /* free stack space                   */
-        mov     %r10,(%rsp)             /* write return adress                */
-        ret
-
-
-asm_getclassvalues_atomic:
-_crit_restart:
-_crit_begin:
-       movl    offbaseval(a0),itmp1l
-       movl    offdiffval(a0),itmp2l
-       movl    offbaseval(a1),itmp3l
-_crit_end:
-       movl    itmp1l,offcast_super_baseval(a2)
-       movl    itmp2l,offcast_super_diffval(a2)
-       movl    itmp3l,offcast_sub_baseval(a2)
+asm_memory_barrier:
+       mfence
        ret
 
-       .data
-               
-asm_criticalsections:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       .quad   _crit_begin
-       .quad   _crit_end
-       .quad   _crit_restart
+
+/* disable exec-stacks ********************************************************/
+
+#if defined(__linux__) && defined(__ELF__)
+       .section .note.GNU-stack,"",%progbits
 #endif
-       .quad 0
 
 
 /*
@@ -864,4 +719,5 @@ asm_criticalsections:
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */