/* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
- Copyright (C) 1996-2005 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 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
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Authors: Andreas Krall
Reinhard Grafl
Christian Thalinger
- $Id: asmpart.S 2201 2005-04-03 21:48:11Z twisti $
+ Changes:
+
+ $Id: asmpart.S 4357 2006-01-22 23:33:38Z twisti $
*/
#include "config.h"
-#include "vm/jit/x86_64/arch.h"
-#include "vm/jit/x86_64/offsets.h"
-#include "vm/jit/x86_64/asmoffsets.h"
-
-
-/* define it like the risc way */
-
-#define v0 %rax
-
-#define a0 %rdi
-#define a1 %rsi
-#define a2 %rdx
-#define a3 %rcx
-#define a4 %r8
-#define a5 %r9
-
-#define fa0 %xmm0
-#define fa1 %xmm1
-#define fa2 %xmm2
-#define fa3 %xmm3
-#define fa4 %xmm4
-#define fa5 %xmm5
-#define fa6 %xmm6
-#define fa7 %xmm7
-#define itmp1 %rax
-#define itmp2 %r10
-#define itmp3 %r11
+#include "md-abi.h"
+#include "md-asm.h"
-#define itmp1l %eax
-#define itmp2l %r10d
-#define itmp3l %r11d
-
-#define itmp1b %al
-#define itmp2b %r10b
-#define itmp3b %r11b
+#include "vm/jit/abi.h"
+#include "vm/jit/x86_64/arch.h"
+#include "vm/jit/x86_64/offsets.h"
-#define xptr itmp1
-#define xpc itmp2
+#include "vm/jit/methodheader.h"
.text
.globl asm_call_jit_compiler
.globl asm_handle_exception
.globl asm_handle_nat_exception
- .globl asm_check_clinit
- .globl asm_builtin_checkarraycast
- .globl asm_builtin_aastore
-#if defined(USE_THREADS)
- .globl asm_builtin_monitorenter
- .globl asm_builtin_monitorexit
-#endif
+ .globl asm_wrapper_patcher
.globl asm_builtin_f2i
.globl asm_builtin_f2l
.globl asm_switchstackandcall
.globl asm_criticalsections
.globl asm_getclassvalues_atomic
-
+
/********************* function asm_calljavafunction ***************************
* *
* *
*******************************************************************************/
-call_name:
.align 8
- .quad 0 /* catch type all */
- .quad calljava_xhandler /* handler pc */
- .quad calljava_xhandler /* end pc */
- .quad asm_calljavafunction /* start pc */
- .long 1 /* extable size */
- .long 0 /* fltsave */
- .long 0 /* intsave */
- .long 0 /* isleaf */
- .long 0 /* IsSync */
- .long 8 /* frame size */
- .quad 0 /* method pointer (pointer to name) */
+ .quad 0 /* catch type all */
+ .quad calljava_xhandler /* handler pc */
+ .quad calljava_xhandler /* end pc */
+ .quad asm_calljavafunction /* start pc */
+ .long 1 /* extable size */
+ .long 0
+ .quad 0 /* line number table start */
+ .quad 0 /* line number table size */
+ .long 0
+ .long 0 /* fltsave */
+ .long 0 /* intsave */
+ .long 0 /* isleaf */
+ .long 0 /* IsSync */
+ .long 8 /* frame size */
+ .quad 0 /* method pointer (pointer to name) */
asm_calljavafunction:
asm_calljavafunction_int:
- sub $(3*8),%rsp /* keep stack 16-byte aligned */
- mov %rbp,0*8(%rsp)
- mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
- mov %rdi,%rax /* move function pointer to %rax */
- /* compilerstub uses this */
-
- mov %rsi,%rdi /* pass remaining parameters */
- mov %rdx,%rsi
- mov %rcx,%rdx
- mov %r8,%rcx
-
- lea asm_call_jit_compiler,%r11
- call *%r11 /* call JIT compiler */
-
- mov 0*8(%rsp),%rbp
- mov 1*8(%rsp),%rbx
- add $(3*8),%rsp /* free stack space */
+ sub $(3*8),sp /* keep stack 16-byte aligned */
+ mov bp,0*8(sp)
+ mov %rbx,1*8(sp) /* %rbx is not a callee saved in CACAO*/
+ mov a0,itmp1 /* move function pointer to itmp1 */
+ /* compilerstub uses this */
+
+ mov a1,a0 /* pass remaining parameters */
+ mov a2,a1
+ mov a3,a2
+ mov a4,a3
+
+ lea asm_call_jit_compiler,itmp3
+ call *itmp3 /* call JIT compiler */
+
+L_asm_calljavafunction_return:
+ mov 0*8(sp),bp
+ mov 1*8(sp),%rbx /* %rbx is not a callee saved in CACAO*/
+ add $(3*8),sp /* free stack space */
ret
calljava_xhandler:
- mov %rax,%rdi /* pass exception pointer */
+ mov xptr,a0 /* pass exception pointer */
call builtin_throw_exception
- mov 0*8(%rsp),%rbp
- mov 1*8(%rsp),%rbx
- add $(3*8),%rsp
- xor %rax,%rax /* return NULL */
- ret
+ xor v0,v0 /* return NULL */
+ jmp L_asm_calljavafunction_return
/********************* function asm_calljavafunction ***************************
* *
*******************************************************************************/
-call_name2:
.align 8
- .quad 0 /* catch type all */
- .quad calljava_xhandler2 /* handler pc */
- .quad calljava_xhandler2 /* end pc */
- .quad asm_calljavafunction2 /* start pc */
- .long 1 /* extable size */
- .long 0 /* fltsave */
- .long 0 /* intsave */
- .long 0 /* isleaf */
- .long 0 /* IsSync */
- .long 24 /* frame size */
- .quad 0 /* method pointer (pointer to name) */
+ .quad 0 /* catch type all */
+ .quad calljava_xhandler2 /* handler pc */
+ .quad calljava_xhandler2 /* end pc */
+ .quad asm_calljavafunction2 /* start pc */
+ .long 1 /* extable size */
+ .long 0
+ .quad 0 /* line number table start */
+ .quad 0 /* line number table size */
+ .long 0
+ .long 0 /* fltsave */
+ .long 0 /* intsave */
+ .long 0 /* isleaf */
+ .long 0 /* IsSync */
+ .long 24 /* frame size */
+ .quad 0 /* method pointer (pointer to name) */
asm_calljavafunction2:
asm_calljavafunction2int:
asm_calljavafunction2long:
asm_calljavafunction2float:
asm_calljavafunction2double:
- sub $(7*8),%rsp /* keep stack 16-byte aligned */
- mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
- mov %rbp,1*8(%rsp)
- mov %r12,2*8(%rsp)
- mov %r13,3*8(%rsp)
- mov %r14,4*8(%rsp)
- mov %r15,5*8(%rsp)
-
- mov %rdi,%rax /* move method pointer for compiler */
- xor %rbp,%rbp /* set argument stack frame to zero */
-
- test %rsi,%rsi /* maybe we have no args... */
+ sub $(7*8),sp /* keep stack 16-byte aligned */
+ mov %rbx,0*8(sp) /* %rbx is not a callee saved in cacao*/
+ mov s0,1*8(sp)
+ mov s1,2*8(sp)
+ mov s2,3*8(sp)
+ mov s3,4*8(sp)
+ mov s4,5*8(sp)
+
+ mov a0,itmp1 /* move method pointer for compiler */
+ xor %rbp,%rbp /* set argument stack frame to zero */
+
+ test a1,a1 /* maybe we have no args... */
jle L_copy_done
- mov %rsi,itmp3 /* arg count */
- mov %rcx,itmp2 /* pointer to arg block */
+ mov a1,itmp3 /* arg count */
+ mov a3,itmp2 /* pointer to arg block */
- mov itmp2,%r14 /* save argument block pointer */
- mov itmp3,%r15 /* save argument count */
+ mov itmp2,%r14 /* save argument block pointer */
+ mov itmp3,%r15 /* save argument count */
- sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
- add $1,itmp3 /* initialize argument count */
- xor %r12,%r12 /* initialize integer argument counter */
- xor %r13,%r13 /* initialize float argument counter */
+ sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
+ add $1,itmp3 /* initialize argument count */
+ xor %r12,%r12 /* initialize integer argument counter*/
+ xor %r13,%r13 /* initialize float argument counter */
L_register_copy:
add $sizejniblock,itmp2 /* goto next argument block */
sub %r13,%rbp /* - float arguments in registers */
jle L_copy_done /* are all assigned to registers? */
+ and $0xfffffffffffffffe,%rbp /* keep stack 16-byte aligned */
shl $3,%rbp /* calculate stack size */
- sub %rbp,%rsp /* stack frame for arguments */
- mov %rsp,%rbx /* use %rbx as temp sp */
+ sub %rbp,sp /* stack frame for arguments */
+ mov sp,%rbx /* use %rbx as temp sp */
sub $sizejniblock,%r14 /* initialize pointer (smaller code) */
add $1,%r15 /* initialize argument count */
jmp L_stack_copy_loop
L_copy_done:
- lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
- call *%r11 /* call JIT compiler */
-
- add %rbp,%rsp /* remove argument stack frame if any */
-
- mov 5*8(%rsp),%r15 /* restore callee saved registers */
- mov 4*8(%rsp),%r14
- mov 3*8(%rsp),%r13
- mov 2*8(%rsp),%r12
- mov 1*8(%rsp),%rbp
- mov 0*8(%rsp),%rbx
- add $(7*8),%rsp /* free stack space */
+ lea asm_call_jit_compiler,itmp3 /* %rax still contains method pointer */
+ call *itmp3 /* call JIT compiler */
+
+ add bp,sp /* remove argument stack frame if any */
+
+L_asm_calljavafunction2_return:
+ mov 0*8(sp),%rbx /* restore callee saved registers */
+ mov 1*8(sp),s0
+ mov 2*8(sp),s1
+ mov 3*8(sp),s2
+ mov 4*8(sp),s3
+ mov 5*8(sp),s4
+ add $(7*8),sp /* free stack space */
ret
calljava_xhandler2:
- mov %rax,%rdi /* pass exception pointer */
+ mov xptr,a0 /* pass exception pointer */
call builtin_throw_exception
-
- mov 5*8(%rsp),%r15 /* restore callee saved registers */
- mov 4*8(%rsp),%r14
- mov 3*8(%rsp),%r13
- mov 2*8(%rsp),%r12
- mov 1*8(%rsp),%rbp
- mov 0*8(%rsp),%rbx
- add $(7*8),%rsp /* free stack space */
- xor %rax,%rax /* return NULL */
- ret
+ xor v0,v0 /* return NULL */
+ jmp L_asm_calljavafunction2_return
jumptable_integer:
*******************************************************************************/
asm_call_jit_compiler:
- sub $8,%rsp /* keep stack 16-byte aligned */
+ /* keep stack 16-byte aligned */
+ sub $((3+ARG_CNT)*8+sizestackframeinfo),sp
- mov %rbx,(%rsp) /* save register */
-
- mov 8(%rsp),%r11 /* get return address */
- mov -1(%r11),%bl /* get function code */
- cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
- jne L_not_static_special
+ mov t0,0*8(sp) /* save register */
- sub $11,%r11 /* calculate address of immediate */
- jmp L_call_jit_compile
+ mov (3+ARG_CNT)*8+sizestackframeinfo(sp),itmp3 /* get return address */
+ mov -1(itmp3),%bl /* get function code */
+ cmp $0xd2,%bl /* called with `call *REG_ITMP2'? */
+ jne L_not_static_special
+
+ sub $11,itmp3 /* calculate address of immediate */
+ jmp L_call_jit_compile
L_not_static_special:
- cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
- jne L_not_virtual_interface
+ cmp $0xd0,%bl /* called with `call *REG_ITMP1' */
+ jne L_not_virtual_interface
- sub $7,%r11 /* calculate address of offset */
- mov (%r11),%r11d /* get offset (32-bit) */
- add %r10,%r11 /* add base address to get method address */
- jmp L_call_jit_compile
+ sub $7,itmp3 /* calculate address of offset */
+ mov (itmp3),itmp3l /* get offset (32-bit) */
+ add itmp2,itmp3 /* add base address to get method addr*/
+ jmp L_call_jit_compile
-L_not_virtual_interface: /* a call from asm_calljavamethod */
- xor %r11,%r11
+L_not_virtual_interface: /* a call from asm_calljavamethod */
+ xor itmp3,itmp3
L_call_jit_compile:
- mov (%rsp),%rbx /* restore register */
-
- sub $(24*8),%rsp /* 8 + 6*8 + 8*8 + 8*8 */
-
- mov %r11,0*8(%rsp) /* save address for method pointer */
-
- mov a0,1*8(%rsp) /* save arguments */
- mov a1,2*8(%rsp)
- mov a2,3*8(%rsp)
- mov a3,4*8(%rsp)
- mov a4,5*8(%rsp)
- mov a5,6*8(%rsp)
-
- movq fa0,7*8(%rsp)
- movq fa1,8*8(%rsp)
- movq fa2,9*8(%rsp)
- movq fa3,10*8(%rsp)
- movq fa4,11*8(%rsp)
- movq fa5,12*8(%rsp)
- movq fa6,13*8(%rsp)
- movq fa7,14*8(%rsp)
-
- movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
- movq %xmm9,16*8(%rsp)
- movq %xmm10,17*8(%rsp)
- movq %xmm11,18*8(%rsp)
- movq %xmm12,19*8(%rsp)
- movq %xmm13,20*8(%rsp)
- movq %xmm14,21*8(%rsp)
- movq %xmm15,22*8(%rsp)
-
- mov %rax,%rdi /* pass method pointer */
- call jit_compile
-
- mov 0*8(%rsp),%r11
-
- mov 1*8(%rsp),a0
- mov 2*8(%rsp),a1
- mov 3*8(%rsp),a2
- mov 4*8(%rsp),a3
- mov 5*8(%rsp),a4
- mov 6*8(%rsp),a5
-
- movq 7*8(%rsp),fa0
- movq 8*8(%rsp),fa1
- movq 9*8(%rsp),fa2
- movq 10*8(%rsp),fa3
- movq 11*8(%rsp),fa4
- movq 12*8(%rsp),fa5
- movq 13*8(%rsp),fa6
- movq 14*8(%rsp),fa7
-
- movq 15*8(%rsp),%xmm8
- movq 16*8(%rsp),%xmm9
- movq 17*8(%rsp),%xmm10
- movq 18*8(%rsp),%xmm11
- movq 19*8(%rsp),%xmm12
- movq 20*8(%rsp),%xmm13
- movq 21*8(%rsp),%xmm14
- movq 22*8(%rsp),%xmm15
-
- add $(24*8),%rsp
- add $8,%rsp /* keep stack 16-byte aligned */
-
- test %rax,%rax /* check for exception */
+ mov 0*8(sp),t0 /* restore register */
+ mov itmp3,0*8(sp) /* save address for method pointer */
+ mov itmp1,1*8(sp) /* save method pointer */
+
+ SAVE_ARGUMENT_REGISTERS(3)
+
+ mov sp,a0 /* create stackframe info */
+ add $((3+ARG_CNT)*8),a0 /* pass sfi */
+ xor a1,a1 /* if pv is NULL, use findmethod */
+ mov sp,a2 /* pass java sp */
+ add $((1+3+ARG_CNT)*8+sizestackframeinfo),a2
+ /* pass ra to java function */
+ mov ((3+ARG_CNT)*8+sizestackframeinfo)(sp),a3
+ mov a3,a4 /* xpc is equal to ra */
+ call stacktrace_create_extern_stackframeinfo
+
+ mov 1*8(sp),a0 /* pass method pointer */
+ call jit_compile
+ mov v0,1*8(sp) /* save return value */
+
+ mov sp,a0 /* remove stackframe info */
+ add $((3+ARG_CNT)*8),a0 /* pass sfi */
+ call stacktrace_remove_stackframeinfo
+
+ mov 0*8(sp),itmp3 /* restore address for method pointer */
+ mov 1*8(sp),v0 /* restore return value */
+
+ RESTORE_ARGUMENT_REGISTERS(3)
+
+ add $((3+ARG_CNT)*8+sizestackframeinfo),sp /* remove stack frame */
+
+ test v0,v0 /* check for exception */
je L_asm_call_jit_compiler_exception
- test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
+ test itmp3,itmp3 /* is address == 0 (asm_calljavamethod*/
je L_call_method
- mov %rax,(%r11) /* and now save the new pointer */
+ mov v0,(itmp3) /* and now save the new pointer */
L_call_method:
- jmp *%rax /* ...and now call the new method */
+ jmp *v0 /* ...and now call the new method */
L_asm_call_jit_compiler_exception:
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
call builtin_asm_get_exceptionptrptr
- mov %rax,itmp2
+ mov v0,itmp2 /* v0 == xptr */
#else
- lea _exceptionptr,itmp2
+ lea _no_threads_exceptionptr,itmp2
#endif
mov (itmp2),xptr /* get the exception pointer */
- movl $0,(itmp2) /* clear the exception pointer */
+ movl $0,(itmp2) /* clear exception pointer */
pop xpc /* delete return address */
sub $5,xpc /* faulting address is ra - 5 */
-
jmp asm_handle_exception
-/********************* function asm_handle_exception ***************************
+/* asm_handle_exception ********************************************************
* *
* This function handles an exception. It does not use the usual calling *
* conventions. The exception pointer is passed in REG_ITMP1 and the *
* the local exception table for a handler. If no one is found, it unwinds *
* stacks and continues searching the callers. *
* *
-* void asm_handle_exception (exceptionptr, exceptionpc); *
-* *
*******************************************************************************/
asm_handle_nat_exception:
- add $8,%rsp /* clear return address of native stub*/
+ add $8,sp /* clear return address of native stub*/
asm_handle_exception:
- sub $(4*8),%rsp
- mov xptr,0*8(%rsp) /* save exception pointer */
- mov xpc,1*8(%rsp) /* save exception pc */
-
- mov xpc,%rdi /* exception pc */
+ sub $((ARG_CNT+TMP_CNT)*8),sp /* create maybe-leaf stackframe */
+
+ SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
+ SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
+
+ mov $((ARG_CNT+TMP_CNT)*8),a3 /* prepare a3 for handle_exception */
+ mov $1,t0 /* set maybe-leaf flag */
+
+L_asm_handle_exception_stack_loop:
+ sub $(6*8),sp
+ mov xptr,0*8(sp) /* save exception pointer */
+ mov xpc,1*8(sp) /* save exception pc */
+ add sp,a3 /* calculate Java sp into a3... */
+ add $(6*8),a3
+ mov a3,3*8(sp) /* ...and save it */
+ mov t0,4*8(sp) /* save maybe-leaf flag */
+
+ mov xpc,a0 /* exception pc */
call codegen_findmethod
- mov %rax,itmp3
- mov %rax,2*8(%rsp) /* save data segment pointer */
+ mov v0,2*8(sp) /* save data segment pointer */
- mov 0*8(%rsp),%rax /* restore exception pointer */
- mov 1*8(%rsp),%r10 /* restore exception pc */
-
-ex_stack_loop:
- mov %rax,%rdi /* exception pointer */
- mov MethodPointer(itmp3),%rsi /* method pointer */
- mov xpc,%rdx /* exception pc */
- mov $0,%rcx
- mov $1,%r8 /* set noindent flag */
- call builtin_trace_exception
-
- mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
- mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
- test %rcx,%rcx /* if empty table skip */
- je empty_table
-
- lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
- mov 0*8(%rsp),xptr /* get xptr */
-
-ex_table_loop:
- mov 1*8(%rsp),xpc /* get xpc */
-
- mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
- cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
- jg ex_table_cont /* if (false) continue */
- mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
- cmp %rdx,xpc /* %rdx = (xpc < endpc) */
- jge ex_table_cont /* if (false) continue */
- mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
- test %rdx,%rdx /* NULL catches everything */
- je ex_handle_it
-
- cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
- jne L_class_loaded
-
- sub $(4*8),%rsp
- mov %rax,0*8(%rsp)
- mov %rcx,1*8(%rsp)
- mov %rdx,2*8(%rsp)
- mov %rdi,3*8(%rsp)
-
- mov %rdx,%rdi
- call load_class_bootstrap
-
- mov 0*8(%rsp),%rax
- mov 1*8(%rsp),%rcx
- mov 2*8(%rsp),%rdx
- mov 3*8(%rsp),%rdi
- add $(4*8),%rsp
-
-L_class_loaded:
- cmpl $0,offclasslinked(%rdx) /* check if class is linked */
- jne L_class_linked
-
- sub $(4*8),%rsp
- mov %rax,0*8(%rsp)
- mov %rcx,1*8(%rsp)
- mov %rdx,2*8(%rsp)
- mov %rdi,3*8(%rsp)
-
- mov %rdx,%rdi
- call link_class
-
- mov 0*8(%rsp),%rax
- mov 1*8(%rsp),%rcx
- mov 2*8(%rsp),%rdx
- mov 3*8(%rsp),%rdi
- add $(4*8),%rsp
-
-L_class_linked:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- push %rdx
+ mov 0*8(sp),a0 /* pass exception pointer */
+ mov 1*8(sp),a1 /* pass exception pc */
+ mov v0,a2 /* pass data segment pointer */
+ mov 3*8(sp),a3 /* pass Java stack pointer */
+ call exceptions_handle_exception
-_crit_restart1:
- mov 0(%rsp),%rdx
-#endif
+ test v0,v0
+ jz L_asm_handle_exception_not_catched
-_crit_begin1:
- mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
- mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
- mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
- mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
- mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
-_crit_end1:
- sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
+ mov v0,xpc /* move handlerpc into xpc */
+ mov 0*8(sp),xptr /* restore exception pointer */
+ mov 4*8(sp),t0 /* get maybe-leaf flag */
+ add $(6*8),sp /* free stack frame */
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- add $8,%rsp
-#endif
+ test t0,t0 /* test for maybe-leaf flag */
+ jz L_asm_handle_exception_no_leaf
- cmp %edx,%esi /* xptr is instanceof catchtype */
- ja ex_table_cont
-
-ex_handle_it:
- mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
+ RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
+ RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
- mov 0*8(%rsp),%rax /* restore exception pointer */
- add $(4*8),%rsp /* free stack frame */
+ add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
- jmp *xpc /* jump to the handler */
+L_asm_handle_exception_no_leaf:
+ jmp *xpc /* jump to the handler */
-ex_table_cont:
- lea ExEntrySize(%rdi),%rdi /* next exception table entry */
- dec %rcx /* decrement entry counter */
- test %rcx,%rcx /* if (t0 > 0) next entry */
- jg ex_table_loop
-
-empty_table:
- mov 0*8(%rsp),%rax /* restore exception pointer */
- mov 1*8(%rsp),%r10 /* restore exception pc */
- mov 2*8(%rsp),%r11 /* restore data segment pointer */
- add $(4*8),%rsp
-
- mov %rax,%rcx /* save exception pointer */
-
-ex_already_cleared:
- movl IsSync(%r11),%eax /* %rax = SyncOffset */
- test %rax,%rax /* if zero no monitorexit */
- je no_monitor_exit
-
-#if defined(USE_THREADS)
- add %rsp,%rax
- mov -8(%rax),%rdi
-
- sub $(4*8),%rsp
- mov %rcx,0*8(%rsp)
- mov %r10,1*8(%rsp)
- mov %r11,2*8(%rsp)
-
- call builtin_monitorexit
+L_asm_handle_exception_not_catched:
+ mov 0*8(sp),xptr /* restore exception pointer */
+ mov 2*8(sp),itmp3 /* restore data segment pointer */
+ mov 4*8(sp),t0 /* get maybe-leaf flag */
+ add $(6*8),sp
- mov 0*8(%rsp),%rcx
- mov 1*8(%rsp),%r10
- mov 2*8(%rsp),%r11
- add $(4*8),%rsp
-#endif
+ test t0,t0
+ jz L_asm_handle_exception_no_leaf_stack
-no_monitor_exit:
- mov FrameSize(%r11),%eax /* %eax = frame size */
- add %rax,%rsp /* unwind stack */
- mov %rsp,%rax /* %rax = pointer to save area */
+ add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
+ xor t0,t0 /* clear the isleaf flags */
- mov IntSave(%r11),%edx /* %edx = saved int register count*/
- test %edx,%edx
- je noint
-
- cmp $1,%edx
- je int1
- cmp $2,%edx
- je int2
- cmp $3,%edx
- je int3
- cmp $4,%edx
- je int4
- cmp $5,%edx
- je int5
-
- mov -48(%rax),%rbx
-int5:
- mov -40(%rax),%rbp
+L_asm_handle_exception_no_leaf_stack:
+ mov FrameSize(itmp3),itmp2l /* get frame size */
+ add sp,itmp2 /* pointer to save area */
+
+ mov IntSave(itmp3),a0l /* a0l = saved int register count */
+ test a0l,a0l
+ je noint
+
+ cmp $1,a0l
+ je int1
+ cmp $2,a0l
+ je int2
+ cmp $3,a0l
+ je int3
+ cmp $4,a0l
+ je int4
+
+ mov -5*8(itmp2),s0
int4:
- mov -32(%rax),%r12
+ mov -4*8(itmp2),s1
int3:
- mov -24(%rax),%r13
+ mov -3*8(itmp2),s2
int2:
- mov -16(%rax),%r14
+ mov -2*8(itmp2),s3
int1:
- mov -8(%rax),%r15
+ mov -1*8(itmp2),s4
- shl $3,%edx /* multiply by 8 bytes */
- sub %rdx,%rax
+ shl $3,a0l /* multiply by 8 bytes */
+ sub a0,itmp2
noint:
- mov FltSave(%r11),%edx /* %edx = saved flt register count*/
- test %edx,%edx
- je noflt
-
- cmpl $1,%edx
- je flt1
- cmpl $2,%edx
- je flt2
- cmpl $3,%edx
- je flt3
- cmpl $4,%edx
- je flt4
- cmpl $5,%edx
- je flt5
- cmpl $6,%edx
- je flt7
- cmpl $7,%edx
- je flt7
-
- movq -64(%rax),%xmm8
-flt7:
- movq -56(%rax),%xmm9
-flt6:
- movq -48(%rax),%xmm10
-flt5:
- movq -40(%rax),%xmm11
+#if 0
+ mov FltSave(itmp3),a0l /* a0l = saved flt register count */
+ test a0l,a0l
+ je noflt
+
+ cmpl $1,a0l
+ je flt1
+ cmpl $2,a0l
+ je flt2
+ cmpl $3,a0l
+ je flt3
+ cmpl $4,a0l
+ je flt4
+
+ movq -5*8(itmp2),%xmm11
flt4:
- movq -32(%rax),%xmm12
+ movq -4*8(itmp2),%xmm12
flt3:
- movq -24(%rax),%xmm13
+ movq -3*8(itmp2),%xmm13
flt2:
- movq -16(%rax),%xmm14
+ movq -2*8(itmp2),%xmm14
flt1:
- movq -8(%rax),%xmm15
+ movq -1*8(itmp2),%xmm15
-noflt:
- pop %r10 /* the new xpc is return address */
- sub $3,%r10 /* subtract 3 bytes for call */
-
- sub $(2*8),%rsp
- mov %rcx,0*8(%rsp)
- mov %r10,1*8(%rsp)
-
- mov %r10,%rdi
- call codegen_findmethod /* get the new data segment ptr */
- mov %rax,%r11
-
- mov 0*8(%rsp),%rcx
- mov 1*8(%rsp),%r10
- add $(2*8),%rsp
+noflt:
+#endif
+ mov FrameSize(itmp3),itmp2l /* get frame size */
+ add itmp2,sp /* unwind stack */
- mov %rcx,%rax /* restore saved exception pointer*/
+ /* exception pointer is still set */
+ pop xpc /* the new xpc is return address */
+ sub $3,xpc /* subtract 3 bytes for call */
- sub $(4*8),%rsp
-
- mov %rax,0*8(%rsp) /* save exception pointer */
- mov %r10,1*8(%rsp) /* save exception pc */
- mov %r11,2*8(%rsp) /* save data segment pointer */
-
- jmp ex_stack_loop
+ xor a3,a3 /* prepare a3 for handle_exception */
+
+ jmp L_asm_handle_exception_stack_loop
-/* asm_check_clinit ************************************************************
+/* asm_wrapper_patcher *********************************************************
- DOCUMENT ME!!!
+ XXX
Stack layout:
-
- 24 ra ; return address of patched call in java machine code
- 16 xmcode ; additional machine code (only for i386 and x86_64)
- 8 mcode ; machine code to patch back in
- 0 class ; pointer to class
+ 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_check_clinit:
- mov 0(%rsp),itmp1
- mov offclassinit(itmp1),itmp1l /* get initialized flag (int) */
- test itmp1,itmp1
- jnz L_is_initialized
-
- sub $(14*8),%rsp /* keep stack 16-byte aligned */
-
- mov a0,0*8(%rsp) /* save argument registers */
- mov a1,1*8(%rsp)
- mov a2,2*8(%rsp)
- mov a3,3*8(%rsp)
- mov a4,4*8(%rsp)
- mov a5,5*8(%rsp)
-
- movq fa0,6*8(%rsp) /* maybe cacao does not use all 8 */
- movq fa1,7*8(%rsp) /* argument register, but who knows */
- movq fa2,8*8(%rsp)
- movq fa3,9*8(%rsp)
- movq fa4,10*8(%rsp)
- movq fa5,11*8(%rsp)
- movq fa6,12*8(%rsp)
- movq fa7,13*8(%rsp)
-
- mov 14*8(%rsp),%rdi /* pass classinfo pointer */
- call initialize_class /* call class initialize function */
-
- mov 0*8(%rsp),a0 /* restore argument registers */
- mov 1*8(%rsp),a1
- mov 2*8(%rsp),a2
- mov 3*8(%rsp),a3
- mov 4*8(%rsp),a4
- mov 5*8(%rsp),a5
-
- movq 6*8(%rsp),fa0
- movq 7*8(%rsp),fa1
- movq 8*8(%rsp),fa2
- movq 9*8(%rsp),fa3
- movq 10*8(%rsp),fa4
- movq 11*8(%rsp),fa5
- movq 12*8(%rsp),fa6
- movq 13*8(%rsp),fa7
-
- add $(14*8),%rsp /* remove stack frame */
-
- test v0,v0 /* we had an exception */
- je L_initializererror
-
-L_is_initialized:
- mov 24(%rsp),itmp1 /* get return address */
- sub $5,itmp1 /* remove size of `call rel32' */
-
- mov 16(%rsp),itmp2 /* get xmcode machine code */
- movb itmp2b,(itmp1) /* patch back in 1 byte */
- mov 8(%rsp),itmp2 /* get mcode machine code */
- movl itmp2l,1(itmp1) /* patch back in 4 bytes */
-
- add $((3+1)*8),%rsp /* remove stub stack frame incl. ra */
-
- jmp *itmp1 /* jump to patched code an execute it */
-
-L_initializererror:
+asm_wrapper_patcher:
+ push bp /* save base pointer */
+ mov sp,bp /* move actual sp to bp */
+ sub $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),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 sp,a0 /* create stackframe info */
+ add $((3+ARG_CNT+TMP_CNT)*8),a0
+ xor a1,a1 /* if pv is NULL, use findmethod */
+ mov bp,a2 /* pass java sp */
+ add $((6+1)*8),a2
+ mov ((5+1)*8)(bp),a3 /* pass ra to java function */
+ mov a3,a4 /* xpc is equal to ra */
+ call stacktrace_create_extern_stackframeinfo
+
+ mov bp,a0 /* pass stack pointer */
+ add $((1+1)*8),a0 /* skip function pointer */
+ mov 1*8(bp),itmp3 /* get function pointer */
+ call *itmp3 /* call the patcher function */
+ mov v0,2*8(sp) /* save return value */
+
+ mov sp,a0 /* remove stackframe info */
+ add $((3+ARG_CNT+TMP_CNT)*8),a0
+ call stacktrace_remove_stackframeinfo
+
+ 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? */
+ jz L_asm_wrapper_patcher_exception
+ ret /* call new patched code */
+
+L_asm_wrapper_patcher_exception:
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
call builtin_asm_get_exceptionptrptr
- mov %rax,itmp2
+ mov v0,itmp2 /* v0 == xptr */
#else
- lea _exceptionptr,itmp2
+ lea _no_threads_exceptionptr,itmp2
#endif
mov (itmp2),xptr /* get the exception pointer */
- movl $0,(itmp2) /* clear the exception pointer */
-
- add $(3*8),%rsp /* remove stub stack frame */
-
- pop xpc /* delete return address */
- sub $5,xpc /* faulting address is ra - 5 */
+ movl $0,(itmp2) /* clear exception pointer */
+ pop xpc /* get and remove return address */
jmp asm_handle_exception
-
-/********************* function asm_builtin_monitorenter ***********************
-* *
-* Does null check and calls monitorenter or throws an exception *
-* *
-*******************************************************************************/
-
-#if defined(USE_THREADS)
-asm_builtin_monitorenter:
- test %rdi,%rdi
- je nb_monitorenter /* if (null) throw exception */
- jmp builtin_monitorenter /* else call builtin_monitorenter */
-
-nb_monitorenter:
- call new_nullpointerexception
- pop %r10 /* delete return address */
- sub $3,%r10 /* faulting address is ra - 3 */
- jmp asm_handle_exception
-#endif
-
-/********************* function asm_builtin_monitorexit ************************
-* *
-* Does null check and calls monitorexit or throws an exception *
-* *
-*******************************************************************************/
-
-#if defined(USE_THREADS)
-asm_builtin_monitorexit:
- test %rdi,%rdi
- je nb_monitorexit /* if (null) throw exception */
- jmp builtin_monitorexit /* else call builtin_monitorenter */
-
-nb_monitorexit:
- call new_nullpointerexception
- pop %r10 /* delete return address */
- sub $3,%r10 /* faulting address is ra - 3 */
- jmp asm_handle_exception
-#endif
-
-
-/********************* function asm_builtin_x2x ********************************
+/* asm_builtin_x2x *************************************************************
* *
* Wrapper functions for float to int corner cases *
* *
*******************************************************************************/
asm_builtin_f2i:
- sub $(14*8),%rsp
-
- mov %rdi,0*8(%rsp)
- mov %rsi,1*8(%rsp)
- mov %rdx,2*8(%rsp)
- mov %rcx,3*8(%rsp)
- mov %r8,4*8(%rsp)
- mov %r9,5*8(%rsp)
+ sub $(ARG_CNT*8),sp
- movq %xmm0,6*8(%rsp)
- movq %xmm1,7*8(%rsp)
- movq %xmm2,8*8(%rsp)
- movq %xmm3,9*8(%rsp)
- movq %xmm4,10*8(%rsp)
- movq %xmm5,11*8(%rsp)
- movq %xmm6,12*8(%rsp)
- movq %xmm7,13*8(%rsp)
+ SAVE_ARGUMENT_REGISTERS(0)
- movq %xmm8,%xmm0
+ movq ftmp1,fa0
call builtin_f2i
- mov 0*8(%rsp),%rdi
- mov 1*8(%rsp),%rsi
- mov 2*8(%rsp),%rdx
- mov 3*8(%rsp),%rcx
- mov 4*8(%rsp),%r8
- mov 5*8(%rsp),%r9
+ RESTORE_ARGUMENT_REGISTERS(0)
- movq 6*8(%rsp),%xmm0
- movq 7*8(%rsp),%xmm1
- movq 8*8(%rsp),%xmm2
- movq 9*8(%rsp),%xmm3
- movq 10*8(%rsp),%xmm4
- movq 11*8(%rsp),%xmm5
- movq 12*8(%rsp),%xmm6
- movq 13*8(%rsp),%xmm7
-
- add $(14*8),%rsp
+ add $(ARG_CNT*8),sp
ret
asm_builtin_f2l:
- sub $(14*8),%rsp
-
- mov %rdi,0*8(%rsp)
- mov %rsi,1*8(%rsp)
- mov %rdx,2*8(%rsp)
- mov %rcx,3*8(%rsp)
- mov %r8,4*8(%rsp)
- mov %r9,5*8(%rsp)
+ sub $(ARG_CNT*8),sp
- movq %xmm0,6*8(%rsp)
- movq %xmm1,7*8(%rsp)
- movq %xmm2,8*8(%rsp)
- movq %xmm3,9*8(%rsp)
- movq %xmm4,10*8(%rsp)
- movq %xmm5,11*8(%rsp)
- movq %xmm6,12*8(%rsp)
- movq %xmm7,13*8(%rsp)
+ SAVE_ARGUMENT_REGISTERS(0)
- movq %xmm8,%xmm0
+ movq ftmp1,fa0
call builtin_f2l
- mov 0*8(%rsp),%rdi
- mov 1*8(%rsp),%rsi
- mov 2*8(%rsp),%rdx
- mov 3*8(%rsp),%rcx
- mov 4*8(%rsp),%r8
- mov 5*8(%rsp),%r9
+ RESTORE_ARGUMENT_REGISTERS(0)
- movq 6*8(%rsp),%xmm0
- movq 7*8(%rsp),%xmm1
- movq 8*8(%rsp),%xmm2
- movq 9*8(%rsp),%xmm3
- movq 10*8(%rsp),%xmm4
- movq 11*8(%rsp),%xmm5
- movq 12*8(%rsp),%xmm6
- movq 13*8(%rsp),%xmm7
-
- add $(14*8),%rsp
+ add $(ARG_CNT*8),sp
ret
asm_builtin_d2i:
- sub $(14*8),%rsp
-
- mov %rdi,0*8(%rsp)
- mov %rsi,1*8(%rsp)
- mov %rdx,2*8(%rsp)
- mov %rcx,3*8(%rsp)
- mov %r8,4*8(%rsp)
- mov %r9,5*8(%rsp)
+ sub $(ARG_CNT*8),sp
- movq %xmm0,6*8(%rsp)
- movq %xmm1,7*8(%rsp)
- movq %xmm2,8*8(%rsp)
- movq %xmm3,9*8(%rsp)
- movq %xmm4,10*8(%rsp)
- movq %xmm5,11*8(%rsp)
- movq %xmm6,12*8(%rsp)
- movq %xmm7,13*8(%rsp)
+ SAVE_ARGUMENT_REGISTERS(0)
- movq %xmm8,%xmm0
+ movq ftmp1,fa0
call builtin_d2i
- mov 0*8(%rsp),%rdi
- mov 1*8(%rsp),%rsi
- mov 2*8(%rsp),%rdx
- mov 3*8(%rsp),%rcx
- mov 4*8(%rsp),%r8
- mov 5*8(%rsp),%r9
-
- movq 6*8(%rsp),%xmm0
- movq 7*8(%rsp),%xmm1
- movq 8*8(%rsp),%xmm2
- movq 9*8(%rsp),%xmm3
- movq 10*8(%rsp),%xmm4
- movq 11*8(%rsp),%xmm5
- movq 12*8(%rsp),%xmm6
- movq 13*8(%rsp),%xmm7
+ RESTORE_ARGUMENT_REGISTERS(0)
- add $(14*8),%rsp
+ add $(ARG_CNT*8),sp
ret
asm_builtin_d2l:
- sub $(14*8),%rsp
+ sub $(ARG_CNT*8),sp
- mov %rdi,0*8(%rsp)
- mov %rsi,1*8(%rsp)
- mov %rdx,2*8(%rsp)
- mov %rcx,3*8(%rsp)
- mov %r8,4*8(%rsp)
- mov %r9,5*8(%rsp)
+ SAVE_ARGUMENT_REGISTERS(0)
- movq %xmm0,6*8(%rsp)
- movq %xmm1,7*8(%rsp)
- movq %xmm2,8*8(%rsp)
- movq %xmm3,9*8(%rsp)
- movq %xmm4,10*8(%rsp)
- movq %xmm5,11*8(%rsp)
- movq %xmm6,12*8(%rsp)
- movq %xmm7,13*8(%rsp)
-
- movq %xmm8,%xmm0
+ movq ftmp1,fa0
call builtin_d2l
- mov 0*8(%rsp),%rdi
- mov 1*8(%rsp),%rsi
- mov 2*8(%rsp),%rdx
- mov 3*8(%rsp),%rcx
- mov 4*8(%rsp),%r8
- mov 5*8(%rsp),%r9
-
- movq 6*8(%rsp),%xmm0
- movq 7*8(%rsp),%xmm1
- movq 8*8(%rsp),%xmm2
- movq 9*8(%rsp),%xmm3
- movq 10*8(%rsp),%xmm4
- movq 11*8(%rsp),%xmm5
- movq 12*8(%rsp),%xmm6
- movq 13*8(%rsp),%xmm7
+ RESTORE_ARGUMENT_REGISTERS(0)
- add $(14*8),%rsp
- ret
-
-
-/* asm_builtin_checkarraycast **************************************************
-
- Does the cast check and eventually throws an exception.
-
-*******************************************************************************/
-
-asm_builtin_checkarraycast:
- sub $24,%rsp /* keep stack 16-byte aligned */
- mov %rdi,(%rsp) /* save object pointer */
- call builtin_checkarraycast /* builtin_checkarraycast */
- test %rax,%rax /* if (false) throw exception */
- je nb_carray_throw
- mov (%rsp),%rax /* return object pointer */
- add $24,%rsp /* free stack space */
- ret
-
-nb_carray_throw:
- call new_classcastexception
- add $24,%rsp
- pop %r10 /* delete return address */
- sub $3,%r10 /* faulting address is ra - 3 */
- jmp asm_handle_exception
-
-
-/* asm_builtin_aastore *********************************************************
-
- Checks if the object can be stored in the given array and stores the
- address if it's possible. This function can also throw some exceptions.
-
-*******************************************************************************/
-
-asm_builtin_aastore:
- sub $(3*8),%rsp /* allocate stack space */
- test %rdi,%rdi /* if null pointer throw exception */
- je nb_aastore_null
-
- movl offarraysize(%rdi),%eax /* load size */
- cmpl %eax,%esi /* do bound check */
- jae nb_aastore_bound /* if out of bounds throw exception */
-
- shl $3,%rsi /* index * 8 */
- mov %rdi,%r10
- add %rsi,%r10 /* add index * 8 to arrayref */
-
- mov %r10,(%rsp) /* save store position */
- mov %rdx,8(%rsp) /* save object */
-
- mov %rdx,%rsi /* object is second argument */
- call builtin_canstore /* builtin_canstore(arrayref,object) */
- test %rax,%rax /* if (false) throw exception */
- je nb_aastore_throw
-
- mov (%rsp),%r10 /* restore store position */
- mov 8(%rsp),%rdx /* restore object */
- mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
- add $(3*8),%rsp /* free stack space */
+ add $(ARG_CNT*8),sp
ret
-nb_aastore_null:
- call new_nullpointerexception
- add $24,%rsp
- pop %r10 /* delete return address */
- sub $3,%r10 /* faulting address is return adress - 3 */
- jmp asm_handle_exception
-nb_aastore_bound:
- mov %rsi,%rdi /* move index into a0 */
- call new_arrayindexoutofboundsexception
- add $24,%rsp
- pop %r10 /* delete return address */
- sub $3,%r10 /* faulting address is return adress - 3 */
- jmp asm_handle_exception
-
-nb_aastore_throw:
- call new_arraystoreexception
- add $24,%rsp
- pop %r10 /* delete return address */
- sub $3,%r10 /* faulting address is return adress - 3 */
- jmp asm_handle_exception
-
-
/******************* function asm_initialize_thread_stack **********************
* *
* initialized a thread stack *
asm_getclassvalues_atomic:
-_crit_restart2:
-_crit_begin2:
+_crit_restart:
+_crit_begin:
movl offbaseval(a0),itmp1l
movl offdiffval(a0),itmp2l
movl offbaseval(a1),itmp3l
-_crit_end2:
+_crit_end:
movl itmp1l,offcast_super_baseval(a2)
movl itmp2l,offcast_super_diffval(a2)
movl itmp3l,offcast_sub_baseval(a2)
asm_criticalsections:
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- .quad _crit_begin1
- .quad _crit_end1
- .quad _crit_restart1
- .quad _crit_begin2
- .quad _crit_end2
- .quad _crit_restart2
+ .quad _crit_begin
+ .quad _crit_end
+ .quad _crit_restart
#endif
.quad 0
-
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where