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 4749 2006-04-11 10:20:18Z twisti $
44 #include "vm/jit/abi-asm.h"
45 #include "vm/jit/methodheader.h"
46 #include "vm/jit/powerpc/offsets.h"
54 /* export functions ***********************************************************/
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:
281 bl builtin_throw_exception
282 b L_asm_vm_call_method_return
302 lwz a0,offvmargdata+4(itmp1)
305 lwz a1,offvmargdata+4(itmp1)
308 lwz a2,offvmargdata+4(itmp1)
311 lwz a3,offvmargdata+4(itmp1)
314 lwz a4,offvmargdata+4(itmp1)
317 lwz a5,offvmargdata+4(itmp1)
320 lwz a6,offvmargdata+4(itmp1)
323 lwz a7,offvmargdata+4(itmp1)
331 #if defined(__DARWIN__)
333 /* we have two entries here, so we get the even argument register
334 alignment for linux */
350 lwz a0,offvmargdata+0(itmp1)
351 lwz a1,offvmargdata+4(itmp1)
354 lwz a2,offvmargdata+0(itmp1)
355 lwz a3,offvmargdata+4(itmp1)
358 lwz a4,offvmargdata+0(itmp1)
359 lwz a5,offvmargdata+4(itmp1)
362 lwz a6,offvmargdata+0(itmp1)
363 lwz a7,offvmargdata+4(itmp1)
367 /* asm_call_jit_compiler *******************************************************
369 Invokes the compiler for untranslated JavaVM methods.
371 *******************************************************************************/
373 asm_call_jit_compiler:
374 L_asm_call_jit_compiler: /* required for PIC code */
376 stw r0,LA_LR_OFFSET(r1) /* save return address */
377 stwu r1,-((LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo)(r1)
378 stw itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
380 mr itmp1,r0 /* save return address to other reg. */
398 stw mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
400 #if defined(__DARWIN__)
401 stw a0,(LA_WORD_SIZE+5+0)*4(r1)
402 stw a1,(LA_WORD_SIZE+5+1)*4(r1)
403 stw a2,(LA_WORD_SIZE+5+2)*4(r1)
404 stw a3,(LA_WORD_SIZE+5+3)*4(r1)
405 stw a4,(LA_WORD_SIZE+5+4)*4(r1)
406 stw a5,(LA_WORD_SIZE+5+5)*4(r1)
407 stw a6,(LA_WORD_SIZE+5+6)*4(r1)
408 stw a7,(LA_WORD_SIZE+5+7)*4(r1)
410 stfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
411 stfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
412 stfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
413 stfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
414 stfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
415 stfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
416 stfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
417 stfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
418 stfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
419 stfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
420 stfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
421 stfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
422 stfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
424 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
427 addi a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
428 li a1,0 /* we don't have pv handy */
429 addi a2,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
430 lwz a3,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(sp)
431 mr a4,a3 /* xpc is equal to ra */
432 bl stacktrace_create_extern_stackframeinfo
434 lwz a0,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
435 bl jit_compile /* compile the Java method */
436 mr pv,r3 /* move address to pv register */
438 addi a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
439 bl stacktrace_remove_stackframeinfo
441 #if defined(__DARWIN__)
442 lwz a0,(LA_WORD_SIZE+5+0)*4(r1)
443 lwz a1,(LA_WORD_SIZE+5+1)*4(r1)
444 lwz a2,(LA_WORD_SIZE+5+2)*4(r1)
445 lwz a3,(LA_WORD_SIZE+5+3)*4(r1)
446 lwz a4,(LA_WORD_SIZE+5+4)*4(r1)
447 lwz a5,(LA_WORD_SIZE+5+5)*4(r1)
448 lwz a6,(LA_WORD_SIZE+5+6)*4(r1)
449 lwz a7,(LA_WORD_SIZE+5+7)*4(r1)
451 lfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
452 lfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
453 lfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
454 lfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
455 lfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
456 lfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
457 lfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
458 lfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
459 lfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
460 lfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
461 lfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
462 lfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
463 lfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
465 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
468 lwz mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
470 lwz itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(r1)
472 addi r1,r1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
474 mr. pv,pv /* test for exception */
475 beq L_asm_call_jit_compiler_exception
480 stw pv,0(mptr) /* store method address */
482 mtctr pv /* move method address to control reg */
483 bctr /* and call the Java method */
485 L_asm_call_jit_compiler_exception:
486 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
488 stw r0,LA_LR_OFFSET(sp)
489 stwu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
490 bl builtin_asm_get_exceptionptrptr
491 lwz r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
493 addi sp,sp,LA_SIZE_ALIGNED
495 # if defined(__DARWIN__)
496 lis v0,ha16(_no_threads_exceptionptr)
497 addi v0,v0,lo16(_no_threads_exceptionptr)
499 lis v0,_no_threads_exceptionptr@ha
500 addi v0,v0,_no_threads_exceptionptr@l
503 lwz xptr,0(v0) /* get the exception pointer */
505 stw itmp3,0(v0) /* clear the exception pointer */
509 b L_asm_handle_nat_exception
512 /********************* function asm_handle_exception ***************************
514 * This function handles an exception. It does not use the usual calling *
515 * conventions. The exception pointer is passed in REG_ITMP1 and the *
516 * pc from the exception raising position is passed in REG_ITMP2. It searches *
517 * the local exception table for a handler. If no one is found, it unwinds *
518 * stacks and continues searching the callers. *
520 * void asm_handle_exception (exceptionptr, exceptionpc); *
522 *******************************************************************************/
524 asm_handle_nat_exception:
525 L_asm_handle_nat_exception: /* required for PIC code */
533 bne L_asm_handle_exception
538 asm_handle_exception:
539 L_asm_handle_exception: /* required for PIC code */
540 addi sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
542 #if defined(__DARWIN__)
544 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
545 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
548 li a3,(ARG_CNT+TMP_CNT)*8 /* prepare a3 for handle_exception */
549 li a4,1 /* set maybe-leaf flag */
551 L_asm_handle_exception_stack_loop:
552 addi sp,sp,-(LA_WORD_SIZE+4+5)*4 /* allocate stack */
553 stw xptr,LA_SIZE+4*4(sp) /* save exception pointer */
554 stw xpc,LA_SIZE+5*4(sp) /* save exception pc */
555 stw pv,LA_SIZE+6*4(sp) /* save data segment pointer */
556 mflr r0 /* save return address */
557 stw r0,LA_SIZE+5*4(sp)
558 add a3,a3,sp /* calculate Java sp into a3... */
559 addi a3,a3,(LA_WORD_SIZE+4+5)*4
560 stw a4,LA_SIZE+8*4(sp) /* save maybe-leaf flag */
562 mr a0,xptr /* pass exception pointer */
563 mr a1,xpc /* pass exception pc */
564 mr a2,pv /* pass data segment pointer */
565 /* a3 is still set */
566 bl exceptions_handle_exception
569 beq L_asm_handle_exception_not_catched
571 mr xpc,v0 /* move handlerpc into xpc */
572 lwz xptr,LA_SIZE+4*4(sp) /* restore exception pointer */
573 lwz pv,LA_SIZE+6*4(sp) /* restore data segment pointer */
574 lwz r0,LA_SIZE+5*4(sp) /* restore return address */
576 lwz a4,LA_SIZE+8*4(sp) /* get maybe-leaf flag */
577 addi sp,sp,(LA_WORD_SIZE+4+5)*4 /* free stack frame */
580 beq L_asm_handle_exception_no_leaf
582 #if defined(__DARWIN__)
584 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
585 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
588 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
590 L_asm_handle_exception_no_leaf:
591 mtctr xpc /* jump to the handler */
594 L_asm_handle_exception_not_catched:
595 lwz xptr,LA_SIZE+4*4(sp) /* restore exception pointer */
596 lwz pv,LA_SIZE+6*4(sp) /* restore data segment pointer */
597 lwz r0,LA_SIZE+5*4(sp) /* restore return address */
599 lwz a4,LA_SIZE+8*4(sp) /* get maybe-leaf flag */
600 addi sp,sp,(LA_WORD_SIZE+4+5)*4 /* free stack frame */
603 beq L_asm_handle_exception_no_leaf_stack
605 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
606 li a4,0 /* clear the maybe-leaf flag */
608 L_asm_handle_exception_no_leaf_stack:
609 lwz t0,FrameSize(pv) /* get frame size */
610 add t0,sp,t0 /* pointer to save area */
612 lwz t1,IsLeaf(pv) /* is leaf procedure */
614 bne L_asm_handle_exception_no_ra_restore
616 lwz r0,LA_LR_OFFSET(t0) /* restore ra */
619 L_asm_handle_exception_no_ra_restore:
620 mflr xpc /* the new xpc is ra */
621 lwz t1,IntSave(pv) /* t1 = saved int register count */
624 mflr t2 /* t2 = current pc */
625 #if defined(__DARWIN__)
626 addi t2,t2,lo16(ex_int2-ex_int1)
628 addi t2,t2,(ex_int2-ex_int1)@l
630 slwi t1,t1,2 /* t1 = register count * 4 */
631 subf t2,t1,t2 /* t2 = IntSave - t1 */
647 subf t0,t1,t0 /* t0 = t0 - register count * 4 */
653 #if defined(__DARWIN__)
654 addi t2,t2,lo16(ex_flt2-ex_flt1)
656 addi t2,t2,(ex_flt2-ex_flt1)@l
658 slwi t1,t1,2 /* t1 = register count * 4 */
659 subf t2,t1,t2 /* t2 = FltSave - t1 */
675 lwz t0,FrameSize(pv) /* get frame size */
676 add sp,sp,t0 /* unwind stack */
677 li a3,0 /* prepare a3 for handle_exception */
686 bne L_asm_handle_exception_stack_loop
691 b L_asm_handle_exception_stack_loop
694 /* asm_wrapper_patcher *********************************************************
699 20 return address into JIT code (patch position)
700 16 pointer to virtual java_objectheader
701 12 machine code (which is patched back later)
702 8 unresolved class/method/field reference
703 4 data segment displacement from load instructions
704 0 patcher function pointer to call (pv is saved here afterwards)
706 *******************************************************************************/
709 mflr r0 /* get Java return address (leaf) */
710 stw r0,6*4(sp) /* store it in the stub stackframe */
711 /* keep stack 16-bytes aligned: 6+1+37 = 44 */
712 stwu sp,-(LA_SIZE+(5+58)*4+sizestackframeinfo)(sp)
714 #if defined(__DARWIN__)
715 stw a0,LA_SIZE+(5+0)*4(r1) /* save argument registers */
716 stw a1,LA_SIZE+(5+1)*4(r1) /* preserve linkage area (24 bytes) */
717 stw a2,LA_SIZE+(5+2)*4(r1) /* and 4 bytes for 4 argument */
718 stw a3,LA_SIZE+(5+3)*4(r1)
719 stw a4,LA_SIZE+(5+4)*4(r1)
720 stw a5,LA_SIZE+(5+5)*4(r1)
721 stw a6,LA_SIZE+(5+6)*4(r1)
722 stw a7,LA_SIZE+(5+7)*4(r1)
724 stfd fa0,LA_SIZE+(5+8)*4(sp)
725 stfd fa1,LA_SIZE+(5+10)*4(sp)
726 stfd fa2,LA_SIZE+(5+12)*4(sp)
727 stfd fa3,LA_SIZE+(5+14)*4(sp)
728 stfd fa4,LA_SIZE+(5+16)*4(sp)
729 stfd fa5,LA_SIZE+(5+18)*4(sp)
730 stfd fa6,LA_SIZE+(5+20)*4(sp)
731 stfd fa7,LA_SIZE+(5+22)*4(sp)
732 stfd fa8,LA_SIZE+(5+24)*4(sp)
733 stfd fa9,LA_SIZE+(5+26)*4(sp)
734 stfd fa10,LA_SIZE+(5+28)*4(sp)
735 stfd fa11,LA_SIZE+(5+30)*4(sp)
736 stfd fa12,LA_SIZE+(5+32)*4(sp)
738 stw t0,(LA_WORD_SIZE+5+33)*4(r1)
739 stw t1,(LA_WORD_SIZE+5+34)*4(r1)
740 stw t2,(LA_WORD_SIZE+5+35)*4(r1)
741 stw t3,(LA_WORD_SIZE+5+36)*4(r1)
742 stw t4,(LA_WORD_SIZE+5+37)*4(r1)
743 stw t5,(LA_WORD_SIZE+5+38)*4(r1)
744 stw t6,(LA_WORD_SIZE+5+39)*4(r1)
745 stw t7,(LA_WORD_SIZE+5+40)*4(r1)
747 stfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
748 stfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
749 stfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
750 stfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
751 stfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
752 stfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
754 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* save 8 int/8 float arguments */
755 SAVE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
758 stw itmp1,LA_SIZE+(5+54)*4(sp)
759 stw itmp2,LA_SIZE+(5+55)*4(sp)
760 stw pv,LA_SIZE+(5+56)*4(sp)
762 addi a0,sp,LA_SIZE+(5+58)*4 /* create stackframe info */
764 addi a2,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
765 mr a3,r0 /* this is correct for leafs */
766 lwz a4,((5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo)(sp) /* pass xpc */
767 bl stacktrace_create_extern_stackframeinfo
769 addi a0,sp,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo /* pass sp */
770 lwz pv,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* get function */
771 lwz itmp1,LA_SIZE+(5+56)*4(sp) /* move pv to position of fp */
772 stw itmp1,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
773 mtctr pv /* call the patcher function */
775 stw v0,LA_SIZE+(5+57)*4(sp) /* save return value */
777 addi a0,sp,LA_SIZE+(5+58)*4
778 bl stacktrace_remove_stackframeinfo /* remove stackframe info */
780 #if defined(__DARWIN__)
781 lwz a0,LA_SIZE+(5+0)*4(r1)
782 lwz a1,LA_SIZE+(5+1)*4(r1)
783 lwz a2,LA_SIZE+(5+2)*4(r1)
784 lwz a3,LA_SIZE+(5+3)*4(r1)
785 lwz a4,LA_SIZE+(5+4)*4(r1)
786 lwz a5,LA_SIZE+(5+5)*4(r1)
787 lwz a6,LA_SIZE+(5+6)*4(r1)
788 lwz a7,LA_SIZE+(5+7)*4(r1)
790 lfd fa0,LA_SIZE+(5+8)*4(sp)
791 lfd fa1,LA_SIZE+(5+10)*4(sp)
792 lfd fa2,LA_SIZE+(5+12)*4(sp)
793 lfd fa3,LA_SIZE+(5+14)*4(sp)
794 lfd fa4,LA_SIZE+(5+16)*4(sp)
795 lfd fa5,LA_SIZE+(5+18)*4(sp)
796 lfd fa6,LA_SIZE+(5+20)*4(sp)
797 lfd fa7,LA_SIZE+(5+22)*4(sp)
798 lfd fa8,LA_SIZE+(5+24)*4(sp)
799 lfd fa9,LA_SIZE+(5+26)*4(sp)
800 lfd fa10,LA_SIZE+(5+28)*4(sp)
801 lfd fa11,LA_SIZE+(5+30)*4(sp)
802 lfd fa12,LA_SIZE+(5+32)*4(sp)
804 lwz t0,(LA_WORD_SIZE+5+33)*4(r1)
805 lwz t1,(LA_WORD_SIZE+5+34)*4(r1)
806 lwz t2,(LA_WORD_SIZE+5+35)*4(r1)
807 lwz t3,(LA_WORD_SIZE+5+36)*4(r1)
808 lwz t4,(LA_WORD_SIZE+5+37)*4(r1)
809 lwz t5,(LA_WORD_SIZE+5+38)*4(r1)
810 lwz t6,(LA_WORD_SIZE+5+39)*4(r1)
811 lwz t7,(LA_WORD_SIZE+5+40)*4(r1)
813 lfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
814 lfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
815 lfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
816 lfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
817 lfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
818 lfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
820 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* restore 8 int/8 float args */
821 RESTORE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
824 lwz itmp1,LA_SIZE+(5+54)*4(sp)
825 lwz itmp2,LA_SIZE+(5+55)*4(sp)
826 lwz pv,LA_SIZE+(5+56)*4(sp)
827 lwz itmp3,LA_SIZE+(5+57)*4(sp) /* restore return value into temp reg.*/
829 lwz r0,(6+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* restore RA */
832 mr. itmp3,itmp3 /* check for an exception */
833 beq L_asm_wrapper_patcher_exception
835 /* get return address (into JIT code) */
836 lwz itmp3,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
838 /* remove stack frame + patcher stub stack */
839 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
842 bctr /* jump to new patched code */
844 L_asm_wrapper_patcher_exception:
845 lwz xpc,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
846 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
848 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
850 stw r0,LA_LR_OFFSET(sp)
851 stwu sp,-(LA_SIZE+1*4)(sp) /* preserve linkage area */
852 stw xpc,LA_SIZE+0*4(sp)
853 bl builtin_asm_get_exceptionptrptr
854 lwz xpc,LA_SIZE+0*4(sp)
855 lwz r0,LA_SIZE+1*4+LA_LR_OFFSET(sp)
857 addi sp,sp,LA_SIZE+1*4
859 # if defined(__DARWIN__)
860 lis v0,ha16(_no_threads_exceptionptr)
861 addi v0,v0,lo16(_no_threads_exceptionptr)
863 lis v0,_no_threads_exceptionptr@ha
864 addi v0,v0,_no_threads_exceptionptr@l
868 lwz xptr,0(v0) /* get the exception pointer */
870 stw itmp3,0(v0) /* clear the exception pointer */
871 b L_asm_handle_exception
874 /* asm_replacement_out *********************************************************
876 This code is jumped to from the replacement-out stubs that are executed
877 when a thread reaches an activated replacement point.
879 The purpose of asm_replacement_out is to read out the parts of the
880 execution state that cannot be accessed from C code, store this state,
881 and then call the C function replace_me.
884 16 start of stack inside method to replace
885 0 rplpoint * info on the replacement point that was reached
887 NOTE: itmp3 has been clobbered by the replacement-out stub!
889 *******************************************************************************/
891 /* some room to accomodate changes of the stack frame size during replacement */
892 /* XXX we should find a cleaner solution here */
893 #define REPLACEMENT_ROOM 512
896 /* create stack frame */
897 addi sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
899 /* save link register */
902 /* save registers in execution state */
903 stw r0 ,( 0*8+offes_intregs)(sp)
904 stw r1 ,( 1*8+offes_intregs)(sp)
905 stw r2 ,( 2*8+offes_intregs)(sp)
906 stw r3 ,( 3*8+offes_intregs)(sp)
907 stw r4 ,( 4*8+offes_intregs)(sp)
908 stw r5 ,( 5*8+offes_intregs)(sp)
909 stw r6 ,( 6*8+offes_intregs)(sp)
910 stw r7 ,( 7*8+offes_intregs)(sp)
911 stw r8 ,( 8*8+offes_intregs)(sp)
912 stw r9 ,( 9*8+offes_intregs)(sp)
913 stw r10,(10*8+offes_intregs)(sp)
914 stw r11,(11*8+offes_intregs)(sp)
915 stw r12,(12*8+offes_intregs)(sp)
916 stw r13,(13*8+offes_intregs)(sp)
917 stw r14,(14*8+offes_intregs)(sp)
918 stw r15,(15*8+offes_intregs)(sp)
919 stw r16,(16*8+offes_intregs)(sp) /* link register */
920 stw r17,(17*8+offes_intregs)(sp)
921 stw r18,(18*8+offes_intregs)(sp)
922 stw r19,(19*8+offes_intregs)(sp)
923 stw r20,(20*8+offes_intregs)(sp)
924 stw r21,(21*8+offes_intregs)(sp)
925 stw r22,(22*8+offes_intregs)(sp)
926 stw r23,(23*8+offes_intregs)(sp)
927 stw r24,(24*8+offes_intregs)(sp)
928 stw r25,(25*8+offes_intregs)(sp)
929 stw r26,(26*8+offes_intregs)(sp)
930 stw r27,(27*8+offes_intregs)(sp)
931 stw r28,(28*8+offes_intregs)(sp)
932 stw r29,(29*8+offes_intregs)(sp)
933 stw r30,(30*8+offes_intregs)(sp)
934 stw r31,(31*8+offes_intregs)(sp)
936 stfd fr0 ,( 0*8+offes_fltregs)(sp)
937 stfd fr1 ,( 1*8+offes_fltregs)(sp)
938 stfd fr2 ,( 2*8+offes_fltregs)(sp)
939 stfd fr3 ,( 3*8+offes_fltregs)(sp)
940 stfd fr4 ,( 4*8+offes_fltregs)(sp)
941 stfd fr5 ,( 5*8+offes_fltregs)(sp)
942 stfd fr6 ,( 6*8+offes_fltregs)(sp)
943 stfd fr7 ,( 7*8+offes_fltregs)(sp)
944 stfd fr8 ,( 8*8+offes_fltregs)(sp)
945 stfd fr9 ,( 9*8+offes_fltregs)(sp)
946 stfd fr10,(10*8+offes_fltregs)(sp)
947 stfd fr11,(11*8+offes_fltregs)(sp)
948 stfd fr12,(12*8+offes_fltregs)(sp)
949 stfd fr13,(13*8+offes_fltregs)(sp)
950 stfd fr14,(14*8+offes_fltregs)(sp)
951 stfd fr15,(15*8+offes_fltregs)(sp)
952 stfd fr16,(16*8+offes_fltregs)(sp)
953 stfd fr17,(17*8+offes_fltregs)(sp)
954 stfd fr18,(18*8+offes_fltregs)(sp)
955 stfd fr19,(19*8+offes_fltregs)(sp)
956 stfd fr20,(20*8+offes_fltregs)(sp)
957 stfd fr21,(21*8+offes_fltregs)(sp)
958 stfd fr22,(22*8+offes_fltregs)(sp)
959 stfd fr23,(23*8+offes_fltregs)(sp)
960 stfd fr24,(24*8+offes_fltregs)(sp)
961 stfd fr25,(25*8+offes_fltregs)(sp)
962 stfd fr26,(26*8+offes_fltregs)(sp)
963 stfd fr27,(27*8+offes_fltregs)(sp)
964 stfd fr28,(28*8+offes_fltregs)(sp)
965 stfd fr29,(29*8+offes_fltregs)(sp)
966 stfd fr30,(30*8+offes_fltregs)(sp)
967 stfd fr31,(31*8+offes_fltregs)(sp)
969 /* calculate sp of method */
970 addi itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
971 stw itmp1,(offes_sp)(sp)
974 stw pv,(offes_pv)(sp)
976 /* call replace_me */
977 lwz a0,-(4*4)(itmp1) /* arg0: rplpoint * */
978 mr a1,sp /* arg1: execution state */
979 addi sp,sp,-(LA_SIZE_ALIGNED)
980 b replace_me /* call C function replace_me */
982 /* asm_replacement_in **********************************************************
984 This code writes the given execution state and jumps to the replacement
987 This function never returns!
989 NOTE: itmp3 is not restored!
992 void asm_replacement_in(executionstate *es);
994 *******************************************************************************/
997 /* a0 == executionstate *es */
999 /* set new sp and pv */
1000 lwz sp,(offes_sp)(a0)
1001 lwz pv,(offes_pv)(a0)
1003 /* copy registers from execution state */
1004 lwz r0 ,( 0*8+offes_intregs)(a0)
1006 /* r2 is reserved */
1007 /* a0 is loaded below */
1008 lwz r4 ,( 4*8+offes_intregs)(a0)
1009 lwz r5 ,( 5*8+offes_intregs)(a0)
1010 lwz r6 ,( 6*8+offes_intregs)(a0)
1011 lwz r7 ,( 7*8+offes_intregs)(a0)
1012 lwz r8 ,( 8*8+offes_intregs)(a0)
1013 lwz r9 ,( 9*8+offes_intregs)(a0)
1014 lwz r10,(10*8+offes_intregs)(a0)
1015 lwz r11,(11*8+offes_intregs)(a0)
1016 lwz r12,(12*8+offes_intregs)(a0)
1018 lwz r14,(14*8+offes_intregs)(a0)
1019 lwz r15,(15*8+offes_intregs)(a0)
1020 lwz r16,(16*8+offes_intregs)(a0) /* link register */
1021 lwz r17,(17*8+offes_intregs)(a0)
1022 lwz r18,(18*8+offes_intregs)(a0)
1023 lwz r19,(19*8+offes_intregs)(a0)
1024 lwz r20,(20*8+offes_intregs)(a0)
1025 lwz r21,(21*8+offes_intregs)(a0)
1026 lwz r22,(22*8+offes_intregs)(a0)
1027 lwz r23,(23*8+offes_intregs)(a0)
1028 lwz r24,(24*8+offes_intregs)(a0)
1029 lwz r25,(25*8+offes_intregs)(a0)
1030 lwz r26,(26*8+offes_intregs)(a0)
1031 lwz r27,(27*8+offes_intregs)(a0)
1032 lwz r28,(28*8+offes_intregs)(a0)
1033 lwz r29,(29*8+offes_intregs)(a0)
1034 lwz r30,(30*8+offes_intregs)(a0)
1035 lwz r31,(31*8+offes_intregs)(a0)
1037 lfd fr0 ,( 0*8+offes_fltregs)(a0)
1038 lfd fr1 ,( 1*8+offes_fltregs)(a0)
1039 lfd fr2 ,( 2*8+offes_fltregs)(a0)
1040 lfd fr3 ,( 3*8+offes_fltregs)(a0)
1041 lfd fr4 ,( 4*8+offes_fltregs)(a0)
1042 lfd fr5 ,( 5*8+offes_fltregs)(a0)
1043 lfd fr6 ,( 6*8+offes_fltregs)(a0)
1044 lfd fr7 ,( 7*8+offes_fltregs)(a0)
1045 lfd fr8 ,( 8*8+offes_fltregs)(a0)
1046 lfd fr9 ,( 9*8+offes_fltregs)(a0)
1047 lfd fr10,(10*8+offes_fltregs)(a0)
1048 lfd fr11,(11*8+offes_fltregs)(a0)
1049 lfd fr12,(12*8+offes_fltregs)(a0)
1050 lfd fr13,(13*8+offes_fltregs)(a0)
1051 lfd fr14,(14*8+offes_fltregs)(a0)
1052 lfd fr15,(15*8+offes_fltregs)(a0)
1053 lfd fr16,(16*8+offes_fltregs)(a0)
1054 lfd fr17,(17*8+offes_fltregs)(a0)
1055 lfd fr18,(18*8+offes_fltregs)(a0)
1056 lfd fr19,(19*8+offes_fltregs)(a0)
1057 lfd fr20,(20*8+offes_fltregs)(a0)
1058 lfd fr21,(21*8+offes_fltregs)(a0)
1059 lfd fr22,(22*8+offes_fltregs)(a0)
1060 lfd fr23,(23*8+offes_fltregs)(a0)
1061 lfd fr24,(24*8+offes_fltregs)(a0)
1062 lfd fr25,(25*8+offes_fltregs)(a0)
1063 lfd fr26,(26*8+offes_fltregs)(a0)
1064 lfd fr27,(27*8+offes_fltregs)(a0)
1065 lfd fr28,(28*8+offes_fltregs)(a0)
1066 lfd fr29,(29*8+offes_fltregs)(a0)
1067 lfd fr30,(30*8+offes_fltregs)(a0)
1068 lfd fr31,(31*8+offes_fltregs)(a0)
1070 /* restore link register */
1076 lwz itmp3,offes_pc(a0)
1080 lwz a0,(3*8+offes_intregs)(a0)
1082 /* jump to new code */
1087 /*********************************************************************/
1119 asm_initialize_thread_stack:
1149 #if defined(__DARWIN__)
1150 lfd fr0,lo16(doublezero-0b)(r3)
1152 lfd fr0,(doublezero-0b)@l(r3)
1179 asm_perform_threadswitch:
1271 asm_switchstackandcall:
1289 asm_getclassvalues_atomic:
1292 lwz r6,offbaseval(r3)
1293 lwz r7,offdiffval(r3)
1294 lwz r8,offbaseval(r4)
1296 stw r6,offcast_super_baseval(r5)
1297 stw r7,offcast_super_diffval(r5)
1298 stw r8,offcast_sub_baseval(r5)
1303 asm_criticalsections:
1304 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1312 #if defined(__DARWIN__)
1314 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1316 L_builtin_throw_exception$stub:
1317 .indirect_symbol _builtin_throw_exception
1319 bcl 20,31,L00$_builtin_throw_exception
1320 L00$_builtin_throw_exception:
1322 addis r11,r11,ha16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)
1324 lwzu r12,lo16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)(r11)
1328 .lazy_symbol_pointer
1329 L_builtin_throw_exception$lazy_ptr:
1330 .indirect_symbol _builtin_throw_exception
1331 .long dyld_stub_binding_helper
1334 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1336 L_exceptions_handle_exception$stub:
1337 .indirect_symbol _exceptions_handle_exception
1339 bcl 20,31,L00$_exceptions_handle_exception
1340 L00$_exceptions_handle_exception:
1342 addis r11,r11,ha16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)
1344 lwzu r12,lo16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)(r11)
1348 .lazy_symbol_pointer
1349 L_exceptions_handle_exception$lazy_ptr:
1350 .indirect_symbol _exceptions_handle_exception
1351 .long dyld_stub_binding_helper
1354 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1356 L_stacktrace_create_extern_stackframeinfo$stub:
1357 .indirect_symbol _stacktrace_create_extern_stackframeinfo
1359 bcl 20,31,L00$_stacktrace_create_extern_stackframeinfo
1360 L00$_stacktrace_create_extern_stackframeinfo:
1362 addis r11,r11,ha16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)
1364 lwzu r12,lo16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)(r11)
1368 .lazy_symbol_pointer
1369 L_stacktrace_create_extern_stackframeinfo$lazy_ptr:
1370 .indirect_symbol _stacktrace_create_extern_stackframeinfo
1371 .long dyld_stub_binding_helper
1374 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1377 .indirect_symbol _jit_compile
1379 bcl 20,31,L00$_jit_compile
1382 addis r11,r11,ha16(L_jit_compile$lazy_ptr - L00$_jit_compile)
1384 lwzu r12,lo16(L_jit_compile$lazy_ptr - L00$_jit_compile)(r11)
1388 .lazy_symbol_pointer
1389 L_jit_compile$lazy_ptr:
1390 .indirect_symbol _jit_compile
1391 .long dyld_stub_binding_helper
1394 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1396 L_stacktrace_remove_stackframeinfo$stub:
1397 .indirect_symbol _stacktrace_remove_stackframeinfo
1399 bcl 20,31,L00$_stacktrace_remove_stackframeinfo
1400 L00$_stacktrace_remove_stackframeinfo:
1402 addis r11,r11,ha16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)
1404 lwzu r12,lo16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)(r11)
1408 .lazy_symbol_pointer
1409 L_stacktrace_remove_stackframeinfo$lazy_ptr:
1410 .indirect_symbol _stacktrace_remove_stackframeinfo
1411 .long dyld_stub_binding_helper
1414 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1416 L_builtin_asm_get_exceptionptrptr$stub:
1417 .indirect_symbol _builtin_asm_get_exceptionptrptr
1419 bcl 20,31,L00$_builtin_asm_get_exceptionptrptr
1420 L00$_builtin_asm_get_exceptionptrptr:
1422 addis r11,r11,ha16(L_builtin_asm_get_exceptionptrptr$lazy_ptr - L00$_builtin_asm_get_exceptionptrptr)
1424 lwzu r12,lo16(L_builtin_asm_get_exceptionptrptr$lazy_ptr - L00$_builtin_asm_get_exceptionptrptr)(r11)
1428 .lazy_symbol_pointer
1429 L_builtin_asm_get_exceptionptrptr$lazy_ptr:
1430 .indirect_symbol _builtin_asm_get_exceptionptrptr
1431 .long dyld_stub_binding_helper
1434 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1437 .indirect_symbol _replace_me
1439 bcl 20,31,L00$_replace_me
1442 addis r11,r11,ha16(L_replace_me$lazy_ptr - L00$_replace_me)
1444 lwzu r12,lo16(L_replace_me$lazy_ptr - L00$_replace_me)(r11)
1448 .lazy_symbol_pointer
1449 L_replace_me$lazy_ptr:
1450 .indirect_symbol _replace_me
1451 .long dyld_stub_binding_helper
1453 #endif /* defined(__DARWIN__) */
1456 /* Disable exec-stacks, required for Gentoo ***********************************/
1458 #if defined(__GCC__) && defined(__ELF__)
1459 .section .note.GNU-stack,"",@progbits
1464 * These are local overrides for various environment variables in Emacs.
1465 * Please do not remove this and leave it at the end of the file, where
1466 * Emacs will automagically detect them.
1467 * ---------------------------------------------------------------------
1470 * indent-tabs-mode: t
1474 * vim:noexpandtab:sw=4:ts=4: