74f7646560697719e0d4d0fb8c7afa10b27dfd22
[cacao.git] / src / vm / jit / sparc64 / asmpart.S
1 /* src/vm/jit/sparc64/asmpart.S - Java-C interface functions for Sparc
2
3    Copyright (C) 1996-2005, 2006 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    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Alexander Jordan
30
31    Changes: 
32
33    $Id: asmpart.S 4749 2006-04-11 10:20:18Z twisti $
34
35 */
36
37
38 #include "config.h"
39
40 #include "vm/jit/sparc64/md-abi.h"
41 #include "offsets.h"
42 #include "md-asm.h"
43
44         .register %g2,#scratch                         /* define as scratch       */
45         .register %g3,#scratch                    /* XXX  reserve for application */
46         .text
47
48 /* export functions ***********************************************************/
49
50         .global asm_vm_call_method        
51         .global asm_vm_call_method_int    
52         .global asm_vm_call_method_long   
53         .global asm_vm_call_method_float  
54         .global asm_vm_call_method_double 
55         .global asm_vm_call_method_exception_handler
56
57         .global asm_call_jit_compiler
58
59         .global asm_handle_exception
60         .global asm_handle_nat_exception
61
62         .global asm_patcher_wrapper
63
64         .global asm_abstractmethoderror
65         
66         .global asm_criticalsections
67         .global asm_getclassvalues_atomic
68
69
70 /* asm_vm_call_method ******************************************************
71  *                                                                         *
72  * This function calls a Java-method (which possibly needs compilation)    *
73  *
74  * C-prototype:
75  *  java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,
76  *                                               vm_arg *vmargs);
77  **************************************************************************/
78
79         .align 8        /* v9: All data types are aligned to their size */
80
81         .xword 0                         /* catch type all */
82         .xword 0                         /* handler pc */
83         .xword 0                         /* end pc */
84         .xword 0                         /* start pc */
85         .word  1                         /* extable size */
86         .word  0                         /* ALIGNMENT PADDING */
87         .xword 0                         /* line number table start */
88         .xword 0                         /* line number table size */
89         .word  0                         /* ALIGNMENT PADDING */
90         .word  0                         /* fltsave */
91         .word  1                         /* intsave */
92         .word  0                         /* isleaf */
93         .word  0                         /* IsSync */
94         .word  0                         /* frame size */
95         .xword 0                         /* method pointer (pointer to name)*/ 
96
97 asm_vm_call_method:       
98 asm_vm_call_method_int:   
99 asm_vm_call_method_long:  
100 asm_vm_call_method_float: 
101 asm_vm_call_method_double:
102         
103         save %sp, -144, %sp             /* 16 reg-save + 2 */
104
105
106         /* todo: copy fp registers */
107
108         brlez %i1, calljava_argsloaded
109         dec %i1
110         ldx [%i2 + offvmargdata], %o0
111         brlez %i1, calljava_argsloaded
112
113         dec %i1
114         ldx [%i2 + (offvmargdata+sizevmarg*1)], %o1
115         brlez %i1, calljava_argsloaded
116
117         dec %i1
118         ldx [%i2 + (offvmargdata+sizevmarg*2)], %o2
119         brlez %i1, calljava_argsloaded
120
121         dec %i1
122         ldx [%i2 + (offvmargdata+sizevmarg*3)], %o3
123         brlez %i1, calljava_argsloaded
124
125         dec %i1
126         ldx [%i2 + (offvmargdata+sizevmarg*4)], %o4
127
128         /* todo: use more out registers ? */
129
130 calljava_argsloaded:
131         /* todo: stack frame layout!! */
132         
133         brlez %i1, calljava_nocopy
134         sllx %i1, 3, %l0        /* remaining args * 8           */
135         mov %sp, %l1            /* right above window save area */
136         sub %sp, %l0, %sp       /* allocate more stack space    */
137         
138 calljava_copyloop:
139         ldx [%i2 + (offvmargdata+sizevmarg*5)], %l0
140         stx %l0, [%l1]
141         inc sizevmarg, %i2      /* src++                        */
142         inc 8, %l1              /* dst++                        */
143         dec %i1                 /* arg_count--                  */
144         bnz %xcc, calljava_copyloop
145
146 calljava_nocopy:
147         /* set pv, like a java method does */
148         /*      add  ra_caller,(asm_vm_call_method - calljava_nocopy + 8),pv_callee */
149         setx  asm_vm_call_method,%l0,pv_callee
150         
151         mov   %i0,itmp1         /* pass method info pointer via itmp1 */
152         
153         setx  asm_call_jit_compiler,%l0,mptr_itmp2  /* fake virtual function call (2 instr) */
154         stx   mptr_itmp2,[%sp + 2047 + 17*8]        /* store function address               */
155         add   %sp,2047 + 16*8,mptr_itmp2            /* set method pointer                   */
156         
157         ldx  [1*8 + mptr_itmp2], pv_caller          /* method call as in Java               */
158         jmpl pv_caller,ra_caller                      /* call JIT compiler          */
159         nop
160 calljava_jit2:
161         /* pretend to restore pv */
162         add  ra_caller,(asm_vm_call_method - calljava_jit2 + 8),zero
163         
164 calljava_return:
165         mov %o0, %i0            /* pass on the return value     */
166         return %i7 + 8          /* implicit window restore */
167         nop
168
169
170 asm_vm_call_method_exception_handler:
171         
172         /* so far this function did not call any c functions */
173         /* but now we need ABI compliant argslots on the stack */
174         sub   %sp,6*8,%sp
175         
176         mov             xptr_itmp2,%o0
177         call    builtin_throw_exception
178         nop
179         return  %i7 + 8                          /* implicit window restore */
180         nop
181         
182
183
184 /****************** function asm_call_jit_compiler *****************************
185 *                                                                              *
186 *   invokes the compiler for untranslated JavaVM methods.                      *
187 *                                                                              *
188 *   Register R0 contains a pointer to the method info structure (prepared      *
189 *   by createcompilerstub). Using the return address in R26 and the            *
190 *   offset in the LDA instruction or using the value in methodptr R28 the      *
191 *   patching address for storing the method address can be computed:           *
192 *                                                                              *
193 *   method address was either loaded using                                     *
194 *   M_LDQ (REG_PV, REG_PV, a)        ; invokestatic/special    ($27)           *
195 *   M_LDA (REG_PV, REG_RA, low)                                                *
196 *   M_LDAH(REG_PV, REG_RA, high)     ; optional                                *
197 *   or                                                                         *
198 *   M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28)           *
199 *   in the static case the method pointer can be computed using the            *
200 *   return address and the lda function following the jmp instruction          *
201 *                                                                              *
202 *******************************************************************************/
203
204 asm_call_jit_compiler:
205         
206         save    %sp,-208,%sp         /* regsave(16) + argslots(6) + 4 float args  */
207
208         SAVE_FLOAT_ARGUMENT_REGISTERS(22)
209
210         mov     itmp1,%o0             /* pass methodinfo pointer                  */
211         mov     mptr_itmp2,%o1        /* pass method pointer                      */
212         mov     %fp,%o2                           /* pass java sp (==fp)                          */
213         mov     ra_callee,%o3         /* pass Java ra                             */
214         mov     %o3,%o4               /* xpc is equal to ra                       */
215         call    jit_asm_compile       /* call jit compiler                        */
216         nop
217         
218         RESTORE_FLOAT_ARGUMENT_REGISTERS(22)
219
220         brz     %o0,L_asm_call_jit_compiler_exception
221         nop
222         
223         restore %o0,%g0,pv_caller     /* restore the callers window               */
224                                       /* the source o0 references the old window  */
225                                       /* pv_caller references the new window      */
226
227
228         /* synchronise instruction cache moved somewhere else           */
229
230         jmpl    pv_caller,zero        /* and call method, the method returns      */
231                                       /* directly to the caller (ra).             */
232         nop     
233         
234 L_asm_call_jit_compiler_exception:
235         /* window still open, ra_callee valid, pv_callee undefined      */
236
237         /* get pv for further exception handling */
238         mov     ra_callee,%o0   
239         call    md_codegen_get_pv_from_pc   /* get PV from RA                     */
240         nop
241         mov     %o0,pv_callee
242
243         call    exceptions_get_and_clear_exception
244         nop
245
246         mov     %o0,xptr_itmp2        /* get exception                            */
247         mov     ra_callee,xpc_itmp3 /* exception address is ra               */
248
249         /* don't restore callers window, behave like java non-leaf */
250
251         b      L_asm_handle_nat_exception
252         nop
253
254
255
256 /* asm_handle_exception ********************************************************
257
258    This function handles an exception. It does not use the usual calling
259    conventions. The exception pointer is passed in REG_ITMP2 and the
260    pc from the exception raising position is passed in REG_ITMP3. It searches
261    the local exception table for a handler. If no one is found, it unwinds
262    stacks and continues searching the callers.
263
264 *******************************************************************************/
265
266
267 asm_handle_nat_exception:
268 L_asm_handle_nat_exception:       /* required for PIC code                    */
269 L_asm_handle_exception_stack_loop:
270         /* exception handling assumes that the current java method saved       */
271         /* the caller's window, and has a valid pv                             */
272
273         /* get ra and pv before saving the window */
274         mov     ra_callee,itmp1
275         mov     pv_callee,%g4
276
277         save    %sp,-176,%sp
278         mov     xptr_itmp2,%l0              /* save exception pointer             */
279         mov     xpc_itmp3,%l1               /* save exception pc                  */
280         mov     zero,%l2                    /* save maybe-leaf flag (cleared)     */
281
282         mov     %l0,%o0                     /* pass xptr                          */
283         mov     %l1,%o1                     /* pass xpc                           */
284         mov     %g4,%o2                     /* pass PV                            */
285         mov     %fp,%o3                     /* pass Java SP                       */
286
287         b       L_asm_handle_exception_continue
288         nop
289
290 asm_handle_exception:
291         mov     pv_callee,%g4
292
293         /* save bigger stack frame for float args and temps */
294         save    %sp,(FLT_ARG_CNT+FLT_TMP_CNT+CSTACK_CNT)*8,%sp
295
296         SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
297         SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
298
299         mov     xptr_itmp2,%l0              /* save exception pointer             */
300         add     zero,1,%l2                  /* set maybe-leaf flag                */
301
302         mov     %l0,%o0                     /* pass xptr                          */
303         mov     xpc_itmp3,%o1               /* pass xpc                           */
304         mov     %g4,%o2                     /* pass PV                            */
305         mov     %fp,%o3                     /* pass Java SP                       */
306
307 L_asm_handle_exception_continue:
308         call    exceptions_handle_exception
309         nop
310
311         brz     %o0,L_asm_handle_exception_not_caught
312         nop
313
314         mov     %o0,xpc_itmp3               /* move handlerpc into xpc            */
315         mov     %l0,xptr_itmp2              /* restore exception pointer          */
316
317         brz     %l2,L_asm_handle_exception_no_leaf
318         nop
319
320         RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
321         RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
322         
323 L_asm_handle_exception_no_leaf:
324         /* restore java window and stackframe (ra and pv are in there) */
325         restore
326         jmpl    xpc_itmp3, zero             /* jump to the handler                */
327         nop
328
329 L_asm_handle_exception_not_caught:
330         mov     %l0,xptr_itmp2              /* restore xptr                       */
331         restore                             /* free our stackframe and window     */
332         /* maybe leaf flag gets cleared after branch to _loop */
333         
334         restore                             /* unwind stack and window            */
335         ba      L_asm_handle_exception_stack_loop
336         mov     ra_caller,xpc_itmp3         /* the new xpc is ra (delay)          */
337         
338
339
340
341 /* asm_abstractmethoderror *****************************************************
342
343    Creates and throws an AbstractMethodError.
344
345 *******************************************************************************/
346
347 asm_abstractmethoderror:
348         /* do a window save */
349         save %sp,-192,%sp
350
351         mov     %fp,%o0                     /* pass java sp(==fp)                 */
352         mov     ra_callee,%o1               /* pass exception address             */
353         call    exceptions_asm_new_abstractmethoderror
354         nop
355
356         mov     %o0,xptr_itmp2              /* get exception pointer              */
357         sub     ra_callee,4,xpc_itmp3       /* exception address is ra - 4        */
358         ba      L_asm_handle_nat_exception
359         nop
360
361         /* XXX: leave the register window open for handle_exception ??? */
362
363 /* asm_patcher_wrapper *********************************************************
364
365    XXX
366
367    Stack layout, when called from patcher stub
368      40   return address into JIT code (patch position)
369      32   pointer to virtual java_objectheader
370      24   machine code (which is patched back later)
371      16   unresolved class/method/field reference
372       8   data segment displacement from load instructions
373       0   patcher function pointer to call
374    -128   WINSAVE REGS (current SP)
375
376 *******************************************************************************/
377                 
378
379 asm_patcher_wrapper:
380         /* get pv and ra, since the emit code is not passing it on */
381         mov     ra_callee,ra_caller
382         mov     pv_callee,pv_caller
383
384         /* create window and stack frame              */
385         save  %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+CSTACK_CNT+4)*8),%sp
386
387         SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
388         SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
389
390         mov     itmp1,%l0               /* save itmp1                             */
391         mov     itmp2,%l1               /* save itmp2                             */
392
393         add     %fp,JITSTACK,%o0      /* pass pseudo SP                           */
394         mov     pv_callee,%o1         /* pass PV                                  */
395         mov     ra_callee,%o2         /* pass RA (correct for leafs)              */
396         call    patcher_wrapper
397         nop
398
399         RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
400         RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
401
402         mov     %l0,itmp1               /* restore itmp1                          */
403         mov     %l1,itmp2               /* restore itmp2                          */
404
405         brnz    %o0,L_asm_patcher_wrapper_exception
406         nop
407
408         /* load RA (patch position from patcher data on the stack */
409         ldx     [%fp+JITSTACK+5*8],itmp3
410
411         /* remove window and stack frame (and stack space allocated in the stub code */
412         restore  %fp,6*8,%sp /* (source regs refer to old window, rd to new window)  */
413
414         jmpl     itmp3,zero              /* jump to newly patched code               */
415         nop
416
417 L_asm_patcher_wrapper_exception:
418         mov      %o0,xptr_itmp2        /* get exception                            */
419         ldx      [%fp+JITSTACK+5*8],xpc_itmp3 /* xpc is RA                         */
420         restore  %fp,6*8,%sp           /* remove stack frame                       */
421         ba       asm_handle_exception
422         nop
423
424
425 asm_getclassvalues_atomic:
426 _crit_restart:
427 _crit_begin:
428 /* not doing a window save, using the global temporary registers */
429         ldsw    [offbaseval+%o0],itmp1
430         ldsw    [offdiffval+%o0],itmp2
431         ldsw    [offbaseval+%o1],itmp3
432 _crit_end:
433         stw     itmp1,[offcast_super_baseval+%o2]
434         stw     itmp2,[offcast_super_diffval+%o2]
435         stw     itmp3,[offcast_sub_baseval+%o2]
436         jmpl    ra_caller+8,zero  /* caller's ra, b/c no window save */
437         nop
438
439
440     .data
441
442 asm_criticalsections:
443 #if defined(ENABLE_THREADS)
444     .xword   _crit_begin
445     .xword   _crit_end
446     .xword   _crit_restart
447 #endif
448     .xword   0
449
450
451