1 /* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
3 Copyright (C) 1996-2005, 2006, 2007, 2008 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
30 #include "vm/jit/mips/md-abi.h"
31 #include "vm/jit/mips/md-asm.h"
33 #include "vm/jit/abi-asm.h"
34 #include "vm/jit/methodheader.h"
41 /* export functions ***********************************************************/
43 .globl asm_vm_call_method
44 .globl asm_vm_call_method_int
45 .globl asm_vm_call_method_long
46 .globl asm_vm_call_method_float
47 .globl asm_vm_call_method_double
48 .globl asm_vm_call_method_exception_handler
49 .globl asm_vm_call_method_end
51 .globl asm_handle_exception
52 .globl asm_handle_nat_exception
54 .globl asm_abstractmethoderror
56 .globl compare_and_swap
59 /* asm_vm_call_method **********************************************************
61 * This function calls a Java-method (which possibly needs compilation) *
62 * with up to 4 address parameters. *
64 * This functions calls the JIT-compiler which eventually translates the *
65 * method into machine code. *
67 * A possibly throwed exception will be returned to the caller as function *
68 * return value, so the java method cannot return a fucntion value (this *
69 * function usually calls 'main' and '<clinit>' which do not return a *
73 * javaobject_header *asm_calljavafunction (methodinfo *m, *
74 * void *arg1, void *arg2, void *arg3, void *arg4); *
76 *******************************************************************************/
78 .ent asm_vm_call_method
82 #if SIZEOF_VOID_P == 8
87 .word 0 /* frame size */
88 .dword 0 /* codeinfo pointer */
90 #else /* SIZEOF_VOID_P == 8 */
95 .word 0 /* frame size */
96 .word 0 /* method pointer (pointer to name) */
98 #endif /* SIZEOF_VOID_P == 8 */
101 asm_vm_call_method_int:
102 asm_vm_call_method_long:
103 asm_vm_call_method_float:
104 asm_vm_call_method_double:
105 .set noreorder /* XXX we need to recompute pv */
107 aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
108 ast ra,0*8(sp) /* save return address */
110 bal L_asm_vm_call_method_compute_pv
111 ast pv,1*8(sp) /* procedure vector */
112 L_asm_vm_call_method_compute_pv:
115 ast s0,3*8(sp) /* save callee saved register */
116 ast a0,4*8(sp) /* save method PV */
118 #if SIZEOF_VOID_P == 8
119 sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
127 move t0,a1 /* address of data structure */
128 move t1,a2 /* stack argument count */
129 move s0,sp /* save stack pointer */
131 #if SIZEOF_VOID_P == 8
151 #else /* SIZEOF_VOID_P == 8 */
153 # if WORDS_BIGENDIAN == 1
165 # if !defined(ENABLE_SOFT_FLOAT)
170 #endif /* SIZEOF_VOID_P == 8 */
172 beqz t1,L_asm_vm_call_method_stack_copy_done
175 sll t2,t1,3 /* calculate stackframe size (* 8) */
176 asubu sp,sp,t2 /* create stackframe */
177 move t2,sp /* temporary stack pointer */
179 L_asm_vm_call_method_stack_copy_loop:
180 #if SIZEOF_VOID_P == 8
181 ld t3,16*8(t0) /* load argument */
182 sd t3,0(t2) /* store argument on stack */
184 # if !defined(ENABLE_SOFT_FLOAT)
185 lw t3,6*8+0(t0) /* load argument */
187 sw t3,0(t2) /* store argument on stack */
194 aaddi t1,t1,-1 /* subtract 1 argument */
195 aaddi t0,t0,8 /* load address of next argument */
196 aaddi t2,t2,8 /* increase stack pointer */
198 bgtz t1,L_asm_vm_call_method_stack_copy_loop
201 L_asm_vm_call_method_stack_copy_done:
202 ala mptr,4*8(s0) /* get address of PV */
203 ald pv,0*8(mptr) /* load PV */
206 L_asm_vm_call_method_recompute_pv:
207 #if SIZEOF_VOID_P == 8
208 aaddiu pv,ra,-76*4 /* recompute procedure vector */
210 aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
213 .set reorder /* XXX we need to recompute pv */
216 move sp,s0 /* restore stack pointer */
218 ald ra,0*8(sp) /* restore return address */
219 ald pv,1*8(sp) /* restore procedure vector */
222 #if SIZEOF_VOID_P == 8
223 ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
231 aaddiu sp,sp,12*8 /* free stack space */
234 asm_vm_call_method_exception_handler:
235 move sp,s0 /* restore stack pointer */
236 #if SIZEOF_VOID_P == 4
237 aaddiu sp,sp,-4*4 /* reserve space for 1 argument */
241 jal builtin_throw_exception
242 #if SIZEOF_VOID_P == 4
245 asm_vm_call_method_end:
248 .end asm_vm_call_method
251 /* asm_handle_exception ********************************************************
253 This function handles an exception. It does not use the usual calling
254 conventions. The exception pointer is passed in REG_ITMP1 and the
255 pc from the exception raising position is passed in REG_ITMP2. It searches
256 the local exception table for a handler. If no one is found, it unwinds
257 stacks and continues searching the callers.
259 *******************************************************************************/
261 .ent asm_handle_nat_exception
263 asm_handle_nat_exception:
264 L_asm_handle_exception_stack_loop:
265 #if SIZEOF_VOID_P == 8
266 aaddiu sp,sp,-6*8 /* keep stack 16-byte aligned */
267 ast xptr,0*8(sp) /* save exception pointer */
268 ast xpc,1*8(sp) /* save exception pc */
269 ast ra,3*8(sp) /* save RA */
270 ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */
272 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
273 ast xptr,4*4+0*8(sp) /* save exception pointer */
274 ast xpc,4*4+1*8(sp) /* save exception pc */
275 ast ra,4*4+3*8(sp) /* save return address */
276 ast zero,4*4+4*8(sp) /* save maybe-leaf flag (cleared) */
279 move a0,ra /* pass RA */
280 jal md_asm_codegen_get_pv_from_pc /* get PV from RA */
282 #if SIZEOF_VOID_P == 8
283 ast v0,2*8(sp) /* save PV */
285 ald a0,0*8(sp) /* pass xptr */
286 ald a1,1*8(sp) /* pass xpc */
287 move a2,v0 /* pass PV */
288 aaddiu a3,sp,6*8 /* pass Java SP */
290 ast v0,4*4+2*8(sp) /* save data segment pointer */
292 ald a0,4*4+0*8(sp) /* pass exception pointer */
293 ald a1,4*4+1*8(sp) /* pass exception pc */
294 move a2,v0 /* pass data segment pointer */
295 aaddiu a3,sp,(4*4+6*8) /* pass Java stack pointer */
298 b L_asm_handle_exception_continue
300 .aent asm_handle_exception
302 asm_handle_exception:
303 aaddiu sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
305 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
306 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
308 #if SIZEOF_VOID_P == 8
309 aaddiu sp,sp,-6*8 /* allocate stack */
310 ast xptr,0*8(sp) /* save exception pointer */
311 ast pv,2*8(sp) /* save PV */
312 ast ra,3*8(sp) /* save RA */
313 addu t0,zero,1 /* set maybe-leaf flag */
314 ast t0,4*8(sp) /* save maybe-leaf flag */
316 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
317 ast xptr,4*4+0*8(sp) /* save exception pointer */
318 ast xpc,4*4+1*8(sp) /* save exception pc */
319 ast pv,4*4+2*8(sp) /* save data segment pointer */
320 ast ra,4*4+3*8(sp) /* save return address */
321 addu t0,zero,1 /* set maybe-leaf flag */
322 ast t0,4*4+4*8(sp) /* save maybe-leaf flag */
325 move a0,xptr /* pass xptr */
326 move a1,xpc /* pass xpc */
327 move a2,pv /* pass PV */
329 #if SIZEOF_VOID_P == 8
330 aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP */
332 aaddiu a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */
335 L_asm_handle_exception_continue:
336 jal exceptions_handle_exception
338 beqz v0,L_asm_handle_exception_not_catched
340 move xpc,v0 /* move handlerpc into xpc */
342 #if SIZEOF_VOID_P == 8
343 ald xptr,0*8(sp) /* restore exception pointer */
344 ald pv,2*8(sp) /* restore PV */
345 ald ra,3*8(sp) /* restore RA */
346 ald t0,4*8(sp) /* get maybe-leaf flag */
347 aaddiu sp,sp,6*8 /* free stackframe */
349 ald xptr,4*4+0*8(sp) /* restore exception pointer */
350 ald pv,4*4+2*8(sp) /* restore data segment pointer */
351 ald ra,4*4+3*8(sp) /* restore return address */
352 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
353 aaddiu sp,sp,4*4+6*8 /* free stackframe */
356 beqz t0,L_asm_handle_exception_no_leaf
358 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
359 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
361 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
363 L_asm_handle_exception_no_leaf:
364 jr xpc /* jump to the handler */
366 L_asm_handle_exception_not_catched:
367 #if SIZEOF_VOID_P == 8
368 ald xptr,0*8(sp) /* restore xptr */
369 ald pv,2*8(sp) /* restore PV */
370 ald ra,3*8(sp) /* restore RA */
371 ald t0,4*8(sp) /* get maybe-leaf flag */
372 aaddiu sp,sp,6*8 /* free stackframe */
374 ald xptr,4*4+0*8(sp) /* restore xptr */
375 ald pv,4*4+2*8(sp) /* restore PV */
376 ald ra,4*4+3*8(sp) /* restore RA */
377 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
378 aaddiu sp,sp,4*4+6*8 /* free stackframe */
381 beqz t0,L_asm_handle_exception_no_leaf_stack
383 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
384 move t0,zero /* clear the maybe-leaf flag */
386 L_asm_handle_exception_no_leaf_stack:
387 lw t1,FrameSize(pv) /* get frame size */
388 aaddu t1,sp,t1 /* pointer to save area */
390 lw t2,IsLeaf(pv) /* is leaf procedure */
391 bnez t2,L_asm_handle_exception_no_ra_restore
393 ald ra,-1*8(t1) /* restore ra */
394 aaddiu t1,t1,-8 /* t1-- */
396 L_asm_handle_exception_no_ra_restore:
397 move xpc,ra /* the new xpc is ra */
398 lw t2,IntSave(pv) /* t1 = saved int register count */
399 ala t3,ex_int2 /* t3 = current pc */
400 sll t2,t2,2 /* t2 = register count * 4 */
401 asubu t3,t3,t2 /* t3 = IntSave - 4 * register count */
402 jr t3 /* jump to save position */
414 sll t2,t2,1 /* t2 = register count * 4 * 2 */
415 asubu t1,t1,t2 /* t1 = t0 - 8 * register count */
417 lw t2,FltSave(pv) /* t2 = saved flt register count */
418 ala t3,ex_flt2 /* t3 = current pc */
419 sll t2,t2,2 /* t2 = register count * 4 */
420 asubu t3,t3,t2 /* t3 = ex_int_sav - 4 * register count */
421 jr t3 /* jump to save position */
423 #if SIZEOF_VOID_P == 8
428 #else /* SIZEOF_VOID_P == 8 */
429 # if !defined(ENABLE_SOFT_FLOAT)
436 # endif /* !defined(ENABLE_SOFT_FLOAT) */
437 #endif /* SIZEOF_VOID_P == 8 */
440 lw t1,FrameSize(pv) /* get frame size */
441 aaddu sp,sp,t1 /* unwind stack */
442 b L_asm_handle_exception_stack_loop
444 .end asm_handle_nat_exception
447 /* asm_abstractmethoderror *****************************************************
449 Creates and throws an AbstractMethodError.
451 *******************************************************************************/
453 .ent asm_abstractmethoderror
455 asm_abstractmethoderror:
456 aaddiu sp,sp,-2*8 /* create stackframe */
457 ast ra,0*8(sp) /* save return address */
458 aaddiu a0,sp,2*8 /* pass java sp */
459 move a1,ra /* pass exception address */
460 jal exceptions_asm_new_abstractmethoderror
461 ald ra,0*8(sp) /* restore return address */
462 aaddiu sp,sp,2*8 /* remove stackframe */
464 move xptr,v0 /* get exception pointer */
465 aaddiu xpc,ra,-4 /* exception address is ra - 4 */
466 b asm_handle_nat_exception
468 .end asm_abstractmethoderror
471 .ent compare_and_swap
484 .end compare_and_swap
487 /* disable exec-stacks ********************************************************/
489 #if defined(__linux__) && defined(__ELF__)
490 .section .note.GNU-stack,"",%progbits
495 * These are local overrides for various environment variables in Emacs.
496 * Please do not remove this and leave it at the end of the file, where
497 * Emacs will automagically detect them.
498 * ---------------------------------------------------------------------
501 * indent-tabs-mode: t
505 * vim:noexpandtab:sw=4:ts=4: