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
32 #include "vm/jit/sparc64/md-abi.h"
35 .register %g2,#scratch /* define as scratch */
36 .register %g3,#scratch /* XXX reserve for application */
39 /* export functions ***********************************************************/
41 .global asm_vm_call_method
42 .global asm_vm_call_method_int
43 .global asm_vm_call_method_long
44 .global asm_vm_call_method_float
45 .global asm_vm_call_method_double
46 .global asm_vm_call_method_exception_handler
47 .global asm_vm_call_method_end
49 .global asm_call_jit_compiler
51 .global asm_handle_exception
52 .global asm_handle_nat_exception
54 .global asm_patcher_wrapper
56 .global asm_abstractmethoderror
58 .global asm_store_fp_state_reg
59 .global asm_load_fp_state_reg
62 /* asm_vm_call_method ******************************************************
64 * This function calls a Java-method (which possibly needs compilation) *
66 * If the java method is throwing an exception, NULL will be returned.
69 * java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,
71 **************************************************************************/
73 .align 8 /* v9: All data types are aligned to their size */
75 .xword 0 /* line number table start */
76 .xword 0 /* line number table size */
80 .word 0 /* frame size */
81 .xword 0 /* method pointer (pointer to name)*/
84 asm_vm_call_method_int:
85 asm_vm_call_method_long:
86 asm_vm_call_method_float:
87 asm_vm_call_method_double:
89 save %sp,-((JITSTACK_CNT+2)*8),%sp
90 add %sp,JITSTACK,%l1 /* pointer to usable stack */
93 /* i1: ptr to arg array */
94 /* i2: num stackargs */
108 brlez %i2, calljava_nocopy
109 nop /* delay: fill me! */
111 sllx %i2,3,%l0 /* remaining args * 8 */
112 sub %sp,%l0,%sp /* allocate more stack space */
113 add %sp,JITSTACK,%l1 /* adjust stack begin pointer */
115 asm_vm_call_copyloop:
116 ldx [%i1+10*8],%l0 /* load argument from array */
117 stx %l0,[%l1] /* store argument to stack */
119 inc 8,%i1 /* src++ */
120 subcc %i2,1,%i2 /* arg_count-- */
121 bnz %xcc, asm_vm_call_copyloop /* use cc from previous instr */
122 inc 8,%l1 /* dst++ (delay) */
126 /* set pv, like a java method does */
127 setx asm_vm_call_method,%l0,pv_callee
129 stx %i0,[%l1 + 1*8] /* store PV on stack */
130 mov %l1,mptr_itmp2 /* set address of PV (-1*8) */
132 ldx [1*8 + mptr_itmp2], pv_caller /* load PV from stack */
133 jmpl pv_caller,ra_caller /* method call as in Java */
137 /* pretend to restore pv */
138 add ra_caller,(asm_vm_call_method - calljava_jit2 + 8),zero
141 mov %o0, %i0 /* pass on the return value */
142 return %i7 + 8 /* implicit window restore */
146 asm_vm_call_method_exception_handler:
148 /* so far this function did not call any c functions */
149 /* but now we need ABI compliant argslots on the stack */
153 call builtin_throw_exception
155 return %i7 + 8 /* implicit window restore */
156 asm_vm_call_method_end:
157 mov zero,%o0 /* delay: return NULL */
161 /****************** function asm_call_jit_compiler *****************************
163 * invokes the compiler for untranslated JavaVM methods. *
165 * Register R0 contains a pointer to the method info structure (prepared *
166 * by createcompilerstub). Using the return address in R26 and the *
167 * offset in the LDA instruction or using the value in methodptr R28 the *
168 * patching address for storing the method address can be computed: *
170 * method address was either loaded using *
171 * M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
172 * M_LDA (REG_PV, REG_RA, low) *
173 * M_LDAH(REG_PV, REG_RA, high) ; optional *
175 * M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
176 * in the static case the method pointer can be computed using the *
177 * return address and the lda function following the jmp instruction *
179 *******************************************************************************/
181 asm_call_jit_compiler:
183 /* stacksave for regsave(16) + argslots(6) + float args */
184 /* Note: +1 to keep stack 16-byte aligned */
185 save %sp,-((16+6+FLT_ARG_CNT+1)*8),%sp
187 SAVE_FLOAT_ARGUMENT_REGISTERS(22)
189 mov itmp1,%o0 /* pass methodinfo pointer */
190 mov mptr_itmp2,%o1 /* pass method pointer */
191 mov %fp,%o2 /* pass java sp (==fp) */
192 mov ra_callee,%o3 /* pass Java ra */
193 mov %o3,%o4 /* xpc is equal to ra */
194 call jit_asm_compile /* call jit compiler */
197 RESTORE_FLOAT_ARGUMENT_REGISTERS(22)
199 brz %o0,L_asm_call_jit_compiler_exception
202 restore %o0,%g0,pv_caller /* restore the callers window */
203 /* the source o0 references the old window */
204 /* pv_caller references the new window */
207 /* synchronise instruction cache moved somewhere else */
209 jmpl pv_caller,zero /* and call method, the method returns */
210 /* directly to the caller (ra). */
213 L_asm_call_jit_compiler_exception:
214 /* window still open, ra_callee valid, pv_callee undefined */
216 call exceptions_get_and_clear_exception
219 mov %o0,xptr_itmp2 /* get exception */
220 mov ra_callee,xpc_itmp3 /* exception address is address of call */
222 /* restore the window of the calling function */
225 b L_asm_handle_nat_exception
230 /* asm_handle_exception ********************************************************
232 This function handles an exception. It does not use the usual calling
233 conventions. The exception pointer is passed in REG_ITMP2 and the
234 pc from the exception raising position is passed in REG_ITMP3. It searches
235 the local exception table for a handler. If no one is found, it unwinds
236 stacks and continues searching the callers.
238 *******************************************************************************/
241 asm_handle_nat_exception:
242 L_asm_handle_nat_exception: /* required for PIC code */
243 L_asm_handle_exception_stack_loop:
244 /* exception handling assumes that the current java method saved */
245 /* the caller's window, and has a valid pv */
247 /* get ra and pv before saving the window */
252 mov xptr_itmp2,%l0 /* save exception pointer */
253 mov xpc_itmp3,%l1 /* save exception pc */
254 mov zero,%l2 /* save maybe-leaf flag (cleared) */
256 mov %l0,%o0 /* pass xptr */
257 mov %l1,%o1 /* pass xpc */
258 mov %g4,%o2 /* pass PV */
259 mov %fp,%o3 /* pass Java SP */
261 b L_asm_handle_exception_continue
264 asm_handle_exception:
267 /* save bigger stack frame for float args and temps */
268 save %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+16+CSTACK_CNT)*8),%sp
270 SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
271 SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
273 mov xptr_itmp2,%l0 /* save exception pointer */
274 add zero,1,%l2 /* set maybe-leaf flag */
276 mov %l0,%o0 /* pass xptr */
277 mov xpc_itmp3,%o1 /* pass xpc */
278 mov %g4,%o2 /* pass PV */
279 mov %fp,%o3 /* pass Java SP */
281 L_asm_handle_exception_continue:
282 call exceptions_handle_exception
285 brz %o0,L_asm_handle_exception_not_caught
288 mov %o0,xpc_itmp3 /* move handlerpc into xpc */
289 mov %l0,xptr_itmp2 /* restore exception pointer */
291 brz %l2,L_asm_handle_exception_no_leaf
294 RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT)
295 RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+FLT_ARG_CNT)
297 L_asm_handle_exception_no_leaf:
298 /* restore java window and stackframe (ra and pv are in there) */
300 jmpl xpc_itmp3, zero /* jump to the handler */
303 L_asm_handle_exception_not_caught:
304 mov %l0,xptr_itmp2 /* restore xptr */
305 restore /* free our stackframe and window */
306 /* maybe leaf flag gets cleared after branch to _loop */
308 restore /* unwind stack and window */
309 ba L_asm_handle_exception_stack_loop
310 mov ra_caller,xpc_itmp3 /* the new xpc is ra (delay) */
315 /* asm_abstractmethoderror *****************************************************
317 Creates and throws an AbstractMethodError.
319 *******************************************************************************/
321 asm_abstractmethoderror:
322 /* do a window save */
325 mov %fp,%o0 /* pass java sp(==fp) */
326 mov ra_callee,%o1 /* pass exception address */
327 call exceptions_asm_new_abstractmethoderror
330 mov %o0,xptr_itmp2 /* get exception pointer */
331 sub ra_callee,4,xpc_itmp3 /* exception address is ra - 4 */
332 ba L_asm_handle_nat_exception
335 /* XXX: leave the register window open for handle_exception ??? */
337 /* asm_patcher_wrapper *********************************************************
341 Stack layout, when called from patcher stub
342 40 return address into JIT code (patch position)
343 32 pointer to virtual java_objectheader
344 24 machine code (which is patched back later)
345 16 unresolved class/method/field reference
346 8 data segment displacement from load instructions
347 0 patcher function pointer to call
348 -128 WINSAVE REGS (current SP)
350 *******************************************************************************/
354 /* get pv and ra, since the emit code is not passing it on */
355 mov ra_callee,ra_caller
356 mov pv_callee,pv_caller
358 /* create window and stack frame */
359 save %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+16+CSTACK_CNT+6)*8),%sp
361 SAVE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
362 SAVE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
363 SAVE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
365 mov itmp1,%l0 /* save itmp1 */
366 mov itmp2,%l1 /* save itmp2 */
368 add %fp,JITSTACK,%o0 /* pass pseudo SP */
369 mov pv_callee,%o1 /* pass PV */
370 mov ra_callee,%o2 /* pass RA (correct for leafs) */
374 RESTORE_FLOAT_RETURN_REGISTER(CSTACK_CNT)
375 RESTORE_FLOAT_ARGUMENT_REGISTERS(CSTACK_CNT+1)
376 RESTORE_FLOAT_TEMPORARY_REGISTERS(CSTACK_CNT+1+FLT_ARG_CNT)
378 mov %l0,itmp1 /* restore itmp1 */
379 mov %l1,itmp2 /* restore itmp2 */
381 brnz %o0,L_asm_patcher_wrapper_exception
384 /* load RA (patch position from patcher data on the stack */
385 ldx [%fp+JITSTACK+5*8],itmp3
387 /* remove window and stack frame (and stack space allocated in the stub code */
388 restore %fp,6*8,%sp /* (source regs refer to old window, rd to new window) */
390 jmpl itmp3,zero /* jump to newly patched code */
393 L_asm_patcher_wrapper_exception:
394 mov %o0,xptr_itmp2 /* get exception */
395 ldx [%fp+JITSTACK+5*8],xpc_itmp3 /* xpc is RA */
396 restore %fp,6*8,%sp /* remove stack frame */
397 ba asm_handle_exception
402 /* asm_store_fp_state_reg **************************************************
404 * This function stores the 64-bit floating point state register to a *
405 * memory location. (which needs to be 8-byte aligned) *
408 * void asm_store_fp_state_reg(u8 *mem); *
410 **************************************************************************/
412 asm_store_fp_state_reg:
414 retl /* return from leaf */
417 /* asm_load_fp_state_reg ***************************************************
419 * This function loades the 64-bit floating point state register from a *
420 * memory location. (which needs to be 8-byte aligned) *
423 * void asm_load_fp_state_reg(u8 *mem); *
425 **************************************************************************/
427 asm_load_fp_state_reg:
429 retl /* return from leaf */
433 /* disable exec-stacks ********************************************************/
435 #if defined(__linux__) && defined(__ELF__)
436 .section .note.GNU-stack,"",%progbits
441 * These are local overrides for various environment variables in Emacs.
442 * Please do not remove this and leave it at the end of the file, where
443 * Emacs will automagically detect them.
444 * ---------------------------------------------------------------------
447 * indent-tabs-mode: t
451 * vim:noexpandtab:sw=4:ts=4: