X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fi386%2Fasmpart.S;h=b9be6e191288c242139bfc018248b49e875043d0;hb=d62d56aa9150bb2156dac82966795fdcbd7562e0;hp=907f122267d5e25f35a95bc859c096e784ae6d20;hpb=f12306c9df77c8af753b5b74588539e3f3b3f043;p=cacao.git diff --git a/src/vm/jit/i386/asmpart.S b/src/vm/jit/i386/asmpart.S index 907f12226..b9be6e191 100644 --- a/src/vm/jit/i386/asmpart.S +++ b/src/vm/jit/i386/asmpart.S @@ -1,9 +1,7 @@ /* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386 - 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, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -19,166 +17,80 @@ 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. - - Contact: cacao@complang.tuwien.ac.at - - Authors: Andreas Krall - Reinhard Grafl - Christian Thalinger - - Changes: Joseph Wenninger - - $Id: asmpart.S 2947 2005-07-09 12:17:14Z twisti $ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ #include "config.h" -#include "vm/jit/i386/offsets.h" -#include "vm/jit/i386/asmoffsets.h" - - -/* define it like the risc way */ -#define v0 %eax +#include "md-asm.h" -#define itmp1 %eax -#define itmp2 %ecx -#define itmp3 %edx +#include "vm/jit/i386/arch.h" +#include "vm/jit/i386/md-abi.h" -#define itmp1b %al -#define itmp2b %cl -#define itmp3b %dl - -#define xptr itmp1 -#define xpc itmp2 +#include "vm/jit/abi-asm.h" +#include "vm/jit/methodheader.h" .text -/********************* exported functions and variables ***********************/ +/* export functions ***********************************************************/ - .globl asm_calljavafunction - .globl asm_calljavafunction_int + .globl asm_md_init - .globl asm_calljavafunction2 - .globl asm_calljavafunction2int - .globl asm_calljavafunction2long - .globl asm_calljavafunction2float - .globl asm_calljavafunction2double + .globl asm_vm_call_method + .globl asm_vm_call_method_int + .globl asm_vm_call_method_long + .globl asm_vm_call_method_float + .globl asm_vm_call_method_double + .globl asm_vm_call_method_exception_handler + .globl asm_vm_call_method_end - .globl asm_call_jit_compiler - .globl asm_handle_builtin_exception .globl asm_handle_nat_exception .globl asm_handle_exception - .globl asm_wrapper_patcher - - .globl asm_builtin_arraycheckcast - .globl asm_builtin_aastore - - .globl asm_builtin_ldiv - .globl asm_builtin_lrem + .globl asm_abstractmethoderror .globl asm_builtin_f2i .globl asm_builtin_f2l .globl asm_builtin_d2i .globl asm_builtin_d2l - .globl asm_perform_threadswitch - .globl asm_initialize_thread_stack - .globl asm_switchstackandcall - .globl asm_getcallingmethod - .globl asm_criticalsections - .globl asm_getclassvalues_atomic - - .globl asm_throw_and_handle_exception - .globl asm_throw_and_handle_hardware_arithmetic_exception - - .globl asm_prepare_native_stackinfo - .globl asm_remove_native_stackinfo + .globl asm_compare_and_swap + .globl asm_memory_barrier +#if defined(ENABLE_ESCAPE_CHECK) + .globl asm_escape_check +#endif -/********************* function asm_calljavafunction *************************** -* * -* This function calls a Java-method (which possibly needs compilation) * -* with up to 4 address parameters. * -* * -* This functions calls the JIT-compiler which eventually translates the * -* method into machine code. * -* * -* C-prototype: * -* javaobject_header *asm_calljavamethod (methodinfo *m, * -* void *arg1, void *arg2, void *arg3, void *arg4); * -* * -*******************************************************************************/ - -call_name: - .align 8 - .long 0 /* catch type all */ - .long calljava_xhandler /* handler pc */ - .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 /* IsSync */ - .long 32 /* frame size */ - .long 0 /* method pointer (pointer to name) */ - -asm_calljavafunction: -asm_calljavafunction_int: - push %ebp /* allocate stack space */ - mov %esp, %ebp - - push %ebx /* save registers */ - push %esi - push %edi - - - sub $16,%esp /* 4 adress parameters * 4 Bytes */ - mov 24(%ebp),%eax /* copy adress parameters to new block */ - mov %eax,12(%esp) - - mov 20(%ebp),%eax - mov %eax,8(%esp) +/* asm_md_init ***************************************************************** - mov 16(%ebp),%eax - mov %eax,4(%esp) + Initialize machine dependent stuff. - mov 12(%ebp),%eax - mov %eax,(%esp) - - mov 8(%ebp),%eax /* move function pointer to %eax */ + See: http://www.srware.com/linux_numerics.txt - lea asm_call_jit_compiler,%edx - call *%edx /* call JIT compiler */ + This puts the X86 FPU in 64-bit precision mode. The default under + Linux is to use 80-bit mode, which produces subtle differences from + FreeBSD and other systems, eg, (int)(1000*atof("0.3")) is 300 in + 64-bit mode, 299 in 80-bit mode. - add $16,%esp - pop %edi /* restore registers */ - pop %esi - pop %ebx - leave - ret + Fixes: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350729 -calljava_xhandler: - push %eax /* pass exception pointer */ - call builtin_throw_exception - add $4,%esp +*******************************************************************************/ - add $16,%esp - pop %edi /* restore registers */ - pop %esi - pop %ebx - leave - xor %eax,%eax /* return NULL */ +asm_md_init: + sub $4,sp /* allocate space for the FPU state */ + fnstcw (sp) /* get the FPU state */ + mov (sp),%eax + and $0xfcff,%ax /* remove the extended mode flag */ + or $0x0200,%ax /* put the double mode flag */ + mov %eax,(sp) /* store new FPU state */ + fldcw (sp) /* setup new FPU state */ + add $4,sp ret @@ -191,255 +103,88 @@ calljava_xhandler: * method into machine code. * * * * C-prototype: * -* javaobject_header *asm_calljavafunction2(methodinfo *m, * +* javaobject_header *asm_vm_call_method(methodinfo *m, * * u4 count, u4 size, void *callblock); * * * *******************************************************************************/ -call_name2: .align 8 - .long 0 /* catch type all */ - .long calljava_xhandler2 /* handler pc */ - .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 */ - .long 0 /* IsSync */ - .long 32 /* frame size */ - .long 0 /* method pointer (pointer to name) */ - -asm_calljavafunction2: -asm_calljavafunction2int: -asm_calljavafunction2long: -asm_calljavafunction2float: -asm_calljavafunction2double: - push %ebp - mov %esp,%ebp /* save stackptr */ - - push %ebx /* save registers */ - push %esi - push %edi - - mov 20(%ebp),%eax /* pointer to arg block (4(push)+4(return)+4+4+4)*/ - mov 12(%ebp),%ecx /* arg count (4(push)+4(return)+4 */ - test %ecx,%ecx /* maybe we have no args */ - jle calljava_copydone - - mov %ecx,%edx /* calculate stack size */ - xor %esi,%esi - mov %eax,%edi /* save pointer to arg block */ -calljava_calcstacksize: - mov offjniitemtype(%eax),%ebx - test $1,%ebx /* Two Word Type? */ - jz calljava_onewordtype - add $4,%esi -calljava_onewordtype: - add $4,%esi - sub $1,%edx - test %edx,%edx /* any args left ?*/ - jz calljava_setstack - add $sizejniblock,%eax /* goto next argument block */ - jmp calljava_calcstacksize - -calljava_setstack: - mov %edi,%eax /* restore pointer to arg block */ - sub %esi,%esp /* stack frame for arguments */ - mov %esp,%edi - -calljava_copyloop: - mov offjniitem(%eax),%edx /* copy 4 Byte of Argument */ - mov %edx,(%edi) - add $4,%edi /* increase sp to next argument */ - mov offjniitemtype(%eax),%ebx /* type -> ebx */ - test $1,%ebx /* Two Word Type? */ - jz calljava_copynext - mov offjniitem+4(%eax),%edx /* copy upper 4 Byte of 2 Word Type */ - mov %edx,(%edi) - add $4,%edi /* increase sp to next argument */ -calljava_copynext: - sub $1,%ecx /* are there any args left? */ - test %ecx,%ecx - jle calljava_copydone - - add $sizejniblock,%eax /* goto next argument block */ - 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 %esi,%esp /* remove arg stack frame */ - pop %edi /* restore registers */ - pop %esi - pop %ebx - leave - ret + .long 0 /* fltsave */ + .long 0 /* intsave */ + .long 0 /* isleaf */ + .long 0 /* frame size */ + .long 0 /* codeinfo pointer */ + +asm_vm_call_method: +asm_vm_call_method_int: +asm_vm_call_method_long: +asm_vm_call_method_float: +asm_vm_call_method_double: + push bp + mov sp,bp /* save stack pointer */ + sub $(4*4),sp /* create stackframe */ + and $0xfffffff0,sp /* align stack to 16-byte */ + + mov t0,0*4(sp) /* save registers */ + mov s1,1*4(sp) + mov s2,2*4(sp) + + mov sp,s1 /* save stack pointer */ + + mov 3*4(bp),t0 /* address of data structure */ + mov 4*4(bp),itmp1 /* number of stack arguments */ + + cmp $0,itmp1 + je L_asm_vm_call_method_stack_copy_done + + mov itmp1,itmp2 + add $1,itmp2 /* keep stack 16-byte aligned */ + and $0xfffffffe,itmp2 + shl $3,itmp2 /* calculate stack size */ + sub itmp2,sp /* create stack frame */ + mov sp,itmp2 /* temporary stack pointer */ + +L_asm_vm_call_method_stack_copy_loop: + mov 0(t0),itmp3 /* load argument */ + mov itmp3,0(itmp2) /* store argument on stack */ + mov 4(t0),itmp3 + mov itmp3,4(itmp2) + + sub $1,itmp1 /* subtract 1 argument */ + add $8,t0 /* set address of next argument */ + add $8,itmp2 /* increase SP */ + + cmp $0,itmp1 + jg L_asm_vm_call_method_stack_copy_loop + +L_asm_vm_call_method_stack_copy_done: + lea (2*4-256)(bp),mptr /* We subtract 256 to force the next */ + /* move instruction to have a 32-bit */ + /* offset. */ + + mov (0*4+256)(mptr),itmp3 /* method call as in Java */ + call *itmp3 /* call JIT compiler */ + +L_asm_vm_call_method_return: + mov s1,sp /* restore stackpointer */ + + mov 0*4(sp),t0 /* restore registers */ + mov 1*4(sp),s1 + mov 2*4(sp),s2 -calljava_xhandler2: - 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 - xor %eax,%eax /* return NULL */ ret +asm_vm_call_method_exception_handler: + push xptr /* pass exception pointer */ + call builtin_throw_exception + add $4,sp +asm_vm_call_method_end: + jmp L_asm_vm_call_method_return -/****************** function asm_call_jit_compiler ***************************** -* * -* invokes the compiler for untranslated JavaVM methods. * -* * -* Register R0 contains a pointer to the method info structure (prepared * -* by createcompilerstub). Using the return address in R26 and the * -* offset in the LDA instruction or using the value in methodptr R28 the * -* patching address for storing the method address can be computed: * -* * -* method address was either loaded using * -* * -* i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special * -* i386_call_reg(REG_ITMP2) * -* * -* or * -* * -* i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface * -* i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) * -* i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ * -* sizeof(methodptr) * m->vftblindex, REG_ITMP1) * -* i386_call_reg(REG_ITMP1) * -* * -* in the static case the method pointer can be computed using the * -* return address and the lda function following the jmp instruction * -* * -*******************************************************************************/ - -asm_call_jit_compiler: - push %ebx /* save register */ - push %ebp - - mov 2*4(%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 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 - -L_call_jit_compile: - push %ebp /* save address for method pointer */ - - push %eax /* push methodpointer on stack */ - call jit_compile - add $4,%esp - - pop %ebp /* restore address for method pointer */ - - test %eax,%eax /* check for exception */ - je L_asm_call_jit_compiler_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 */ - -L_asm_call_jit_compiler_exception: - pop %ebp /* restore registers */ - pop %ebx -#if defined(USE_THREADS) && defined(NATIVE_THREADS) - call builtin_asm_get_exceptionptrptr - mov %eax,%ecx -#else - lea _exceptionptr,%ecx -#endif - mov (%ecx),%eax /* get the exception pointer */ - movl $0,(%ecx) /* clear the exception pointer */ - - 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. The native info - should be moved around the jit call to get - a more compliant trace for the "exception in - initializer" case*/ - push %ecx /* store fault adress */ - push %eax /* temporarily save exception pointer*/ - push $0 /* internal function */ - 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 12(%esp),%eax /* get the exception pointer again*/ - movl $0,12(%esp) /*java stack begins just above structure*/ - push $0 /*used for the jni_callblock structure*/ - push %eax /*save eax for later */ - /* get fillInStackTrace method*/ - push utf_void__java_lang_Throwable - push utf_fillInStackTrace - 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 $24,%esp - pop %ecx - - - 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 * @@ -447,357 +192,159 @@ L_refillinStacktrace: /*a compilation error should cause a stacktr * 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 $4,%esp /* clear return address of native stub */ + add $4,sp /* 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 */ - - call codegen_findmethod /* get the data segment ptr */ - mov %eax,%edx - - mov -4(%ebp),%eax - mov -8(%ebp),%ecx /* could be changed in findmethod */ - - push %edx /* save data segment pointer */ - push %ebx - push %esi - push %edi - -ex_stack_loop: - 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 $0,12(%esp) /* line number */ - movl $1,16(%esp) /* set no unwind flag */ - call builtin_trace_exception - 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 */ - je empty_table - - lea ExTableStart(%esi),%edi /* %edi = start of exception table*/ - mov -4(%ebp),%eax /* get xptr */ - -ex_table_loop: - mov -8(%ebp),%edx /* get xpc */ - - mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */ - cmp %edx,%ebx /* %ebx = (startpc <= xpc) */ - jg ex_table_cont /* if (false) continue */ - mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */ - cmp %ebx,%edx /* %ebx = (xpc < endpc) */ - jge ex_table_cont /* if (false) continue */ - mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */ - test %ebx,%ebx /* NULL catches everything */ - je ex_handle_it - - 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 load_class_bootstrap - - 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 link_class - - 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 - - pop %edi /* restore registers */ - pop %esi - pop %ebx - add $8,%esp /* suck %ecx, %edx */ - pop %eax /* restore xptr */ - - leave - jmp *%edx /* jump to exception handler */ - -ex_table_cont: - lea ExEntrySize(%edi),%edi - dec %ecx - test %ecx,%ecx - jg ex_table_loop - -empty_table: - pop %edi - pop %esi - pop %ebx - pop %edx /* restore data segment pointer */ - pop %ecx - pop %eax - pop %ebp - - push %eax /* save exception pointer */ - -ex_already_cleared: - mov IsSync(%edx),%eax /* %eax = SyncOffset */ - test %eax,%eax /* if zero no monitorexit */ - je no_monitor_exit - -#if defined(USE_THREADS) - add %esp,%eax - mov (%eax),%eax /* we have the xptr on the stack (+4-4=0) */ - push %edx /* save regs */ - push %eax - call builtin_monitorexit - add $4,%esp - pop %edx /* restore regs */ -#endif +L_asm_handle_exception: /* required for PIC code */ + sub $((ARG_CNT+TMP_CNT+3)*4),sp /* keep stack 16-byte aligned */ -no_monitor_exit: - mov %esp,%eax - add FrameSize(%edx),%eax /* %eax = frame size */ - add $4,%eax /* we have the xptr on the stack */ - - mov IntSave(%edx),%ecx /* %ecx = saved int register count*/ - test %ecx,%ecx - je noint - cmp $1,%ecx - je int1 - cmp $2,%ecx - je int2 - cmp $3,%ecx - je int3 - -int4: - mov -16(%eax),%ebx - -int3: - mov -12(%eax),%ebp + SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */ + SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */ -int2: - mov -8(%eax),%esi + mov $((ARG_CNT+TMP_CNT+3)*4),itmp3 /* prepare a3 for handle_exception */ + mov $1,t0 /* set maybe-leaf flag */ -int1: - mov -4(%eax),%edi +L_asm_handle_exception_stack_loop: + sub $(12*4),sp /* keep stack 16-byte aligned */ + mov xptr,4*4(sp) /* save exception pointer */ + mov xpc,5*4(sp) /* save exception pc */ + add sp,itmp3 /* calculate Java sp into a3... */ + add $(12*4),itmp3 + mov itmp3,7*4(sp) /* ...and save it */ + mov t0,8*4(sp) /* save maybe-leaf flag */ - shl $2,%ecx /* multiply by 4 bytes */ - sub %ecx,%eax - -noint: - mov FltSave(%edx),%ecx /* %ecx = saved flt register count */ - test %ecx,%ecx - je noflt - cmp $1,%ecx - je flt1 - cmp $2,%ecx - je flt2 - cmp $3,%ecx - je flt3 - -flt4: - fldl -32(%eax) - fstp %st(1) + mov xpc,0*4(sp) /* pass exception pc */ + call methodtree_find + mov v0,6*4(sp) /* save data segment pointer */ -flt3: - fldl -24(%eax) - fstp %st(2) - -flt2: - fldl -16(%eax) - fstp %st(3) - -flt1: - fldl -8(%eax) - fstp %st(4) - -noflt: - pop %eax /* restore exception pointer */ - - mov FrameSize(%edx),%ecx /* %ecx = frame size */ - add %ecx,%esp /* unwind stack */ - - pop %ecx /* the new xpc is return address */ - sub $2,%ecx /* -2 -> call */ - - jmp asm_handle_exception_loop - + mov 4*4(sp),itmp3 /* pass exception pointer */ + mov itmp3,0*4(sp) + mov 5*4(sp),itmp3 /* pass exception pc */ + mov itmp3,1*4(sp) + mov v0,2*4(sp) /* pass data segment pointer */ + mov 7*4(sp),itmp3 /* pass Java stack pointer */ + mov itmp3,3*4(sp) + call exceptions_handle_exception -/* asm_wrapper_patcher ********************************************************* + test v0,v0 + jz L_asm_handle_exception_not_catched - XXX + mov v0,xpc /* move handlerpc into xpc */ + mov 4*4(sp),xptr /* restore exception pointer */ + mov 8*4(sp),t0 /* get maybe-leaf flag */ + add $(12*4),sp /* free stackframe */ - Stack layout: - 20 return address - 16 pointer to virtual java_objectheader - 12 last byte of machine code (xmcode) - 8 machine code (which is patched back later) - 4 unresolved field reference - 0 patcher function pointer to call + test t0,t0 /* test for maybe-leaf flag */ + jz L_asm_handle_exception_no_leaf -*******************************************************************************/ + RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */ + RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */ -asm_wrapper_patcher: - sub $(2*4),%esp /* create stack frame */ + add $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe */ - mov itmp1,0*4(%esp) /* save itmp1 and itmp2 */ - mov itmp2,1*4(%esp) /* may be used by some instructions */ +L_asm_handle_exception_no_leaf: + jmp *xpc /* jump to exception handler */ -#if 0 - /* 3*4 bytes */ - mov 3*4(%esp),itmp1 /* return adress into java code */ - mov %esp,itmp2 /* begin of java stack frame */ - add $(3*4),itmp2 - push itmp1 - push itmp2 - pushl $0 /* internal (invisible) method */ - call asm_prepare_native_stackinfo /* puts additional 2 *4 bytes of - data onto the stack */ -#endif +L_asm_handle_exception_not_catched: + mov 4*4(sp),xptr /* restore exception pointer */ + mov 6*4(sp),itmp3 /* restore data segment pointer */ + mov 8*4(sp),t0 /* get maybe-leaf flag */ + add $(12*4),sp /* free stackframe */ - mov %esp,itmp1 /* pass stack pointer */ - add $(3*4),itmp1 /* also skip patcher function pointer */ - push itmp1 - mov 3*4(%esp),itmp1 /* get function pointer from stack */ - call *itmp1 /* call the patcher function */ - add $4,%esp - mov v0,itmp3 /* save return value */ + test t0,t0 + jz L_asm_handle_exception_no_leaf_stack -#if 0 - 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 */ -#endif + add $((ARG_CNT+TMP_CNT+3)*4),sp /* remove maybe-leaf stackframe */ + xor t0,t0 /* clear the maybe-leaf flag */ + +L_asm_handle_exception_no_leaf_stack: + mov FrameSize(itmp3),itmp2 /* get frame size */ + add sp,itmp2 /* pointer to save area */ + + push xptr /* we are out of registers */ + + mov IntSave(itmp3),itmp1 /* itmp1 = saved int register count */ + test itmp1,itmp1 + je noint - mov 0*4(%esp),itmp1 /* restore itmp1 and itmp2 */ - mov 1*4(%esp),itmp2 /* may be used by some instructions */ + cmp $1,itmp1 + je int1 + cmp $2,itmp1 + je int2 - add $((5+2)*4),%esp /* remove stack frame, keep ra */ - test itmp3,itmp3 /* exception thrown? */ - jz L_asm_wrapper_patcher_exception - ret /* call new patched code */ + mov -4-3*8(itmp2),s0 +int2: + mov -4-2*8(itmp2),s1 +int1: + mov -4-1*8(itmp2),s2 -L_asm_wrapper_patcher_exception: -#if defined(USE_THREADS) && defined(NATIVE_THREADS) - call builtin_asm_get_exceptionptrptr - mov v0,itmp2 -#else - lea _exceptionptr,itmp2 + shl $2,itmp1 /* multiply by 4 bytes */ + sub itmp1,itmp2 + +noint: +#if 0 + mov FltSave(itmp3),itmp1 /* itmp1 = saved flt register count */ + test itmp1,itmp1 + je noflt + + cmp $1,itmp1 + je flt1 + cmp $2,itmp1 + je flt2 + cmp $3,itmp1 + je flt3 + + fldl -4*8(itmp2) + fstp %st(1) +flt3: + fldl -3*8(itmp2) + fstp %st(2) +flt2: + fldl -2*8(itmp2) + fstp %st(3) +flt1: + fldl -1*8(itmp2) + fstp %st(4) + +noflt: #endif - mov (itmp2),xptr /* get the exception pointer */ - movl $0,(itmp2) /* clear the exception pointer */ + pop xptr /* restore exception pointer */ + mov FrameSize(itmp3),itmp2 /* get frame size */ + add itmp2,sp /* unwind stack */ - pop xpc /* get and remove return address */ - jmp asm_handle_exception + pop xpc /* the new xpc is return address */ + sub $2,xpc /* subtract 2-bytes for call */ + xor itmp3,itmp3 /* prepare a3 for handle_exception */ -/************************ function asm_builtin_ldiv **************************** -* * -* Does null check and calls ldiv or throws an exception * -* * -*******************************************************************************/ + jmp L_asm_handle_exception_stack_loop + -asm_builtin_ldiv: - mov 12(%esp),%eax - or 16(%esp),%eax - test %eax,%eax /* if (null) throw exception */ - je nb_ldiv +/* asm_abstractmethoderror ***************************************************** - jmp builtin_ldiv + Creates and throws an AbstractMethodError. -nb_ldiv: - 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 **************************** -* * -* Does null check and calls lrem or throws an exception * -* * *******************************************************************************/ -asm_builtin_lrem: - mov 12(%esp),%eax - or 16(%esp),%eax - test %eax,%eax /* if (null) throw exception */ - je nb_lrem +asm_abstractmethoderror: + sub $(3*4),sp /* keep stack 16-byte aligned */ + mov sp,itmp1 /* pass java sp */ + add $((1+3)*4),itmp1 + mov itmp1,0*4(sp) + mov 3*4(sp),itmp2 /* pass exception address */ + sub $2,itmp2 + mov itmp2,1*4(sp) + call exceptions_asm_new_abstractmethoderror + /* exception pointer is return value */ + add $(3*4),sp /* remove stack frame */ - jmp builtin_lrem + pop xpc /* get exception address */ + sub $2,xpc /* exception address is ra - 2 */ + jmp L_asm_handle_exception -nb_lrem: - 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 ***************************** * * @@ -806,522 +353,98 @@ nb_lrem: *******************************************************************************/ asm_builtin_f2i: - sub $4,%esp + sub $(3*4),%esp fsts (%esp) call builtin_f2i - add $4,%esp + add $(3*4),%esp ret asm_builtin_d2i: - sub $8,%esp + sub $(3*4),%esp fstl (%esp) call builtin_d2i - add $8,%esp + add $(3*4),%esp ret asm_builtin_f2l: - sub $4,%esp + sub $(3*4),%esp fsts (%esp) call builtin_f2l - add $4,%esp + add $(3*4),%esp ret asm_builtin_d2l: - sub $8,%esp + sub $(3*4),%esp fstl (%esp) call builtin_d2l - add $8,%esp + add $(3*4),%esp ret -/* asm_builtin_arraycheckcast ************************************************** - - Does the cast check and eventually throws an exception. - -*******************************************************************************/ - -asm_builtin_arraycheckcast: - sub $8,%esp /* build stack frame (2 * 4 bytes) */ - - mov 12(%esp),%eax /* first param: 8 (frame) + 4 (return)*/ - mov %eax,(%esp) /* save object pointer */ +/* asm_compare_and_swap ******************************************************** - mov 16(%esp),%eax /* second param: 8 (frame) + 4 (return) + 4*/ - mov %eax,4(%esp) + Does an atomic compare and swap. Required for the lock + implementation. - call builtin_arraycheckcast + Atomically do the following: Check if the location still contains + `oldval`. If so, replace it by `newval` and return `oldval`. - test %eax,%eax /* if (false) throw exception */ - je nb_carray_throw + RETURN VALUE: + the old value at *p - 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 + long compare_and_swap(volatile long *p, long oldval, long newval); - -/******************* function asm_builtin_aastore ****************************** -* * -* Does the cast check and eventually throws an exception * -* void asm_builtin_aastore(java_objectarray *a, s4 index, java_objectheader *o)* *******************************************************************************/ -asm_builtin_aastore: - 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 20(%esp),%ecx /* index (12 + 4 + 4) */ - 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 24(%esp),%eax /* object is second argument (12+4+4+4) */ - mov %eax,4(%esp) - - call builtin_canstore /* builtin_canstore(arrayref,object) */ - - test %eax,%eax /* if (false) throw exception */ - je nb_aastore_store - - mov 24(%esp),%eax - mov 8(%esp),%ecx - mov %eax,offobjarrdata(%ecx) /* store objectptr in array */ - - add $12,%esp +asm_compare_and_swap: + mov 1*4(sp),%ecx /* load p into a register */ + mov 2*4(sp),%eax /* load oldval into return register */ + mov 3*4(sp),%edx /* load newval into a register */ + lock; cmpxchgl %edx,0(%ecx) ret -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*/ - - push %eax - call new_arrayindexoutofboundsexception - add $(1*4),%esp - - call asm_remove_native_stackinfo /*return adress is the first on stack again*/ - - pop %ecx /* delete return address */ - sub $2,%ecx /* faulting address is return adress - 2 */ - 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_initialize_thread_stack ********************** -* * -* initialized a thread stack * -* (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)* -* * -*******************************************************************************/ -asm_initialize_thread_stack: - 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 */ - - -/******************* function asm_perform_threadswitch ************************* -* * -* void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); * -* * -* performs a threadswitch * -* * -*******************************************************************************/ +/* asm_memory_barrier ********************************************************** -asm_perform_threadswitch: - 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 - + A memory barrier for the Java Memory Model. -/********************* function asm_switchstackandcall ************************* -* * -* int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, * -* void *p); * -* * -* Switches to a new stack, calls a function and switches back. * -* a0 new stack pointer * -* a1 function pointer * -* a2 pointer to variable where stack top should be stored * -* a3 pointer to user data, is passed to the function * -* * *******************************************************************************/ -asm_switchstackandcall: - 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 */ - - mov 8(%esp),%eax /* load function pointer */ - mov 16(%esp),%ecx /* fourth argument *p */ - - mov %edx,%esp /* switch to new stack */ - - sub $4,%esp - mov %ecx,0(%esp) /* pass pointer */ - call *%eax /* and call function */ - add $4,%esp - - mov (%esp),%edx /* load return address */ - mov 4(%esp),%esp /* switch to old stack */ - mov %edx,(%esp) +asm_memory_barrier: + lock; add $0,0(sp) ret - -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*/ - - 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_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_new2: -/*optimize a littlebit */ - mov %esp,%eax -/*DEBUG*/ -/* push %eax - call i386_native_stub_debug - pop %eax */ - - 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 - - -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 +#if defined(ENABLE_ESCAPE_CHECK) +asm_escape_check: + sub $24,%esp + mov t0, 4(%esp) + mov itmp1, 8(%esp) + mov itmp2, 12(%esp) + mov itmp3, 16(%esp) + mov 28(%esp), itmp1 + mov itmp1, (%esp) + call escape_analysis_escape_check + mov 4(%esp), t0 + mov 8(%esp), itmp1 + mov 12(%esp), itmp2 + mov 16(%esp), itmp3 - -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 + add $24,sp 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 +/* disable exec-stacks ********************************************************/ -#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); +#if defined(__linux__) && defined(__ELF__) + .section .note.GNU-stack,"",%progbits #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 @@ -1333,4 +456,5 @@ asm_remove_native_stackinfo: * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */