1 /* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
3 Copyright (C) 1996-2005, 2006, 2007 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 $Id: asmpart.S 7678 2007-04-09 17:23:55Z twisti $
32 #include "vm/jit/mips/md-abi.h"
33 #include "vm/jit/mips/md-asm.h"
34 #include "vm/jit/mips/offsets.h"
36 #include "vm/jit/abi-asm.h"
37 #include "vm/jit/methodheader.h"
44 /* export functions ***********************************************************/
46 .globl asm_vm_call_method
47 .globl asm_vm_call_method_int
48 .globl asm_vm_call_method_long
49 .globl asm_vm_call_method_float
50 .globl asm_vm_call_method_double
51 .globl asm_vm_call_method_exception_handler
52 .globl asm_vm_call_method_end
54 .globl asm_call_jit_compiler
56 .globl asm_handle_exception
57 .globl asm_handle_nat_exception
59 .globl asm_abstractmethoderror
61 .globl asm_patcher_wrapper
63 #if defined(ENABLE_REPLACEMENT)
64 .globl asm_replacement_out
65 .globl asm_replacement_in
68 .globl asm_getclassvalues_atomic
69 .globl asm_criticalsections
71 .globl compare_and_swap
74 /* asm_vm_call_method **********************************************************
76 * This function calls a Java-method (which possibly needs compilation) *
77 * with up to 4 address parameters. *
79 * This functions calls the JIT-compiler which eventually translates the *
80 * method into machine code. *
82 * A possibly throwed exception will be returned to the caller as function *
83 * return value, so the java method cannot return a fucntion value (this *
84 * function usually calls 'main' and '<clinit>' which do not return a *
88 * javaobject_header *asm_calljavafunction (methodinfo *m, *
89 * void *arg1, void *arg2, void *arg3, void *arg4); *
91 *******************************************************************************/
93 .ent asm_vm_call_method
97 #if SIZEOF_VOID_P == 8
99 .dword 0 /* catch type all */
100 .dword 0 /* handler pc */
101 .dword 0 /* end pc */
102 .dword 0 /* start pc */
103 .word 1 /* extable size */
104 .word 0 /* 4-byte ALIGNMENT PADDING */
105 .dword 0 /* line number table start */
106 .dword 0 /* line number table size */
107 .word 0 /* 4-byte ALIGNMENT PADDING */
108 .word 0 /* fltsave */
109 .word 0 /* intsave */
112 .word 0 /* frame size */
113 .dword 0 /* codeinfo pointer */
115 #else /* SIZEOF_VOID_P == 8 */
117 .word 0 /* catch type all */
118 .word 0 /* handler pc */
120 .word 0 /* start pc */
121 .word 1 /* extable size */
122 .word 0 /* line number table start */
123 .word 0 /* line number table size */
124 .word 0 /* fltsave */
125 .word 0 /* intsave */
128 .word 0 /* frame size */
129 .word 0 /* method pointer (pointer to name) */
131 #endif /* SIZEOF_VOID_P == 8 */
134 asm_vm_call_method_int:
135 asm_vm_call_method_long:
136 asm_vm_call_method_float:
137 asm_vm_call_method_double:
138 .set noreorder /* XXX we need to recompute pv */
140 aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
141 ast ra,0*8(sp) /* save return address */
143 bal L_asm_vm_call_method_compute_pv
144 ast pv,1*8(sp) /* procedure vector */
145 L_asm_vm_call_method_compute_pv:
150 #if SIZEOF_VOID_P == 8
151 sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
159 ast a0,4*8(sp) /* save method pointer for compiler */
161 move t0,a2 /* address of first block */
162 move s7,a1 /* argument count */
163 blez s7,calljava_argsloaded
166 #if SIZEOF_VOID_P == 8
168 ald a0,offvmargdata(t0)
169 ldc1 fa0,offvmargdata(t0)
171 blez s7,calljava_argsloaded
174 ald a1,offvmargdata+sizevmarg*1(t0)
175 ldc1 fa1,offvmargdata+sizevmarg*1(t0)
177 blez s7,calljava_argsloaded
180 ald a2,offvmargdata+sizevmarg*2(t0)
181 ldc1 fa2,offvmargdata+sizevmarg*2(t0)
183 blez s7,calljava_argsloaded
186 ald a3,offvmargdata+sizevmarg*3(t0)
187 ldc1 fa3,offvmargdata+sizevmarg*3(t0)
189 blez s7,calljava_argsloaded
192 ald a4,offvmargdata+sizevmarg*4(t0)
193 ldc1 fa4,offvmargdata+sizevmarg*4(t0)
195 blez s7,calljava_argsloaded
198 ald a5,offvmargdata+sizevmarg*5(t0)
199 ldc1 fa5,offvmargdata+sizevmarg*5(t0)
201 blez s7,calljava_argsloaded
204 ald a6,offvmargdata+sizevmarg*6(t0)
205 ldc1 fa6,offvmargdata+sizevmarg*6(t0)
207 blez s7,calljava_argsloaded
210 ald a7,offvmargdata+sizevmarg*7(t0)
211 ldc1 fa7,offvmargdata+sizevmarg*7(t0)
214 #else /* SIZEOF_VOID_P == 8 */
216 #if WORDS_BIGENDIAN == 1
217 ald a0,offvmargdata+4(t0)
219 ald a0,offvmargdata(t0)
221 #if !defined(ENABLE_SOFT_FLOAT)
222 ldc1 fa0,offvmargdata(t0)
225 blez s7,calljava_argsloaded
227 #if WORDS_BIGENDIAN == 1
228 ald a1,offvmargdata+4+sizevmarg*1(t0)
230 ald a1,offvmargdata+sizevmarg*1(t0)
232 #if !defined(ENABLE_SOFT_FLOAT)
233 ldc1 fa1,offvmargdata+sizevmarg*1(t0)
236 blez s7,calljava_argsloaded
238 #if WORDS_BIGENDIAN == 1
239 ald a2,offvmargdata+4+sizevmarg*2(t0)
241 ald a2,offvmargdata+sizevmarg*2(t0)
244 blez s7,calljava_argsloaded
246 #if WORDS_BIGENDIAN == 1
247 ald a3,offvmargdata+4+sizevmarg*3(t0)
249 ald a3,offvmargdata+sizevmarg*3(t0)
252 blez s7,calljava_argsloaded
254 #endif /* SIZEOF_VOID_P == 8 */
257 move t4,sp /* save stack pointer */
258 blez s7,calljava_nocopy
261 #if SIZEOF_VOID_P == 4
262 aaddiu s7,s7,4 /* add stack space for 4 arguments */
264 subu t1,zero,s7 /* remaining argument count (negative) */
265 sll t2,t1,3 /* calculate stackframe size */
266 aaddu sp,sp,t2 /* create stackframe */
267 aaddu t2,t2,t4 /* also set temp sp */
268 #if SIZEOF_VOID_P == 4
269 aaddiu t2,t2,4*8 /* skip stack space for 4 arguments */
274 #if SIZEOF_VOID_P == 8
275 ald t3,offvmargdata+sizevmarg*8(t0)
277 # if WORDS_BIGENDIAN == 1
278 ald t3,offvmargdata+4+sizevmarg*4(t0)
280 ald t3,offvmargdata+sizevmarg*4(t0)
283 ast t3,0(t2) /* store argument on stack */
284 addi t1,t1,1 /* count 1 argument */
285 aaddi t0,t0,sizevmarg /* load address of next block */
286 aaddi t2,t2,8 /* increase stack position */
287 bnez t1,calljava_copyloop /* all arguments copied? */
291 ald itmp1,4*8(t4) /* pass method pointer via itmp1 */
293 ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
294 ast mptr,2*8(t4) /* store function address */
295 ala mptr,1*8(t4) /* set method pointer */
297 ald pv,1*8(mptr) /* method call as in Java */
298 jalr pv /* call JIT compiler */
300 L_asm_vm_call_method_recompute_pv:
301 #if SIZEOF_VOID_P == 8
302 aaddiu pv,ra,-76*4 /* recompute procedure vector */
304 aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
307 .set reorder /* XXX we need to recompute pv */
309 sll t1,s7,3 /* remove argument stackframe */
313 ald ra,0*8(sp) /* restore return address */
314 ald pv,1*8(sp) /* restore procedure vector */
317 #if SIZEOF_VOID_P == 8
318 ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
326 aaddiu sp,sp,12*8 /* free stack space */
329 asm_vm_call_method_exception_handler:
330 sll t1,s7,3 /* remove stackframe */
332 #if SIZEOF_VOID_P == 4
333 aaddiu sp,sp,-4*4 /* reserve space for 1 argument */
337 jal builtin_throw_exception
338 #if SIZEOF_VOID_P == 4
341 asm_vm_call_method_end:
344 .end asm_vm_call_method
347 /****************** function asm_call_jit_compiler *****************************
349 * invokes the compiler for untranslated JavaVM methods. *
351 * Register REG_ITEMP1 contains a pointer to the method info structure *
352 * (prepared by createcompilerstub). Using the return address in R31 and the *
353 * offset in the LDA instruction or using the value in methodptr R25 the *
354 * patching address for storing the method address can be computed: *
356 * method address was either loaded using *
357 * M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
358 * M_JSR (REG_RA, REG_PV); *
360 * M_LDA (REG_PV, REG_RA, val) *
362 * M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
363 * M_JSR (REG_RA, REG_PV); *
365 * in the static case the method pointer can be computed using the *
366 * return address and the lda function following the jmp instruction *
368 *******************************************************************************/
370 .ent asm_call_jit_compiler
372 asm_call_jit_compiler:
373 #if SIZEOF_VOID_P == 8
375 aaddiu sp,sp,-(ARG_CNT+2)*8 /* +2: keep stack 16-bytes aligned */
377 ast ra,0*8(sp) /* save return address */
379 SAVE_ARGUMENT_REGISTERS(1)
381 move a0,itmp1 /* pass methodinfo pointer */
382 move a1,mptr /* pass method pointer */
383 aaddiu a2,sp,(ARG_CNT+2)*8 /* pass java sp */
385 jal jit_asm_compile /* call jit compiler */
388 ald ra,0*8(sp) /* restore return address */
390 RESTORE_ARGUMENT_REGISTERS(1)
392 aaddiu sp,sp,(ARG_CNT+2)*8 /* remove stack frame */
394 #else /* SIZEOF_VOID_P == 8 */
396 aaddiu sp,sp,-(ARG_CNT+2)*8 /* +4: keep stack 16-bytes aligned */
398 ast ra,4*4+0*4(sp) /* save return address */
400 SAVE_ARGUMENT_REGISTERS(6)
402 move a0,itmp1 /* pass methodinfo pointer */
403 move a1,mptr /* pass method pointer */
404 aaddiu a2,sp,(ARG_CNT+2)*8 /* pass java sp */
406 jal jit_asm_compile /* call jit compiler */
409 ald ra,4*4+0*4(sp) /* restore return address */
411 RESTORE_ARGUMENT_REGISTERS(6)
413 aaddiu sp,sp,(ARG_CNT+2)*8 /* remove stack frame */
415 #endif /* SIZEOF_VOID_P == 8 */
417 beqz pv,L_asm_call_jit_compiler_exception
419 jr pv /* and call method. The method returns */
420 /* directly to the caller (ra). */
422 L_asm_call_jit_compiler_exception:
425 jal exceptions_get_and_clear_exception
429 move xptr,v0 /* get exception */
430 aaddiu xpc,ra,-4 /* exception address is RA - 4 */
431 b asm_handle_nat_exception
433 .end asm_call_jit_compiler
436 /* asm_handle_exception ********************************************************
438 This function handles an exception. It does not use the usual calling
439 conventions. The exception pointer is passed in REG_ITMP1 and the
440 pc from the exception raising position is passed in REG_ITMP2. It searches
441 the local exception table for a handler. If no one is found, it unwinds
442 stacks and continues searching the callers.
444 *******************************************************************************/
446 .ent asm_handle_nat_exception
448 asm_handle_nat_exception:
449 L_asm_handle_exception_stack_loop:
450 #if SIZEOF_VOID_P == 8
451 aaddiu sp,sp,-6*8 /* keep stack 16-byte aligned */
452 ast xptr,0*8(sp) /* save exception pointer */
453 ast xpc,1*8(sp) /* save exception pc */
454 ast ra,3*8(sp) /* save RA */
455 ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */
457 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
458 ast xptr,4*4+0*8(sp) /* save exception pointer */
459 ast xpc,4*4+1*8(sp) /* save exception pc */
460 ast ra,4*4+3*8(sp) /* save return address */
461 ast zero,4*4+4*8(sp) /* save maybe-leaf flag (cleared) */
464 move a0,ra /* pass RA */
465 jal md_codegen_get_pv_from_pc /* get PV from RA */
467 #if SIZEOF_VOID_P == 8
468 ast v0,2*8(sp) /* save PV */
470 ald a0,0*8(sp) /* pass xptr */
471 ald a1,1*8(sp) /* pass xpc */
472 move a2,v0 /* pass PV */
473 aaddiu a3,sp,6*8 /* pass Java SP */
475 ast v0,4*4+2*8(sp) /* save data segment pointer */
477 ald a0,4*4+0*8(sp) /* pass exception pointer */
478 ald a1,4*4+1*8(sp) /* pass exception pc */
479 move a2,v0 /* pass data segment pointer */
480 aaddiu a3,sp,(4*4+6*8) /* pass Java stack pointer */
483 b L_asm_handle_exception_continue
485 .aent asm_handle_exception
487 asm_handle_exception:
488 aaddiu sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
490 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
491 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
493 #if SIZEOF_VOID_P == 8
494 aaddiu sp,sp,-6*8 /* allocate stack */
495 ast xptr,0*8(sp) /* save exception pointer */
496 ast pv,2*8(sp) /* save PV */
497 ast ra,3*8(sp) /* save RA */
498 addu t0,zero,1 /* set maybe-leaf flag */
499 ast t0,4*8(sp) /* save maybe-leaf flag */
501 aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
502 ast xptr,4*4+0*8(sp) /* save exception pointer */
503 ast xpc,4*4+1*8(sp) /* save exception pc */
504 ast pv,4*4+2*8(sp) /* save data segment pointer */
505 ast ra,4*4+3*8(sp) /* save return address */
506 addu t0,zero,1 /* set maybe-leaf flag */
507 ast t0,4*4+4*8(sp) /* save maybe-leaf flag */
510 move a0,xptr /* pass xptr */
511 move a1,xpc /* pass xpc */
512 move a2,pv /* pass PV */
514 #if SIZEOF_VOID_P == 8
515 aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP */
517 aaddiu a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */
520 L_asm_handle_exception_continue:
521 jal exceptions_handle_exception
523 beqz v0,L_asm_handle_exception_not_catched
525 move xpc,v0 /* move handlerpc into xpc */
527 #if SIZEOF_VOID_P == 8
528 ald xptr,0*8(sp) /* restore exception pointer */
529 ald pv,2*8(sp) /* restore PV */
530 ald ra,3*8(sp) /* restore RA */
531 ald t0,4*8(sp) /* get maybe-leaf flag */
532 aaddiu sp,sp,6*8 /* free stackframe */
534 ald xptr,4*4+0*8(sp) /* restore exception pointer */
535 ald pv,4*4+2*8(sp) /* restore data segment pointer */
536 ald ra,4*4+3*8(sp) /* restore return address */
537 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
538 aaddiu sp,sp,4*4+6*8 /* free stackframe */
541 beqz t0,L_asm_handle_exception_no_leaf
543 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
544 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
546 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
548 L_asm_handle_exception_no_leaf:
549 jr xpc /* jump to the handler */
551 L_asm_handle_exception_not_catched:
552 #if SIZEOF_VOID_P == 8
553 ald xptr,0*8(sp) /* restore xptr */
554 ald pv,2*8(sp) /* restore PV */
555 ald ra,3*8(sp) /* restore RA */
556 ald t0,4*8(sp) /* get maybe-leaf flag */
557 aaddiu sp,sp,6*8 /* free stackframe */
559 ald xptr,4*4+0*8(sp) /* restore xptr */
560 ald pv,4*4+2*8(sp) /* restore PV */
561 ald ra,4*4+3*8(sp) /* restore RA */
562 ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
563 aaddiu sp,sp,4*4+6*8 /* free stackframe */
566 beqz t0,L_asm_handle_exception_no_leaf_stack
568 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
569 move t0,zero /* clear the maybe-leaf flag */
571 L_asm_handle_exception_no_leaf_stack:
572 lw t1,FrameSize(pv) /* get frame size */
573 aaddu t1,sp,t1 /* pointer to save area */
575 lw t2,IsLeaf(pv) /* is leaf procedure */
576 bnez t2,L_asm_handle_exception_no_ra_restore
578 ald ra,-1*8(t1) /* restore ra */
579 aaddiu t1,t1,-8 /* t1-- */
581 L_asm_handle_exception_no_ra_restore:
582 move xpc,ra /* the new xpc is ra */
583 lw t2,IntSave(pv) /* t1 = saved int register count */
584 ala t3,ex_int2 /* t3 = current pc */
585 sll t2,t2,2 /* t2 = register count * 4 */
586 asubu t3,t3,t2 /* t3 = IntSave - 4 * register count */
587 jr t3 /* jump to save position */
599 sll t2,t2,1 /* t2 = register count * 4 * 2 */
600 asubu t1,t1,t2 /* t1 = t0 - 8 * register count */
602 lw t2,FltSave(pv) /* t2 = saved flt register count */
603 ala t3,ex_flt2 /* t3 = current pc */
604 sll t2,t2,2 /* t2 = register count * 4 */
605 asubu t3,t3,t2 /* t3 = ex_int_sav - 4 * register count */
606 jr t3 /* jump to save position */
608 #if SIZEOF_VOID_P == 8
613 #else /* SIZEOF_VOID_P == 8 */
614 # if !defined(ENABLE_SOFT_FLOAT)
621 # endif /* !defined(ENABLE_SOFT_FLOAT) */
622 #endif /* SIZEOF_VOID_P == 8 */
625 lw t1,FrameSize(pv) /* get frame size */
626 aaddu sp,sp,t1 /* unwind stack */
627 b L_asm_handle_exception_stack_loop
629 .end asm_handle_nat_exception
632 /* asm_abstractmethoderror *****************************************************
634 Creates and throws an AbstractMethodError.
636 *******************************************************************************/
638 .ent asm_abstractmethoderror
640 asm_abstractmethoderror:
641 aaddiu sp,sp,-2*8 /* create stackframe */
642 ast ra,0*8(sp) /* save return address */
643 aaddiu a0,sp,2*8 /* pass java sp */
644 move a1,ra /* pass exception address */
645 jal exceptions_asm_new_abstractmethoderror
646 ald ra,0*8(sp) /* restore return address */
647 aaddiu sp,sp,2*8 /* remove stackframe */
649 move xptr,v0 /* get exception pointer */
650 aaddiu xpc,ra,-4 /* exception address is ra - 4 */
651 b asm_handle_nat_exception
653 .end asm_abstractmethoderror
656 /* asm_patcher_wrapper *********************************************************
661 56 return address into JIT code (patch position)
662 48 pointer to virtual java_objectheader
663 40 machine code (which is patched back later)
664 32 machine code (which is patched back later)
665 24 machine code (which is patched back later)
666 16 unresolved class/method/field reference
667 8 data segment displacement from load instructions
668 0 patcher function pointer to call
670 *******************************************************************************/
672 .ent asm_patcher_wrapper
675 #if SIZEOF_VOID_P == 8
677 aaddiu sp,sp,-((2+16+22+4)*8)/* create stack frame */
679 SAVE_RETURN_REGISTERS(0) /* save 1 int/1 float return registers */
680 SAVE_ARGUMENT_REGISTERS(2) /* save 8 int/8 float argument registers */
681 SAVE_TEMPORARY_REGISTERS(18) /* save 5 int/16 float temporary registers */
683 ast itmp1,(2+16+22+0)*8(sp) /* save itmp1 */
684 ast itmp2,(2+16+22+1)*8(sp) /* save itmp2 */
685 ast ra,(2+16+22+2)*8(sp) /* save method return address (for leafs) */
686 ast pv,(2+16+22+3)*8(sp) /* save pv of calling java function */
688 aaddiu a0,sp,(2+16+22+4)*8 /* pass SP of patcher stub */
689 move a1,pv /* pass PV */
690 move a2,ra /* pass RA (correct for leafs) */
694 RESTORE_RETURN_REGISTERS(0) /* restore 1 int/1 float return registers */
695 RESTORE_ARGUMENT_REGISTERS(2) /* restore 8 int/8 float argument registers */
696 RESTORE_TEMPORARY_REGISTERS(18) /* restore 5 int/16 float temporary reg. */
698 ald itmp1,(2+16+22+0)*8(sp) /* restore itmp1 */
699 ald itmp2,(2+16+22+1)*8(sp) /* restore itmp2 */
700 ald ra,(2+16+22+2)*8(sp) /* restore method return address (for leafs)*/
701 ald pv,(2+16+22+3)*8(sp) /* restore pv of calling java function */
703 bnez itmp3,L_asm_patcher_wrapper_exception
705 ald itmp3,(7+2+16+22+4)*8(sp) /* load RA */
706 aaddiu sp,sp,(8+2+16+22+4)*8 /* remove stack frame */
708 jr itmp3 /* jump to new patched code */
710 L_asm_patcher_wrapper_exception:
711 move xptr,itmp3 /* get exception */
712 ald xpc,(7+2+16+22+4)*8(sp) /* xpc is RA */
713 aaddiu sp,sp,(8+2+16+22+4)*8 /* remove stack frame */
715 #else /* SIZEOF_VOID_P == 8 */
717 aaddiu sp,sp,-((6+4+8+16+7)*4) /* create stack frame */
718 /* +7 keeps the SP 16-bytes aligned */
720 SAVE_RETURN_REGISTERS(6) /* save 2 int / 1 float return registers */
721 SAVE_ARGUMENT_REGISTERS(10) /* save 4 int / 2 float argument registers */
722 SAVE_TEMPORARY_REGISTERS(18) /* save 8 int / 4 float temporary registers */
724 ast itmp1,(6+4+8+16+0)*4(sp) /* save itmp1 */
725 ast itmp2,(6+4+8+16+1)*4(sp) /* save itmp2 */
726 ast ra,(6+4+8+16+2)*4(sp) /* save method return address (for leafs) */
727 ast pv,(6+4+8+16+3)*4(sp) /* save pv of calling java function */
729 aaddiu a0,sp,(6+4+8+16+7)*4 /* pass SP of patcher stub */
730 move a1,pv /* pass PV */
731 move a2,ra /* pass RA (correct for leafs) */
735 RESTORE_RETURN_REGISTERS(6) /* restore 2 int / 2 float return registers */
736 RESTORE_ARGUMENT_REGISTERS(10) /* restore 4 int / 2 float argument regs */
737 RESTORE_TEMPORARY_REGISTERS(18) /* restore 8 int / 4 float temporary regs */
739 ald itmp1,(6+4+8+16+0)*4(sp) /* restore itmp1 */
740 ald itmp2,(6+4+8+16+1)*4(sp) /* restore itmp2 */
741 ald ra,(6+4+8+16+2)*4(sp) /* restore method return address (for leafs)*/
742 ald pv,(6+4+8+16+3)*4(sp) /* restore pv of calling java function */
744 bnez itmp3,L_asm_wrapper_patcher_exception
746 ald itmp3,7*8+(6+4+8+16+7)*4(sp) /* load RA */
747 aaddiu sp,sp,8*8+(6+4+8+16+7)*4 /* remove stack frame */
749 jr itmp3 /* jump to new patched code */
751 L_asm_wrapper_patcher_exception:
752 move xptr,itmp3 /* get exception */
753 ald xpc,7*8+(6+4+8+16+7)*4(sp) /* xpc is RA */
754 aaddiu sp,sp,8*8+(6+4+8+16+7)*4 /* remove stack frame */
756 #endif /* SIZEOF_VOID_P == 8 */
758 b asm_handle_exception
760 .end asm_patcher_wrapper
762 #if defined(ENABLE_REPLACEMENT)
764 /* asm_replacement_out *********************************************************
766 This code is jumped to from the replacement-out stubs that are executed
767 when a thread reaches an activated replacement point.
769 The purpose of asm_replacement_out is to read out the parts of the
770 execution state that cannot be accessed from C code, store this state,
771 and then call the C function replace_me.
774 16 start of stack inside method to replace
775 0 rplpoint * info on the replacement point that was reached
777 NOTE: itmp3 has been clobbered by the replacement-out stub!
779 *******************************************************************************/
781 /* some room to accomodate changes of the stack frame size during replacement */
782 /* XXX we should find a cleaner solution here */
783 #define REPLACEMENT_ROOM 512
785 #define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
787 .ent asm_replacement_out
790 /* create stack frame */
791 aaddiu sp,sp,-REPLACEMENT_STACK_OFFSET
793 /* save registers in execution state */
794 ast $0 ,( 0*8+offes_intregs)(sp)
795 ast $1 ,( 1*8+offes_intregs)(sp)
796 ast $2 ,( 2*8+offes_intregs)(sp)
797 ast $3 ,( 3*8+offes_intregs)(sp)
798 ast $4 ,( 4*8+offes_intregs)(sp)
799 ast $5 ,( 5*8+offes_intregs)(sp)
800 ast $6 ,( 6*8+offes_intregs)(sp)
801 ast $7 ,( 7*8+offes_intregs)(sp)
802 ast $8 ,( 8*8+offes_intregs)(sp)
803 ast $9 ,( 9*8+offes_intregs)(sp)
804 ast $10,(10*8+offes_intregs)(sp)
805 ast $11,(11*8+offes_intregs)(sp)
806 ast $12,(12*8+offes_intregs)(sp)
807 ast $13,(13*8+offes_intregs)(sp)
808 ast $14,(14*8+offes_intregs)(sp)
809 ast $15,(15*8+offes_intregs)(sp)
810 ast $16,(16*8+offes_intregs)(sp)
811 ast $17,(17*8+offes_intregs)(sp)
812 ast $18,(18*8+offes_intregs)(sp)
813 ast $19,(19*8+offes_intregs)(sp)
814 ast $20,(20*8+offes_intregs)(sp)
815 ast $21,(21*8+offes_intregs)(sp)
816 ast $22,(22*8+offes_intregs)(sp)
817 ast $23,(23*8+offes_intregs)(sp)
818 ast $24,(24*8+offes_intregs)(sp)
819 ast $25,(25*8+offes_intregs)(sp)
820 ast $26,(26*8+offes_intregs)(sp)
821 ast $27,(27*8+offes_intregs)(sp)
822 ast $28,(28*8+offes_intregs)(sp)
823 ast $29,(29*8+offes_intregs)(sp)
824 ast $30,(30*8+offes_intregs)(sp)
825 ast $31,(31*8+offes_intregs)(sp)
827 #if SIZEOF_VOID_P == 8
829 sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
830 sdc1 $f1 ,( 1*8+offes_fltregs)(sp)
831 sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
832 sdc1 $f3 ,( 3*8+offes_fltregs)(sp)
833 sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
834 sdc1 $f5 ,( 5*8+offes_fltregs)(sp)
835 sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
836 sdc1 $f7 ,( 7*8+offes_fltregs)(sp)
837 sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
838 sdc1 $f9 ,( 9*8+offes_fltregs)(sp)
839 sdc1 $f10,(10*8+offes_fltregs)(sp)
840 sdc1 $f11,(11*8+offes_fltregs)(sp)
841 sdc1 $f12,(12*8+offes_fltregs)(sp)
842 sdc1 $f13,(13*8+offes_fltregs)(sp)
843 sdc1 $f14,(14*8+offes_fltregs)(sp)
844 sdc1 $f15,(15*8+offes_fltregs)(sp)
845 sdc1 $f16,(16*8+offes_fltregs)(sp)
846 sdc1 $f17,(17*8+offes_fltregs)(sp)
847 sdc1 $f18,(18*8+offes_fltregs)(sp)
848 sdc1 $f19,(19*8+offes_fltregs)(sp)
849 sdc1 $f20,(20*8+offes_fltregs)(sp)
850 sdc1 $f21,(21*8+offes_fltregs)(sp)
851 sdc1 $f22,(22*8+offes_fltregs)(sp)
852 sdc1 $f23,(23*8+offes_fltregs)(sp)
853 sdc1 $f24,(24*8+offes_fltregs)(sp)
854 sdc1 $f25,(25*8+offes_fltregs)(sp)
855 sdc1 $f26,(26*8+offes_fltregs)(sp)
856 sdc1 $f27,(27*8+offes_fltregs)(sp)
857 sdc1 $f28,(28*8+offes_fltregs)(sp)
858 sdc1 $f29,(29*8+offes_fltregs)(sp)
859 sdc1 $f30,(30*8+offes_fltregs)(sp)
860 sdc1 $f31,(31*8+offes_fltregs)(sp)
862 #else /* SIZEOF_VOID_P == 8 */
864 sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
865 sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
866 sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
867 sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
868 sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
869 sdc1 $f10,(10*8+offes_fltregs)(sp)
870 sdc1 $f12,(12*8+offes_fltregs)(sp)
871 sdc1 $f14,(14*8+offes_fltregs)(sp)
872 sdc1 $f16,(16*8+offes_fltregs)(sp)
873 sdc1 $f18,(18*8+offes_fltregs)(sp)
874 sdc1 $f20,(20*8+offes_fltregs)(sp)
875 sdc1 $f22,(22*8+offes_fltregs)(sp)
876 sdc1 $f24,(24*8+offes_fltregs)(sp)
877 sdc1 $f26,(26*8+offes_fltregs)(sp)
878 sdc1 $f28,(28*8+offes_fltregs)(sp)
879 sdc1 $f30,(30*8+offes_fltregs)(sp)
881 #endif /* SIZEOF_VOID_P == 8 */
883 /* calculate sp of method */
884 aaddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
885 ast itmp1,(offes_sp)(sp)
888 ast pv,(offes_pv)(sp)
890 /* call replace_me */
891 ald a0,-(2*8)(itmp1) /* arg0: rplpoint * */
892 move a1,sp /* arg1: execution state */
893 jal replace_me /* call C function replace_me */
894 jal abort /* NEVER REACHED */
896 .end asm_replacement_out
898 /* asm_replacement_in **********************************************************
900 This code writes the given execution state and jumps to the replacement
903 This function never returns!
905 NOTE: itmp3 is not restored!
908 void asm_replacement_in(executionstate *es);
910 *******************************************************************************/
912 .ent asm_replacement_in
915 /* a0 == executionstate *es */
917 /* set new sp and pv */
918 ald sp,(offes_sp)(a0)
919 ald pv,(offes_pv)(a0)
921 /* copy registers from execution state */
923 ald $1 ,( 1*8+offes_intregs)(a0)
924 ald $2 ,( 2*8+offes_intregs)(a0)
925 ald $3 ,( 2*8+offes_intregs)(a0)
926 /* a0 is loaded below */
927 ald $5 ,( 5*8+offes_intregs)(a0)
928 ald $6 ,( 6*8+offes_intregs)(a0)
929 ald $7 ,( 7*8+offes_intregs)(a0)
930 ald $8 ,( 8*8+offes_intregs)(a0)
931 ald $9 ,( 9*8+offes_intregs)(a0)
932 ald $10,(10*8+offes_intregs)(a0)
933 ald $11,(11*8+offes_intregs)(a0)
934 ald $12,(12*8+offes_intregs)(a0)
935 ald $13,(13*8+offes_intregs)(a0)
936 ald $14,(14*8+offes_intregs)(a0)
937 ald $15,(15*8+offes_intregs)(a0)
938 ald $16,(16*8+offes_intregs)(a0)
939 ald $17,(17*8+offes_intregs)(a0)
940 ald $18,(18*8+offes_intregs)(a0)
941 ald $19,(19*8+offes_intregs)(a0)
942 ald $20,(20*8+offes_intregs)(a0)
943 ald $21,(21*8+offes_intregs)(a0)
944 ald $22,(22*8+offes_intregs)(a0)
945 ald $23,(23*8+offes_intregs)(a0)
946 ald $24,(24*8+offes_intregs)(a0)
947 ald $25,(25*8+offes_intregs)(a0)
948 ald $26,(26*8+offes_intregs)(a0)
949 ald $27,(27*8+offes_intregs)(a0)
950 ald $28,(28*8+offes_intregs)(a0)
953 ald $31,(31*8+offes_intregs)(a0)
955 #if SIZEOF_VOID_P == 8
957 ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
958 ldc1 $f1 ,( 1*8+offes_fltregs)(a0)
959 ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
960 ldc1 $f3 ,( 3*8+offes_fltregs)(a0)
961 ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
962 ldc1 $f5 ,( 5*8+offes_fltregs)(a0)
963 ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
964 ldc1 $f7 ,( 7*8+offes_fltregs)(a0)
965 ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
966 ldc1 $f9 ,( 9*8+offes_fltregs)(a0)
967 ldc1 $f10,(10*8+offes_fltregs)(a0)
968 ldc1 $f11,(11*8+offes_fltregs)(a0)
969 ldc1 $f12,(12*8+offes_fltregs)(a0)
970 ldc1 $f13,(13*8+offes_fltregs)(a0)
971 ldc1 $f14,(14*8+offes_fltregs)(a0)
972 ldc1 $f15,(15*8+offes_fltregs)(a0)
973 ldc1 $f16,(16*8+offes_fltregs)(a0)
974 ldc1 $f17,(17*8+offes_fltregs)(a0)
975 ldc1 $f18,(18*8+offes_fltregs)(a0)
976 ldc1 $f19,(19*8+offes_fltregs)(a0)
977 ldc1 $f20,(20*8+offes_fltregs)(a0)
978 ldc1 $f21,(21*8+offes_fltregs)(a0)
979 ldc1 $f22,(22*8+offes_fltregs)(a0)
980 ldc1 $f23,(23*8+offes_fltregs)(a0)
981 ldc1 $f24,(24*8+offes_fltregs)(a0)
982 ldc1 $f25,(25*8+offes_fltregs)(a0)
983 ldc1 $f26,(26*8+offes_fltregs)(a0)
984 ldc1 $f27,(27*8+offes_fltregs)(a0)
985 ldc1 $f28,(28*8+offes_fltregs)(a0)
986 ldc1 $f29,(29*8+offes_fltregs)(a0)
987 ldc1 $f30,(30*8+offes_fltregs)(a0)
988 ldc1 $f31,(31*8+offes_fltregs)(a0)
990 #else /* SIZEOF_VOID_P == 8 */
992 ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
993 ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
994 ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
995 ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
996 ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
997 ldc1 $f10,(10*8+offes_fltregs)(a0)
998 ldc1 $f12,(12*8+offes_fltregs)(a0)
999 ldc1 $f14,(14*8+offes_fltregs)(a0)
1000 ldc1 $f16,(16*8+offes_fltregs)(a0)
1001 ldc1 $f18,(18*8+offes_fltregs)(a0)
1002 ldc1 $f20,(20*8+offes_fltregs)(a0)
1003 ldc1 $f22,(22*8+offes_fltregs)(a0)
1004 ldc1 $f24,(24*8+offes_fltregs)(a0)
1005 ldc1 $f26,(26*8+offes_fltregs)(a0)
1006 ldc1 $f28,(28*8+offes_fltregs)(a0)
1007 ldc1 $f30,(30*8+offes_fltregs)(a0)
1009 #endif /* SIZEOF_VOID_P == 8 */
1013 ald itmp3,offes_pc(a0)
1017 ald a0,(4*8+offes_intregs)(a0)
1019 /* jump to new code */
1023 .end asm_replacement_in
1025 #endif /* defined(ENABLE_REPLACEMENT) */
1028 .ent asm_getclassvalues_atomic
1030 asm_getclassvalues_atomic:
1033 lw t0,offbaseval(a0)
1034 lw t1,offdiffval(a0)
1035 lw t2,offbaseval(a1)
1037 sw t0,offcast_super_baseval(a2)
1038 sw t1,offcast_super_diffval(a2)
1039 sw t2,offcast_sub_baseval(a2)
1042 .end asm_getclassvalues_atomic
1046 asm_criticalsections:
1047 #if defined(ENABLE_THREADS)
1050 .dword _crit_restart
1057 .ent compare_and_swap
1070 .end compare_and_swap
1073 /* disable exec-stacks ********************************************************/
1075 #if defined(__linux__) && defined(__ELF__)
1076 .section .note.GNU-stack,"",%progbits
1081 * These are local overrides for various environment variables in Emacs.
1082 * Please do not remove this and leave it at the end of the file, where
1083 * Emacs will automagically detect them.
1084 * ---------------------------------------------------------------------
1087 * indent-tabs-mode: t
1091 * vim:noexpandtab:sw=4:ts=4: