1 /* src/vm/jit/sparc64/asmpart.S - Java-C interface functions for Sparc64
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
8 This file is part of CACAO.
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.
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.
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
25 $Id: asmpart.S 4749 2006-04-11 10:20:18Z twisti $
32 #include "vm/jit/sparc64/md-abi.h"
36 .register %g2,#scratch /* define as scratch */
37 .register %g3,#scratch /* XXX reserve for application */
40 /* export functions ***********************************************************/
42 .global asm_vm_call_method
43 .global asm_vm_call_method_int
44 .global asm_vm_call_method_long
45 .global asm_vm_call_method_float
46 .global asm_vm_call_method_double
47 .global asm_vm_call_method_exception_handler
48 .global asm_vm_call_method_end
50 .global asm_call_jit_compiler
52 .global asm_handle_exception
53 .global asm_handle_nat_exception
55 .global asm_patcher_wrapper
57 .global asm_abstractmethoderror
59 .global asm_criticalsections
60 .global asm_getclassvalues_atomic
62 .global asm_store_fp_state_reg
63 .global asm_load_fp_state_reg
66 /* asm_vm_call_method ******************************************************
68 * This function calls a Java-method (which possibly needs compilation) *
70 * If the java method is throwing an exception, NULL will be returned.
73 * java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,
75 **************************************************************************/
77 .align 8 /* v9: All data types are aligned to their size */
79 .xword 0 /* catch type all */
80 .xword 0 /* handler pc */
82 .xword 0 /* start pc */
83 .word 1 /* extable size */
84 .word 0 /* ALIGNMENT PADDING */
85 .xword 0 /* line number table start */
86 .xword 0 /* line number table size */
87 .word 0 /* ALIGNMENT PADDING */
92 .word 0 /* frame size */
93 .xword 0 /* method pointer (pointer to name)*/
96 asm_vm_call_method_int:
97 asm_vm_call_method_long:
98 asm_vm_call_method_float:
99 asm_vm_call_method_double:
101 save %sp,-((JITSTACK_CNT+2)*8),%sp
102 add %sp,JITSTACK,%l1 /* right above window save area */
105 /* %i1 not needed after _nocopy -> calculate in branch delay */
107 brlez %i1, calljava_nocopy
109 dec %i1 /* branch delay */
110 ldx [%i2 + offvmargdata],%o0
111 ldx [%i2 + offvmargtype],%l2
113 be,a %xcc,calljava_arg0isfloat
114 ld [%i2 + offvmargdata],fa0f /* delay: annulled if branch not taken */
115 ldd [%i2 + offvmargdata],fa0
116 calljava_arg0isfloat:
117 brlez %i1,calljava_nocopy
119 dec %i1 /* branch delay */
120 ldx [%i2 + (offvmargdata+sizevmarg*1)],%o1
121 ldx [%i2 + (offvmargtype+sizevmarg*1)],%l2
123 be,a %xcc,calljava_arg1isfloat
124 ld [%i2 + (offvmargdata+sizevmarg*1)],fa1f
125 ldd [%i2 + (offvmargdata+sizevmarg*1)],fa1
126 calljava_arg1isfloat:
127 brlez %i1,calljava_nocopy
130 ldx [%i2 + (offvmargdata+sizevmarg*2)],%o2
131 ldx [%i2 + (offvmargtype+sizevmarg*2)],%l2
133 be,a %xcc,calljava_arg2isfloat
134 ld [%i2 + (offvmargdata+sizevmarg*2)],fa2f
135 ldd [%i2 + (offvmargdata+sizevmarg*2)],fa2
136 calljava_arg2isfloat:
137 brlez %i1,calljava_nocopy
140 ldx [%i2 + (offvmargdata+sizevmarg*3)],%o3
141 ldx [%i2 + (offvmargtype+sizevmarg*3)],%l2
143 be,a %xcc,calljava_arg3isfloat
144 ld [%i2 + (offvmargdata+sizevmarg*3)],fa3f
145 ldd [%i2 + (offvmargdata+sizevmarg*3)],fa3
146 calljava_arg3isfloat:
147 brlez %i1,calljava_nocopy
150 ldx [%i2 + (offvmargdata+sizevmarg*4)],%o4
151 ldx [%i2 + (offvmargtype+sizevmarg*4)],%l2
153 be,a %xcc,calljava_arg4isfloat
154 ld [%i2 + (offvmargdata+sizevmarg*4)],fa4f
155 ldd [%i2 + (offvmargdata+sizevmarg*4)],fa4
156 calljava_arg4isfloat:
159 brlez %i1, calljava_nocopy
161 sllx %i1,3,%l0 /* remaining args * 8 */
162 sub %sp,%l0,%sp /* allocate more stack space */
163 add %sp,JITSTACK,%l1 /* adjust stack begin pointer */
166 ldx [%i2 + (offvmargtype+sizevmarg*5)],%l2
168 be %xcc,calljava_copyloop_float
170 ldx [%i2 + (offvmargdata+sizevmarg*5)],%l0
173 calljava_copyloop_float:
174 ld [%i2 + (offvmargdata+sizevmarg*5)],%f1
177 inc sizevmarg,%i2 /* src++ */
178 subcc %i1,1,%i1 /* arg_count-- */
179 bnz %xcc, calljava_copyloop /* use cc from previous instr */
180 inc 8,%l1 /* dst++ (delay) */
184 /* set pv, like a java method does */
185 /* add ra_caller,(asm_vm_call_method - calljava_nocopy + 8),pv_callee */
186 setx asm_vm_call_method,%l0,pv_callee
188 mov %i0,itmp1 /* pass method info pointer via itmp1 */
190 setx asm_call_jit_compiler,%l0,mptr_itmp2 /* fake virtual function call (2 instr) */
191 stx mptr_itmp2,[%l1 + 1*8] /* store function address */
192 mov %l1,mptr_itmp2 /* set method pointer */
194 ldx [1*8 + mptr_itmp2], pv_caller /* method call as in Java */
195 jmpl pv_caller,ra_caller /* call JIT compiler */
198 /* pretend to restore pv */
199 add ra_caller,(asm_vm_call_method - calljava_jit2 + 8),zero
202 mov %o0, %i0 /* pass on the return value */
203 return %i7 + 8 /* implicit window restore */
207 asm_vm_call_method_exception_handler:
209 /* so far this function did not call any c functions */
210 /* but now we need ABI compliant argslots on the stack */
214 call builtin_throw_exception
216 return %i7 + 8 /* implicit window restore */
217 asm_vm_call_method_end:
218 mov zero,%o0 /* delay: return NULL */
222 /****************** function asm_call_jit_compiler *****************************
224 * invokes the compiler for untranslated JavaVM methods. *
226 * Register R0 contains a pointer to the method info structure (prepared *
227 * by createcompilerstub). Using the return address in R26 and the *
228 * offset in the LDA instruction or using the value in methodptr R28 the *
229 * patching address for storing the method address can be computed: *
231 * method address was either loaded using *
232 * M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
233 * M_LDA (REG_PV, REG_RA, low) *
234 * M_LDAH(REG_PV, REG_RA, high) ; optional *
236 * M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
237 * in the static case the method pointer can be computed using the *
238 * return address and the lda function following the jmp instruction *
240 *******************************************************************************/
242 asm_call_jit_compiler:
244 /* stacksave for regsave(16) + argslots(6) + float args */
245 /* Note: +1 to keep stack 16-byte aligned */
246 save %sp,-((16+6+FLT_ARG_CNT+1)*8),%sp
248 SAVE_FLOAT_ARGUMENT_REGISTERS(22)
250 mov itmp1,%o0 /* pass methodinfo pointer */
251 mov mptr_itmp2,%o1 /* pass method pointer */
252 mov %fp,%o2 /* pass java sp (==fp) */
253 mov ra_callee,%o3 /* pass Java ra */
254 mov %o3,%o4 /* xpc is equal to ra */
255 call jit_asm_compile /* call jit compiler */
258 RESTORE_FLOAT_ARGUMENT_REGISTERS(22)
260 brz %o0,L_asm_call_jit_compiler_exception
263 restore %o0,%g0,pv_caller /* restore the callers window */
264 /* the source o0 references the old window */
265 /* pv_caller references the new window */
268 /* synchronise instruction cache moved somewhere else */
270 jmpl pv_caller,zero /* and call method, the method returns */
271 /* directly to the caller (ra). */
274 L_asm_call_jit_compiler_exception:
275 /* window still open, ra_callee valid, pv_callee undefined */
277 call exceptions_get_and_clear_exception
280 mov %o0,xptr_itmp2 /* get exception */
281 mov ra_callee,xpc_itmp3 /* exception address is address of call */
283 /* restore the window of the calling function */
286 b L_asm_handle_nat_exception
291 /* asm_handle_exception ********************************************************
293 This function handles an exception. It does not use the usual calling
294 conventions. The exception pointer is passed in REG_ITMP2 and the
295 pc from the exception raising position is passed in REG_ITMP3. It searches
296 the local exception table for a handler. If no one is found, it unwinds
297 stacks and continues searching the callers.
299 *******************************************************************************/
302 asm_handle_nat_exception:
303 L_asm_handle_nat_exception: /* required for PIC code */
304 L_asm_handle_exception_stack_loop:
305 /* exception handling assumes that the current java method saved */
306 /* the caller's window, and has a valid pv */
308 /* get ra and pv before saving the window */
313 mov xptr_itmp2,%l0 /* save exception pointer */
314 mov xpc_itmp3,%l1 /* save exception pc */
315 mov zero,%l2 /* save maybe-leaf flag (cleared) */
317 mov %l0,%o0 /* pass xptr */
318 mov %l1,%o1 /* pass xpc */
319 mov %g4,%o2 /* pass PV */
320 mov %fp,%o3 /* pass Java SP */
322 b L_asm_handle_exception_continue
325 asm_handle_exception:
328 /* save bigger stack frame for float args and temps */
329 save %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+CSTACK_CNT)*8),%sp
331 SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
332 SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
334 mov xptr_itmp2,%l0 /* save exception pointer */
335 add zero,1,%l2 /* set maybe-leaf flag */
337 mov %l0,%o0 /* pass xptr */
338 mov xpc_itmp3,%o1 /* pass xpc */
339 mov %g4,%o2 /* pass PV */
340 mov %fp,%o3 /* pass Java SP */
342 L_asm_handle_exception_continue:
343 call exceptions_handle_exception
346 brz %o0,L_asm_handle_exception_not_caught
349 mov %o0,xpc_itmp3 /* move handlerpc into xpc */
350 mov %l0,xptr_itmp2 /* restore exception pointer */
352 brz %l2,L_asm_handle_exception_no_leaf
355 RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
356 RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
358 L_asm_handle_exception_no_leaf:
359 /* restore java window and stackframe (ra and pv are in there) */
361 jmpl xpc_itmp3, zero /* jump to the handler */
364 L_asm_handle_exception_not_caught:
365 mov %l0,xptr_itmp2 /* restore xptr */
366 restore /* free our stackframe and window */
367 /* maybe leaf flag gets cleared after branch to _loop */
369 restore /* unwind stack and window */
370 ba L_asm_handle_exception_stack_loop
371 mov ra_caller,xpc_itmp3 /* the new xpc is ra (delay) */
376 /* asm_abstractmethoderror *****************************************************
378 Creates and throws an AbstractMethodError.
380 *******************************************************************************/
382 asm_abstractmethoderror:
383 /* do a window save */
386 mov %fp,%o0 /* pass java sp(==fp) */
387 mov ra_callee,%o1 /* pass exception address */
388 call exceptions_asm_new_abstractmethoderror
391 mov %o0,xptr_itmp2 /* get exception pointer */
392 sub ra_callee,4,xpc_itmp3 /* exception address is ra - 4 */
393 ba L_asm_handle_nat_exception
396 /* XXX: leave the register window open for handle_exception ??? */
398 /* asm_patcher_wrapper *********************************************************
402 Stack layout, when called from patcher stub
403 40 return address into JIT code (patch position)
404 32 pointer to virtual java_objectheader
405 24 machine code (which is patched back later)
406 16 unresolved class/method/field reference
407 8 data segment displacement from load instructions
408 0 patcher function pointer to call
409 -128 WINSAVE REGS (current SP)
411 *******************************************************************************/
415 /* get pv and ra, since the emit code is not passing it on */
416 mov ra_callee,ra_caller
417 mov pv_callee,pv_caller
419 /* create window and stack frame */
420 save %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+CSTACK_CNT+6)*8),%sp
422 SAVE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
423 SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
424 SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
426 mov itmp1,%l0 /* save itmp1 */
427 mov itmp2,%l1 /* save itmp2 */
429 add %fp,JITSTACK,%o0 /* pass pseudo SP */
430 mov pv_callee,%o1 /* pass PV */
431 mov ra_callee,%o2 /* pass RA (correct for leafs) */
435 RESTORE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
436 RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
437 RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
439 mov %l0,itmp1 /* restore itmp1 */
440 mov %l1,itmp2 /* restore itmp2 */
442 brnz %o0,L_asm_patcher_wrapper_exception
445 /* load RA (patch position from patcher data on the stack */
446 ldx [%fp+JITSTACK+5*8],itmp3
448 /* remove window and stack frame (and stack space allocated in the stub code */
449 restore %fp,6*8,%sp /* (source regs refer to old window, rd to new window) */
451 jmpl itmp3,zero /* jump to newly patched code */
454 L_asm_patcher_wrapper_exception:
455 mov %o0,xptr_itmp2 /* get exception */
456 ldx [%fp+JITSTACK+5*8],xpc_itmp3 /* xpc is RA */
457 restore %fp,6*8,%sp /* remove stack frame */
458 ba asm_handle_exception
463 /* asm_store_fp_state_reg **************************************************
465 * This function stores the 64-bit floating point state register to a *
466 * memory location. (which needs to be 8-byte aligned) *
469 * void asm_store_fp_state_reg(u8 *mem); *
471 **************************************************************************/
473 asm_store_fp_state_reg:
475 retl /* return from leaf */
478 /* asm_load_fp_state_reg ***************************************************
480 * This function loades the 64-bit floating point state register from a *
481 * memory location. (which needs to be 8-byte aligned) *
484 * void asm_load_fp_state_reg(u8 *mem); *
486 **************************************************************************/
488 asm_load_fp_state_reg:
490 retl /* return from leaf */
496 asm_getclassvalues_atomic:
499 /* not doing a window save, using the global temporary registers */
500 ldsw [offbaseval+%o0],itmp1
501 ldsw [offdiffval+%o0],itmp2
502 ldsw [offbaseval+%o1],itmp3
504 stw itmp1,[offcast_super_baseval+%o2]
505 stw itmp2,[offcast_super_diffval+%o2]
506 stw itmp3,[offcast_sub_baseval+%o2]
507 jmpl ra_caller+8,zero /* caller's ra, b/c no window save */
513 asm_criticalsections:
514 #if defined(ENABLE_THREADS)
522 /* disable exec-stacks ********************************************************/
524 #if defined(__linux__) && defined(__ELF__)
525 .section .note.GNU-stack,"",%progbits
530 * These are local overrides for various environment variables in Emacs.
531 * Please do not remove this and leave it at the end of the file, where
532 * Emacs will automagically detect them.
533 * ---------------------------------------------------------------------
536 * indent-tabs-mode: t
540 * vim:noexpandtab:sw=4:ts=4: