1 /* src/vm/jit/powerpc/asmpart.S - Java-C interface functions for PowerPC
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.text; 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
31 Changes: Christian Thalinger
34 $Id: asmpart.S 4712 2006-03-30 11:59:46Z twisti $
44 #include "vm/jit/abi-asm.h"
45 #include "vm/jit/methodheader.h"
46 #include "vm/jit/powerpc/offsets.h"
54 /* exported functions and variables *******************************************/
56 .globl asm_vm_call_method
57 .globl asm_vm_call_method_int
58 .globl asm_vm_call_method_long
59 .globl asm_vm_call_method_float
60 .globl asm_vm_call_method_double
62 .globl asm_vm_call_method_exception_handler
64 .globl asm_call_jit_compiler
66 .globl asm_handle_nat_exception
67 .globl asm_handle_exception
69 .globl asm_wrapper_patcher
71 .globl asm_replacement_out
72 .globl asm_replacement_in
75 .globl asm_initialize_thread_stack
76 .globl asm_perform_threadswitch
77 .globl asm_switchstackandcall
78 .globl asm_criticalsections
79 .globl asm_getclassvalues_atomic
82 /* asm_vm_call_method **********************************************************
84 * This function calls a Java-method (which possibly needs compilation) *
85 * with up to 4 address parameters. *
87 * This functions calls the JIT-compiler which eventually translates the *
88 * method into machine code. *
91 * javaobject_header *asm_calljavamethod (methodinfo *m, *
92 * void *arg1, void *arg2, void *arg3, void *arg4); *
94 *******************************************************************************/
98 .long 0 /* catch type all */
99 .long 0 /* exception handler pc */
101 .long 0 /* start pc */
102 .long 1 /* extable size */
103 .long 0 /* line number table start */
104 .long 0 /* line number table size */
105 .long 0 /* fltsave */
106 .long 0 /* intsave */
109 .long 0 /* frame size */
110 .long 0 /* method pointer (pointer to name) */
113 asm_vm_call_method_int:
114 asm_vm_call_method_long:
115 asm_vm_call_method_float:
116 asm_vm_call_method_double:
118 stw r0,LA_LR_OFFSET(r1)
121 #if defined(__DARWIN__)
122 stw itmp1,10*4(sp) /* register r11 is callee saved */
124 stw pv,11*4(sp) /* save PV register */
126 stw itmp3,12*4(sp) /* registers r14-r31 are callee saved */
127 stfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
130 #if defined(__DARWIN__)
146 SAVE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
149 stw a0,9*4(r1) /* save method pointer for compiler */
151 mr itmp1,r5 /* pointer to arg block */
152 mr itmp2,r4 /* arg count */
154 addi itmp1,itmp1,-sizevmarg /* initialize pointer (smaller code) */
155 addi itmp2,itmp2,1 /* initialize argument count */
156 li t0,0 /* initialize integer argument counter */
157 li t1,0 /* initialize float argument counter */
159 mflr r0 /* save link register (PIC code) */
160 bl L_asm_vm_call_method_get_pc
161 L_asm_vm_call_method_get_pc:
162 mflr t3 /* t3 contains the current pc */
166 addi itmp1,itmp1,sizevmarg /* goto next argument block */
167 addi itmp2,itmp2,-1 /* argument count - 1 */
169 beq L_register_copy_done
171 #if WORDS_BIGENDIAN == 1
172 lwz itmp3,offvmargtype+4(itmp1)
176 andi. r0,itmp3,0x0002 /* is this a float/double type? */
177 bne L_register_handle_float
179 cmpwi t0,INT_ARG_CNT /* are we out of integer argument */
180 beq L_register_copy /* registers? yes, next loop */
182 andi. r0,itmp3,0x0001 /* is this a long type? */
183 bne L_register_handle_long
185 L_register_handle_int:
186 #if defined(__DARWIN__)
187 addis itmp3,t3,ha16(L_jumptable_int - L_asm_vm_call_method_get_pc)
188 la itmp3,lo16(L_jumptable_int - L_asm_vm_call_method_get_pc)(itmp3)
190 lis itmp3,L_jumptable_int@ha
191 addi itmp3,itmp3,L_jumptable_int@l
193 slwi t2,t0,2 /* multiple of 4-bytes */
194 add itmp3,itmp3,t2 /* calculate address of jumptable */
195 lwz itmp3,0(itmp3) /* load function address */
196 addi t0,t0,1 /* integer argument counter + 1 */
200 L_register_handle_long:
201 #if defined(__DARWIN__)
202 addis itmp3,t3,ha16(L_jumptable_long - L_asm_vm_call_method_get_pc)
203 la itmp3,lo16(L_jumptable_long - L_asm_vm_call_method_get_pc)(itmp3)
205 lis itmp3,L_jumptable_long@ha
206 addi itmp3,itmp3,L_jumptable_long@l
208 addi t2,t0,1 /* align to even numbers */
211 slwi t2,t2,2 /* multiple of 4-bytes */
212 add itmp3,itmp3,t2 /* calculate address of jumptable */
213 lwz itmp3,0(itmp3) /* load function address */
214 addi t0,t0,1 /* integer argument counter + 1 */
218 L_register_handle_float:
219 L_register_copy_done:
222 lwz itmp1,9*4(sp) /* pass method pointer via tmp1 */
224 #if defined(__DARWIN__)
225 addis mptr,t3,ha16(L_asm_call_jit_compiler - L_asm_vm_call_method_get_pc)
226 la mptr,lo16(L_asm_call_jit_compiler - L_asm_vm_call_method_get_pc)(mptr)
228 lis mptr,L_asm_call_jit_compiler@ha
229 addi mptr,mptr,L_asm_call_jit_compiler@l
239 #if defined(__DARWIN__)
240 addi pv,itmp1,lo16(asm_vm_call_method-1b)
242 addi pv,itmp1,(asm_vm_call_method-1b)@l
245 L_asm_vm_call_method_return:
246 #if defined(__DARWIN__)
247 lwz itmp1,10*4(sp) /* register r11 is callee saved */
249 lwz pv,11*4(sp) /* save PV register */
252 lfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
255 #if defined(__DARWIN__)
271 RESTORE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
274 lwz r0,40*4+LA_LR_OFFSET(r1)
279 asm_vm_call_method_exception_handler:
282 bl L_builtin_throw_exception$stub
284 li v0,0 /* return NULL */
285 b L_asm_vm_call_method_return
305 lwz a0,offvmargdata+4(itmp1)
308 lwz a1,offvmargdata+4(itmp1)
311 lwz a2,offvmargdata+4(itmp1)
314 lwz a3,offvmargdata+4(itmp1)
317 lwz a4,offvmargdata+4(itmp1)
320 lwz a5,offvmargdata+4(itmp1)
323 lwz a6,offvmargdata+4(itmp1)
326 lwz a7,offvmargdata+4(itmp1)
334 #if defined(__DARWIN__)
336 /* we have two entries here, so we get the even argument register
337 alignment for linux */
353 lwz a0,offvmargdata+0(itmp1)
354 lwz a1,offvmargdata+4(itmp1)
357 lwz a2,offvmargdata+0(itmp1)
358 lwz a3,offvmargdata+4(itmp1)
361 lwz a4,offvmargdata+0(itmp1)
362 lwz a5,offvmargdata+4(itmp1)
365 lwz a6,offvmargdata+0(itmp1)
366 lwz a7,offvmargdata+4(itmp1)
370 /* asm_call_jit_compiler *******************************************************
372 Invokes the compiler for untranslated JavaVM methods.
374 *******************************************************************************/
376 asm_call_jit_compiler:
377 L_asm_call_jit_compiler: /* required for PIC code */
379 stw r0,LA_LR_OFFSET(r1) /* save return address */
380 stwu r1,-((LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo)(r1)
381 stw itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
383 mr itmp1,r0 /* save return address to other reg. */
401 stw mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
403 #if defined(__DARWIN__)
404 stw a0,(LA_WORD_SIZE+5+0)*4(r1)
405 stw a1,(LA_WORD_SIZE+5+1)*4(r1)
406 stw a2,(LA_WORD_SIZE+5+2)*4(r1)
407 stw a3,(LA_WORD_SIZE+5+3)*4(r1)
408 stw a4,(LA_WORD_SIZE+5+4)*4(r1)
409 stw a5,(LA_WORD_SIZE+5+5)*4(r1)
410 stw a6,(LA_WORD_SIZE+5+6)*4(r1)
411 stw a7,(LA_WORD_SIZE+5+7)*4(r1)
413 stfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
414 stfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
415 stfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
416 stfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
417 stfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
418 stfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
419 stfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
420 stfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
421 stfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
422 stfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
423 stfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
424 stfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
425 stfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
427 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
430 addi a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
431 li a1,0 /* we don't have pv handy */
432 addi a2,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
433 lwz a3,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(sp)
434 mr a4,a3 /* xpc is equal to ra */
435 bl L_stacktrace_create_extern_stackframeinfo$stub
437 lwz a0,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
438 bl L_jit_compile$stub /* compile the Java method */
439 mr pv,r3 /* move address to pv register */
441 addi a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
442 bl L_stacktrace_remove_stackframeinfo$stub
444 #if defined(__DARWIN__)
445 lwz a0,(LA_WORD_SIZE+5+0)*4(r1)
446 lwz a1,(LA_WORD_SIZE+5+1)*4(r1)
447 lwz a2,(LA_WORD_SIZE+5+2)*4(r1)
448 lwz a3,(LA_WORD_SIZE+5+3)*4(r1)
449 lwz a4,(LA_WORD_SIZE+5+4)*4(r1)
450 lwz a5,(LA_WORD_SIZE+5+5)*4(r1)
451 lwz a6,(LA_WORD_SIZE+5+6)*4(r1)
452 lwz a7,(LA_WORD_SIZE+5+7)*4(r1)
454 lfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
455 lfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
456 lfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
457 lfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
458 lfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
459 lfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
460 lfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
461 lfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
462 lfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
463 lfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
464 lfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
465 lfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
466 lfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
468 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
471 lwz mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
473 lwz itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(r1)
475 addi r1,r1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
477 mr. pv,pv /* test for exception */
478 beq L_asm_call_jit_compiler_exception
483 stw pv,0(mptr) /* store method address */
485 mtctr pv /* move method address to control reg */
486 bctr /* and call the Java method */
488 L_asm_call_jit_compiler_exception:
489 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
491 stw r0,LA_LR_OFFSET(sp)
492 stwu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
493 bl L_builtin_asm_get_exceptionptrptr$stub
494 lwz r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
496 addi sp,sp,LA_SIZE_ALIGNED
498 # if defined(__DARWIN__)
499 lis v0,ha16(_no_threads_exceptionptr)
500 addi v0,v0,lo16(_no_threads_exceptionptr)
502 lis v0,_no_threads_exceptionptr@ha
503 addi v0,v0,_no_threads_exceptionptr@l
506 lwz xptr,0(v0) /* get the exception pointer */
508 stw itmp3,0(v0) /* clear the exception pointer */
512 b L_asm_handle_nat_exception
515 /********************* function asm_handle_exception ***************************
517 * This function handles an exception. It does not use the usual calling *
518 * conventions. The exception pointer is passed in REG_ITMP1 and the *
519 * pc from the exception raising position is passed in REG_ITMP2. It searches *
520 * the local exception table for a handler. If no one is found, it unwinds *
521 * stacks and continues searching the callers. *
523 * void asm_handle_exception (exceptionptr, exceptionpc); *
525 *******************************************************************************/
527 asm_handle_nat_exception:
528 L_asm_handle_nat_exception: /* required for PIC code */
536 bne L_asm_handle_exception
541 asm_handle_exception:
542 L_asm_handle_exception: /* required for PIC code */
543 addi sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
545 #if defined(__DARWIN__)
547 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
548 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
551 li a3,(ARG_CNT+TMP_CNT)*8 /* prepare a3 for handle_exception */
552 li a4,1 /* set maybe-leaf flag */
554 L_asm_handle_exception_stack_loop:
555 addi sp,sp,-(LA_WORD_SIZE+4+5)*4 /* allocate stack */
556 stw xptr,LA_SIZE+4*4(sp) /* save exception pointer */
557 stw xpc,LA_SIZE+5*4(sp) /* save exception pc */
558 stw pv,LA_SIZE+6*4(sp) /* save data segment pointer */
559 mflr r0 /* save return address */
560 stw r0,LA_SIZE+5*4(sp)
561 add a3,a3,sp /* calculate Java sp into a3... */
562 addi a3,a3,(LA_WORD_SIZE+4+5)*4
563 stw a4,LA_SIZE+8*4(sp) /* save maybe-leaf flag */
565 mr a0,xptr /* pass exception pointer */
566 mr a1,xpc /* pass exception pc */
567 mr a2,pv /* pass data segment pointer */
568 /* a3 is still set */
569 bl L_exceptions_handle_exception$stub
572 beq L_asm_handle_exception_not_catched
574 mr xpc,v0 /* move handlerpc into xpc */
575 lwz xptr,LA_SIZE+4*4(sp) /* restore exception pointer */
576 lwz pv,LA_SIZE+6*4(sp) /* restore data segment pointer */
577 lwz r0,LA_SIZE+5*4(sp) /* restore return address */
579 lwz a4,LA_SIZE+8*4(sp) /* get maybe-leaf flag */
580 addi sp,sp,(LA_WORD_SIZE+4+5)*4 /* free stack frame */
583 beq L_asm_handle_exception_no_leaf
585 #if defined(__DARWIN__)
587 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
588 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
591 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
593 L_asm_handle_exception_no_leaf:
594 mtctr xpc /* jump to the handler */
597 L_asm_handle_exception_not_catched:
598 lwz xptr,LA_SIZE+4*4(sp) /* restore exception pointer */
599 lwz pv,LA_SIZE+6*4(sp) /* restore data segment pointer */
600 lwz r0,LA_SIZE+5*4(sp) /* restore return address */
602 lwz a4,LA_SIZE+8*4(sp) /* get maybe-leaf flag */
603 addi sp,sp,(LA_WORD_SIZE+4+5)*4 /* free stack frame */
606 beq L_asm_handle_exception_no_leaf_stack
608 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
609 li a4,0 /* clear the maybe-leaf flag */
611 L_asm_handle_exception_no_leaf_stack:
612 lwz t0,FrameSize(pv) /* get frame size */
613 add t0,sp,t0 /* pointer to save area */
615 lwz t1,IsLeaf(pv) /* is leaf procedure */
617 bne L_asm_handle_exception_no_ra_restore
619 lwz r0,LA_LR_OFFSET(t0) /* restore ra */
622 L_asm_handle_exception_no_ra_restore:
623 mflr xpc /* the new xpc is ra */
624 lwz t1,IntSave(pv) /* t1 = saved int register count */
627 mflr t2 /* t2 = current pc */
628 #if defined(__DARWIN__)
629 addi t2,t2,lo16(ex_int2-ex_int1)
631 addi t2,t2,(ex_int2-ex_int1)@l
633 slwi t1,t1,2 /* t1 = register count * 4 */
634 subf t2,t1,t2 /* t2 = IntSave - t1 */
650 subf t0,t1,t0 /* t0 = t0 - register count * 4 */
656 #if defined(__DARWIN__)
657 addi t2,t2,lo16(ex_flt2-ex_flt1)
659 addi t2,t2,(ex_flt2-ex_flt1)@l
661 slwi t1,t1,2 /* t1 = register count * 4 */
662 subf t2,t1,t2 /* t2 = FltSave - t1 */
678 lwz t0,FrameSize(pv) /* get frame size */
679 add sp,sp,t0 /* unwind stack */
680 li a3,0 /* prepare a3 for handle_exception */
689 bne L_asm_handle_exception_stack_loop
694 b L_asm_handle_exception_stack_loop
697 /* asm_wrapper_patcher *********************************************************
702 20 return address into JIT code (patch position)
703 16 pointer to virtual java_objectheader
704 12 machine code (which is patched back later)
705 8 unresolved class/method/field reference
706 4 data segment displacement from load instructions
707 0 patcher function pointer to call (pv is saved here afterwards)
709 *******************************************************************************/
712 mflr r0 /* get Java return address (leaf) */
713 stw r0,6*4(sp) /* store it in the stub stackframe */
714 /* keep stack 16-bytes aligned: 6+1+37 = 44 */
715 stwu sp,-(LA_SIZE+(5+58)*4+sizestackframeinfo)(sp)
717 #if defined(__DARWIN__)
718 stw a0,LA_SIZE+(5+0)*4(r1) /* save argument registers */
719 stw a1,LA_SIZE+(5+1)*4(r1) /* preserve linkage area (24 bytes) */
720 stw a2,LA_SIZE+(5+2)*4(r1) /* and 4 bytes for 4 argument */
721 stw a3,LA_SIZE+(5+3)*4(r1)
722 stw a4,LA_SIZE+(5+4)*4(r1)
723 stw a5,LA_SIZE+(5+5)*4(r1)
724 stw a6,LA_SIZE+(5+6)*4(r1)
725 stw a7,LA_SIZE+(5+7)*4(r1)
727 stfd fa0,LA_SIZE+(5+8)*4(sp)
728 stfd fa1,LA_SIZE+(5+10)*4(sp)
729 stfd fa2,LA_SIZE+(5+12)*4(sp)
730 stfd fa3,LA_SIZE+(5+14)*4(sp)
731 stfd fa4,LA_SIZE+(5+16)*4(sp)
732 stfd fa5,LA_SIZE+(5+18)*4(sp)
733 stfd fa6,LA_SIZE+(5+20)*4(sp)
734 stfd fa7,LA_SIZE+(5+22)*4(sp)
735 stfd fa8,LA_SIZE+(5+24)*4(sp)
736 stfd fa9,LA_SIZE+(5+26)*4(sp)
737 stfd fa10,LA_SIZE+(5+28)*4(sp)
738 stfd fa11,LA_SIZE+(5+30)*4(sp)
739 stfd fa12,LA_SIZE+(5+32)*4(sp)
741 stw t0,(LA_WORD_SIZE+5+33)*4(r1)
742 stw t1,(LA_WORD_SIZE+5+34)*4(r1)
743 stw t2,(LA_WORD_SIZE+5+35)*4(r1)
744 stw t3,(LA_WORD_SIZE+5+36)*4(r1)
745 stw t4,(LA_WORD_SIZE+5+37)*4(r1)
746 stw t5,(LA_WORD_SIZE+5+38)*4(r1)
747 stw t6,(LA_WORD_SIZE+5+39)*4(r1)
748 stw t7,(LA_WORD_SIZE+5+40)*4(r1)
750 stfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
751 stfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
752 stfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
753 stfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
754 stfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
755 stfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
757 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* save 8 int/8 float arguments */
758 SAVE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
761 stw itmp1,LA_SIZE+(5+54)*4(sp)
762 stw itmp2,LA_SIZE+(5+55)*4(sp)
763 stw pv,LA_SIZE+(5+56)*4(sp)
765 addi a0,sp,LA_SIZE+(5+58)*4 /* create stackframe info */
767 addi a2,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
768 mr a3,r0 /* this is correct for leafs */
769 lwz a4,((5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo)(sp) /* pass xpc */
770 bl L_stacktrace_create_extern_stackframeinfo$stub
772 addi a0,sp,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo /* pass sp */
773 lwz pv,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* get function */
774 lwz itmp1,LA_SIZE+(5+56)*4(sp) /* move pv to position of fp */
775 stw itmp1,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
776 mtctr pv /* call the patcher function */
778 stw v0,LA_SIZE+(5+57)*4(sp) /* save return value */
780 addi a0,sp,LA_SIZE+(5+58)*4
781 bl L_stacktrace_remove_stackframeinfo$stub /* remove stackframe info */
783 #if defined(__DARWIN__)
784 lwz a0,LA_SIZE+(5+0)*4(r1)
785 lwz a1,LA_SIZE+(5+1)*4(r1)
786 lwz a2,LA_SIZE+(5+2)*4(r1)
787 lwz a3,LA_SIZE+(5+3)*4(r1)
788 lwz a4,LA_SIZE+(5+4)*4(r1)
789 lwz a5,LA_SIZE+(5+5)*4(r1)
790 lwz a6,LA_SIZE+(5+6)*4(r1)
791 lwz a7,LA_SIZE+(5+7)*4(r1)
793 lfd fa0,LA_SIZE+(5+8)*4(sp)
794 lfd fa1,LA_SIZE+(5+10)*4(sp)
795 lfd fa2,LA_SIZE+(5+12)*4(sp)
796 lfd fa3,LA_SIZE+(5+14)*4(sp)
797 lfd fa4,LA_SIZE+(5+16)*4(sp)
798 lfd fa5,LA_SIZE+(5+18)*4(sp)
799 lfd fa6,LA_SIZE+(5+20)*4(sp)
800 lfd fa7,LA_SIZE+(5+22)*4(sp)
801 lfd fa8,LA_SIZE+(5+24)*4(sp)
802 lfd fa9,LA_SIZE+(5+26)*4(sp)
803 lfd fa10,LA_SIZE+(5+28)*4(sp)
804 lfd fa11,LA_SIZE+(5+30)*4(sp)
805 lfd fa12,LA_SIZE+(5+32)*4(sp)
807 lwz t0,(LA_WORD_SIZE+5+33)*4(r1)
808 lwz t1,(LA_WORD_SIZE+5+34)*4(r1)
809 lwz t2,(LA_WORD_SIZE+5+35)*4(r1)
810 lwz t3,(LA_WORD_SIZE+5+36)*4(r1)
811 lwz t4,(LA_WORD_SIZE+5+37)*4(r1)
812 lwz t5,(LA_WORD_SIZE+5+38)*4(r1)
813 lwz t6,(LA_WORD_SIZE+5+39)*4(r1)
814 lwz t7,(LA_WORD_SIZE+5+40)*4(r1)
816 lfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
817 lfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
818 lfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
819 lfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
820 lfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
821 lfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
823 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* restore 8 int/8 float args */
824 RESTORE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
827 lwz itmp1,LA_SIZE+(5+54)*4(sp)
828 lwz itmp2,LA_SIZE+(5+55)*4(sp)
829 lwz pv,LA_SIZE+(5+56)*4(sp)
830 lwz itmp3,LA_SIZE+(5+57)*4(sp) /* restore return value into temp reg.*/
832 lwz r0,(6+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* restore RA */
835 mr. itmp3,itmp3 /* check for an exception */
836 beq L_asm_wrapper_patcher_exception
838 /* get return address (into JIT code) */
839 lwz itmp3,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
841 /* remove stack frame + patcher stub stack */
842 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
845 bctr /* jump to new patched code */
847 L_asm_wrapper_patcher_exception:
848 lwz xpc,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
849 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
851 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
853 stw r0,LA_LR_OFFSET(sp)
854 stwu sp,-(LA_SIZE+1*4)(sp) /* preserve linkage area */
855 stw xpc,LA_SIZE+0*4(sp)
856 bl L_builtin_asm_get_exceptionptrptr$stub
857 lwz xpc,LA_SIZE+0*4(sp)
858 lwz r0,LA_SIZE+1*4+LA_LR_OFFSET(sp)
860 addi sp,sp,LA_SIZE+1*4
862 # if defined(__DARWIN__)
863 lis v0,ha16(_no_threads_exceptionptr)
864 addi v0,v0,lo16(_no_threads_exceptionptr)
866 lis v0,_no_threads_exceptionptr@ha
867 addi v0,v0,_no_threads_exceptionptr@l
871 lwz xptr,0(v0) /* get the exception pointer */
873 stw itmp3,0(v0) /* clear the exception pointer */
874 b L_asm_handle_exception
877 /* asm_replacement_out *********************************************************
879 This code is jumped to from the replacement-out stubs that are executed
880 when a thread reaches an activated replacement point.
882 The purpose of asm_replacement_out is to read out the parts of the
883 execution state that cannot be accessed from C code, store this state,
884 and then call the C function replace_me.
887 16 start of stack inside method to replace
888 0 rplpoint * info on the replacement point that was reached
890 NOTE: itmp3 has been clobbered by the replacement-out stub!
892 *******************************************************************************/
894 /* some room to accomodate changes of the stack frame size during replacement */
895 /* XXX we should find a cleaner solution here */
896 #define REPLACEMENT_ROOM 512
899 /* create stack frame */
900 addi sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
902 /* save link register */
905 /* save registers in execution state */
906 stw r0 ,( 0*8+offes_intregs)(sp)
907 stw r1 ,( 1*8+offes_intregs)(sp)
908 stw r2 ,( 2*8+offes_intregs)(sp)
909 stw r3 ,( 3*8+offes_intregs)(sp)
910 stw r4 ,( 4*8+offes_intregs)(sp)
911 stw r5 ,( 5*8+offes_intregs)(sp)
912 stw r6 ,( 6*8+offes_intregs)(sp)
913 stw r7 ,( 7*8+offes_intregs)(sp)
914 stw r8 ,( 8*8+offes_intregs)(sp)
915 stw r9 ,( 9*8+offes_intregs)(sp)
916 stw r10,(10*8+offes_intregs)(sp)
917 stw r11,(11*8+offes_intregs)(sp)
918 stw r12,(12*8+offes_intregs)(sp)
919 stw r13,(13*8+offes_intregs)(sp)
920 stw r14,(14*8+offes_intregs)(sp)
921 stw r15,(15*8+offes_intregs)(sp)
922 stw r16,(16*8+offes_intregs)(sp) /* link register */
923 stw r17,(17*8+offes_intregs)(sp)
924 stw r18,(18*8+offes_intregs)(sp)
925 stw r19,(19*8+offes_intregs)(sp)
926 stw r20,(20*8+offes_intregs)(sp)
927 stw r21,(21*8+offes_intregs)(sp)
928 stw r22,(22*8+offes_intregs)(sp)
929 stw r23,(23*8+offes_intregs)(sp)
930 stw r24,(24*8+offes_intregs)(sp)
931 stw r25,(25*8+offes_intregs)(sp)
932 stw r26,(26*8+offes_intregs)(sp)
933 stw r27,(27*8+offes_intregs)(sp)
934 stw r28,(28*8+offes_intregs)(sp)
935 stw r29,(29*8+offes_intregs)(sp)
936 stw r30,(30*8+offes_intregs)(sp)
937 stw r31,(31*8+offes_intregs)(sp)
939 stfd fr0 ,( 0*8+offes_fltregs)(sp)
940 stfd fr1 ,( 1*8+offes_fltregs)(sp)
941 stfd fr2 ,( 2*8+offes_fltregs)(sp)
942 stfd fr3 ,( 3*8+offes_fltregs)(sp)
943 stfd fr4 ,( 4*8+offes_fltregs)(sp)
944 stfd fr5 ,( 5*8+offes_fltregs)(sp)
945 stfd fr6 ,( 6*8+offes_fltregs)(sp)
946 stfd fr7 ,( 7*8+offes_fltregs)(sp)
947 stfd fr8 ,( 8*8+offes_fltregs)(sp)
948 stfd fr9 ,( 9*8+offes_fltregs)(sp)
949 stfd fr10,(10*8+offes_fltregs)(sp)
950 stfd fr11,(11*8+offes_fltregs)(sp)
951 stfd fr12,(12*8+offes_fltregs)(sp)
952 stfd fr13,(13*8+offes_fltregs)(sp)
953 stfd fr14,(14*8+offes_fltregs)(sp)
954 stfd fr15,(15*8+offes_fltregs)(sp)
955 stfd fr16,(16*8+offes_fltregs)(sp)
956 stfd fr17,(17*8+offes_fltregs)(sp)
957 stfd fr18,(18*8+offes_fltregs)(sp)
958 stfd fr19,(19*8+offes_fltregs)(sp)
959 stfd fr20,(20*8+offes_fltregs)(sp)
960 stfd fr21,(21*8+offes_fltregs)(sp)
961 stfd fr22,(22*8+offes_fltregs)(sp)
962 stfd fr23,(23*8+offes_fltregs)(sp)
963 stfd fr24,(24*8+offes_fltregs)(sp)
964 stfd fr25,(25*8+offes_fltregs)(sp)
965 stfd fr26,(26*8+offes_fltregs)(sp)
966 stfd fr27,(27*8+offes_fltregs)(sp)
967 stfd fr28,(28*8+offes_fltregs)(sp)
968 stfd fr29,(29*8+offes_fltregs)(sp)
969 stfd fr30,(30*8+offes_fltregs)(sp)
970 stfd fr31,(31*8+offes_fltregs)(sp)
972 /* calculate sp of method */
973 addi itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
974 stw itmp1,(offes_sp)(sp)
977 stw pv,(offes_pv)(sp)
979 /* call replace_me */
980 lwz a0,-(4*4)(itmp1) /* arg0: rplpoint * */
981 mr a1,sp /* arg1: execution state */
982 addi sp,sp,-(LA_SIZE_ALIGNED)
983 b L_replace_me$stub /* call C function replace_me */
985 /* asm_replacement_in **********************************************************
987 This code writes the given execution state and jumps to the replacement
990 This function never returns!
992 NOTE: itmp3 is not restored!
995 void asm_replacement_in(executionstate *es);
997 *******************************************************************************/
1000 /* a0 == executionstate *es */
1002 /* set new sp and pv */
1003 lwz sp,(offes_sp)(a0)
1004 lwz pv,(offes_pv)(a0)
1006 /* copy registers from execution state */
1007 lwz r0 ,( 0*8+offes_intregs)(a0)
1009 /* r2 is reserved */
1010 /* a0 is loaded below */
1011 lwz r4 ,( 4*8+offes_intregs)(a0)
1012 lwz r5 ,( 5*8+offes_intregs)(a0)
1013 lwz r6 ,( 6*8+offes_intregs)(a0)
1014 lwz r7 ,( 7*8+offes_intregs)(a0)
1015 lwz r8 ,( 8*8+offes_intregs)(a0)
1016 lwz r9 ,( 9*8+offes_intregs)(a0)
1017 lwz r10,(10*8+offes_intregs)(a0)
1018 lwz r11,(11*8+offes_intregs)(a0)
1019 lwz r12,(12*8+offes_intregs)(a0)
1021 lwz r14,(14*8+offes_intregs)(a0)
1022 lwz r15,(15*8+offes_intregs)(a0)
1023 lwz r16,(16*8+offes_intregs)(a0) /* link register */
1024 lwz r17,(17*8+offes_intregs)(a0)
1025 lwz r18,(18*8+offes_intregs)(a0)
1026 lwz r19,(19*8+offes_intregs)(a0)
1027 lwz r20,(20*8+offes_intregs)(a0)
1028 lwz r21,(21*8+offes_intregs)(a0)
1029 lwz r22,(22*8+offes_intregs)(a0)
1030 lwz r23,(23*8+offes_intregs)(a0)
1031 lwz r24,(24*8+offes_intregs)(a0)
1032 lwz r25,(25*8+offes_intregs)(a0)
1033 lwz r26,(26*8+offes_intregs)(a0)
1034 lwz r27,(27*8+offes_intregs)(a0)
1035 lwz r28,(28*8+offes_intregs)(a0)
1036 lwz r29,(29*8+offes_intregs)(a0)
1037 lwz r30,(30*8+offes_intregs)(a0)
1038 lwz r31,(31*8+offes_intregs)(a0)
1040 lfd fr0 ,( 0*8+offes_fltregs)(a0)
1041 lfd fr1 ,( 1*8+offes_fltregs)(a0)
1042 lfd fr2 ,( 2*8+offes_fltregs)(a0)
1043 lfd fr3 ,( 3*8+offes_fltregs)(a0)
1044 lfd fr4 ,( 4*8+offes_fltregs)(a0)
1045 lfd fr5 ,( 5*8+offes_fltregs)(a0)
1046 lfd fr6 ,( 6*8+offes_fltregs)(a0)
1047 lfd fr7 ,( 7*8+offes_fltregs)(a0)
1048 lfd fr8 ,( 8*8+offes_fltregs)(a0)
1049 lfd fr9 ,( 9*8+offes_fltregs)(a0)
1050 lfd fr10,(10*8+offes_fltregs)(a0)
1051 lfd fr11,(11*8+offes_fltregs)(a0)
1052 lfd fr12,(12*8+offes_fltregs)(a0)
1053 lfd fr13,(13*8+offes_fltregs)(a0)
1054 lfd fr14,(14*8+offes_fltregs)(a0)
1055 lfd fr15,(15*8+offes_fltregs)(a0)
1056 lfd fr16,(16*8+offes_fltregs)(a0)
1057 lfd fr17,(17*8+offes_fltregs)(a0)
1058 lfd fr18,(18*8+offes_fltregs)(a0)
1059 lfd fr19,(19*8+offes_fltregs)(a0)
1060 lfd fr20,(20*8+offes_fltregs)(a0)
1061 lfd fr21,(21*8+offes_fltregs)(a0)
1062 lfd fr22,(22*8+offes_fltregs)(a0)
1063 lfd fr23,(23*8+offes_fltregs)(a0)
1064 lfd fr24,(24*8+offes_fltregs)(a0)
1065 lfd fr25,(25*8+offes_fltregs)(a0)
1066 lfd fr26,(26*8+offes_fltregs)(a0)
1067 lfd fr27,(27*8+offes_fltregs)(a0)
1068 lfd fr28,(28*8+offes_fltregs)(a0)
1069 lfd fr29,(29*8+offes_fltregs)(a0)
1070 lfd fr30,(30*8+offes_fltregs)(a0)
1071 lfd fr31,(31*8+offes_fltregs)(a0)
1073 /* restore link register */
1079 lwz itmp3,offes_pc(a0)
1083 lwz a0,(3*8+offes_intregs)(a0)
1085 /* jump to new code */
1090 /*********************************************************************/
1122 asm_initialize_thread_stack:
1152 #if defined(__DARWIN__)
1153 lfd fr0,lo16(doublezero-0b)(r3)
1155 lfd fr0,(doublezero-0b)@l(r3)
1182 asm_perform_threadswitch:
1274 asm_switchstackandcall:
1292 asm_getclassvalues_atomic:
1295 lwz r6,offbaseval(r3)
1296 lwz r7,offdiffval(r3)
1297 lwz r8,offbaseval(r4)
1299 stw r6,offcast_super_baseval(r5)
1300 stw r7,offcast_super_diffval(r5)
1301 stw r8,offcast_sub_baseval(r5)
1306 asm_criticalsections:
1307 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1315 #if defined(__DARWIN__)
1317 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1319 L_builtin_throw_exception$stub:
1320 .indirect_symbol _builtin_throw_exception
1322 bcl 20,31,L00$_builtin_throw_exception
1323 L00$_builtin_throw_exception:
1325 addis r11,r11,ha16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)
1327 lwzu r12,lo16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)(r11)
1331 .lazy_symbol_pointer
1332 L_builtin_throw_exception$lazy_ptr:
1333 .indirect_symbol _builtin_throw_exception
1334 .long dyld_stub_binding_helper
1337 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1339 L_exceptions_handle_exception$stub:
1340 .indirect_symbol _exceptions_handle_exception
1342 bcl 20,31,L00$_exceptions_handle_exception
1343 L00$_exceptions_handle_exception:
1345 addis r11,r11,ha16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)
1347 lwzu r12,lo16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)(r11)
1351 .lazy_symbol_pointer
1352 L_exceptions_handle_exception$lazy_ptr:
1353 .indirect_symbol _exceptions_handle_exception
1354 .long dyld_stub_binding_helper
1357 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1359 L_stacktrace_create_extern_stackframeinfo$stub:
1360 .indirect_symbol _stacktrace_create_extern_stackframeinfo
1362 bcl 20,31,L00$_stacktrace_create_extern_stackframeinfo
1363 L00$_stacktrace_create_extern_stackframeinfo:
1365 addis r11,r11,ha16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)
1367 lwzu r12,lo16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)(r11)
1371 .lazy_symbol_pointer
1372 L_stacktrace_create_extern_stackframeinfo$lazy_ptr:
1373 .indirect_symbol _stacktrace_create_extern_stackframeinfo
1374 .long dyld_stub_binding_helper
1377 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1380 .indirect_symbol _jit_compile
1382 bcl 20,31,L00$_jit_compile
1385 addis r11,r11,ha16(L_jit_compile$lazy_ptr - L00$_jit_compile)
1387 lwzu r12,lo16(L_jit_compile$lazy_ptr - L00$_jit_compile)(r11)
1391 .lazy_symbol_pointer
1392 L_jit_compile$lazy_ptr:
1393 .indirect_symbol _jit_compile
1394 .long dyld_stub_binding_helper
1397 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1399 L_stacktrace_remove_stackframeinfo$stub:
1400 .indirect_symbol _stacktrace_remove_stackframeinfo
1402 bcl 20,31,L00$_stacktrace_remove_stackframeinfo
1403 L00$_stacktrace_remove_stackframeinfo:
1405 addis r11,r11,ha16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)
1407 lwzu r12,lo16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)(r11)
1411 .lazy_symbol_pointer
1412 L_stacktrace_remove_stackframeinfo$lazy_ptr:
1413 .indirect_symbol _stacktrace_remove_stackframeinfo
1414 .long dyld_stub_binding_helper
1417 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1419 L_builtin_asm_get_exceptionptrptr$stub:
1420 .indirect_symbol _builtin_asm_get_exceptionptrptr
1422 bcl 20,31,L00$_builtin_asm_get_exceptionptrptr
1423 L00$_builtin_asm_get_exceptionptrptr:
1425 addis r11,r11,ha16(L_builtin_asm_get_exceptionptrptr$lazy_ptr - L00$_builtin_asm_get_exceptionptrptr)
1427 lwzu r12,lo16(L_builtin_asm_get_exceptionptrptr$lazy_ptr - L00$_builtin_asm_get_exceptionptrptr)(r11)
1431 .lazy_symbol_pointer
1432 L_builtin_asm_get_exceptionptrptr$lazy_ptr:
1433 .indirect_symbol _builtin_asm_get_exceptionptrptr
1434 .long dyld_stub_binding_helper
1437 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1440 .indirect_symbol _replace_me
1442 bcl 20,31,L00$_replace_me
1445 addis r11,r11,ha16(L_replace_me$lazy_ptr - L00$_replace_me)
1447 lwzu r12,lo16(L_replace_me$lazy_ptr - L00$_replace_me)(r11)
1451 .lazy_symbol_pointer
1452 L_replace_me$lazy_ptr:
1453 .indirect_symbol _replace_me
1454 .long dyld_stub_binding_helper
1456 #endif /* defined(__DARWIN__) */
1459 /* Disable exec-stacks, required for Gentoo ***********************************/
1461 #if defined(__GCC__) && defined(__ELF__)
1462 .section .note.GNU-stack,"",@progbits
1467 * These are local overrides for various environment variables in Emacs.
1468 * Please do not remove this and leave it at the end of the file, where
1469 * Emacs will automagically detect them.
1470 * ---------------------------------------------------------------------
1473 * indent-tabs-mode: t
1477 * vim:noexpandtab:sw=4:ts=4: