/* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: asmpart.S 8123 2007-06-20 23:50:55Z michi $
-
*/
#include "vm/jit/x86_64/arch.h"
#include "vm/jit/x86_64/md-abi.h"
#include "vm/jit/x86_64/md-asm.h"
-#include "vm/jit/x86_64/offsets.h"
#include "vm/jit/abi-asm.h"
#include "vm/jit/methodheader.h"
.globl asm_vm_call_method_exception_handler
.globl asm_vm_call_method_end
- .globl asm_call_jit_compiler
-
.globl asm_handle_exception
.globl asm_handle_nat_exception
.globl asm_abstractmethoderror
- .globl asm_patcher_wrapper
-
-#if defined(ENABLE_REPLACEMENT)
- .globl asm_replacement_out
- .globl asm_replacement_in
-#endif
-
.globl asm_builtin_f2i
.globl asm_builtin_f2l
.globl asm_builtin_d2i
.globl asm_builtin_d2l
- .globl asm_compare_and_swap
- .globl asm_memory_barrier
-
- .globl asm_criticalsections
- .globl asm_getclassvalues_atomic
-
/********************* function asm_calljavafunction ***************************
* *
.align 8
- .quad 0 /* catch type all */
- .quad 0 /* handler pc */
- .quad 0 /* end pc */
- .quad 0 /* start pc */
- .long 1 /* extable size */
- .long 0 /* ALIGNMENT PADDING */
- .quad 0 /* line number table start */
- .quad 0 /* line number table size */
- .long 0 /* ALIGNMENT PADDING */
.long 0 /* fltsave */
.long 0 /* intsave */
.long 0 /* isleaf */
- .long 0 /* IsSync */
.long 0 /* frame size */
.quad 0 /* codeinfo pointer */
je L_asm_vm_call_method_stack_copy_done
mov itmp1,itmp2
- and $0xfffffffffffffffe,itmp2 /* keep stack 16-byte aligned */
+ add $1,itmp2 /* keep stack 16-byte aligned */
+ and $0xfffffffffffffffe,itmp2
shl $3,itmp2 /* calculate stack size */
sub itmp2,sp /* create stack frame */
mov sp,itmp2 /* temporary stack pointer */
mov (0*8+256)(mptr),itmp3 /* load PV */
call *itmp3
+L_asm_vm_call_method_return:
mov s0,sp /* restore SP */
-L_asm_vm_call_method_return:
mov 0*8(sp),%rbx /* restore callee saved registers */
mov 1*8(sp),s0
mov 2*8(sp),s1
nop
-/****************** function asm_call_jit_compiler *****************************
-* *
-* invokes the compiler for untranslated JavaVM methods. *
-* *
-* Register R0 contains a pointer to the method info structure (prepared *
-* by createcompilerstub). Using the return address in R26 and the *
-* offset in the LDA instruction or using the value in methodptr R28 the *
-* patching address for storing the method address can be computed: *
-* *
-* method address was either loaded using *
-* *
-* i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
-* i386_call_reg(REG_ITMP2) *
-* *
-* or *
-* *
-* i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
-* i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
-* i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
-* sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
-* i386_call_reg(REG_ITMP1) *
-* *
-* in the static case the method pointer can be computed using the *
-* return address and the lda function following the jmp instruction *
-* *
-*******************************************************************************/
-
-asm_call_jit_compiler:
-L_asm_call_jit_compiler: /* required for PIC code */
- sub $(ARG_CNT+1)*8,sp /* +1: keep stack 16-byte aligned */
-
- SAVE_ARGUMENT_REGISTERS(0)
-
- mov itmp1,a0 /* pass methodinfo pointer */
- mov mptr,a1 /* pass method pointer */
- mov sp,a2 /* pass java sp */
- add $(1+ARG_CNT+1)*8,a2
- mov (ARG_CNT+1)*8(sp),a3 /* pass ra to java function */
- call jit_asm_compile@PLT
-
- RESTORE_ARGUMENT_REGISTERS(0)
-
- add $(ARG_CNT+1)*8,sp /* remove stack frame */
-
- test v0,v0 /* check for exception */
- je L_asm_call_jit_compiler_exception
-
- jmp *v0 /* ...and now call the new method */
-
-L_asm_call_jit_compiler_exception:
- call exceptions_get_and_clear_exception@PLT
- pop xpc /* delete return address */
- sub $3,xpc /* faulting address is ra - 3 */
- jmp L_asm_handle_exception
-
-
/* asm_handle_exception ********************************************************
* *
* This function handles an exception. It does not use the usual calling *
mov t0,4*8(sp) /* save maybe-leaf flag */
mov xpc,a0 /* exception pc */
- call codegen_get_pv_from_pc@PLT
+ call methodtree_find@PLT
mov v0,2*8(sp) /* save data segment pointer */
mov 0*8(sp),a0 /* pass exception pointer */
jmp L_asm_handle_exception
-/* asm_patcher_wrapper *********************************************************
-
- XXX
-
- Stack layout:
- 40 return address
- 32 pointer to virtual java_objectheader
- 24 machine code (which is patched back later)
- 16 unresolved class/method/field reference
- 8 data segment displacement from load instructions
- 0 pointer to patcher function
- -8 bp
-
-*******************************************************************************/
-
-asm_patcher_wrapper:
- push bp /* save base pointer */
- mov sp,bp /* move actual sp to bp */
- sub $(3+ARG_CNT+TMP_CNT)*8,sp
- and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
- /* leaf functions) */
-
- SAVE_ARGUMENT_REGISTERS(3)
- SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
-
- mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
- mov itmp2,1*8(sp) /* can be used by some instructions */
-
- mov bp,a0 /* pass SP of patcher stub */
- add $(1*8),a0
- mov $0,a1 /* pass PV (if NULL, use findmethod) */
- mov $0,a2 /* pass RA (it's on the stack) */
- call patcher_wrapper@PLT
- mov v0,2*8(sp) /* save return value */
-
- RESTORE_ARGUMENT_REGISTERS(3)
- RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
-
- mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
- mov 1*8(sp),itmp2 /* can be used by some instructions */
- mov 2*8(sp),itmp3 /* restore return value */
-
- mov bp,sp /* restore original sp */
- pop bp /* restore bp */
- add $(5*8),sp /* remove patcher stackframe, keep RA */
-
- test itmp3,itmp3 /* exception thrown? */
- jne L_asm_patcher_wrapper_exception
- ret /* call new patched code */
-
-L_asm_patcher_wrapper_exception:
- mov itmp3,xptr /* get exception */
- pop xpc /* get and remove return address */
- jmp L_asm_handle_exception
-
-#if defined(ENABLE_REPLACEMENT)
-
-/* asm_replacement_out *********************************************************
-
- This code is jumped to from the replacement-out stubs that are executed
- when a thread reaches an activated replacement point.
-
- The purpose of asm_replacement_out is to read out the parts of the
- execution state that cannot be accessed from C code, store this state,
- and then call the C function replace_me.
-
- Stack layout:
- 8 start of stack inside method to replace
- 0 rplpoint * info on the replacement point that was reached
-
-*******************************************************************************/
-
-/* some room to accomodate changes of the stack frame size during replacement */
- /* XXX we should find a cleaner solution here */
-#define REPLACEMENT_ROOM 512
-
-asm_replacement_out:
- /* create stack frame */
- sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
-
- /* save registers in execution state */
- mov %rax,(RAX*8+offes_intregs)(sp)
- mov %rbx,(RBX*8+offes_intregs)(sp)
- mov %rcx,(RCX*8+offes_intregs)(sp)
- mov %rdx,(RDX*8+offes_intregs)(sp)
- mov %rsi,(RSI*8+offes_intregs)(sp)
- mov %rdi,(RDI*8+offes_intregs)(sp)
- mov %rbp,(RBP*8+offes_intregs)(sp)
- movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
- mov %r8 ,(R8 *8+offes_intregs)(sp)
- mov %r9 ,(R9 *8+offes_intregs)(sp)
- mov %r10,(R10*8+offes_intregs)(sp)
- mov %r11,(R11*8+offes_intregs)(sp)
- mov %r12,(R12*8+offes_intregs)(sp)
- mov %r13,(R13*8+offes_intregs)(sp)
- mov %r14,(R14*8+offes_intregs)(sp)
- mov %r15,(R15*8+offes_intregs)(sp)
-
- movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
- movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
- movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
- movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
- movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
- movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
- movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
- movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
- movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
- movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
- movq %xmm10,(XMM10*8+offes_fltregs)(sp)
- movq %xmm11,(XMM11*8+offes_fltregs)(sp)
- movq %xmm12,(XMM12*8+offes_fltregs)(sp)
- movq %xmm13,(XMM13*8+offes_fltregs)(sp)
- movq %xmm14,(XMM14*8+offes_fltregs)(sp)
- movq %xmm15,(XMM15*8+offes_fltregs)(sp)
-
- /* calculate sp of method */
- mov sp,itmp1
- add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
- mov itmp1,(offes_sp)(sp)
-
- /* pv must be looked up via AVL tree */
- movq $0,(offes_pv)(sp)
-
- /* call replace_me */
- mov -8(itmp1),a0 /* rplpoint * */
- mov sp,a1 /* arg1: execution state */
- call replace_me@PLT /* call C function replace_me */
- call abort@PLT /* NEVER REACHED */
-
-/* asm_replacement_in **********************************************************
-
- This code writes the given execution state and jumps to the replacement
- code.
-
- This function never returns!
-
- C prototype:
- void asm_replacement_in(executionstate *es, replace_safestack_t *st);
-
-*******************************************************************************/
-
-asm_replacement_in:
- /* get arguments */
- mov a1,s1 /* replace_safestack_t *st */
- mov a0,%rbp /* executionstate *es == safe stack */
-
- /* switch to the safe stack */
- mov %rbp,sp
-
- /* call replace_build_execution_state(st) */
- mov s1,a0
- call replace_build_execution_state@PLT
-
- /* set new sp */
- mov (offes_sp)(%rbp),sp
-
- /* push address of new code */
- pushq (offes_pc)(%rbp)
-
- /* allocate an executionstate_t on the stack */
- sub $(sizeexecutionstate),sp
-
- /* call replace_free_safestack(st,& of allocated executionstate_t) */
- mov sp,a1
- mov s1,a0
- call replace_free_safestack@PLT
-
- /* copy registers from execution state */
- movq (XMM0 *8+offes_fltregs)(sp),%xmm0
- movq (XMM1 *8+offes_fltregs)(sp),%xmm1
- movq (XMM2 *8+offes_fltregs)(sp),%xmm2
- movq (XMM3 *8+offes_fltregs)(sp),%xmm3
- movq (XMM4 *8+offes_fltregs)(sp),%xmm4
- movq (XMM5 *8+offes_fltregs)(sp),%xmm5
- movq (XMM6 *8+offes_fltregs)(sp),%xmm6
- movq (XMM7 *8+offes_fltregs)(sp),%xmm7
- movq (XMM8 *8+offes_fltregs)(sp),%xmm8
- movq (XMM9 *8+offes_fltregs)(sp),%xmm9
- movq (XMM10*8+offes_fltregs)(sp),%xmm10
- movq (XMM11*8+offes_fltregs)(sp),%xmm11
- movq (XMM12*8+offes_fltregs)(sp),%xmm12
- movq (XMM13*8+offes_fltregs)(sp),%xmm13
- movq (XMM14*8+offes_fltregs)(sp),%xmm14
- movq (XMM15*8+offes_fltregs)(sp),%xmm15
-
- mov (RAX*8+offes_intregs)(sp),%rax
- mov (RBX*8+offes_intregs)(sp),%rbx
- mov (RCX*8+offes_intregs)(sp),%rcx
- mov (RDX*8+offes_intregs)(sp),%rdx
- mov (RSI*8+offes_intregs)(sp),%rsi
- mov (RDI*8+offes_intregs)(sp),%rdi
- mov (RBP*8+offes_intregs)(sp),%rbp
- mov (R8 *8+offes_intregs)(sp),%r8
- mov (R9 *8+offes_intregs)(sp),%r9
- mov (R10*8+offes_intregs)(sp),%r10
- mov (R11*8+offes_intregs)(sp),%r11
- mov (R12*8+offes_intregs)(sp),%r12
- mov (R13*8+offes_intregs)(sp),%r13
- mov (R14*8+offes_intregs)(sp),%r14
- mov (R15*8+offes_intregs)(sp),%r15
-
- /* pop the execution state off the stack */
- add $(sizeexecutionstate),sp
-
- /* jump to new code */
- ret
-
-#endif /* defined(ENABLE_REPLACEMENT) */
-
-
/* asm_builtin_x2x *************************************************************
* *
* Wrapper functions for float to int corner cases *
ret
-/* asm_compare_and_swap ********************************************************
-
- Does an atomic compare and swap. Required for the lock
- implementation.
-
-*******************************************************************************/
-
-asm_compare_and_swap:
- mov a1,v0 /* v0 is %rax */
- lock cmpxchg a2,(a0)
- ret
-
-
-/* asm_memory_barrier **********************************************************
-
- A memory barrier for the Java Memory Model.
-
-*******************************************************************************/
-
-asm_memory_barrier:
- mfence
- ret
-
-
-asm_getclassvalues_atomic:
-_crit_restart:
-_crit_begin:
- movl offbaseval(a0),itmp1l
- movl offdiffval(a0),itmp2l
- movl offbaseval(a1),itmp3l
-_crit_end:
- movl itmp1l,offcast_super_baseval(a2)
- movl itmp2l,offcast_super_diffval(a2)
- movl itmp3l,offcast_sub_baseval(a2)
- ret
-
- .data
-
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
- .quad _crit_begin
- .quad _crit_end
- .quad _crit_restart
-#endif
- .quad 0
-
-
/* disable exec-stacks ********************************************************/
#if defined(__linux__) && defined(__ELF__)