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 4749 2006-04-11 10:20:18Z 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 jmp L_asm_vm_call_method_return
235 mov offvmargdata(itmp2),a0
238 mov offvmargdata(itmp2),a1
241 mov offvmargdata(itmp2),a2
244 mov offvmargdata(itmp2),a3
247 mov offvmargdata(itmp2),a4
250 mov offvmargdata(itmp2),a5
265 movq offvmargdata(itmp2),fa0
268 movq offvmargdata(itmp2),fa1
271 movq offvmargdata(itmp2),fa2
274 movq offvmargdata(itmp2),fa3
277 movq offvmargdata(itmp2),fa4
280 movq offvmargdata(itmp2),fa5
283 movq offvmargdata(itmp2),fa6
286 movq offvmargdata(itmp2),fa7
290 /****************** function asm_call_jit_compiler *****************************
292 * invokes the compiler for untranslated JavaVM methods. *
294 * Register R0 contains a pointer to the method info structure (prepared *
295 * by createcompilerstub). Using the return address in R26 and the *
296 * offset in the LDA instruction or using the value in methodptr R28 the *
297 * patching address for storing the method address can be computed: *
299 * method address was either loaded using *
301 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
302 * i386_call_reg(REG_ITMP2) *
306 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
307 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
308 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
309 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
310 * i386_call_reg(REG_ITMP1) *
312 * in the static case the method pointer can be computed using the *
313 * return address and the lda function following the jmp instruction *
315 *******************************************************************************/
317 asm_call_jit_compiler:
318 L_asm_call_jit_compiler: /* required for PIC code */
319 /* keep stack 16-byte aligned */
320 sub $((3+ARG_CNT)*8+sizestackframeinfo),sp
322 mov t0,0*8(sp) /* save register */
324 mov (3+ARG_CNT)*8+sizestackframeinfo(sp),itmp3 /* get return address */
325 mov -1(itmp3),%bl /* get function code */
326 cmp $0xd2,%bl /* called with `call *REG_ITMP2'? */
327 jne L_not_static_special
329 sub $11,itmp3 /* calculate address of immediate */
330 jmp L_call_jit_compile
332 L_not_static_special:
333 cmp $0xd0,%bl /* called with `call *REG_ITMP1' */
334 jne L_not_virtual_interface
336 sub $7,itmp3 /* calculate address of offset */
337 mov (itmp3),itmp3l /* get offset (32-bit) */
338 add itmp2,itmp3 /* add base address to get method addr*/
339 jmp L_call_jit_compile
341 L_not_virtual_interface: /* a call from asm_calljavamethod */
345 mov 0*8(sp),t0 /* restore register */
346 mov itmp3,0*8(sp) /* save address for method pointer */
347 mov itmp1,1*8(sp) /* save method pointer */
349 SAVE_ARGUMENT_REGISTERS(3)
351 mov sp,a0 /* create stackframe info */
352 add $((3+ARG_CNT)*8),a0 /* pass sfi */
353 xor a1,a1 /* if pv is NULL, use findmethod */
354 mov sp,a2 /* pass java sp */
355 add $((1+3+ARG_CNT)*8+sizestackframeinfo),a2
356 /* pass ra to java function */
357 mov ((3+ARG_CNT)*8+sizestackframeinfo)(sp),a3
358 mov a3,a4 /* xpc is equal to ra */
359 call stacktrace_create_extern_stackframeinfo@PLT
361 mov 1*8(sp),a0 /* pass method pointer */
363 mov v0,1*8(sp) /* save return value */
365 mov sp,a0 /* remove stackframe info */
366 add $((3+ARG_CNT)*8),a0 /* pass sfi */
367 call stacktrace_remove_stackframeinfo@PLT
369 mov 0*8(sp),itmp3 /* restore address for method pointer */
370 mov 1*8(sp),v0 /* restore return value */
372 RESTORE_ARGUMENT_REGISTERS(3)
374 add $((3+ARG_CNT)*8+sizestackframeinfo),sp /* remove stack frame */
376 test v0,v0 /* check for exception */
377 je L_asm_call_jit_compiler_exception
379 test itmp3,itmp3 /* is address == 0 (asm_calljavamethod*/
382 mov v0,(itmp3) /* and now save the new pointer */
385 jmp *v0 /* ...and now call the new method */
387 L_asm_call_jit_compiler_exception:
388 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
389 call builtin_asm_get_exceptionptrptr@PLT
390 mov v0,itmp2 /* v0 == xptr */
392 lea _no_threads_exceptionptr(%rip),itmp2
394 mov (itmp2),xptr /* get the exception pointer */
395 movl $0,(itmp2) /* clear exception pointer */
397 pop xpc /* delete return address */
398 sub $5,xpc /* faulting address is ra - 5 */
399 jmp L_asm_handle_exception
402 /* asm_handle_exception ********************************************************
404 * This function handles an exception. It does not use the usual calling *
405 * conventions. The exception pointer is passed in REG_ITMP1 and the *
406 * pc from the exception raising position is passed in REG_ITMP2. It searches *
407 * the local exception table for a handler. If no one is found, it unwinds *
408 * stacks and continues searching the callers. *
410 *******************************************************************************/
412 asm_handle_nat_exception:
413 add $8,sp /* clear return address of native stub*/
415 asm_handle_exception:
416 L_asm_handle_exception: /* required for PIC code */
417 sub $((ARG_CNT+TMP_CNT)*8),sp /* create maybe-leaf stackframe */
419 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
420 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
422 mov $((ARG_CNT+TMP_CNT)*8),a3 /* prepare a3 for handle_exception */
423 mov $1,t0 /* set maybe-leaf flag */
425 L_asm_handle_exception_stack_loop:
427 mov xptr,0*8(sp) /* save exception pointer */
428 mov xpc,1*8(sp) /* save exception pc */
429 add sp,a3 /* calculate Java sp into a3... */
431 mov a3,3*8(sp) /* ...and save it */
432 mov t0,4*8(sp) /* save maybe-leaf flag */
434 mov xpc,a0 /* exception pc */
435 call codegen_findmethod@PLT
436 mov v0,2*8(sp) /* save data segment pointer */
438 mov 0*8(sp),a0 /* pass exception pointer */
439 mov 1*8(sp),a1 /* pass exception pc */
440 mov v0,a2 /* pass data segment pointer */
441 mov 3*8(sp),a3 /* pass Java stack pointer */
442 call exceptions_handle_exception@PLT
445 jz L_asm_handle_exception_not_catched
447 mov v0,xpc /* move handlerpc into xpc */
448 mov 0*8(sp),xptr /* restore exception pointer */
449 mov 4*8(sp),t0 /* get maybe-leaf flag */
450 add $(6*8),sp /* free stack frame */
452 test t0,t0 /* test for maybe-leaf flag */
453 jz L_asm_handle_exception_no_leaf
455 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
456 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
458 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
460 L_asm_handle_exception_no_leaf:
461 jmp *xpc /* jump to the handler */
463 L_asm_handle_exception_not_catched:
464 mov 0*8(sp),xptr /* restore exception pointer */
465 mov 2*8(sp),itmp3 /* restore data segment pointer */
466 mov 4*8(sp),t0 /* get maybe-leaf flag */
470 jz L_asm_handle_exception_no_leaf_stack
472 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
473 xor t0,t0 /* clear the isleaf flags */
475 L_asm_handle_exception_no_leaf_stack:
476 mov FrameSize(itmp3),itmp2l /* get frame size */
477 add sp,itmp2 /* pointer to save area */
479 mov IntSave(itmp3),a0l /* a0l = saved int register count */
502 shl $3,a0l /* multiply by 8 bytes */
507 mov FltSave(itmp3),a0l /* a0l = saved flt register count */
520 movq -5*8(itmp2),%xmm11
522 movq -4*8(itmp2),%xmm12
524 movq -3*8(itmp2),%xmm13
526 movq -2*8(itmp2),%xmm14
528 movq -1*8(itmp2),%xmm15
532 mov FrameSize(itmp3),itmp2l /* get frame size */
533 add itmp2,sp /* unwind stack */
535 /* exception pointer is still set */
536 pop xpc /* the new xpc is return address */
537 sub $3,xpc /* subtract 3 bytes for call */
539 xor a3,a3 /* prepare a3 for handle_exception */
541 jmp L_asm_handle_exception_stack_loop
544 /* asm_wrapper_patcher *********************************************************
550 32 pointer to virtual java_objectheader
551 24 machine code (which is patched back later)
552 16 unresolved class/method/field reference
553 8 data segment displacement from load instructions
554 0 pointer to patcher function
557 *******************************************************************************/
560 push bp /* save base pointer */
561 mov sp,bp /* move actual sp to bp */
562 sub $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),sp
563 and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
564 /* leaf functions) */
566 SAVE_ARGUMENT_REGISTERS(3)
567 SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
569 mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
570 mov itmp2,1*8(sp) /* can be used by some instructions */
572 mov sp,a0 /* create stackframe info */
573 add $((3+ARG_CNT+TMP_CNT)*8),a0
574 xor a1,a1 /* if pv is NULL, use findmethod */
575 mov bp,a2 /* pass java sp */
577 mov ((5+1)*8)(bp),a3 /* pass ra to java function */
578 mov a3,a4 /* xpc is equal to ra */
579 call stacktrace_create_extern_stackframeinfo@PLT
581 mov bp,a0 /* pass stack pointer */
582 add $((1+1)*8),a0 /* skip function pointer */
583 mov 1*8(bp),itmp3 /* get function pointer */
584 call *itmp3 /* call the patcher function */
585 mov v0,2*8(sp) /* save return value */
587 mov sp,a0 /* remove stackframe info */
588 add $((3+ARG_CNT+TMP_CNT)*8),a0
589 call stacktrace_remove_stackframeinfo@PLT
591 RESTORE_ARGUMENT_REGISTERS(3)
592 RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
594 mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
595 mov 1*8(sp),itmp2 /* can be used by some instructions */
596 mov 2*8(sp),itmp3 /* restore return value */
598 mov bp,sp /* restore original sp */
599 pop bp /* restore bp */
600 add $(5*8),sp /* remove patcher stackframe, keep ra */
602 test itmp3,itmp3 /* exception thrown? */
603 jz L_asm_wrapper_patcher_exception
604 ret /* call new patched code */
606 L_asm_wrapper_patcher_exception:
607 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
608 call builtin_asm_get_exceptionptrptr@PLT
609 mov v0,itmp2 /* v0 == xptr */
611 mov _no_threads_exceptionptr,itmp2
613 mov (itmp2),xptr /* get the exception pointer */
614 movl $0,(itmp2) /* clear exception pointer */
616 pop xpc /* get and remove return address */
617 jmp L_asm_handle_exception
620 /* asm_replacement_out *********************************************************
622 This code is jumped to from the replacement-out stubs that are executed
623 when a thread reaches an activated replacement point.
625 The purpose of asm_replacement_out is to read out the parts of the
626 execution state that cannot be accessed from C code, store this state,
627 and then call the C function replace_me.
630 8 start of stack inside method to replace
631 0 rplpoint * info on the replacement point that was reached
633 *******************************************************************************/
635 /* some room to accomodate changes of the stack frame size during replacement */
636 /* XXX we should find a cleaner solution here */
637 #define REPLACEMENT_ROOM 512
640 /* create stack frame */
641 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
643 /* save registers in execution state */
644 mov %rax,(RAX*8+offes_intregs)(sp)
645 mov %rbx,(RBX*8+offes_intregs)(sp)
646 mov %rcx,(RCX*8+offes_intregs)(sp)
647 mov %rdx,(RDX*8+offes_intregs)(sp)
648 mov %rsi,(RSI*8+offes_intregs)(sp)
649 mov %rdi,(RDI*8+offes_intregs)(sp)
650 mov %rbp,(RBP*8+offes_intregs)(sp)
651 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
652 mov %r8 ,(R8 *8+offes_intregs)(sp)
653 mov %r9 ,(R9 *8+offes_intregs)(sp)
654 mov %r10,(R10*8+offes_intregs)(sp)
655 mov %r11,(R11*8+offes_intregs)(sp)
656 mov %r12,(R12*8+offes_intregs)(sp)
657 mov %r13,(R13*8+offes_intregs)(sp)
658 mov %r14,(R14*8+offes_intregs)(sp)
659 mov %r15,(R15*8+offes_intregs)(sp)
661 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
662 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
663 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
664 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
665 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
666 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
667 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
668 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
669 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
670 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
671 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
672 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
673 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
674 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
675 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
676 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
678 /* calculate sp of method */
680 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
681 mov itmp1,(offes_sp)(sp)
683 /* pv must be looked up via AVL tree */
684 movq $0,(offes_pv)(sp)
686 /* call replace_me */
687 mov -8(itmp1),a0 /* rplpoint * */
688 mov sp,a1 /* arg1: execution state */
689 call replace_me@PLT /* call C function replace_me */
690 call abort@PLT /* NEVER REACHED */
692 /* asm_replacement_in **********************************************************
694 This code writes the given execution state and jumps to the replacement
697 This function never returns!
700 void asm_replacement_in(executionstate *es);
702 *******************************************************************************/
705 mov a0,%rbp /* executionstate *es */
708 mov (offes_sp)(%rbp),%rsp
710 /* store address of new code */
711 push (offes_pc)(%rbp)
713 /* copy registers from execution state */
714 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
715 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
716 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
717 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
718 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
719 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
720 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
721 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
722 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
723 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
724 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
725 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
726 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
727 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
728 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
729 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
731 mov (RAX*8+offes_intregs)(%rbp),%rax
732 mov (RBX*8+offes_intregs)(%rbp),%rbx
733 mov (RCX*8+offes_intregs)(%rbp),%rcx
734 mov (RDX*8+offes_intregs)(%rbp),%rdx
735 mov (RSI*8+offes_intregs)(%rbp),%rsi
736 mov (RDI*8+offes_intregs)(%rbp),%rdi
737 mov (R8 *8+offes_intregs)(%rbp),%r8
738 mov (R9 *8+offes_intregs)(%rbp),%r9
739 mov (R10*8+offes_intregs)(%rbp),%r10
740 mov (R11*8+offes_intregs)(%rbp),%r11
741 mov (R12*8+offes_intregs)(%rbp),%r12
742 mov (R13*8+offes_intregs)(%rbp),%r13
743 mov (R14*8+offes_intregs)(%rbp),%r14
744 mov (R15*8+offes_intregs)(%rbp),%r15
746 mov (RBP*8+offes_intregs)(%rbp),%rbp
748 /* jump to new code */
751 /* asm_builtin_x2x *************************************************************
753 * Wrapper functions for float to int corner cases *
755 *******************************************************************************/
760 SAVE_ARGUMENT_REGISTERS(0)
765 RESTORE_ARGUMENT_REGISTERS(0)
774 SAVE_ARGUMENT_REGISTERS(0)
779 RESTORE_ARGUMENT_REGISTERS(0)
788 SAVE_ARGUMENT_REGISTERS(0)
793 RESTORE_ARGUMENT_REGISTERS(0)
802 SAVE_ARGUMENT_REGISTERS(0)
807 RESTORE_ARGUMENT_REGISTERS(0)
813 /******************* function asm_initialize_thread_stack **********************
815 * initialized a thread stack *
816 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
818 *******************************************************************************/
820 asm_initialize_thread_stack:
831 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
832 mov %rsi,%rax /* return restorepoint in %rax */
836 /******************* function asm_perform_threadswitch *************************
838 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
840 * performs a threadswitch *
842 *******************************************************************************/
844 asm_perform_threadswitch:
845 sub $(7*8),%rsp /* allocate stack frame */
854 mov 7*8(%rsp),%rax /* save current return address */
857 mov %rsp,(%rdi) /* first argument **from */
858 mov %rsp,(%rdx) /* third argument **stackTop */
860 mov (%rsi),%rsp /* load new stack pointer */
869 mov 6*8(%rsp),%rax /* restore return address */
870 add $(7*8),%rsp /* free stack frame */
875 /********************* function asm_switchstackandcall *************************
877 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
880 * Switches to a new stack, calls a function and switches back. *
881 * a0 (%rdi) new stack pointer *
882 * a1 (%rsi) function pointer *
883 * a2 (%rdx) pointer to variable where stack top should be stored *
884 * a3 (%rcx) pointer to user data, is passed to the function *
886 *******************************************************************************/
888 asm_switchstackandcall:
889 sub $(1*8),%rsp /* keep stack 16-byte aligned */
890 sub $16,%rdi /* allocate new stack */
892 mov 8(%rsp),%rax /* save return address on new stack */
894 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
895 mov %rsp,(%rdx) /* save old stack pointer to variable */
897 mov %rdi,%rsp /* switch to new stack */
899 mov %rcx,%rdi /* pass pointer */
900 call *%rsi /* and call function */
902 mov (%rsp),%r10 /* load return address */
903 mov 8(%rsp),%rsp /* switch to old stack */
904 add $(1*8),%rsp /* free stack space */
905 mov %r10,(%rsp) /* write return adress */
909 asm_getclassvalues_atomic:
912 movl offbaseval(a0),itmp1l
913 movl offdiffval(a0),itmp2l
914 movl offbaseval(a1),itmp3l
916 movl itmp1l,offcast_super_baseval(a2)
917 movl itmp2l,offcast_super_diffval(a2)
918 movl itmp3l,offcast_sub_baseval(a2)
923 asm_criticalsections:
924 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
932 /* Disable exec-stacks, required for Gentoo ***********************************/
934 #if defined(__GCC__) && defined(__ELF__)
935 .section .note.GNU-stack,"",@progbits
940 * These are local overrides for various environment variables in Emacs.
941 * Please do not remove this and leave it at the end of the file, where
942 * Emacs will automagically detect them.
943 * ---------------------------------------------------------------------
946 * indent-tabs-mode: t
950 * vim:noexpandtab:sw=4:ts=4: