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 4654 2006-03-19 19:46:11Z edwin $
44 #include "vm/jit/abi.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_call_jit_compiler
64 .globl asm_handle_nat_exception
65 .globl asm_handle_exception
67 .globl asm_wrapper_patcher
69 .globl asm_replacement_out
70 .globl asm_replacement_in
73 .globl asm_initialize_thread_stack
74 .globl asm_perform_threadswitch
75 .globl asm_switchstackandcall
76 .globl asm_criticalsections
77 .globl asm_getclassvalues_atomic
80 /* asm_vm_call_method **********************************************************
82 * This function calls a Java-method (which possibly needs compilation) *
83 * with up to 4 address parameters. *
85 * This functions calls the JIT-compiler which eventually translates the *
86 * method into machine code. *
89 * javaobject_header *asm_calljavamethod (methodinfo *m, *
90 * void *arg1, void *arg2, void *arg3, void *arg4); *
92 *******************************************************************************/
96 .long 0 /* catch type all */
97 .long calljava_xhandler2 /* handler pc */
98 .long calljava_xhandler2 /* end pc */
99 .long L_asm_vm_call_method /* start pc */
100 .long 1 /* extable size */
101 .long 0 /* line number table start */
102 .long 0 /* line number table size */
103 .long 0 /* fltsave */
104 .long 0 /* intsave */
107 .long 0 /* frame size */
108 .long 0 /* method pointer (pointer to name) */
111 asm_vm_call_method_int:
112 asm_vm_call_method_long:
113 asm_vm_call_method_float:
114 asm_vm_call_method_double:
115 L_asm_vm_call_method: /* required for PIC code */
117 stw r0,LA_LR_OFFSET(r1)
120 #if defined(__DARWIN__)
121 stw itmp1,10*4(sp) /* register r11 is callee saved */
123 stw pv,11*4(sp) /* save PV register */
125 stw itmp3,12*4(sp) /* registers r14-r31 are callee saved */
126 stfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
129 #if defined(__DARWIN__)
145 SAVE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
148 stw a0,9*4(r1) /* save method pointer for compiler */
150 mr itmp1,r5 /* pointer to arg block */
151 mr itmp2,r4 /* arg count */
153 addi itmp1,itmp1,-sizevmarg /* initialize pointer (smaller code) */
154 addi itmp2,itmp2,1 /* initialize argument count */
155 li r17,0 /* initialize integer argument counter */
156 li r18,0 /* initialize float argument counter */
159 addi itmp1,itmp1,sizevmarg /* goto next argument block */
160 addi itmp2,itmp2,-1 /* argument count - 1 */
162 beq L_register_copy_done
164 #if WORDS_BIGENDIAN == 1
165 lwz itmp3,offvmargtype+4(itmp1)
169 andi. r0,itmp3,0x0002 /* is this a float/double type? */
170 bne L_register_handle_float
172 cmpwi r17,INT_ARG_CNT /* are we out of integer argument */
173 beq L_register_copy /* registers? yes, next loop */
175 andi. r0,itmp3,0x0001 /* is this a long type? */
176 bne L_register_handle_long
178 L_register_handle_int:
179 #if defined(__DARWIN__)
180 lis itmp3,ha16(jumptable_int)
181 addi itmp3,itmp3,lo16(jumptable_int)
183 lis itmp3,jumptable_int@ha
184 addi itmp3,itmp3,jumptable_int@l
186 slwi r19,r17,2 /* multiple of 4-bytes */
187 add itmp3,itmp3,r19 /* calculate address of jumptable */
188 lwz itmp3,0(itmp3) /* load function address */
189 addi r17,r17,1 /* integer argument counter + 1 */
193 L_register_handle_long:
194 #if defined(__DARWIN__)
195 lis itmp3,ha16(jumptable_long)
196 addi itmp3,itmp3,lo16(jumptable_long)
198 lis itmp3,jumptable_long@ha
199 addi itmp3,itmp3,jumptable_long@l
201 addi r19,r17,1 /* align to even numbers */
204 slwi r19,r19,2 /* multiple of 4-bytes */
205 add itmp3,itmp3,r19 /* calculate address of jumptable */
206 lwz itmp3,0(itmp3) /* load function address */
207 addi r17,r17,1 /* integer argument counter + 1 */
211 L_register_handle_float:
212 L_register_copy_done:
215 lwz itmp1,9*4(sp) /* pass method pointer via tmp1 */
217 #if defined(__DARWIN__)
218 lis mptr,ha16(L_asm_call_jit_compiler)
219 addi mptr,mptr,lo16(L_asm_call_jit_compiler)
221 lis mptr,L_asm_call_jit_compiler@ha
222 addi mptr,mptr,L_asm_call_jit_compiler@l
232 #if defined(__DARWIN__)
233 addi pv,itmp1,lo16(L_asm_vm_call_method-1b)
235 addi pv,itmp1,(L_asm_vm_call_method-1b)@l
238 L_asm_vm_call_method_return:
239 #if defined(__DARWIN__)
240 lwz itmp1,10*4(sp) /* register r11 is callee saved */
242 lwz pv,11*4(sp) /* save PV register */
245 lfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
248 #if defined(__DARWIN__)
264 RESTORE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
267 lwz r0,40*4+LA_LR_OFFSET(r1)
274 bl builtin_throw_exception
275 li v0,0 /* return NULL */
276 b L_asm_vm_call_method_return
290 lwz a0,offvmargdata+4(itmp1)
293 lwz a1,offvmargdata+4(itmp1)
296 lwz a2,offvmargdata+4(itmp1)
299 lwz a3,offvmargdata+4(itmp1)
302 lwz a4,offvmargdata+4(itmp1)
305 lwz a5,offvmargdata+4(itmp1)
308 lwz a6,offvmargdata+4(itmp1)
311 lwz a7,offvmargdata+4(itmp1)
316 #if defined(__DARWIN__)
318 /* we have two entries here, so we get the even argument register
319 alignment for linux */
332 lwz a0,offvmargdata+0(itmp1)
333 lwz a1,offvmargdata+4(itmp1)
336 lwz a2,offvmargdata+0(itmp1)
337 lwz a3,offvmargdata+4(itmp1)
340 lwz a4,offvmargdata+0(itmp1)
341 lwz a5,offvmargdata+4(itmp1)
344 lwz a6,offvmargdata+0(itmp1)
345 lwz a7,offvmargdata+4(itmp1)
349 /* asm_call_jit_compiler *******************************************************
351 Invokes the compiler for untranslated JavaVM methods.
353 *******************************************************************************/
355 asm_call_jit_compiler:
356 L_asm_call_jit_compiler: /* required for PIC code */
358 stw r0,LA_LR_OFFSET(r1) /* save return address */
359 stwu r1,-((LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo)(r1)
360 stw itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
362 mr itmp1,r0 /* save return address to other reg. */
380 stw mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
382 #if defined(__DARWIN__)
383 stw a0,(LA_WORD_SIZE+5+0)*4(r1)
384 stw a1,(LA_WORD_SIZE+5+1)*4(r1)
385 stw a2,(LA_WORD_SIZE+5+2)*4(r1)
386 stw a3,(LA_WORD_SIZE+5+3)*4(r1)
387 stw a4,(LA_WORD_SIZE+5+4)*4(r1)
388 stw a5,(LA_WORD_SIZE+5+5)*4(r1)
389 stw a6,(LA_WORD_SIZE+5+6)*4(r1)
390 stw a7,(LA_WORD_SIZE+5+7)*4(r1)
392 stfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
393 stfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
394 stfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
395 stfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
396 stfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
397 stfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
398 stfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
399 stfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
400 stfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
401 stfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
402 stfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
403 stfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
404 stfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
406 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
409 addi a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
410 li a1,0 /* we don't have pv handy */
411 addi a2,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
412 lwz a3,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(sp)
413 mr a4,a3 /* xpc is equal to ra */
414 bl stacktrace_create_extern_stackframeinfo
416 lwz a0,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
417 bl jit_compile /* compile the Java method */
418 mr pv,r3 /* move address to pv register */
420 addi a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
421 bl stacktrace_remove_stackframeinfo
423 #if defined(__DARWIN__)
424 lwz a0,(LA_WORD_SIZE+5+0)*4(r1)
425 lwz a1,(LA_WORD_SIZE+5+1)*4(r1)
426 lwz a2,(LA_WORD_SIZE+5+2)*4(r1)
427 lwz a3,(LA_WORD_SIZE+5+3)*4(r1)
428 lwz a4,(LA_WORD_SIZE+5+4)*4(r1)
429 lwz a5,(LA_WORD_SIZE+5+5)*4(r1)
430 lwz a6,(LA_WORD_SIZE+5+6)*4(r1)
431 lwz a7,(LA_WORD_SIZE+5+7)*4(r1)
433 lfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
434 lfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
435 lfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
436 lfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
437 lfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
438 lfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
439 lfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
440 lfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
441 lfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
442 lfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
443 lfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
444 lfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
445 lfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
447 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
450 lwz mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
452 lwz itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(r1)
454 addi r1,r1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
456 mr. pv,pv /* test for exception */
457 beq L_asm_call_jit_compiler_exception
462 stw pv,0(mptr) /* store method address */
464 mtctr pv /* move method address to control reg */
465 bctr /* and call the Java method */
467 L_asm_call_jit_compiler_exception:
468 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
470 stw r0,LA_LR_OFFSET(sp)
471 stwu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
472 bl builtin_asm_get_exceptionptrptr
473 lwz r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
475 addi sp,sp,LA_SIZE_ALIGNED
477 # if defined(__DARWIN__)
478 lwz v0,lo16(_no_threads_exceptionptr-0b)(pv)
480 lis v0,_no_threads_exceptionptr@ha
481 addi v0,v0,_no_threads_exceptionptr@l
484 lwz xptr,0(v0) /* get the exception pointer */
486 stw itmp3,0(v0) /* clear the exception pointer */
490 b L_asm_handle_nat_exception
493 /********************* function asm_handle_exception ***************************
495 * This function handles an exception. It does not use the usual calling *
496 * conventions. The exception pointer is passed in REG_ITMP1 and the *
497 * pc from the exception raising position is passed in REG_ITMP2. It searches *
498 * the local exception table for a handler. If no one is found, it unwinds *
499 * stacks and continues searching the callers. *
501 * void asm_handle_exception (exceptionptr, exceptionpc); *
503 *******************************************************************************/
505 asm_handle_nat_exception:
506 L_asm_handle_nat_exception: /* required for PIC code */
514 bne L_asm_handle_exception
519 asm_handle_exception:
520 L_asm_handle_exception: /* required for PIC code */
521 addi sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
523 #if defined(__DARWIN__)
525 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
526 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
529 li a3,(ARG_CNT+TMP_CNT)*8 /* prepare a3 for handle_exception */
530 li a4,1 /* set maybe-leaf flag */
532 L_asm_handle_exception_stack_loop:
533 addi sp,sp,-(LA_WORD_SIZE+4+5)*4 /* allocate stack */
534 stw xptr,LA_SIZE+4*4(sp) /* save exception pointer */
535 stw xpc,LA_SIZE+5*4(sp) /* save exception pc */
536 stw pv,LA_SIZE+6*4(sp) /* save data segment pointer */
537 mflr r0 /* save return address */
538 stw r0,LA_SIZE+5*4(sp)
539 add a3,a3,sp /* calculate Java sp into a3... */
540 addi a3,a3,(LA_WORD_SIZE+4+5)*4
541 stw a4,LA_SIZE+8*4(sp) /* save maybe-leaf flag */
543 mr a0,xptr /* pass exception pointer */
544 mr a1,xpc /* pass exception pc */
545 mr a2,pv /* pass data segment pointer */
546 /* a3 is still set */
547 bl exceptions_handle_exception
550 beq L_asm_handle_exception_not_catched
552 mr xpc,v0 /* move handlerpc into xpc */
553 lwz xptr,LA_SIZE+4*4(sp) /* restore exception pointer */
554 lwz pv,LA_SIZE+6*4(sp) /* restore data segment pointer */
555 lwz r0,LA_SIZE+5*4(sp) /* restore return address */
557 lwz a4,LA_SIZE+8*4(sp) /* get maybe-leaf flag */
558 addi sp,sp,(LA_WORD_SIZE+4+5)*4 /* free stack frame */
561 beq L_asm_handle_exception_no_leaf
563 #if defined(__DARWIN__)
565 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
566 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
569 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
571 L_asm_handle_exception_no_leaf:
572 mtctr xpc /* jump to the handler */
575 L_asm_handle_exception_not_catched:
576 lwz xptr,LA_SIZE+4*4(sp) /* restore exception pointer */
577 lwz pv,LA_SIZE+6*4(sp) /* restore data segment pointer */
578 lwz r0,LA_SIZE+5*4(sp) /* restore return address */
580 lwz a4,LA_SIZE+8*4(sp) /* get maybe-leaf flag */
581 addi sp,sp,(LA_WORD_SIZE+4+5)*4 /* free stack frame */
584 beq L_asm_handle_exception_no_leaf_stack
586 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
587 li a4,0 /* clear the maybe-leaf flag */
589 L_asm_handle_exception_no_leaf_stack:
590 lwz t0,FrameSize(pv) /* get frame size */
591 add t0,sp,t0 /* pointer to save area */
593 lwz t1,IsLeaf(pv) /* is leaf procedure */
595 bne L_asm_handle_exception_no_ra_restore
597 lwz r0,LA_LR_OFFSET(t0) /* restore ra */
600 L_asm_handle_exception_no_ra_restore:
601 mflr xpc /* the new xpc is ra */
602 lwz t1,IntSave(pv) /* t1 = saved int register count */
605 mflr t2 /* t2 = current pc */
606 #if defined(__DARWIN__)
607 addi t2,t2,lo16(ex_int2-ex_int1)
609 addi t2,t2,(ex_int2-ex_int1)@l
611 slwi t1,t1,2 /* t1 = register count * 4 */
612 subf t2,t1,t2 /* t2 = IntSave - t1 */
628 subf t0,t1,t0 /* t0 = t0 - register count * 4 */
634 #if defined(__DARWIN__)
635 addi t2,t2,lo16(ex_flt2-ex_flt1)
637 addi t2,t2,(ex_flt2-ex_flt1)@l
639 slwi t1,t1,2 /* t1 = register count * 4 */
640 subf t2,t1,t2 /* t2 = FltSave - t1 */
656 lwz t0,FrameSize(pv) /* get frame size */
657 add sp,sp,t0 /* unwind stack */
658 li a3,0 /* prepare a3 for handle_exception */
667 bne L_asm_handle_exception_stack_loop
672 b L_asm_handle_exception_stack_loop
675 /* asm_wrapper_patcher *********************************************************
680 20 return address into JIT code (patch position)
681 16 pointer to virtual java_objectheader
682 12 machine code (which is patched back later)
683 8 unresolved class/method/field reference
684 4 data segment displacement from load instructions
685 0 patcher function pointer to call (pv is saved here afterwards)
687 *******************************************************************************/
690 mflr r0 /* get Java return address (leaf) */
691 stw r0,6*4(sp) /* store it in the stub stackframe */
692 /* keep stack 16-bytes aligned: 6+1+37 = 44 */
693 stwu sp,-(LA_SIZE+(5+58)*4+sizestackframeinfo)(sp)
695 #if defined(__DARWIN__)
696 stw a0,LA_SIZE+(5+0)*4(r1) /* save argument registers */
697 stw a1,LA_SIZE+(5+1)*4(r1) /* preserve linkage area (24 bytes) */
698 stw a2,LA_SIZE+(5+2)*4(r1) /* and 4 bytes for 4 argument */
699 stw a3,LA_SIZE+(5+3)*4(r1)
700 stw a4,LA_SIZE+(5+4)*4(r1)
701 stw a5,LA_SIZE+(5+5)*4(r1)
702 stw a6,LA_SIZE+(5+6)*4(r1)
703 stw a7,LA_SIZE+(5+7)*4(r1)
705 stfd fa0,LA_SIZE+(5+8)*4(sp)
706 stfd fa1,LA_SIZE+(5+10)*4(sp)
707 stfd fa2,LA_SIZE+(5+12)*4(sp)
708 stfd fa3,LA_SIZE+(5+14)*4(sp)
709 stfd fa4,LA_SIZE+(5+16)*4(sp)
710 stfd fa5,LA_SIZE+(5+18)*4(sp)
711 stfd fa6,LA_SIZE+(5+20)*4(sp)
712 stfd fa7,LA_SIZE+(5+22)*4(sp)
713 stfd fa8,LA_SIZE+(5+24)*4(sp)
714 stfd fa9,LA_SIZE+(5+26)*4(sp)
715 stfd fa10,LA_SIZE+(5+28)*4(sp)
716 stfd fa11,LA_SIZE+(5+30)*4(sp)
717 stfd fa12,LA_SIZE+(5+32)*4(sp)
719 stw t0,(LA_WORD_SIZE+5+33)*4(r1)
720 stw t1,(LA_WORD_SIZE+5+34)*4(r1)
721 stw t2,(LA_WORD_SIZE+5+35)*4(r1)
722 stw t3,(LA_WORD_SIZE+5+36)*4(r1)
723 stw t4,(LA_WORD_SIZE+5+37)*4(r1)
724 stw t5,(LA_WORD_SIZE+5+38)*4(r1)
725 stw t6,(LA_WORD_SIZE+5+39)*4(r1)
726 stw t7,(LA_WORD_SIZE+5+40)*4(r1)
728 stfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
729 stfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
730 stfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
731 stfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
732 stfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
733 stfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
735 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* save 8 int/8 float arguments */
736 SAVE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
739 stw itmp1,LA_SIZE+(5+54)*4(sp)
740 stw itmp2,LA_SIZE+(5+55)*4(sp)
741 stw pv,LA_SIZE+(5+56)*4(sp)
743 addi a0,sp,LA_SIZE+(5+58)*4 /* create stackframe info */
745 addi a2,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
746 mr a3,r0 /* this is correct for leafs */
747 lwz a4,((5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo)(sp) /* pass xpc */
748 bl stacktrace_create_extern_stackframeinfo
750 addi a0,sp,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo /* pass sp */
751 lwz pv,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* get function */
752 lwz itmp1,LA_SIZE+(5+56)*4(sp) /* move pv to position of fp */
753 stw itmp1,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
754 mtctr pv /* call the patcher function */
756 stw v0,LA_SIZE+(5+57)*4(sp) /* save return value */
758 addi a0,sp,LA_SIZE+(5+58)*4
759 bl stacktrace_remove_stackframeinfo /* remove stackframe info */
761 #if defined(__DARWIN__)
762 lwz a0,LA_SIZE+(5+0)*4(r1)
763 lwz a1,LA_SIZE+(5+1)*4(r1)
764 lwz a2,LA_SIZE+(5+2)*4(r1)
765 lwz a3,LA_SIZE+(5+3)*4(r1)
766 lwz a4,LA_SIZE+(5+4)*4(r1)
767 lwz a5,LA_SIZE+(5+5)*4(r1)
768 lwz a6,LA_SIZE+(5+6)*4(r1)
769 lwz a7,LA_SIZE+(5+7)*4(r1)
771 lfd fa0,LA_SIZE+(5+8)*4(sp)
772 lfd fa1,LA_SIZE+(5+10)*4(sp)
773 lfd fa2,LA_SIZE+(5+12)*4(sp)
774 lfd fa3,LA_SIZE+(5+14)*4(sp)
775 lfd fa4,LA_SIZE+(5+16)*4(sp)
776 lfd fa5,LA_SIZE+(5+18)*4(sp)
777 lfd fa6,LA_SIZE+(5+20)*4(sp)
778 lfd fa7,LA_SIZE+(5+22)*4(sp)
779 lfd fa8,LA_SIZE+(5+24)*4(sp)
780 lfd fa9,LA_SIZE+(5+26)*4(sp)
781 lfd fa10,LA_SIZE+(5+28)*4(sp)
782 lfd fa11,LA_SIZE+(5+30)*4(sp)
783 lfd fa12,LA_SIZE+(5+32)*4(sp)
785 lwz t0,(LA_WORD_SIZE+5+33)*4(r1)
786 lwz t1,(LA_WORD_SIZE+5+34)*4(r1)
787 lwz t2,(LA_WORD_SIZE+5+35)*4(r1)
788 lwz t3,(LA_WORD_SIZE+5+36)*4(r1)
789 lwz t4,(LA_WORD_SIZE+5+37)*4(r1)
790 lwz t5,(LA_WORD_SIZE+5+38)*4(r1)
791 lwz t6,(LA_WORD_SIZE+5+39)*4(r1)
792 lwz t7,(LA_WORD_SIZE+5+40)*4(r1)
794 lfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
795 lfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
796 lfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
797 lfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
798 lfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
799 lfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
801 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* restore 8 int/8 float args */
802 RESTORE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
805 lwz itmp1,LA_SIZE+(5+54)*4(sp)
806 lwz itmp2,LA_SIZE+(5+55)*4(sp)
807 lwz pv,LA_SIZE+(5+56)*4(sp)
808 lwz itmp3,LA_SIZE+(5+57)*4(sp) /* restore return value into temp reg.*/
810 lwz r0,(6+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* restore RA */
813 mr. itmp3,itmp3 /* check for an exception */
814 beq L_asm_wrapper_patcher_exception
816 /* get return address (into JIT code) */
817 lwz itmp3,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
819 /* remove stack frame + patcher stub stack */
820 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
823 bctr /* jump to new patched code */
825 L_asm_wrapper_patcher_exception:
826 lwz xpc,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
827 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
829 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
831 stw r0,LA_LR_OFFSET(sp)
832 stwu sp,-(LA_SIZE+1*4)(sp) /* preserve linkage area */
833 stw xpc,LA_SIZE+0*4(sp)
834 bl builtin_asm_get_exceptionptrptr
835 lwz xpc,LA_SIZE+0*4(sp)
836 lwz r0,LA_SIZE+1*4+LA_LR_OFFSET(sp)
838 addi sp,sp,LA_SIZE+1*4
840 # if defined(__DARWIN__)
841 lwz v0,lo16(_no_threads_exceptionptr-0b)(pv)
843 lis v0,_no_threads_exceptionptr@ha
844 addi v0,v0,_no_threads_exceptionptr@l
848 lwz xptr,0(v0) /* get the exception pointer */
850 stw itmp3,0(v0) /* clear the exception pointer */
851 b L_asm_handle_exception
854 /* asm_replacement_out *********************************************************
856 This code is jumped to from the replacement-out stubs that are executed
857 when a thread reaches an activated replacement point.
859 The purpose of asm_replacement_out is to read out the parts of the
860 execution state that cannot be accessed from C code, store this state,
861 and then call the C function replace_me.
864 16 start of stack inside method to replace
865 0 rplpoint * info on the replacement point that was reached
867 NOTE: itmp3 has been clobbered by the replacement-out stub!
869 *******************************************************************************/
871 /* some room to accomodate changes of the stack frame size during replacement */
872 /* XXX we should find a cleaner solution here */
873 #define REPLACEMENT_ROOM 512
876 /* create stack frame */
877 addi sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
879 /* save link register */
882 /* save registers in execution state */
883 stw r0 ,( 0*8+offes_intregs)(sp)
884 stw r1 ,( 1*8+offes_intregs)(sp)
885 stw r2 ,( 2*8+offes_intregs)(sp)
886 stw r3 ,( 3*8+offes_intregs)(sp)
887 stw r4 ,( 4*8+offes_intregs)(sp)
888 stw r5 ,( 5*8+offes_intregs)(sp)
889 stw r6 ,( 6*8+offes_intregs)(sp)
890 stw r7 ,( 7*8+offes_intregs)(sp)
891 stw r8 ,( 8*8+offes_intregs)(sp)
892 stw r9 ,( 9*8+offes_intregs)(sp)
893 stw r10,(10*8+offes_intregs)(sp)
894 stw r11,(11*8+offes_intregs)(sp)
895 stw r12,(12*8+offes_intregs)(sp)
896 stw r13,(13*8+offes_intregs)(sp)
897 stw r14,(14*8+offes_intregs)(sp)
898 stw r15,(15*8+offes_intregs)(sp)
899 stw r16,(16*8+offes_intregs)(sp) /* link register */
900 stw r17,(17*8+offes_intregs)(sp)
901 stw r18,(18*8+offes_intregs)(sp)
902 stw r19,(19*8+offes_intregs)(sp)
903 stw r20,(20*8+offes_intregs)(sp)
904 stw r21,(21*8+offes_intregs)(sp)
905 stw r22,(22*8+offes_intregs)(sp)
906 stw r23,(23*8+offes_intregs)(sp)
907 stw r24,(24*8+offes_intregs)(sp)
908 stw r25,(25*8+offes_intregs)(sp)
909 stw r26,(26*8+offes_intregs)(sp)
910 stw r27,(27*8+offes_intregs)(sp)
911 stw r28,(28*8+offes_intregs)(sp)
912 stw r29,(29*8+offes_intregs)(sp)
913 stw r30,(30*8+offes_intregs)(sp)
914 stw r31,(31*8+offes_intregs)(sp)
916 stfd fr0 ,( 0*8+offes_fltregs)(sp)
917 stfd fr1 ,( 1*8+offes_fltregs)(sp)
918 stfd fr2 ,( 2*8+offes_fltregs)(sp)
919 stfd fr3 ,( 3*8+offes_fltregs)(sp)
920 stfd fr4 ,( 4*8+offes_fltregs)(sp)
921 stfd fr5 ,( 5*8+offes_fltregs)(sp)
922 stfd fr6 ,( 6*8+offes_fltregs)(sp)
923 stfd fr7 ,( 7*8+offes_fltregs)(sp)
924 stfd fr8 ,( 8*8+offes_fltregs)(sp)
925 stfd fr9 ,( 9*8+offes_fltregs)(sp)
926 stfd fr10,(10*8+offes_fltregs)(sp)
927 stfd fr11,(11*8+offes_fltregs)(sp)
928 stfd fr12,(12*8+offes_fltregs)(sp)
929 stfd fr13,(13*8+offes_fltregs)(sp)
930 stfd fr14,(14*8+offes_fltregs)(sp)
931 stfd fr15,(15*8+offes_fltregs)(sp)
932 stfd fr16,(16*8+offes_fltregs)(sp)
933 stfd fr17,(17*8+offes_fltregs)(sp)
934 stfd fr18,(18*8+offes_fltregs)(sp)
935 stfd fr19,(19*8+offes_fltregs)(sp)
936 stfd fr20,(20*8+offes_fltregs)(sp)
937 stfd fr21,(21*8+offes_fltregs)(sp)
938 stfd fr22,(22*8+offes_fltregs)(sp)
939 stfd fr23,(23*8+offes_fltregs)(sp)
940 stfd fr24,(24*8+offes_fltregs)(sp)
941 stfd fr25,(25*8+offes_fltregs)(sp)
942 stfd fr26,(26*8+offes_fltregs)(sp)
943 stfd fr27,(27*8+offes_fltregs)(sp)
944 stfd fr28,(28*8+offes_fltregs)(sp)
945 stfd fr29,(29*8+offes_fltregs)(sp)
946 stfd fr30,(30*8+offes_fltregs)(sp)
947 stfd fr31,(31*8+offes_fltregs)(sp)
949 /* calculate sp of method */
950 addi itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
951 stw itmp1,(offes_sp)(sp)
954 stw pv,(offes_pv)(sp)
956 /* call replace_me */
957 lwz a0,-(4*4)(itmp1) /* arg0: rplpoint * */
958 mr a1,sp /* arg1: execution state */
959 addi sp,sp,-(LA_SIZE_ALIGNED)
960 b replace_me /* call C function replace_me */
962 /* asm_replacement_in **********************************************************
964 This code writes the given execution state and jumps to the replacement
967 This function never returns!
969 NOTE: itmp3 is not restored!
972 void asm_replacement_in(executionstate *es);
974 *******************************************************************************/
977 /* a0 == executionstate *es */
979 /* set new sp and pv */
980 lwz sp,(offes_sp)(a0)
981 lwz pv,(offes_pv)(a0)
983 /* copy registers from execution state */
984 lwz r0 ,( 0*8+offes_intregs)(a0)
987 /* a0 is loaded below */
988 lwz r4 ,( 4*8+offes_intregs)(a0)
989 lwz r5 ,( 5*8+offes_intregs)(a0)
990 lwz r6 ,( 6*8+offes_intregs)(a0)
991 lwz r7 ,( 7*8+offes_intregs)(a0)
992 lwz r8 ,( 8*8+offes_intregs)(a0)
993 lwz r9 ,( 9*8+offes_intregs)(a0)
994 lwz r10,(10*8+offes_intregs)(a0)
995 lwz r11,(11*8+offes_intregs)(a0)
996 lwz r12,(12*8+offes_intregs)(a0)
998 lwz r14,(14*8+offes_intregs)(a0)
999 lwz r15,(15*8+offes_intregs)(a0)
1000 lwz r16,(16*8+offes_intregs)(a0) /* link register */
1001 lwz r17,(17*8+offes_intregs)(a0)
1002 lwz r18,(18*8+offes_intregs)(a0)
1003 lwz r19,(19*8+offes_intregs)(a0)
1004 lwz r20,(20*8+offes_intregs)(a0)
1005 lwz r21,(21*8+offes_intregs)(a0)
1006 lwz r22,(22*8+offes_intregs)(a0)
1007 lwz r23,(23*8+offes_intregs)(a0)
1008 lwz r24,(24*8+offes_intregs)(a0)
1009 lwz r25,(25*8+offes_intregs)(a0)
1010 lwz r26,(26*8+offes_intregs)(a0)
1011 lwz r27,(27*8+offes_intregs)(a0)
1012 lwz r28,(28*8+offes_intregs)(a0)
1013 lwz r29,(29*8+offes_intregs)(a0)
1014 lwz r30,(30*8+offes_intregs)(a0)
1015 lwz r31,(31*8+offes_intregs)(a0)
1017 lfd fr0 ,( 0*8+offes_fltregs)(a0)
1018 lfd fr1 ,( 1*8+offes_fltregs)(a0)
1019 lfd fr2 ,( 2*8+offes_fltregs)(a0)
1020 lfd fr3 ,( 3*8+offes_fltregs)(a0)
1021 lfd fr4 ,( 4*8+offes_fltregs)(a0)
1022 lfd fr5 ,( 5*8+offes_fltregs)(a0)
1023 lfd fr6 ,( 6*8+offes_fltregs)(a0)
1024 lfd fr7 ,( 7*8+offes_fltregs)(a0)
1025 lfd fr8 ,( 8*8+offes_fltregs)(a0)
1026 lfd fr9 ,( 9*8+offes_fltregs)(a0)
1027 lfd fr10,(10*8+offes_fltregs)(a0)
1028 lfd fr11,(11*8+offes_fltregs)(a0)
1029 lfd fr12,(12*8+offes_fltregs)(a0)
1030 lfd fr13,(13*8+offes_fltregs)(a0)
1031 lfd fr14,(14*8+offes_fltregs)(a0)
1032 lfd fr15,(15*8+offes_fltregs)(a0)
1033 lfd fr16,(16*8+offes_fltregs)(a0)
1034 lfd fr17,(17*8+offes_fltregs)(a0)
1035 lfd fr18,(18*8+offes_fltregs)(a0)
1036 lfd fr19,(19*8+offes_fltregs)(a0)
1037 lfd fr20,(20*8+offes_fltregs)(a0)
1038 lfd fr21,(21*8+offes_fltregs)(a0)
1039 lfd fr22,(22*8+offes_fltregs)(a0)
1040 lfd fr23,(23*8+offes_fltregs)(a0)
1041 lfd fr24,(24*8+offes_fltregs)(a0)
1042 lfd fr25,(25*8+offes_fltregs)(a0)
1043 lfd fr26,(26*8+offes_fltregs)(a0)
1044 lfd fr27,(27*8+offes_fltregs)(a0)
1045 lfd fr28,(28*8+offes_fltregs)(a0)
1046 lfd fr29,(29*8+offes_fltregs)(a0)
1047 lfd fr30,(30*8+offes_fltregs)(a0)
1048 lfd fr31,(31*8+offes_fltregs)(a0)
1050 /* restore link register */
1056 lwz itmp3,offes_pc(a0)
1060 lwz a0,(3*8+offes_intregs)(a0)
1062 /* jump to new code */
1067 /*********************************************************************/
1099 asm_initialize_thread_stack:
1129 #if defined(__DARWIN__)
1130 lfd fr0,lo16(doublezero-0b)(r3)
1132 lfd fr0,(doublezero-0b)@l(r3)
1159 asm_perform_threadswitch:
1251 asm_switchstackandcall:
1269 asm_getclassvalues_atomic:
1272 lwz r6,offbaseval(r3)
1273 lwz r7,offdiffval(r3)
1274 lwz r8,offbaseval(r4)
1276 stw r6,offcast_super_baseval(r5)
1277 stw r7,offcast_super_diffval(r5)
1278 stw r8,offcast_sub_baseval(r5)
1283 asm_criticalsections:
1284 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1292 /* Disable exec-stacks, required for Gentoo ***********************************/
1294 #if defined(__GCC__) && defined(__ELF__)
1295 .section .note.GNU-stack,"",@progbits
1300 * These are local overrides for various environment variables in Emacs.
1301 * Please do not remove this and leave it at the end of the file, where
1302 * Emacs will automagically detect them.
1303 * ---------------------------------------------------------------------
1306 * indent-tabs-mode: t
1310 * vim:noexpandtab:sw=4:ts=4: