1 /* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
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; 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
30 #include "vm/jit/x86_64/arch.h"
31 #include "vm/jit/x86_64/md-abi.h"
32 #include "vm/jit/x86_64/md-asm.h"
34 #include "vm/jit/abi-asm.h"
35 #include "vm/jit/methodheader.h"
41 /* export functions ***********************************************************/
43 .globl asm_vm_call_method
44 .globl asm_vm_call_method_int
45 .globl asm_vm_call_method_long
46 .globl asm_vm_call_method_float
47 .globl asm_vm_call_method_double
48 .globl asm_vm_call_method_exception_handler
49 .globl asm_vm_call_method_end
51 .globl asm_call_jit_compiler
53 .globl asm_handle_exception
54 .globl asm_handle_nat_exception
56 .globl asm_abstractmethoderror
58 .globl asm_builtin_f2i
59 .globl asm_builtin_f2l
60 .globl asm_builtin_d2i
61 .globl asm_builtin_d2l
63 .globl asm_compare_and_swap
64 .globl asm_memory_barrier
67 /********************* function asm_calljavafunction ***************************
69 * This function calls a Java-method (which possibly needs compilation) *
70 * with up to 4 address parameters. *
72 * This functions calls the JIT-compiler which eventually translates the *
73 * method into machine code. *
76 * javaobject_header *asm_calljavamethod (methodinfo *m, *
77 * void *arg1, void *arg2, void *arg3, void *arg4); *
79 *******************************************************************************/
83 .quad 0 /* catch type all */
84 .quad 0 /* handler pc */
86 .quad 0 /* start pc */
87 .long 1 /* extable size */
88 .long 0 /* ALIGNMENT PADDING */
89 .quad 0 /* line number table start */
90 .quad 0 /* line number table size */
91 .long 0 /* ALIGNMENT PADDING */
96 .long 0 /* frame size */
97 .quad 0 /* codeinfo pointer */
100 asm_vm_call_method_int:
101 asm_vm_call_method_long:
102 asm_vm_call_method_float:
103 asm_vm_call_method_double:
104 sub $(7*8),sp /* keep stack 16-byte aligned */
105 mov %rbx,0*8(sp) /* %rbx is not a callee saved in cacao*/
112 mov a0,6*8(sp) /* store method PV */
114 mov sp,s0 /* save stack pointer */
116 mov a1,t0 /* address of data structure */
117 mov a2,itmp1 /* number of stack arguments */
136 je L_asm_vm_call_method_stack_copy_done
139 add $1,itmp2 /* keep stack 16-byte aligned */
140 and $0xfffffffffffffffe,itmp2
141 shl $3,itmp2 /* calculate stack size */
142 sub itmp2,sp /* create stack frame */
143 mov sp,itmp2 /* temporary stack pointer */
145 L_asm_vm_call_method_stack_copy_loop:
146 mov 14*8(t0),itmp3 /* load argument */
147 mov itmp3,0(itmp2) /* store argument on stack */
149 sub $1,itmp1l /* subtract 1 argument */
150 add $8,t0 /* set address of next argument */
151 add $8,itmp2 /* increase SP */
154 jg L_asm_vm_call_method_stack_copy_loop
156 L_asm_vm_call_method_stack_copy_done:
157 lea (6*8-256)(s0),mptr /* We subtract 256 to force the next */
158 /* move instruction to have a 32-bit */
161 mov (0*8+256)(mptr),itmp3 /* load PV */
164 mov s0,sp /* restore SP */
166 L_asm_vm_call_method_return:
167 mov 0*8(sp),%rbx /* restore callee saved registers */
173 add $(7*8),sp /* free stack space */
176 asm_vm_call_method_exception_handler:
177 mov xptr,a0 /* pass exception pointer */
178 call builtin_throw_exception@PLT
179 jmp L_asm_vm_call_method_return
181 asm_vm_call_method_end:
185 /****************** function asm_call_jit_compiler *****************************
187 * invokes the compiler for untranslated JavaVM methods. *
189 * Register R0 contains a pointer to the method info structure (prepared *
190 * by createcompilerstub). Using the return address in R26 and the *
191 * offset in the LDA instruction or using the value in methodptr R28 the *
192 * patching address for storing the method address can be computed: *
194 * method address was either loaded using *
196 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
197 * i386_call_reg(REG_ITMP2) *
201 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
202 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
203 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
204 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
205 * i386_call_reg(REG_ITMP1) *
207 * in the static case the method pointer can be computed using the *
208 * return address and the lda function following the jmp instruction *
210 *******************************************************************************/
212 asm_call_jit_compiler:
213 L_asm_call_jit_compiler: /* required for PIC code */
214 sub $(ARG_CNT+1)*8,sp /* +1: keep stack 16-byte aligned */
216 SAVE_ARGUMENT_REGISTERS(0)
218 mov itmp1,a0 /* pass methodinfo pointer */
219 mov mptr,a1 /* pass method pointer */
220 mov sp,a2 /* pass java sp */
221 add $(1+ARG_CNT+1)*8,a2
222 mov (ARG_CNT+1)*8(sp),a3 /* pass ra to java function */
223 call jit_asm_compile@PLT
225 RESTORE_ARGUMENT_REGISTERS(0)
227 add $(ARG_CNT+1)*8,sp /* remove stack frame */
229 test v0,v0 /* check for exception */
230 je L_asm_call_jit_compiler_exception
232 jmp *v0 /* ...and now call the new method */
234 L_asm_call_jit_compiler_exception:
235 call exceptions_get_and_clear_exception@PLT
236 pop xpc /* delete return address */
237 sub $3,xpc /* faulting address is ra - 3 */
238 jmp L_asm_handle_exception
241 /* asm_handle_exception ********************************************************
243 * This function handles an exception. It does not use the usual calling *
244 * conventions. The exception pointer is passed in REG_ITMP1 and the *
245 * pc from the exception raising position is passed in REG_ITMP2. It searches *
246 * the local exception table for a handler. If no one is found, it unwinds *
247 * stacks and continues searching the callers. *
249 *******************************************************************************/
251 asm_handle_nat_exception:
252 add $8,sp /* clear return address of native stub*/
254 asm_handle_exception:
255 L_asm_handle_exception: /* required for PIC code */
256 sub $((ARG_CNT+TMP_CNT)*8),sp /* create maybe-leaf stackframe */
258 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
259 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
261 mov $((ARG_CNT+TMP_CNT)*8),a3 /* prepare a3 for handle_exception */
262 mov $1,t0 /* set maybe-leaf flag */
264 L_asm_handle_exception_stack_loop:
266 mov xptr,0*8(sp) /* save exception pointer */
267 mov xpc,1*8(sp) /* save exception pc */
268 add sp,a3 /* calculate Java sp into a3... */
270 mov a3,3*8(sp) /* ...and save it */
271 mov t0,4*8(sp) /* save maybe-leaf flag */
273 mov xpc,a0 /* exception pc */
274 call codegen_get_pv_from_pc@PLT
275 mov v0,2*8(sp) /* save data segment pointer */
277 mov 0*8(sp),a0 /* pass exception pointer */
278 mov 1*8(sp),a1 /* pass exception pc */
279 mov v0,a2 /* pass data segment pointer */
280 mov 3*8(sp),a3 /* pass Java stack pointer */
281 call exceptions_handle_exception@PLT
284 jz L_asm_handle_exception_not_catched
286 mov v0,xpc /* move handlerpc into xpc */
287 mov 0*8(sp),xptr /* restore exception pointer */
288 mov 4*8(sp),t0 /* get maybe-leaf flag */
289 add $(6*8),sp /* free stack frame */
291 test t0,t0 /* test for maybe-leaf flag */
292 jz L_asm_handle_exception_no_leaf
294 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
295 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
297 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
299 L_asm_handle_exception_no_leaf:
300 jmp *xpc /* jump to the handler */
302 L_asm_handle_exception_not_catched:
303 mov 0*8(sp),xptr /* restore exception pointer */
304 mov 2*8(sp),itmp3 /* restore data segment pointer */
305 mov 4*8(sp),t0 /* get maybe-leaf flag */
309 jz L_asm_handle_exception_no_leaf_stack
311 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
312 xor t0,t0 /* clear the isleaf flags */
314 L_asm_handle_exception_no_leaf_stack:
315 mov FrameSize(itmp3),itmp2l /* get frame size */
316 add sp,itmp2 /* pointer to save area */
318 mov IntSave(itmp3),a0l /* a0l = saved int register count */
341 shl $3,a0l /* multiply by 8 bytes */
346 mov FltSave(itmp3),a0l /* a0l = saved flt register count */
359 movq -5*8(itmp2),%xmm11
361 movq -4*8(itmp2),%xmm12
363 movq -3*8(itmp2),%xmm13
365 movq -2*8(itmp2),%xmm14
367 movq -1*8(itmp2),%xmm15
371 mov FrameSize(itmp3),itmp2l /* get frame size */
372 add itmp2,sp /* unwind stack */
374 /* exception pointer is still set */
375 pop xpc /* the new xpc is return address */
376 sub $3,xpc /* subtract 3 bytes for call */
378 xor a3,a3 /* prepare a3 for handle_exception */
380 jmp L_asm_handle_exception_stack_loop
383 /* asm_abstractmethoderror *****************************************************
385 Creates and throws an AbstractMethodError.
387 *******************************************************************************/
389 asm_abstractmethoderror:
390 mov sp,a0 /* pass java sp */
392 mov 0*8(sp),a1 /* pass exception address */
394 call exceptions_asm_new_abstractmethoderror@PLT
395 /* exception pointer is return value */
396 pop xpc /* get exception address */
397 sub $3,xpc /* exception address is ra - 3 */
398 jmp L_asm_handle_exception
401 /* asm_builtin_x2x *************************************************************
403 * Wrapper functions for float to int corner cases *
405 *******************************************************************************/
410 SAVE_ARGUMENT_REGISTERS(0)
415 RESTORE_ARGUMENT_REGISTERS(0)
424 SAVE_ARGUMENT_REGISTERS(0)
429 RESTORE_ARGUMENT_REGISTERS(0)
438 SAVE_ARGUMENT_REGISTERS(0)
443 RESTORE_ARGUMENT_REGISTERS(0)
452 SAVE_ARGUMENT_REGISTERS(0)
457 RESTORE_ARGUMENT_REGISTERS(0)
463 /* asm_compare_and_swap ********************************************************
465 Does an atomic compare and swap. Required for the lock
468 *******************************************************************************/
470 asm_compare_and_swap:
471 mov a1,v0 /* v0 is %rax */
476 /* asm_memory_barrier **********************************************************
478 A memory barrier for the Java Memory Model.
480 *******************************************************************************/
487 /* disable exec-stacks ********************************************************/
489 #if defined(__linux__) && defined(__ELF__)
490 .section .note.GNU-stack,"",%progbits
495 * These are local overrides for various environment variables in Emacs.
496 * Please do not remove this and leave it at the end of the file, where
497 * Emacs will automagically detect them.
498 * ---------------------------------------------------------------------
501 * indent-tabs-mode: t
505 * vim:noexpandtab:sw=4:ts=4: