/* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
- Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
-
- Authors: Andreas Krall
- Reinhard Grafl
- Christian Thalinger
-
- $Id: asmpart.S 3237 2005-09-21 13:22:49Z twisti $
+ $Id: asmpart.S 7483 2007-03-08 13:17:40Z michi $
*/
#include "config.h"
-#include "md-abi.h"
-#include "md-asm.h"
-
#include "vm/jit/x86_64/arch.h"
+#include "vm/jit/x86_64/md-abi.h"
+#include "vm/jit/x86_64/md-asm.h"
#include "vm/jit/x86_64/offsets.h"
+#include "vm/jit/abi-asm.h"
#include "vm/jit/methodheader.h"
.text
-/********************* exported functions and variables ***********************/
-
- .globl asm_calljavafunction
- .globl asm_calljavafunction_int
+/* export functions ***********************************************************/
- .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_call_jit_compiler
+
.globl asm_handle_exception
.globl asm_handle_nat_exception
- .globl asm_wrapper_patcher
+ .globl asm_abstractmethoderror
+
+ .globl asm_patcher_wrapper
- .globl asm_builtin_arraycheckcast
+#if defined(ENABLE_REPLACEMENT)
+ .globl asm_replacement_out
+ .globl asm_replacement_in
+#endif
.globl asm_builtin_f2i
.globl asm_builtin_f2l
.globl asm_builtin_d2i
.globl asm_builtin_d2l
- .globl asm_perform_threadswitch
- .globl asm_initialize_thread_stack
- .globl asm_switchstackandcall
+ .globl asm_compare_and_swap
+ .globl asm_memory_barrier
+
.globl asm_criticalsections
.globl asm_getclassvalues_atomic
* *
*******************************************************************************/
-call_name:
- .align 8
-
- .quad 0 /* catch type all */
- .quad calljava_xhandler /* handler pc */
- .quad calljava_xhandler /* end pc */
- .quad asm_calljavafunction /* start pc */
- .long 1 /* extable size */
- .long 0
- .quad 0 /* line number table start */
- .quad 0 /* line number table size */
- .long 0
- .long 0 /* fltsave */
- .long 0 /* intsave */
- .long 0 /* isleaf */
- .long 0 /* IsSync */
- .long 8 /* frame size */
- .quad 0 /* method pointer (pointer to name) */
-
-asm_calljavafunction:
-asm_calljavafunction_int:
- sub $(3*8),%rsp /* keep stack 16-byte aligned */
- mov %rbp,0*8(%rsp)
- mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
- mov %rdi,%rax /* move function pointer to %rax */
- /* compilerstub uses this */
-
- mov %rsi,%rdi /* pass remaining parameters */
- mov %rdx,%rsi
- mov %rcx,%rdx
- mov %r8,%rcx
-
- lea asm_call_jit_compiler,%r11
- call *%r11 /* call JIT compiler */
-
- mov 0*8(%rsp),%rbp
- mov 1*8(%rsp),%rbx
- add $(3*8),%rsp /* free stack space */
- ret
-
-calljava_xhandler:
- mov %rax,%rdi /* pass exception pointer */
- call builtin_throw_exception
- mov 0*8(%rsp),%rbp
- mov 1*8(%rsp),%rbx
- add $(3*8),%rsp
- xor %rax,%rax /* return NULL */
- ret
-
-
-/********************* 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_name2:
.align 8
- .quad 0 /* catch type all */
- .quad calljava_xhandler2 /* handler pc */
- .quad calljava_xhandler2 /* end pc */
- .quad asm_calljavafunction2 /* start pc */
- .long 1 /* extable size */
- .long 0
- .quad 0 /* line number table start */
- .quad 0 /* line number table size */
- .long 0
- .long 0 /* fltsave */
- .long 0 /* intsave */
- .long 0 /* isleaf */
- .long 0 /* IsSync */
- .long 24 /* frame size */
- .quad 0 /* method pointer (pointer to name) */
-
-asm_calljavafunction2:
-asm_calljavafunction2int:
-asm_calljavafunction2long:
-asm_calljavafunction2float:
-asm_calljavafunction2double:
- sub $(7*8),%rsp /* keep stack 16-byte aligned */
- mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
- mov %rbp,1*8(%rsp)
- mov %r12,2*8(%rsp)
- mov %r13,3*8(%rsp)
- mov %r14,4*8(%rsp)
- mov %r15,5*8(%rsp)
-
- mov %rdi,%rax /* move method pointer for compiler */
- xor %rbp,%rbp /* set argument stack frame to zero */
-
- test %rsi,%rsi /* maybe we have no args... */
+ .quad 0 /* catch type all */
+ .quad 0 /* handler pc */
+ .quad 0 /* end pc */
+ .quad 0 /* start pc */
+ .long 1 /* extable size */
+ .long 0 /* ALIGNMENT PADDING */
+ .quad 0 /* line number table start */
+ .quad 0 /* line number table size */
+ .long 0 /* ALIGNMENT PADDING */
+ .long 0 /* fltsave */
+ .long 0 /* intsave */
+ .long 0 /* isleaf */
+ .long 0 /* IsSync */
+ .long 0 /* frame size */
+ .quad 0 /* codeinfo pointer */
+
+asm_vm_call_method:
+asm_vm_call_method_int:
+asm_vm_call_method_long:
+asm_vm_call_method_float:
+asm_vm_call_method_double:
+ sub $(7*8),sp /* keep stack 16-byte aligned */
+ mov %rbx,0*8(sp) /* %rbx is not a callee saved in cacao*/
+ mov s0,1*8(sp)
+ mov s1,2*8(sp)
+ mov s2,3*8(sp)
+ mov s3,4*8(sp)
+ mov s4,5*8(sp)
+
+ mov a0,itmp1 /* move method pointer for compiler */
+ xor %rbp,%rbp /* set argument stack frame to zero */
+
+ test a1,a1 /* maybe we have no args... */
jle L_copy_done
- mov %rsi,itmp3 /* arg count */
- mov %rcx,itmp2 /* pointer to arg block */
+ mov a1,itmp3 /* arg count */
+ mov a2,itmp2 /* pointer to arg block */
- mov itmp2,%r14 /* save argument block pointer */
- mov itmp3,%r15 /* save argument count */
+ mov itmp2,%r14 /* save argument block pointer */
+ mov itmp3,%r15 /* save argument count */
- sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
- add $1,itmp3 /* initialize argument count */
- xor %r12,%r12 /* initialize integer argument counter */
- xor %r13,%r13 /* initialize float argument counter */
+ sub $sizevmarg,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 */
+ add $sizevmarg,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 */
+ andb $0x02,offvmargtype(itmp2) /* is this a float/double type? */
+ jnz L_register_handle_float /* yes, handle it */
- cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
- je L_register_copy /* register? yes, next loop */
+ cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
+ je L_register_copy /* register? yes, next loop */
- lea jumptable_integer,%rbp
+ lea jumptable_integer(%rip),%rbp
mov 0(%rbp,%r12,8),%rbx
inc %r12 /* integer argument counter + 1 */
jmp *%rbx
cmp $FLT_ARG_CNT,%r13 /* are we out of float argument */
je L_register_copy /* register? yes, next loop */
- lea jumptable_float,%rbp
+ lea jumptable_float(%rip),%rbp
mov 0(%rbp,%r13,8),%rbx
inc %r13 /* float argument counter + 1 */
jmp *%rbx
and $0xfffffffffffffffe,%rbp /* keep stack 16-byte aligned */
shl $3,%rbp /* calculate stack size */
- sub %rbp,%rsp /* stack frame for arguments */
- mov %rsp,%rbx /* use %rbx as temp sp */
+ sub %rbp,sp /* stack frame for arguments */
+ mov sp,%rbx /* use %rbx as temp sp */
- sub $sizejniblock,%r14 /* initialize pointer (smaller code) */
+ sub $sizevmarg,%r14 /* initialize pointer (smaller code) */
add $1,%r15 /* initialize argument count */
L_stack_copy_loop:
- add $sizejniblock,%r14 /* goto next argument block */
+ add $sizevmarg,%r14 /* goto next argument block */
dec %r15 /* are there any arguments left? */
jz L_copy_done /* no test needed after dec */
- andb $0x02,offjniitemtype(%r14) /* is this a float/double type? */
+ andb $0x02,offvmargtype(%r14) /* is this a float/double type? */
jnz L_stack_handle_float
- dec %r12 /* arguments assigned to registers */
+ 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 */
+ dec %r13 /* arguments assigned to registers */
jge L_stack_copy_loop
L_stack_copy:
- mov offjniitem(%r14),itmp3 /* copy s8 argument onto stack */
- mov itmp3,0(%rbx)
- add $8,%rbx /* increase sp to next argument */
+ mov offvmargdata(%r14),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 */
-
- add %rbp,%rsp /* remove argument stack frame if any */
-
- mov 5*8(%rsp),%r15 /* restore callee saved registers */
- mov 4*8(%rsp),%r14
- mov 3*8(%rsp),%r13
- mov 2*8(%rsp),%r12
- mov 1*8(%rsp),%rbp
- mov 0*8(%rsp),%rbx
- add $(7*8),%rsp /* free stack space */
+ /* itmp1 still contains method pointer*/
+ lea L_asm_call_jit_compiler(%rip),mptr
+ mov sp,itmp3 /* calculate the old stack pointer */
+ add bp,itmp3
+ mov mptr,6*8(itmp3)
+ lea (6*8-256)(itmp3),mptr /* We subtract 256 to force the next */
+ /* move instruction to have a 32-bit */
+ /* offset. */
+
+ mov (0*8+256)(mptr),itmp3 /* method call as in Java */
+ call *itmp3 /* call JIT compiler */
+
+ add bp,sp /* remove argument stack frame if any */
+
+L_asm_vm_call_method_return:
+ mov 0*8(sp),%rbx /* restore callee saved registers */
+ mov 1*8(sp),s0
+ mov 2*8(sp),s1
+ mov 3*8(sp),s2
+ mov 4*8(sp),s3
+ mov 5*8(sp),s4
+ add $(7*8),sp /* free stack space */
ret
-calljava_xhandler2:
- mov %rax,%rdi /* pass exception pointer */
- call builtin_throw_exception
-
- mov 5*8(%rsp),%r15 /* restore callee saved registers */
- mov 4*8(%rsp),%r14
- mov 3*8(%rsp),%r13
- mov 2*8(%rsp),%r12
- mov 1*8(%rsp),%rbp
- mov 0*8(%rsp),%rbx
- add $(7*8),%rsp /* free stack space */
- xor %rax,%rax /* return NULL */
- ret
+asm_vm_call_method_exception_handler:
+ mov xptr,a0 /* pass exception pointer */
+ call builtin_throw_exception@PLT
+ jmp L_asm_vm_call_method_return
jumptable_integer:
.quad handle_a5
handle_a0:
- mov offjniitem(itmp2),a0
+ mov offvmargdata(itmp2),a0
jmp L_register_copy
handle_a1:
- mov offjniitem(itmp2),a1
+ mov offvmargdata(itmp2),a1
jmp L_register_copy
handle_a2:
- mov offjniitem(itmp2),a2
+ mov offvmargdata(itmp2),a2
jmp L_register_copy
handle_a3:
- mov offjniitem(itmp2),a3
+ mov offvmargdata(itmp2),a3
jmp L_register_copy
handle_a4:
- mov offjniitem(itmp2),a4
+ mov offvmargdata(itmp2),a4
jmp L_register_copy
handle_a5:
- mov offjniitem(itmp2),a5
+ mov offvmargdata(itmp2),a5
jmp L_register_copy
.quad handle_fa7
handle_fa0:
- movq offjniitem(itmp2),fa0
+ movq offvmargdata(itmp2),fa0
jmp L_register_copy
handle_fa1:
- movq offjniitem(itmp2),fa1
+ movq offvmargdata(itmp2),fa1
jmp L_register_copy
handle_fa2:
- movq offjniitem(itmp2),fa2
+ movq offvmargdata(itmp2),fa2
jmp L_register_copy
handle_fa3:
- movq offjniitem(itmp2),fa3
+ movq offvmargdata(itmp2),fa3
jmp L_register_copy
handle_fa4:
- movq offjniitem(itmp2),fa4
+ movq offvmargdata(itmp2),fa4
jmp L_register_copy
handle_fa5:
- movq offjniitem(itmp2),fa5
+ movq offvmargdata(itmp2),fa5
jmp L_register_copy
handle_fa6:
- movq offjniitem(itmp2),fa6
+ movq offvmargdata(itmp2),fa6
jmp L_register_copy
handle_fa7:
- movq offjniitem(itmp2),fa7
+ movq offvmargdata(itmp2),fa7
jmp L_register_copy
*******************************************************************************/
asm_call_jit_compiler:
- sub $((3+24)*8+sizestackframeinfo),sp /* keep stack 16-byte aligned */
-
- mov %rbx,0*8(%rsp) /* save register */
-
- mov (3+24)*8+sizestackframeinfo(%rsp),itmp3 /* get return address */
- mov -1(itmp3),%bl /* get function code */
- cmp $0xd2,%bl /* called with `call *REG_ITMP2'? */
- jne L_not_static_special
-
- sub $11,itmp3 /* calculate address of immediate */
- jmp L_call_jit_compile
-
-L_not_static_special:
- cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
- jne L_not_virtual_interface
-
- sub $7,itmp3 /* calculate address of offset */
- mov (itmp3),itmp3l /* get offset (32-bit) */
- add itmp2,itmp3 /* add base address to get method address */
- jmp L_call_jit_compile
-
-L_not_virtual_interface: /* a call from asm_calljavamethod */
- xor itmp3,itmp3
-
-L_call_jit_compile:
- mov 0*8(sp),%rbx /* restore register */
- mov itmp3,0*8(sp) /* save address for method pointer */
- mov itmp1,1*8(sp) /* save method pointer */
+L_asm_call_jit_compiler: /* required for PIC code */
+ sub $(ARG_CNT+1)*8,sp /* +1: keep stack 16-byte aligned */
- SAVE_ARGUMENT_REGISTERS(2)
+ SAVE_ARGUMENT_REGISTERS(0)
- mov sp,a0 /* create stackframe info */
- add $((3+24)*8),a0 /* pass sfi */
- xor a1,a1 /* if pv is NULL, use findmethod */
+ mov itmp1,a0 /* pass methodinfo pointer */
+ mov mptr,a1 /* pass method pointer */
mov sp,a2 /* pass java sp */
- add $((1+3+24)*8+sizestackframeinfo),a2
- mov ((3+24)*8+sizestackframeinfo)(sp),a3 /* pass ra to java function */
- mov a3,a4 /* xpc is equal to ra */
- call stacktrace_create_extern_stackframeinfo
-
- mov 1*8(sp),a0 /* pass method pointer */
- call jit_compile
- mov v0,1*8(sp) /* save return value */
-
- mov sp,a0 /* remove stackframe info */
- add $((3+24)*8),a0 /* pass sfi */
- call stacktrace_remove_stackframeinfo
+ add $(1+ARG_CNT+1)*8,a2
+ mov (ARG_CNT+1)*8(sp),a3 /* pass ra to java function */
+ call jit_asm_compile@PLT
- mov 0*8(sp),itmp3 /* restore address for method pointer */
- mov 1*8(sp),v0 /* restore return value */
-
- RESTORE_ARGUMENT_REGISTERS(2)
+ RESTORE_ARGUMENT_REGISTERS(0)
- add $((3+24)*8+sizestackframeinfo),sp /* remove stack frame */
+ add $(ARG_CNT+1)*8,sp /* remove stack frame */
test v0,v0 /* check for exception */
je L_asm_call_jit_compiler_exception
- test %r11,%r11 /* is address == 0 (asm_calljavamethod*/
- je L_call_method
-
- mov %rax,(%r11) /* and now save the new pointer */
-
-L_call_method:
- jmp *%rax /* ...and now call the new method */
+ jmp *v0 /* ...and now call the new method */
L_asm_call_jit_compiler_exception:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- call builtin_asm_get_exceptionptrptr
- mov v0,itmp2 /* v0 == xptr */
-#else
- lea _exceptionptr,itmp2
-#endif
- mov (itmp2),xptr /* get the exception pointer */
- movl $0,(itmp2) /* clear exception pointer */
-
+ call exceptions_get_and_clear_exception@PLT
pop xpc /* delete return address */
- sub $5,xpc /* faulting address is ra - 5 */
- jmp asm_handle_exception
+ sub $3,xpc /* faulting address is ra - 3 */
+ jmp L_asm_handle_exception
-/********************* function asm_handle_exception ***************************
+/* asm_handle_exception ********************************************************
* *
* This function handles an exception. It does not use the usual calling *
* conventions. The exception pointer is passed in REG_ITMP1 and the *
* the local exception table for a handler. If no one is found, it unwinds *
* stacks and continues searching the callers. *
* *
-* void asm_handle_exception (exceptionptr, exceptionpc); *
-* *
*******************************************************************************/
asm_handle_nat_exception:
- add $8,%rsp /* clear return address of native stub*/
+ add $8,sp /* clear return address of native stub*/
asm_handle_exception:
- sub $(4*8),%rsp
- mov xptr,0*8(%rsp) /* save exception pointer */
- mov xpc,1*8(%rsp) /* save exception pc */
-
- mov xpc,%rdi /* exception pc */
- call codegen_findmethod
- mov %rax,itmp3
- mov %rax,2*8(%rsp) /* save data segment pointer */
+L_asm_handle_exception: /* required for PIC code */
+ sub $((ARG_CNT+TMP_CNT)*8),sp /* create maybe-leaf stackframe */
+
+ SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
+ SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
+
+ mov $((ARG_CNT+TMP_CNT)*8),a3 /* prepare a3 for handle_exception */
+ mov $1,t0 /* set maybe-leaf flag */
+
+L_asm_handle_exception_stack_loop:
+ sub $(6*8),sp
+ mov xptr,0*8(sp) /* save exception pointer */
+ mov xpc,1*8(sp) /* save exception pc */
+ add sp,a3 /* calculate Java sp into a3... */
+ add $(6*8),a3
+ mov a3,3*8(sp) /* ...and save it */
+ mov t0,4*8(sp) /* save maybe-leaf flag */
+
+ mov xpc,a0 /* exception pc */
+ call codegen_get_pv_from_pc@PLT
+ mov v0,2*8(sp) /* save data segment pointer */
- mov 0*8(%rsp),%rax /* restore exception pointer */
- mov 1*8(%rsp),%r10 /* restore exception pc */
-
-ex_stack_loop:
- mov %rax,%rdi /* exception pointer */
- mov MethodPointer(itmp3),%rsi /* method pointer */
- mov xpc,%rdx /* exception pc */
- mov $0,%rcx
- mov $1,%r8 /* set noindent flag */
- call builtin_trace_exception
-
- mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
- mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
- test %rcx,%rcx /* if empty table skip */
- je empty_table
-
- lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
- mov 0*8(%rsp),xptr /* get xptr */
-
-ex_table_loop:
- mov 1*8(%rsp),xpc /* get xpc */
-
- mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
- cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
- jg ex_table_cont /* if (false) continue */
- mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
- cmp %rdx,xpc /* %rdx = (xpc < endpc) */
- jge ex_table_cont /* if (false) continue */
- mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
- test %rdx,%rdx /* NULL catches everything */
- je ex_handle_it
-
- cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
- jne L_class_loaded
-
- sub $(4*8),%rsp
- mov %rax,0*8(%rsp)
- mov %rcx,1*8(%rsp)
- mov %rdx,2*8(%rsp)
- mov %rdi,3*8(%rsp)
-
- mov %rdx,%rdi
- call load_class_bootstrap
-
- mov 0*8(%rsp),%rax
- mov 1*8(%rsp),%rcx
- mov 2*8(%rsp),%rdx
- mov 3*8(%rsp),%rdi
- add $(4*8),%rsp
-
-L_class_loaded:
- cmpl $0,offclasslinked(%rdx) /* check if class is linked */
- jne L_class_linked
-
- sub $(4*8),%rsp
- mov %rax,0*8(%rsp)
- mov %rcx,1*8(%rsp)
- mov %rdx,2*8(%rsp)
- mov %rdi,3*8(%rsp)
-
- mov %rdx,%rdi
- call link_class
-
- mov 0*8(%rsp),%rax
- mov 1*8(%rsp),%rcx
- mov 2*8(%rsp),%rdx
- mov 3*8(%rsp),%rdi
- add $(4*8),%rsp
-
-L_class_linked:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- push %rdx
-
-_crit_restart1:
- mov 0(%rsp),%rdx
-#endif
+ mov 0*8(sp),a0 /* pass exception pointer */
+ mov 1*8(sp),a1 /* pass exception pc */
+ mov v0,a2 /* pass data segment pointer */
+ mov 3*8(sp),a3 /* pass Java stack pointer */
+ call exceptions_handle_exception@PLT
-_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
+ test v0,v0
+ jz L_asm_handle_exception_not_catched
- cmp %edx,%esi /* xptr is instanceof catchtype */
- ja ex_table_cont
-
-ex_handle_it:
- mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
+ mov v0,xpc /* move handlerpc into xpc */
+ mov 0*8(sp),xptr /* restore exception pointer */
+ mov 4*8(sp),t0 /* get maybe-leaf flag */
+ add $(6*8),sp /* free stack frame */
- mov 0*8(%rsp),%rax /* restore exception pointer */
- add $(4*8),%rsp /* free stack frame */
+ test t0,t0 /* test for maybe-leaf flag */
+ jz L_asm_handle_exception_no_leaf
- jmp *xpc /* jump to the handler */
+ RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
+ RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
-ex_table_cont:
- lea ExEntrySize(%rdi),%rdi /* next exception table entry */
- dec %rcx /* decrement entry counter */
- test %rcx,%rcx /* if (t0 > 0) next entry */
- jg ex_table_loop
-
-empty_table:
- mov 0*8(%rsp),%rax /* restore exception pointer */
- mov 1*8(%rsp),%r10 /* restore exception pc */
- mov 2*8(%rsp),%r11 /* restore data segment pointer */
- add $(4*8),%rsp
-
- mov %rax,%rcx /* save exception pointer */
-
-ex_already_cleared:
- movl IsSync(%r11),%eax /* %rax = SyncOffset */
- test %rax,%rax /* if zero no monitorexit */
- je no_monitor_exit
-
-#if defined(USE_THREADS)
- add %rsp,%rax
- mov -8(%rax),%rdi
-
- sub $(4*8),%rsp
- mov %rcx,0*8(%rsp)
- mov %r10,1*8(%rsp)
- mov %r11,2*8(%rsp)
-
- call builtin_monitorexit
+ add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
- mov 0*8(%rsp),%rcx
- mov 1*8(%rsp),%r10
- mov 2*8(%rsp),%r11
- add $(4*8),%rsp
-#endif
+L_asm_handle_exception_no_leaf:
+ jmp *xpc /* jump to the handler */
-no_monitor_exit:
- mov FrameSize(%r11),%eax /* %eax = frame size */
- add %rax,%rsp /* unwind stack */
- mov %rsp,%rax /* %rax = pointer to save area */
+L_asm_handle_exception_not_catched:
+ mov 0*8(sp),xptr /* restore exception pointer */
+ mov 2*8(sp),itmp3 /* restore data segment pointer */
+ mov 4*8(sp),t0 /* get maybe-leaf flag */
+ add $(6*8),sp
- mov IntSave(%r11),%edx /* %edx = saved int register count*/
- test %edx,%edx
- je noint
-
- cmp $1,%edx
- je int1
- cmp $2,%edx
- je int2
- cmp $3,%edx
- je int3
- cmp $4,%edx
- je int4
- cmp $5,%edx
- je int5
-
- mov -48(%rax),%rbx
-int5:
- mov -40(%rax),%rbp
+ test t0,t0
+ jz L_asm_handle_exception_no_leaf_stack
+
+ add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
+ xor t0,t0 /* clear the isleaf flags */
+
+L_asm_handle_exception_no_leaf_stack:
+ mov FrameSize(itmp3),itmp2l /* get frame size */
+ add sp,itmp2 /* pointer to save area */
+
+ mov IntSave(itmp3),a0l /* a0l = saved int register count */
+ test a0l,a0l
+ je noint
+
+ cmp $1,a0l
+ je int1
+ cmp $2,a0l
+ je int2
+ cmp $3,a0l
+ je int3
+ cmp $4,a0l
+ je int4
+
+ mov -5*8(itmp2),s0
int4:
- mov -32(%rax),%r12
+ mov -4*8(itmp2),s1
int3:
- mov -24(%rax),%r13
+ mov -3*8(itmp2),s2
int2:
- mov -16(%rax),%r14
+ mov -2*8(itmp2),s3
int1:
- mov -8(%rax),%r15
+ mov -1*8(itmp2),s4
- shl $3,%edx /* multiply by 8 bytes */
- sub %rdx,%rax
+ shl $3,a0l /* multiply by 8 bytes */
+ sub a0,itmp2
noint:
- mov FltSave(%r11),%edx /* %edx = saved flt register count*/
- test %edx,%edx
- je noflt
-
- cmpl $1,%edx
- je flt1
- cmpl $2,%edx
- je flt2
- cmpl $3,%edx
- je flt3
- cmpl $4,%edx
- je flt4
- cmpl $5,%edx
- je flt5
- cmpl $6,%edx
- je flt7
- cmpl $7,%edx
- je flt7
-
- movq -64(%rax),%xmm8
-flt7:
- movq -56(%rax),%xmm9
-flt6:
- movq -48(%rax),%xmm10
-flt5:
- movq -40(%rax),%xmm11
+#if 0
+ mov FltSave(itmp3),a0l /* a0l = saved flt register count */
+ test a0l,a0l
+ je noflt
+
+ cmpl $1,a0l
+ je flt1
+ cmpl $2,a0l
+ je flt2
+ cmpl $3,a0l
+ je flt3
+ cmpl $4,a0l
+ je flt4
+
+ movq -5*8(itmp2),%xmm11
flt4:
- movq -32(%rax),%xmm12
+ movq -4*8(itmp2),%xmm12
flt3:
- movq -24(%rax),%xmm13
+ movq -3*8(itmp2),%xmm13
flt2:
- movq -16(%rax),%xmm14
+ movq -2*8(itmp2),%xmm14
flt1:
- movq -8(%rax),%xmm15
+ movq -1*8(itmp2),%xmm15
-noflt:
- pop %r10 /* the new xpc is return address */
- sub $3,%r10 /* subtract 3 bytes for call */
+noflt:
+#endif
+ mov FrameSize(itmp3),itmp2l /* get frame size */
+ add itmp2,sp /* unwind stack */
- sub $(2*8),%rsp
- mov %rcx,0*8(%rsp)
- mov %r10,1*8(%rsp)
+ /* exception pointer is still set */
+ pop xpc /* the new xpc is return address */
+ sub $3,xpc /* subtract 3 bytes for call */
- mov %r10,%rdi
- call codegen_findmethod /* get the new data segment ptr */
- mov %rax,%r11
-
- mov 0*8(%rsp),%rcx
- mov 1*8(%rsp),%r10
- add $(2*8),%rsp
+ xor a3,a3 /* prepare a3 for handle_exception */
+
+ jmp L_asm_handle_exception_stack_loop
- mov %rcx,%rax /* restore saved exception pointer*/
- sub $(4*8),%rsp
-
- mov %rax,0*8(%rsp) /* save exception pointer */
- mov %r10,1*8(%rsp) /* save exception pc */
- mov %r11,2*8(%rsp) /* save data segment pointer */
-
- jmp ex_stack_loop
+/* asm_abstractmethoderror *****************************************************
+
+ Creates and throws an AbstractMethodError.
+*******************************************************************************/
+
+asm_abstractmethoderror:
+ mov sp,a0 /* pass java sp */
+ add $1*8,a0
+ mov 0*8(sp),a1 /* pass exception address */
+ sub $3,a1
+ call exceptions_asm_new_abstractmethoderror@PLT
+ /* exception pointer is return value */
+ pop xpc /* get exception address */
+ sub $3,xpc /* exception address is ra - 3 */
+ jmp L_asm_handle_exception
-/* asm_wrapper_patcher *********************************************************
+
+/* asm_patcher_wrapper *********************************************************
XXX
16 unresolved class/method/field reference
8 data segment displacement from load instructions
0 pointer to patcher function
+ -8 bp
*******************************************************************************/
-asm_wrapper_patcher:
- sub $(20*8+sizestackframeinfo),sp /* stack frame (16-byte aligned) */
+asm_patcher_wrapper:
+ push bp /* save base pointer */
+ mov sp,bp /* move actual sp to bp */
+ sub $(3+ARG_CNT+TMP_CNT)*8,sp
+ and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
+ /* leaf functions) */
- SAVE_ARGUMENT_REGISTERS(0)
- SAVE_TEMPORARY_REGISTERS(14)
+ SAVE_ARGUMENT_REGISTERS(3)
+ SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
- mov itmp1,15*8(sp) /* save itmp1 and itmp2 */
- mov itmp2,16*8(sp) /* can be used by some instructions */
+ mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
+ mov itmp2,1*8(sp) /* can be used by some instructions */
- mov sp,a0 /* create stackframe info */
- add $(20*8),a0
- xor a1,a1 /* if pv is NULL, use findmethod */
- mov sp,a2 /* pass java sp */
- add $((6+20)*8+sizestackframeinfo),a2
- mov ((5+20)*8+sizestackframeinfo)(sp),a3 /* pass ra to java function */
- mov a3,a4 /* xpc is equal to ra */
- call stacktrace_create_extern_stackframeinfo
-
- mov sp,a0 /* pass stack pointer */
- add $((1+20)*8+sizestackframeinfo),a0 /* skip function pointer */
- mov (20*8+sizestackframeinfo)(sp),itmp3 /* get function pointer */
- call *itmp3 /* call the patcher function */
- mov v0,17*8(sp) /* save return value */
+ mov bp,a0 /* pass SP of patcher stub */
+ add $(1*8),a0
+ mov $0,a1 /* pass PV (if NULL, use findmethod) */
+ mov $0,a2 /* pass RA (it's on the stack) */
+ call patcher_wrapper@PLT
+ mov v0,2*8(sp) /* save return value */
- mov sp,a0 /* remove stackframe info */
- add $(20*8),a0
- call stacktrace_remove_stackframeinfo
-
- RESTORE_ARGUMENT_REGISTERS(0)
- RESTORE_TEMPORARY_REGISTERS(14)
+ RESTORE_ARGUMENT_REGISTERS(3)
+ RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
- mov 15*8(sp),itmp1 /* restore itmp1 and itmp2 */
- mov 16*8(sp),itmp2 /* can be used by some instructions */
- mov 17*8(sp),itmp3 /* restore return value */
+ mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
+ mov 1*8(sp),itmp2 /* can be used by some instructions */
+ mov 2*8(sp),itmp3 /* restore return value */
- add $((5+20)*8+sizestackframeinfo),sp /* remove stack frame, keep ra */
+ mov bp,sp /* restore original sp */
+ pop bp /* restore bp */
+ add $(5*8),sp /* remove patcher stackframe, keep RA */
test itmp3,itmp3 /* exception thrown? */
- jz L_asm_wrapper_patcher_exception
+ jne L_asm_patcher_wrapper_exception
ret /* call new patched code */
-L_asm_wrapper_patcher_exception:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- call builtin_asm_get_exceptionptrptr
- mov v0,itmp2 /* v0 == xptr */
-#else
- lea _exceptionptr,itmp2
-#endif
- mov (itmp2),xptr /* get the exception pointer */
- movl $0,(itmp2) /* clear exception pointer */
-
+L_asm_patcher_wrapper_exception:
+ mov itmp3,xptr /* get exception */
pop xpc /* get and remove return address */
- jmp asm_handle_exception
+ jmp L_asm_handle_exception
+
+#if defined(ENABLE_REPLACEMENT)
+
+/* asm_replacement_out *********************************************************
+
+ This code is jumped to from the replacement-out stubs that are executed
+ when a thread reaches an activated replacement point.
+
+ The purpose of asm_replacement_out is to read out the parts of the
+ execution state that cannot be accessed from C code, store this state,
+ and then call the C function replace_me.
+
+ Stack layout:
+ 8 start of stack inside method to replace
+ 0 rplpoint * info on the replacement point that was reached
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+ /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM 512
+
+asm_replacement_out:
+ /* create stack frame */
+ sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
+
+ /* save registers in execution state */
+ mov %rax,(RAX*8+offes_intregs)(sp)
+ mov %rbx,(RBX*8+offes_intregs)(sp)
+ mov %rcx,(RCX*8+offes_intregs)(sp)
+ mov %rdx,(RDX*8+offes_intregs)(sp)
+ mov %rsi,(RSI*8+offes_intregs)(sp)
+ mov %rdi,(RDI*8+offes_intregs)(sp)
+ mov %rbp,(RBP*8+offes_intregs)(sp)
+ movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
+ mov %r8 ,(R8 *8+offes_intregs)(sp)
+ mov %r9 ,(R9 *8+offes_intregs)(sp)
+ mov %r10,(R10*8+offes_intregs)(sp)
+ mov %r11,(R11*8+offes_intregs)(sp)
+ mov %r12,(R12*8+offes_intregs)(sp)
+ mov %r13,(R13*8+offes_intregs)(sp)
+ mov %r14,(R14*8+offes_intregs)(sp)
+ mov %r15,(R15*8+offes_intregs)(sp)
+
+ movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
+ movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
+ movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
+ movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
+ movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
+ movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
+ movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
+ movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
+ movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
+ movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
+ movq %xmm10,(XMM10*8+offes_fltregs)(sp)
+ movq %xmm11,(XMM11*8+offes_fltregs)(sp)
+ movq %xmm12,(XMM12*8+offes_fltregs)(sp)
+ movq %xmm13,(XMM13*8+offes_fltregs)(sp)
+ movq %xmm14,(XMM14*8+offes_fltregs)(sp)
+ movq %xmm15,(XMM15*8+offes_fltregs)(sp)
+
+ /* calculate sp of method */
+ mov sp,itmp1
+ add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
+ mov itmp1,(offes_sp)(sp)
+
+ /* pv must be looked up via AVL tree */
+ movq $0,(offes_pv)(sp)
+
+ /* call replace_me */
+ mov -8(itmp1),a0 /* rplpoint * */
+ mov sp,a1 /* arg1: execution state */
+ call replace_me@PLT /* call C function replace_me */
+ call abort@PLT /* NEVER REACHED */
+
+/* asm_replacement_in **********************************************************
+
+ This code writes the given execution state and jumps to the replacement
+ code.
+
+ This function never returns!
+
+ C prototype:
+ void asm_replacement_in(executionstate *es, replace_safestack_t *st);
+
+*******************************************************************************/
+
+asm_replacement_in:
+ /* get arguments */
+ mov a1,s1 /* replace_safestack_t *st */
+ mov a0,%rbp /* executionstate *es == safe stack */
+
+ /* switch to the safe stack */
+ mov %rbp,sp
+
+ /* call replace_build_execution_state(st) */
+ mov s1,a0
+ call replace_build_execution_state@PLT
+
+ /* set new sp */
+ mov (offes_sp)(%rbp),sp
+
+ /* push address of new code */
+ pushq (offes_pc)(%rbp)
+
+ /* allocate an executionstate_t on the stack */
+ sub $(sizeexecutionstate),sp
+
+ /* call replace_free_safestack(st,& of allocated executionstate_t) */
+ mov sp,a1
+ mov s1,a0
+ call replace_free_safestack@PLT
+
+ /* copy registers from execution state */
+ movq (XMM0 *8+offes_fltregs)(sp),%xmm0
+ movq (XMM1 *8+offes_fltregs)(sp),%xmm1
+ movq (XMM2 *8+offes_fltregs)(sp),%xmm2
+ movq (XMM3 *8+offes_fltregs)(sp),%xmm3
+ movq (XMM4 *8+offes_fltregs)(sp),%xmm4
+ movq (XMM5 *8+offes_fltregs)(sp),%xmm5
+ movq (XMM6 *8+offes_fltregs)(sp),%xmm6
+ movq (XMM7 *8+offes_fltregs)(sp),%xmm7
+ movq (XMM8 *8+offes_fltregs)(sp),%xmm8
+ movq (XMM9 *8+offes_fltregs)(sp),%xmm9
+ movq (XMM10*8+offes_fltregs)(sp),%xmm10
+ movq (XMM11*8+offes_fltregs)(sp),%xmm11
+ movq (XMM12*8+offes_fltregs)(sp),%xmm12
+ movq (XMM13*8+offes_fltregs)(sp),%xmm13
+ movq (XMM14*8+offes_fltregs)(sp),%xmm14
+ movq (XMM15*8+offes_fltregs)(sp),%xmm15
+
+ mov (RAX*8+offes_intregs)(sp),%rax
+ mov (RBX*8+offes_intregs)(sp),%rbx
+ mov (RCX*8+offes_intregs)(sp),%rcx
+ mov (RDX*8+offes_intregs)(sp),%rdx
+ mov (RSI*8+offes_intregs)(sp),%rsi
+ mov (RDI*8+offes_intregs)(sp),%rdi
+ mov (RBP*8+offes_intregs)(sp),%rbp
+ mov (R8 *8+offes_intregs)(sp),%r8
+ mov (R9 *8+offes_intregs)(sp),%r9
+ mov (R10*8+offes_intregs)(sp),%r10
+ mov (R11*8+offes_intregs)(sp),%r11
+ mov (R12*8+offes_intregs)(sp),%r12
+ mov (R13*8+offes_intregs)(sp),%r13
+ mov (R14*8+offes_intregs)(sp),%r14
+ mov (R15*8+offes_intregs)(sp),%r15
+
+ /* pop the execution state off the stack */
+ add $(sizeexecutionstate),sp
+
+ /* jump to new code */
+ ret
+
+#endif /* defined(ENABLE_REPLACEMENT) */
/* asm_builtin_x2x *************************************************************
*******************************************************************************/
asm_builtin_f2i:
- sub $(14*8),%rsp
+ sub $(ARG_CNT*8),sp
SAVE_ARGUMENT_REGISTERS(0)
- movq %xmm8,%xmm0
- call builtin_f2i
+ movq ftmp1,fa0
+ call builtin_f2i@PLT
RESTORE_ARGUMENT_REGISTERS(0)
- add $(14*8),%rsp
+ add $(ARG_CNT*8),sp
ret
asm_builtin_f2l:
- sub $(14*8),%rsp
+ sub $(ARG_CNT*8),sp
SAVE_ARGUMENT_REGISTERS(0)
- movq %xmm8,%xmm0
- call builtin_f2l
+ movq ftmp1,fa0
+ call builtin_f2l@PLT
RESTORE_ARGUMENT_REGISTERS(0)
- add $(14*8),%rsp
+ add $(ARG_CNT*8),sp
ret
asm_builtin_d2i:
- sub $(14*8),%rsp
+ sub $(ARG_CNT*8),sp
SAVE_ARGUMENT_REGISTERS(0)
- movq %xmm8,%xmm0
- call builtin_d2i
+ movq ftmp1,fa0
+ call builtin_d2i@PLT
RESTORE_ARGUMENT_REGISTERS(0)
- add $(14*8),%rsp
+ add $(ARG_CNT*8),sp
ret
asm_builtin_d2l:
- sub $(14*8),%rsp
+ sub $(ARG_CNT*8),sp
SAVE_ARGUMENT_REGISTERS(0)
- movq %xmm8,%xmm0
- call builtin_d2l
+ movq ftmp1,fa0
+ call builtin_d2l@PLT
RESTORE_ARGUMENT_REGISTERS(0)
- add $(14*8),%rsp
+ add $(ARG_CNT*8),sp
ret
-/******************* function asm_initialize_thread_stack **********************
-* *
-* initialized a thread stack *
-* (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
-* *
-*******************************************************************************/
-
-asm_initialize_thread_stack:
- sub $(7*8),%rsi
-
- xor %r10,%r10
- mov %r10,0*8(%rsi)
- mov %r10,1*8(%rsi)
- mov %r10,2*8(%rsi)
- mov %r10,3*8(%rsi)
- mov %r10,4*8(%rsi)
- mov %r10,5*8(%rsi)
+/* asm_compare_and_swap ********************************************************
- mov %rdi,6*8(%rsi) /* save (u1*) (func) */
- mov %rsi,%rax /* return restorepoint in %rax */
- ret
+ Does an atomic compare and swap. Required for the lock
+ implementation.
-
-/******************* function asm_perform_threadswitch *************************
-* *
-* void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
-* *
-* performs a threadswitch *
-* *
*******************************************************************************/
-asm_perform_threadswitch:
- sub $(7*8),%rsp /* allocate stack frame */
-
- mov %rbx,0*8(%rsp)
- 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 7*8(%rsp),%rax /* save current return address */
- mov %rax,6*8(%rsp)
-
- mov %rsp,(%rdi) /* first argument **from */
- mov %rsp,(%rdx) /* third argument **stackTop */
+asm_compare_and_swap:
+ mov a1,v0 /* v0 is %rax */
+ lock cmpxchg a2,(a0)
+ ret
- mov (%rsi),%rsp /* load new stack pointer */
- mov 0*8(%rsp),%rbx
- mov 1*8(%rsp),%rbp
- mov 2*8(%rsp),%r12
- mov 3*8(%rsp),%r13
- mov 4*8(%rsp),%r14
- mov 5*8(%rsp),%r15
+/* asm_memory_barrier **********************************************************
- mov 6*8(%rsp),%rax /* restore return address */
- add $(7*8),%rsp /* free stack frame */
- mov %rax,(%rsp)
- 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 (%rdi) new stack pointer *
-* a1 (%rsi) function pointer *
-* a2 (%rdx) pointer to variable where stack top should be stored *
-* a3 (%rcx) pointer to user data, is passed to the function *
-* *
*******************************************************************************/
-asm_switchstackandcall:
- sub $(1*8),%rsp /* keep stack 16-byte aligned */
- sub $16,%rdi /* allocate new stack */
-
- mov 8(%rsp),%rax /* save return address on new stack */
- mov %rax,(%rdi)
- mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
- mov %rsp,(%rdx) /* save old stack pointer to variable */
-
- mov %rdi,%rsp /* switch to new stack */
-
- mov %rcx,%rdi /* pass pointer */
- call *%rsi /* and call function */
-
- mov (%rsp),%r10 /* load return address */
- mov 8(%rsp),%rsp /* switch to old stack */
- add $(1*8),%rsp /* free stack space */
- mov %r10,(%rsp) /* write return adress */
- ret
+asm_memory_barrier:
+ mfence
+ ret
asm_getclassvalues_atomic:
-_crit_restart2:
-_crit_begin2:
+_crit_restart:
+_crit_begin:
movl offbaseval(a0),itmp1l
movl offdiffval(a0),itmp2l
movl offbaseval(a1),itmp3l
-_crit_end2:
+_crit_end:
movl itmp1l,offcast_super_baseval(a2)
movl itmp2l,offcast_super_diffval(a2)
movl itmp3l,offcast_sub_baseval(a2)
.data
asm_criticalsections:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- .quad _crit_begin1
- .quad _crit_end1
- .quad _crit_restart1
- .quad _crit_begin2
- .quad _crit_end2
- .quad _crit_restart2
+#if defined(ENABLE_THREADS)
+ .quad _crit_begin
+ .quad _crit_end
+ .quad _crit_restart
#endif
.quad 0
+/* Disable exec-stacks, required for Gentoo ***********************************/
+
+#if defined(__GCC__) && 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
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/