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 4851 2006-04-27 10:32:27Z 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)(r1)
379 #if defined(__DARWIN__)
380 stw a0,(LA_WORD_SIZE+5+0)*4(r1)
381 stw a1,(LA_WORD_SIZE+5+1)*4(r1)
382 stw a2,(LA_WORD_SIZE+5+2)*4(r1)
383 stw a3,(LA_WORD_SIZE+5+3)*4(r1)
384 stw a4,(LA_WORD_SIZE+5+4)*4(r1)
385 stw a5,(LA_WORD_SIZE+5+5)*4(r1)
386 stw a6,(LA_WORD_SIZE+5+6)*4(r1)
387 stw a7,(LA_WORD_SIZE+5+7)*4(r1)
389 stfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
390 stfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
391 stfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
392 stfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
393 stfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
394 stfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
395 stfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
396 stfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
397 stfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
398 stfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
399 stfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
400 stfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
401 stfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
403 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
408 addi a2,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)
409 lwz a3,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)+LA_LR_OFFSET(sp)
411 mr pv,v0 /* move address to pv register */
413 #if defined(__DARWIN__)
414 lwz a0,(LA_WORD_SIZE+5+0)*4(r1)
415 lwz a1,(LA_WORD_SIZE+5+1)*4(r1)
416 lwz a2,(LA_WORD_SIZE+5+2)*4(r1)
417 lwz a3,(LA_WORD_SIZE+5+3)*4(r1)
418 lwz a4,(LA_WORD_SIZE+5+4)*4(r1)
419 lwz a5,(LA_WORD_SIZE+5+5)*4(r1)
420 lwz a6,(LA_WORD_SIZE+5+6)*4(r1)
421 lwz a7,(LA_WORD_SIZE+5+7)*4(r1)
423 lfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
424 lfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
425 lfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
426 lfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
427 lfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
428 lfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
429 lfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
430 lfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
431 lfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
432 lfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
433 lfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
434 lfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
435 lfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
437 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
440 lwz itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)+LA_LR_OFFSET(r1)
443 addi sp,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8)
445 mr. pv,pv /* test for exception */
446 beq L_asm_call_jit_compiler_exception
448 mtctr pv /* move method address to control reg */
449 bctr /* and call the Java method */
451 L_asm_call_jit_compiler_exception:
452 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
454 stw r0,LA_LR_OFFSET(sp)
455 stwu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
456 bl builtin_asm_get_exceptionptrptr
457 lwz r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
459 addi sp,sp,LA_SIZE_ALIGNED
461 # if defined(__DARWIN__)
462 lis v0,ha16(_no_threads_exceptionptr)
463 addi v0,v0,lo16(_no_threads_exceptionptr)
465 lis v0,_no_threads_exceptionptr@ha
466 addi v0,v0,_no_threads_exceptionptr@l
469 lwz xptr,0(v0) /* get the exception pointer */
471 stw itmp3,0(v0) /* clear the exception pointer */
475 b L_asm_handle_nat_exception
478 /********************* function asm_handle_exception ***************************
480 * This function handles an exception. It does not use the usual calling *
481 * conventions. The exception pointer is passed in REG_ITMP1 and the *
482 * pc from the exception raising position is passed in REG_ITMP2. It searches *
483 * the local exception table for a handler. If no one is found, it unwinds *
484 * stacks and continues searching the callers. *
486 * void asm_handle_exception (exceptionptr, exceptionpc); *
488 *******************************************************************************/
490 asm_handle_nat_exception:
491 L_asm_handle_nat_exception: /* required for PIC code */
499 bne L_asm_handle_exception
504 asm_handle_exception:
505 L_asm_handle_exception: /* required for PIC code */
506 addi sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
508 #if defined(__DARWIN__)
510 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
511 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
514 li a3,(ARG_CNT+TMP_CNT)*8 /* prepare a3 for handle_exception */
515 li a4,1 /* set maybe-leaf flag */
517 L_asm_handle_exception_stack_loop:
518 addi sp,sp,-(LA_WORD_SIZE+4+5)*4 /* allocate stack */
519 stw xptr,LA_SIZE+4*4(sp) /* save exception pointer */
520 stw xpc,LA_SIZE+5*4(sp) /* save exception pc */
521 stw pv,LA_SIZE+6*4(sp) /* save data segment pointer */
522 mflr r0 /* save return address */
523 stw r0,LA_SIZE+5*4(sp)
524 add a3,a3,sp /* calculate Java sp into a3... */
525 addi a3,a3,(LA_WORD_SIZE+4+5)*4
526 stw a4,LA_SIZE+8*4(sp) /* save maybe-leaf flag */
528 mr a0,xptr /* pass exception pointer */
529 mr a1,xpc /* pass exception pc */
530 mr a2,pv /* pass data segment pointer */
531 /* a3 is still set */
532 bl exceptions_handle_exception
535 beq L_asm_handle_exception_not_catched
537 mr xpc,v0 /* move handlerpc into xpc */
538 lwz xptr,LA_SIZE+4*4(sp) /* restore exception pointer */
539 lwz pv,LA_SIZE+6*4(sp) /* restore data segment pointer */
540 lwz r0,LA_SIZE+5*4(sp) /* restore return address */
542 lwz a4,LA_SIZE+8*4(sp) /* get maybe-leaf flag */
543 addi sp,sp,(LA_WORD_SIZE+4+5)*4 /* free stack frame */
546 beq L_asm_handle_exception_no_leaf
548 #if defined(__DARWIN__)
550 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
551 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
554 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
556 L_asm_handle_exception_no_leaf:
557 mtctr xpc /* jump to the handler */
560 L_asm_handle_exception_not_catched:
561 lwz xptr,LA_SIZE+4*4(sp) /* restore exception pointer */
562 lwz pv,LA_SIZE+6*4(sp) /* restore data segment pointer */
563 lwz r0,LA_SIZE+5*4(sp) /* restore return address */
565 lwz a4,LA_SIZE+8*4(sp) /* get maybe-leaf flag */
566 addi sp,sp,(LA_WORD_SIZE+4+5)*4 /* free stack frame */
569 beq L_asm_handle_exception_no_leaf_stack
571 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
572 li a4,0 /* clear the maybe-leaf flag */
574 L_asm_handle_exception_no_leaf_stack:
575 lwz t0,FrameSize(pv) /* get frame size */
576 add t0,sp,t0 /* pointer to save area */
578 lwz t1,IsLeaf(pv) /* is leaf procedure */
580 bne L_asm_handle_exception_no_ra_restore
582 lwz r0,LA_LR_OFFSET(t0) /* restore ra */
585 L_asm_handle_exception_no_ra_restore:
586 mflr xpc /* the new xpc is ra */
587 lwz t1,IntSave(pv) /* t1 = saved int register count */
590 mflr t2 /* t2 = current pc */
591 #if defined(__DARWIN__)
592 addi t2,t2,lo16(ex_int2-ex_int1)
594 addi t2,t2,(ex_int2-ex_int1)@l
596 slwi t1,t1,2 /* t1 = register count * 4 */
597 subf t2,t1,t2 /* t2 = IntSave - t1 */
613 subf t0,t1,t0 /* t0 = t0 - register count * 4 */
619 #if defined(__DARWIN__)
620 addi t2,t2,lo16(ex_flt2-ex_flt1)
622 addi t2,t2,(ex_flt2-ex_flt1)@l
624 slwi t1,t1,2 /* t1 = register count * 4 */
625 subf t2,t1,t2 /* t2 = FltSave - t1 */
641 lwz t0,FrameSize(pv) /* get frame size */
642 add sp,sp,t0 /* unwind stack */
643 li a3,0 /* prepare a3 for handle_exception */
652 bne L_asm_handle_exception_stack_loop
657 b L_asm_handle_exception_stack_loop
660 /* asm_wrapper_patcher *********************************************************
665 20 return address into JIT code (patch position)
666 16 pointer to virtual java_objectheader
667 12 machine code (which is patched back later)
668 8 unresolved class/method/field reference
669 4 data segment displacement from load instructions
670 0 patcher function pointer to call (pv is saved here afterwards)
672 *******************************************************************************/
675 mflr r0 /* get Java return address (leaf) */
676 stw r0,6*4(sp) /* store it in the stub stackframe */
677 /* keep stack 16-bytes aligned: 6+1+37 = 44 */
678 stwu sp,-(LA_SIZE+(5+58)*4+sizestackframeinfo)(sp)
680 #if defined(__DARWIN__)
681 stw a0,LA_SIZE+(5+0)*4(r1) /* save argument registers */
682 stw a1,LA_SIZE+(5+1)*4(r1) /* preserve linkage area (24 bytes) */
683 stw a2,LA_SIZE+(5+2)*4(r1) /* and 4 bytes for 4 argument */
684 stw a3,LA_SIZE+(5+3)*4(r1)
685 stw a4,LA_SIZE+(5+4)*4(r1)
686 stw a5,LA_SIZE+(5+5)*4(r1)
687 stw a6,LA_SIZE+(5+6)*4(r1)
688 stw a7,LA_SIZE+(5+7)*4(r1)
690 stfd fa0,LA_SIZE+(5+8)*4(sp)
691 stfd fa1,LA_SIZE+(5+10)*4(sp)
692 stfd fa2,LA_SIZE+(5+12)*4(sp)
693 stfd fa3,LA_SIZE+(5+14)*4(sp)
694 stfd fa4,LA_SIZE+(5+16)*4(sp)
695 stfd fa5,LA_SIZE+(5+18)*4(sp)
696 stfd fa6,LA_SIZE+(5+20)*4(sp)
697 stfd fa7,LA_SIZE+(5+22)*4(sp)
698 stfd fa8,LA_SIZE+(5+24)*4(sp)
699 stfd fa9,LA_SIZE+(5+26)*4(sp)
700 stfd fa10,LA_SIZE+(5+28)*4(sp)
701 stfd fa11,LA_SIZE+(5+30)*4(sp)
702 stfd fa12,LA_SIZE+(5+32)*4(sp)
704 stw t0,(LA_WORD_SIZE+5+33)*4(r1)
705 stw t1,(LA_WORD_SIZE+5+34)*4(r1)
706 stw t2,(LA_WORD_SIZE+5+35)*4(r1)
707 stw t3,(LA_WORD_SIZE+5+36)*4(r1)
708 stw t4,(LA_WORD_SIZE+5+37)*4(r1)
709 stw t5,(LA_WORD_SIZE+5+38)*4(r1)
710 stw t6,(LA_WORD_SIZE+5+39)*4(r1)
711 stw t7,(LA_WORD_SIZE+5+40)*4(r1)
713 stfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
714 stfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
715 stfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
716 stfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
717 stfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
718 stfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
720 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* save 8 int/8 float arguments */
721 SAVE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
724 stw itmp1,LA_SIZE+(5+54)*4(sp)
725 stw itmp2,LA_SIZE+(5+55)*4(sp)
726 stw pv,LA_SIZE+(5+56)*4(sp)
728 addi a0,sp,LA_SIZE+(5+58)*4 /* create stackframe info */
730 addi a2,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
731 mr a3,r0 /* this is correct for leafs */
732 lwz a4,((5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo)(sp) /* pass xpc */
733 bl stacktrace_create_extern_stackframeinfo
735 addi a0,sp,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo /* pass sp */
736 lwz pv,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* get function */
737 lwz itmp1,LA_SIZE+(5+56)*4(sp) /* move pv to position of fp */
738 stw itmp1,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
739 mtctr pv /* call the patcher function */
741 stw v0,LA_SIZE+(5+57)*4(sp) /* save return value */
743 addi a0,sp,LA_SIZE+(5+58)*4
744 bl stacktrace_remove_stackframeinfo /* remove stackframe info */
746 #if defined(__DARWIN__)
747 lwz a0,LA_SIZE+(5+0)*4(r1)
748 lwz a1,LA_SIZE+(5+1)*4(r1)
749 lwz a2,LA_SIZE+(5+2)*4(r1)
750 lwz a3,LA_SIZE+(5+3)*4(r1)
751 lwz a4,LA_SIZE+(5+4)*4(r1)
752 lwz a5,LA_SIZE+(5+5)*4(r1)
753 lwz a6,LA_SIZE+(5+6)*4(r1)
754 lwz a7,LA_SIZE+(5+7)*4(r1)
756 lfd fa0,LA_SIZE+(5+8)*4(sp)
757 lfd fa1,LA_SIZE+(5+10)*4(sp)
758 lfd fa2,LA_SIZE+(5+12)*4(sp)
759 lfd fa3,LA_SIZE+(5+14)*4(sp)
760 lfd fa4,LA_SIZE+(5+16)*4(sp)
761 lfd fa5,LA_SIZE+(5+18)*4(sp)
762 lfd fa6,LA_SIZE+(5+20)*4(sp)
763 lfd fa7,LA_SIZE+(5+22)*4(sp)
764 lfd fa8,LA_SIZE+(5+24)*4(sp)
765 lfd fa9,LA_SIZE+(5+26)*4(sp)
766 lfd fa10,LA_SIZE+(5+28)*4(sp)
767 lfd fa11,LA_SIZE+(5+30)*4(sp)
768 lfd fa12,LA_SIZE+(5+32)*4(sp)
770 lwz t0,(LA_WORD_SIZE+5+33)*4(r1)
771 lwz t1,(LA_WORD_SIZE+5+34)*4(r1)
772 lwz t2,(LA_WORD_SIZE+5+35)*4(r1)
773 lwz t3,(LA_WORD_SIZE+5+36)*4(r1)
774 lwz t4,(LA_WORD_SIZE+5+37)*4(r1)
775 lwz t5,(LA_WORD_SIZE+5+38)*4(r1)
776 lwz t6,(LA_WORD_SIZE+5+39)*4(r1)
777 lwz t7,(LA_WORD_SIZE+5+40)*4(r1)
779 lfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
780 lfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
781 lfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
782 lfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
783 lfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
784 lfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
786 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* restore 8 int/8 float args */
787 RESTORE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
790 lwz itmp1,LA_SIZE+(5+54)*4(sp)
791 lwz itmp2,LA_SIZE+(5+55)*4(sp)
792 lwz pv,LA_SIZE+(5+56)*4(sp)
793 lwz itmp3,LA_SIZE+(5+57)*4(sp) /* restore return value into temp reg.*/
795 lwz r0,(6+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* restore RA */
798 mr. itmp3,itmp3 /* check for an exception */
799 beq L_asm_wrapper_patcher_exception
801 /* get return address (into JIT code) */
802 lwz itmp3,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
804 /* remove stack frame + patcher stub stack */
805 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
808 bctr /* jump to new patched code */
810 L_asm_wrapper_patcher_exception:
811 lwz xpc,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
812 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
814 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
816 stw r0,LA_LR_OFFSET(sp)
817 stwu sp,-(LA_SIZE+1*4)(sp) /* preserve linkage area */
818 stw xpc,LA_SIZE+0*4(sp)
819 bl builtin_asm_get_exceptionptrptr
820 lwz xpc,LA_SIZE+0*4(sp)
821 lwz r0,LA_SIZE+1*4+LA_LR_OFFSET(sp)
823 addi sp,sp,LA_SIZE+1*4
825 # if defined(__DARWIN__)
826 lis v0,ha16(_no_threads_exceptionptr)
827 addi v0,v0,lo16(_no_threads_exceptionptr)
829 lis v0,_no_threads_exceptionptr@ha
830 addi v0,v0,_no_threads_exceptionptr@l
834 lwz xptr,0(v0) /* get the exception pointer */
836 stw itmp3,0(v0) /* clear the exception pointer */
837 b L_asm_handle_exception
840 /* asm_replacement_out *********************************************************
842 This code is jumped to from the replacement-out stubs that are executed
843 when a thread reaches an activated replacement point.
845 The purpose of asm_replacement_out is to read out the parts of the
846 execution state that cannot be accessed from C code, store this state,
847 and then call the C function replace_me.
850 16 start of stack inside method to replace
851 0 rplpoint * info on the replacement point that was reached
853 NOTE: itmp3 has been clobbered by the replacement-out stub!
855 *******************************************************************************/
857 /* some room to accomodate changes of the stack frame size during replacement */
858 /* XXX we should find a cleaner solution here */
859 #define REPLACEMENT_ROOM 512
862 /* create stack frame */
863 addi sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
865 /* save link register */
868 /* save registers in execution state */
869 stw r0 ,( 0*8+offes_intregs)(sp)
870 stw r1 ,( 1*8+offes_intregs)(sp)
871 stw r2 ,( 2*8+offes_intregs)(sp)
872 stw r3 ,( 3*8+offes_intregs)(sp)
873 stw r4 ,( 4*8+offes_intregs)(sp)
874 stw r5 ,( 5*8+offes_intregs)(sp)
875 stw r6 ,( 6*8+offes_intregs)(sp)
876 stw r7 ,( 7*8+offes_intregs)(sp)
877 stw r8 ,( 8*8+offes_intregs)(sp)
878 stw r9 ,( 9*8+offes_intregs)(sp)
879 stw r10,(10*8+offes_intregs)(sp)
880 stw r11,(11*8+offes_intregs)(sp)
881 stw r12,(12*8+offes_intregs)(sp)
882 stw r13,(13*8+offes_intregs)(sp)
883 stw r14,(14*8+offes_intregs)(sp)
884 stw r15,(15*8+offes_intregs)(sp)
885 stw r16,(16*8+offes_intregs)(sp) /* link register */
886 stw r17,(17*8+offes_intregs)(sp)
887 stw r18,(18*8+offes_intregs)(sp)
888 stw r19,(19*8+offes_intregs)(sp)
889 stw r20,(20*8+offes_intregs)(sp)
890 stw r21,(21*8+offes_intregs)(sp)
891 stw r22,(22*8+offes_intregs)(sp)
892 stw r23,(23*8+offes_intregs)(sp)
893 stw r24,(24*8+offes_intregs)(sp)
894 stw r25,(25*8+offes_intregs)(sp)
895 stw r26,(26*8+offes_intregs)(sp)
896 stw r27,(27*8+offes_intregs)(sp)
897 stw r28,(28*8+offes_intregs)(sp)
898 stw r29,(29*8+offes_intregs)(sp)
899 stw r30,(30*8+offes_intregs)(sp)
900 stw r31,(31*8+offes_intregs)(sp)
902 stfd fr0 ,( 0*8+offes_fltregs)(sp)
903 stfd fr1 ,( 1*8+offes_fltregs)(sp)
904 stfd fr2 ,( 2*8+offes_fltregs)(sp)
905 stfd fr3 ,( 3*8+offes_fltregs)(sp)
906 stfd fr4 ,( 4*8+offes_fltregs)(sp)
907 stfd fr5 ,( 5*8+offes_fltregs)(sp)
908 stfd fr6 ,( 6*8+offes_fltregs)(sp)
909 stfd fr7 ,( 7*8+offes_fltregs)(sp)
910 stfd fr8 ,( 8*8+offes_fltregs)(sp)
911 stfd fr9 ,( 9*8+offes_fltregs)(sp)
912 stfd fr10,(10*8+offes_fltregs)(sp)
913 stfd fr11,(11*8+offes_fltregs)(sp)
914 stfd fr12,(12*8+offes_fltregs)(sp)
915 stfd fr13,(13*8+offes_fltregs)(sp)
916 stfd fr14,(14*8+offes_fltregs)(sp)
917 stfd fr15,(15*8+offes_fltregs)(sp)
918 stfd fr16,(16*8+offes_fltregs)(sp)
919 stfd fr17,(17*8+offes_fltregs)(sp)
920 stfd fr18,(18*8+offes_fltregs)(sp)
921 stfd fr19,(19*8+offes_fltregs)(sp)
922 stfd fr20,(20*8+offes_fltregs)(sp)
923 stfd fr21,(21*8+offes_fltregs)(sp)
924 stfd fr22,(22*8+offes_fltregs)(sp)
925 stfd fr23,(23*8+offes_fltregs)(sp)
926 stfd fr24,(24*8+offes_fltregs)(sp)
927 stfd fr25,(25*8+offes_fltregs)(sp)
928 stfd fr26,(26*8+offes_fltregs)(sp)
929 stfd fr27,(27*8+offes_fltregs)(sp)
930 stfd fr28,(28*8+offes_fltregs)(sp)
931 stfd fr29,(29*8+offes_fltregs)(sp)
932 stfd fr30,(30*8+offes_fltregs)(sp)
933 stfd fr31,(31*8+offes_fltregs)(sp)
935 /* calculate sp of method */
936 addi itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
937 stw itmp1,(offes_sp)(sp)
940 stw pv,(offes_pv)(sp)
942 /* call replace_me */
943 lwz a0,-(4*4)(itmp1) /* arg0: rplpoint * */
944 mr a1,sp /* arg1: execution state */
945 addi sp,sp,-(LA_SIZE_ALIGNED)
946 b replace_me /* call C function replace_me */
948 /* asm_replacement_in **********************************************************
950 This code writes the given execution state and jumps to the replacement
953 This function never returns!
955 NOTE: itmp3 is not restored!
958 void asm_replacement_in(executionstate *es);
960 *******************************************************************************/
963 /* a0 == executionstate *es */
965 /* set new sp and pv */
966 lwz sp,(offes_sp)(a0)
967 lwz pv,(offes_pv)(a0)
969 /* copy registers from execution state */
970 lwz r0 ,( 0*8+offes_intregs)(a0)
973 /* a0 is loaded below */
974 lwz r4 ,( 4*8+offes_intregs)(a0)
975 lwz r5 ,( 5*8+offes_intregs)(a0)
976 lwz r6 ,( 6*8+offes_intregs)(a0)
977 lwz r7 ,( 7*8+offes_intregs)(a0)
978 lwz r8 ,( 8*8+offes_intregs)(a0)
979 lwz r9 ,( 9*8+offes_intregs)(a0)
980 lwz r10,(10*8+offes_intregs)(a0)
981 lwz r11,(11*8+offes_intregs)(a0)
982 lwz r12,(12*8+offes_intregs)(a0)
984 lwz r14,(14*8+offes_intregs)(a0)
985 lwz r15,(15*8+offes_intregs)(a0)
986 lwz r16,(16*8+offes_intregs)(a0) /* link register */
987 lwz r17,(17*8+offes_intregs)(a0)
988 lwz r18,(18*8+offes_intregs)(a0)
989 lwz r19,(19*8+offes_intregs)(a0)
990 lwz r20,(20*8+offes_intregs)(a0)
991 lwz r21,(21*8+offes_intregs)(a0)
992 lwz r22,(22*8+offes_intregs)(a0)
993 lwz r23,(23*8+offes_intregs)(a0)
994 lwz r24,(24*8+offes_intregs)(a0)
995 lwz r25,(25*8+offes_intregs)(a0)
996 lwz r26,(26*8+offes_intregs)(a0)
997 lwz r27,(27*8+offes_intregs)(a0)
998 lwz r28,(28*8+offes_intregs)(a0)
999 lwz r29,(29*8+offes_intregs)(a0)
1000 lwz r30,(30*8+offes_intregs)(a0)
1001 lwz r31,(31*8+offes_intregs)(a0)
1003 lfd fr0 ,( 0*8+offes_fltregs)(a0)
1004 lfd fr1 ,( 1*8+offes_fltregs)(a0)
1005 lfd fr2 ,( 2*8+offes_fltregs)(a0)
1006 lfd fr3 ,( 3*8+offes_fltregs)(a0)
1007 lfd fr4 ,( 4*8+offes_fltregs)(a0)
1008 lfd fr5 ,( 5*8+offes_fltregs)(a0)
1009 lfd fr6 ,( 6*8+offes_fltregs)(a0)
1010 lfd fr7 ,( 7*8+offes_fltregs)(a0)
1011 lfd fr8 ,( 8*8+offes_fltregs)(a0)
1012 lfd fr9 ,( 9*8+offes_fltregs)(a0)
1013 lfd fr10,(10*8+offes_fltregs)(a0)
1014 lfd fr11,(11*8+offes_fltregs)(a0)
1015 lfd fr12,(12*8+offes_fltregs)(a0)
1016 lfd fr13,(13*8+offes_fltregs)(a0)
1017 lfd fr14,(14*8+offes_fltregs)(a0)
1018 lfd fr15,(15*8+offes_fltregs)(a0)
1019 lfd fr16,(16*8+offes_fltregs)(a0)
1020 lfd fr17,(17*8+offes_fltregs)(a0)
1021 lfd fr18,(18*8+offes_fltregs)(a0)
1022 lfd fr19,(19*8+offes_fltregs)(a0)
1023 lfd fr20,(20*8+offes_fltregs)(a0)
1024 lfd fr21,(21*8+offes_fltregs)(a0)
1025 lfd fr22,(22*8+offes_fltregs)(a0)
1026 lfd fr23,(23*8+offes_fltregs)(a0)
1027 lfd fr24,(24*8+offes_fltregs)(a0)
1028 lfd fr25,(25*8+offes_fltregs)(a0)
1029 lfd fr26,(26*8+offes_fltregs)(a0)
1030 lfd fr27,(27*8+offes_fltregs)(a0)
1031 lfd fr28,(28*8+offes_fltregs)(a0)
1032 lfd fr29,(29*8+offes_fltregs)(a0)
1033 lfd fr30,(30*8+offes_fltregs)(a0)
1034 lfd fr31,(31*8+offes_fltregs)(a0)
1036 /* restore link register */
1042 lwz itmp3,offes_pc(a0)
1046 lwz a0,(3*8+offes_intregs)(a0)
1048 /* jump to new code */
1053 /*********************************************************************/
1085 asm_initialize_thread_stack:
1115 #if defined(__DARWIN__)
1116 lfd fr0,lo16(doublezero-0b)(r3)
1118 lfd fr0,(doublezero-0b)@l(r3)
1145 asm_perform_threadswitch:
1237 asm_switchstackandcall:
1255 asm_getclassvalues_atomic:
1258 lwz r6,offbaseval(r3)
1259 lwz r7,offdiffval(r3)
1260 lwz r8,offbaseval(r4)
1262 stw r6,offcast_super_baseval(r5)
1263 stw r7,offcast_super_diffval(r5)
1264 stw r8,offcast_sub_baseval(r5)
1269 asm_criticalsections:
1270 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1278 #if defined(__DARWIN__)
1280 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1282 L_builtin_throw_exception$stub:
1283 .indirect_symbol _builtin_throw_exception
1285 bcl 20,31,L00$_builtin_throw_exception
1286 L00$_builtin_throw_exception:
1288 addis r11,r11,ha16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)
1290 lwzu r12,lo16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)(r11)
1294 .lazy_symbol_pointer
1295 L_builtin_throw_exception$lazy_ptr:
1296 .indirect_symbol _builtin_throw_exception
1297 .long dyld_stub_binding_helper
1300 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1302 L_exceptions_handle_exception$stub:
1303 .indirect_symbol _exceptions_handle_exception
1305 bcl 20,31,L00$_exceptions_handle_exception
1306 L00$_exceptions_handle_exception:
1308 addis r11,r11,ha16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)
1310 lwzu r12,lo16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)(r11)
1314 .lazy_symbol_pointer
1315 L_exceptions_handle_exception$lazy_ptr:
1316 .indirect_symbol _exceptions_handle_exception
1317 .long dyld_stub_binding_helper
1320 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1322 L_stacktrace_create_extern_stackframeinfo$stub:
1323 .indirect_symbol _stacktrace_create_extern_stackframeinfo
1325 bcl 20,31,L00$_stacktrace_create_extern_stackframeinfo
1326 L00$_stacktrace_create_extern_stackframeinfo:
1328 addis r11,r11,ha16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)
1330 lwzu r12,lo16(L_stacktrace_create_extern_stackframeinfo$lazy_ptr - L00$_stacktrace_create_extern_stackframeinfo)(r11)
1334 .lazy_symbol_pointer
1335 L_stacktrace_create_extern_stackframeinfo$lazy_ptr:
1336 .indirect_symbol _stacktrace_create_extern_stackframeinfo
1337 .long dyld_stub_binding_helper
1340 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1342 L_jit_asm_compile$stub:
1343 .indirect_symbol _jit_asm_compile
1345 bcl 20,31,L00$_jit_asm_compile
1346 L00$_jit_asm_compile:
1348 addis r11,r11,ha16(L_jit_asm_compile$lazy_ptr - L00$_jit_asm_compile)
1350 lwzu r12,lo16(L_jit_asm_compile$lazy_ptr - L00$_jit_asm_compile)(r11)
1354 .lazy_symbol_pointer
1355 L_jit_asm_compile$lazy_ptr:
1356 .indirect_symbol _jit_asm_compile
1357 .long dyld_stub_binding_helper
1360 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1362 L_stacktrace_remove_stackframeinfo$stub:
1363 .indirect_symbol _stacktrace_remove_stackframeinfo
1365 bcl 20,31,L00$_stacktrace_remove_stackframeinfo
1366 L00$_stacktrace_remove_stackframeinfo:
1368 addis r11,r11,ha16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)
1370 lwzu r12,lo16(L_stacktrace_remove_stackframeinfo$lazy_ptr - L00$_stacktrace_remove_stackframeinfo)(r11)
1374 .lazy_symbol_pointer
1375 L_stacktrace_remove_stackframeinfo$lazy_ptr:
1376 .indirect_symbol _stacktrace_remove_stackframeinfo
1377 .long dyld_stub_binding_helper
1380 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1382 L_builtin_asm_get_exceptionptrptr$stub:
1383 .indirect_symbol _builtin_asm_get_exceptionptrptr
1385 bcl 20,31,L00$_builtin_asm_get_exceptionptrptr
1386 L00$_builtin_asm_get_exceptionptrptr:
1388 addis r11,r11,ha16(L_builtin_asm_get_exceptionptrptr$lazy_ptr - L00$_builtin_asm_get_exceptionptrptr)
1390 lwzu r12,lo16(L_builtin_asm_get_exceptionptrptr$lazy_ptr - L00$_builtin_asm_get_exceptionptrptr)(r11)
1394 .lazy_symbol_pointer
1395 L_builtin_asm_get_exceptionptrptr$lazy_ptr:
1396 .indirect_symbol _builtin_asm_get_exceptionptrptr
1397 .long dyld_stub_binding_helper
1400 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
1403 .indirect_symbol _replace_me
1405 bcl 20,31,L00$_replace_me
1408 addis r11,r11,ha16(L_replace_me$lazy_ptr - L00$_replace_me)
1410 lwzu r12,lo16(L_replace_me$lazy_ptr - L00$_replace_me)(r11)
1414 .lazy_symbol_pointer
1415 L_replace_me$lazy_ptr:
1416 .indirect_symbol _replace_me
1417 .long dyld_stub_binding_helper
1419 #endif /* defined(__DARWIN__) */
1422 /* Disable exec-stacks, required for Gentoo ***********************************/
1424 #if defined(__GCC__) && defined(__ELF__)
1425 .section .note.GNU-stack,"",@progbits
1430 * These are local overrides for various environment variables in Emacs.
1431 * Please do not remove this and leave it at the end of the file, where
1432 * Emacs will automagically detect them.
1433 * ---------------------------------------------------------------------
1436 * indent-tabs-mode: t
1440 * vim:noexpandtab:sw=4:ts=4: