-/* jit/x86_64/asmpart.S - Java-C interface functions for x86_64
+/* vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Institut f. Computersprachen, TU Wien
- R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
- S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
- J. Wenninger
+ 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
This file is part of CACAO.
Reinhard Grafl
Christian Thalinger
- $Id: asmpart.S 1125 2004-06-03 21:30:30Z twisti $
+ $Id: asmpart.S 1735 2004-12-07 14:33:27Z twisti $
*/
#include "config.h"
-#include "offsets.h"
-
-
-#define MethodPointer -8
-#define FrameSize -12
-#define IsSync -16
-#define IsLeaf -20
-#define IntSave -24
-#define FltSave -28
-#define ExTableSize -32
-#define ExTableStart -32
-
-#define ExEntrySize -32
-#define ExStartPC -8
-#define ExEndPC -16
-#define ExHandlerPC -24
-#define ExCatchType -32
+#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 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
#define itmp2l %r10d
#define itmp3l %r11d
+#define itmp1b %al
+#define itmp2b %r10b
+#define itmp3b %r11b
+
#define xptr itmp1
#define xpc itmp2
/********************* exported functions and variables ***********************/
.globl asm_calljavafunction
+ .globl calljava_xhandler
.globl asm_calljavafunction2
.globl asm_calljavafunction2long
.globl asm_calljavafunction2double
+ .globl calljava_xhandler2
.globl asm_call_jit_compiler
.globl asm_handle_exception
.globl asm_handle_nat_exception
*******************************************************************************/
call_name:
- .ascii "calljavafunction\0\0"
-
.align 8
+
.quad 0 /* catch type all */
.quad calljava_xhandler /* handler pc */
.quad calljava_xhandler /* end pc */
lea asm_call_jit_compiler,%r11
call *%r11 /* call JIT compiler */
-calljava_jit:
-calljava_return:
-calljava_ret:
mov 0*8(%rsp),%rbp
mov 1*8(%rsp),%rbx
add $(3*8),%rsp /* free stack space */
*******************************************************************************/
call_name2:
- .ascii "calljavafunction2\0\0"
-
.align 8
+
.quad 0 /* catch type all */
.quad calljava_xhandler2 /* handler pc */
.quad calljava_xhandler2 /* end pc */
.long 0 /* intsave */
.long 0 /* isleaf */
.long 0 /* IsSync */
- .long 8 /* frame size */
+ .long 24 /* frame size */
.quad 0 /* method pointer (pointer to name) */
asm_calljavafunction2:
asm_calljavafunction2double:
asm_calljavafunction2long:
- sub $(1*8),%rsp /* keep stack 16-byte aligned */
+ 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 /* save method pointer for compiler */
- mov %rsi,%r11 /* arg count */
- mov %rcx,%r10 /* pointer to arg block */
+ mov %rdi,%rax /* move method pointer for compiler */
-#if 0
-L_noint_1:
- test %r11,%r11 /* maybe we have no args */
- jle calljava_copydone
-
- movb offjniitemtype(%r10),%dil /* which type has the current item */
- andb 0x02,%dil /* is this a float/double type */
- je L_int_1
+ mov %rsi,itmp3 /* arg count */
+ mov %rcx,itmp2 /* pointer to arg block */
+
+ test itmp3,itmp3 /* maybe we have no args... */
+ jle L_copy_done
+
+ 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 */
+
+L_register_copy:
+ add $sizejniblock,itmp2 /* goto next argument block */
+ dec itmp3 /* argument count - 1 */
+ jz L_register_copy_done
+ andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
+ jnz L_register_handle_float /* yes, handle it */
+
+ cmp $(INT_ARG_CNT - 1),%r12 /* are we out of integer argument */
+ je L_register_copy /* register? yes, next loop */
+
+ lea jumptable_integer,%rbp
+ mov 0(%rbp,%r12,8),%rbx
+ inc %r12 /* integer argument counter + 1 */
+ jmp *%rbx
+
+L_register_handle_float:
+ cmp $(FLT_ARG_CNT - 1),%r13 /* are we out of float argument */
+ je L_register_copy /* register? yes, next loop */
+
+ lea jumptable_float,%rbp
+ mov 0(%rbp,%r13,8),%rbx
+ inc %r13 /* float argument counter + 1 */
+ jmp *%rbx
-L_int_1:
-#endif
- mov offjniitem(%r10),%rdi /* move args into registers */
- sub $1,%r11
- test %r11,%r11
- je calljava_copydone
-
- mov offjniitem+sizejniblock*1(%r10),%rsi
- sub $1,%r11
- test %r11,%r11
- je calljava_copydone
-
- mov offjniitem+sizejniblock*2(%r10),%rdx
- mov offjniitem+sizejniblock*3(%r10),%rcx
-
-calljava_copydone:
- lea asm_call_jit_compiler,%r11
+L_register_copy_done:
+ mov %r15,itmp3 /* calculate remaining arguments after */
+ sub %r12,itmp3 /* register copy */
+ sub %r13,itmp3
+ jle L_copy_done /* are all assigned to registers? */
+
+ shl $3,itmp3 /* calculate stack size */
+ sub itmp3,%rsp /* stack frame for arguments */
+ mov %rsp,%rbx /* use %rbx as temp sp */
+
+ sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
+ add $1,%r15 /* initialize argument count */
+
+L_stack_copy_loop:
+ add $sizejniblock,itmp2 /* goto next argument block */
+ dec %r15 /* are there any arguments left? */
+ jz L_copy_done /* no test needed after dec */
+
+ andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
+ jnz L_stack_handle_float
+ dec %r12 /* arguments assigned to registers */
+ jge L_stack_copy_loop
+ jmp L_stack_copy
+
+L_stack_handle_float:
+ dec %r13 /* arguments assigned to registers */
+ jge L_stack_copy_loop
+
+L_stack_copy:
+ mov offjniitem(itmp2),itmp3 /* copy s8 argument onto stack */
+ mov itmp3,0(%rbx)
+ add $8,%rbx /* increase sp to next argument */
+ jmp L_stack_copy_loop
+
+L_copy_done:
+ lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
call *%r11 /* call JIT compiler */
+ 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 $(1*8),%rsp /* free stack space */
+ add $(7*8),%rsp /* free stack space */
ret
calljava_xhandler2:
mov %rax,%rdi /* 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 $(1*8),%rsp
+ add $(7*8),%rsp /* free stack space */
ret
+jumptable_integer:
+ .quad handle_a0
+ .quad handle_a1
+ .quad handle_a2
+ .quad handle_a3
+ .quad handle_a4
+ .quad handle_a5
+
+handle_a0:
+ mov offjniitem(itmp2),a0
+ jmp L_register_copy
+handle_a1:
+ mov offjniitem(itmp2),a1
+ jmp L_register_copy
+handle_a2:
+ mov offjniitem(itmp2),a2
+ jmp L_register_copy
+handle_a3:
+ mov offjniitem(itmp2),a3
+ jmp L_register_copy
+handle_a4:
+ mov offjniitem(itmp2),a4
+ jmp L_register_copy
+handle_a5:
+ mov offjniitem(itmp2),a5
+ jmp L_register_copy
+
+
+jumptable_float:
+ .quad handle_fa0
+ .quad handle_fa1
+ .quad handle_fa2
+ .quad handle_fa3
+ .quad handle_fa4
+ .quad handle_fa5
+ .quad handle_fa6
+ .quad handle_fa7
+
+handle_fa0:
+ movq offjniitem(itmp2),fa0
+ jmp L_register_copy
+handle_fa1:
+ movq offjniitem(itmp2),fa1
+ jmp L_register_copy
+handle_fa2:
+ movq offjniitem(itmp2),fa2
+ jmp L_register_copy
+handle_fa3:
+ movq offjniitem(itmp2),fa3
+ jmp L_register_copy
+handle_fa4:
+ movq offjniitem(itmp2),fa4
+ jmp L_register_copy
+handle_fa5:
+ movq offjniitem(itmp2),fa5
+ jmp L_register_copy
+handle_fa6:
+ movq offjniitem(itmp2),fa6
+ jmp L_register_copy
+handle_fa7:
+ movq offjniitem(itmp2),fa7
+ jmp L_register_copy
+
+
/****************** function asm_call_jit_compiler *****************************
* *
* invokes the compiler for untranslated JavaVM methods. *
add $(4*8),%rsp
L_class_linked:
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ push %rdx
+
+_crit_restart1:
+ mov 0(%rsp),%rdx
+#endif
+
+_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) */
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ add $8,%rsp
+#endif
+
cmp %edx,%esi /* xptr is instanceof catchtype */
ja ex_table_cont
jmp ex_stack_loop
-/********************* function asm_check_clinit *******************************
-* *
-* Does null check and calls monitorenter or throws an exception *
-* *
+/* asm_check_clinit ************************************************************
+
+ DOCUMENT ME!!!
+
+ Stack layout:
+
+ 32 ra ; return address of patched call in java machine code
+ 24 xmcode ; additional machine code (only for i386 and x86_64)
+ 16 mcode ; machine code to patch back in
+ 8 class ; pointer to class
+ 0 sp ; stack pointer of java stack frame + return address
+
*******************************************************************************/
asm_check_clinit:
- mov offclassinit(%rax),%r10d /* get initialized flag (int) */
- test %r10,%r10
+ mov 8(%rsp),itmp1
+ mov offclassinit(itmp1),itmp1l /* get initialized flag (int) */
+ test itmp1,itmp1
jnz L_is_initialized
- sub $(7*8),%rsp /* keep stack 16-byte aligned */
+ sub $(15*8),%rsp /* keep stack 16-byte aligned */
+
mov %rdi,0*8(%rsp) /* save argument registers */
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)
-
- mov %rax,%rdi /* pass classinfo pointer */
+
+ movq %xmm0,6*8(%rsp) /* maybe cacao does not use all 8 */
+ movq %xmm1,7*8(%rsp) /* argument register, but who knows */
+ 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)
+
+ mov 8+15*8(%rsp),%rdi /* pass classinfo pointer */
call class_init /* call class_init function */
mov 0*8(%rsp),%rdi /* restore argument registers */
mov 3*8(%rsp),%rcx
mov 4*8(%rsp),%r8
mov 5*8(%rsp),%r9
- add $(7*8),%rsp
- test %rax,%rax /* we had an exception */
+ 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 $(15*8),%rsp
+
+ test v0,v0 /* we had an exception */
je L_initializererror
L_is_initialized:
- mov (%rsp),%rax /* get return address */
- sub $23,%rax /* asm_putstatic call code size */
- movb $0xeb,(%rax) /* jmp rel8 */
- movb $21,1(%rax) /* 8-bit offset */
- ret
+ mov 32(%rsp),itmp1 /* get return address */
+ sub $5,itmp1 /* remove size of `call rel32' */
+
+ mov 24(%rsp),itmp2 /* get xmcode machine code */
+ movb itmp2b,(itmp1) /* patch back in 1 byte */
+ mov 16(%rsp),itmp2 /* get mcode machine code */
+ movl itmp2l,1(itmp1) /* patch back in 4 bytes */
+
+ add $(5*8),%rsp /* remove stub stack frame incl. ra */
+
+ jmp *itmp1 /* jump to patched code an execute it */
L_initializererror:
+ add $(4*8),%rsp /* remove stub stack frame */
+
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
call builtin_asm_get_exceptionptrptr
mov %rax,itmp2
#endif
pop xpc /* delete return address */
- sub $3,xpc /* faulting address is return adress - 3 */
+ sub $5,xpc /* faulting address is ra - 5 */
jmp asm_handle_exception
jmp builtin_monitorenter /* else call builtin_monitorenter */
nb_monitorenter:
- mov string_java_lang_NullPointerException,%rdi
- call new_exception
-
+ call new_nullpointerexception
pop %r10 /* delete return address */
sub $3,%r10 /* faulting address is return adress - 3 */
jmp asm_handle_exception
jmp builtin_monitorexit /* else call builtin_monitorenter */
nb_monitorexit:
- mov string_java_lang_NullPointerException,%rdi
- call new_exception
-
+ call new_nullpointerexception
pop %r10 /* delete return address */
sub $3,%r10 /* faulting address is return adress - 3 */
jmp asm_handle_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
+ 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:
- mov string_java_lang_ClassCastException,%rdi
- call new_exception
-
- add $24,%rsp
- pop %r10 /* delete return address */
- sub $3,%r10 /* faulting address is return adress - 3 */
- jmp asm_handle_exception
+ call new_classcastexception
+ add $24,%rsp
+ pop %r10 /* delete return address */
+ sub $3,%r10 /* faulting address is return adress - 3 */
+ jmp asm_handle_exception
/******************* function asm_builtin_aastore ******************************
ret
nb_aastore_null:
- mov string_java_lang_NullPointerException,%rdi
- call new_exception
-
+ call new_nullpointerexception
add $24,%rsp
- pop %r10 /* delete return address */
+ pop %r10 /* delete return address */
sub $3,%r10 /* faulting address is return adress - 3 */
jmp asm_handle_exception
nb_aastore_bound:
- mov string_java_lang_ArrayIndexOutOfBoundsException,%rdi
- call new_exception_int /* %rsi already contains the index */
-
+ mov %rsi,%rdi /* move index into a0 */
+ call new_arrayindexoutofboundsexception
add $24,%rsp
- pop %r10 /* delete return address */
+ pop %r10 /* delete return address */
sub $3,%r10 /* faulting address is return adress - 3 */
jmp asm_handle_exception
nb_aastore_throw:
- mov string_java_lang_ArrayStoreException,%rdi
- call new_exception
-
+ call new_arraystoreexception
add $24,%rsp
- pop %r10 /* delete return address */
+ pop %r10 /* delete return address */
sub $3,%r10 /* faulting address is return adress - 3 */
jmp asm_handle_exception
ret
-asm_getclassvalues_atomic:
-_crit_restart2:
-_crit_begin2:
+asm_getclassvalues_atomic:
+_crit_restart2:
+_crit_begin2:
movl offbaseval(a0),itmp1l
movl offdiffval(a0),itmp2l
movl offbaseval(a1),itmp3l
-_crit_end2:
+_crit_end2:
movl itmp1l,offcast_super_baseval(a2)
movl itmp2l,offcast_super_diffval(a2)
movl itmp3l,offcast_sub_baseval(a2)
.data
-asm_criticalsections:
+asm_criticalsections:
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- .long _crit_begin1
- .long _crit_end1
- .long _crit_restart1
- .long _crit_begin2
- .long _crit_end2
- .long _crit_restart2
+ .quad _crit_begin1
+ .quad _crit_end1
+ .quad _crit_restart1
+ .quad _crit_begin2
+ .quad _crit_end2
+ .quad _crit_restart2
#endif
- .long 0
+ .quad 0
/*