1 /* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 #include "vm/jit/i386/arch.h"
31 #include "vm/jit/i386/md-abi.h"
33 #include "vm/jit/abi-asm.h"
34 #include "vm/jit/methodheader.h"
40 /* 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
49 .globl asm_vm_call_method_exception_handler
50 .globl asm_vm_call_method_end
52 .globl asm_handle_nat_exception
53 .globl asm_handle_exception
55 .globl asm_abstractmethoderror
57 .globl asm_builtin_f2i
58 .globl asm_builtin_f2l
59 .globl asm_builtin_d2i
60 .globl asm_builtin_d2l
62 .globl asm_compare_and_swap
63 .globl asm_memory_barrier
65 #if defined(ENABLE_ESCAPE_CHECK)
66 .globl asm_escape_check
70 /* asm_md_init *****************************************************************
72 Initialize machine dependent stuff.
74 See: http://www.srware.com/linux_numerics.txt
76 This puts the X86 FPU in 64-bit precision mode. The default under
77 Linux is to use 80-bit mode, which produces subtle differences from
78 FreeBSD and other systems, eg, (int)(1000*atof("0.3")) is 300 in
79 64-bit mode, 299 in 80-bit mode.
81 Fixes: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350729
83 *******************************************************************************/
86 sub $4,sp /* allocate space for the FPU state */
87 fnstcw (sp) /* get the FPU state */
89 and $0xfcff,%ax /* remove the extended mode flag */
90 or $0x0200,%ax /* put the double mode flag */
91 mov %eax,(sp) /* store new FPU state */
92 fldcw (sp) /* setup new FPU state */
97 /********************* function asm_calljavafunction ***************************
99 * This function calls a Java-method (which possibly needs compilation) *
100 * with up to 4 address parameters. *
102 * This functions calls the JIT-compiler which eventually translates the *
103 * method into machine code. *
106 * javaobject_header *asm_vm_call_method(methodinfo *m, *
107 * u4 count, u4 size, void *callblock); *
109 *******************************************************************************/
113 .long 0 /* fltsave */
114 .long 0 /* intsave */
116 .long 0 /* frame size */
117 .long 0 /* codeinfo pointer */
120 asm_vm_call_method_int:
121 asm_vm_call_method_long:
122 asm_vm_call_method_float:
123 asm_vm_call_method_double:
125 mov sp,bp /* save stack pointer */
126 sub $(4*4),sp /* create stackframe */
127 and $0xfffffff0,sp /* align stack to 16-byte */
129 mov t0,0*4(sp) /* save registers */
133 mov sp,s1 /* save stack pointer */
135 mov 3*4(bp),t0 /* address of data structure */
136 mov 4*4(bp),itmp1 /* number of stack arguments */
139 je L_asm_vm_call_method_stack_copy_done
142 add $1,itmp2 /* keep stack 16-byte aligned */
143 and $0xfffffffe,itmp2
144 shl $3,itmp2 /* calculate stack size */
145 sub itmp2,sp /* create stack frame */
146 mov sp,itmp2 /* temporary stack pointer */
148 L_asm_vm_call_method_stack_copy_loop:
149 mov 0(t0),itmp3 /* load argument */
150 mov itmp3,0(itmp2) /* store argument on stack */
154 sub $1,itmp1 /* subtract 1 argument */
155 add $8,t0 /* set address of next argument */
156 add $8,itmp2 /* increase SP */
159 jg L_asm_vm_call_method_stack_copy_loop
161 L_asm_vm_call_method_stack_copy_done:
162 lea (2*4-256)(bp),mptr /* We subtract 256 to force the next */
163 /* move instruction to have a 32-bit */
166 mov (0*4+256)(mptr),itmp3 /* method call as in Java */
167 call *itmp3 /* call JIT compiler */
169 L_asm_vm_call_method_return:
170 mov s1,sp /* restore stackpointer */
172 mov 0*4(sp),t0 /* restore registers */
179 asm_vm_call_method_exception_handler:
180 #if defined(ENABLE_PIC_ASM)
184 push xptr /* pass exception pointer */
185 #if defined(ENABLE_PIC_ASM)
187 add $_GLOBAL_OFFSET_TABLE_, %ebx
188 call builtin_throw_exception@PLT
192 call builtin_throw_exception
195 asm_vm_call_method_end:
196 jmp L_asm_vm_call_method_return
199 /* asm_handle_exception ********************************************************
201 * This function handles an exception. It does not use the usual calling *
202 * conventions. The exception pointer is passed in REG_ITMP1 and the *
203 * pc from the exception raising position is passed in REG_ITMP2. It searches *
204 * the local exception table for a handler. If no one is found, it unwinds *
205 * stacks and continues searching the callers. *
207 *******************************************************************************/
209 asm_handle_nat_exception:
210 add $4,sp /* clear return address of native stub*/
212 asm_handle_exception:
213 L_asm_handle_exception: /* required for PIC code */
214 sub $((ARG_CNT+TMP_CNT+3)*4),sp /* keep stack 16-byte aligned */
216 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
217 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
219 mov $((ARG_CNT+TMP_CNT+3)*4),itmp3 /* prepare a3 for handle_exception */
220 mov $1,t0 /* set maybe-leaf flag */
222 L_asm_handle_exception_stack_loop:
223 sub $(12*4),sp /* keep stack 16-byte aligned */
224 mov xptr,4*4(sp) /* save exception pointer */
225 mov xpc,5*4(sp) /* save exception pc */
226 add sp,itmp3 /* calculate Java sp into a3... */
228 mov itmp3,7*4(sp) /* ...and save it */
229 mov t0,8*4(sp) /* save maybe-leaf flag */
231 mov xpc,0*4(sp) /* pass exception pc */
232 #if defined(ENABLE_PIC_ASM)
234 add $_GLOBAL_OFFSET_TABLE_, %ebx
235 call methodtree_find@PLT
239 mov v0,6*4(sp) /* save data segment pointer */
241 mov 4*4(sp),itmp3 /* pass exception pointer */
243 mov 5*4(sp),itmp3 /* pass exception pc */
245 mov v0,2*4(sp) /* pass data segment pointer */
246 mov 7*4(sp),itmp3 /* pass Java stack pointer */
248 #if defined(ENABLE_PIC_ASM)
249 /* GOT still in %ebx */
250 call exceptions_handle_exception@PLT
252 call exceptions_handle_exception
256 jz L_asm_handle_exception_not_catched
258 mov v0,xpc /* move handlerpc into xpc */
259 mov 4*4(sp),xptr /* restore exception pointer */
260 mov 8*4(sp),t0 /* get maybe-leaf flag */
261 add $(12*4),sp /* free stackframe */
263 test t0,t0 /* test for maybe-leaf flag */
264 jz L_asm_handle_exception_no_leaf
266 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
267 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
269 add $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe */
271 L_asm_handle_exception_no_leaf:
272 jmp *xpc /* jump to exception handler */
274 L_asm_handle_exception_not_catched:
275 mov 4*4(sp),xptr /* restore exception pointer */
276 mov 6*4(sp),itmp3 /* restore data segment pointer */
277 mov 8*4(sp),t0 /* get maybe-leaf flag */
278 add $(12*4),sp /* free stackframe */
281 jz L_asm_handle_exception_no_leaf_stack
283 add $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe */
284 xor t0,t0 /* clear the maybe-leaf flag */
286 L_asm_handle_exception_no_leaf_stack:
287 mov FrameSize(itmp3),itmp2 /* get frame size */
288 add sp,itmp2 /* pointer to save area */
290 push xptr /* we are out of registers */
292 mov IntSave(itmp3),itmp1 /* itmp1 = saved int register count */
307 shl $2,itmp1 /* multiply by 4 bytes */
312 mov FltSave(itmp3),itmp1 /* itmp1 = saved flt register count */
337 pop xptr /* restore exception pointer */
338 mov FrameSize(itmp3),itmp2 /* get frame size */
339 add itmp2,sp /* unwind stack */
341 pop xpc /* the new xpc is return address */
342 sub $2,xpc /* subtract 2-bytes for call */
344 xor itmp3,itmp3 /* prepare a3 for handle_exception */
346 jmp L_asm_handle_exception_stack_loop
349 /* asm_abstractmethoderror *****************************************************
351 Creates and throws an AbstractMethodError.
353 *******************************************************************************/
355 asm_abstractmethoderror:
356 sub $(3*4),sp /* keep stack 16-byte aligned */
357 mov sp,itmp1 /* pass java sp */
360 mov 3*4(sp),itmp2 /* pass exception address */
363 #if defined(ENABLE_PIC_ASM)
365 add $_GLOBAL_OFFSET_TABLE_, %ebx
366 call exceptions_asm_new_abstractmethoderror@PLT
368 call exceptions_asm_new_abstractmethoderror
370 /* exception pointer is return value */
371 add $(3*4),sp /* remove stack frame */
373 pop xpc /* get exception address */
374 sub $2,xpc /* exception address is ra - 2 */
375 jmp L_asm_handle_exception
378 /************************ function asm_builtin_x2x *****************************
380 * Wrapper functions for corner cases *
382 *******************************************************************************/
384 #if defined(ENABLE_PIC_ASM)
392 #if defined(ENABLE_PIC_ASM)
397 add $_GLOBAL_OFFSET_TABLE_, %ebx
410 #if defined(ENABLE_PIC_ASM)
415 add $_GLOBAL_OFFSET_TABLE_, %ebx
428 #if defined(ENABLE_PIC_ASM)
433 add $_GLOBAL_OFFSET_TABLE_, %ebx
446 #if defined(ENABLE_PIC_ASM)
451 add $_GLOBAL_OFFSET_TABLE_, %ebx
463 /* asm_compare_and_swap ********************************************************
465 Does an atomic compare and swap. Required for the lock
468 Atomically do the following: Check if the location still contains
469 `oldval`. If so, replace it by `newval` and return `oldval`.
474 long compare_and_swap(volatile long *p, long oldval, long newval);
476 *******************************************************************************/
478 asm_compare_and_swap:
479 mov 1*4(sp),%ecx /* load p into a register */
480 mov 2*4(sp),%eax /* load oldval into return register */
481 mov 3*4(sp),%edx /* load newval into a register */
482 lock; cmpxchgl %edx,0(%ecx)
486 /* asm_memory_barrier **********************************************************
488 A memory barrier for the Java Memory Model.
490 *******************************************************************************/
497 #if defined(ENABLE_ESCAPE_CHECK)
509 call escape_analysis_escape_check
521 /* disable exec-stacks ********************************************************/
523 #if defined(__linux__) && defined(__ELF__)
524 .section .note.GNU-stack,"",%progbits
528 * These are local overrides for various environment variables in Emacs.
529 * Please do not remove this and leave it at the end of the file, where
530 * Emacs will automagically detect them.
531 * ---------------------------------------------------------------------
534 * indent-tabs-mode: t
538 * vim:noexpandtab:sw=4:ts=4: