1 /* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 #include "vm/jit/mips/md-abi.h"
29 #include "vm/jit/mips/md-asm.h"
31 #include "vm/jit/abi-asm.h"
32 #include "vm/jit/methodheader.h"
39 /* export functions ***********************************************************/
41 .globl asm_vm_call_method
42 .globl asm_vm_call_method_int
43 .globl asm_vm_call_method_long
44 .globl asm_vm_call_method_float
45 .globl asm_vm_call_method_double
46 .globl asm_vm_call_method_exception_handler
47 .globl asm_vm_call_method_end
49 .globl asm_handle_exception
50 .globl asm_handle_nat_exception
52 .globl asm_abstractmethoderror
54 .globl compare_and_swap
57 /* asm_vm_call_method **********************************************************
59 * This function calls a Java-method (which possibly needs compilation) *
60 * with up to 4 address parameters. *
62 * This functions calls the JIT-compiler which eventually translates the *
63 * method into machine code. *
65 * A possibly throwed exception will be returned to the caller as function *
66 * return value, so the java method cannot return a fucntion value (this *
67 * function usually calls 'main' and '<clinit>' which do not return a *
71 * javaobject_header *asm_calljavafunction (methodinfo *m, *
72 * void *arg1, void *arg2, void *arg3, void *arg4); *
74 *******************************************************************************/
76 .ent asm_vm_call_method
80 #if SIZEOF_VOID_P == 8
85 .word 0 /* frame size */
86 .dword 0 /* codeinfo pointer */
88 #else /* SIZEOF_VOID_P == 8 */
93 .word 0 /* frame size */
94 .word 0 /* method pointer (pointer to name) */
96 #endif /* SIZEOF_VOID_P == 8 */
99 asm_vm_call_method_int:
100 asm_vm_call_method_long:
101 asm_vm_call_method_float:
102 asm_vm_call_method_double:
103 .set noreorder /* XXX we need to recompute pv */
105 aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
106 ast ra,0*8(sp) /* save return address */
108 bal L_asm_vm_call_method_compute_pv
109 ast pv,1*8(sp) /* procedure vector */
110 L_asm_vm_call_method_compute_pv:
113 ast s0,3*8(sp) /* save callee saved register */
114 ast a0,4*8(sp) /* save method PV */
116 #if SIZEOF_VOID_P == 8
117 s.d fss0,5*8(sp) /* save non JavaABI saved flt registers */
125 move t0,a1 /* address of data structure */
126 move t1,a2 /* stack argument count */
127 move s0,sp /* save stack pointer */
129 #if SIZEOF_VOID_P == 8
149 #else /* SIZEOF_VOID_P == 8 */
151 # if WORDS_BIGENDIAN == 1
163 # if !defined(ENABLE_SOFT_FLOAT)
168 #endif /* SIZEOF_VOID_P == 8 */
170 beqz t1,L_asm_vm_call_method_stack_copy_done
173 sll t2,t1,3 /* calculate stackframe size (* 8) */
174 asubu sp,sp,t2 /* create stackframe */
175 move t2,sp /* temporary stack pointer */
177 L_asm_vm_call_method_stack_copy_loop:
178 #if SIZEOF_VOID_P == 8
179 ld t3,16*8(t0) /* load argument */
180 sd t3,0(t2) /* store argument on stack */
182 # if !defined(ENABLE_SOFT_FLOAT)
183 lw t3,6*8+0(t0) /* load argument */
185 sw t3,0(t2) /* store argument on stack */
192 aaddi t1,t1,-1 /* subtract 1 argument */
193 aaddi t0,t0,8 /* load address of next argument */
194 aaddi t2,t2,8 /* increase stack pointer */
196 bgtz t1,L_asm_vm_call_method_stack_copy_loop
199 L_asm_vm_call_method_stack_copy_done:
200 ala mptr,4*8(s0) /* get address of PV */
201 ald pv,0*8(mptr) /* load PV */
204 L_asm_vm_call_method_recompute_pv:
205 #if SIZEOF_VOID_P == 8
206 aaddiu pv,ra,-76*4 /* recompute procedure vector */
208 aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
211 .set reorder /* XXX we need to recompute pv */
214 move sp,s0 /* restore stack pointer */
216 ald ra,0*8(sp) /* restore return address */
217 ald pv,1*8(sp) /* restore procedure vector */
220 #if SIZEOF_VOID_P == 8
221 l.d fss0,5*8(sp) /* restore non JavaABI saved flt regs */
229 aaddiu sp,sp,12*8 /* free stack space */
232 asm_vm_call_method_exception_handler:
233 move sp,s0 /* restore stack pointer */
234 #if SIZEOF_VOID_P == 4
235 aaddiu sp,sp,-4*4 /* reserve space for 1 argument */
239 jal builtin_throw_exception
240 #if SIZEOF_VOID_P == 4
243 asm_vm_call_method_end:
246 .end asm_vm_call_method
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_ITMP1 and the
253 pc from the exception raising position is passed in REG_ITMP2. 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 *******************************************************************************/
259 .ent asm_handle_nat_exception
261 asm_handle_nat_exception:
262 L_asm_handle_exception_stack_loop:
263 #if SIZEOF_VOID_P == 8
264 aaddiu sp,sp,-6*8 /* keep stack 16-byte aligned */
265 ast xptr,0*8(sp) /* save exception pointer */
266 ast xpc,1*8(sp) /* save exception pc */
267 ast ra,3*8(sp) /* save RA */
268 ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */
270 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
271 ast xptr,4*4+0*8(sp) /* save exception pointer */
272 ast xpc,4*4+1*8(sp) /* save exception pc */
273 ast ra,4*4+3*8(sp) /* save return address */
274 ast zero,4*4+4*8(sp) /* save maybe-leaf flag (cleared) */
277 move a0,ra /* pass RA */
278 jal md_asm_codegen_get_pv_from_pc /* get PV from RA */
280 #if SIZEOF_VOID_P == 8
281 ast v0,2*8(sp) /* save PV */
283 ald a0,0*8(sp) /* pass xptr */
284 ald a1,1*8(sp) /* pass xpc */
285 move a2,v0 /* pass PV */
286 aaddiu a3,sp,6*8 /* pass Java SP */
288 ast v0,4*4+2*8(sp) /* save data segment pointer */
290 ald a0,4*4+0*8(sp) /* pass exception pointer */
291 ald a1,4*4+1*8(sp) /* pass exception pc */
292 move a2,v0 /* pass data segment pointer */
293 aaddiu a3,sp,(4*4+6*8) /* pass Java stack pointer */
296 b L_asm_handle_exception_continue
298 .aent asm_handle_exception
300 asm_handle_exception:
301 aaddiu sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
303 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
304 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
306 #if SIZEOF_VOID_P == 8
307 aaddiu sp,sp,-6*8 /* allocate stack */
308 ast xptr,0*8(sp) /* save exception pointer */
309 ast pv,2*8(sp) /* save PV */
310 ast ra,3*8(sp) /* save RA */
311 addu t0,zero,1 /* set maybe-leaf flag */
312 ast t0,4*8(sp) /* save maybe-leaf flag */
314 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
315 ast xptr,4*4+0*8(sp) /* save exception pointer */
316 ast xpc,4*4+1*8(sp) /* save exception pc */
317 ast pv,4*4+2*8(sp) /* save data segment pointer */
318 ast ra,4*4+3*8(sp) /* save return address */
319 addu t0,zero,1 /* set maybe-leaf flag */
320 ast t0,4*4+4*8(sp) /* save maybe-leaf flag */
323 move a0,xptr /* pass xptr */
324 move a1,xpc /* pass xpc */
325 move a2,pv /* pass PV */
327 #if SIZEOF_VOID_P == 8
328 aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP */
330 aaddiu a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */
333 L_asm_handle_exception_continue:
334 jal exceptions_handle_exception
336 beqz v0,L_asm_handle_exception_not_catched
338 move xpc,v0 /* move handlerpc into xpc */
340 #if SIZEOF_VOID_P == 8
341 ald xptr,0*8(sp) /* restore exception pointer */
342 ald pv,2*8(sp) /* restore PV */
343 ald ra,3*8(sp) /* restore RA */
344 ald t0,4*8(sp) /* get maybe-leaf flag */
345 aaddiu sp,sp,6*8 /* free stackframe */
347 ald xptr,4*4+0*8(sp) /* restore exception pointer */
348 ald pv,4*4+2*8(sp) /* restore data segment pointer */
349 ald ra,4*4+3*8(sp) /* restore return address */
350 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
351 aaddiu sp,sp,4*4+6*8 /* free stackframe */
354 beqz t0,L_asm_handle_exception_no_leaf
356 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
357 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
359 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
361 L_asm_handle_exception_no_leaf:
362 jr xpc /* jump to the handler */
364 L_asm_handle_exception_not_catched:
365 #if SIZEOF_VOID_P == 8
366 ald xptr,0*8(sp) /* restore xptr */
367 ald pv,2*8(sp) /* restore PV */
368 ald ra,3*8(sp) /* restore RA */
369 ald t0,4*8(sp) /* get maybe-leaf flag */
370 aaddiu sp,sp,6*8 /* free stackframe */
372 ald xptr,4*4+0*8(sp) /* restore xptr */
373 ald pv,4*4+2*8(sp) /* restore PV */
374 ald ra,4*4+3*8(sp) /* restore RA */
375 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
376 aaddiu sp,sp,4*4+6*8 /* free stackframe */
379 beqz t0,L_asm_handle_exception_no_leaf_stack
381 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
382 move t0,zero /* clear the maybe-leaf flag */
384 L_asm_handle_exception_no_leaf_stack:
385 lw t1,FrameSize(pv) /* get frame size */
386 aaddu t1,sp,t1 /* pointer to save area */
388 lw t2,IsLeaf(pv) /* is leaf procedure */
389 bnez t2,L_asm_handle_exception_no_ra_restore
391 ald ra,-1*8(t1) /* restore ra */
392 aaddiu t1,t1,-8 /* t1-- */
394 L_asm_handle_exception_no_ra_restore:
395 move xpc,ra /* the new xpc is ra */
396 lw t2,IntSave(pv) /* t1 = saved int register count */
397 ala t3,ex_int2 /* t3 = current pc */
398 sll t2,t2,2 /* t2 = register count * 4 */
399 asubu t3,t3,t2 /* t3 = IntSave - 4 * register count */
400 jr t3 /* jump to save position */
412 sll t2,t2,1 /* t2 = register count * 4 * 2 */
413 asubu t1,t1,t2 /* t1 = t0 - 8 * register count */
415 lw t2,FltSave(pv) /* t2 = saved flt register count */
416 ala t3,ex_flt2 /* t3 = current pc */
417 sll t2,t2,2 /* t2 = register count * 4 */
418 asubu t3,t3,t2 /* t3 = ex_int_sav - 4 * register count */
419 jr t3 /* jump to save position */
421 #if SIZEOF_VOID_P == 8
426 #else /* SIZEOF_VOID_P == 8 */
427 # if !defined(ENABLE_SOFT_FLOAT)
434 # endif /* !defined(ENABLE_SOFT_FLOAT) */
435 #endif /* SIZEOF_VOID_P == 8 */
438 lw t1,FrameSize(pv) /* get frame size */
439 aaddu sp,sp,t1 /* unwind stack */
440 b L_asm_handle_exception_stack_loop
442 .end asm_handle_nat_exception
445 /* asm_abstractmethoderror *****************************************************
447 Creates and throws an AbstractMethodError.
449 *******************************************************************************/
451 .ent asm_abstractmethoderror
453 asm_abstractmethoderror:
454 aaddiu sp,sp,-2*8 /* create stackframe */
455 ast ra,0*8(sp) /* save return address */
456 aaddiu a0,sp,2*8 /* pass java sp */
457 move a1,ra /* pass exception address */
458 jal exceptions_asm_new_abstractmethoderror
459 ald ra,0*8(sp) /* restore return address */
460 aaddiu sp,sp,2*8 /* remove stackframe */
462 move xptr,v0 /* get exception pointer */
463 aaddiu xpc,ra,-4 /* exception address is ra - 4 */
464 b asm_handle_nat_exception
466 .end asm_abstractmethoderror
469 .ent compare_and_swap
473 #if defined(__GNUC__)
477 #if defined(__GNUC__)
482 #if defined(__GNUC__)
486 #if defined(__GNUC__)
491 #if defined(__GNUC__)
495 #if defined(__GNUC__)
500 .end compare_and_swap
503 /* disable exec-stacks ********************************************************/
505 #if defined(__linux__) && defined(__ELF__)
506 .section .note.GNU-stack,"",%progbits
511 * These are local overrides for various environment variables in Emacs.
512 * Please do not remove this and leave it at the end of the file, where
513 * Emacs will automagically detect them.
514 * ---------------------------------------------------------------------
517 * indent-tabs-mode: t
521 * vim:noexpandtab:sw=4:ts=4: