1 /* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
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
29 Changes: Christian Thalinger
32 $Id: asmpart.S 7455 2007-03-05 15:46:53Z tbfg $
39 #include "vm/jit/mips/md-abi.h"
40 #include "vm/jit/mips/md-asm.h"
41 #include "vm/jit/mips/offsets.h"
43 #include "vm/jit/abi-asm.h"
44 #include "vm/jit/methodheader.h"
51 /* export functions ***********************************************************/
53 .globl asm_vm_call_method
54 .globl asm_vm_call_method_int
55 .globl asm_vm_call_method_long
56 .globl asm_vm_call_method_float
57 .globl asm_vm_call_method_double
58 .globl asm_vm_call_method_exception_handler
59 .globl asm_vm_call_method_end
61 .globl asm_call_jit_compiler
63 .globl asm_handle_exception
64 .globl asm_handle_nat_exception
66 .globl asm_abstractmethoderror
68 .globl asm_patcher_wrapper
70 #if defined(ENABLE_REPLACEMENT)
71 .globl asm_replacement_out
72 .globl asm_replacement_in
75 .globl asm_getclassvalues_atomic
76 .globl asm_criticalsections
78 .globl compare_and_swap
81 /* asm_vm_call_method **********************************************************
83 * This function calls a Java-method (which possibly needs compilation) *
84 * with up to 4 address parameters. *
86 * This functions calls the JIT-compiler which eventually translates the *
87 * method into machine code. *
89 * A possibly throwed exception will be returned to the caller as function *
90 * return value, so the java method cannot return a fucntion value (this *
91 * function usually calls 'main' and '<clinit>' which do not return a *
95 * javaobject_header *asm_calljavafunction (methodinfo *m, *
96 * void *arg1, void *arg2, void *arg3, void *arg4); *
98 *******************************************************************************/
100 .ent asm_vm_call_method
104 #if SIZEOF_VOID_P == 8
106 .dword 0 /* catch type all */
107 .dword 0 /* handler pc */
108 .dword 0 /* end pc */
109 .dword 0 /* start pc */
110 .word 1 /* extable size */
111 .word 0 /* 4-byte ALIGNMENT PADDING */
112 .dword 0 /* line number table start */
113 .dword 0 /* line number table size */
114 .word 0 /* 4-byte ALIGNMENT PADDING */
115 .word 0 /* fltsave */
116 .word 0 /* intsave */
119 .word 0 /* frame size */
120 .dword 0 /* codeinfo pointer */
122 #else /* SIZEOF_VOID_P == 8 */
124 .word 0 /* catch type all */
125 .word 0 /* handler pc */
127 .word 0 /* start pc */
128 .word 1 /* extable size */
129 .word 0 /* line number table start */
130 .word 0 /* line number table size */
131 .word 0 /* fltsave */
132 .word 0 /* intsave */
135 .word 0 /* frame size */
136 .word 0 /* method pointer (pointer to name) */
138 #endif /* SIZEOF_VOID_P == 8 */
141 asm_vm_call_method_int:
142 asm_vm_call_method_long:
143 asm_vm_call_method_float:
144 asm_vm_call_method_double:
145 .set noreorder /* XXX we need to recompute pv */
147 aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
148 ast ra,0*8(sp) /* save return address */
150 bal L_asm_vm_call_method_compute_pv
151 ast pv,1*8(sp) /* procedure vector */
152 L_asm_vm_call_method_compute_pv:
157 #if SIZEOF_VOID_P == 8
158 sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
166 ast a0,4*8(sp) /* save method pointer for compiler */
168 move t0,a2 /* address of first block */
169 move s7,a1 /* argument count */
170 blez s7,calljava_argsloaded
173 #if SIZEOF_VOID_P == 8
175 ald a0,offvmargdata(t0)
176 ldc1 fa0,offvmargdata(t0)
178 blez s7,calljava_argsloaded
181 ald a1,offvmargdata+sizevmarg*1(t0)
182 ldc1 fa1,offvmargdata+sizevmarg*1(t0)
184 blez s7,calljava_argsloaded
187 ald a2,offvmargdata+sizevmarg*2(t0)
188 ldc1 fa2,offvmargdata+sizevmarg*2(t0)
190 blez s7,calljava_argsloaded
193 ald a3,offvmargdata+sizevmarg*3(t0)
194 ldc1 fa3,offvmargdata+sizevmarg*3(t0)
196 blez s7,calljava_argsloaded
199 ald a4,offvmargdata+sizevmarg*4(t0)
200 ldc1 fa4,offvmargdata+sizevmarg*4(t0)
202 blez s7,calljava_argsloaded
205 ald a5,offvmargdata+sizevmarg*5(t0)
206 ldc1 fa5,offvmargdata+sizevmarg*5(t0)
208 blez s7,calljava_argsloaded
211 ald a6,offvmargdata+sizevmarg*6(t0)
212 ldc1 fa6,offvmargdata+sizevmarg*6(t0)
214 blez s7,calljava_argsloaded
217 ald a7,offvmargdata+sizevmarg*7(t0)
218 ldc1 fa7,offvmargdata+sizevmarg*7(t0)
221 #else /* SIZEOF_VOID_P == 8 */
223 #if WORDS_BIGENDIAN == 1
224 ald a0,offvmargdata+4(t0)
226 ald a0,offvmargdata(t0)
228 #if !defined(ENABLE_SOFT_FLOAT)
229 ldc1 fa0,offvmargdata(t0)
232 blez s7,calljava_argsloaded
234 #if WORDS_BIGENDIAN == 1
235 ald a1,offvmargdata+4+sizevmarg*1(t0)
237 ald a1,offvmargdata+sizevmarg*1(t0)
239 #if !defined(ENABLE_SOFT_FLOAT)
240 ldc1 fa1,offvmargdata+sizevmarg*1(t0)
243 blez s7,calljava_argsloaded
245 #if WORDS_BIGENDIAN == 1
246 ald a2,offvmargdata+4+sizevmarg*2(t0)
248 ald a2,offvmargdata+sizevmarg*2(t0)
251 blez s7,calljava_argsloaded
253 #if WORDS_BIGENDIAN == 1
254 ald a3,offvmargdata+4+sizevmarg*3(t0)
256 ald a3,offvmargdata+sizevmarg*3(t0)
259 blez s7,calljava_argsloaded
261 #endif /* SIZEOF_VOID_P == 8 */
264 move t4,sp /* save stack pointer */
265 blez s7,calljava_nocopy
268 #if SIZEOF_VOID_P == 4
269 aaddiu s7,s7,4 /* add stack space for 4 arguments */
271 subu t1,zero,s7 /* remaining argument count (negative) */
272 sll t2,t1,3 /* calculate stackframe size */
273 aaddu sp,sp,t2 /* create stackframe */
274 aaddu t2,t2,t4 /* also set temp sp */
275 #if SIZEOF_VOID_P == 4
276 aaddiu t2,t2,4*8 /* skip stack space for 4 arguments */
281 #if SIZEOF_VOID_P == 8
282 ald t3,offvmargdata+sizevmarg*8(t0)
284 # if WORDS_BIGENDIAN == 1
285 ald t3,offvmargdata+4+sizevmarg*4(t0)
287 ald t3,offvmargdata+sizevmarg*4(t0)
290 ast t3,0(t2) /* store argument on stack */
291 addi t1,t1,1 /* count 1 argument */
292 aaddi t0,t0,sizevmarg /* load address of next block */
293 aaddi t2,t2,8 /* increase stack position */
294 bnez t1,calljava_copyloop /* all arguments copied? */
298 ald itmp1,4*8(t4) /* pass method pointer via itmp1 */
300 ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
301 ast mptr,2*8(t4) /* store function address */
302 ala mptr,1*8(t4) /* set method pointer */
304 ald pv,1*8(mptr) /* method call as in Java */
305 jalr pv /* call JIT compiler */
307 L_asm_vm_call_method_recompute_pv:
308 #if SIZEOF_VOID_P == 8
309 aaddiu pv,ra,-76*4 /* recompute procedure vector */
311 aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
314 .set reorder /* XXX we need to recompute pv */
316 sll t1,s7,3 /* remove argument stackframe */
320 ald ra,0*8(sp) /* restore return address */
321 ald pv,1*8(sp) /* restore procedure vector */
324 #if SIZEOF_VOID_P == 8
325 ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
333 aaddiu sp,sp,12*8 /* free stack space */
336 asm_vm_call_method_exception_handler:
337 sll t1,s7,3 /* remove stackframe */
339 #if SIZEOF_VOID_P == 4
340 aaddiu sp,sp,-4*4 /* reserve space for 1 argument */
344 jal builtin_throw_exception
345 #if SIZEOF_VOID_P == 4
348 asm_vm_call_method_end:
351 .end asm_vm_call_method
354 /****************** function asm_call_jit_compiler *****************************
356 * invokes the compiler for untranslated JavaVM methods. *
358 * Register REG_ITEMP1 contains a pointer to the method info structure *
359 * (prepared by createcompilerstub). Using the return address in R31 and the *
360 * offset in the LDA instruction or using the value in methodptr R25 the *
361 * patching address for storing the method address can be computed: *
363 * method address was either loaded using *
364 * M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
365 * M_JSR (REG_RA, REG_PV); *
367 * M_LDA (REG_PV, REG_RA, val) *
369 * M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
370 * M_JSR (REG_RA, REG_PV); *
372 * in the static case the method pointer can be computed using the *
373 * return address and the lda function following the jmp instruction *
375 *******************************************************************************/
377 .ent asm_call_jit_compiler
379 asm_call_jit_compiler:
380 #if SIZEOF_VOID_P == 8
382 aaddiu sp,sp,-(ARG_CNT+2)*8 /* +2: keep stack 16-bytes aligned */
384 ast ra,0*8(sp) /* save return address */
386 SAVE_ARGUMENT_REGISTERS(1)
388 move a0,itmp1 /* pass methodinfo pointer */
389 move a1,mptr /* pass method pointer */
390 aaddiu a2,sp,(ARG_CNT+2)*8 /* pass java sp */
392 jal jit_asm_compile /* call jit compiler */
395 ald ra,0*8(sp) /* restore return address */
397 RESTORE_ARGUMENT_REGISTERS(1)
399 aaddiu sp,sp,(ARG_CNT+2)*8 /* remove stack frame */
401 #else /* SIZEOF_VOID_P == 8 */
403 aaddiu sp,sp,-(ARG_CNT+2)*8 /* +4: keep stack 16-bytes aligned */
405 ast ra,4*4+0*4(sp) /* save return address */
407 SAVE_ARGUMENT_REGISTERS(6)
409 move a0,itmp1 /* pass methodinfo pointer */
410 move a1,mptr /* pass method pointer */
411 aaddiu a2,sp,(ARG_CNT+2)*8 /* pass java sp */
413 jal jit_asm_compile /* call jit compiler */
416 ald ra,4*4+0*4(sp) /* restore return address */
418 RESTORE_ARGUMENT_REGISTERS(6)
420 aaddiu sp,sp,(ARG_CNT+2)*8 /* remove stack frame */
422 #endif /* SIZEOF_VOID_P == 8 */
424 beqz pv,L_asm_call_jit_compiler_exception
426 jr pv /* and call method. The method returns */
427 /* directly to the caller (ra). */
429 L_asm_call_jit_compiler_exception:
432 jal exceptions_get_and_clear_exception
436 move xptr,v0 /* get exception */
437 aaddiu xpc,ra,-4 /* exception address is RA - 4 */
438 b asm_handle_nat_exception
440 .end asm_call_jit_compiler
443 /* asm_handle_exception ********************************************************
445 This function handles an exception. It does not use the usual calling
446 conventions. The exception pointer is passed in REG_ITMP1 and the
447 pc from the exception raising position is passed in REG_ITMP2. It searches
448 the local exception table for a handler. If no one is found, it unwinds
449 stacks and continues searching the callers.
451 *******************************************************************************/
453 .ent asm_handle_nat_exception
455 asm_handle_nat_exception:
456 L_asm_handle_exception_stack_loop:
457 #if SIZEOF_VOID_P == 8
458 aaddiu sp,sp,-6*8 /* keep stack 16-byte aligned */
459 ast xptr,0*8(sp) /* save exception pointer */
460 ast xpc,1*8(sp) /* save exception pc */
461 ast ra,3*8(sp) /* save RA */
462 ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */
464 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
465 ast xptr,4*4+0*8(sp) /* save exception pointer */
466 ast xpc,4*4+1*8(sp) /* save exception pc */
467 ast ra,4*4+3*8(sp) /* save return address */
468 ast zero,4*4+4*8(sp) /* save maybe-leaf flag (cleared) */
471 move a0,ra /* pass RA */
472 jal md_codegen_get_pv_from_pc /* get PV from RA */
474 #if SIZEOF_VOID_P == 8
475 ast v0,2*8(sp) /* save PV */
477 ald a0,0*8(sp) /* pass xptr */
478 ald a1,1*8(sp) /* pass xpc */
479 move a2,v0 /* pass PV */
480 aaddiu a3,sp,6*8 /* pass Java SP */
482 ast v0,4*4+2*8(sp) /* save data segment pointer */
484 ald a0,4*4+0*8(sp) /* pass exception pointer */
485 ald a1,4*4+1*8(sp) /* pass exception pc */
486 move a2,v0 /* pass data segment pointer */
487 aaddiu a3,sp,(4*4+6*8) /* pass Java stack pointer */
490 b L_asm_handle_exception_continue
492 .aent asm_handle_exception
494 asm_handle_exception:
495 aaddiu sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
497 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
498 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
500 #if SIZEOF_VOID_P == 8
501 aaddiu sp,sp,-6*8 /* allocate stack */
502 ast xptr,0*8(sp) /* save exception pointer */
503 ast pv,2*8(sp) /* save PV */
504 ast ra,3*8(sp) /* save RA */
505 addu t0,zero,1 /* set maybe-leaf flag */
506 ast t0,4*8(sp) /* save maybe-leaf flag */
508 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
509 ast xptr,4*4+0*8(sp) /* save exception pointer */
510 ast xpc,4*4+1*8(sp) /* save exception pc */
511 ast pv,4*4+2*8(sp) /* save data segment pointer */
512 ast ra,4*4+3*8(sp) /* save return address */
513 addu t0,zero,1 /* set maybe-leaf flag */
514 ast t0,4*4+4*8(sp) /* save maybe-leaf flag */
517 move a0,xptr /* pass xptr */
518 move a1,xpc /* pass xpc */
519 move a2,pv /* pass PV */
521 #if SIZEOF_VOID_P == 8
522 aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP */
524 aaddiu a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */
527 L_asm_handle_exception_continue:
528 jal exceptions_handle_exception
530 beqz v0,L_asm_handle_exception_not_catched
532 move xpc,v0 /* move handlerpc into xpc */
534 #if SIZEOF_VOID_P == 8
535 ald xptr,0*8(sp) /* restore exception pointer */
536 ald pv,2*8(sp) /* restore PV */
537 ald ra,3*8(sp) /* restore RA */
538 ald t0,4*8(sp) /* get maybe-leaf flag */
539 aaddiu sp,sp,6*8 /* free stackframe */
541 ald xptr,4*4+0*8(sp) /* restore exception pointer */
542 ald pv,4*4+2*8(sp) /* restore data segment pointer */
543 ald ra,4*4+3*8(sp) /* restore return address */
544 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
545 aaddiu sp,sp,4*4+6*8 /* free stackframe */
548 beqz t0,L_asm_handle_exception_no_leaf
550 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
551 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
553 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
555 L_asm_handle_exception_no_leaf:
556 jr xpc /* jump to the handler */
558 L_asm_handle_exception_not_catched:
559 #if SIZEOF_VOID_P == 8
560 ald xptr,0*8(sp) /* restore xptr */
561 ald pv,2*8(sp) /* restore PV */
562 ald ra,3*8(sp) /* restore RA */
563 ald t0,4*8(sp) /* get maybe-leaf flag */
564 aaddiu sp,sp,6*8 /* free stackframe */
566 ald xptr,4*4+0*8(sp) /* restore xptr */
567 ald pv,4*4+2*8(sp) /* restore PV */
568 ald ra,4*4+3*8(sp) /* restore RA */
569 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
570 aaddiu sp,sp,4*4+6*8 /* free stackframe */
573 beqz t0,L_asm_handle_exception_no_leaf_stack
575 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
576 move t0,zero /* clear the maybe-leaf flag */
578 L_asm_handle_exception_no_leaf_stack:
579 lw t1,FrameSize(pv) /* get frame size */
580 aaddu t1,sp,t1 /* pointer to save area */
582 lw t2,IsLeaf(pv) /* is leaf procedure */
583 bnez t2,L_asm_handle_exception_no_ra_restore
585 ald ra,-1*8(t1) /* restore ra */
586 aaddiu t1,t1,-8 /* t1-- */
588 L_asm_handle_exception_no_ra_restore:
589 move xpc,ra /* the new xpc is ra */
590 lw t2,IntSave(pv) /* t1 = saved int register count */
591 ala t3,ex_int2 /* t3 = current pc */
592 sll t2,t2,2 /* t2 = register count * 4 */
593 asubu t3,t3,t2 /* t3 = IntSave - 4 * register count */
594 jr t3 /* jump to save position */
606 sll t2,t2,1 /* t2 = register count * 4 * 2 */
607 asubu t1,t1,t2 /* t1 = t0 - 8 * register count */
609 lw t2,FltSave(pv) /* t2 = saved flt register count */
610 ala t3,ex_flt2 /* t3 = current pc */
611 sll t2,t2,2 /* t2 = register count * 4 */
612 asubu t3,t3,t2 /* t3 = ex_int_sav - 4 * register count */
613 jr t3 /* jump to save position */
615 #if SIZEOF_VOID_P == 8
620 #else /* SIZEOF_VOID_P == 8 */
621 # if !defined(ENABLE_SOFT_FLOAT)
628 # endif /* !defined(ENABLE_SOFT_FLOAT) */
629 #endif /* SIZEOF_VOID_P == 8 */
632 lw t1,FrameSize(pv) /* get frame size */
633 aaddu sp,sp,t1 /* unwind stack */
634 b L_asm_handle_exception_stack_loop
636 .end asm_handle_nat_exception
639 /* asm_abstractmethoderror *****************************************************
641 Creates and throws an AbstractMethodError.
643 *******************************************************************************/
645 .ent asm_abstractmethoderror
647 asm_abstractmethoderror:
648 aaddiu sp,sp,-2*8 /* create stackframe */
649 ast ra,0*8(sp) /* save return address */
650 aaddiu a0,sp,2*8 /* pass java sp */
651 move a1,ra /* pass exception address */
652 jal exceptions_asm_new_abstractmethoderror
653 ald ra,0*8(sp) /* restore return address */
654 aaddiu sp,sp,2*8 /* remove stackframe */
656 move xptr,v0 /* get exception pointer */
657 aaddiu xpc,ra,-4 /* exception address is ra - 4 */
658 b asm_handle_nat_exception
660 .end asm_abstractmethoderror
663 /* asm_patcher_wrapper *********************************************************
668 56 return address into JIT code (patch position)
669 48 pointer to virtual java_objectheader
670 40 machine code (which is patched back later)
671 32 machine code (which is patched back later)
672 24 machine code (which is patched back later)
673 16 unresolved class/method/field reference
674 8 data segment displacement from load instructions
675 0 patcher function pointer to call
677 *******************************************************************************/
679 .ent asm_patcher_wrapper
682 #if SIZEOF_VOID_P == 8
684 aaddiu sp,sp,-((2+16+22+4)*8)/* create stack frame */
686 SAVE_RETURN_REGISTERS(0) /* save 1 int/1 float return registers */
687 SAVE_ARGUMENT_REGISTERS(2) /* save 8 int/8 float argument registers */
688 SAVE_TEMPORARY_REGISTERS(18) /* save 5 int/16 float temporary registers */
690 ast itmp1,(2+16+22+0)*8(sp) /* save itmp1 */
691 ast itmp2,(2+16+22+1)*8(sp) /* save itmp2 */
692 ast ra,(2+16+22+2)*8(sp) /* save method return address (for leafs) */
693 ast pv,(2+16+22+3)*8(sp) /* save pv of calling java function */
695 aaddiu a0,sp,(2+16+22+4)*8 /* pass SP of patcher stub */
696 move a1,pv /* pass PV */
697 move a2,ra /* pass RA (correct for leafs) */
701 RESTORE_RETURN_REGISTERS(0) /* restore 1 int/1 float return registers */
702 RESTORE_ARGUMENT_REGISTERS(2) /* restore 8 int/8 float argument registers */
703 RESTORE_TEMPORARY_REGISTERS(18) /* restore 5 int/16 float temporary reg. */
705 ald itmp1,(2+16+22+0)*8(sp) /* restore itmp1 */
706 ald itmp2,(2+16+22+1)*8(sp) /* restore itmp2 */
707 ald ra,(2+16+22+2)*8(sp) /* restore method return address (for leafs)*/
708 ald pv,(2+16+22+3)*8(sp) /* restore pv of calling java function */
710 bnez itmp3,L_asm_patcher_wrapper_exception
712 ald itmp3,(7+2+16+22+4)*8(sp) /* load RA */
713 aaddiu sp,sp,(8+2+16+22+4)*8 /* remove stack frame */
715 jr itmp3 /* jump to new patched code */
717 L_asm_patcher_wrapper_exception:
718 move xptr,itmp3 /* get exception */
719 ald xpc,(7+2+16+22+4)*8(sp) /* xpc is RA */
720 aaddiu sp,sp,(8+2+16+22+4)*8 /* remove stack frame */
722 #else /* SIZEOF_VOID_P == 8 */
724 aaddiu sp,sp,-((6+4+8+16+7)*4) /* create stack frame */
725 /* +7 keeps the SP 16-bytes aligned */
727 SAVE_RETURN_REGISTERS(6) /* save 2 int / 1 float return registers */
728 SAVE_ARGUMENT_REGISTERS(10) /* save 4 int / 2 float argument registers */
729 SAVE_TEMPORARY_REGISTERS(18) /* save 8 int / 4 float temporary registers */
731 ast itmp1,(6+4+8+16+0)*4(sp) /* save itmp1 */
732 ast itmp2,(6+4+8+16+1)*4(sp) /* save itmp2 */
733 ast ra,(6+4+8+16+2)*4(sp) /* save method return address (for leafs) */
734 ast pv,(6+4+8+16+3)*4(sp) /* save pv of calling java function */
736 aaddiu a0,sp,(6+4+8+16+7)*4 /* pass SP of patcher stub */
737 move a1,pv /* pass PV */
738 move a2,ra /* pass RA (correct for leafs) */
742 RESTORE_RETURN_REGISTERS(6) /* restore 2 int / 2 float return registers */
743 RESTORE_ARGUMENT_REGISTERS(10) /* restore 4 int / 2 float argument regs */
744 RESTORE_TEMPORARY_REGISTERS(18) /* restore 8 int / 4 float temporary regs */
746 ald itmp1,(6+4+8+16+0)*4(sp) /* restore itmp1 */
747 ald itmp2,(6+4+8+16+1)*4(sp) /* restore itmp2 */
748 ald ra,(6+4+8+16+2)*4(sp) /* restore method return address (for leafs)*/
749 ald pv,(6+4+8+16+3)*4(sp) /* restore pv of calling java function */
751 bnez itmp3,L_asm_wrapper_patcher_exception
753 ald itmp3,7*8+(6+4+8+16+7)*4(sp) /* load RA */
754 aaddiu sp,sp,8*8+(6+4+8+16+7)*4 /* remove stack frame */
756 jr itmp3 /* jump to new patched code */
758 L_asm_wrapper_patcher_exception:
759 move xptr,itmp3 /* get exception */
760 ald xpc,7*8+(6+4+8+16+7)*4(sp) /* xpc is RA */
761 aaddiu sp,sp,8*8+(6+4+8+16+7)*4 /* remove stack frame */
763 #endif /* SIZEOF_VOID_P == 8 */
765 b asm_handle_exception
767 .end asm_patcher_wrapper
769 #if defined(ENABLE_REPLACEMENT)
771 /* asm_replacement_out *********************************************************
773 This code is jumped to from the replacement-out stubs that are executed
774 when a thread reaches an activated replacement point.
776 The purpose of asm_replacement_out is to read out the parts of the
777 execution state that cannot be accessed from C code, store this state,
778 and then call the C function replace_me.
781 16 start of stack inside method to replace
782 0 rplpoint * info on the replacement point that was reached
784 NOTE: itmp3 has been clobbered by the replacement-out stub!
786 *******************************************************************************/
788 /* some room to accomodate changes of the stack frame size during replacement */
789 /* XXX we should find a cleaner solution here */
790 #define REPLACEMENT_ROOM 512
792 #define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
794 .ent asm_replacement_out
797 /* create stack frame */
798 aaddiu sp,sp,-REPLACEMENT_STACK_OFFSET
800 /* save registers in execution state */
801 ast $0 ,( 0*8+offes_intregs)(sp)
802 ast $1 ,( 1*8+offes_intregs)(sp)
803 ast $2 ,( 2*8+offes_intregs)(sp)
804 ast $3 ,( 3*8+offes_intregs)(sp)
805 ast $4 ,( 4*8+offes_intregs)(sp)
806 ast $5 ,( 5*8+offes_intregs)(sp)
807 ast $6 ,( 6*8+offes_intregs)(sp)
808 ast $7 ,( 7*8+offes_intregs)(sp)
809 ast $8 ,( 8*8+offes_intregs)(sp)
810 ast $9 ,( 9*8+offes_intregs)(sp)
811 ast $10,(10*8+offes_intregs)(sp)
812 ast $11,(11*8+offes_intregs)(sp)
813 ast $12,(12*8+offes_intregs)(sp)
814 ast $13,(13*8+offes_intregs)(sp)
815 ast $14,(14*8+offes_intregs)(sp)
816 ast $15,(15*8+offes_intregs)(sp)
817 ast $16,(16*8+offes_intregs)(sp)
818 ast $17,(17*8+offes_intregs)(sp)
819 ast $18,(18*8+offes_intregs)(sp)
820 ast $19,(19*8+offes_intregs)(sp)
821 ast $20,(20*8+offes_intregs)(sp)
822 ast $21,(21*8+offes_intregs)(sp)
823 ast $22,(22*8+offes_intregs)(sp)
824 ast $23,(23*8+offes_intregs)(sp)
825 ast $24,(24*8+offes_intregs)(sp)
826 ast $25,(25*8+offes_intregs)(sp)
827 ast $26,(26*8+offes_intregs)(sp)
828 ast $27,(27*8+offes_intregs)(sp)
829 ast $28,(28*8+offes_intregs)(sp)
830 ast $29,(29*8+offes_intregs)(sp)
831 ast $30,(30*8+offes_intregs)(sp)
832 ast $31,(31*8+offes_intregs)(sp)
834 #if SIZEOF_VOID_P == 8
836 sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
837 sdc1 $f1 ,( 1*8+offes_fltregs)(sp)
838 sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
839 sdc1 $f3 ,( 3*8+offes_fltregs)(sp)
840 sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
841 sdc1 $f5 ,( 5*8+offes_fltregs)(sp)
842 sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
843 sdc1 $f7 ,( 7*8+offes_fltregs)(sp)
844 sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
845 sdc1 $f9 ,( 9*8+offes_fltregs)(sp)
846 sdc1 $f10,(10*8+offes_fltregs)(sp)
847 sdc1 $f11,(11*8+offes_fltregs)(sp)
848 sdc1 $f12,(12*8+offes_fltregs)(sp)
849 sdc1 $f13,(13*8+offes_fltregs)(sp)
850 sdc1 $f14,(14*8+offes_fltregs)(sp)
851 sdc1 $f15,(15*8+offes_fltregs)(sp)
852 sdc1 $f16,(16*8+offes_fltregs)(sp)
853 sdc1 $f17,(17*8+offes_fltregs)(sp)
854 sdc1 $f18,(18*8+offes_fltregs)(sp)
855 sdc1 $f19,(19*8+offes_fltregs)(sp)
856 sdc1 $f20,(20*8+offes_fltregs)(sp)
857 sdc1 $f21,(21*8+offes_fltregs)(sp)
858 sdc1 $f22,(22*8+offes_fltregs)(sp)
859 sdc1 $f23,(23*8+offes_fltregs)(sp)
860 sdc1 $f24,(24*8+offes_fltregs)(sp)
861 sdc1 $f25,(25*8+offes_fltregs)(sp)
862 sdc1 $f26,(26*8+offes_fltregs)(sp)
863 sdc1 $f27,(27*8+offes_fltregs)(sp)
864 sdc1 $f28,(28*8+offes_fltregs)(sp)
865 sdc1 $f29,(29*8+offes_fltregs)(sp)
866 sdc1 $f30,(30*8+offes_fltregs)(sp)
867 sdc1 $f31,(31*8+offes_fltregs)(sp)
869 #else /* SIZEOF_VOID_P == 8 */
871 sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
872 sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
873 sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
874 sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
875 sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
876 sdc1 $f10,(10*8+offes_fltregs)(sp)
877 sdc1 $f12,(12*8+offes_fltregs)(sp)
878 sdc1 $f14,(14*8+offes_fltregs)(sp)
879 sdc1 $f16,(16*8+offes_fltregs)(sp)
880 sdc1 $f18,(18*8+offes_fltregs)(sp)
881 sdc1 $f20,(20*8+offes_fltregs)(sp)
882 sdc1 $f22,(22*8+offes_fltregs)(sp)
883 sdc1 $f24,(24*8+offes_fltregs)(sp)
884 sdc1 $f26,(26*8+offes_fltregs)(sp)
885 sdc1 $f28,(28*8+offes_fltregs)(sp)
886 sdc1 $f30,(30*8+offes_fltregs)(sp)
888 #endif /* SIZEOF_VOID_P == 8 */
890 /* calculate sp of method */
891 aaddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
892 ast itmp1,(offes_sp)(sp)
895 ast pv,(offes_pv)(sp)
897 /* call replace_me */
898 ald a0,-(2*8)(itmp1) /* arg0: rplpoint * */
899 move a1,sp /* arg1: execution state */
900 jal replace_me /* call C function replace_me */
901 jal abort /* NEVER REACHED */
903 .end asm_replacement_out
905 /* asm_replacement_in **********************************************************
907 This code writes the given execution state and jumps to the replacement
910 This function never returns!
912 NOTE: itmp3 is not restored!
915 void asm_replacement_in(executionstate *es);
917 *******************************************************************************/
919 .ent asm_replacement_in
922 /* a0 == executionstate *es */
924 /* set new sp and pv */
925 ald sp,(offes_sp)(a0)
926 ald pv,(offes_pv)(a0)
928 /* copy registers from execution state */
930 ald $1 ,( 1*8+offes_intregs)(a0)
931 ald $2 ,( 2*8+offes_intregs)(a0)
932 ald $3 ,( 2*8+offes_intregs)(a0)
933 /* a0 is loaded below */
934 ald $5 ,( 5*8+offes_intregs)(a0)
935 ald $6 ,( 6*8+offes_intregs)(a0)
936 ald $7 ,( 7*8+offes_intregs)(a0)
937 ald $8 ,( 8*8+offes_intregs)(a0)
938 ald $9 ,( 9*8+offes_intregs)(a0)
939 ald $10,(10*8+offes_intregs)(a0)
940 ald $11,(11*8+offes_intregs)(a0)
941 ald $12,(12*8+offes_intregs)(a0)
942 ald $13,(13*8+offes_intregs)(a0)
943 ald $14,(14*8+offes_intregs)(a0)
944 ald $15,(15*8+offes_intregs)(a0)
945 ald $16,(16*8+offes_intregs)(a0)
946 ald $17,(17*8+offes_intregs)(a0)
947 ald $18,(18*8+offes_intregs)(a0)
948 ald $19,(19*8+offes_intregs)(a0)
949 ald $20,(20*8+offes_intregs)(a0)
950 ald $21,(21*8+offes_intregs)(a0)
951 ald $22,(22*8+offes_intregs)(a0)
952 ald $23,(23*8+offes_intregs)(a0)
953 ald $24,(24*8+offes_intregs)(a0)
954 ald $25,(25*8+offes_intregs)(a0)
955 ald $26,(26*8+offes_intregs)(a0)
956 ald $27,(27*8+offes_intregs)(a0)
957 ald $28,(28*8+offes_intregs)(a0)
960 ald $31,(31*8+offes_intregs)(a0)
962 #if SIZEOF_VOID_P == 8
964 ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
965 ldc1 $f1 ,( 1*8+offes_fltregs)(a0)
966 ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
967 ldc1 $f3 ,( 3*8+offes_fltregs)(a0)
968 ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
969 ldc1 $f5 ,( 5*8+offes_fltregs)(a0)
970 ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
971 ldc1 $f7 ,( 7*8+offes_fltregs)(a0)
972 ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
973 ldc1 $f9 ,( 9*8+offes_fltregs)(a0)
974 ldc1 $f10,(10*8+offes_fltregs)(a0)
975 ldc1 $f11,(11*8+offes_fltregs)(a0)
976 ldc1 $f12,(12*8+offes_fltregs)(a0)
977 ldc1 $f13,(13*8+offes_fltregs)(a0)
978 ldc1 $f14,(14*8+offes_fltregs)(a0)
979 ldc1 $f15,(15*8+offes_fltregs)(a0)
980 ldc1 $f16,(16*8+offes_fltregs)(a0)
981 ldc1 $f17,(17*8+offes_fltregs)(a0)
982 ldc1 $f18,(18*8+offes_fltregs)(a0)
983 ldc1 $f19,(19*8+offes_fltregs)(a0)
984 ldc1 $f20,(20*8+offes_fltregs)(a0)
985 ldc1 $f21,(21*8+offes_fltregs)(a0)
986 ldc1 $f22,(22*8+offes_fltregs)(a0)
987 ldc1 $f23,(23*8+offes_fltregs)(a0)
988 ldc1 $f24,(24*8+offes_fltregs)(a0)
989 ldc1 $f25,(25*8+offes_fltregs)(a0)
990 ldc1 $f26,(26*8+offes_fltregs)(a0)
991 ldc1 $f27,(27*8+offes_fltregs)(a0)
992 ldc1 $f28,(28*8+offes_fltregs)(a0)
993 ldc1 $f29,(29*8+offes_fltregs)(a0)
994 ldc1 $f30,(30*8+offes_fltregs)(a0)
995 ldc1 $f31,(31*8+offes_fltregs)(a0)
997 #else /* SIZEOF_VOID_P == 8 */
999 ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
1000 ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
1001 ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
1002 ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
1003 ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
1004 ldc1 $f10,(10*8+offes_fltregs)(a0)
1005 ldc1 $f12,(12*8+offes_fltregs)(a0)
1006 ldc1 $f14,(14*8+offes_fltregs)(a0)
1007 ldc1 $f16,(16*8+offes_fltregs)(a0)
1008 ldc1 $f18,(18*8+offes_fltregs)(a0)
1009 ldc1 $f20,(20*8+offes_fltregs)(a0)
1010 ldc1 $f22,(22*8+offes_fltregs)(a0)
1011 ldc1 $f24,(24*8+offes_fltregs)(a0)
1012 ldc1 $f26,(26*8+offes_fltregs)(a0)
1013 ldc1 $f28,(28*8+offes_fltregs)(a0)
1014 ldc1 $f30,(30*8+offes_fltregs)(a0)
1016 #endif /* SIZEOF_VOID_P == 8 */
1020 ald itmp3,offes_pc(a0)
1024 ald a0,(4*8+offes_intregs)(a0)
1026 /* jump to new code */
1030 .end asm_replacement_in
1032 #endif /* defined(ENABLE_REPLACEMENT) */
1035 .ent asm_getclassvalues_atomic
1037 asm_getclassvalues_atomic:
1040 lw t0,offbaseval(a0)
1041 lw t1,offdiffval(a0)
1042 lw t2,offbaseval(a1)
1044 sw t0,offcast_super_baseval(a2)
1045 sw t1,offcast_super_diffval(a2)
1046 sw t2,offcast_sub_baseval(a2)
1049 .end asm_getclassvalues_atomic
1053 asm_criticalsections:
1054 #if defined(ENABLE_THREADS)
1057 .dword _crit_restart
1064 .ent compare_and_swap
1077 .end compare_and_swap
1080 /* Disable exec-stacks, required for Gentoo ***********************************/
1082 #if defined(__GCC__) && defined(__ELF__)
1083 .section .note.GNU-stack,"",@progbits
1088 * These are local overrides for various environment variables in Emacs.
1089 * Please do not remove this and leave it at the end of the file, where
1090 * Emacs will automagically detect them.
1091 * ---------------------------------------------------------------------
1094 * indent-tabs-mode: t
1098 * vim:noexpandtab:sw=4:ts=4: