-/* jit/i386/asmpart.S - Java-C interface functions for i386
+/* vm/jit/i386/asmpart.S - Java-C interface functions for i386
- 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 848 2004-01-05 10:51:58Z twisti $
+ Changes: Joseph Wenninger
-*/
+ $Id: asmpart.S 1735 2004-12-07 14:33:27Z twisti $
+*/
-#include "offsets.h"
-/* data segment offsets */
+#include "config.h"
+#include "vm/jit/i386/offsets.h"
+#include "vm/jit/i386/asmoffsets.h"
-#define MethodPointer -4
-#define FrameSize -8
-#define IsSync -12
-#define IsLeaf -16
-#define IntSave -20
-#define FltSave -24
-#define ExTableSize -28
-#define ExTableStart -28
-#define ExEntrySize -16
-#define ExStartPC -4
-#define ExEndPC -8
-#define ExHandlerPC -12
-#define ExCatchType -16
+#define itmp1 %eax
+#define itmp2 %ecx
+#define itmp3 %edx
+#define itmp1b %al
+#define itmp2b %cl
+#define itmp3b %dl
.text
/********************* exported functions and variables ***********************/
- .globl has_no_x_instr_set
.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_dumpregistersandcall
.globl asm_handle_builtin_exception
.globl asm_handle_nat_exception
.globl asm_handle_exception
.globl asm_initialize_thread_stack
.globl asm_switchstackandcall
.globl asm_getcallingmethod
-
-
+ .globl asm_builtin_new
+ .globl asm_criticalsections
+ .globl asm_getclassvalues_atomic
+ .globl asm_prepare_native_stackinfo
+ .globl asm_remove_native_stackinfo
/*************************** imported functions *******************************/
.globl jit_compile
.globl builtin_throw_exception
.globl builtin_trace_exception
.globl class_java_lang_Object
- .globl findmethod
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- .globl cast_lock
- .globl cast_unlock
-#endif
-
-
-/*********************** function has_no_x_instr_set ***************************
-* *
-* determines if the byte support instruction set (21164a and higher) *
-* is available. *
-* *
-* Use it on i386 architecture to init the fpu. *
-* *
-*******************************************************************************/
-
-has_no_x_instr_set:
- finit /* intitialize the fpu */
-
- pushl $0x027f /* Round to nearest, 53-bit mode, exceptions masked */
- fldcw (%esp)
- addl $4,%esp
-
- xor %eax,%eax /* result code 0 (not used for i386) */
- ret
+ .globl codegen_findmethod
+ .globl callgetexceptionptrptr
+ .globl asm_throw_and_handle_exception
+ .globl asm_throw_and_handle_hardware_arithmetic_exception
/********************* function asm_calljavafunction ***************************
.long calljava_xhandler /* end pc */
.long asm_calljavafunction /* start pc */
.long 1 /* extable size */
+ .long 0 /* line number table start */
+ .long 0 /* line number table size */
.long 0 /* fltsave */
.long 0 /* intsave */
.long 0 /* isleaf */
.long 0 /* method pointer (pointer to name) */
asm_calljavafunction:
- push %ebp /* allocate stack space */
- mov %esp, %ebp
+ push %ebp /* allocate stack space */
+ mov %esp, %ebp
- push %ebx /* save registers */
- push %esi
- push %edi
+ push %ebx /* save registers */
+ push %esi
+ push %edi
- sub $32,%esp /* pass the remaining parameters */
- xor %edx,%edx
+ sub $32,%esp /* pass the remaining parameters */
+ xor %edx,%edx
- mov %edx,28(%esp) /* convert parms to 8 byte */
- mov 24(%ebp),%eax
- mov %eax,24(%esp)
+ mov %edx,28(%esp) /* convert parms to 8 byte */
+ mov 24(%ebp),%eax
+ mov %eax,24(%esp)
- mov %edx,20(%esp)
- mov 20(%ebp),%eax
- mov %eax,16(%esp)
+ mov %edx,20(%esp)
+ mov 20(%ebp),%eax
+ mov %eax,16(%esp)
- mov %edx,12(%esp)
- mov 16(%ebp),%eax
- mov %eax,8(%esp)
+ mov %edx,12(%esp)
+ mov 16(%ebp),%eax
+ mov %eax,8(%esp)
- mov %edx,4(%esp)
- mov 12(%ebp),%eax
- mov %eax,(%esp)
+ mov %edx,4(%esp)
+ mov 12(%ebp),%eax
+ mov %eax,(%esp)
- mov 8(%ebp),%eax /* move function pointer to %eax */
+ mov 8(%ebp),%eax /* move function pointer to %eax */
- lea asm_call_jit_compiler,%edx
- call *%edx /* call JIT compiler */
+ lea asm_call_jit_compiler,%edx
+ call *%edx /* call JIT compiler */
-calljava_return:
- add $32,%esp
- pop %edi /* restore registers */
- pop %esi
- pop %ebx
- leave
- ret
+ add $32,%esp
+ pop %edi /* restore registers */
+ pop %esi
+ pop %ebx
+ leave
+ ret
calljava_xhandler:
- push %eax /* pass exception pointer */
- call builtin_throw_exception
- add $4,%esp
+ push %eax /* pass exception pointer */
+ call builtin_throw_exception
+ add $4,%esp
- add $32,%esp
- pop %edi /* restore registers */
- pop %esi
- pop %ebx
- leave
- ret
-
+ add $32,%esp
+ pop %edi /* restore registers */
+ pop %esi
+ pop %ebx
+ leave
+ ret
/********************* function asm_calljavafunction ***************************
* method into machine code. *
* *
* C-prototype: *
-* javaobject_header *asm_calljavamethod (methodinfo *m, *
-* void *arg1, void *arg2, void *arg3, void *arg4); *
+* javaobject_header *asm_calljavafunction2(methodinfo *m, *
+* u4 count, u4 size, void *callblock); *
* *
*******************************************************************************/
.long calljava_xhandler2 /* end pc */
.long asm_calljavafunction2 /* start pc */
.long 1 /* extable size */
+ .long 0 /* line number table start */
+ .long 0 /* line number table size */
.long 0 /* fltsave */
.long 0 /* intsave */
.long 0 /* isleaf */
asm_calljavafunction2:
asm_calljavafunction2double:
asm_calljavafunction2long:
- push %ebp /* save ebp */
-
- mov %esp,%eax /* save stackptr */
- mov 20(%esp),%ebp
-
- push %ebx /* save registers */
- push %esi
- push %edi
-
- sub $32,%esp
-
- mov sizejniblock*3+offjniitem+4(%ebp),%ebx
- mov %ebx,28(%esp)
- mov sizejniblock*3+offjniitem(%ebp),%ebx
- mov %ebx,24(%esp)
-
- mov sizejniblock*2+offjniitem+4(%ebp),%ebx
- mov %ebx,20(%esp)
- mov sizejniblock*2+offjniitem(%ebp),%ebx
- mov %ebx,16(%esp)
-
-
- mov sizejniblock+offjniitem+4(%ebp),%ebx
- mov %ebx,12(%esp)
- mov sizejniblock+offjniitem(%ebp),%ebx
- mov %ebx,8(%esp)
-
- mov offjniitem+4(%ebp),%ebx
- mov %ebx,4(%esp)
- mov offjniitem(%ebp),%ebx
- mov %ebx,0(%esp)
-
- mov %eax,%ebp
- mov 8(%ebp),%eax /* move function pointer to %eax */
-
- lea asm_call_jit_compiler,%edx
- call *%edx /* call JIT compiler */
+ push %ebp
+ mov %esp,%ebp /* save stackptr */
+
+ push %ebx /* save registers */
+ push %esi
+ push %edi
+
+ mov 20(%ebp),%eax /* pointer to arg block */
+ mov 12(%ebp),%ecx /* arg count */
+ test %ecx,%ecx /* maybe we have no args */
+ jle calljava_copydone
+
+ mov %ecx,%edx /* calculate stack size */
+ shl $3,%edx
+ mov %edx,%esi /* save in callee saved register */
+ sub %esi,%esp /* stack frame for arguments */
+ mov %esp,%edi
+
+calljava_copyloop:
+ mov offjniitem(%eax),%edx
+ mov %edx,0(%edi)
+ mov offjniitem+4(%eax),%edx
+ mov %edx,4(%edi)
+
+ sub $1,%ecx /* are there any args left? */
+ test %ecx,%ecx
+ jle calljava_copydone
+
+ add $sizejniblock,%eax /* goto next argument block */
+ add $8,%edi /* increase sp to next argument */
+ jmp calljava_copyloop
+
+calljava_copydone:
+ mov 8(%ebp),%eax /* move function pointer to %eax */
+
+ lea asm_call_jit_compiler,%edx
+ call *%edx /* call JIT compiler */
calljava_return2:
- add $32,%esp
- pop %edi /* restore registers */
- pop %esi
- pop %ebx
- leave
- ret
+ add %esi,%esp /* remove arg stack frame */
+ pop %edi /* restore registers */
+ pop %esi
+ pop %ebx
+ leave
+ ret
calljava_xhandler2:
- push %eax /* pass exception pointer */
- call builtin_throw_exception
- add $4,%esp
-
- add $32,%esp
- pop %edi /* restore registers */
- pop %esi
- pop %ebx
- leave
- ret
+ push %eax /* pass exception pointer */
+ call builtin_throw_exception
+ add $4,%esp
+
+ add %esi,%esp /* remove arg stack frame */
+ pop %edi /* restore registers */
+ pop %esi
+ pop %ebx
+ leave
+ ret
/****************** function asm_call_jit_compiler *****************************
* *
*******************************************************************************/
-
asm_call_jit_compiler:
- push %ebx /* save register */
- push %ebp
-
- mov 8(%esp),%ebp /* get return address (2 push) */
- mov -1(%ebp),%bl /* get function code */
- cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
- jne L_not_static_special
-
- sub $6,%ebp /* calculate address of immediate */
- jmp L_call_jit_compile
+ push %ebx /* save register */
+ push %ebp
+
+ mov 8(%esp),%ebp /* get return address (2 push) */
+ mov -1(%ebp),%bl /* get function code */
+ cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
+ jne L_not_static_special
+
+ sub $6,%ebp /* calculate address of immediate */
+ jmp L_call_jit_compile
L_not_static_special:
- cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
- jne L_not_virtual_interface
-
- sub $6,%ebp /* calculate address of offset */
- mov (%ebp),%ebp /* get offset */
- add %ecx,%ebp /* add base address to get method address */
- jmp L_call_jit_compile
+ cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
+ jne L_not_virtual_interface
+
+ sub $6,%ebp /* calculate address of offset */
+ mov (%ebp),%ebp /* get offset */
+ add itmp2,%ebp /* add base address to get method address */
+ jmp L_call_jit_compile
L_not_virtual_interface: /* a call from asm_calljavafunction */
- xor %ebp,%ebp
+ xor %ebp,%ebp
L_call_jit_compile:
- push %ebp /* save address for method pointer */
+ push %ebp /* save address for method pointer */
- push %eax /* push methodpointer on stack */
- call jit_compile
- add $4,%esp
+ push %eax /* push methodpointer on stack */
+ call jit_compile
+ add $4,%esp
- pop %ebp /* restore address for method pointer */
- test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
- je L_call_method
-
- mov %eax,(%ebp) /* and now save the new pointer */
+ pop %ebp /* restore address for method pointer */
+
+ test %eax,%eax /* check for exception */
+ je L_exception
+
+ test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
+ je L_call_method
+
+ mov %eax,(%ebp) /* and now save the new pointer */
L_call_method:
- pop %ebp /* restore registers */
- pop %ebx
-
- jmp *%eax /* ...and now call the new method */
+ pop %ebp /* restore registers */
+ pop %ebx
+
+ jmp *%eax /* ...and now call the new method */
+L_exception:
+ pop %ebp /* restore registers */
+ pop %ebx
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ call builtin_asm_get_exceptionptrptr
+ mov %eax,%ecx
+ mov (%ecx),%eax /* get the exception pointer */
+ movl $0,(%ecx) /* clear the exception pointer */
+#else
+ lea _exceptionptr,%ecx
+ mov (%ecx),%eax /* get the exception pointer */
+ movl $0,(%ecx) /* clear the exception pointer */
+#endif
-/****************** function asm_dumpregistersandcall **************************
-* *
-* This funtion saves all callee saved registers and calls the function *
-* which is passed as parameter. *
-* *
-* This function is needed by the garbage collector, which needs to access *
-* all registers which are stored on the stack. Unused registers are *
-* cleared to avoid interferances with the GC. *
-* *
-* void asm_dumpregistersandcall (functionptr f); *
-* *
-*******************************************************************************/
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+
+L_refillinStacktrace: /*a compilation error should cause a stacktrace
+ which starts at the method call, which caused
+ the compilation of the new function. Until this
+ point the trace is invalid anyways, since it is
+ not complete. Compared to other runtimes it will
+ not be correct either, since we report eg class
+ not found errors too early, since we always
+ compile methods completely*/
+ push %ecx /* store fault adress */
+ push %eax /* temporarily save exception pointer*/
+ call builtin_asm_get_stackframeinfo
+ push %eax /* save location of thread specific stack info head pointer */
+ mov (%eax),%ecx /* save old value of pointer*/
+ push %ecx
+ mov %esp,(%eax) /*store pointer to this structure*/
+ mov 8(%esp),%eax /* get the exception pointer again*/
+ movl $0,8(%esp) /*mark this block as native*/
+ push $0 /*used for the jni_callblock structure*/
+ push %eax /*save eax for later */
+ /* get fillInStackTrace method*/
+ push utf_fillInStackTrace_desc
+ push utf_fillInStackTrace_name
+ mov offobjvftbl(%eax),%ecx
+ mov offclass(%ecx),%eax
+ push %eax
+ call class_resolvemethod
+ add $12,%esp
+ push $0
+ push $4 /*TYPE_ADR*/
+ push %esp
+ push $sizejniblock
+ push $1
+ push %eax
+ call asm_calljavafunction2
+ add $24,%esp
+
+ /*remove native stack info */
+ mov 8(%esp),%ecx
+ mov 12(%esp),%eax
+ mov %ecx,(%eax)
+ mov (%esp),%eax
+ add $20,%esp
+ pop %ecx
+
+
+ jmp asm_handle_exception
-asm_dumpregistersandcall:
- xor %eax,%eax
- mov %eax,(%eax)
-
- push %ebp
- push %ecx
- push %edx
- push %ebx
- push %esi
- push %edi
-
- mov 4(%ebp),%eax /* load function pointer */
- call *%eax /* call function */
-
- pop %edi
- pop %esi
- pop %ebx
- pop %edx
- pop %ecx
- pop %ebp
-
- ret
-
/********************* function asm_handle_exception ***************************
* *
* *
*******************************************************************************/
-asm_handle_builtin_exception:
- add $4,%esp /* clear return address of this call */
- mov (%esp),%eax /* get exceptionptr */
- leave /* leave builtin function */
- mov (%esp),%edx /* get exceptionpc */
- sub $2,%edx /* size of builtin call */
- jmp asm_handle_exception
-
asm_handle_nat_exception:
add $4,%esp /* clear return address of native stub */
asm_handle_exception:
+asm_handle_exception_loop:
push %ebp
mov %esp,%ebp
push %eax /* save exception pointer */
push %ecx /* save exception pc */
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- call cast_lock
-#endif
-
- call findmethod /* get the data segment ptr */
+ call codegen_findmethod /* get the data segment ptr */
mov %eax,%edx
mov -4(%ebp),%eax
push %edi
ex_stack_loop:
- sub $16,%esp
+ sub $20,%esp
mov %eax,(%esp) /* exception pointer */
mov MethodPointer(%edx),%eax /* method pointer */
mov %eax,4(%esp)
mov %ecx,8(%esp) /* exception pc */
- movl $1,12(%esp) /* set no unwind flag */
+ movl $0,12(%esp) /* line number */
+ movl $1,16(%esp) /* set no unwind flag */
call builtin_trace_exception
- add $16,%esp
-
+ add $20,%esp
mov -12(%ebp),%esi /* %esi = data segment pointer */
mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
test %ecx,%ecx /* if empty table skip */
test %ebx,%ebx /* NULL catches everything */
je ex_handle_it
- mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
- mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
- mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
- mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
- mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
- sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
- cmp %ebx,%esi /* xptr is instanceof catchtype */
- ja ex_table_cont
+ cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
+ jne L_class_loaded
+
+ sub $3*4,%esp
+ mov %eax,1*4(%esp) /* save not callee saved regs */
+ mov %ecx,2*4(%esp)
+
+ mov %ebx,0*4(%esp) /* exception class is argument */
+ call class_load
+
+ mov 0*4(%esp),%ebx
+ mov 1*4(%esp),%eax
+ mov 2*4(%esp),%ecx
+ add $3*4,%esp
+
+L_class_loaded:
+ cmpl $0,offclasslinked(%ebx)
+ jne L_class_linked
+
+ sub $3*4,%esp
+ mov %eax,1*4(%esp) /* save not callee saved regs */
+ mov %ecx,2*4(%esp)
+
+ mov %ebx,0*4(%esp) /* exception class is argument */
+ call class_link
+
+ mov 0*4(%esp),%ebx
+ mov 1*4(%esp),%eax
+ mov 2*4(%esp),%ecx
+ add $3*4,%esp
+
+L_class_linked:
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ push %ebx
+
+_crit_restart1:
+ mov 0(%esp),%ebx
+#endif
+
+_crit_begin1:
+ mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
+ mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
+ mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
+ mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
+ mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
+_crit_end1:
+ sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ add $4,%esp
+#endif
+
+ cmp %ebx,%esi /* xptr is instanceof catchtype */
+ ja ex_table_cont
ex_handle_it:
mov ExHandlerPC(%edi),%edx
add $8,%esp /* suck %ecx, %edx */
pop %eax /* restore xptr */
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- call cast_unlock
-#endif
-
leave
jmp *%edx /* jump to exception handler */
pop %ecx /* the new xpc is return address */
sub $2,%ecx
- jmp asm_handle_exception
+ jmp asm_handle_exception_loop
-/********************* function asm_check_clinit *******************************
-* *
-* Does null check and calls monitorenter or throws an exception *
-* *
+/* asm_check_clinit ************************************************************
+
+ DOCUMENT ME!!!
+
+ Stack layout:
+
+ 16 ra ; return address of patched call in java machine code
+ 12 xmcode ; additional machine code (only for i386 and x86_64)
+ 8 mcode ; machine code to patch back in
+ 4 class ; pointer to class
+ 0 sp ; stack pointer of java stack frame + return address
+
*******************************************************************************/
asm_check_clinit:
- mov offclassinit(%eax),%ecx /* get initialized flag */
- test %ecx,%ecx
- jnz L_is_initialized
+ mov 4(%esp),%eax /* get fieldinfo's class pointer */
+ mov offclassinit(%eax),%eax /* get initialized flag */
+ test %eax,%eax
+ jnz L_is_initialized
+
+ /*3*4 bytes*/
+ mov 16(%esp),itmp1
+ push itmp1 /*return adress into java machine code */
+ mov 4(%esp),itmp1
+ push itmp1 /*begin of java stack frame*/
+ pushl $0 /*internal (invisible) method*/
+ call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
+ data onto the stack */
+
+ sub $4,%esp
+ mov 20+4+4(%esp),itmp1 /* get class pointer */
+ mov itmp1,(%esp) /* store class pointer as a0 */
+ call class_init /* call class_init function */
+ add $4,%esp
+
+ call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
+ into java machine code on stack */
+ add $4,%esp /* ret address no longer needed, is still
+ on stack a few bytes above */
+
+ test %eax,%eax /* we had an exception */
+ je L_initializererror
- push %eax /* pass classinfo pointer */
- call class_init /* call class_init function */
- add $4,%esp
-
L_is_initialized:
- mov (%esp),%eax /* get return address */
- sub $12,%eax /* asm_putstatic call code size */
- movb $0xeb,(%eax) /* jmp rel8 */
- movl $10,1(%eax) /* 32-bit offset */
- ret
+ mov 16(%esp),itmp1 /* get return address */
+ sub $5,itmp1 /* remove size of `call rel32' */
+
+ mov 12(%esp),itmp2 /* get xmcode machine code */
+ movb itmp2b,(itmp1) /* patch back in 1 byte */
+ mov 8(%esp),itmp2 /* get mcode machine code */
+ mov itmp2,1(itmp1) /* patch back in 4 bytes */
+
+ add $(5*4),%esp /* remove stub stack frame incl. ra */
+
+ jmp *itmp1 /* jump to patched code an execute it */
+
+L_initializererror:
+ add $(4*4),%esp /* remove stub stack frame */
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ call builtin_asm_get_exceptionptrptr
+ mov %eax,%ecx
+ mov (%ecx),%eax /* get the exception pointer */
+ movl $0,(%ecx) /* clear the exception pointer */
+#else
+ lea _exceptionptr,%ecx
+ mov (%ecx),%eax /* get the exception pointer */
+ movl $0,(%ecx) /* clear the exception pointer */
+#endif
+
+ pop itmp2 /* get and delete ra */
+ sub $5,itmp2 /* faulting address is ra - 5 */
+
+ jmp asm_handle_exception
+
-
/********************* function asm_builtin_monitorenter ***********************
* *
* Does null check and calls monitorenter or throws an exception *
*******************************************************************************/
asm_builtin_monitorenter:
- cmpl $0,4(%esp)
- je nb_monitorenter /* if (null) throw exception */
- jmp builtin_monitorenter /* else call builtin_monitorenter */
+ cmpl $0,4(%esp)
+ je nb_monitorenter /* if (null) throw exception */
+ jmp builtin_monitorenter /* else call builtin_monitorenter */
nb_monitorenter:
- popl %ecx /* delete return address */
- subl $2,%ecx /* faulting address is return adress - 2 */
- movl proto_java_lang_NullPointerException,%eax
- jmp asm_handle_exception
-
+ mov string_java_lang_NullPointerException,%eax
+ pop %ecx
+ sub $2,%ecx
+ jmp asm_throw_and_handle_exception
+
+#if 0
+ push string_java_lang_NullPointerException
+ call new_exception
+ add $(1*4),%esp
+
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+ jmp asm_handle_exception
+#endif
/********************* function asm_builtin_monitorexit ************************
* *
*******************************************************************************/
asm_builtin_monitorexit:
- mov 4(%esp),%eax
- test %eax,%eax
- je nb_monitorexit /* if (null) throw exception */
- push %ecx /* save registers which could be used */
- push %edx
- push %eax
- call builtin_monitorexit /* else call builtin_monitorenter */
- add $4,%esp
- pop %edx /* restore registers which could be used */
- pop %ecx
- ret
+ mov 4(%esp),%eax
+ test %eax,%eax
+ je nb_monitorexit /* if (null) throw exception */
+ push %ecx /* save registers which could be used */
+ push %edx
+ push %eax
+ call builtin_monitorexit /* else call builtin_monitorenter */
+ add $4,%esp
+ pop %edx /* restore registers which could be used */
+ pop %ecx
+ ret
nb_monitorexit:
- popl %ecx /* delete return address */
- subl $2,%ecx /* faulting address is return adress - 2 */
- movl proto_java_lang_NullPointerException,%eax
- jmp asm_handle_exception
-
+ mov string_java_lang_NullPointerException,%eax
+ pop %ecx
+ sub $2,%ecx
+ jmp asm_throw_and_handle_exception
+
+#if 0
+ push string_java_lang_NullPointerException
+ call new_exception
+ add $(1*4),%esp
+
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+ jmp asm_handle_exception
+#endif
/************************ function asm_builtin_ldiv ****************************
* *
*******************************************************************************/
asm_builtin_ldiv:
- mov 12(%esp),%eax
- or 16(%esp),%eax
- test %eax,%eax /* if (null) throw exception */
- je nb_ldiv
+ mov 12(%esp),%eax
+ or 16(%esp),%eax
+ test %eax,%eax /* if (null) throw exception */
+ je nb_ldiv
- jmp builtin_ldiv
+ jmp builtin_ldiv
nb_ldiv:
- pop %ecx /* delete return address */
- sub $2,%ecx /* faulting address is return adress - 2 */
- mov proto_java_lang_ArithmeticException,%eax
- jmp asm_handle_exception
-
+ pop %ecx
+ sub $2,%ecx
+ jmp asm_throw_and_handle_hardware_arithmetic_exception
+#if 0
+ push string_java_lang_ArithmeticException_message
+ push string_java_lang_ArithmeticException
+ call new_exception_message
+ add $(2*4),%esp
+
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+ jmp asm_handle_exception
+#endif
/************************ function asm_builtin_lrem ****************************
* *
*******************************************************************************/
asm_builtin_lrem:
- mov 12(%esp),%eax
- or 16(%esp),%eax
- test %eax,%eax /* if (null) throw exception */
- je nb_lrem
+ mov 12(%esp),%eax
+ or 16(%esp),%eax
+ test %eax,%eax /* if (null) throw exception */
+ je nb_lrem
- jmp builtin_lrem
+ jmp builtin_lrem
nb_lrem:
- pop %ecx /* delete return address */
- sub $2,%ecx /* faulting address is return adress - 2 */
- mov proto_java_lang_ArithmeticException,%eax
- jmp asm_handle_exception
-
+ pop %ecx
+ sub $2,%ecx
+ jmp asm_throw_and_handle_hardware_arithmetic_exception
+#if 0
+ push string_java_lang_ArithmeticException_message
+ push string_java_lang_ArithmeticException
+ call new_exception_message
+ add $(2*4),%esp
+
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+ jmp asm_handle_exception
+#endif
/************************ function asm_builtin_x2x *****************************
* *
*******************************************************************************/
asm_builtin_f2i:
- sub $4,%esp
- fsts (%esp)
- call builtin_f2i
- add $4,%esp
- ret
+ sub $4,%esp
+ fsts (%esp)
+ call builtin_f2i
+ add $4,%esp
+ ret
asm_builtin_d2i:
- sub $8,%esp
- fstl (%esp)
- call builtin_d2i
- add $8,%esp
- ret
+ sub $8,%esp
+ fstl (%esp)
+ call builtin_d2i
+ add $8,%esp
+ ret
asm_builtin_f2l:
- sub $4,%esp
- fsts (%esp)
- call builtin_f2l
- add $4,%esp
- ret
+ sub $4,%esp
+ fsts (%esp)
+ call builtin_f2l
+ add $4,%esp
+ ret
asm_builtin_d2l:
- sub $8,%esp
- fstl (%esp)
- call builtin_d2l
- add $8,%esp
- ret
-
-
-/*********************** function new_builtin_checkcast ************************
-* *
-* Does the cast check and eventually throws an exception *
-* *
-*******************************************************************************/
+ sub $8,%esp
+ fstl (%esp)
+ call builtin_d2l
+ add $8,%esp
+ ret
-asm_builtin_checkcast:
- xor %eax,%eax
- mov %eax,(%eax)
- ret
-
/******************* function asm_builtin_checkarraycast ***********************
* *
* Does the cast check and eventually throws an exception *
*******************************************************************************/
asm_builtin_checkarraycast:
- sub $8,%esp /* build stack frame (2 * 4 bytes) */
+ sub $8,%esp /* build stack frame (2 * 4 bytes) */
- mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
- mov %eax,(%esp) /* save object pointer */
+ mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
+ mov %eax,(%esp) /* save object pointer */
- mov 20(%esp),%eax
- mov %eax,4(%esp)
+ mov 20(%esp),%eax
+ mov %eax,4(%esp)
- call builtin_checkarraycast /* builtin_checkarraycast */
-
- test %eax,%eax /* if (false) throw exception */
- je nb_carray_throw
+ call builtin_checkarraycast /* builtin_checkarraycast */
- mov 12(%esp),%eax /* return object pointer */
- add $8,%esp
- ret
+ test %eax,%eax /* if (false) throw exception */
+ je nb_carray_throw
-nb_carray_throw:
- add $8,%esp
-
- pop %ecx /* delete return address */
- sub $2,%ecx /* faulting address is return adress - 2 */
- mov proto_java_lang_ClassCastException,%eax
- jmp asm_handle_exception
+ mov 12(%esp),%eax /* return object pointer */
+ add $8,%esp
+ ret
+nb_carray_throw:
+ add $8,%esp
+ mov string_java_lang_ClassCastException,%eax
+ pop %ecx
+ sub $2,%ecx
+ jmp asm_throw_and_handle_exception
+#if 0
+ push string_java_lang_ClassCastException
+ call new_exception
+ add $(1*4),%esp
+
+ add $8,%esp
+
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+ jmp asm_handle_exception
+#endif
/******************* function asm_builtin_newarray *****************************
* *
*******************************************************************************/
asm_builtin_newarray:
- sub $8,%esp /* build stack frame (2 * 4 bytes) */
+ sub $8,%esp /* build stack frame (2 * 4 bytes) */
- mov 12(%esp),%eax
- mov %eax,(%esp)
+ mov 12(%esp),%eax
+ mov %eax,(%esp)
- mov 20(%esp),%eax
- mov %eax,4(%esp)
+ mov 20(%esp),%eax
+ mov %eax,4(%esp)
- call builtin_newarray
-
- add $8,%esp
- ret
+ call builtin_newarray
+
+ add $8,%esp
+ ret
/******************* function asm_builtin_aastore ******************************
*******************************************************************************/
asm_builtin_aastore:
- subl $12,%esp /* build stack frame (3 * 4 bytes) */
-
- movl 16(%esp),%eax /* 12 (frame) + 4 (return) */
- test %eax,%eax /* if null pointer throw exception */
- je nb_aastore_null
-
- movl offarraysize(%eax),%edx /* load size */
- movl 24(%esp),%ecx /* index */
- cmpl %edx,%ecx /* do bound check */
- ja nb_aastore_bound /* if out of bounds throw exception */
+ sub $12,%esp /* build stack frame (3 * 4 bytes) */
+
+ mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
+ test %eax,%eax /* if null pointer throw exception */
+ je nb_aastore_null
+
+ mov offarraysize(%eax),%edx /* load size */
+ mov 24(%esp),%ecx /* index */
+ cmp %edx,%ecx /* do bound check */
+ jae nb_aastore_bound /* if out of bounds throw exception */
+
+ shl $2,%ecx /* index * 4 */
+ add %eax,%ecx /* add index * 4 to arrayref */
+
+ mov %ecx,8(%esp) /* save store position */
+
+ mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
+ mov %eax,(%esp)
+
+ mov 32(%esp),%eax /* object is second argument */
+ mov %eax,4(%esp)
+
+ call builtin_canstore /* builtin_canstore(arrayref,object) */
- shll $2,%ecx /* index * 4 */
- addl %eax,%ecx /* add index * 4 to arrayref */
-
- movl %ecx,8(%esp) /* save store position */
-
- movl 16(%esp),%eax /* 12 (frame) + 4 (return) */
- movl %eax,(%esp)
+ test %eax,%eax /* if (false) throw exception */
+ je nb_aastore_store
- movl 32(%esp),%eax /* object is second argument */
- movl %eax,4(%esp)
-
- call builtin_canstore /* builtin_canstore(arrayref,object) */
+ mov 32(%esp),%eax
+ mov 8(%esp),%ecx
+ mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
+
+ add $12,%esp
+ ret
- test %eax,%eax /* if (false) throw exception */
- je nb_aastore_throw
+nb_aastore_null:
+ add $12,%esp
+ mov string_java_lang_NullPointerException,%eax
+ pop %ecx
+ sub $2,%ecx
+ jmp asm_throw_and_handle_exception
+
+#if 0
+ push string_java_lang_NullPointerException
+ call new_exception
+ add $(1*4),%esp
+
+ add $12,%esp
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+ jmp asm_handle_exception
+#endif
+nb_aastore_bound:
+ add $12,%esp
+ mov %ecx,%eax /* itmp2 contains array index */
+ pushl $0 /*directly below return adress*/
+ pushl $0 /*internal (invisible) method*/
+ call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
- movl 32(%esp),%eax
- movl 8(%esp),%ecx
- movl %eax,offobjarrdata(%ecx)/* store objectptr in array */
-
- addl $12,%esp
- ret
+ push %eax
+ call new_arrayindexoutofboundsexception
+ add $(1*4),%esp
-nb_aastore_null:
- addl $12,%esp
- popl %ecx /* delete return address */
- subl $2,%ecx /* faulting address is return adress - 2 */
- movl proto_java_lang_NullPointerException,%eax
- jmp asm_handle_exception
+ call asm_remove_native_stackinfo /*return adress is the first on stack again*/
-nb_aastore_bound:
- addl $12,%esp
- popl %ecx /* delete return address */
- subl $2,%ecx /* faulting address is return adress - 2 */
- movl proto_java_lang_ArrayIndexOutOfBoundsException,%eax
- jmp asm_handle_exception
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+ jmp asm_handle_exception
-nb_aastore_throw:
- addl $12,%esp
- popl %ecx /* delete return address */
- subl $2,%ecx /* faulting address is return adress - 2 */
- movl proto_java_lang_ArrayStoreException,%eax
- jmp asm_handle_exception
-
+nb_aastore_store:
+ add $12,%esp
+
+ mov string_java_lang_ArrayStoreException,%eax
+ pop %ecx
+ sub $2,%ecx
+ jmp asm_throw_and_handle_exception
+
+#if 0
+ push string_java_lang_ArrayStoreException
+ call new_exception
+ add $(1*4),%esp
+
+ add $12,%esp
+ pop %ecx /* delete return address */
+ sub $2,%ecx /* faulting address is return adress - 2 */
+ jmp asm_handle_exception
+#endif
/******************* function asm_builtin_arrayinstanceof **********************
* *
*******************************************************************************/
asm_builtin_arrayinstanceof:
- subl $8,%esp /* build stack frame (2 * 4 bytes) */
+ sub $8,%esp /* build stack frame (2 * 4 bytes) */
- movl 12(%esp),%eax
- movl %eax,(%esp)
+ mov 12(%esp),%eax
+ mov %eax,(%esp)
- movl 20(%esp),%eax
- movl %eax,4(%esp)
+ mov 20(%esp),%eax
+ mov %eax,4(%esp)
- call builtin_arrayinstanceof
-
- addl $8,%esp
- ret
+ call builtin_arrayinstanceof
+
+ add $8,%esp
+ ret
/******************* function asm_initialize_thread_stack **********************
*******************************************************************************/
asm_initialize_thread_stack:
- movl 8(%esp),%eax /* (to)->stackEnd */
- subl $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
-
- xorl %edx,%edx
- movl %edx,0(%eax)
- movl %edx,4(%eax)
- movl %edx,8(%eax)
- movl %edx,12(%eax)
- movl %edx,16(%eax)
- movl %edx,20(%eax)
- movl %edx,24(%eax)
- movl %edx,28(%eax)
-
- movl 4(%esp),%edx /* save (u1*) (func) */
- movl %edx,32(%eax)
+ mov 8(%esp),%eax /* (to)->stackEnd */
+ sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
+
+ xor %edx,%edx
+ mov %edx,0(%eax)
+ mov %edx,4(%eax)
+ mov %edx,8(%eax)
+ mov %edx,12(%eax)
+ mov %edx,16(%eax)
+ mov %edx,20(%eax)
+ mov %edx,24(%eax)
+ mov %edx,28(%eax)
+
+ mov 4(%esp),%edx /* save (u1*) (func) */
+ mov %edx,32(%eax)
ret /* return restorepoint in %eax */
*******************************************************************************/
asm_perform_threadswitch:
- subl $36,%esp
-
- movl %eax,0(%esp)
- movl %ecx,4(%esp)
- movl %edx,8(%esp)
- movl %ebx,12(%esp)
- movl %esp,16(%esp)
- movl %ebp,20(%esp)
- movl %esi,24(%esp)
- movl %edi,28(%esp)
-
- movl 36(%esp),%eax /* save current return address */
- movl %eax,32(%esp)
-
- movl 40(%esp),%eax /* first argument **from */
- movl %esp,0(%eax)
-
- movl 48(%esp),%eax /* third argument **stackTop */
- movl %esp,0(%eax)
-
- movl 44(%esp),%eax /* second argument **to */
- movl 0(%eax),%esp /* load new stack pointer */
-
- movl 0(%esp),%eax
- movl 4(%esp),%ecx
- movl 8(%esp),%edx
- movl 12(%esp),%ebx
- /* skip stack pointer */
- movl 20(%esp),%ebp
- movl 24(%esp),%esi
- movl 28(%esp),%edi
-
- addl $32,%esp /* leave return address on stack */
- ret
+ sub $36,%esp
+
+ mov %eax,0(%esp)
+ mov %ecx,4(%esp)
+ mov %edx,8(%esp)
+ mov %ebx,12(%esp)
+ mov %esp,16(%esp)
+ mov %ebp,20(%esp)
+ mov %esi,24(%esp)
+ mov %edi,28(%esp)
+
+ mov 36(%esp),%eax /* save current return address */
+ mov %eax,32(%esp)
+
+ mov 40(%esp),%eax /* first argument **from */
+ mov %esp,0(%eax)
+
+ mov 48(%esp),%eax /* third argument **stackTop */
+ mov %esp,0(%eax)
+
+ mov 44(%esp),%eax /* second argument **to */
+ mov 0(%eax),%esp /* load new stack pointer */
+
+ mov 0(%esp),%eax
+ mov 4(%esp),%ecx
+ mov 8(%esp),%edx
+ mov 12(%esp),%ebx
+ /* skip stack pointer */
+ mov 20(%esp),%ebp
+ mov 24(%esp),%esi
+ mov 28(%esp),%edi
+
+ add $32,%esp /* leave return address on stack */
+ ret
/********************* function asm_switchstackandcall *************************
*******************************************************************************/
asm_switchstackandcall:
- movl 4(%esp),%edx /* first argument *stack */
- subl $8,%edx /* allocate new stack */
+ mov 4(%esp),%edx /* first argument *stack */
+ sub $8,%edx /* allocate new stack */
+
+ mov (%esp),%eax /* save return address on new stack */
+ mov %eax,(%edx)
+
+ mov %esp,4(%edx) /* save old stack pointer on new stack */
+
+ mov 12(%esp),%eax /* third argument **stacktopsave */
+ mov %esp,(%eax) /* save old stack pointer to variable */
- movl (%esp),%eax /* save return address on new stack */
- movl %eax,(%edx)
+ mov 8(%esp),%eax /* load function pointer */
+ mov 16(%esp),%ecx /* fourth argument *p */
+
+ mov %edx,%esp /* switch to new stack */
- movl %esp,4(%edx) /* save old stack pointer on new stack*/
+ sub $4,%esp
+ mov %ecx,0(%esp) /* pass pointer */
+ call *%eax /* and call function */
+ add $4,%esp
- movl 12(%esp),%eax /* third argument **stacktopsave */
- movl %esp,(%eax) /* save old stack pointer to variable */
+ mov (%esp),%edx /* load return address */
+ mov 4(%esp),%esp /* switch to old stack */
+ mov %edx,(%esp)
+ ret
- movl 8(%esp),%eax /* load function pointer */
- movl 16(%esp),%ecx /* fourth argument *p */
- movl %edx,%esp /* switch to new stack */
+asm_throw_and_handle_exception:
+ push %ecx
+ pushl $0 /* the pushed XPC is directly below the java frame*/
+ pushl $0
+ call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
+
+ push %eax
+ call new_exception
+ add $4,%esp /*remove parameter*/
- subl $4,%esp
- movl %ecx,0(%esp) /* pass pointer */
- call *%eax /* and call function */
- addl $4,%esp
+ call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
- movl (%esp),%edx /* load return address */
- movl 4(%esp),%esp /* switch to old stack */
- movl %edx,(%esp)
- ret
+ pop %ecx
+ jmp asm_handle_exception
+ ret /*should never be reached */
+asm_throw_and_handle_hardware_arithmetic_exception:
+
+ push %ecx
+ pushl $0 /* the pushed XPC is directly below the java frame*/
+ pushl $0
+ call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
+
+ mov string_java_lang_ArithmeticException_message,%eax
+ push %eax
+ mov string_java_lang_ArithmeticException,%eax
+ push %eax
+
+ call new_exception_message
+ add $8,%esp /*remove parameters */
+
+ call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
+
+ pop %ecx
+ jmp asm_handle_exception
+ ret /*should never be reached */
+
+asm_builtin_new:
+/*optimize a littlebit */
+ mov %esp,%eax
+/*DEBUG*/
+/* push %eax
+ call i386_native_stub_debug
+ pop %eax */
-/********************* function asm_getcallingmethod ***************************
-* *
-* classinfo *asm_getcallingmethod (); *
-* *
-* goes back stack frames to get the calling method *
-* *
-* t2 .. sp *
-* t3 .. ra *
-* t4 .. pv *
-* *
-*******************************************************************************/
+ movl 4(%esp),%eax
+ mov offclassinit(%eax),%ecx /* get initialized flag */
+ test %ecx,%ecx
+ jnz L_builtin_new_noinit
+
+ mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
+
+ /* 2 *4 bytes, the return adress is used directy */
+ pushl $0 /* the structure is placed directly below the java stackframe*/
+ pushl $0 /* builtin (invisible) method */
+ call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
+#if 0
+ sub $16,%esp /* build stack frame (4 * 4 bytes) */
+
+ mov 20(%esp),%eax
+ mov %eax,(%esp)
+
+ call builtin_asm_get_stackframeinfo
+ movl $0,12(%esp)
+ mov %eax,8(%esp)
+ mov (%eax),%ebx
+ mov %ebx,4(%esp)
+ mov %esp,%ecx
+ add $4,%ecx
+ mov %ecx,(%eax)
+#endif
+ push %eax
+ call builtin_new
+ add $4,%esp
+
+ call asm_remove_native_stackinfo /*first element on stack is return adress again*/
+#if 0
+ call
+ mov 4(%esp),%ebx
+ mov 8(%esp),%ecx
+ mov %ebx,(%ecx)
+
+ add $16,%esp
+#endif
+ jmp L_builtin_new_patch
+
-asm_getcallingmethod:
- xorl %eax,%eax
-/* movl $0,(%eax) */
+L_builtin_new_noinit:
+ mov 4(%esp),%eax
+ push %eax
+ call builtin_new
+ add $4,%esp
+ /*jmp L_builtin_new_patch*/
+
+L_builtin_new_patch:
+/*add patching code here */
+ lea builtin_new,%edx
+ mov (%esp),%ecx
+ mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
ret
+
+
+
+
+asm_getclassvalues_atomic:
+_crit_restart2:
+ mov 4(%esp),%ecx /* super */
+ mov 8(%esp),%edx /* sub */
+_crit_begin2:
+ mov offbaseval(%ecx),%eax
+ mov offdiffval(%ecx),%ecx
+ mov offbaseval(%edx),%edx
+_crit_end2:
+ push %ebx
+ mov 16(%esp),%ebx /* out */
+ mov %eax,offcast_super_baseval(%ebx)
+ mov %ecx,offcast_super_diffval(%ebx)
+ mov %edx,offcast_sub_baseval(%ebx)
+ pop %ebx
+ ret
+
+ .data
+
+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
+#endif
+ .long 0
+
+
+
+/************************ function asm_prepare_native_stackinfo ****************************
+* *
+* creates a stackfame for the begin of a native function (either builtin or not ) *
+* expected stack at begin of function *
+* .... *
+* address of the jit call which invokes the native *
+* begin address of stack frame of the java method *
+* method pointer or 0 (for built ins) *
+* return address *
+* *
+* at end of function: *
+* ... *
+* address of the jit call which invokes the native *
+* begin address of stack frame of the java method *
+* method pointer or 0 (for built ins) *
+* address of thread specific top of native list *
+* old value of thread specific head *
+* return address *
+* *
+* .... *
+* This thing is less efficient than the original #define (callerside) *
+* destroyes REG_ITMP2, keeps REG_ITMP1 *
+********************************************************************************************/
+
+
+asm_prepare_native_stackinfo:
+ sub $8,%esp
+ mov 8(%esp),%ecx
+ mov %ecx,(%esp)
+ push %eax
+ lea builtin_asm_get_stackframeinfo,%ecx
+ call *%ecx
+ mov %eax, 12(%esp)
+ mov (%eax),%ecx
+ mov %ecx,8(%esp)
+ mov %esp,%ecx
+ add $8,%ecx
+ mov %ecx,(%eax)
+ pop %eax
+ ret
+#if 0
+#define PREPARE_NATIVE_STACKINFO \
+ i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
+ i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
+ i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
+ i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
+ i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
+ i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
+ i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
+ i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
+ i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
+ i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
+ i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
+ i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
+#endif
+
+
+/************************ function asm_remove _native_stackinfo *******************************************
+* *
+* creates a stackfame for the begin of a native function (either builtin or not) *
+* expected stack at begin of function *
+* address of the jit call which invokes the native *
+* begin address of stack frame of the java method *
+* method pointer or 0 (for built ins) *
+* address thread specific top of native list *
+* old value of thread specific head *
+* return address *
+* *
+* at end of function: *
+* .... *
+* return adresss of the jit call which invokes the native *
+* return address *
+* *
+* REG_ITMP2_XPC = address of the jit call which invokes the native *
+* *
+* *
+* This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
+***********************************************************************************************************/
+
+asm_remove_native_stackinfo:
+ mov 4(%esp),%ecx
+ mov 8(%esp),%edx
+ mov %ecx,(%edx)
+ pop %edx
+ add $16,%esp
+ push %edx
+ ret
+
+#if 0
+#define REMOVE_NATIVE_STACKINFO \
+ i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
+ i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
+ i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
+ i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
+#endif
+
+
+
+
/*
* 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