1 /* src/vm/jit/sparc64/asmpart.S - Java-C interface functions for Sparc
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
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 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
33 $Id: asmpart.S 4749 2006-04-11 10:20:18Z twisti $
40 #include "vm/jit/sparc64/md-abi.h"
44 .register %g2,#scratch /* define as scratch */
45 .register %g3,#scratch /* XXX reserve for application */
48 /* export functions ***********************************************************/
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
57 .global asm_call_jit_compiler
59 .global asm_handle_exception
60 .global asm_handle_nat_exception
62 .global asm_patcher_wrapper
64 .global asm_abstractmethoderror
66 .global asm_criticalsections
67 .global asm_getclassvalues_atomic
70 /* asm_vm_call_method ******************************************************
72 * This function calls a Java-method (which possibly needs compilation) *
75 * java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,
77 **************************************************************************/
79 .align 8 /* v9: All data types are aligned to their size */
81 .xword 0 /* catch type all */
82 .xword 0 /* handler 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 */
94 .word 0 /* frame size */
95 .xword 0 /* method pointer (pointer to name)*/
98 asm_vm_call_method_int:
99 asm_vm_call_method_long:
100 asm_vm_call_method_float:
101 asm_vm_call_method_double:
103 save %sp, -144, %sp /* 16 reg-save + 2 */
106 /* todo: copy fp registers */
108 brlez %i1, calljava_argsloaded
110 ldx [%i2 + offvmargdata], %o0
111 brlez %i1, calljava_argsloaded
114 ldx [%i2 + (offvmargdata+sizevmarg*1)], %o1
115 brlez %i1, calljava_argsloaded
118 ldx [%i2 + (offvmargdata+sizevmarg*2)], %o2
119 brlez %i1, calljava_argsloaded
122 ldx [%i2 + (offvmargdata+sizevmarg*3)], %o3
123 brlez %i1, calljava_argsloaded
126 ldx [%i2 + (offvmargdata+sizevmarg*4)], %o4
128 /* todo: use more out registers ? */
131 /* todo: stack frame layout!! */
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 */
139 ldx [%i2 + (offvmargdata+sizevmarg*5)], %l0
141 inc sizevmarg, %i2 /* src++ */
142 inc 8, %l1 /* dst++ */
143 dec %i1 /* arg_count-- */
144 bnz %xcc, calljava_copyloop
148 mov %i0,itmp1 /* pass method info pointer via itmp1 */
150 setx asm_call_jit_compiler,%l0,mptr_itmp2 /* fake virtual function call (2 instr) */
151 stx mptr_itmp2,[%sp + 2047 + 17*8] /* store function address */
152 add %sp,2047 + 16*8,mptr_itmp2 /* set method pointer */
154 ldx [1*8 + mptr_itmp2], pv_caller /* method call as in Java */
155 jmpl pv_caller,ra_caller /* call JIT compiler */
158 /* pretend to restore pv */
159 add ra_caller,(asm_vm_call_method - calljava_jit2 + 8),pv_callee
162 mov %o0, %i0 /* pass on the return value */
163 return %i7 + 8 /* implicit window restore */
167 asm_vm_call_method_exception_handler:
170 call builtin_throw_exception
172 return %i7 + 8 /* implicit window restore */
177 /****************** function asm_call_jit_compiler *****************************
179 * invokes the compiler for untranslated JavaVM methods. *
181 * Register R0 contains a pointer to the method info structure (prepared *
182 * by createcompilerstub). Using the return address in R26 and the *
183 * offset in the LDA instruction or using the value in methodptr R28 the *
184 * patching address for storing the method address can be computed: *
186 * method address was either loaded using *
187 * M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
188 * M_LDA (REG_PV, REG_RA, low) *
189 * M_LDAH(REG_PV, REG_RA, high) ; optional *
191 * M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
192 * in the static case the method pointer can be computed using the *
193 * return address and the lda function following the jmp instruction *
195 *******************************************************************************/
197 asm_call_jit_compiler:
199 save %sp,-208,%sp /* regsave(16) + argslots(6) + 4 float args */
201 SAVE_FLOAT_ARGUMENT_REGISTERS(22)
203 mov itmp1,%o0 /* pass methodinfo pointer */
204 mov mptr_itmp2,%o1 /* pass method pointer */
205 mov %fp,%o2 /* pass java sp (==fp) */
206 mov ra_callee,%o3 /* pass Java ra */
207 mov %o3,%o4 /* xpc is equal to ra */
208 call jit_asm_compile /* call jit compiler */
211 RESTORE_FLOAT_ARGUMENT_REGISTERS(22)
213 brz %o0,L_asm_call_jit_compiler_exception
216 restore %o0,%g0,pv_caller /* restore the callers window */
217 /* the source o0 references the old window */
218 /* pv_caller references the new window */
221 /* synchronise instruction cache moved somewhere else */
223 jmpl pv_caller,zero /* and call method, the method returns */
224 /* directly to the caller (ra). */
227 L_asm_call_jit_compiler_exception:
228 /* window still open, ra_callee valid, pv_callee undefined */
230 /* get pv for further exception handling */
232 call md_codegen_get_pv_from_pc /* get PV from RA */
236 call exceptions_get_and_clear_exception
239 mov %o0,xptr_itmp2 /* get exception */
240 mov ra_callee,xpc_itmp3 /* exception address is ra */
242 /* don't restore callers window, behave like java non-leaf */
244 b L_asm_handle_nat_exception
249 /* asm_handle_exception ********************************************************
251 This function handles an exception. It does not use the usual calling
252 conventions. The exception pointer is passed in REG_ITMP2 and the
253 pc from the exception raising position is passed in REG_ITMP3. It searches
254 the local exception table for a handler. If no one is found, it unwinds
255 stacks and continues searching the callers.
257 *******************************************************************************/
260 asm_handle_nat_exception:
261 L_asm_handle_nat_exception: /* required for PIC code */
262 L_asm_handle_exception_stack_loop:
263 /* exception handling assumes that the current java method saved */
264 /* the caller's window, and has a valid pv */
266 /* get ra and pv before saving the window */
271 mov xptr_itmp2,%l0 /* save exception pointer */
272 mov xpc_itmp3,%l1 /* save exception pc */
273 mov zero,%l2 /* save maybe-leaf flag (cleared) */
275 mov %l0,%o0 /* pass xptr */
276 mov %l1,%o1 /* pass xpc */
277 mov %g4,%o2 /* pass PV */
278 mov %fp,%o3 /* pass Java SP */
280 b L_asm_handle_exception_continue
283 asm_handle_exception:
286 /* save bigger stack frame for float args and temps */
287 save %sp,(FLT_ARG_CNT+FLT_TMP_CNT+ABICALL_OFF)*8,%sp
289 SAVE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
290 SAVE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
292 mov xptr_itmp2,%l0 /* save exception pointer */
293 add zero,1,%l2 /* set maybe-leaf flag */
295 mov %l0,%o0 /* pass xptr */
296 mov xpc_itmp3,%o1 /* pass xpc */
297 mov %g4,%o2 /* pass PV */
298 mov %fp,%o3 /* pass Java SP */
300 L_asm_handle_exception_continue:
301 call exceptions_handle_exception
304 brz %o0,L_asm_handle_exception_not_caught
307 mov %o0,xpc_itmp3 /* move handlerpc into xpc */
308 mov %l0,xptr_itmp2 /* restore exception pointer */
310 brz %l2,L_asm_handle_exception_no_leaf
313 RESTORE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
314 RESTORE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
316 L_asm_handle_exception_no_leaf:
317 /* restore java window and stackframe (ra and pv are in there) */
319 jmpl xpc_itmp3, zero /* jump to the handler */
322 L_asm_handle_exception_not_caught:
323 mov %l0,xptr_itmp2 /* restore xptr */
324 restore /* free our stackframe and window */
325 /* maybe leaf flag gets cleared after branch to _loop */
327 restore /* unwind stack and window */
328 ba L_asm_handle_exception_stack_loop
329 mov xpc_itmp3,ra_caller /* the new xpc is ra (delay) */
334 /* asm_abstractmethoderror *****************************************************
336 Creates and throws an AbstractMethodError.
338 *******************************************************************************/
340 asm_abstractmethoderror:
341 /* do a window save */
344 mov %fp,%o0 /* pass java sp(==fp) */
345 mov ra_callee,%o1 /* pass exception address */
346 call exceptions_asm_new_abstractmethoderror
349 mov %o0,xptr_itmp2 /* get exception pointer */
350 sub ra_callee,4,xpc_itmp3 /* exception address is ra - 4 */
351 ba L_asm_handle_nat_exception
354 /* XXX: leave the register window open for handle_exception ??? */
356 /* asm_patcher_wrapper *********************************************************
360 Stack layout, when called from patcher stub
361 40 return address into JIT code (patch position)
362 32 pointer to virtual java_objectheader
363 24 machine code (which is patched back later)
364 16 unresolved class/method/field reference
365 8 data segment displacement from load instructions
366 0 patcher function pointer to call
367 -128 WINSAVE REGS (current SP)
369 *******************************************************************************/
373 /* get pv and ra, since the emit code is not passing it on */
374 mov ra_callee,ra_caller
375 mov pv_callee,pv_caller
377 /* create window and stack frame */
378 save %sp,-((FLT_ARG_CNT+FLT_TMP_CNT+ABICALL_OFF+4)*8),%sp
380 SAVE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
381 SAVE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
383 mov itmp1,%l0 /* save itmp1 */
384 mov itmp2,%l1 /* save itmp2 */
386 add %fp,USESTACK,%o0 /* pass pseudo SP */
387 mov pv_callee,%o1 /* pass PV */
388 mov ra_callee,%o2 /* pass RA (correct for leafs) */
392 RESTORE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
393 RESTORE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
395 mov %l0,itmp1 /* restore itmp1 */
396 mov %l1,itmp2 /* restore itmp2 */
398 brnz %o0,L_asm_patcher_wrapper_exception
400 /* load RA (patch position from patcher data on the stack */
401 ldx [%fp+USESTACK+5*8],itmp3
403 /* remove window and stack frame (and stack space allocated in the stub code */
404 restore %fp,6*8,%sp /* (source regs refer to old window, rd to new window) */
406 jmpl itmp3,zero /* jump to newly patched code */
408 L_asm_patcher_wrapper_exception:
409 mov itmp3,xptr_itmp2 /* get exception */
410 ldx [%fp+USESTACK+5*8],xpc_itmp3 /* xpc is RA */
411 restore %fp,6*8,%sp /* remove stack frame */
412 ba asm_handle_exception
416 asm_getclassvalues_atomic:
419 /* not doing a window save, using the global temporary registers */
420 ldsw [offbaseval+%o0],itmp1
421 ldsw [offdiffval+%o0],itmp2
422 ldsw [offbaseval+%o1],itmp3
424 stw itmp1,[offcast_super_baseval+%o2]
425 stw itmp2,[offcast_super_diffval+%o2]
426 stw itmp3,[offcast_sub_baseval+%o2]
427 jmpl ra_caller,zero /* caller's ra, b/c no window save */
429 .end asm_getclassvalues_atomic
434 asm_criticalsections:
435 #if defined(ENABLE_THREADS)