1 /* src/vm/jit/powerpc/asmpart.S - Java-C interface functions for PowerPC
3 Copyright (C) 1996-2005, 2006, 2007 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
33 #include "vm/jit/abi-asm.h"
34 #include "vm/jit/methodheader.h"
42 /* export functions ***********************************************************/
44 .globl asm_vm_call_method
45 .globl asm_vm_call_method_int
46 .globl asm_vm_call_method_long
47 .globl asm_vm_call_method_float
48 .globl asm_vm_call_method_double
50 .globl asm_vm_call_method_exception_handler
51 .globl asm_vm_call_method_end
53 .globl asm_handle_nat_exception
54 .globl asm_handle_exception
56 .globl asm_abstractmethoderror
60 .globl asm_compare_and_swap
61 .globl asm_memory_barrier
64 /* asm_vm_call_method **********************************************************
66 * This function calls a Java-method (which possibly needs compilation) *
67 * with up to 4 address parameters. *
69 * This functions calls the JIT-compiler which eventually translates the *
70 * method into machine code. *
73 * javaobject_header *asm_calljavamethod (methodinfo *m, *
74 * void *arg1, void *arg2, void *arg3, void *arg4); *
76 *******************************************************************************/
80 .long 0 /* catch type all */
81 .long 0 /* exception handler pc */
83 .long 0 /* start pc */
84 .long 1 /* extable size */
85 .long 0 /* line number table start */
86 .long 0 /* line number table size */
90 .long 0 /* frame size */
91 .long 0 /* codeinfo pointer */
94 asm_vm_call_method_int:
95 asm_vm_call_method_long:
96 asm_vm_call_method_float:
97 asm_vm_call_method_double:
99 stw r0,LA_LR_OFFSET(sp)
100 stwu sp,-40*4(sp) /* keep stack 16-byte aligned */
102 stw s0,8*4(sp) /* save used callee saved registers */
104 #if defined(__DARWIN__)
105 stw itmp1,10*4(sp) /* register r11 is callee saved */
107 stw pv,11*4(sp) /* save PV register */
109 stw itmp3,12*4(sp) /* registers r14-r31 are callee saved */
110 stfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
113 #if defined(__DARWIN__)
129 SAVE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
132 mr pv,a0 /* move PV into PV register */
133 mtctr pv /* move PV into branch register */
135 mr t0,a1 /* address of data structure */
136 mr t1,a2 /* stack argument count */
138 mr s0,sp /* save SP */
140 lwz a0,0*8+4(t0) /* we are on big-endian */
158 #if defined(__DARWIN__)
167 beq L_asm_vm_call_method_stack_copy_done
169 slwi t2,t1,3 /* calculate stackframe size (* 8) */
171 sub sp,sp,t2 /* create stackframe */
172 mr t2,sp /* temporary stack pointer */
174 L_asm_vm_call_method_stack_copy_loop:
175 #if defined(__DARWIN__)
176 lwz t3,21*8+0(t0) /* load argument */
179 lwz t3,16*8+0(t0) /* load argument */
182 stw t3,0(t2) /* store argument on stack */
185 addi t0,t0,8 /* load address of next argument */
186 addi t2,t2,8 /* increase stack pointer */
187 addi t1,t1,-1 /* subtract 1 argument */
189 bgt L_asm_vm_call_method_stack_copy_loop
191 L_asm_vm_call_method_stack_copy_done:
195 #if defined(__DARWIN__)
196 addi pv,itmp1,lo16(asm_vm_call_method - 1b)
198 addi pv,itmp1,(asm_vm_call_method - 1b)@l
201 L_asm_vm_call_method_return:
202 mr sp,s0 /* restore the SP */
204 lwz s0,8*4(sp) /* restore used callee saved registers*/
206 #if defined(__DARWIN__)
207 lwz itmp1,10*4(sp) /* register r11 is callee saved */
209 lwz pv,11*4(sp) /* save PV register */
212 lfd ftmp1,14*4(sp) /* registers f14-f31 are callee saved */
215 #if defined(__DARWIN__)
231 RESTORE_TEMPORARY_REGISTERS(18) /* the offset has to be even */
234 lwz r0,40*4+LA_LR_OFFSET(sp)
239 asm_vm_call_method_exception_handler:
241 bl builtin_throw_exception
242 b L_asm_vm_call_method_return
244 asm_vm_call_method_end:
248 /********************* function asm_handle_exception ***************************
250 * This function handles an exception. It does not use the usual calling *
251 * conventions. The exception pointer is passed in REG_ITMP1 and the *
252 * pc from the exception raising position is passed in REG_ITMP2. It searches *
253 * the local exception table for a handler. If no one is found, it unwinds *
254 * stacks and continues searching the callers. *
256 * void asm_handle_exception (exceptionptr, exceptionpc); *
258 *******************************************************************************/
260 asm_handle_nat_exception:
261 L_asm_handle_nat_exception: /* required for PIC code */
262 L_asm_handle_exception_stack_loop:
264 addi sp,sp,-(LA_SIZE+((4+6)*4)) /* allocate stack (+4 for darwin) */
265 stw xptr,LA_SIZE+(4+0)*4(sp) /* save exception pointer */
266 stw xpc,LA_SIZE+(4+1)*4(sp) /* save exception pc */
267 stw r0,LA_SIZE+(4+3)*4(sp) /* save return address */
269 stw itmp3,LA_SIZE+(4+4)*4(sp) /* save maybe-leaf flag (cleared) */
271 mr a0,r0 /* pass return address */
272 bl md_codegen_get_pv_from_pc /* get PV from RA */
273 stw v0,LA_SIZE+(4+2)*4(sp) /* save data segment pointer */
275 lwz a0,LA_SIZE+(4+0)*4(sp) /* pass xptr */
276 lwz a1,LA_SIZE+(4+1)*4(sp) /* pass xpc */
277 lwz a2,LA_SIZE+(4+2)*4(sp) /* pass PV (v0 == a0) */
278 addi a3,sp,LA_SIZE+((4+6)*4) /* pass Java SP */
280 b L_asm_handle_exception_continue
282 asm_handle_exception:
283 L_asm_handle_exception: /* required for PIC code */
284 addi sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
286 #if defined(__DARWIN__)
288 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
289 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
292 addi sp,sp,-(LA_SIZE+(4+6)*4) /* allocate stack */
293 stw xptr,LA_SIZE+(4+0)*4(sp) /* save xptr */
294 stw pv,LA_SIZE+(4+2)*4(sp) /* save PV */
295 mflr r0 /* save RA */
296 stw r0,LA_SIZE+(4+3)*4(sp)
297 li t0,1 /* set maybe-leaf flag */
298 stw t0,LA_SIZE+(4+4)*4(sp) /* save maybe-leaf flag */
300 mr a0,xptr /* pass exception pointer */
301 mr a1,xpc /* pass exception pc */
302 mr a2,pv /* pass data segment pointer */
303 addi a3,sp,LA_SIZE+(ARG_CNT+TMP_CNT)*8+(4+6)*4
305 L_asm_handle_exception_continue:
306 bl exceptions_handle_exception
309 beq L_asm_handle_exception_not_catched
311 mr xpc,v0 /* move handlerpc into xpc */
312 lwz xptr,LA_SIZE+(4+0)*4(sp) /* restore xptr */
313 lwz pv,LA_SIZE+(4+2)*4(sp) /* restore PV */
314 lwz r0,LA_SIZE+(4+3)*4(sp) /* restore RA */
316 lwz t0,LA_SIZE+(4+4)*4(sp) /* get maybe-leaf flag */
317 addi sp,sp,LA_SIZE+(4+6)*4 /* free stack frame */
320 beq L_asm_handle_exception_no_leaf
322 #if defined(__DARWIN__)
324 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
325 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
328 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
330 L_asm_handle_exception_no_leaf:
331 mtctr xpc /* jump to the handler */
334 L_asm_handle_exception_not_catched:
335 lwz xptr,LA_SIZE+(4+0)*4(sp) /* restore xptr */
336 lwz pv,LA_SIZE+(4+2)*4(sp) /* restore PV */
337 lwz r0,LA_SIZE+(4+3)*4(sp) /* restore RA */
339 lwz t0,LA_SIZE+(4+4)*4(sp) /* get maybe-leaf flag */
340 addi sp,sp,LA_SIZE+(4+6)*4 /* free stack frame */
343 beq L_asm_handle_exception_no_leaf_stack
345 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
346 li t0,0 /* clear the maybe-leaf flag */
348 L_asm_handle_exception_no_leaf_stack:
349 lwz t1,FrameSize(pv) /* get frame size */
350 add t1,sp,t1 /* pointer to save area */
352 lwz t2,IsLeaf(pv) /* is leaf procedure */
354 bne L_asm_handle_exception_no_ra_restore
356 lwz r0,LA_LR_OFFSET(t1) /* restore ra */
359 L_asm_handle_exception_no_ra_restore:
360 mflr xpc /* the new xpc is ra */
361 mr t4,xpc /* save RA */
362 lwz t2,IntSave(pv) /* t2 = saved int register count */
365 mflr t3 /* t3 = current pc */
366 #if defined(__DARWIN__)
367 addi t3,t3,lo16(ex_int2-ex_int1)
369 addi t3,t3,(ex_int2-ex_int1)@l
371 slwi t2,t2,2 /* t2 = register count * 4 */
372 subf t3,t2,t3 /* t3 = IntSave - t2 */
388 subf t1,t2,t1 /* t1 = t1 - register count * 4 */
394 #if defined(__DARWIN__)
395 addi t3,t3,lo16(ex_flt2-ex_flt1)
397 addi t3,t3,(ex_flt2-ex_flt1)@l
399 slwi t2,t2,2 /* t2 = register count * 4 */
400 subf t3,t2,t3 /* t3 = FltSave - t2 */
416 mtlr t4 /* restore RA */
417 lwz t1,FrameSize(pv) /* get frame size */
418 add sp,sp,t1 /* unwind stack */
419 b L_asm_handle_exception_stack_loop
422 /* asm_abstractmethoderror *****************************************************
424 Creates and throws an AbstractMethodError.
426 *******************************************************************************/
428 asm_abstractmethoderror:
430 stw r0,LA_LR_OFFSET(sp)
431 stwu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
432 addi a0,sp,LA_SIZE_ALIGNED /* pass java sp */
433 mr a1,r0 /* pass exception address */
434 bl exceptions_asm_new_abstractmethoderror
435 lwz r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
436 mtlr r0 /* restore return address */
437 addi sp,sp,LA_SIZE_ALIGNED
439 mr xptr,v0 /* get exception pointer */
440 mr xpc,r0 /* we can't use r0 directly in addi */
441 addi xpc,xpc,-4 /* exception address is ra - 4 */
442 b L_asm_handle_nat_exception
445 /*********************************************************************/
473 /* asm_compare_and_swap ********************************************************
477 *******************************************************************************/
479 asm_compare_and_swap:
492 /* asm_memory_barrier **********************************************************
496 *******************************************************************************/
503 #if defined(__DARWIN__)
505 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
507 L_builtin_throw_exception$stub:
508 .indirect_symbol _builtin_throw_exception
510 bcl 20,31,L00$_builtin_throw_exception
511 L00$_builtin_throw_exception:
513 addis r11,r11,ha16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)
515 lwzu r12,lo16(L_builtin_throw_exception$lazy_ptr - L00$_builtin_throw_exception)(r11)
520 L_builtin_throw_exception$lazy_ptr:
521 .indirect_symbol _builtin_throw_exception
522 .long dyld_stub_binding_helper
525 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
527 L_md_codegen_get_pv_from_pc$stub:
528 .indirect_symbol _md_codegen_get_pv_from_pc
530 bcl 20,31,L00$_md_codegen_get_pv_from_pc
531 L00$_md_codegen_get_pv_from_pc:
533 addis r11,r11,ha16(L_md_codegen_get_pv_from_pc$lazy_ptr - L00$_md_codegen_get_pv_from_pc)
535 lwzu r12,lo16(L_md_codegen_get_pv_from_pc$lazy_ptr - L00$_md_codegen_get_pv_from_pc)(r11)
540 L_md_codegen_get_pv_from_pc$lazy_ptr:
541 .indirect_symbol _md_codegen_get_pv_from_pc
542 .long dyld_stub_binding_helper
545 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
547 L_exceptions_handle_exception$stub:
548 .indirect_symbol _exceptions_handle_exception
550 bcl 20,31,L00$_exceptions_handle_exception
551 L00$_exceptions_handle_exception:
553 addis r11,r11,ha16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)
555 lwzu r12,lo16(L_exceptions_handle_exception$lazy_ptr - L00$_exceptions_handle_exception)(r11)
560 L_exceptions_handle_exception$lazy_ptr:
561 .indirect_symbol _exceptions_handle_exception
562 .long dyld_stub_binding_helper
565 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
567 L_exceptions_asm_new_abstractmethoderror$stub:
568 .indirect_symbol _exceptions_asm_new_abstractmethoderror
570 bcl 20,31,L00$_exceptions_asm_new_abstractmethoderror
571 L00$_exceptions_asm_new_abstractmethoderror:
573 addis r11,r11,ha16(L_exceptions_asm_new_abstractmethoderror$lazy_ptr - L00$_exceptions_asm_new_abstractmethoderror)
575 lwzu r12,lo16(L_exceptions_asm_new_abstractmethoderror$lazy_ptr - L00$_exceptions_asm_new_abstractmethoderror)(r11)
580 L_exceptions_asm_new_abstractmethoderror$lazy_ptr:
581 .indirect_symbol _exceptions_asm_new_abstractmethoderror
582 .long dyld_stub_binding_helper
584 #endif /* defined(__DARWIN__) */
587 /* disable exec-stacks ********************************************************/
589 #if defined(__linux__) && defined(__ELF__)
590 .section .note.GNU-stack,"",%progbits
595 * These are local overrides for various environment variables in Emacs.
596 * Please do not remove this and leave it at the end of the file, where
597 * Emacs will automagically detect them.
598 * ---------------------------------------------------------------------
601 * indent-tabs-mode: t
605 * vim:noexpandtab:sw=4:ts=4: