671afc88ebe2ff39bcaf49eab321a31af9644a4c
[cacao.git] / src / vm / jit / sparc64 / asmpart.S
1 /* src/vm/jit/sparc64/asmpart.S - Java-C interface functions for Sparc64
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: asmpart.S 4749 2006-04-11 10:20:18Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include "md-asm.h"
33
34 #include "vm/jit/sparc64/md-abi.h"
35
36
37         .register %g2,#scratch                         /* define as scratch       */
38         .register %g3,#scratch                    /* XXX  reserve for application */
39         .text
40
41 /* export functions ***********************************************************/
42
43         .global asm_vm_call_method        
44         .global asm_vm_call_method_int    
45         .global asm_vm_call_method_long   
46         .global asm_vm_call_method_float  
47         .global asm_vm_call_method_double 
48         .global asm_vm_call_method_exception_handler
49         .global asm_vm_call_method_end
50
51         .global asm_call_jit_compiler
52
53         .global asm_handle_exception
54         .global asm_handle_nat_exception
55
56         .global asm_patcher_wrapper
57
58         .global asm_abstractmethoderror
59         
60         .global asm_store_fp_state_reg
61         .global asm_load_fp_state_reg
62
63
64 /* asm_vm_call_method ******************************************************
65  *                                                                         *
66  * This function calls a Java-method (which possibly needs compilation)    *
67  *
68  * If the java method is throwing an exception, NULL will be returned.
69  *
70  * C-prototype:
71  *  java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,
72  *                                               vm_arg *vmargs);
73  **************************************************************************/
74
75         .align 8        /* v9: All data types are aligned to their size */
76
77         .xword 0                         /* catch type all */
78         .xword 0                         /* handler pc */
79         .xword 0                         /* end pc */
80         .xword 0                         /* start pc */
81         .word  1                         /* extable size */
82         .word  0                         /* ALIGNMENT PADDING */
83         .xword 0                         /* line number table start */
84         .xword 0                         /* line number table size */
85         .word  0                         /* ALIGNMENT PADDING */
86         .word  0                         /* fltsave */
87         .word  1                         /* intsave */
88         .word  0                         /* isleaf */
89         .word  0                         /* IsSync */
90         .word  0                         /* frame size */
91         .xword 0                         /* method pointer (pointer to name)*/ 
92
93 asm_vm_call_method:       
94 asm_vm_call_method_int:   
95 asm_vm_call_method_long:  
96 asm_vm_call_method_float: 
97 asm_vm_call_method_double:
98         
99         save %sp,-((JITSTACK_CNT+2)*8),%sp
100         add %sp,JITSTACK,%l1               /* pointer to usable stack      */
101
102         /* i0: PV               */
103         /* i1: ptr to arg array */
104         /* i2: num stackargs    */
105
106         ldx [%i1+0*8],%o0
107         ldx [%i1+1*8],%o1
108         ldx [%i1+2*8],%o2
109         ldx [%i1+3*8],%o3
110         ldx [%i1+4*8],%o4
111
112         ldd [%i1+5*8],fa0
113         ldd [%i1+6*8],fa1
114         ldd [%i1+7*8],fa2
115         ldd [%i1+8*8],fa3
116         ldd [%i1+9*8],fa4
117
118         brlez %i2, calljava_nocopy
119         nop /* delay: fill me! */
120         
121         sllx %i2,3,%l0                     /* remaining args * 8           */
122         sub %sp,%l0,%sp                    /* allocate more stack space    */
123         add %sp,JITSTACK,%l1               /* adjust stack begin pointer   */
124         
125 asm_vm_call_copyloop:
126         ldx [%i1+10*8],%l0                 /* load argument from array     */
127         stx %l0,[%l1]                      /* store argument to stack      */
128
129         inc 8,%i1                          /* src++                        */
130         subcc %i2,1,%i2                    /* arg_count--                  */
131         bnz %xcc, asm_vm_call_copyloop     /* use cc from previous instr   */
132         inc 8,%l1                          /* dst++ (delay)                */
133
134
135 calljava_nocopy:
136         /* set pv, like a java method does */
137         setx  asm_vm_call_method,%l0,pv_callee
138         
139         stx   %i0,[%l1 + 1*8]              /* store PV on stack            */
140         mov   %l1,mptr_itmp2               /* set address of PV (-1*8)     */
141         
142         ldx  [1*8 + mptr_itmp2], pv_caller /* load PV from stack           */
143         jmpl pv_caller,ra_caller           /* method call as in Java       */
144         nop
145
146 calljava_jit2:
147         /* pretend to restore pv */
148         add  ra_caller,(asm_vm_call_method - calljava_jit2 + 8),zero
149         
150 calljava_return:
151         mov %o0, %i0            /* pass on the return value     */
152         return %i7 + 8          /* implicit window restore */
153         nop
154
155
156 asm_vm_call_method_exception_handler:
157         
158         /* so far this function did not call any c functions */
159         /* but now we need ABI compliant argslots on the stack */
160         sub   %sp,6*8,%sp
161         
162         mov             xptr_itmp2,%o0
163         call    builtin_throw_exception
164         nop
165         return  %i7 + 8                          /* implicit window restore */
166 asm_vm_call_method_end:
167         mov    zero,%o0                  /* delay: return NULL      */
168         
169
170
171 /****************** function asm_call_jit_compiler *****************************
172 *                                                                              *
173 *   invokes the compiler for untranslated JavaVM methods.                      *
174 *                                                                              *
175 *   Register R0 contains a pointer to the method info structure (prepared      *
176 *   by createcompilerstub). Using the return address in R26 and the            *
177 *   offset in the LDA instruction or using the value in methodptr R28 the      *
178 *   patching address for storing the method address can be computed:           *
179 *                                                                              *
180 *   method address was either loaded using                                     *
181 *   M_LDQ (REG_PV, REG_PV, a)        ; invokestatic/special    ($27)           *
182 *   M_LDA (REG_PV, REG_RA, low)                                                *
183 *   M_LDAH(REG_PV, REG_RA, high)     ; optional                                *
184 *   or                                                                         *
185 *   M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28)           *
186 *   in the static case the method pointer can be computed using the            *
187 *   return address and the lda function following the jmp instruction          *
188 *                                                                              *
189 *******************************************************************************/
190
191 asm_call_jit_compiler:
192         
193         /* stacksave for regsave(16) + argslots(6) + float args  */
194         /* Note: +1 to keep stack 16-byte aligned                */
195         save    %sp,-((16+6+FLT_ARG_CNT+1)*8),%sp
196
197         SAVE_FLOAT_ARGUMENT_REGISTERS(22)
198
199         mov     itmp1,%o0             /* pass methodinfo pointer                  */
200         mov     mptr_itmp2,%o1        /* pass method pointer                      */
201         mov     %fp,%o2                           /* pass java sp (==fp)                          */
202         mov     ra_callee,%o3         /* pass Java ra                             */
203         mov     %o3,%o4               /* xpc is equal to ra                       */
204         call    jit_asm_compile       /* call jit compiler                        */
205         nop
206         
207         RESTORE_FLOAT_ARGUMENT_REGISTERS(22)
208
209         brz     %o0,L_asm_call_jit_compiler_exception
210         nop
211         
212         restore %o0,%g0,pv_caller     /* restore the callers window               */
213                                       /* the source o0 references the old window  */
214                                       /* pv_caller references the new window      */
215
216
217         /* synchronise instruction cache moved somewhere else           */
218
219         jmpl    pv_caller,zero        /* and call method, the method returns      */
220                                       /* directly to the caller (ra).             */
221         nop     
222         
223 L_asm_call_jit_compiler_exception:
224         /* window still open, ra_callee valid, pv_callee undefined      */
225
226         call    exceptions_get_and_clear_exception
227         nop
228
229         mov     %o0,xptr_itmp2        /* get exception                            */
230         mov     ra_callee,xpc_itmp3  /* exception address is address of call      */
231
232         /* restore the window of the calling function */
233         restore
234
235         b      L_asm_handle_nat_exception
236         nop
237
238
239
240 /* asm_handle_exception ********************************************************
241
242    This function handles an exception. It does not use the usual calling
243    conventions. The exception pointer is passed in REG_ITMP2 and the
244    pc from the exception raising position is passed in REG_ITMP3. It searches
245    the local exception table for a handler. If no one is found, it unwinds
246    stacks and continues searching the callers.
247
248 *******************************************************************************/
249
250
251 asm_handle_nat_exception:
252 L_asm_handle_nat_exception:       /* required for PIC code                    */
253 L_asm_handle_exception_stack_loop:
254         /* exception handling assumes that the current java method saved       */
255         /* the caller's window, and has a valid pv                             */
256
257         /* get ra and pv before saving the window */
258         mov     ra_callee,itmp1
259         mov     pv_callee,%g4
260
261         save    %sp,-176,%sp
262         mov     xptr_itmp2,%l0              /* save exception pointer             */
263         mov     xpc_itmp3,%l1               /* save exception pc                  */
264         mov     zero,%l2                    /* save maybe-leaf flag (cleared)     */
265
266         mov     %l0,%o0                     /* pass xptr                          */
267         mov     %l1,%o1                     /* pass xpc                           */
268         mov     %g4,%o2                     /* pass PV                            */
269         mov     %fp,%o3                     /* pass Java SP                       */
270
271         b       L_asm_handle_exception_continue
272         nop
273
274 asm_handle_exception:
275         mov     pv_callee,%g4
276
277         /* save bigger stack frame for float args and temps */
278         save    %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+16+CSTACK_CNT)*8),%sp
279
280         SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
281         SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
282
283         mov     xptr_itmp2,%l0              /* save exception pointer             */
284         add     zero,1,%l2                  /* set maybe-leaf flag                */
285
286         mov     %l0,%o0                     /* pass xptr                          */
287         mov     xpc_itmp3,%o1               /* pass xpc                           */
288         mov     %g4,%o2                     /* pass PV                            */
289         mov     %fp,%o3                     /* pass Java SP                       */
290
291 L_asm_handle_exception_continue:
292         call    exceptions_handle_exception
293         nop
294
295         brz     %o0,L_asm_handle_exception_not_caught
296         nop
297
298         mov     %o0,xpc_itmp3               /* move handlerpc into xpc            */
299         mov     %l0,xptr_itmp2              /* restore exception pointer          */
300
301         brz     %l2,L_asm_handle_exception_no_leaf
302         nop
303
304         RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
305         RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
306         
307 L_asm_handle_exception_no_leaf:
308         /* restore java window and stackframe (ra and pv are in there) */
309         restore
310         jmpl    xpc_itmp3, zero             /* jump to the handler                */
311         nop
312
313 L_asm_handle_exception_not_caught:
314         mov     %l0,xptr_itmp2              /* restore xptr                       */
315         restore                             /* free our stackframe and window     */
316         /* maybe leaf flag gets cleared after branch to _loop */
317         
318         restore                             /* unwind stack and window            */
319         ba      L_asm_handle_exception_stack_loop
320         mov     ra_caller,xpc_itmp3         /* the new xpc is ra (delay)          */
321         
322
323
324
325 /* asm_abstractmethoderror *****************************************************
326
327    Creates and throws an AbstractMethodError.
328
329 *******************************************************************************/
330
331 asm_abstractmethoderror:
332         /* do a window save */
333         save %sp,-192,%sp
334
335         mov     %fp,%o0                     /* pass java sp(==fp)                 */
336         mov     ra_callee,%o1               /* pass exception address             */
337         call    exceptions_asm_new_abstractmethoderror
338         nop
339
340         mov     %o0,xptr_itmp2              /* get exception pointer              */
341         sub     ra_callee,4,xpc_itmp3       /* exception address is ra - 4        */
342         ba      L_asm_handle_nat_exception
343         nop
344
345         /* XXX: leave the register window open for handle_exception ??? */
346
347 /* asm_patcher_wrapper *********************************************************
348
349    XXX
350
351    Stack layout, when called from patcher stub
352      40   return address into JIT code (patch position)
353      32   pointer to virtual java_objectheader
354      24   machine code (which is patched back later)
355      16   unresolved class/method/field reference
356       8   data segment displacement from load instructions
357       0   patcher function pointer to call
358    -128   WINSAVE REGS (current SP)
359
360 *******************************************************************************/
361                 
362
363 asm_patcher_wrapper:
364         /* get pv and ra, since the emit code is not passing it on */
365         mov     ra_callee,ra_caller
366         mov     pv_callee,pv_caller
367
368         /* create window and stack frame              */
369         save  %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+16+CSTACK_CNT+6)*8),%sp
370
371         SAVE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
372         SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
373         SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
374
375         mov     itmp1,%l0               /* save itmp1                             */
376         mov     itmp2,%l1               /* save itmp2                             */
377
378         add     %fp,JITSTACK,%o0      /* pass pseudo SP                           */
379         mov     pv_callee,%o1         /* pass PV                                  */
380         mov     ra_callee,%o2         /* pass RA (correct for leafs)              */
381         call    patcher_wrapper
382         nop
383
384         RESTORE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
385         RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
386         RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
387
388         mov     %l0,itmp1               /* restore itmp1                          */
389         mov     %l1,itmp2               /* restore itmp2                          */
390
391         brnz    %o0,L_asm_patcher_wrapper_exception
392         nop
393
394         /* load RA (patch position from patcher data on the stack */
395         ldx     [%fp+JITSTACK+5*8],itmp3
396
397         /* remove window and stack frame (and stack space allocated in the stub code */
398         restore  %fp,6*8,%sp /* (source regs refer to old window, rd to new window)  */
399
400         jmpl     itmp3,zero              /* jump to newly patched code               */
401         nop
402
403 L_asm_patcher_wrapper_exception:
404         mov      %o0,xptr_itmp2        /* get exception                            */
405         ldx      [%fp+JITSTACK+5*8],xpc_itmp3 /* xpc is RA                         */
406         restore  %fp,6*8,%sp           /* remove stack frame                       */
407         ba       asm_handle_exception
408         nop
409
410
411     
412 /* asm_store_fp_state_reg **************************************************
413  *                                                                         *
414  * This function stores the 64-bit floating point state register to a      *
415  * memory location. (which needs to be 8-byte aligned)                     *
416  *                                                                         *
417  * C-prototype:                                                            *
418  *  void asm_store_fp_state_reg(u8 *mem);                                  *
419  *                                                                             *
420  **************************************************************************/
421  
422 asm_store_fp_state_reg:
423         stx %fsr,[%o0]
424         retl  /* return from leaf */
425         nop
426         
427 /* asm_load_fp_state_reg ***************************************************
428  *                                                                         *
429  * This function loades the 64-bit floating point state register from a    *
430  * memory location. (which needs to be 8-byte aligned)                     *
431  *                                                                         *
432  * C-prototype:                                                            *
433  *  void asm_load_fp_state_reg(u8 *mem);                                   *
434  *                                                                             *
435  **************************************************************************/
436  
437 asm_load_fp_state_reg:
438         ldx [%o0],%fsr
439         retl  /* return from leaf */
440         nop
441
442
443 /* disable exec-stacks ********************************************************/
444
445 #if defined(__linux__) && defined(__ELF__)
446         .section .note.GNU-stack,"",%progbits
447 #endif
448
449
450 /*
451  * These are local overrides for various environment variables in Emacs.
452  * Please do not remove this and leave it at the end of the file, where
453  * Emacs will automagically detect them.
454  * ---------------------------------------------------------------------
455  * Local variables:
456  * mode: asm
457  * indent-tabs-mode: t
458  * c-basic-offset: 4
459  * tab-width: 4
460  * End:
461  * vim:noexpandtab:sw=4:ts=4:
462  */