* Removed all Id tags.
[cacao.git] / src / vm / jit / sparc64 / asmpart.S
index 71c71cdafb9ec75d9c757001628ffcba194e7f46..30e64416f719ea624fc4234afe5ae89b78a68057 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/jit/sparc64/asmpart.S - Java-C interface functions for Sparc
+/* src/vm/jit/sparc64/asmpart.S - Java-C interface functions for Sparc64
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-            Alexander Jordan
-
-   Changes: 
-
-   $Id: asmpart.S 4749 2006-04-11 10:20:18Z twisti $
-
 */
 
 
 #include "config.h"
-#include "offsets.h"
+
 #include "md-asm.h"
 
+#include "vm/jit/sparc64/md-abi.h"
+
+
        .register %g2,#scratch                         /* define as scratch       */
        .register %g3,#scratch                    /* XXX  reserve for application */
        .text
        .global asm_vm_call_method_float  
        .global asm_vm_call_method_double 
        .global asm_vm_call_method_exception_handler
+       .global asm_vm_call_method_end
 
        .global asm_call_jit_compiler
 
        .global asm_handle_exception
        .global asm_handle_nat_exception
 
+       .global asm_patcher_wrapper
 
        .global asm_abstractmethoderror
        
-       .global asm_criticalsections
-       .global asm_getclassvalues_atomic
+       .global asm_store_fp_state_reg
+       .global asm_load_fp_state_reg
 
 
 /* asm_vm_call_method ******************************************************
  *                                                                         *
  * This function calls a Java-method (which possibly needs compilation)    *
  *
+ * If the java method is throwing an exception, NULL will be returned.
+ *
  * C-prototype:
  *  java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,
  *                                              vm_arg *vmargs);
@@ -97,63 +94,56 @@ asm_vm_call_method_long:
 asm_vm_call_method_float: 
 asm_vm_call_method_double:
        
-       save %sp, -144, %sp             /* 16 reg-save + 2 */
-
-
-       /* todo: copy fp registers */
-
-       brlez %i1, calljava_argsloaded
-       dec %i1
-       ldx [%i2 + offvmargdata], %o0
-       brlez %i1, calljava_argsloaded
-
-       dec %i1
-       ldx [%i2 + (offvmargdata+sizevmarg*1)], %o1
-       brlez %i1, calljava_argsloaded
-
-       dec %i1
-       ldx [%i2 + (offvmargdata+sizevmarg*2)], %o2
-       brlez %i1, calljava_argsloaded
-
-       dec %i1
-       ldx [%i2 + (offvmargdata+sizevmarg*3)], %o3
-       brlez %i1, calljava_argsloaded
-
-       dec %i1
-       ldx [%i2 + (offvmargdata+sizevmarg*4)], %o4
-
-       /* todo: use more out registers ? */
-
-calljava_argsloaded:
-       /* todo: stack frame layout!! */
+       save %sp,-((JITSTACK_CNT+2)*8),%sp
+       add %sp,JITSTACK,%l1               /* pointer to usable stack      */
+
+       /* i0: PV               */
+       /* i1: ptr to arg array */
+       /* i2: num stackargs    */
+
+       ldx [%i1+0*8],%o0
+       ldx [%i1+1*8],%o1
+       ldx [%i1+2*8],%o2
+       ldx [%i1+3*8],%o3
+       ldx [%i1+4*8],%o4
+
+       ldd [%i1+5*8],fa0
+       ldd [%i1+6*8],fa1
+       ldd [%i1+7*8],fa2
+       ldd [%i1+8*8],fa3
+       ldd [%i1+9*8],fa4
+
+       brlez %i2, calljava_nocopy
+       nop /* delay: fill me! */
        
-       brlez %i1, calljava_nocopy
-       sllx %i1, 3, %l0        /* remaining args * 8           */
-       mov %sp, %l1            /* right above window save area */
-       sub %sp, %l0, %sp       /* allocate more stack space    */
+       sllx %i2,3,%l0                     /* remaining args * 8           */
+       sub %sp,%l0,%sp                    /* allocate more stack space    */
+       add %sp,JITSTACK,%l1               /* adjust stack begin pointer   */
        
-calljava_copyloop:
-       ldx [%i2 + (offvmargdata+sizevmarg*5)], %l0
-       stx %l0, [%l1]
-       inc sizevmarg, %i2      /* src++                        */
-       inc 8, %l1              /* dst++                        */
-       dec %i1                 /* arg_count--                  */
-       bnz %xcc, calljava_copyloop
+asm_vm_call_copyloop:
+       ldx [%i1+10*8],%l0                 /* load argument from array     */
+       stx %l0,[%l1]                      /* store argument to stack      */
 
-calljava_nocopy:
+       inc 8,%i1                          /* src++                        */
+       subcc %i2,1,%i2                    /* arg_count--                  */
+       bnz %xcc, asm_vm_call_copyloop     /* use cc from previous instr   */
+       inc 8,%l1                          /* dst++ (delay)                */
 
-       mov   %i0,itmp1         /* pass method pointer via itmp1 */
+
+calljava_nocopy:
+       /* set pv, like a java method does */
+       setx  asm_vm_call_method,%l0,pv_callee
        
-       setx  asm_call_jit_compiler,%l0,mptr_itmp2  /* fake virtual function call (2 instr) */
-       stx   mptr_itmp2,[%sp + 2047 + 17*8]        /* store function address               */
-       add   %sp,2047 + 16*8,mptr_itmp2            /* set method pointer                   */
+       stx   %i0,[%l1 + 1*8]              /* store PV on stack            */
+       mov   %l1,mptr_itmp2               /* set address of PV (-1*8)     */
        
-       ldx  [1*8 + mptr_itmp2], pv_caller          /* method call as in Java               */
-       jmpl pv_caller,ra_caller                      /* call JIT compiler          */
+       ldx  [1*8 + mptr_itmp2], pv_caller /* load PV from stack           */
+       jmpl pv_caller,ra_caller           /* method call as in Java       */
        nop
+
 calljava_jit2:
        /* pretend to restore pv */
-       add  ra_caller,(asm_vm_call_method - calljava_jit2 + 8),pv_callee
+       add  ra_caller,(asm_vm_call_method - calljava_jit2 + 8),zero
        
 calljava_return:
        mov %o0, %i0            /* pass on the return value     */
@@ -162,10 +152,17 @@ calljava_return:
 
 
 asm_vm_call_method_exception_handler:
-       mov             itmp1,%o0
+       
+       /* so far this function did not call any c functions */
+       /* but now we need ABI compliant argslots on the stack */
+       sub   %sp,6*8,%sp
+       
+       mov             xptr_itmp2,%o0
        call    builtin_throw_exception
-       return  %i7 + 8                          /* implicit window restore */
        nop
+       return  %i7 + 8                          /* implicit window restore */
+asm_vm_call_method_end:
+       mov    zero,%o0                  /* delay: return NULL      */
        
 
 
@@ -191,44 +188,50 @@ asm_vm_call_method_exception_handler:
 
 asm_call_jit_compiler:
        
-       /* XXX save + reserve stack space          */
-       /* XXX save float arg registers */
+       /* stacksave for regsave(16) + argslots(6) + float args  */
+       /* Note: +1 to keep stack 16-byte aligned                */
+       save    %sp,-((16+6+FLT_ARG_CNT+1)*8),%sp
+
+       SAVE_FLOAT_ARGUMENT_REGISTERS(22)
 
        mov     itmp1,%o0             /* pass methodinfo pointer                  */
        mov     mptr_itmp2,%o1        /* pass method pointer                      */
        mov     %fp,%o2                           /* pass java sp (==fp)                          */
-       mov     ra_caller,%o3         /* pass Java ra                             */
+       mov     ra_callee,%o3         /* pass Java ra                             */
        mov     %o3,%o4               /* xpc is equal to ra                       */
        call    jit_asm_compile       /* call jit compiler                        */
        nop
+       
+       RESTORE_FLOAT_ARGUMENT_REGISTERS(22)
 
-       mov     %o0,pv_callee         /* save return value into callee(!) pv      */
-                                     /* the in's we have are also the in's of the*/
-                                     /* method that will be called               */
-
-       /* XXX do a window restore here ???  */
-       /* XXX restore float argument registers */
+       brz     %o0,L_asm_call_jit_compiler_exception
+       nop
+       
+       restore %o0,%g0,pv_caller     /* restore the callers window               */
+                                     /* the source o0 references the old window  */
+                                     /* pv_caller references the new window      */
 
-       brz     pv_callee,L_asm_call_jit_compiler_exception
 
        /* synchronise instruction cache moved somewhere else           */
 
-       jmpl    pv_callee,zero        /* and call method, the method returns      */
-                                     /* directly to the caller (ra).             */    
+       jmpl    pv_caller,zero        /* and call method, the method returns      */
+                                     /* directly to the caller (ra).             */
+       nop     
        
 L_asm_call_jit_compiler_exception:
-       /* no need to do a save, only ra needs to be preserved */
+       /* window still open, ra_callee valid, pv_callee undefined      */
 
-       /* we save ra in one of the application globals */
-       mov     ra_caller,xpc_itmp3   /* save return address (xpc)                */
-       
        call    exceptions_get_and_clear_exception
-
-       mov     xpc_itmp3,ra_caller   /* restore return address (xpc)             */
+       nop
 
        mov     %o0,xptr_itmp2        /* get exception                            */
-       sub     ra_caller,4,xpc_itmp3 /* exception address is ra - 4              */
-       ba      L_asm_handle_nat_exception
+       mov     ra_callee,xpc_itmp3  /* exception address is address of call      */
+
+       /* restore the window of the calling function */
+       restore
+
+       b      L_asm_handle_nat_exception
+       nop
 
 
 
@@ -245,11 +248,76 @@ L_asm_call_jit_compiler_exception:
 
 asm_handle_nat_exception:
 L_asm_handle_nat_exception:       /* required for PIC code                    */
+L_asm_handle_exception_stack_loop:
+       /* exception handling assumes that the current java method saved       */
+       /* the caller's window, and has a valid pv                             */
+
+       /* get ra and pv before saving the window */
+       mov     ra_callee,itmp1
+       mov     pv_callee,%g4
+
+       save    %sp,-176,%sp
+       mov     xptr_itmp2,%l0              /* save exception pointer             */
+       mov     xpc_itmp3,%l1               /* save exception pc                  */
+       mov     zero,%l2                    /* save maybe-leaf flag (cleared)     */
+
+       mov     %l0,%o0                     /* pass xptr                          */
+       mov     %l1,%o1                     /* pass xpc                           */
+       mov     %g4,%o2                     /* pass PV                            */
+       mov     %fp,%o3                     /* pass Java SP                       */
+
+       b       L_asm_handle_exception_continue
+       nop
+
 asm_handle_exception:
+       mov     pv_callee,%g4
+
+       /* save bigger stack frame for float args and temps */
+       save    %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+16+CSTACK_CNT)*8),%sp
+
+       SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
+       SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
+
+       mov     xptr_itmp2,%l0              /* save exception pointer             */
+       add     zero,1,%l2                  /* set maybe-leaf flag                */
+
+       mov     %l0,%o0                     /* pass xptr                          */
+       mov     xpc_itmp3,%o1               /* pass xpc                           */
+       mov     %g4,%o2                     /* pass PV                            */
+       mov     %fp,%o3                     /* pass Java SP                       */
+
+L_asm_handle_exception_continue:
+       call    exceptions_handle_exception
+       nop
+
+       brz     %o0,L_asm_handle_exception_not_caught
+       nop
+
+       mov     %o0,xpc_itmp3               /* move handlerpc into xpc            */
+       mov     %l0,xptr_itmp2              /* restore exception pointer          */
+
+       brz     %l2,L_asm_handle_exception_no_leaf
+       nop
+
+       RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
+       RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
+       
+L_asm_handle_exception_no_leaf:
+       /* restore java window and stackframe (ra and pv are in there) */
+       restore
+       jmpl    xpc_itmp3, zero             /* jump to the handler                */
+       nop
+
+L_asm_handle_exception_not_caught:
+       mov     %l0,xptr_itmp2              /* restore xptr                       */
+       restore                             /* free our stackframe and window     */
+       /* maybe leaf flag gets cleared after branch to _loop */
+       
+       restore                             /* unwind stack and window            */
+       ba      L_asm_handle_exception_stack_loop
+       mov     ra_caller,xpc_itmp3         /* the new xpc is ra (delay)          */
        
-       /* nothing here */
 
-       restore zero,0,zero
 
 
 /* asm_abstractmethoderror *****************************************************
@@ -265,38 +333,128 @@ asm_abstractmethoderror:
        mov     %fp,%o0                     /* pass java sp(==fp)                 */
        mov     ra_callee,%o1               /* pass exception address             */
        call    exceptions_asm_new_abstractmethoderror
+       nop
 
        mov     %o0,xptr_itmp2              /* get exception pointer              */
        sub     ra_callee,4,xpc_itmp3       /* exception address is ra - 4        */
        ba      L_asm_handle_nat_exception
+       nop
 
        /* XXX: leave the register window open for handle_exception ??? */
 
-asm_getclassvalues_atomic:
-_crit_restart:
-_crit_begin:
-/* not doing a window save, using the global temporary registers */
-       ldsw    [offbaseval+%o0],itmp1
-       ldsw    [offdiffval+%o0],itmp2
-       ldsw    [offbaseval+%o1],itmp3
-_crit_end:
-       stw     itmp1,[offcast_super_baseval+%o2]
-       stw     itmp2,[offcast_super_diffval+%o2]
-       stw     itmp3,[offcast_sub_baseval+%o2]
-       jmpl    ra_caller,zero  /* caller's ra, b/c no window save */
-
-       .end    asm_getclassvalues_atomic
-
-
-    .data
-
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
-    .xword   _crit_begin
-    .xword   _crit_end
-    .xword   _crit_restart
-#endif
-    .xword   0
+/* asm_patcher_wrapper *********************************************************
+
+   XXX
+
+   Stack layout, when called from patcher stub
+     40   return address into JIT code (patch position)
+     32   pointer to virtual java_objectheader
+     24   machine code (which is patched back later)
+     16   unresolved class/method/field reference
+      8   data segment displacement from load instructions
+      0   patcher function pointer to call
+   -128   WINSAVE REGS (current SP)
+
+*******************************************************************************/
+               
+
+asm_patcher_wrapper:
+       /* get pv and ra, since the emit code is not passing it on */
+       mov     ra_callee,ra_caller
+       mov     pv_callee,pv_caller
+
+       /* create window and stack frame              */
+       save  %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+16+CSTACK_CNT+6)*8),%sp
+
+       SAVE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
+       SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
+       SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
+
+       mov     itmp1,%l0               /* save itmp1                             */
+       mov     itmp2,%l1               /* save itmp2                             */
+
+       add     %fp,JITSTACK,%o0      /* pass pseudo SP                           */
+       mov     pv_callee,%o1         /* pass PV                                  */
+       mov     ra_callee,%o2         /* pass RA (correct for leafs)              */
+       call    patcher_wrapper
+       nop
 
+       RESTORE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
+       RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
+       RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
+
+       mov     %l0,itmp1               /* restore itmp1                          */
+       mov     %l1,itmp2               /* restore itmp2                          */
+
+       brnz    %o0,L_asm_patcher_wrapper_exception
+       nop
+
+       /* load RA (patch position from patcher data on the stack */
+       ldx     [%fp+JITSTACK+5*8],itmp3
+
+       /* remove window and stack frame (and stack space allocated in the stub code */
+       restore  %fp,6*8,%sp /* (source regs refer to old window, rd to new window)  */
+
+       jmpl     itmp3,zero              /* jump to newly patched code               */
+       nop
+
+L_asm_patcher_wrapper_exception:
+       mov      %o0,xptr_itmp2        /* get exception                            */
+       ldx      [%fp+JITSTACK+5*8],xpc_itmp3 /* xpc is RA                         */
+       restore  %fp,6*8,%sp           /* remove stack frame                       */
+       ba       asm_handle_exception
+       nop
+
+
+    
+/* asm_store_fp_state_reg **************************************************
+ *                                                                         *
+ * This function stores the 64-bit floating point state register to a      *
+ * memory location. (which needs to be 8-byte aligned)                     *
+ *                                                                         *
+ * C-prototype:                                                            *
+ *  void asm_store_fp_state_reg(u8 *mem);                                  *
+ *                                                                            *
+ **************************************************************************/
+asm_store_fp_state_reg:
+       stx %fsr,[%o0]
+       retl  /* return from leaf */
+       nop
+       
+/* asm_load_fp_state_reg ***************************************************
+ *                                                                         *
+ * This function loades the 64-bit floating point state register from a    *
+ * memory location. (which needs to be 8-byte aligned)                     *
+ *                                                                         *
+ * C-prototype:                                                            *
+ *  void asm_load_fp_state_reg(u8 *mem);                                   *
+ *                                                                            *
+ **************************************************************************/
+asm_load_fp_state_reg:
+       ldx [%o0],%fsr
+       retl  /* return from leaf */
+       nop
+
+
+/* disable exec-stacks ********************************************************/
+
+#if defined(__linux__) && defined(__ELF__)
+       .section .note.GNU-stack,"",%progbits
+#endif
 
 
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * 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:
+ */