* Removed all Id tags.
[cacao.git] / src / vm / jit / s390 / asmpart.S
index 0817e0abeffe2c6962abc6cf51c10f261236e24e..b711f0c27637f3cbc21714cdfcc1a195c64ab1ca 100644 (file)
@@ -22,8 +22,6 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: asmpart.S 7661 2007-04-03 22:29:59Z twisti $
-
 */
 
 
 #include "vm/jit/s390/arch.h"
 #include "vm/jit/s390/md-abi.h"
 #include "vm/jit/s390/md-asm.h"
-#include "vm/jit/s390/offsets.h"
 
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/methodheader.h"
 
-/* Copy a call to a PIC function from gcc -S
- * We setup a temporary literal pool pointer.
- */
-
-#define PIC_CALL(fun, magic)                                  \
-       bras itmp3, L_##magic##_lp_end                          ; \
-L_##magic##_lp:                                             ; \
-L_##magic##_lp_5:                                           ; \
-       .long fun@PLTOFF                                        ; \
-L_##magic##_lp_4:                                           ; \
-       .long _GLOBAL_OFFSET_TABLE_-L_##magic##_lp              ; \
-L_##magic##_lp_end:                                         ; \
-       l       itmp2,L_##magic##_lp_4-L_##magic##_lp(itmp3)    ; \
-       la      itmp2,0(itmp2,itmp3)                            ; \
-       l       itmp1,L_##magic##_lp_5-L_##magic##_lp(itmp3)    ; \
-       bas     %r14,0(itmp1,itmp2)                             
-
        .text
 
 
@@ -74,8 +54,6 @@ L_##magic##_lp_end:                                         ; \
 
        .globl asm_abstractmethoderror
 
-       .globl asm_patcher_wrapper
-
        .globl asm_replacement_out
        .globl asm_replacement_in
 
@@ -84,9 +62,6 @@ L_##magic##_lp_end:                                         ; \
        .globl asm_builtin_d2i
        .globl asm_builtin_d2l
 
-       .globl asm_criticalsections
-       .globl asm_getclassvalues_atomic
-
 
 asm_abstractmethoderror:
        .long 0
@@ -103,6 +78,24 @@ asm_builtin_d2i:
 asm_builtin_d2l:
        .long 0
 
+/* Generates a PIC call.
+ *
+ * func: function to call
+ * tag: tag unique for this call to generate a label
+ * tmp: one temporary register needed for calculation
+ *
+ * The offset table used is located at the bottom of this file.
+ *
+ * Note: destroys r12/itmp2. r12 MUST contain GOT for PIC calls!
+ */
+#define CALL_PIC(func, tag)                                                         \
+       bras   %r14, L_bras_##tag;                           /* get PC */               \
+L_bras_##tag:                                                                       \
+       l      %r12, L_offsets - L_bras_##tag (%r14);        /* load offset to PLT */   \
+       la     %r12, L_offsets - L_bras_##tag (%r12, %r14);  /* load PLT address */     \
+       l      %r14, L_offset_##func - L_bras_##tag (%r14);  /* load offset to func */  \
+       bas    %r14, 0(%r14, %r12);
+
 /********************* function asm_calljavafunction ***************************
 *                                                                              *
 *   This function calls a Java-method (which possibly needs compilation)       *
@@ -137,322 +130,80 @@ asm_vm_call_method_long:
 asm_vm_call_method_float:
 asm_vm_call_method_double:
 
-/*
-
-a0:   methodinfo *m
-a1:   s4 vmargscount   ---> v0: java_objectheader *
-a2:   vm_arg *vmargs
-r14:  return address
-
-96 ...     on stack parameters (none)
-0 - 96     register save area
--------------------------------------------------- <- SP on asm_vm_... entry
-           local variables
-                  saved return address (important to be at 0(sp) because of md_stacktrace_get_returnaddress)
------------------------------------------ <- SP after stack frame allocation
-           arguments on stack
----------------------------------------------------- <- SP on JIT code entry
-           saved return address (callee saved)
-
-*/
-
-
-/*
-       Regiser usage:
-       itmp1: argument block pointer
-       itmp2: argument counter
-       s0: integer argument counter
-       s1: float argument counter
-       s2: integer register counter
-       s3: backup argument block pointer
-       s4: backup argument count
-*/
-
-       stm   %r6, %r15, 24(sp)               /* save callers regiters */
-       stm   a0, a2, 8(sp)                   /* save arguments */
-       ahi   sp, -8                          /* allocate stack space for local variables */
-       st    %r14, 0(sp)                     /* store RA once more at bottom of stack frame */
-
-       ltr   a1, a1                          /* maybe we have no args... */
-       je    L_no_args
-
-       lr    itmp2, a1                       /* load arg count */
-       lr    itmp1, a2                       /* load arg pointer */
-
-       ahi   itmp1, -sizevmarg               /* initialize arg pointer */
-       ahi   itmp2, 1                        /* initialize arg count */ 
-       lhi   s0, 0                           /* initialize integer arg counter */
-       lhi   s2, 0                           /* initialize integer register counter */
-       lhi   s1, 0                           /* initialize float arg counter */
-
-       lr    s4, a1                          /* backup arg count */
-       lr    s3, a2                          /* backup arg pointer */
-
-L_register_copy:
-
-       ahi   itmp1, sizevmarg                /* forward arg pointer */
-       ahi   itmp2, -1                       /* decrement arg count */
-       je    L_register_copy_done            /* no arguments left */
-
-       tm    offvmargtype(itmp1), 0x02       /* is this a float/double type? */
-       jne   L_register_handle_float
-
-L_register_handle_int:
-
-       chi   s2, INT_ARG_CNT                 /* are we out of integer arg registers ? */
-       je    L_register_copy                 /* yes, next loop */
-
-       tm    offvmargtype(itmp1), 0x01       /* is this a 2 word type ? */
-       jne   L_register_handle_long
-
-       ahi   s0, 1                           /* increment integer arg counter */
-       ahi   s2, 1                           /* increment integer register counter */
-
-       /* handle argument */
-
-       chi   s2, 1
-       je    L_handle_i0
-       chi   s2, 2
-       je    L_handle_i1
-       chi   s2, 3
-       je    L_handle_i2
-       chi   s2, 4
-       je    L_handle_i3
-       chi   s2, 5
-       je    L_handle_i4
-
-L_register_handle_long:
-
-       chi   s2, (INT_ARG_CNT - 1)           /* are there 2 integer arg registers left ? */
-       jl    L_register_handle_long_continue /* yes */
-       lhi   s2, INT_ARG_CNT                 /* no, drop last register */
-       j     L_register_copy
-
-L_register_handle_long_continue:
-
-       ahi   s0, 1                           /* increment integer arg counter */
-       ahi   s2, 2                           /* consume 2 integer arg registers */
-
-       /* handle argument */
-
-       chi   s2, 1
-       je    L_handle_l0
-       chi   s2, 2
-       je    L_handle_l1
-       chi   s2, 3
-       je    L_handle_l2
-       chi   s2, 4
-       je    L_handle_l3
-
-L_register_handle_float:
-
-       chi   s1, FLT_ARG_CNT                 /* are we out of float arg registers */
-       je    L_register_copy                 /* no arg regisers left */
-
-       ahi   s1, 1                           /* increment float argument counter */
-
-       tm    offvmargtype(itmp1), 0x01       /* is this a 2 word type ? */
-       jne   L_register_handle_double
-
-       /* handle argument */
-
-       chi   s1, 1
-       je    L_handle_f0
-       chi   s1, 2
-       je    L_handle_f1
-
-L_register_handle_double:
-
-       /* handle argument */
-
-       chi   s1, 1
-       je    L_handle_d0
-       chi   s1, 2
-       je    L_handle_d1
-
-L_register_copy_done:
-
-/*
-       Regiser usage:
-       itmp1: argument block pointer
-       itmp2: argument counter
-       s0: integer argument counter (initialized by previous code) 
-       s1: float argument counter (initialized by previous code)
-       s2: pointer to current argument on stack
-       s3: backup argument block pointer (used to initialize itmp1)
-           after used as backup of original stack pointer
-       s4: backup argument count (used to initialize itmp2)
-           after used as size of parameters on stack
-*/
-
-       lr    itmp2, s4                     /* restore argument counter */
-       lr    itmp1, s3                     /* restore argument block pointer */
-
-                                           /* calculate remaining arguments */
-       sr    s4, s0                        /* - integer arguments in registers */
-       sr    s4, s1                        /* - float arguments in registers */
-
-       lr    s3, sp                        /* backup stack pointer (does not alter CC) */
-
-       je    L_copy_done                   /* no arguments left for stack */
-
-       sll   s4, 3                         /* allocate 8 bytes per parameter on stack */       
-       sr    sp, s4                        /* allocate stack space for arguments */ 
-
-       lr    s2, sp                        /* points now to current argument on stack */
-
-       ahi   itmp1, -sizevmarg             /* initialize argument block pointer */
-       ahi   itmp2, 1                      /* initialize argument counter */
-
-L_stack_copy_loop:
-
-       ahi   itmp1, sizevmarg              /* forward argument block pointer */
-       ahi   itmp2, -1                     /* decrement argument counter */
-       je    L_copy_done                   /* all arguments done */
-
-       tm    offvmargtype(itmp1), 0x0      /* is this a float/double type? */
-       jne   L_stack_handle_float
-
-L_stack_handle_int:
-
-       ahi   s0, -1                         /* decrement number of integer arguments in regs */
-       jhe   L_stack_copy_loop              /* argument is in register */
-
-       tm    offvmargtype(itmp1), 0x01      /* is this a 2 word type ? */
-       jne   L_stack_handle_long
-
-       mvc   0(4, s2), offvmargdata+4(itmp1) /* copy integer value */
-       ahi   s2, 4
-       j     L_stack_copy_loop
-
-L_stack_handle_long:
-
-       mvc   0(8, s2), offvmargdata(itmp1)  /* copy long value */
-       ahi   s2, 8
-       j     L_stack_copy_loop
-
-L_stack_handle_float:
+       ahi sp, -8*4                /* allocate stack frame */
 
-       ahi   s1, -1                         /* decrement number of float arguments in regs */
-       jhe   L_stack_copy_loop              /* argument is in register */
+       /* a0: PV */
+       /* a1: data structure */
+       /* a2: number of stack arguments */
 
-       tm    offvmargtype(itmp1), 0x01      /* is this a 2 word type ? */
-       jne   L_stack_handle_double
+       st    s0, 0*4(sp)           /* store used calle saved registers */
+       st    s1, 1*4(sp)
+       st    a0, 2*4(sp)
+       st    mptr, 3*4(sp)         /* mptr/itmp2 is callee saved in terms of C abi */
+       st    pv, 4*4(sp)
+       st    a4, 5*4(sp)           /* a4 is callee saved in terms of C abi */
+       st    ra, 6*4(sp)
 
-       mvc   0(4, s2), offvmargdata(itmp1)  /* copy float value */
-       ahi   s2, 4
-       j     L_stack_copy_loop
+       lr    s0, a1                /* data structure */
+       lr    %r0, a2               /* number of stack arguments */
 
-L_stack_handle_double:
+       l     a0, 0*8+4(s0)         /* big endian */
+       l     a1, 1*8+4(s0)
+       l     a2, 2*8+4(s0)
+       l     a3, 3*8+4(s0)
+       l     a4, 4*8+4(s0)         
 
-       mvc   0(8, s2), offvmargdata(itmp1)  /* copy double value */
-       ahi   s2, 8
-       j     L_stack_copy_loop
+       ld    fa0, 5*8(s0)
+       ld    fa1, 6*8(s0)
 
-L_copy_done:
+       lr    s1, sp                /* backup stack pointer */
 
-       /* Now we call the compiler in a rather questionable way i needed
-        * some days to understand:
-        *
-        * We can't simply call asm_call_jit_compiler, but we have to call an 
-        * address loaded from memory like it is done in JIT code.
-        *
-        * This is because the compiler will intercept the instruction before 
-        * the call instruction, extract the address where the function pointer
-        * has been loaded from and overwrite it with the code entry.
-        *
-        * Arguments are passed in temporary registers.
-        */
+       ltr   %r0, %r0              /* are there any stack arguments ? */
+       je    L_asm_vm_call_method_stack_copy_done
+       lr    %r1, %r0              /* copy number of stack arguments */
+       sll   %r1, 3                /* calculate stackframe size */ 
+       sr    sp, %r1               /* allocate stack frame */
+       lr    %r1, sp               /* temporary stack pointer */
 
-       /* load address of L_asm_call_jit_compiler into memory */
+L_asm_vm_call_method_stack_copy_loop:
 
-       basr  mptr, 0                         /* store PC */
-L_basr:
-       la    mptr, L_asm_call_jit_compiler-L_basr(mptr) /* add offset to PC */
-       st    mptr, 4(s3)                     /* store on stack */
+       mvc   0(8, %r1), 7*8(s0)    /* copy argument */
+       ahi   %r1, 8                /* increase sp */
+       ahi   s0, 8                 /* set address of next argument */
+       ahi   %r0, -1               /* substract 1 argument */
+       jh    L_asm_vm_call_method_stack_copy_loop
 
-       l     itmp1, 8+8(s3)                  /* load methodinfo for compiler */
-       la    mptr, 4(s3)                     /* store **function in mptr for compiler */
+L_asm_vm_call_method_stack_copy_done:
 
-       /* call L_asm_call_jit_compiler like JIT code would do */
+       la    mptr, 2*4(s1)         /* load method pointer */
+       l     pv, 0(mptr)           /* load procedure vector from method pointer */
+       basr  ra, pv                /* call method */
+       lr    sp, s1                /* restore stack pointer */
 
-       l     itmp3, 0(mptr)                  /* load address of target from memory */
-       basr  %r14, itmp3                     /* jump to target */
+L_asm_vm_call_method_return:
 
-       /* todo will s4 survive the call? */
-       ar    sp, s4                          /* remove stack space for arguments */
+       l     s0, 0*4(sp)           /* restore used callee saved registers */
+       l     s1, 1*4(sp)
+       l     mptr, 3*4(sp)
+       l     pv, 4*4(sp)
+       l     a4, 5*4(sp)
+       l     ra, 6*4(sp)
 
-L_asm_vm_call_method_return:
+       ahi   sp, 8*4               /* remove stackframe */
+       br    ra                    /* return */
 
-       ahi   sp, 8                           /* remove stack space for local variables */
-       lm    %r6, %r15, 24(sp)               /* restore callers registers */
-       br    %r14                            /* return */
 
 asm_vm_call_method_exception_handler:
        lr    a0, xptr
 
-       bras  %r14, L_avcmeh_bras
-       .long builtin_throw_exception
-L_avcmeh_bras:
-       l     %r14, 0(%r14)
        ahi   sp, -96
-       basr  %r14, %r14
+       CALL_PIC(builtin_throw_exception, avcmeh)
        ahi   sp, 96
 
        j     L_asm_vm_call_method_return
 
-/* .... */
-
-L_no_args:
-       lr    s3, sp
-       lhi   s4, 0
-       j     L_copy_done
-
-L_handle_i0:
-       l     a0, offvmargdata+4(itmp1)
-       j     L_register_copy
-L_handle_i1:
-       l     a1, offvmargdata+4(itmp1)
-       j     L_register_copy
-L_handle_i2:
-       l     a2, offvmargdata+4(itmp1)
-       j     L_register_copy
-L_handle_i3:
-       l     a3, offvmargdata+4(itmp1)
-       j     L_register_copy
-L_handle_i4:
-       l     a4, offvmargdata+4(itmp1)
-       j     L_register_copy
-
-L_handle_l0:
-       lm    a0, a1, offvmargdata(itmp1)
-       j     L_register_copy
-L_handle_l1:
-       lm    a1, a2, offvmargdata(itmp1)
-       j     L_register_copy
-L_handle_l2:
-       lm    a2, a3, offvmargdata(itmp1)
-       j     L_register_copy
-L_handle_l3:
-       lm    a3, a4, offvmargdata(itmp1)
-       j     L_register_copy
-
-L_handle_f0:
-       le    fa0, offvmargdata(itmp1)
-       j     L_register_copy
-L_handle_f1:
-       le    fa1, offvmargdata(itmp1)
-       j     L_register_copy
-
-L_handle_d0:
-       ld    fa0, offvmargdata(itmp1)
-       j     L_register_copy
-L_handle_d1:
-       ld    fa1, offvmargdata(itmp1)
-       j     L_register_copy
-
 asm_vm_call_method_end:
-       nop
+       brc   0,0       
 
 /****************** function asm_call_jit_compiler *****************************
 *                                                                              *
@@ -484,7 +235,7 @@ argument registers: arguments (like in JIT)
 asm_call_jit_compiler:
 L_asm_call_jit_compiler:
 
-#      define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96)
+#      define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96 + 4)
 
        ahi     sp,-ACJC_STACKFRAME        /* allocate stack space */
 
@@ -500,13 +251,7 @@ L_asm_call_jit_compiler:
        la      a2,ACJC_STACKFRAME(sp)     /* pass java sp                       */
        la      a3,0(%r14)                 /* pass return address, make sure bit 32 is 0 */
 
-       /* call jit_asm_compile in a PIC way */
-
-       bras    itmp2, L_bras_jac
-       .long   jit_asm_compile
-L_bras_jac:
-       l       itmp2, 0(itmp2)
-       basr    %r14, itmp2
+       CALL_PIC(jit_asm_compile, acjc)
 
        lr      pv, v0                     /* save return value */
 
@@ -525,18 +270,15 @@ jit_code_entry:                        /* label to set breakpoint on */
 
 
 L_asm_call_jit_compiler_exception:
-       bras    itmp2, L_bras_acjce
-       .long exceptions_get_and_clear_exception
-L_bras_acjce:
-       l       itmp2, 0(itmp2)
-       basr    %r14, itmp2
+
+       CALL_PIC(exceptions_get_and_clear_exception, acjce)
+
        lr      xptr, %r2
        l       xpc,96+32(sp)              /* restore return address */
        ahi     sp, ACJC_STACKFRAME        /* remove stack frame */
        j       L_asm_handle_nat_exception
 
 
-#if 0
 /* asm_handle_exception ********************************************************
 *                                                                              *
 *   This function handles an exception. It does not use the usual calling      *
@@ -547,478 +289,177 @@ L_bras_acjce:
 *                                                                              *
 *******************************************************************************/
 
-#endif
-
 asm_handle_nat_exception:
 L_asm_handle_nat_exception:
        /* TODO really nothing here ? */
 asm_handle_exception:
-L_asm_handle_exception:                 /* required for PIC code              */
-
-       ahi     sp, -(ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* create maybe-leaf stackframe */
-       STORE_ARGUMENT_REGISTERS(0)
-       STORE_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)      
-       lhi     a3, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* prepare a3 for handle_exception */
-
-       lhi     %r0, 1                      /* set maybe-leaf flag */
-
-L_asm_handle_exception_stack_loop:
-       ahi     sp,-(6*4)
-       st      xptr,0*4(sp)                /* save exception pointer             */
-       st      xpc,1*4(sp)                 /* save exception pc                  */
-       la      a3,(6*4)(a3,sp)             /* calculate Java sp into a3...       */
-       st      a3,3*4(sp)                  /* ...and save it                     */
-       st      %r0,4*4(sp)                 /* save maybe-leaf flag               */
-
-       lr      a0,xpc                      /* exception pc                       */
-
-       ahi     sp,-96                      /* add register save area for C code */
-
-       bras    %r14,L_ahe_bras             /* call codegen_get_pv_from_pc */
-       .long   codegen_get_pv_from_pc
-L_ahe_bras:
-       l       %r14,0(%r14)
-       basr    %r14,%r14
-       st      v0,2*4+96(sp)               /* save data segment pointer          */
-    
-       lr      a2,v0                       /* pass data segment pointer          */
-       l       a0,0*4+96(sp)               /* pass exception pointer             */
-       l       a1,1*4+96(sp)               /* pass exception pc                  */
-       l       a3,3*4+96(sp)               /* pass Java stack pointer            */
-
-       bras    %r14,L_ahe_bras2            /* call exceptions_handle_exception */
-       .long   exceptions_handle_exception
-L_ahe_bras2:
-       l       %r14,0(%r14)
-       basr    %r14,%r14
-
-       ahi     sp,96                       /* remove regiser save area for C code */
-
-       ltr     v0,v0
-       jz      L_asm_handle_exception_not_catched
-
-       lr      xpc,v0                      /* move handlerpc into xpc            */
-       l       xptr,0*4(sp)                /* restore exception pointer          */
-       l       %r0,4*4(sp)                 /* get maybe-leaf flag                */
-       ahi     sp,(6*4)                    /* free stack frame                   */
-
-       ltr     %r0, %r0
-       jz      L_asm_handle_exception_no_leaf
-
-       LOAD_ARGUMENT_REGISTERS(0)
-       LOAD_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)       
-
-       ahi     sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
-
-L_asm_handle_exception_no_leaf:
-       br      xpc                         /* jump to the handler */
-
-L_asm_handle_exception_not_catched:
-       l       xptr,0*4(sp)                /* restore exception pointer          */
-       l       itmp3,2*4(sp)               /* restore data segment pointer       */
-       ahi     itmp3,-0xfff                /* for negative displacements */
-       l       %r0,4*4(sp)                 /* get maybe-leaf flag                */
-       ahi     sp,(6*4)
-
-       ltr     %r0,%r0
-       jz      L_asm_handle_exception_no_leaf_stack
-
-       ahi     sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
-       lhi     %r0,0                       /* clear the isleaf flags             */
-
-       /*
-       +-----------------+-----------+---------+----+
-       | Memuse          | Float Sav | Int Sav | RA |
-       |                 | 0 ... n   | 0 ... n |    |
-       +-----------------+-----------+---------+----+
-       ^                 ^           ^
-       SP                F           I
-       */
-
-L_asm_handle_exception_no_leaf_stack:
-
-       l       itmp2,0xfff+FrameSize(itmp3)/* get frame size                     */
-       la      itmp2,0(itmp2,sp)           /* pointer to save area */
-       ahi     itmp2,-4                    /* skip RA */
-
-       l       a0,0xfff+IntSave(itmp3)     /* a0 = saved int register count  */
-
-       ltr     a0,a0
-       je      noint
-
-       sll     a0,2                        /* a0 = saved int register count * 4 */
-       sr      itmp2, a0                   /* skip Int Sav */
-
-       chi     a0,1*4
-       je      int1
-       chi     a0,2*4
-       je      int2
-       chi     a0,3*4
-       je      int3
-       chi     a0,4*4
-       je      int4
-       
-       l       s0,0*4(itmp2)
-int4:   
-       l       s1,1*4(itmp2)
-int3:   
-       l       s2,2*4(itmp2)
-int2:   
-       l       s3,3*4(itmp2)
-int1:   
-       l       s4,4*4(itmp2)
-
-noint:
-
-       l       a0,0xfff+FltSave(itmp3)
-       ltr         a0,a0                       /* Number of saved floating point registers */
-       je      noflt
-
-       sll     a0,3                        /* Number of saved floating point registers * 8 */
-       sr      itmp2,a0
-       
-       chi     a0,1*8
-       je      flt1
-       chi    a0,2*8
-       je      flt2
-
-flt2:   
-       ld    %f6,1*8(itmp2)
-flt1:   
-       ld    %f4,0*8(itmp2)
-                
-noflt:
-
-       l       itmp3,0xfff+FrameSize(itmp3)/* get frame size (at least 4 - RA)   */
-       ahi     itmp3,-4                    /* substract 4 */
-       l       xpc,0(itmp3,sp)             /* load the new xpc -  return address */
-       la      sp, 4(itmp3,sp)             /* unwind stack                       */
-
-                                           /* exception pointer is still set     */
-#if 0
-       sub     $3,xpc                      /* subtract 3 bytes for call          */
-#endif
+L_asm_handle_exception:
 
-       lhi     a3,0                        /* prepare a3 for handle_exception    */
-       
-       j               L_asm_handle_exception_stack_loop
+       /* a wrapper for md_handle_exception */
 
+#      define STACKFRAMESIZE (96 + (16 * 4) + (16 * 8) + (4 * 4))
+#      define REGS 96
+#      define FREGS (96 + (16 * 4))
+#      define OUT (96 + (16 * 4) + (16 * 8))
 
-#if 0
+       ahi   sp, -STACKFRAMESIZE   /* allocate stack frame containing the arrays */
 
-/* asm_abstractmethoderror *****************************************************
+       /* store special registers to array */
 
-   Creates and throws an AbstractMethodError.
+       st    xptr, REGS+(1*4)(sp)
+       st    xpc, REGS+(12*4)(sp)
+       st    pv, REGS+(13*4)(sp)
+       la    itmp3, STACKFRAMESIZE(sp)
+       st    itmp3, REGS+(15*4)(sp)
 
-*******************************************************************************/
+       /* store temporary and argument registers */
 
-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
-
-#endif
+       stm   a0, a4, REGS+(2*4)(sp)
+       std   %f0, FREGS+(0*8)(sp)
+       std   %f1, FREGS+(1*8)(sp)
+       std   %f2, FREGS+(2*8)(sp)
+       std   %f3, FREGS+(3*8)(sp)
+       std   %f5, FREGS+(5*8)(sp)
+       std   %f7, FREGS+(7*8)(sp)
+       std   %f8, FREGS+(8*8)(sp)
+       std   %f9, FREGS+(9*8)(sp)
+       std   %f10, FREGS+(10*8)(sp)
+       std   %f11, FREGS+(11*8)(sp)
+       std   %f12, FREGS+(12*8)(sp)
+       std   %f13, FREGS+(13*8)(sp)
+       std   %f14, FREGS+(14*8)(sp)
+       std   %f15, FREGS+(15*8)(sp)
 
-/* asm_patcher_wrapper *********************************************************
+       /* call md_handle_exception */
 
-   XXX
+       la    a0, REGS(sp)
+       la    a1, FREGS(sp)
+       la    a2, OUT(sp)
 
-   Stack layout:
-     20   return address into JIT code (patch position)
-     16   pointer to virtual java_objectheader
-     12   machine code (which is patched back later)
-      8   unresolved class/method/field reference
-      4   data segment displacement from load instructions
-      0   patcher function pointer to call (pv afterwards)
+       CALL_PIC(md_handle_exception, ahe)
 
-*******************************************************************************/
+       l     itmp3, OUT+(2*4)(sp)  /* out[2] contains maybe leaf flag */
+       ltr   itmp3, itmp3           
+       je    L_restore_saved
 
-asm_patcher_wrapper:
-#      define  apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
+L_restore_temporary_and_argument:
 
-       ahi     sp, -apw_sfs                /* create stack frame */
+       /* if we are maybe leaf,
+        * we have to restore argument and temporary registers
+        */
 
-       /* store all volatile registers and a2, because we will touch it */
+       lm    a0, a4, REGS+(2*4)(sp)
+       ld    %f0, FREGS+(0*8)(sp)
+       ld    %f1, FREGS+(1*8)(sp)
+       ld    %f2, FREGS+(2*8)(sp)
+       ld    %f3, FREGS+(3*8)(sp)
+       ld    %f5, FREGS+(5*8)(sp)
+       ld    %f7, FREGS+(7*8)(sp)
+       ld    %f8, FREGS+(8*8)(sp)
+       ld    %f9, FREGS+(9*8)(sp)
+       ld    %f10, FREGS+(10*8)(sp)
+       ld    %f11, FREGS+(11*8)(sp)
+       ld    %f12, FREGS+(12*8)(sp)
+       ld    %f13, FREGS+(13*8)(sp)
+       ld    %f14, FREGS+(14*8)(sp)
+       ld    %f15, FREGS+(15*8)(sp)
+
+       j     L_restore_done
+
+L_restore_saved:
+
+       /* if we are not a maybe leaf,
+        * we have to restore callee saved registers of the callee
+        */
 
-       st      a2, 96(sp)
-       STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
-       STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
+       l     itmp3, OUT+(0*4)(sp)  /* out[0] contains IntSav */
 
-       /* pass arguments */
+       ahi   itmp3, -1
+       jl    L_int_done
+       l     s4, REGS+(11*4)(sp)
 
-       la      a0, apw_sfs(sp)             /* pass SP of patcher stub */
-       lr      a1, pv                      /* pass PV (if NULL, use findmethod)  */
-       lhi     a2, 0                       /* pass RA                            */
+       ahi   itmp3, -1
+       jl    L_int_done
+       l     s3, REGS+(10*4)(sp)
 
-       /* call patcher_wrapper */
+       ahi   itmp3, -1
+       jl    L_int_done
+       l     s2, REGS+(9*4)(sp)
 
-       bras    itmp1, L_apw_bras           /* call patcher_wrapper */
-       .long   patcher_wrapper
-L_apw_bras:
-       l       itmp1, 0(itmp1)
-       basr    %r14, itmp1
+       ahi   itmp3, -1
+       jl    L_int_done
+       l     s1, REGS+(8*4)(sp)
 
-       /* store return value */
+       ahi   itmp3, -1
+       jl    L_int_done
+       l     s0, REGS+(7*4)(sp)
 
-       st      v0,0(sp)                    /* save return value */
+L_int_done:
 
-       /* restore volatile registers */
+       /* restore callee saved float registers */
 
-       l       a2, 96(sp)
-       LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
-       LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
+       l     itmp3, OUT+(1*4)(sp)   /* out[1] contains FltSav */
 
-       l       itmp3, 0(sp)                /* restore return value */
-       ltr     itmp3, itmp3                /* exception thrown ? */
-       jne     L_asm_patcher_wrapper_exception /* handle exception */
-       l       itmp3, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
-       ahi     sp, apw_sfs + (6 * 4)       /* remove stack frame, and stack frame by patcher stub */
-       br      itmp3                       /* return */
+       ahi   itmp3, -1
+       jl    L_flt_done
+       ld    %f6, FREGS+(6*8)(sp)
 
-L_asm_patcher_wrapper_exception:
-       lr      xptr,itmp3                  /* get exception                      */
-       l       xpc, apw_sfs + (5 * 4)(sp)  /* load return address to JIT from stack */
-       ahi     sp, apw_sfs + (6 * 4)       /* remove stack frame, and stack frame by patcher stub */
-       j       L_asm_handle_exception
+       ahi   itmp3, -1
+       jl    L_flt_done
+       ld    %f4, FREGS+(4*8)(sp)
 
-#if 0
+L_flt_done:
 
-/* asm_replacement_out *********************************************************
+L_restore_done:
 
-   This code is jumped to from the replacement-out stubs that are executed
-   when a thread reaches an activated replacement point.
+       /* write new values for special registers */
 
-   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.
+       l     xptr, REGS+(1*4)(sp)
+       l     xpc, REGS+(12*4)(sp)
+       l     pv, REGS+(13*4)(sp)  
+       l     sp, REGS+(15*4)(sp)   
 
-   Stack layout:
-      8                 start of stack inside method to replace
-      0   rplpoint *    info on the replacement point that was reached
+       br    xpc                   /* jump to handler */
 
-*******************************************************************************/
+#      undef STACKFRAMESIZE
+#      undef REGS
+#      undef FREGS
+#      undef OUT
 
-/* some room to accomodate changes of the stack frame size during replacement */
-       /* XXX we should find a cleaner solution here */
-#define REPLACEMENT_ROOM  512
+#if 0
 
-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);
+/* asm_abstractmethoderror *****************************************************
 
-*******************************************************************************/
+   Creates and throws an AbstractMethodError.
 
