1 /* src/vm/jit/powerpc64/asmpart.S - Java-C interface functions for PowerPC64
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
35 #include "vm/jit/abi-asm.h"
36 #include "vm/jit/methodheader.h"
39 /* export functions ***********************************************************/
41 .globl asm_vm_call_method_exception_handler
42 .globl asm_vm_call_method_end
44 .globl asm_handle_nat_exception
45 .globl asm_handle_exception
47 .globl asm_abstractmethoderror
52 /* asm_vm_call_method **********************************************************
54 * This function calls a Java-method (which possibly needs compilation) *
55 * with up to 4 address parameters. *
57 * This functions calls the JIT-compiler which eventually translates the *
58 * method into machine code. *
61 * javaobject_header *asm_calljavamethod (methodinfo *m, *
62 * void *arg1, void *arg2, void *arg3, void *arg4); *
64 *******************************************************************************/
65 /* this is the method header see src/vm/jit/methodheader.h */
72 .long 0 /* frame size */
73 .quad 0 /* codeinfo pointer */
77 .globl asm_vm_call_method
78 .globl asm_vm_call_method_int
79 .globl asm_vm_call_method_long
80 .globl asm_vm_call_method_float
81 .globl asm_vm_call_method_double
86 asm_vm_call_method_int:
87 asm_vm_call_method_long:
88 asm_vm_call_method_float:
89 asm_vm_call_method_double:
90 .quad .asm_vm_call_method,.TOC.@tocbase,0
92 .size asm_vm_call_method, 24
93 .type .asm_vm_call_method,@function
94 .globl .asm_vm_call_method
97 .globl asm_vm_call_method
98 asm_vm_call_method_int:
99 .globl asm_vm_call_method_int
100 asm_vm_call_method_long:
101 .globl asm_vm_call_method_long
102 asm_vm_call_method_float:
103 .globl asm_vm_call_method_float
104 asm_vm_call_method_double:
105 .globl asm_vm_call_method_double
109 .asm_vm_call_method_int:
110 .asm_vm_call_method_long:
111 .asm_vm_call_method_float:
112 .asm_vm_call_method_double:
114 std r0,LA_LR_OFFSET(sp)
117 std s0,8*8(sp) /* save used callee saved registers */
118 std a0,9*8(sp) /* save method pointer for compiler */
120 std pv,11*8(sp) /* save PV register */
122 std itmp3,12*8(sp) /* registers r14-r31 are callee saved */
123 stfd ftmp1,13*8(sp) /* registers f14-f31 are callee saved */
127 SAVE_TEMPORARY_REGISTERS(15)
128 mr s0, sp /* save stack pointer */
130 /* a1 contains a pointer to a unit64_t structure filled with all INT_ARG_REG,
131 followed by ADR_ARG_CNT and FLT_ARG_CNT, afterwards what else needs to be copied onto
133 a2 contains the number of additional stack slots to be copied
164 beq L_stack_copy_done
167 addi t1,t1,20*8 /* before first possible stack slot arg */
168 mr t3,t2 /* argument counter */
169 sldi t2,t2,8 /* calculate size of stack */
170 sub sp,sp,t2 /* increase the stack */
171 mr t2,sp /* t2 points to bottom of stack now */
174 addi t1,t1,8 /* next possible stack slot to copy */
175 mr. t3,t3 /* more stack slots to copy ? */
176 beq L_stack_copy_done
184 mr itmp1, s0 /* fake invokevirtual invocation */
185 addi itmp1, itmp1, 9*8 /* address of methods pv */
191 addi pv,itmp1,(.asm_vm_call_method - 1b)@l
193 L_asm_vm_call_method_return:
194 mr sp,s0 /* restore the function's sp */
196 ld s0,8*8(sp) /* restore used callee saved registers */
198 ld pv,11*8(sp) /* save PV register */
201 lfd ftmp1,13*8(sp) /* registers f14-f31 are callee saved */
204 RESTORE_TEMPORARY_REGISTERS(15)
206 ld r0,40*8+LA_LR_OFFSET(sp)
211 asm_vm_call_method_exception_handler:
213 bl builtin_throw_exception
214 b L_asm_vm_call_method_return
216 asm_vm_call_method_end:
220 /********************* function asm_handle_exception ***************************
222 * This function handles an exception. It does not use the usual calling *
223 * conventions. The exception pointer is passed in REG_ITMP1 and the *
224 * pc from the exception raising position is passed in REG_ITMP2. It searches *
225 * the local exception table for a handler. If no one is found, it unwinds *
226 * stacks and continues searching the callers. *
228 * void asm_handle_exception (exceptionptr, exceptionpc); *
230 *******************************************************************************/
232 asm_handle_nat_exception:
233 L_asm_handle_nat_exception: /* required for PIC code */
234 L_asm_handle_exception_stack_loop:
236 addi sp,sp,-(LA_SIZE+PA_SIZE+((4+6)*8)) /* allocate stack (+4 for darwin) */
237 std xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* save exception pointer */
238 std xpc,LA_SIZE+PA_SIZE+(4+1)*8(sp) /* save exception pc */
239 std r0,LA_SIZE+PA_SIZE+(4+3)*8(sp) /* save return address */
241 std itmp3,LA_SIZE+PA_SIZE+(4+4)*8(sp) /* save maybe-leaf flag (cleared) */
243 mr a0,r0 /* pass return address */
244 bl md_asm_codegen_get_pv_from_pc /* get PV from RA */
245 std v0,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* save data segment pointer */
247 ld a0,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* pass xptr */
248 ld a1,LA_SIZE+PA_SIZE+(4+1)*8(sp) /* pass xpc */
249 ld a2,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* pass PV (v0 == a0) */
250 addi a3,sp,LA_SIZE+PA_SIZE+((4+6)*8) /* pass Java SP */
252 b L_asm_handle_exception_continue
255 asm_handle_exception:
256 L_asm_handle_exception: /* required for PIC code */
257 addi sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
259 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
260 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
262 addi sp,sp,-(LA_SIZE+PA_SIZE+(4+6)*8) /* allocate stack */
263 std xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* save exception pointer */
264 std pv,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* save data segment pointer */
265 mflr r0 /* save return address */
266 std r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)
268 std t0, LA_SIZE+PA_SIZE+(4+4)*8(sp) /* maybe-leaf flag */
270 mr a0,xptr /* pass exception pointer */
271 mr a1,xpc /* pass exception pc */
272 mr a2,pv /* pass data segment pointer */
273 addi a3,sp,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+(4+6)*8
276 L_asm_handle_exception_continue:
277 bl exceptions_handle_exception
280 beq L_asm_handle_exception_not_catched
282 mr xpc,v0 /* move handlerpc into xpc */
283 ld xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* restore exception pointer */
284 ld pv,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* restore data segment pointer */
285 ld r0,LA_SIZE+PA_SIZE+(4+3)*8(sp) /* restore return address */
287 ld t0,LA_SIZE+PA_SIZE+(4+4)*8(sp) /* get maybe-leaf flag */
288 addi sp,sp,LA_SIZE+PA_SIZE+(4+6)*8 /* free stack frame */
291 beq L_asm_handle_exception_no_leaf
293 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
294 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
296 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
298 L_asm_handle_exception_no_leaf:
299 mtctr xpc /* jump to the handler */
302 L_asm_handle_exception_not_catched:
303 ld xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* restore exception pointer */
304 ld pv,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* restore data segment pointer */
305 ld r0,LA_SIZE+PA_SIZE+(4+3)*8(sp) /* restore return address */
307 ld t0,LA_SIZE+PA_SIZE+(4+4)*8(sp) /* get maybe-leaf flag */
308 addi sp,sp,LA_SIZE+PA_SIZE+(4+6)*8 /* free stack frame */
311 beq L_asm_handle_exception_no_leaf_stack
313 addi sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
314 li t0,0 /* clear the maybe-leaf flag */
316 L_asm_handle_exception_no_leaf_stack:
317 lwz t1,FrameSize(pv) /* get frame size */
318 add t1,sp,t1 /* pointer to save area */
320 lwz t2,IsLeaf(pv) /* is leaf procedure */
322 bne L_asm_handle_exception_no_ra_restore
324 ld r0,LA_LR_OFFSET(t1) /* restore ra */
327 L_asm_handle_exception_no_ra_restore:
328 mflr xpc /* the new xpc is ra */
329 mr t4,xpc /* save RA */
330 lwz t2,IntSave(pv) /* t1 = saved int register count */
333 mflr t3 /* t3 = current pc */
334 addi t3,t3,(ex_int2-ex_int1)@l
335 slwi t2,t2,2 /* t2 = register count * 4 */
336 subf t3,t2,t3 /* t3 = IntSave - t2 */
351 subf t1,t2,t1 /* t1 = t1 - register count * 4 */
356 addi t3,t3,(ex_flt2-ex_flt1)@l
357 slwi t2,t2,2 /* t2 = register count * 4 */
358 subf t3,t2,t3 /* t3 = FltSave - t2 */
374 mtlr t4 /* restore RA */
376 add sp,sp,t1 /* unwind stack */
377 b L_asm_handle_exception_stack_loop
380 /* asm_abstractmethoderror *****************************************************
382 Creates and throws an AbstractMethodError.
384 *******************************************************************************/
386 asm_abstractmethoderror:
388 std r0,LA_LR_OFFSET(sp)
389 stdu sp,-LA_SIZE_ALIGNED(sp) /* preserve linkage area */
390 addi a0,sp,LA_SIZE_ALIGNED /* pass java sp */
391 mr a1,r0 /* pass exception address */
392 bl exceptions_asm_new_abstractmethoderror
393 ld r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
394 mtlr r0 /* restore return address */
395 addi sp,sp,LA_SIZE_ALIGNED
397 mr xptr,v0 /* get exception pointer */
398 mr xpc,r0 /* we can't use r0 directly in addi */
399 addi xpc,xpc,-4 /* exception address is ra - 4 */
400 b L_asm_handle_nat_exception
403 /* asm_cacheflush **************************************************************
404 assumes 128 byte cache line size.
405 All registers used may be trashed for fun and profit.
406 *******************************************************************************/
411 .quad .asm_cacheflush,.TOC.@tocbase,0
413 .size asm_cacheflush, 24
414 .type .asm_cacheflush,@function
415 .globl .asm_cacheflush
417 /* construct the AND mask */
418 li r6, 0xffffffffffff8000
419 ori r6,r6,0x000000000000ff80
446 /* disable exec-stacks ********************************************************/
448 #if defined(__linux__) && defined(__ELF__)
449 .section .note.GNU-stack,"",%progbits
454 * These are local overrides for various environment variables in Emacs.
455 * Please do not remove this and leave it at the end of the file, where
456 * Emacs will automagically detect them.
457 * ---------------------------------------------------------------------
460 * indent-tabs-mode: t
464 * vim:noexpandtab:sw=4:ts=4: