1 /* src/vm/jit/powerpc/asmpart.S - Java-C interface functions for PowerPC
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
31 Changes: Christian Thalinger
33 $Id: asmpart.S 3727 2005-11-21 22:01:57Z twisti $
43 #include "vm/jit/methodheader.h"
44 #include "vm/jit/powerpc/offsets.h"
51 .globl asm_calljavafunction
52 .globl asm_calljavafunction_int
54 .globl asm_calljavafunction2
55 .globl asm_calljavafunction2int
56 .globl asm_calljavafunction2long
57 .globl asm_calljavafunction2float
58 .globl asm_calljavafunction2double
60 .globl asm_call_jit_compiler
62 .globl asm_handle_nat_exception
63 .globl asm_handle_exception
65 .globl asm_wrapper_patcher
68 .globl asm_initialize_thread_stack
69 .globl asm_perform_threadswitch
70 .globl asm_switchstackandcall
71 .globl asm_criticalsections
72 .globl asm_getclassvalues_atomic
75 /********************* function asm_calljavafunction ***************************
77 * This function calls a Java-method (which possibly needs compilation) *
78 * with up to 4 address parameters. *
80 * This functions calls the JIT-compiler which eventually translates the *
81 * method into machine code. *
84 * javaobject_header *asm_calljavamethod (methodinfo *m, *
85 * void *arg1, void *arg2, void *arg3, void *arg4); *
87 *******************************************************************************/
91 .long 0 /* catch type all */
92 .long calljava_xhandler /* handler pc */
93 .long calljava_xhandler /* end pc */
94 .long asm_calljavafunction /* start pc */
95 .long 1 /* extable size */
96 .long 0 /* line number table start */
97 .long 0 /* line number table size */
102 .long 24 /* frame size */
103 .long 0 /* method pointer (pointer to name) */
105 asm_calljavafunction:
106 asm_calljavafunction_int:
108 stw r0,LA_LR_OFFSET(r1)
111 #if defined(__DARWIN__)
112 stw itmp1,10*4(sp) /* register r11 is callee saved */
114 stw pv,11*4(sp) /* save PV register */
116 stw itmp3,12*4(sp) /* registers r14-r31 are callee saved */
117 stfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
120 #if defined(__DARWIN__)
136 SAVE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
146 #if defined(__DARWIN__)
147 lis mptr,ha16(asm_call_jit_compiler)
148 addi mptr,mptr,lo16(asm_call_jit_compiler)
150 lis mptr,asm_call_jit_compiler@ha
151 addi mptr,mptr,asm_call_jit_compiler@l
162 #if defined(__DARWIN__)
163 addi pv,itmp1,lo16(asm_calljavafunction-1b)
165 addi pv,itmp1,(asm_calljavafunction-1b)@l
168 L_asm_calljavafunction_restore:
169 #if defined(__DARWIN__)
170 lwz itmp1,10*4(sp) /* register r11 is callee saved */
172 lwz pv,11*4(sp) /* save PV register */
175 lfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
178 #if defined(__DARWIN__)
194 RESTORE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
197 lwz r0,40*4+LA_LR_OFFSET(r1)
204 bl builtin_throw_exception
205 li v0,0 /* return NULL */
206 b L_asm_calljavafunction_restore
213 .long 0 /* catch type all */
214 .long calljava_xhandler2 /* handler pc */
215 .long calljava_xhandler2 /* end pc */
216 .long asm_calljavafunction2 /* start pc */
217 .long 1 /* extable size */
218 .long 0 /* line number table start */
219 .long 0 /* line number table size */
220 .long 0 /* fltsave */
221 .long 0 /* intsave */
224 .long 24 /* frame size */
225 .long 0 /* method pointer (pointer to name) */
227 asm_calljavafunction2:
228 asm_calljavafunction2int:
229 asm_calljavafunction2long:
230 asm_calljavafunction2float:
231 asm_calljavafunction2double:
233 stw r0,LA_LR_OFFSET(r1)
236 #if defined(__DARWIN__)
237 stw itmp1,10*4(sp) /* register r11 is callee saved */
239 stw pv,11*4(sp) /* save PV register */
241 stw itmp3,12*4(sp) /* registers r14-r31 are callee saved */
242 stfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
245 #if defined(__DARWIN__)
261 SAVE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
264 stw r3,36(r1) /* save method pointer for compiler */
265 mr itmp1,r6 /* pointer to arg block */
266 mr itmp2,r4 /* arg count */
268 addi itmp1,itmp1,-sizejniblock /* initialize pointer (smaller code) */
269 addi itmp2,itmp2,1 /* initialize argument count */
270 li r17,0 /* initialize integer argument counter */
271 li r18,0 /* initialize float argument counter */
274 addi itmp1,itmp1,sizejniblock /* goto next argument block */
275 addi itmp2,itmp2,-1 /* argument count - 1 */
277 beq L_register_copy_done
279 lwz itmp3,offjniitemtype+4(itmp1)
280 andi. r0,itmp3,0x0002 /* is this a float/double type? */
281 bne L_register_handle_float
283 cmpwi r17,INT_ARG_CNT /* are we out of integer argument */
284 beq L_register_copy /* registers? yes, next loop */
286 andi. r0,itmp3,0x0001 /* is this a long type? */
287 bne L_register_handle_long
289 L_register_handle_int:
290 #if defined(__DARWIN__)
291 lis itmp3,ha16(jumptable_int)
292 addi itmp3,itmp3,lo16(jumptable_int)
294 lis itmp3,jumptable_int@ha
295 addi itmp3,itmp3,jumptable_int@l
297 slwi r19,r17,2 /* multiple of 4-bytes */
298 add itmp3,itmp3,r19 /* calculate address of jumptable */
299 lwz itmp3,0(itmp3) /* load function address */
300 addi r17,r17,1 /* integer argument counter + 1 */
304 L_register_handle_long:
305 #if defined(__DARWIN__)
306 lis itmp3,ha16(jumptable_long)
307 addi itmp3,itmp3,lo16(jumptable_long)
309 lis itmp3,jumptable_long@ha
310 addi itmp3,itmp3,jumptable_long@l
312 addi r19,r17,1 /* align to even numbers */
315 slwi r19,r19,2 /* multiple of 4-bytes */
316 add itmp3,itmp3,r19 /* calculate address of jumptable */
317 lwz itmp3,0(itmp3) /* load function address */
318 addi r17,r17,1 /* integer argument counter + 1 */
322 L_register_handle_float:
323 L_register_copy_done:
327 #if defined(__DARWIN__)
328 lis mptr,ha16(asm_call_jit_compiler)
329 addi mptr,mptr,lo16(asm_call_jit_compiler)
331 lis mptr,asm_call_jit_compiler@ha
332 addi mptr,mptr,asm_call_jit_compiler@l
342 #if defined(__DARWIN__)
343 addi pv,itmp1,lo16(asm_calljavafunction2-1b)
345 addi pv,itmp1,(asm_calljavafunction2-1b)@l
348 L_asm_calljavafunction2_restore:
349 #if defined(__DARWIN__)
350 lwz itmp1,10*4(sp) /* register r11 is callee saved */
352 lwz pv,11*4(sp) /* save PV register */
355 lfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
358 #if defined(__DARWIN__)
374 RESTORE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
377 lwz r0,40*4+LA_LR_OFFSET(r1)
384 bl builtin_throw_exception
385 li v0,0 /* return NULL */
386 b L_asm_calljavafunction2_restore
400 lwz a0,offjniitem+4(itmp1)
403 lwz a1,offjniitem+4(itmp1)
406 lwz a2,offjniitem+4(itmp1)
409 lwz a3,offjniitem+4(itmp1)
412 lwz a4,offjniitem+4(itmp1)
415 lwz a5,offjniitem+4(itmp1)
418 lwz a6,offjniitem+4(itmp1)
421 lwz a7,offjniitem+4(itmp1)
426 #if defined(__DARWIN__)
428 /* we have two entries here, so we get the even argument register
429 alignment for linux */
442 lwz a0,offjniitem+0(itmp1)
443 lwz a1,offjniitem+4(itmp1)
446 lwz a2,offjniitem+0(itmp1)
447 lwz a3,offjniitem+4(itmp1)
450 lwz a4,offjniitem+0(itmp1)
451 lwz a5,offjniitem+4(itmp1)
454 lwz a6,offjniitem+0(itmp1)
455 lwz a7,offjniitem+4(itmp1)
459 /* asm_call_jit_compiler *******************************************************
461 Invokes the compiler for untranslated JavaVM methods.
463 *******************************************************************************/
465 asm_call_jit_compiler:
467 stw r0,LA_LR_OFFSET(r1) /* save return address */
468 stwu r1,-((LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo)(r1)
469 stw itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
471 mr itmp1,r0 /* save return address to other reg. */
489 stw mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
491 #if defined(__DARWIN__)
492 stw a0,(LA_WORD_SIZE+5+0)*4(r1)
493 stw a1,(LA_WORD_SIZE+5+1)*4(r1)
494 stw a2,(LA_WORD_SIZE+5+2)*4(r1)
495 stw a3,(LA_WORD_SIZE+5+3)*4(r1)
496 stw a4,(LA_WORD_SIZE+5+4)*4(r1)
497 stw a5,(LA_WORD_SIZE+5+5)*4(r1)
498 stw a6,(LA_WORD_SIZE+5+6)*4(r1)
499 stw a7,(LA_WORD_SIZE+5+7)*4(r1)
501 stfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
502 stfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
503 stfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
504 stfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
505 stfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
506 stfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
507 stfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
508 stfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
509 stfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
510 stfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
511 stfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
512 stfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
513 stfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
515 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
518 addi a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
519 li a1,0 /* we don't have pv handy */
520 addi a2,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
521 lwz a3,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(sp)
522 mr a4,a3 /* xpc is equal to ra */
523 bl stacktrace_create_extern_stackframeinfo
525 lwz itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 1*4)(r1)
527 bl jit_compile /* compile the Java method */
528 mr pv,r3 /* move address to pv register */
530 addi a0,sp,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)
531 bl stacktrace_remove_stackframeinfo
533 #if defined(__DARWIN__)
534 lwz a0,(LA_WORD_SIZE+5+0)*4(r1)
535 lwz a1,(LA_WORD_SIZE+5+1)*4(r1)
536 lwz a2,(LA_WORD_SIZE+5+2)*4(r1)
537 lwz a3,(LA_WORD_SIZE+5+3)*4(r1)
538 lwz a4,(LA_WORD_SIZE+5+4)*4(r1)
539 lwz a5,(LA_WORD_SIZE+5+5)*4(r1)
540 lwz a6,(LA_WORD_SIZE+5+6)*4(r1)
541 lwz a7,(LA_WORD_SIZE+5+7)*4(r1)
543 lfd fa0,(LA_WORD_SIZE+5+8)*4(r1)
544 lfd fa1,(LA_WORD_SIZE+5+10)*4(r1)
545 lfd fa2,(LA_WORD_SIZE+5+12)*4(r1)
546 lfd fa3,(LA_WORD_SIZE+5+14)*4(r1)
547 lfd fa4,(LA_WORD_SIZE+5+16)*4(r1)
548 lfd fa5,(LA_WORD_SIZE+5+18)*4(r1)
549 lfd fa6,(LA_WORD_SIZE+5+20)*4(r1)
550 lfd fa7,(LA_WORD_SIZE+5+22)*4(r1)
551 lfd fa8,(LA_WORD_SIZE+5+24)*4(r1)
552 lfd fa9,(LA_WORD_SIZE+5+26)*4(r1)
553 lfd fa10,(LA_WORD_SIZE+5+28)*4(r1)
554 lfd fa11,(LA_WORD_SIZE+5+30)*4(r1)
555 lfd fa12,(LA_WORD_SIZE+5+32)*4(r1)
557 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1)
560 lwz mptr,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 2*4)(r1)
562 lwz itmp1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo+LA_LR_OFFSET(r1)
564 addi r1,r1,(LA_SIZE + 5*4 + INT_ARG_CNT*4 + FLT_ARG_CNT*8 + 3*4)+sizestackframeinfo
566 mr. pv,pv /* test for exception */
567 beq L_asm_call_jit_compiler_exception
572 stw pv,0(mptr) /* store method address */
574 mtctr pv /* move method address to control reg */
575 bctr /* and call the Java method */
577 L_asm_call_jit_compiler_exception:
578 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
580 stw r0,LA_LR_OFFSET(sp)
581 stwu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
582 bl builtin_asm_get_exceptionptrptr
583 lwz r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
585 addi sp,sp,LA_SIZE_ALIGNED
587 # if defined(__DARWIN__)
588 lwz v0,lo16(_no_threads_exceptionptr-0b)(pv)
590 lis v0,_no_threads_exceptionptr@ha
591 addi v0,v0,_no_threads_exceptionptr@l
594 lwz xptr,0(v0) /* get the exception pointer */
596 stw itmp3,0(v0) /* clear the exception pointer */
600 b asm_handle_nat_exception
603 /********************* function asm_handle_exception ***************************
605 * This function handles an exception. It does not use the usual calling *
606 * conventions. The exception pointer is passed in REG_ITMP1 and the *
607 * pc from the exception raising position is passed in REG_ITMP2. It searches *
608 * the local exception table for a handler. If no one is found, it unwinds *
609 * stacks and continues searching the callers. *
611 * void asm_handle_exception (exceptionptr, exceptionpc); *
613 *******************************************************************************/
615 asm_handle_nat_exception:
623 bne asm_handle_exception
628 asm_handle_exception:
651 addi r1,r1,-4*4 /* allocate stack */
652 stw xptr,0*4(r1) /* save used register */
658 lwz r3,0*4(r1) /* exception pointer */
659 lwz r4,MethodPointer(pv) /* method pointer */
660 mr r5,xpc /* exception pc */
662 li r6,0 /* line number */
663 li r7,4 /* set no unwind flag */
665 /* XXX no valid stack frame chaining here */
666 addi r1,r1,-(24+5*4) /* 24 linkage area + 5 argument * 4 */
667 bl builtin_trace_exception
672 lwz xptr,0*4(r1) /* restore xptr */
677 lwz r3,ExTableSize(pv) /* r3 = exception table size */
678 mr. r3,r3 /* if empty table skip */
681 addi r4,pv,ExTableStart /* r4 = start of exception table */
684 lwz r5,ExStartPC(r4) /* r5 = exception start pc */
685 cmplw r5,xpc /* (startpc <= xpc) */
687 lwz r5,ExEndPC(r4) /* r5 = exception end pc */
688 cmplw xpc,r5 /* (xpc < endpc) */
690 lwz r7,ExCatchType(r4) /* r7 = exception catch type */
694 lwz itmp3,offclassloaded(r7)
698 /* XXX no valid stack frame chaining here */
699 addi r1,r1,-16*4 /* allocate stack */
700 stw r3,7*4(r1) /* save used registers */
701 stw r4,8*4(r1) /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save) */
709 mr r3,r7 /* arg1 = exceptionclass */
710 bl load_class_bootstrap
723 lwz itmp3,offclasslinked(r7)
725 /* XXX no valid stack frame chaining here */
726 addi r1,r1,-16*4 /* allocate stack */
730 stw r3,7*4(r1) /* save used registers */
731 stw r4,8*4(r1) /* 6*4 (linkage) + 1*4 (arg1) + 7*4 (save) */
738 mr r3,r7 /* arg1 = exceptionclass */
753 lwz r6,offobjvftbl(xptr) /* r6 = vftblptr(xptr) */
754 lwz r7,offclassvftbl(r7) /* r7 = vftblptr(catchtype) class (not obj) */
755 lwz r6,offbaseval(r6) /* r6 = baseval(xptr) */
756 lwz r8,offbaseval(r7) /* r8 = baseval(catchtype) */
757 lwz r7,offdiffval(r7) /* r7 = diffval(catchtype) */
759 subf r6,r8,r6 /* r6 = baseval(xptr) - baseval(catchtype) */
760 cmplw r6,r7 /* xptr is instanceof catchtype */
762 bgt ex_table_cont /* if (false) continue */
765 lwz xpc,ExHandlerPC(r4) /* xpc = exception handler pc */
794 addi r4,r4,ExEntrySize /* next exception table entry */
795 addic. r3,r3,-1 /* decrement entry counter */
796 bgt ex_table_loop /* if (t0 > 0) next entry */
799 mr. r9,r9 /* if here the first time, then */
800 beq ex_already_cleared
801 addi r1,r1,18*4 /* deallocate stack and */
802 li r9,0 /* clear the no unwind flag */
804 lwz r3,IsSync(pv) /* t0 = SyncOffset */
806 beq no_monitor_exit /* if zero no monitorexit */
808 #if defined(USE_THREADS)
822 /* XXX no valid stack frame chaining here */
824 bl builtin_monitorexit
838 lwz r3,FrameSize(pv) /* r3 = frame size */
839 add r1,r1,r3 /* unwind stack */
840 mr r3,r1 /* r3 = pointer to save area */
841 lwz r4,IsLeaf(pv) /* r4 = is leaf procedure */
843 bne ex_no_restore /* if (leaf) skip */
844 lwz r4,LA_LR_OFFSET(r3) /* restore ra */
847 mflr r4 /* the new xpc is ra */
849 lwz r4,IntSave(pv) /* r4 = saved int register count */
853 #if defined(__DARWIN__)
854 addi r5,r5,lo16(ex_int2-ex_int1)
856 addi r5,r5,(ex_int2-ex_int1)@l
880 #if defined(__DARWIN__)
881 addi r5,r5,lo16(ex_flt2-ex_flt1)
883 addi r5,r5,(ex_flt2-ex_flt1)@l
915 /* asm_wrapper_patcher *********************************************************
920 20 return address into JIT code (patch position)
921 16 pointer to virtual java_objectheader
922 12 machine code (which is patched back later)
923 8 unresolved class/method/field reference
924 4 data segment displacement from load instructions
925 0 patcher function pointer to call (pv is saved here afterwards)
927 *******************************************************************************/
930 mflr r0 /* get Java return address (leaf) */
931 stw r0,6*4(sp) /* store it in the stub stackframe */
932 /* keep stack 16-bytes aligned: 6+1+37 = 44 */
933 stwu sp,-(LA_SIZE+(5+58)*4+sizestackframeinfo)(sp)
935 #if defined(__DARWIN__)
936 stw a0,LA_SIZE+(5+0)*4(r1) /* save argument registers */
937 stw a1,LA_SIZE+(5+1)*4(r1) /* preserve linkage area (24 bytes) */
938 stw a2,LA_SIZE+(5+2)*4(r1) /* and 4 bytes for 4 argument */
939 stw a3,LA_SIZE+(5+3)*4(r1)
940 stw a4,LA_SIZE+(5+4)*4(r1)
941 stw a5,LA_SIZE+(5+5)*4(r1)
942 stw a6,LA_SIZE+(5+6)*4(r1)
943 stw a7,LA_SIZE+(5+7)*4(r1)
945 stfd fa0,LA_SIZE+(5+8)*4(sp)
946 stfd fa1,LA_SIZE+(5+10)*4(sp)
947 stfd fa2,LA_SIZE+(5+12)*4(sp)
948 stfd fa3,LA_SIZE+(5+14)*4(sp)
949 stfd fa4,LA_SIZE+(5+16)*4(sp)
950 stfd fa5,LA_SIZE+(5+18)*4(sp)
951 stfd fa6,LA_SIZE+(5+20)*4(sp)
952 stfd fa7,LA_SIZE+(5+22)*4(sp)
953 stfd fa8,LA_SIZE+(5+24)*4(sp)
954 stfd fa9,LA_SIZE+(5+26)*4(sp)
955 stfd fa10,LA_SIZE+(5+28)*4(sp)
956 stfd fa11,LA_SIZE+(5+30)*4(sp)
957 stfd fa12,LA_SIZE+(5+32)*4(sp)
959 stw t0,(LA_WORD_SIZE+5+33)*4(r1)
960 stw t1,(LA_WORD_SIZE+5+34)*4(r1)
961 stw t2,(LA_WORD_SIZE+5+35)*4(r1)
962 stw t3,(LA_WORD_SIZE+5+36)*4(r1)
963 stw t4,(LA_WORD_SIZE+5+37)*4(r1)
964 stw t5,(LA_WORD_SIZE+5+38)*4(r1)
965 stw t6,(LA_WORD_SIZE+5+39)*4(r1)
966 stw t7,(LA_WORD_SIZE+5+40)*4(r1)
968 stfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
969 stfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
970 stfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
971 stfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
972 stfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
973 stfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
975 SAVE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* save 8 int/8 float arguments */
976 SAVE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
979 stw itmp1,LA_SIZE+(5+54)*4(sp)
980 stw itmp2,LA_SIZE+(5+55)*4(sp)
981 stw pv,LA_SIZE+(5+56)*4(sp)
983 addi a0,sp,LA_SIZE+(5+58)*4 /* create stackframe info */
985 addi a2,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
986 mr a3,r0 /* this is correct for leafs */
987 lwz a4,((5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo)(sp) /* pass xpc */
988 bl stacktrace_create_extern_stackframeinfo
990 addi a0,sp,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo /* pass sp */
991 lwz pv,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* get function */
992 lwz itmp1,LA_SIZE+(5+56)*4(sp) /* move pv to position of fp */
993 stw itmp1,(0+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
994 mtctr pv /* call the patcher function */
996 stw v0,LA_SIZE+(5+57)*4(sp) /* save return value */
998 addi a0,sp,LA_SIZE+(5+58)*4
999 bl stacktrace_remove_stackframeinfo /* remove stackframe info */
1001 #if defined(__DARWIN__)
1002 lwz a0,LA_SIZE+(5+0)*4(r1)
1003 lwz a1,LA_SIZE+(5+1)*4(r1)
1004 lwz a2,LA_SIZE+(5+2)*4(r1)
1005 lwz a3,LA_SIZE+(5+3)*4(r1)
1006 lwz a4,LA_SIZE+(5+4)*4(r1)
1007 lwz a5,LA_SIZE+(5+5)*4(r1)
1008 lwz a6,LA_SIZE+(5+6)*4(r1)
1009 lwz a7,LA_SIZE+(5+7)*4(r1)
1011 lfd fa0,LA_SIZE+(5+8)*4(sp)
1012 lfd fa1,LA_SIZE+(5+10)*4(sp)
1013 lfd fa2,LA_SIZE+(5+12)*4(sp)
1014 lfd fa3,LA_SIZE+(5+14)*4(sp)
1015 lfd fa4,LA_SIZE+(5+16)*4(sp)
1016 lfd fa5,LA_SIZE+(5+18)*4(sp)
1017 lfd fa6,LA_SIZE+(5+20)*4(sp)
1018 lfd fa7,LA_SIZE+(5+22)*4(sp)
1019 lfd fa8,LA_SIZE+(5+24)*4(sp)
1020 lfd fa9,LA_SIZE+(5+26)*4(sp)
1021 lfd fa10,LA_SIZE+(5+28)*4(sp)
1022 lfd fa11,LA_SIZE+(5+30)*4(sp)
1023 lfd fa12,LA_SIZE+(5+32)*4(sp)
1025 lwz t0,(LA_WORD_SIZE+5+33)*4(r1)
1026 lwz t1,(LA_WORD_SIZE+5+34)*4(r1)
1027 lwz t2,(LA_WORD_SIZE+5+35)*4(r1)
1028 lwz t3,(LA_WORD_SIZE+5+36)*4(r1)
1029 lwz t4,(LA_WORD_SIZE+5+37)*4(r1)
1030 lwz t5,(LA_WORD_SIZE+5+38)*4(r1)
1031 lwz t6,(LA_WORD_SIZE+5+39)*4(r1)
1032 lwz t7,(LA_WORD_SIZE+5+40)*4(r1)
1034 lfd ft0,(LA_WORD_SIZE+5+42)*4(r1)
1035 lfd ft1,(LA_WORD_SIZE+5+44)*4(r1)
1036 lfd ft2,(LA_WORD_SIZE+5+46)*4(r1)
1037 lfd ft3,(LA_WORD_SIZE+5+48)*4(r1)
1038 lfd ft4,(LA_WORD_SIZE+5+50)*4(r1)
1039 lfd ft5,(LA_WORD_SIZE+5+52)*4(r1)
1041 RESTORE_ARGUMENT_REGISTERS(LA_WORD_SIZE+1) /* restore 8 int/8 float args */
1042 RESTORE_TEMPORARY_REGISTERS(LA_WORD_SIZE+1+24)
1045 lwz itmp1,LA_SIZE+(5+54)*4(sp)
1046 lwz itmp2,LA_SIZE+(5+55)*4(sp)
1047 lwz pv,LA_SIZE+(5+56)*4(sp)
1048 lwz itmp3,LA_SIZE+(5+57)*4(sp) /* restore return value into temp reg.*/
1050 lwz r0,(6+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp) /* restore RA */
1053 mr. itmp3,itmp3 /* check for an exception */
1054 beq L_asm_wrapper_patcher_exception
1056 /* get return address (into JIT code) */
1057 lwz itmp3,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
1059 /* remove stack frame + patcher stub stack */
1060 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
1063 bctr /* jump to new patched code */
1065 L_asm_wrapper_patcher_exception:
1066 lwz xpc,(5+LA_WORD_SIZE+5+58)*4+sizestackframeinfo(sp)
1067 addi sp,sp,(8+LA_WORD_SIZE+5+58)*4+sizestackframeinfo
1069 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1071 stw r0,LA_LR_OFFSET(sp)
1072 stwu sp,-(LA_SIZE+1*4)(sp) /* preserve linkage area */
1073 stw xpc,LA_SIZE+0*4(sp)
1074 bl builtin_asm_get_exceptionptrptr
1075 lwz xpc,LA_SIZE+0*4(sp)
1076 lwz r0,LA_SIZE+1*4+LA_LR_OFFSET(sp)
1078 addi sp,sp,LA_SIZE+1*4
1080 # if defined(__DARWIN__)
1081 lwz v0,lo16(_no_threads_exceptionptr-0b)(pv)
1083 lis v0,_no_threads_exceptionptr@ha
1084 addi v0,v0,_no_threads_exceptionptr@l
1088 lwz xptr,0(v0) /* get the exception pointer */
1090 stw itmp3,0(v0) /* clear the exception pointer */
1091 b asm_handle_exception
1124 asm_initialize_thread_stack:
1154 #if defined(__DARWIN__)
1155 lfd fr0,lo16(doublezero-0b)(r3)
1157 lfd fr0,(doublezero-0b)@l(r3)
1184 asm_perform_threadswitch:
1276 asm_switchstackandcall:
1294 asm_getclassvalues_atomic:
1297 lwz r6,offbaseval(r3)
1298 lwz r7,offdiffval(r3)
1299 lwz r8,offbaseval(r4)
1301 stw r6,offcast_super_baseval(r5)
1302 stw r7,offcast_super_diffval(r5)
1303 stw r8,offcast_sub_baseval(r5)
1308 asm_criticalsections:
1309 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1312 .long _crit_restart1
1315 .long _crit_restart2
1321 * These are local overrides for various environment variables in Emacs.
1322 * Please do not remove this and leave it at the end of the file, where
1323 * Emacs will automagically detect them.
1324 * ---------------------------------------------------------------------
1327 * indent-tabs-mode: t