-asm_replacement_in:
-       mov     a0,%rbp                     /* executionstate *es                 */
-
-       /* set new sp */
-       mov     (offes_sp)(%rbp),%rsp
-       
-       /* store address of new code */
-       push    (offes_pc)(%rbp)
-       
-       /* copy registers from execution state */
-       movq    (XMM0 *8+offes_fltregs)(%rbp),%xmm0
-       movq    (XMM1 *8+offes_fltregs)(%rbp),%xmm1
-       movq    (XMM2 *8+offes_fltregs)(%rbp),%xmm2
-       movq    (XMM3 *8+offes_fltregs)(%rbp),%xmm3
-       movq    (XMM4 *8+offes_fltregs)(%rbp),%xmm4
-       movq    (XMM5 *8+offes_fltregs)(%rbp),%xmm5
-       movq    (XMM6 *8+offes_fltregs)(%rbp),%xmm6
-       movq    (XMM7 *8+offes_fltregs)(%rbp),%xmm7
-       movq    (XMM8 *8+offes_fltregs)(%rbp),%xmm8
-       movq    (XMM9 *8+offes_fltregs)(%rbp),%xmm9
-       movq    (XMM10*8+offes_fltregs)(%rbp),%xmm10
-       movq    (XMM11*8+offes_fltregs)(%rbp),%xmm11
-       movq    (XMM12*8+offes_fltregs)(%rbp),%xmm12
-       movq    (XMM13*8+offes_fltregs)(%rbp),%xmm13
-       movq    (XMM14*8+offes_fltregs)(%rbp),%xmm14
-       movq    (XMM15*8+offes_fltregs)(%rbp),%xmm15
-
-       mov     (RAX*8+offes_intregs)(%rbp),%rax
-       mov     (RBX*8+offes_intregs)(%rbp),%rbx
-       mov     (RCX*8+offes_intregs)(%rbp),%rcx
-       mov     (RDX*8+offes_intregs)(%rbp),%rdx
-       mov     (RSI*8+offes_intregs)(%rbp),%rsi
-       mov     (RDI*8+offes_intregs)(%rbp),%rdi
-       mov     (R8 *8+offes_intregs)(%rbp),%r8
-       mov     (R9 *8+offes_intregs)(%rbp),%r9
-       mov     (R10*8+offes_intregs)(%rbp),%r10
-       mov     (R11*8+offes_intregs)(%rbp),%r11
-       mov     (R12*8+offes_intregs)(%rbp),%r12
-       mov     (R13*8+offes_intregs)(%rbp),%r13
-       mov     (R14*8+offes_intregs)(%rbp),%r14
-       mov     (R15*8+offes_intregs)(%rbp),%r15
-
-       mov     (RBP*8+offes_intregs)(%rbp),%rbp
-
-       /* jump to new code */
-       ret
-
-
-/* asm_builtin_x2x *************************************************************
-*                                                                              *
-*   Wrapper functions for float to int corner cases                            *
-*                                                                              *
 *******************************************************************************/
 
-asm_builtin_f2i:
-       sub     $(ARG_CNT*8),sp
-       
-       SAVE_ARGUMENT_REGISTERS(0)
-       
-       movq    ftmp1,fa0
-       call    builtin_f2i@PLT
-       
-       RESTORE_ARGUMENT_REGISTERS(0)
-       
-       add     $(ARG_CNT*8),sp
-       ret
-
-
-asm_builtin_f2l:
-       sub     $(ARG_CNT*8),sp
-       
-       SAVE_ARGUMENT_REGISTERS(0)
-       
-       movq    ftmp1,fa0
-       call    builtin_f2l@PLT
-       
-       RESTORE_ARGUMENT_REGISTERS(0)
-       
-       add     $(ARG_CNT*8),sp
-       ret
-
-
-asm_builtin_d2i:
-       sub     $(ARG_CNT*8),sp
-       
-       SAVE_ARGUMENT_REGISTERS(0)
-       
-       movq    ftmp1,fa0
-       call    builtin_d2i@PLT
-       
-       RESTORE_ARGUMENT_REGISTERS(0)
-       
-       add     $(ARG_CNT*8),sp
-       ret
-
+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_builtin_d2l:
-       sub     $(ARG_CNT*8),sp
-       
-       SAVE_ARGUMENT_REGISTERS(0)
-       
-       movq    ftmp1,fa0
-       call    builtin_d2l@PLT
-       
-       RESTORE_ARGUMENT_REGISTERS(0)
-       
-       add     $(ARG_CNT*8),sp
-       ret
-
-#endif /* if 0 */
-
-/* TODO use move here ? */
-
-asm_getclassvalues_atomic:
-_crit_restart:
-_crit_begin:
-       l       %r0,offbaseval(a0)
-       l       %r1,offdiffval(a0)
-       l       a3,offbaseval(a1)
-_crit_end:
-       st      %r0,offcast_super_baseval(a2)
-       st      %r1,offcast_super_diffval(a2)
-       st      a3,offcast_sub_baseval(a2)
-       br      %r14
-
-       .data
-               
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
-       .long   _crit_begin
-       .long   _crit_end
-       .long   _crit_restart
 #endif
-       .long 0
-
 
-/* disable exec-stacks ********************************************************/
-
-#if 0
-
-#if defined(__linux__) && defined(__ELF__)
-       .section .note.GNU-stack,"",@progbits
-#endif
+/* Offset table for PIC calls, see CALL_PIC */
 
+L_offsets:
+       .long  _GLOBAL_OFFSET_TABLE_ - L_offsets
+L_offset_builtin_throw_exception:
+       .long  builtin_throw_exception@PLTOFF
+L_offset_jit_asm_compile:
+       .long  jit_asm_compile@PLTOFF
+L_offset_exceptions_get_and_clear_exception:
+       .long  exceptions_get_and_clear_exception@PLTOFF
+L_offset_md_handle_exception:
+       .long  md_handle_exception@PLTOFF
 
-#endif /* if 0 */
 
 /*
  * These are local overrides for various environment variables in Emacs.