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 7206 2007-01-11 22:39:52Z twisti $
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
60 .globl asm_call_jit_compiler
62 .globl asm_handle_exception
63 .globl asm_handle_nat_exception
65 .globl asm_abstractmethoderror
67 .globl asm_patcher_wrapper
69 #if defined(ENABLE_REPLACEMENT)
70 .globl asm_replacement_out
71 .globl asm_replacement_in
74 .globl asm_getclassvalues_atomic
75 .globl asm_criticalsections
77 .globl compare_and_swap
80 /* asm_vm_call_method **********************************************************
82 * This function calls a Java-method (which possibly needs compilation) *
83 * with up to 4 address parameters. *
85 * This functions calls the JIT-compiler which eventually translates the *
86 * method into machine code. *
88 * A possibly throwed exception will be returned to the caller as function *
89 * return value, so the java method cannot return a fucntion value (this *
90 * function usually calls 'main' and '<clinit>' which do not return a *
94 * javaobject_header *asm_calljavafunction (methodinfo *m, *
95 * void *arg1, void *arg2, void *arg3, void *arg4); *
97 *******************************************************************************/
99 .ent asm_vm_call_method
103 #if SIZEOF_VOID_P == 8
105 .dword 0 /* catch type all */
106 .dword 0 /* handler pc */
107 .dword 0 /* end pc */
108 .dword 0 /* start pc */
109 .word 1 /* extable size */
110 .word 0 /* 4-byte ALIGNMENT PADDING */
111 .dword 0 /* line number table start */
112 .dword 0 /* line number table size */
113 .word 0 /* 4-byte ALIGNMENT PADDING */
114 .word 0 /* fltsave */
115 .word 0 /* intsave */
118 .word 0 /* frame size */
119 .dword 0 /* codeinfo pointer */
121 #else /* SIZEOF_VOID_P == 8 */
123 .word 0 /* catch type all */
124 .word 0 /* handler pc */
126 .word 0 /* start pc */
127 .word 1 /* extable size */
128 .word 0 /* line number table start */
129 .word 0 /* line number table size */
130 .word 0 /* fltsave */
131 .word 0 /* intsave */
134 .word 0 /* frame size */
135 .word 0 /* method pointer (pointer to name) */
137 #endif /* SIZEOF_VOID_P == 8 */
140 asm_vm_call_method_int:
141 asm_vm_call_method_long:
142 asm_vm_call_method_float:
143 asm_vm_call_method_double:
144 .set noreorder /* XXX we need to recompute pv */
146 aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
147 ast ra,0*8(sp) /* save return address */
149 bal L_asm_vm_call_method_compute_pv
150 ast pv,1*8(sp) /* procedure vector */
151 L_asm_vm_call_method_compute_pv:
156 #if SIZEOF_VOID_P == 8
157 sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
165 ast a0,4*8(sp) /* save method pointer for compiler */
167 move t0,a2 /* address of first block */
168 move s7,a1 /* argument count */
169 blez s7,calljava_argsloaded
172 #if SIZEOF_VOID_P == 8
174 ald a0,offvmargdata(t0)
175 ldc1 fa0,offvmargdata(t0)
177 blez s7,calljava_argsloaded
180 ald a1,offvmargdata+sizevmarg*1(t0)
181 ldc1 fa1,offvmargdata+sizevmarg*1(t0)
183 blez s7,calljava_argsloaded
186 ald a2,offvmargdata+sizevmarg*2(t0)
187 ldc1 fa2,offvmargdata+sizevmarg*2(t0)
189 blez s7,calljava_argsloaded
192 ald a3,offvmargdata+sizevmarg*3(t0)
193 ldc1 fa3,offvmargdata+sizevmarg*3(t0)
195 blez s7,calljava_argsloaded
198 ald a4,offvmargdata+sizevmarg*4(t0)
199 ldc1 fa4,offvmargdata+sizevmarg*4(t0)
201 blez s7,calljava_argsloaded
204 ald a5,offvmargdata+sizevmarg*5(t0)
205 ldc1 fa5,offvmargdata+sizevmarg*5(t0)
207 blez s7,calljava_argsloaded
210 ald a6,offvmargdata+sizevmarg*6(t0)
211 ldc1 fa6,offvmargdata+sizevmarg*6(t0)
213 blez s7,calljava_argsloaded
216 ald a7,offvmargdata+sizevmarg*7(t0)
217 ldc1 fa7,offvmargdata+sizevmarg*7(t0)
220 #else /* SIZEOF_VOID_P == 8 */
222 #if WORDS_BIGENDIAN == 1
223 ald a0,offvmargdata+4(t0)
225 ald a0,offvmargdata(t0)
227 #if !defined(ENABLE_SOFT_FLOAT)
228 ldc1 fa0,offvmargdata(t0)
231 blez s7,calljava_argsloaded
233 #if WORDS_BIGENDIAN == 1
234 ald a1,offvmargdata+4+sizevmarg*1(t0)
236 ald a1,offvmargdata+sizevmarg*1(t0)
238 #if !defined(ENABLE_SOFT_FLOAT)
239 ldc1 fa1,offvmargdata+sizevmarg*1(t0)
242 blez s7,calljava_argsloaded
244 #if WORDS_BIGENDIAN == 1
245 ald a2,offvmargdata+4+sizevmarg*2(t0)
247 ald a2,offvmargdata+sizevmarg*2(t0)
250 blez s7,calljava_argsloaded
252 #if WORDS_BIGENDIAN == 1
253 ald a3,offvmargdata+4+sizevmarg*3(t0)
255 ald a3,offvmargdata+sizevmarg*3(t0)
258 blez s7,calljava_argsloaded
260 #endif /* SIZEOF_VOID_P == 8 */
263 move t4,sp /* save stack pointer */
264 blez s7,calljava_nocopy
267 #if SIZEOF_VOID_P == 4
268 aaddiu s7,s7,4 /* add stack space for 4 arguments */
270 subu t1,zero,s7 /* remaining argument count (negative) */
271 sll t2,t1,3 /* calculate stackframe size */
272 aaddu sp,sp,t2 /* create stackframe */
273 aaddu t2,t2,t4 /* also set temp sp */
274 #if SIZEOF_VOID_P == 4
275 aaddiu t2,t2,4*8 /* skip stack space for 4 arguments */
280 #if SIZEOF_VOID_P == 8
281 ald t3,offvmargdata+sizevmarg*8(t0)
283 # if WORDS_BIGENDIAN == 1
284 ald t3,offvmargdata+4+sizevmarg*4(t0)
286 ald t3,offvmargdata+sizevmarg*4(t0)
289 ast t3,0(t2) /* store argument on stack */
290 addi t1,t1,1 /* count 1 argument */
291 aaddi t0,t0,sizevmarg /* load address of next block */
292 aaddi t2,t2,8 /* increase stack position */
293 bnez t1,calljava_copyloop /* all arguments copied? */
297 ald itmp1,4*8(t4) /* pass method pointer via itmp1 */
299 ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
300 ast mptr,2*8(t4) /* store function address */
301 ala mptr,1*8(t4) /* set method pointer */
303 ald pv,1*8(mptr) /* method call as in Java */
304 jalr pv /* call JIT compiler */
306 L_asm_vm_call_method_recompute_pv:
307 #if SIZEOF_VOID_P == 8
308 aaddiu pv,ra,-76*4 /* recompute procedure vector */
310 aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
313 .set reorder /* XXX we need to recompute pv */
315 sll t1,s7,3 /* remove argument stackframe */
319 ald ra,0*8(sp) /* restore return address */
320 ald pv,1*8(sp) /* restore procedure vector */
323 #if SIZEOF_VOID_P == 8
324 ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
332 aaddiu sp,sp,12*8 /* free stack space */
335 asm_vm_call_method_exception_handler:
336 sll t1,s7,3 /* remove stackframe */
338 #if SIZEOF_VOID_P == 4
339 aaddiu sp,sp,-4*4 /* reserve space for 1 argument */
343 jal builtin_throw_exception
344 #if SIZEOF_VOID_P == 4
349 .end asm_vm_call_method
352 /****************** function asm_call_jit_compiler *****************************
354 * invokes the compiler for untranslated JavaVM methods. *
356 * Register REG_ITEMP1 contains a pointer to the method info structure *
357 * (prepared by createcompilerstub). Using the return address in R31 and the *
358 * offset in the LDA instruction or using the value in methodptr R25 the *
359 * patching address for storing the method address can be computed: *
361 * method address was either loaded using *
362 * M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
363 * M_JSR (REG_RA, REG_PV); *
365 * M_LDA (REG_PV, REG_RA, val) *
367 * M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
368 * M_JSR (REG_RA, REG_PV); *
370 * in the static case the method pointer can be computed using the *
371 * return address and the lda function following the jmp instruction *
373 *******************************************************************************/
375 .ent asm_call_jit_compiler
377 asm_call_jit_compiler:
378 #if SIZEOF_VOID_P == 8
380 aaddiu sp,sp,-(ARG_CNT+2)*8 /* +2: keep stack 16-bytes aligned */
382 ast ra,0*8(sp) /* save return address */
384 SAVE_ARGUMENT_REGISTERS(1)
386 move a0,itmp1 /* pass methodinfo pointer */
387 move a1,mptr /* pass method pointer */
388 aaddiu a2,sp,(ARG_CNT+2)*8 /* pass java sp */
390 jal jit_asm_compile /* call jit compiler */
393 ald ra,0*8(sp) /* restore return address */
395 RESTORE_ARGUMENT_REGISTERS(1)
397 aaddiu sp,sp,(ARG_CNT+2)*8 /* remove stack frame */
399 #else /* SIZEOF_VOID_P == 8 */
401 aaddiu sp,sp,-(ARG_CNT+2)*8 /* +4: keep stack 16-bytes aligned */
403 ast ra,4*4+0*4(sp) /* save return address */
405 SAVE_ARGUMENT_REGISTERS(6)
407 move a0,itmp1 /* pass methodinfo pointer */
408 move a1,mptr /* pass method pointer */
409 aaddiu a2,sp,(ARG_CNT+2)*8 /* pass java sp */
411 jal jit_asm_compile /* call jit compiler */
414 ald ra,4*4+0*4(sp) /* restore return address */
416 RESTORE_ARGUMENT_REGISTERS(6)
418 aaddiu sp,sp,(ARG_CNT+2)*8 /* remove stack frame */
420 #endif /* SIZEOF_VOID_P == 8 */
422 beqz pv,L_asm_call_jit_compiler_exception
424 jr pv /* and call method. The method returns */
425 /* directly to the caller (ra). */
427 L_asm_call_jit_compiler_exception:
430 jal exceptions_get_and_clear_exception
434 move xptr,v0 /* get exception */
435 aaddiu xpc,ra,-4 /* exception address is RA - 4 */
436 b asm_handle_nat_exception
438 .end asm_call_jit_compiler
441 /* asm_handle_exception ********************************************************
443 This function handles an exception. It does not use the usual calling
444 conventions. The exception pointer is passed in REG_ITMP1 and the
445 pc from the exception raising position is passed in REG_ITMP2. It searches
446 the local exception table for a handler. If no one is found, it unwinds
447 stacks and continues searching the callers.
449 *******************************************************************************/
451 .ent asm_handle_nat_exception
453 asm_handle_nat_exception:
454 L_asm_handle_exception_stack_loop:
455 #if SIZEOF_VOID_P == 8
456 aaddiu sp,sp,-6*8 /* keep stack 16-byte aligned */
457 ast xptr,0*8(sp) /* save exception pointer */
458 ast xpc,1*8(sp) /* save exception pc */
459 ast ra,3*8(sp) /* save RA */
460 ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */
462 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
463 ast xptr,4*4+0*8(sp) /* save exception pointer */
464 ast xpc,4*4+1*8(sp) /* save exception pc */
465 ast ra,4*4+3*8(sp) /* save return address */
466 ast zero,4*4+4*8(sp) /* save maybe-leaf flag (cleared) */
469 move a0,ra /* pass RA */
470 jal md_codegen_get_pv_from_pc /* get PV from RA */
472 #if SIZEOF_VOID_P == 8
473 ast v0,2*8(sp) /* save PV */
475 ald a0,0*8(sp) /* pass xptr */
476 ald a1,1*8(sp) /* pass xpc */
477 move a2,v0 /* pass PV */
478 aaddiu a3,sp,6*8 /* pass Java SP */
480 ast v0,4*4+2*8(sp) /* save data segment pointer */
482 ald a0,4*4+0*8(sp) /* pass exception pointer */
483 ald a1,4*4+1*8(sp) /* pass exception pc */
484 move a2,v0 /* pass data segment pointer */
485 aaddiu a3,sp,(4*4+6*8) /* pass Java stack pointer */
488 b L_asm_handle_exception_continue
490 .aent asm_handle_exception
492 asm_handle_exception:
493 aaddiu sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
495 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
496 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
498 #if SIZEOF_VOID_P == 8
499 aaddiu sp,sp,-6*8 /* allocate stack */
500 ast xptr,0*8(sp) /* save exception pointer */
501 ast pv,2*8(sp) /* save PV */
502 ast ra,3*8(sp) /* save RA */
503 addu t0,zero,1 /* set maybe-leaf flag */
504 ast t0,4*8(sp) /* save maybe-leaf flag */
506 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
507 ast xptr,4*4+0*8(sp) /* save exception pointer */
508 ast xpc,4*4+1*8(sp) /* save exception pc */
509 ast pv,4*4+2*8(sp) /* save data segment pointer */
510 ast ra,4*4+3*8(sp) /* save return address */
511 addu t0,zero,1 /* set maybe-leaf flag */
512 ast t0,4*4+4*8(sp) /* save maybe-leaf flag */
515 move a0,xptr /* pass xptr */
516 move a1,xpc /* pass xpc */
517 move a2,pv /* pass PV */
519 #if SIZEOF_VOID_P == 8
520 aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP */
522 aaddiu a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */
525 L_asm_handle_exception_continue:
526 jal exceptions_handle_exception
528 beqz v0,L_asm_handle_exception_not_catched
530 move xpc,v0 /* move handlerpc into xpc */
532 #if SIZEOF_VOID_P == 8
533 ald xptr,0*8(sp) /* restore exception pointer */
534 ald pv,2*8(sp) /* restore PV */
535 ald ra,3*8(sp) /* restore RA */
536 ald t0,4*8(sp) /* get maybe-leaf flag */
537 aaddiu sp,sp,6*8 /* free stackframe */
539 ald xptr,4*4+0*8(sp) /* restore exception pointer */
540 ald pv,4*4+2*8(sp) /* restore data segment pointer */
541 ald ra,4*4+3*8(sp) /* restore return address */
542 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
543 aaddiu sp,sp,4*4+6*8 /* free stackframe */
546 beqz t0,L_asm_handle_exception_no_leaf
548 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
549 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
551 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
553 L_asm_handle_exception_no_leaf:
554 jr xpc /* jump to the handler */
556 L_asm_handle_exception_not_catched:
557 #if SIZEOF_VOID_P == 8
558 ald xptr,0*8(sp) /* restore xptr */
559 ald pv,2*8(sp) /* restore PV */
560 ald ra,3*8(sp) /* restore RA */
561 ald t0,4*8(sp) /* get maybe-leaf flag */
562 aaddiu sp,sp,6*8 /* free stackframe */
564 ald xptr,4*4+0*8(sp) /* restore xptr */
565 ald pv,4*4+2*8(sp) /* restore PV */
566 ald ra,4*4+3*8(sp) /* restore RA */
567 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
568 aaddiu sp,sp,4*4+6*8 /* free stackframe */
571 beqz t0,L_asm_handle_exception_no_leaf_stack
573 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
574 move t0,zero /* clear the maybe-leaf flag */
576 L_asm_handle_exception_no_leaf_stack:
577 lw t1,FrameSize(pv) /* get frame size */
578 aaddu t1,sp,t1 /* pointer to save area */
580 lw t2,IsLeaf(pv) /* is leaf procedure */
581 bnez t2,L_asm_handle_exception_no_ra_restore
583 ald ra,-1*8(t1) /* restore ra */
584 aaddiu t1,t1,-8 /* t1-- */
586 L_asm_handle_exception_no_ra_restore:
587 move xpc,ra /* the new xpc is ra */
588 lw t2,IntSave(pv) /* t1 = saved int register count */
589 ala t3,ex_int2 /* t3 = current pc */
590 sll t2,t2,2 /* t2 = register count * 4 */
591 asubu t3,t3,t2 /* t3 = IntSave - 4 * register count */
592 jr t3 /* jump to save position */
604 sll t2,t2,1 /* t2 = register count * 4 * 2 */
605 asubu t1,t1,t2 /* t1 = t0 - 8 * register count */
607 lw t2,FltSave(pv) /* t2 = saved flt register count */
608 ala t3,ex_flt2 /* t3 = current pc */
609 sll t2,t2,2 /* t2 = register count * 4 */
610 asubu t3,t3,t2 /* t3 = ex_int_sav - 4 * register count */
611 jr t3 /* jump to save position */
613 #if SIZEOF_VOID_P == 8
618 #else /* SIZEOF_VOID_P == 8 */
619 # if !defined(ENABLE_SOFT_FLOAT)
626 # endif /* !defined(ENABLE_SOFT_FLOAT) */
627 #endif /* SIZEOF_VOID_P == 8 */
630 lw t1,FrameSize(pv) /* get frame size */
631 aaddu sp,sp,t1 /* unwind stack */
632 b L_asm_handle_exception_stack_loop
634 .end asm_handle_nat_exception
637 /* asm_abstractmethoderror *****************************************************
639 Creates and throws an AbstractMethodError.
641 *******************************************************************************/
643 .ent asm_abstractmethoderror
645 asm_abstractmethoderror:
646 aaddiu sp,sp,-2*8 /* create stackframe */
647 ast ra,0*8(sp) /* save return address */
648 aaddiu a0,sp,2*8 /* pass java sp */
649 move a1,ra /* pass exception address */
650 jal exceptions_asm_new_abstractmethoderror
651 ald ra,0*8(sp) /* restore return address */
652 aaddiu sp,sp,2*8 /* remove stackframe */
654 move xptr,v0 /* get exception pointer */
655 aaddiu xpc,ra,-4 /* exception address is ra - 4 */
656 b asm_handle_nat_exception
658 .end asm_abstractmethoderror
661 /* asm_patcher_wrapper *********************************************************
666 56 return address into JIT code (patch position)
667 48 pointer to virtual java_objectheader
668 40 machine code (which is patched back later)
669 32 machine code (which is patched back later)
670 24 machine code (which is patched back later)
671 16 unresolved class/method/field reference
672 8 data segment displacement from load instructions
673 0 patcher function pointer to call
675 *******************************************************************************/
677 .ent asm_patcher_wrapper
680 #if SIZEOF_VOID_P == 8
682 aaddiu sp,sp,-((2+16+22+4)*8)/* create stack frame */
684 SAVE_RETURN_REGISTERS(0) /* save 1 int/1 float return registers */
685 SAVE_ARGUMENT_REGISTERS(2) /* save 8 int/8 float argument registers */
686 SAVE_TEMPORARY_REGISTERS(18) /* save 5 int/16 float temporary registers */
688 ast itmp1,(2+16+22+0)*8(sp) /* save itmp1 */
689 ast itmp2,(2+16+22+1)*8(sp) /* save itmp2 */
690 ast ra,(2+16+22+2)*8(sp) /* save method return address (for leafs) */
691 ast pv,(2+16+22+3)*8(sp) /* save pv of calling java function */
693 aaddiu a0,sp,(2+16+22+4)*8 /* pass SP of patcher stub */
694 move a1,pv /* pass PV */
695 move a2,ra /* pass RA (correct for leafs) */
699 RESTORE_RETURN_REGISTERS(0) /* restore 1 int/1 float return registers */
700 RESTORE_ARGUMENT_REGISTERS(2) /* restore 8 int/8 float argument registers */
701 RESTORE_TEMPORARY_REGISTERS(18) /* restore 5 int/16 float temporary reg. */
703 ald itmp1,(2+16+22+0)*8(sp) /* restore itmp1 */
704 ald itmp2,(2+16+22+1)*8(sp) /* restore itmp2 */
705 ald ra,(2+16+22+2)*8(sp) /* restore method return address (for leafs)*/
706 ald pv,(2+16+22+3)*8(sp) /* restore pv of calling java function */
708 bnez itmp3,L_asm_patcher_wrapper_exception
710 ald itmp3,(7+2+16+22+4)*8(sp) /* load RA */
711 aaddiu sp,sp,(8+2+16+22+4)*8 /* remove stack frame */
713 jr itmp3 /* jump to new patched code */
715 L_asm_patcher_wrapper_exception:
716 move xptr,itmp3 /* get exception */
717 ald xpc,(7+2+16+22+4)*8(sp) /* xpc is RA */
718 aaddiu sp,sp,(8+2+16+22+4)*8 /* remove stack frame */
720 #else /* SIZEOF_VOID_P == 8 */
722 aaddiu sp,sp,-((5+4+4+8+7)*4) /* create stack frame */
723 /* +7 keeps the SP 16-bytes aligned */
725 SAVE_RETURN_REGISTERS(5) /* save 2 int / 2 float return registers */
726 SAVE_ARGUMENT_REGISTERS(9) /* save 4 int argument registers */
727 SAVE_TEMPORARY_REGISTERS(13) /* save 8 int temporary registers */
729 ast itmp1,(5+4+4+8+0)*4(sp) /* save itmp1 */
730 ast itmp2,(5+4+4+8+1)*4(sp) /* save itmp2 */
731 ast ra,(5+4+4+8+2)*4(sp) /* save method return address (for leafs) */
732 ast pv,(5+4+4+8+3)*4(sp) /* save pv of calling java function */
734 aaddiu a0,sp,(5+4+4+8+7)*4 /* pass SP of patcher stub */
735 move a1,pv /* pass PV */
736 move a2,ra /* pass RA (correct for leafs) */
740 RESTORE_RETURN_REGISTERS(5) /* restore 2 int / 2 float return registers */
741 RESTORE_ARGUMENT_REGISTERS(9) /* restore 4 int argument registers */
742 RESTORE_TEMPORARY_REGISTERS(13) /* restore 9 int temporary registers */
744 ald itmp1,(5+4+4+8+0)*4(sp) /* restore itmp1 */
745 ald itmp2,(5+4+4+8+1)*4(sp) /* restore itmp2 */
746 ald ra,(5+4+4+8+2)*4(sp) /* restore method return address (for leafs)*/
747 ald pv,(5+4+4+8+3)*4(sp) /* restore pv of calling java function */
749 bnez itmp3,L_asm_wrapper_patcher_exception
751 ald itmp3,7*8+(5+4+4+8+7)*4(sp) /* load RA */
752 aaddiu sp,sp,8*8+(5+4+4+8+7)*4 /* remove stack frame */
754 jr itmp3 /* jump to new patched code */
756 L_asm_wrapper_patcher_exception:
757 move xptr,itmp3 /* get exception */
758 ald xpc,7*8+(5+4+4+8+7)*4(sp) /* xpc is RA */
759 aaddiu sp,sp,8*8+(5+4+4+8+7)*4 /* remove stack frame */
761 #endif /* SIZEOF_VOID_P == 8 */
763 b asm_handle_exception
765 .end asm_patcher_wrapper
767 #if defined(ENABLE_REPLACEMENT)
769 /* asm_replacement_out *********************************************************
771 This code is jumped to from the replacement-out stubs that are executed
772 when a thread reaches an activated replacement point.
774 The purpose of asm_replacement_out is to read out the parts of the
775 execution state that cannot be accessed from C code, store this state,
776 and then call the C function replace_me.
779 16 start of stack inside method to replace
780 0 rplpoint * info on the replacement point that was reached
782 NOTE: itmp3 has been clobbered by the replacement-out stub!
784 *******************************************************************************/
786 /* some room to accomodate changes of the stack frame size during replacement */
787 /* XXX we should find a cleaner solution here */
788 #define REPLACEMENT_ROOM 512
790 #define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
792 .ent asm_replacement_out
795 /* create stack frame */
796 aaddiu sp,sp,-REPLACEMENT_STACK_OFFSET
798 /* save registers in execution state */
799 ast $0 ,( 0*8+offes_intregs)(sp)
800 ast $1 ,( 1*8+offes_intregs)(sp)
801 ast $2 ,( 2*8+offes_intregs)(sp)
802 ast $3 ,( 3*8+offes_intregs)(sp)
803 ast $4 ,( 4*8+offes_intregs)(sp)
804 ast $5 ,( 5*8+offes_intregs)(sp)
805 ast $6 ,( 6*8+offes_intregs)(sp)
806 ast $7 ,( 7*8+offes_intregs)(sp)
807 ast $8 ,( 8*8+offes_intregs)(sp)
808 ast $9 ,( 9*8+offes_intregs)(sp)
809 ast $10,(10*8+offes_intregs)(sp)
810 ast $11,(11*8+offes_intregs)(sp)
811 ast $12,(12*8+offes_intregs)(sp)
812 ast $13,(13*8+offes_intregs)(sp)
813 ast $14,(14*8+offes_intregs)(sp)
814 ast $15,(15*8+offes_intregs)(sp)
815 ast $16,(16*8+offes_intregs)(sp)
816 ast $17,(17*8+offes_intregs)(sp)
817 ast $18,(18*8+offes_intregs)(sp)
818 ast $19,(19*8+offes_intregs)(sp)
819 ast $20,(20*8+offes_intregs)(sp)
820 ast $21,(21*8+offes_intregs)(sp)
821 ast $22,(22*8+offes_intregs)(sp)
822 ast $23,(23*8+offes_intregs)(sp)
823 ast $24,(24*8+offes_intregs)(sp)
824 ast $25,(25*8+offes_intregs)(sp)
825 ast $26,(26*8+offes_intregs)(sp)
826 ast $27,(27*8+offes_intregs)(sp)
827 ast $28,(28*8+offes_intregs)(sp)
828 ast $29,(29*8+offes_intregs)(sp)
829 ast $30,(30*8+offes_intregs)(sp)
830 ast $31,(31*8+offes_intregs)(sp)
832 #if SIZEOF_VOID_P == 8
834 sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
835 sdc1 $f1 ,( 1*8+offes_fltregs)(sp)
836 sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
837 sdc1 $f3 ,( 3*8+offes_fltregs)(sp)
838 sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
839 sdc1 $f5 ,( 5*8+offes_fltregs)(sp)
840 sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
841 sdc1 $f7 ,( 7*8+offes_fltregs)(sp)
842 sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
843 sdc1 $f9 ,( 9*8+offes_fltregs)(sp)
844 sdc1 $f10,(10*8+offes_fltregs)(sp)
845 sdc1 $f11,(11*8+offes_fltregs)(sp)
846 sdc1 $f12,(12*8+offes_fltregs)(sp)
847 sdc1 $f13,(13*8+offes_fltregs)(sp)
848 sdc1 $f14,(14*8+offes_fltregs)(sp)
849 sdc1 $f15,(15*8+offes_fltregs)(sp)
850 sdc1 $f16,(16*8+offes_fltregs)(sp)
851 sdc1 $f17,(17*8+offes_fltregs)(sp)
852 sdc1 $f18,(18*8+offes_fltregs)(sp)
853 sdc1 $f19,(19*8+offes_fltregs)(sp)
854 sdc1 $f20,(20*8+offes_fltregs)(sp)
855 sdc1 $f21,(21*8+offes_fltregs)(sp)
856 sdc1 $f22,(22*8+offes_fltregs)(sp)
857 sdc1 $f23,(23*8+offes_fltregs)(sp)
858 sdc1 $f24,(24*8+offes_fltregs)(sp)
859 sdc1 $f25,(25*8+offes_fltregs)(sp)
860 sdc1 $f26,(26*8+offes_fltregs)(sp)
861 sdc1 $f27,(27*8+offes_fltregs)(sp)
862 sdc1 $f28,(28*8+offes_fltregs)(sp)
863 sdc1 $f29,(29*8+offes_fltregs)(sp)
864 sdc1 $f30,(30*8+offes_fltregs)(sp)
865 sdc1 $f31,(31*8+offes_fltregs)(sp)
867 #else /* SIZEOF_VOID_P == 8 */
869 sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
870 sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
871 sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
872 sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
873 sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
874 sdc1 $f10,(10*8+offes_fltregs)(sp)
875 sdc1 $f12,(12*8+offes_fltregs)(sp)
876 sdc1 $f14,(14*8+offes_fltregs)(sp)
877 sdc1 $f16,(16*8+offes_fltregs)(sp)
878 sdc1 $f18,(18*8+offes_fltregs)(sp)
879 sdc1 $f20,(20*8+offes_fltregs)(sp)
880 sdc1 $f22,(22*8+offes_fltregs)(sp)
881 sdc1 $f24,(24*8+offes_fltregs)(sp)
882 sdc1 $f26,(26*8+offes_fltregs)(sp)
883 sdc1 $f28,(28*8+offes_fltregs)(sp)
884 sdc1 $f30,(30*8+offes_fltregs)(sp)
886 #endif /* SIZEOF_VOID_P == 8 */
888 /* calculate sp of method */
889 aaddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
890 ast itmp1,(offes_sp)(sp)
893 ast pv,(offes_pv)(sp)
895 /* call replace_me */
896 ald a0,-(2*8)(itmp1) /* arg0: rplpoint * */
897 move a1,sp /* arg1: execution state */
898 jal replace_me /* call C function replace_me */
899 jal abort /* NEVER REACHED */
901 .end asm_replacement_out
903 /* asm_replacement_in **********************************************************
905 This code writes the given execution state and jumps to the replacement
908 This function never returns!
910 NOTE: itmp3 is not restored!
913 void asm_replacement_in(executionstate *es);
915 *******************************************************************************/
917 .ent asm_replacement_in
920 /* a0 == executionstate *es */
922 /* set new sp and pv */
923 ald sp,(offes_sp)(a0)
924 ald pv,(offes_pv)(a0)
926 /* copy registers from execution state */
928 ald $1 ,( 1*8+offes_intregs)(a0)
929 ald $2 ,( 2*8+offes_intregs)(a0)
930 ald $3 ,( 2*8+offes_intregs)(a0)
931 /* a0 is loaded below */
932 ald $5 ,( 5*8+offes_intregs)(a0)
933 ald $6 ,( 6*8+offes_intregs)(a0)
934 ald $7 ,( 7*8+offes_intregs)(a0)
935 ald $8 ,( 8*8+offes_intregs)(a0)
936 ald $9 ,( 9*8+offes_intregs)(a0)
937 ald $10,(10*8+offes_intregs)(a0)
938 ald $11,(11*8+offes_intregs)(a0)
939 ald $12,(12*8+offes_intregs)(a0)
940 ald $13,(13*8+offes_intregs)(a0)
941 ald $14,(14*8+offes_intregs)(a0)
942 ald $15,(15*8+offes_intregs)(a0)
943 ald $16,(16*8+offes_intregs)(a0)
944 ald $17,(17*8+offes_intregs)(a0)
945 ald $18,(18*8+offes_intregs)(a0)
946 ald $19,(19*8+offes_intregs)(a0)
947 ald $20,(20*8+offes_intregs)(a0)
948 ald $21,(21*8+offes_intregs)(a0)
949 ald $22,(22*8+offes_intregs)(a0)
950 ald $23,(23*8+offes_intregs)(a0)
951 ald $24,(24*8+offes_intregs)(a0)
952 ald $25,(25*8+offes_intregs)(a0)
953 ald $26,(26*8+offes_intregs)(a0)
954 ald $27,(27*8+offes_intregs)(a0)
955 ald $28,(28*8+offes_intregs)(a0)
958 ald $31,(31*8+offes_intregs)(a0)
960 #if SIZEOF_VOID_P == 8
962 ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
963 ldc1 $f1 ,( 1*8+offes_fltregs)(a0)
964 ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
965 ldc1 $f3 ,( 3*8+offes_fltregs)(a0)
966 ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
967 ldc1 $f5 ,( 5*8+offes_fltregs)(a0)
968 ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
969 ldc1 $f7 ,( 7*8+offes_fltregs)(a0)
970 ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
971 ldc1 $f9 ,( 9*8+offes_fltregs)(a0)
972 ldc1 $f10,(10*8+offes_fltregs)(a0)
973 ldc1 $f11,(11*8+offes_fltregs)(a0)
974 ldc1 $f12,(12*8+offes_fltregs)(a0)
975 ldc1 $f13,(13*8+offes_fltregs)(a0)
976 ldc1 $f14,(14*8+offes_fltregs)(a0)
977 ldc1 $f15,(15*8+offes_fltregs)(a0)
978 ldc1 $f16,(16*8+offes_fltregs)(a0)
979 ldc1 $f17,(17*8+offes_fltregs)(a0)
980 ldc1 $f18,(18*8+offes_fltregs)(a0)
981 ldc1 $f19,(19*8+offes_fltregs)(a0)
982 ldc1 $f20,(20*8+offes_fltregs)(a0)
983 ldc1 $f21,(21*8+offes_fltregs)(a0)
984 ldc1 $f22,(22*8+offes_fltregs)(a0)
985 ldc1 $f23,(23*8+offes_fltregs)(a0)
986 ldc1 $f24,(24*8+offes_fltregs)(a0)
987 ldc1 $f25,(25*8+offes_fltregs)(a0)
988 ldc1 $f26,(26*8+offes_fltregs)(a0)
989 ldc1 $f27,(27*8+offes_fltregs)(a0)
990 ldc1 $f28,(28*8+offes_fltregs)(a0)
991 ldc1 $f29,(29*8+offes_fltregs)(a0)
992 ldc1 $f30,(30*8+offes_fltregs)(a0)
993 ldc1 $f31,(31*8+offes_fltregs)(a0)
995 #else /* SIZEOF_VOID_P == 8 */
997 ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
998 ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
999 ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
1000 ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
1001 ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
1002 ldc1 $f10,(10*8+offes_fltregs)(a0)
1003 ldc1 $f12,(12*8+offes_fltregs)(a0)
1004 ldc1 $f14,(14*8+offes_fltregs)(a0)
1005 ldc1 $f16,(16*8+offes_fltregs)(a0)
1006 ldc1 $f18,(18*8+offes_fltregs)(a0)
1007 ldc1 $f20,(20*8+offes_fltregs)(a0)
1008 ldc1 $f22,(22*8+offes_fltregs)(a0)
1009 ldc1 $f24,(24*8+offes_fltregs)(a0)
1010 ldc1 $f26,(26*8+offes_fltregs)(a0)
1011 ldc1 $f28,(28*8+offes_fltregs)(a0)
1012 ldc1 $f30,(30*8+offes_fltregs)(a0)
1014 #endif /* SIZEOF_VOID_P == 8 */
1018 ald itmp3,offes_pc(a0)
1022 ald a0,(4*8+offes_intregs)(a0)
1024 /* jump to new code */
1028 .end asm_replacement_in
1030 #endif /* defined(ENABLE_REPLACEMENT) */
1033 .ent asm_getclassvalues_atomic
1035 asm_getclassvalues_atomic:
1038 lw t0,offbaseval(a0)
1039 lw t1,offdiffval(a0)
1040 lw t2,offbaseval(a1)
1042 sw t0,offcast_super_baseval(a2)
1043 sw t1,offcast_super_diffval(a2)
1044 sw t2,offcast_sub_baseval(a2)
1047 .end asm_getclassvalues_atomic
1051 asm_criticalsections:
1052 #if defined(ENABLE_THREADS)
1055 .dword _crit_restart
1062 .ent compare_and_swap
1075 .end compare_and_swap
1078 /* Disable exec-stacks, required for Gentoo ***********************************/
1080 #if defined(__GCC__) && defined(__ELF__)
1081 .section .note.GNU-stack,"",@progbits
1086 * These are local overrides for various environment variables in Emacs.
1087 * Please do not remove this and leave it at the end of the file, where
1088 * Emacs will automagically detect them.
1089 * ---------------------------------------------------------------------
1092 * indent-tabs-mode: t
1096 * vim:noexpandtab:sw=4:ts=4: