1 /* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
31 Changes: Edwin Steiner
33 $Id: asmpart.S 4921 2006-05-15 14:24:36Z twisti $
40 #include "vm/jit/x86_64/arch.h"
41 #include "vm/jit/x86_64/md-abi.h"
42 #include "vm/jit/x86_64/md-asm.h"
43 #include "vm/jit/x86_64/offsets.h"
45 #include "vm/jit/abi-asm.h"
46 #include "vm/jit/methodheader.h"
52 /* export functions ***********************************************************/
54 .globl asm_vm_call_method
55 .globl asm_vm_call_method_int
56 .globl asm_vm_call_method_long
57 .globl asm_vm_call_method_float
58 .globl asm_vm_call_method_double
59 .globl asm_vm_call_method_exception_handler
61 .globl asm_call_jit_compiler
62 .globl asm_handle_exception
63 .globl asm_handle_nat_exception
65 .globl asm_wrapper_patcher
67 .globl asm_replacement_out
68 .globl asm_replacement_in
70 .globl asm_builtin_f2i
71 .globl asm_builtin_f2l
72 .globl asm_builtin_d2i
73 .globl asm_builtin_d2l
75 .globl asm_perform_threadswitch
76 .globl asm_initialize_thread_stack
77 .globl asm_switchstackandcall
78 .globl asm_criticalsections
79 .globl asm_getclassvalues_atomic
82 /********************* function asm_calljavafunction ***************************
84 * This function calls a Java-method (which possibly needs compilation) *
85 * with up to 4 address parameters. *
87 * This functions calls the JIT-compiler which eventually translates the *
88 * method into machine code. *
91 * javaobject_header *asm_calljavamethod (methodinfo *m, *
92 * void *arg1, void *arg2, void *arg3, void *arg4); *
94 *******************************************************************************/
98 .quad 0 /* catch type all */
99 .quad 0 /* handler pc */
101 .quad 0 /* start pc */
102 .long 1 /* extable size */
104 .quad 0 /* line number table start */
105 .quad 0 /* line number table size */
107 .long 0 /* fltsave */
108 .long 0 /* intsave */
111 .long 0 /* frame size */
112 .quad 0 /* method pointer (pointer to name) */
115 asm_vm_call_method_int:
116 asm_vm_call_method_long:
117 asm_vm_call_method_float:
118 asm_vm_call_method_double:
119 sub $(7*8),sp /* keep stack 16-byte aligned */
120 mov %rbx,0*8(sp) /* %rbx is not a callee saved in cacao*/
127 mov a0,itmp1 /* move method pointer for compiler */
128 xor %rbp,%rbp /* set argument stack frame to zero */
130 test a1,a1 /* maybe we have no args... */
133 mov a1,itmp3 /* arg count */
134 mov a2,itmp2 /* pointer to arg block */
136 mov itmp2,%r14 /* save argument block pointer */
137 mov itmp3,%r15 /* save argument count */
139 sub $sizevmarg,itmp2 /* initialize pointer (smaller code) */
140 add $1,itmp3 /* initialize argument count */
141 xor %r12,%r12 /* initialize integer argument counter*/
142 xor %r13,%r13 /* initialize float argument counter */
145 add $sizevmarg,itmp2 /* goto next argument block */
146 dec itmp3 /* argument count - 1 */
147 jz L_register_copy_done
148 andb $0x02,offvmargtype(itmp2) /* is this a float/double type? */
149 jnz L_register_handle_float /* yes, handle it */
151 cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
152 je L_register_copy /* register? yes, next loop */
154 lea jumptable_integer(%rip),%rbp
155 mov 0(%rbp,%r12,8),%rbx
156 inc %r12 /* integer argument counter + 1 */
159 L_register_handle_float:
160 cmp $FLT_ARG_CNT,%r13 /* are we out of float argument */
161 je L_register_copy /* register? yes, next loop */
163 lea jumptable_float(%rip),%rbp
164 mov 0(%rbp,%r13,8),%rbx
165 inc %r13 /* float argument counter + 1 */
168 L_register_copy_done:
169 mov %r15,%rbp /* calculate remaining arguments */
170 sub %r12,%rbp /* - integer arguments in registers */
171 sub %r13,%rbp /* - float arguments in registers */
172 jle L_copy_done /* are all assigned to registers? */
174 and $0xfffffffffffffffe,%rbp /* keep stack 16-byte aligned */
175 shl $3,%rbp /* calculate stack size */
176 sub %rbp,sp /* stack frame for arguments */
177 mov sp,%rbx /* use %rbx as temp sp */
179 sub $sizevmarg,%r14 /* initialize pointer (smaller code) */
180 add $1,%r15 /* initialize argument count */
183 add $sizevmarg,%r14 /* goto next argument block */
184 dec %r15 /* are there any arguments left? */
185 jz L_copy_done /* no test needed after dec */
187 andb $0x02,offvmargtype(%r14) /* is this a float/double type? */
188 jnz L_stack_handle_float
189 dec %r12 /* arguments assigned to registers */
190 jge L_stack_copy_loop
193 L_stack_handle_float:
194 dec %r13 /* arguments assigned to registers */
195 jge L_stack_copy_loop
198 mov offvmargdata(%r14),itmp3 /* copy s8 argument onto stack */
200 add $8,%rbx /* increase sp to next argument */
201 jmp L_stack_copy_loop
204 /* itmp1 still contains method pointer*/
205 lea L_asm_call_jit_compiler(%rip),mptr
206 mov sp,itmp3 /* calculate the old stack pointer */
209 lea (6*8-256)(itmp3),mptr /* We subtract 256 to force the next */
210 /* move instruction to have a 32-bit */
213 mov (0*8+256)(mptr),itmp3 /* method call as in Java */
214 call *itmp3 /* call JIT compiler */
216 add bp,sp /* remove argument stack frame if any */
218 L_asm_vm_call_method_return:
219 mov 0*8(sp),%rbx /* restore callee saved registers */
225 add $(7*8),sp /* free stack space */
228 asm_vm_call_method_exception_handler:
229 mov xptr,a0 /* pass exception pointer */
230 call builtin_throw_exception@PLT
231 jmp L_asm_vm_call_method_return
243 mov offvmargdata(itmp2),a0
246 mov offvmargdata(itmp2),a1
249 mov offvmargdata(itmp2),a2
252 mov offvmargdata(itmp2),a3
255 mov offvmargdata(itmp2),a4
258 mov offvmargdata(itmp2),a5
273 movq offvmargdata(itmp2),fa0
276 movq offvmargdata(itmp2),fa1
279 movq offvmargdata(itmp2),fa2
282 movq offvmargdata(itmp2),fa3
285 movq offvmargdata(itmp2),fa4
288 movq offvmargdata(itmp2),fa5
291 movq offvmargdata(itmp2),fa6
294 movq offvmargdata(itmp2),fa7
298 /****************** function asm_call_jit_compiler *****************************
300 * invokes the compiler for untranslated JavaVM methods. *
302 * Register R0 contains a pointer to the method info structure (prepared *
303 * by createcompilerstub). Using the return address in R26 and the *
304 * offset in the LDA instruction or using the value in methodptr R28 the *
305 * patching address for storing the method address can be computed: *
307 * method address was either loaded using *
309 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
310 * i386_call_reg(REG_ITMP2) *
314 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
315 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
316 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
317 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
318 * i386_call_reg(REG_ITMP1) *
320 * in the static case the method pointer can be computed using the *
321 * return address and the lda function following the jmp instruction *
323 *******************************************************************************/
325 asm_call_jit_compiler:
326 L_asm_call_jit_compiler: /* required for PIC code */
327 sub $(ARG_CNT+1)*8,sp /* +1: keep stack 16-byte aligned */
329 SAVE_ARGUMENT_REGISTERS(0)
331 mov itmp1,a0 /* pass methodinfo pointer */
332 mov mptr,a1 /* pass method pointer */
333 mov sp,a2 /* pass java sp */
334 add $(1+ARG_CNT+1)*8,a2
335 mov (ARG_CNT+1)*8(sp),a3 /* pass ra to java function */
336 call jit_asm_compile@PLT
338 RESTORE_ARGUMENT_REGISTERS(0)
340 add $(ARG_CNT+1)*8,sp /* remove stack frame */
342 test v0,v0 /* check for exception */
343 je L_asm_call_jit_compiler_exception
345 jmp *v0 /* ...and now call the new method */
347 L_asm_call_jit_compiler_exception:
348 #if defined(ENABLE_THREADS)
349 call builtin_asm_get_exceptionptrptr@PLT
350 mov v0,itmp2 /* v0 == xptr */
352 lea _no_threads_exceptionptr(%rip),itmp2
354 mov (itmp2),xptr /* get the exception pointer */
355 movl $0,(itmp2) /* clear exception pointer */
357 pop xpc /* delete return address */
358 sub $5,xpc /* faulting address is ra - 5 */
359 jmp L_asm_handle_exception
362 /* asm_handle_exception ********************************************************
364 * This function handles an exception. It does not use the usual calling *
365 * conventions. The exception pointer is passed in REG_ITMP1 and the *
366 * pc from the exception raising position is passed in REG_ITMP2. It searches *
367 * the local exception table for a handler. If no one is found, it unwinds *
368 * stacks and continues searching the callers. *
370 *******************************************************************************/
372 asm_handle_nat_exception:
373 add $8,sp /* clear return address of native stub*/
375 asm_handle_exception:
376 L_asm_handle_exception: /* required for PIC code */
377 sub $((ARG_CNT+TMP_CNT)*8),sp /* create maybe-leaf stackframe */
379 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
380 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
382 mov $((ARG_CNT+TMP_CNT)*8),a3 /* prepare a3 for handle_exception */
383 mov $1,t0 /* set maybe-leaf flag */
385 L_asm_handle_exception_stack_loop:
387 mov xptr,0*8(sp) /* save exception pointer */
388 mov xpc,1*8(sp) /* save exception pc */
389 add sp,a3 /* calculate Java sp into a3... */
391 mov a3,3*8(sp) /* ...and save it */
392 mov t0,4*8(sp) /* save maybe-leaf flag */
394 mov xpc,a0 /* exception pc */
395 call codegen_findmethod@PLT
396 mov v0,2*8(sp) /* save data segment pointer */
398 mov 0*8(sp),a0 /* pass exception pointer */
399 mov 1*8(sp),a1 /* pass exception pc */
400 mov v0,a2 /* pass data segment pointer */
401 mov 3*8(sp),a3 /* pass Java stack pointer */
402 call exceptions_handle_exception@PLT
405 jz L_asm_handle_exception_not_catched
407 mov v0,xpc /* move handlerpc into xpc */
408 mov 0*8(sp),xptr /* restore exception pointer */
409 mov 4*8(sp),t0 /* get maybe-leaf flag */
410 add $(6*8),sp /* free stack frame */
412 test t0,t0 /* test for maybe-leaf flag */
413 jz L_asm_handle_exception_no_leaf
415 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
416 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
418 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
420 L_asm_handle_exception_no_leaf:
421 jmp *xpc /* jump to the handler */
423 L_asm_handle_exception_not_catched:
424 mov 0*8(sp),xptr /* restore exception pointer */
425 mov 2*8(sp),itmp3 /* restore data segment pointer */
426 mov 4*8(sp),t0 /* get maybe-leaf flag */
430 jz L_asm_handle_exception_no_leaf_stack
432 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
433 xor t0,t0 /* clear the isleaf flags */
435 L_asm_handle_exception_no_leaf_stack:
436 mov FrameSize(itmp3),itmp2l /* get frame size */
437 add sp,itmp2 /* pointer to save area */
439 mov IntSave(itmp3),a0l /* a0l = saved int register count */
462 shl $3,a0l /* multiply by 8 bytes */
467 mov FltSave(itmp3),a0l /* a0l = saved flt register count */
480 movq -5*8(itmp2),%xmm11
482 movq -4*8(itmp2),%xmm12
484 movq -3*8(itmp2),%xmm13
486 movq -2*8(itmp2),%xmm14
488 movq -1*8(itmp2),%xmm15
492 mov FrameSize(itmp3),itmp2l /* get frame size */
493 add itmp2,sp /* unwind stack */
495 /* exception pointer is still set */
496 pop xpc /* the new xpc is return address */
497 sub $3,xpc /* subtract 3 bytes for call */
499 xor a3,a3 /* prepare a3 for handle_exception */
501 jmp L_asm_handle_exception_stack_loop
504 /* asm_wrapper_patcher *********************************************************
510 32 pointer to virtual java_objectheader
511 24 machine code (which is patched back later)
512 16 unresolved class/method/field reference
513 8 data segment displacement from load instructions
514 0 pointer to patcher function
517 *******************************************************************************/
520 push bp /* save base pointer */
521 mov sp,bp /* move actual sp to bp */
522 sub $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),sp
523 and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
524 /* leaf functions) */
526 SAVE_ARGUMENT_REGISTERS(3)
527 SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
529 mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
530 mov itmp2,1*8(sp) /* can be used by some instructions */
532 mov sp,a0 /* create stackframe info */
533 add $((3+ARG_CNT+TMP_CNT)*8),a0
534 xor a1,a1 /* if pv is NULL, use findmethod */
535 mov bp,a2 /* pass java sp */
537 mov ((5+1)*8)(bp),a3 /* pass ra to java function */
538 mov a3,a4 /* xpc is equal to ra */
539 call stacktrace_create_extern_stackframeinfo@PLT
541 mov bp,a0 /* pass stack pointer */
542 add $((1+1)*8),a0 /* skip function pointer */
543 mov 1*8(bp),itmp3 /* get function pointer */
544 call *itmp3 /* call the patcher function */
545 mov v0,2*8(sp) /* save return value */
547 mov sp,a0 /* remove stackframe info */
548 add $((3+ARG_CNT+TMP_CNT)*8),a0
549 call stacktrace_remove_stackframeinfo@PLT
551 RESTORE_ARGUMENT_REGISTERS(3)
552 RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
554 mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
555 mov 1*8(sp),itmp2 /* can be used by some instructions */
556 mov 2*8(sp),itmp3 /* restore return value */
558 mov bp,sp /* restore original sp */
559 pop bp /* restore bp */
560 add $(5*8),sp /* remove patcher stackframe, keep ra */
562 test itmp3,itmp3 /* exception thrown? */
563 jz L_asm_wrapper_patcher_exception
564 ret /* call new patched code */
566 L_asm_wrapper_patcher_exception:
567 #if defined(ENABLE_THREADS)
568 call builtin_asm_get_exceptionptrptr@PLT
569 mov v0,itmp2 /* v0 == xptr */
571 mov _no_threads_exceptionptr,itmp2
573 mov (itmp2),xptr /* get the exception pointer */
574 movl $0,(itmp2) /* clear exception pointer */
576 pop xpc /* get and remove return address */
577 jmp L_asm_handle_exception
580 /* asm_replacement_out *********************************************************
582 This code is jumped to from the replacement-out stubs that are executed
583 when a thread reaches an activated replacement point.
585 The purpose of asm_replacement_out is to read out the parts of the
586 execution state that cannot be accessed from C code, store this state,
587 and then call the C function replace_me.
590 8 start of stack inside method to replace
591 0 rplpoint * info on the replacement point that was reached
593 *******************************************************************************/
595 /* some room to accomodate changes of the stack frame size during replacement */
596 /* XXX we should find a cleaner solution here */
597 #define REPLACEMENT_ROOM 512
600 /* create stack frame */
601 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
603 /* save registers in execution state */
604 mov %rax,(RAX*8+offes_intregs)(sp)
605 mov %rbx,(RBX*8+offes_intregs)(sp)
606 mov %rcx,(RCX*8+offes_intregs)(sp)
607 mov %rdx,(RDX*8+offes_intregs)(sp)
608 mov %rsi,(RSI*8+offes_intregs)(sp)
609 mov %rdi,(RDI*8+offes_intregs)(sp)
610 mov %rbp,(RBP*8+offes_intregs)(sp)
611 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
612 mov %r8 ,(R8 *8+offes_intregs)(sp)
613 mov %r9 ,(R9 *8+offes_intregs)(sp)
614 mov %r10,(R10*8+offes_intregs)(sp)
615 mov %r11,(R11*8+offes_intregs)(sp)
616 mov %r12,(R12*8+offes_intregs)(sp)
617 mov %r13,(R13*8+offes_intregs)(sp)
618 mov %r14,(R14*8+offes_intregs)(sp)
619 mov %r15,(R15*8+offes_intregs)(sp)
621 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
622 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
623 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
624 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
625 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
626 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
627 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
628 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
629 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
630 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
631 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
632 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
633 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
634 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
635 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
636 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
638 /* calculate sp of method */
640 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
641 mov itmp1,(offes_sp)(sp)
643 /* pv must be looked up via AVL tree */
644 movq $0,(offes_pv)(sp)
646 /* call replace_me */
647 mov -8(itmp1),a0 /* rplpoint * */
648 mov sp,a1 /* arg1: execution state */
649 call replace_me@PLT /* call C function replace_me */
650 call abort@PLT /* NEVER REACHED */
652 /* asm_replacement_in **********************************************************
654 This code writes the given execution state and jumps to the replacement
657 This function never returns!
660 void asm_replacement_in(executionstate *es);
662 *******************************************************************************/
665 mov a0,%rbp /* executionstate *es */
668 mov (offes_sp)(%rbp),%rsp
670 /* store address of new code */
671 push (offes_pc)(%rbp)
673 /* copy registers from execution state */
674 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
675 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
676 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
677 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
678 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
679 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
680 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
681 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
682 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
683 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
684 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
685 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
686 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
687 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
688 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
689 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
691 mov (RAX*8+offes_intregs)(%rbp),%rax
692 mov (RBX*8+offes_intregs)(%rbp),%rbx
693 mov (RCX*8+offes_intregs)(%rbp),%rcx
694 mov (RDX*8+offes_intregs)(%rbp),%rdx
695 mov (RSI*8+offes_intregs)(%rbp),%rsi
696 mov (RDI*8+offes_intregs)(%rbp),%rdi
697 mov (R8 *8+offes_intregs)(%rbp),%r8
698 mov (R9 *8+offes_intregs)(%rbp),%r9
699 mov (R10*8+offes_intregs)(%rbp),%r10
700 mov (R11*8+offes_intregs)(%rbp),%r11
701 mov (R12*8+offes_intregs)(%rbp),%r12
702 mov (R13*8+offes_intregs)(%rbp),%r13
703 mov (R14*8+offes_intregs)(%rbp),%r14
704 mov (R15*8+offes_intregs)(%rbp),%r15
706 mov (RBP*8+offes_intregs)(%rbp),%rbp
708 /* jump to new code */
711 /* asm_builtin_x2x *************************************************************
713 * Wrapper functions for float to int corner cases *
715 *******************************************************************************/
720 SAVE_ARGUMENT_REGISTERS(0)
725 RESTORE_ARGUMENT_REGISTERS(0)
734 SAVE_ARGUMENT_REGISTERS(0)
739 RESTORE_ARGUMENT_REGISTERS(0)
748 SAVE_ARGUMENT_REGISTERS(0)
753 RESTORE_ARGUMENT_REGISTERS(0)
762 SAVE_ARGUMENT_REGISTERS(0)
767 RESTORE_ARGUMENT_REGISTERS(0)
773 /******************* function asm_initialize_thread_stack **********************
775 * initialized a thread stack *
776 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
778 *******************************************************************************/
780 asm_initialize_thread_stack:
791 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
792 mov %rsi,%rax /* return restorepoint in %rax */
796 /******************* function asm_perform_threadswitch *************************
798 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
800 * performs a threadswitch *
802 *******************************************************************************/
804 asm_perform_threadswitch:
805 sub $(7*8),%rsp /* allocate stack frame */
814 mov 7*8(%rsp),%rax /* save current return address */
817 mov %rsp,(%rdi) /* first argument **from */
818 mov %rsp,(%rdx) /* third argument **stackTop */
820 mov (%rsi),%rsp /* load new stack pointer */
829 mov 6*8(%rsp),%rax /* restore return address */
830 add $(7*8),%rsp /* free stack frame */
835 /********************* function asm_switchstackandcall *************************
837 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
840 * Switches to a new stack, calls a function and switches back. *
841 * a0 (%rdi) new stack pointer *
842 * a1 (%rsi) function pointer *
843 * a2 (%rdx) pointer to variable where stack top should be stored *
844 * a3 (%rcx) pointer to user data, is passed to the function *
846 *******************************************************************************/
848 asm_switchstackandcall:
849 sub $(1*8),%rsp /* keep stack 16-byte aligned */
850 sub $16,%rdi /* allocate new stack */
852 mov 8(%rsp),%rax /* save return address on new stack */
854 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
855 mov %rsp,(%rdx) /* save old stack pointer to variable */
857 mov %rdi,%rsp /* switch to new stack */
859 mov %rcx,%rdi /* pass pointer */
860 call *%rsi /* and call function */
862 mov (%rsp),%r10 /* load return address */
863 mov 8(%rsp),%rsp /* switch to old stack */
864 add $(1*8),%rsp /* free stack space */
865 mov %r10,(%rsp) /* write return adress */
869 asm_getclassvalues_atomic:
872 movl offbaseval(a0),itmp1l
873 movl offdiffval(a0),itmp2l
874 movl offbaseval(a1),itmp3l
876 movl itmp1l,offcast_super_baseval(a2)
877 movl itmp2l,offcast_super_diffval(a2)
878 movl itmp3l,offcast_sub_baseval(a2)
883 asm_criticalsections:
884 #if defined(ENABLE_THREADS)
892 /* Disable exec-stacks, required for Gentoo ***********************************/
894 #if defined(__GCC__) && defined(__ELF__)
895 .section .note.GNU-stack,"",@progbits
900 * These are local overrides for various environment variables in Emacs.
901 * Please do not remove this and leave it at the end of the file, where
902 * Emacs will automagically detect them.
903 * ---------------------------------------------------------------------
906 * indent-tabs-mode: t
910 * vim:noexpandtab:sw=4:ts=4: