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 4735 2006-04-05 10:02:14Z 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),itmp3
206 call *itmp3 /* call JIT compiler */
208 add bp,sp /* remove argument stack frame if any */
210 L_asm_vm_call_method_return:
211 mov 0*8(sp),%rbx /* restore callee saved registers */
217 add $(7*8),sp /* free stack space */
220 asm_vm_call_method_exception_handler:
221 mov xptr,a0 /* pass exception pointer */
222 call builtin_throw_exception@PLT
223 xor v0,v0 /* return NULL */
224 jmp L_asm_vm_call_method_return
236 mov offvmargdata(itmp2),a0
239 mov offvmargdata(itmp2),a1
242 mov offvmargdata(itmp2),a2
245 mov offvmargdata(itmp2),a3
248 mov offvmargdata(itmp2),a4
251 mov offvmargdata(itmp2),a5
266 movq offvmargdata(itmp2),fa0
269 movq offvmargdata(itmp2),fa1
272 movq offvmargdata(itmp2),fa2
275 movq offvmargdata(itmp2),fa3
278 movq offvmargdata(itmp2),fa4
281 movq offvmargdata(itmp2),fa5
284 movq offvmargdata(itmp2),fa6
287 movq offvmargdata(itmp2),fa7
291 /****************** function asm_call_jit_compiler *****************************
293 * invokes the compiler for untranslated JavaVM methods. *
295 * Register R0 contains a pointer to the method info structure (prepared *
296 * by createcompilerstub). Using the return address in R26 and the *
297 * offset in the LDA instruction or using the value in methodptr R28 the *
298 * patching address for storing the method address can be computed: *
300 * method address was either loaded using *
302 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
303 * i386_call_reg(REG_ITMP2) *
307 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
308 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
309 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
310 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
311 * i386_call_reg(REG_ITMP1) *
313 * in the static case the method pointer can be computed using the *
314 * return address and the lda function following the jmp instruction *
316 *******************************************************************************/
318 asm_call_jit_compiler:
319 L_asm_call_jit_compiler: /* required for PIC code */
320 /* keep stack 16-byte aligned */
321 sub $((3+ARG_CNT)*8+sizestackframeinfo),sp
323 mov t0,0*8(sp) /* save register */
325 mov (3+ARG_CNT)*8+sizestackframeinfo(sp),itmp3 /* get return address */
326 mov -1(itmp3),%bl /* get function code */
327 cmp $0xd2,%bl /* called with `call *REG_ITMP2'? */
328 jne L_not_static_special
330 sub $11,itmp3 /* calculate address of immediate */
331 jmp L_call_jit_compile
333 L_not_static_special:
334 cmp $0xd0,%bl /* called with `call *REG_ITMP1' */
335 jne L_not_virtual_interface
337 sub $7,itmp3 /* calculate address of offset */
338 mov (itmp3),itmp3l /* get offset (32-bit) */
339 add itmp2,itmp3 /* add base address to get method addr*/
340 jmp L_call_jit_compile
342 L_not_virtual_interface: /* a call from asm_calljavamethod */
346 mov 0*8(sp),t0 /* restore register */
347 mov itmp3,0*8(sp) /* save address for method pointer */
348 mov itmp1,1*8(sp) /* save method pointer */
350 SAVE_ARGUMENT_REGISTERS(3)
352 mov sp,a0 /* create stackframe info */
353 add $((3+ARG_CNT)*8),a0 /* pass sfi */
354 xor a1,a1 /* if pv is NULL, use findmethod */
355 mov sp,a2 /* pass java sp */
356 add $((1+3+ARG_CNT)*8+sizestackframeinfo),a2
357 /* pass ra to java function */
358 mov ((3+ARG_CNT)*8+sizestackframeinfo)(sp),a3
359 mov a3,a4 /* xpc is equal to ra */
360 call stacktrace_create_extern_stackframeinfo@PLT
362 mov 1*8(sp),a0 /* pass method pointer */
364 mov v0,1*8(sp) /* save return value */
366 mov sp,a0 /* remove stackframe info */
367 add $((3+ARG_CNT)*8),a0 /* pass sfi */
368 call stacktrace_remove_stackframeinfo@PLT
370 mov 0*8(sp),itmp3 /* restore address for method pointer */
371 mov 1*8(sp),v0 /* restore return value */
373 RESTORE_ARGUMENT_REGISTERS(3)
375 add $((3+ARG_CNT)*8+sizestackframeinfo),sp /* remove stack frame */
377 test v0,v0 /* check for exception */
378 je L_asm_call_jit_compiler_exception
380 test itmp3,itmp3 /* is address == 0 (asm_calljavamethod*/
383 mov v0,(itmp3) /* and now save the new pointer */
386 jmp *v0 /* ...and now call the new method */
388 L_asm_call_jit_compiler_exception:
389 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
390 call builtin_asm_get_exceptionptrptr@PLT
391 mov v0,itmp2 /* v0 == xptr */
393 lea _no_threads_exceptionptr(%rip),itmp2
395 mov (itmp2),xptr /* get the exception pointer */
396 movl $0,(itmp2) /* clear exception pointer */
398 pop xpc /* delete return address */
399 sub $5,xpc /* faulting address is ra - 5 */
400 jmp L_asm_handle_exception
403 /* asm_handle_exception ********************************************************
405 * This function handles an exception. It does not use the usual calling *
406 * conventions. The exception pointer is passed in REG_ITMP1 and the *
407 * pc from the exception raising position is passed in REG_ITMP2. It searches *
408 * the local exception table for a handler. If no one is found, it unwinds *
409 * stacks and continues searching the callers. *
411 *******************************************************************************/
413 asm_handle_nat_exception:
414 add $8,sp /* clear return address of native stub*/
416 asm_handle_exception:
417 L_asm_handle_exception: /* required for PIC code */
418 sub $((ARG_CNT+TMP_CNT)*8),sp /* create maybe-leaf stackframe */
420 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
421 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
423 mov $((ARG_CNT+TMP_CNT)*8),a3 /* prepare a3 for handle_exception */
424 mov $1,t0 /* set maybe-leaf flag */
426 L_asm_handle_exception_stack_loop:
428 mov xptr,0*8(sp) /* save exception pointer */
429 mov xpc,1*8(sp) /* save exception pc */
430 add sp,a3 /* calculate Java sp into a3... */
432 mov a3,3*8(sp) /* ...and save it */
433 mov t0,4*8(sp) /* save maybe-leaf flag */
435 mov xpc,a0 /* exception pc */
436 call codegen_findmethod@PLT
437 mov v0,2*8(sp) /* save data segment pointer */
439 mov 0*8(sp),a0 /* pass exception pointer */
440 mov 1*8(sp),a1 /* pass exception pc */
441 mov v0,a2 /* pass data segment pointer */
442 mov 3*8(sp),a3 /* pass Java stack pointer */
443 call exceptions_handle_exception@PLT
446 jz L_asm_handle_exception_not_catched
448 mov v0,xpc /* move handlerpc into xpc */
449 mov 0*8(sp),xptr /* restore exception pointer */
450 mov 4*8(sp),t0 /* get maybe-leaf flag */
451 add $(6*8),sp /* free stack frame */
453 test t0,t0 /* test for maybe-leaf flag */
454 jz L_asm_handle_exception_no_leaf
456 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
457 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
459 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
461 L_asm_handle_exception_no_leaf:
462 jmp *xpc /* jump to the handler */
464 L_asm_handle_exception_not_catched:
465 mov 0*8(sp),xptr /* restore exception pointer */
466 mov 2*8(sp),itmp3 /* restore data segment pointer */
467 mov 4*8(sp),t0 /* get maybe-leaf flag */
471 jz L_asm_handle_exception_no_leaf_stack
473 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
474 xor t0,t0 /* clear the isleaf flags */
476 L_asm_handle_exception_no_leaf_stack:
477 mov FrameSize(itmp3),itmp2l /* get frame size */
478 add sp,itmp2 /* pointer to save area */
480 mov IntSave(itmp3),a0l /* a0l = saved int register count */
503 shl $3,a0l /* multiply by 8 bytes */
508 mov FltSave(itmp3),a0l /* a0l = saved flt register count */
521 movq -5*8(itmp2),%xmm11
523 movq -4*8(itmp2),%xmm12
525 movq -3*8(itmp2),%xmm13
527 movq -2*8(itmp2),%xmm14
529 movq -1*8(itmp2),%xmm15
533 mov FrameSize(itmp3),itmp2l /* get frame size */
534 add itmp2,sp /* unwind stack */
536 /* exception pointer is still set */
537 pop xpc /* the new xpc is return address */
538 sub $3,xpc /* subtract 3 bytes for call */
540 xor a3,a3 /* prepare a3 for handle_exception */
542 jmp L_asm_handle_exception_stack_loop
545 /* asm_wrapper_patcher *********************************************************
551 32 pointer to virtual java_objectheader
552 24 machine code (which is patched back later)
553 16 unresolved class/method/field reference
554 8 data segment displacement from load instructions
555 0 pointer to patcher function
558 *******************************************************************************/
561 push bp /* save base pointer */
562 mov sp,bp /* move actual sp to bp */
563 sub $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),sp
564 and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
565 /* leaf functions) */
567 SAVE_ARGUMENT_REGISTERS(3)
568 SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
570 mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
571 mov itmp2,1*8(sp) /* can be used by some instructions */
573 mov sp,a0 /* create stackframe info */
574 add $((3+ARG_CNT+TMP_CNT)*8),a0
575 xor a1,a1 /* if pv is NULL, use findmethod */
576 mov bp,a2 /* pass java sp */
578 mov ((5+1)*8)(bp),a3 /* pass ra to java function */
579 mov a3,a4 /* xpc is equal to ra */
580 call stacktrace_create_extern_stackframeinfo@PLT
582 mov bp,a0 /* pass stack pointer */
583 add $((1+1)*8),a0 /* skip function pointer */
584 mov 1*8(bp),itmp3 /* get function pointer */
585 call *itmp3 /* call the patcher function */
586 mov v0,2*8(sp) /* save return value */
588 mov sp,a0 /* remove stackframe info */
589 add $((3+ARG_CNT+TMP_CNT)*8),a0
590 call stacktrace_remove_stackframeinfo@PLT
592 RESTORE_ARGUMENT_REGISTERS(3)
593 RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
595 mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
596 mov 1*8(sp),itmp2 /* can be used by some instructions */
597 mov 2*8(sp),itmp3 /* restore return value */
599 mov bp,sp /* restore original sp */
600 pop bp /* restore bp */
601 add $(5*8),sp /* remove patcher stackframe, keep ra */
603 test itmp3,itmp3 /* exception thrown? */
604 jz L_asm_wrapper_patcher_exception
605 ret /* call new patched code */
607 L_asm_wrapper_patcher_exception:
608 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
609 call builtin_asm_get_exceptionptrptr@PLT
610 mov v0,itmp2 /* v0 == xptr */
612 mov _no_threads_exceptionptr,itmp2
614 mov (itmp2),xptr /* get the exception pointer */
615 movl $0,(itmp2) /* clear exception pointer */
617 pop xpc /* get and remove return address */
618 jmp L_asm_handle_exception
621 /* asm_replacement_out *********************************************************
623 This code is jumped to from the replacement-out stubs that are executed
624 when a thread reaches an activated replacement point.
626 The purpose of asm_replacement_out is to read out the parts of the
627 execution state that cannot be accessed from C code, store this state,
628 and then call the C function replace_me.
631 8 start of stack inside method to replace
632 0 rplpoint * info on the replacement point that was reached
634 *******************************************************************************/
636 /* some room to accomodate changes of the stack frame size during replacement */
637 /* XXX we should find a cleaner solution here */
638 #define REPLACEMENT_ROOM 512
641 /* create stack frame */
642 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
644 /* save registers in execution state */
645 mov %rax,(RAX*8+offes_intregs)(sp)
646 mov %rbx,(RBX*8+offes_intregs)(sp)
647 mov %rcx,(RCX*8+offes_intregs)(sp)
648 mov %rdx,(RDX*8+offes_intregs)(sp)
649 mov %rsi,(RSI*8+offes_intregs)(sp)
650 mov %rdi,(RDI*8+offes_intregs)(sp)
651 mov %rbp,(RBP*8+offes_intregs)(sp)
652 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
653 mov %r8 ,(R8 *8+offes_intregs)(sp)
654 mov %r9 ,(R9 *8+offes_intregs)(sp)
655 mov %r10,(R10*8+offes_intregs)(sp)
656 mov %r11,(R11*8+offes_intregs)(sp)
657 mov %r12,(R12*8+offes_intregs)(sp)
658 mov %r13,(R13*8+offes_intregs)(sp)
659 mov %r14,(R14*8+offes_intregs)(sp)
660 mov %r15,(R15*8+offes_intregs)(sp)
662 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
663 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
664 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
665 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
666 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
667 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
668 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
669 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
670 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
671 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
672 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
673 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
674 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
675 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
676 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
677 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
679 /* calculate sp of method */
681 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
682 mov itmp1,(offes_sp)(sp)
684 /* pv must be looked up via AVL tree */
685 movq $0,(offes_pv)(sp)
687 /* call replace_me */
688 mov -8(itmp1),a0 /* rplpoint * */
689 mov sp,a1 /* arg1: execution state */
690 call replace_me@PLT /* call C function replace_me */
691 call abort@PLT /* NEVER REACHED */
693 /* asm_replacement_in **********************************************************
695 This code writes the given execution state and jumps to the replacement
698 This function never returns!
701 void asm_replacement_in(executionstate *es);
703 *******************************************************************************/
706 mov a0,%rbp /* executionstate *es */
709 mov (offes_sp)(%rbp),%rsp
711 /* store address of new code */
712 push (offes_pc)(%rbp)
714 /* copy registers from execution state */
715 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
716 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
717 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
718 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
719 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
720 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
721 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
722 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
723 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
724 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
725 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
726 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
727 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
728 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
729 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
730 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
732 mov (RAX*8+offes_intregs)(%rbp),%rax
733 mov (RBX*8+offes_intregs)(%rbp),%rbx
734 mov (RCX*8+offes_intregs)(%rbp),%rcx
735 mov (RDX*8+offes_intregs)(%rbp),%rdx
736 mov (RSI*8+offes_intregs)(%rbp),%rsi
737 mov (RDI*8+offes_intregs)(%rbp),%rdi
738 mov (R8 *8+offes_intregs)(%rbp),%r8
739 mov (R9 *8+offes_intregs)(%rbp),%r9
740 mov (R10*8+offes_intregs)(%rbp),%r10
741 mov (R11*8+offes_intregs)(%rbp),%r11
742 mov (R12*8+offes_intregs)(%rbp),%r12
743 mov (R13*8+offes_intregs)(%rbp),%r13
744 mov (R14*8+offes_intregs)(%rbp),%r14
745 mov (R15*8+offes_intregs)(%rbp),%r15
747 mov (RBP*8+offes_intregs)(%rbp),%rbp
749 /* jump to new code */
752 /* asm_builtin_x2x *************************************************************
754 * Wrapper functions for float to int corner cases *
756 *******************************************************************************/
761 SAVE_ARGUMENT_REGISTERS(0)
766 RESTORE_ARGUMENT_REGISTERS(0)
775 SAVE_ARGUMENT_REGISTERS(0)
780 RESTORE_ARGUMENT_REGISTERS(0)
789 SAVE_ARGUMENT_REGISTERS(0)
794 RESTORE_ARGUMENT_REGISTERS(0)
803 SAVE_ARGUMENT_REGISTERS(0)
808 RESTORE_ARGUMENT_REGISTERS(0)
814 /******************* function asm_initialize_thread_stack **********************
816 * initialized a thread stack *
817 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
819 *******************************************************************************/
821 asm_initialize_thread_stack:
832 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
833 mov %rsi,%rax /* return restorepoint in %rax */
837 /******************* function asm_perform_threadswitch *************************
839 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
841 * performs a threadswitch *
843 *******************************************************************************/
845 asm_perform_threadswitch:
846 sub $(7*8),%rsp /* allocate stack frame */
855 mov 7*8(%rsp),%rax /* save current return address */
858 mov %rsp,(%rdi) /* first argument **from */
859 mov %rsp,(%rdx) /* third argument **stackTop */
861 mov (%rsi),%rsp /* load new stack pointer */
870 mov 6*8(%rsp),%rax /* restore return address */
871 add $(7*8),%rsp /* free stack frame */
876 /********************* function asm_switchstackandcall *************************
878 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
881 * Switches to a new stack, calls a function and switches back. *
882 * a0 (%rdi) new stack pointer *
883 * a1 (%rsi) function pointer *
884 * a2 (%rdx) pointer to variable where stack top should be stored *
885 * a3 (%rcx) pointer to user data, is passed to the function *
887 *******************************************************************************/
889 asm_switchstackandcall:
890 sub $(1*8),%rsp /* keep stack 16-byte aligned */
891 sub $16,%rdi /* allocate new stack */
893 mov 8(%rsp),%rax /* save return address on new stack */
895 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
896 mov %rsp,(%rdx) /* save old stack pointer to variable */
898 mov %rdi,%rsp /* switch to new stack */
900 mov %rcx,%rdi /* pass pointer */
901 call *%rsi /* and call function */
903 mov (%rsp),%r10 /* load return address */
904 mov 8(%rsp),%rsp /* switch to old stack */
905 add $(1*8),%rsp /* free stack space */
906 mov %r10,(%rsp) /* write return adress */
910 asm_getclassvalues_atomic:
913 movl offbaseval(a0),itmp1l
914 movl offdiffval(a0),itmp2l
915 movl offbaseval(a1),itmp3l
917 movl itmp1l,offcast_super_baseval(a2)
918 movl itmp2l,offcast_super_diffval(a2)
919 movl itmp3l,offcast_sub_baseval(a2)
924 asm_criticalsections:
925 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
933 /* Disable exec-stacks, required for Gentoo ***********************************/
935 #if defined(__GCC__) && defined(__ELF__)
936 .section .note.GNU-stack,"",@progbits
941 * These are local overrides for various environment variables in Emacs.
942 * Please do not remove this and leave it at the end of the file, where
943 * Emacs will automagically detect them.
944 * ---------------------------------------------------------------------
947 * indent-tabs-mode: t
951 * vim:noexpandtab:sw=4:ts=4: