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 4690 2006-03-27 11:37:46Z twisti $
43 #include "vm/jit/abi.h"
44 #include "vm/jit/x86_64/arch.h"
45 #include "vm/jit/x86_64/offsets.h"
47 #include "vm/jit/methodheader.h"
53 /* exported functions and variables *******************************************/
55 .globl asm_vm_call_method
56 .globl asm_vm_call_method_int
57 .globl asm_vm_call_method_long
58 .globl asm_vm_call_method_float
59 .globl asm_vm_call_method_double
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 calljava_xhandler2 /* handler pc */
100 .quad calljava_xhandler2 /* end pc */
101 .quad L_asm_vm_call_method /* 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 24 /* 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 L_asm_vm_call_method: /* required for PIC code */
120 sub $(7*8),sp /* keep stack 16-byte aligned */
121 mov %rbx,0*8(sp) /* %rbx is not a callee saved in cacao*/
128 mov a0,itmp1 /* move method pointer for compiler */
129 xor %rbp,%rbp /* set argument stack frame to zero */
131 test a1,a1 /* maybe we have no args... */
134 mov a1,itmp3 /* arg count */
135 mov a2,itmp2 /* pointer to arg block */
137 mov itmp2,%r14 /* save argument block pointer */
138 mov itmp3,%r15 /* save argument count */
140 sub $sizevmarg,itmp2 /* initialize pointer (smaller code) */
141 add $1,itmp3 /* initialize argument count */
142 xor %r12,%r12 /* initialize integer argument counter*/
143 xor %r13,%r13 /* initialize float argument counter */
146 add $sizevmarg,itmp2 /* goto next argument block */
147 dec itmp3 /* argument count - 1 */
148 jz L_register_copy_done
149 andb $0x02,offvmargtype(itmp2) /* is this a float/double type? */
150 jnz L_register_handle_float /* yes, handle it */
152 cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
153 je L_register_copy /* register? yes, next loop */
155 lea jumptable_integer(%rip),%rbp
156 mov 0(%rbp,%r12,8),%rbx
157 inc %r12 /* integer argument counter + 1 */
160 L_register_handle_float:
161 cmp $FLT_ARG_CNT,%r13 /* are we out of float argument */
162 je L_register_copy /* register? yes, next loop */
164 lea jumptable_float(%rip),%rbp
165 mov 0(%rbp,%r13,8),%rbx
166 inc %r13 /* float argument counter + 1 */
169 L_register_copy_done:
170 mov %r15,%rbp /* calculate remaining arguments */
171 sub %r12,%rbp /* - integer arguments in registers */
172 sub %r13,%rbp /* - float arguments in registers */
173 jle L_copy_done /* are all assigned to registers? */
175 and $0xfffffffffffffffe,%rbp /* keep stack 16-byte aligned */
176 shl $3,%rbp /* calculate stack size */
177 sub %rbp,sp /* stack frame for arguments */
178 mov sp,%rbx /* use %rbx as temp sp */
180 sub $sizevmarg,%r14 /* initialize pointer (smaller code) */
181 add $1,%r15 /* initialize argument count */
184 add $sizevmarg,%r14 /* goto next argument block */
185 dec %r15 /* are there any arguments left? */
186 jz L_copy_done /* no test needed after dec */
188 andb $0x02,offvmargtype(%r14) /* is this a float/double type? */
189 jnz L_stack_handle_float
190 dec %r12 /* arguments assigned to registers */
191 jge L_stack_copy_loop
194 L_stack_handle_float:
195 dec %r13 /* arguments assigned to registers */
196 jge L_stack_copy_loop
199 mov offvmargdata(%r14),itmp3 /* copy s8 argument onto stack */
201 add $8,%rbx /* increase sp to next argument */
202 jmp L_stack_copy_loop
205 /* itmp1 still contains method pointer*/
206 lea L_asm_call_jit_compiler(%rip),itmp3
207 call *itmp3 /* call JIT compiler */
209 add bp,sp /* remove argument stack frame if any */
211 L_asm_vm_call_method_return:
212 mov 0*8(sp),%rbx /* restore callee saved registers */
218 add $(7*8),sp /* free stack space */
223 mov xptr,a0 /* pass exception pointer */
224 call builtin_throw_exception@PLT
226 xor v0,v0 /* return NULL */
227 jmp L_asm_vm_call_method_return
239 mov offvmargdata(itmp2),a0
242 mov offvmargdata(itmp2),a1
245 mov offvmargdata(itmp2),a2
248 mov offvmargdata(itmp2),a3
251 mov offvmargdata(itmp2),a4
254 mov offvmargdata(itmp2),a5
269 movq offvmargdata(itmp2),fa0
272 movq offvmargdata(itmp2),fa1
275 movq offvmargdata(itmp2),fa2
278 movq offvmargdata(itmp2),fa3
281 movq offvmargdata(itmp2),fa4
284 movq offvmargdata(itmp2),fa5
287 movq offvmargdata(itmp2),fa6
290 movq offvmargdata(itmp2),fa7
294 /****************** function asm_call_jit_compiler *****************************
296 * invokes the compiler for untranslated JavaVM methods. *
298 * Register R0 contains a pointer to the method info structure (prepared *
299 * by createcompilerstub). Using the return address in R26 and the *
300 * offset in the LDA instruction or using the value in methodptr R28 the *
301 * patching address for storing the method address can be computed: *
303 * method address was either loaded using *
305 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
306 * i386_call_reg(REG_ITMP2) *
310 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
311 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
312 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
313 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
314 * i386_call_reg(REG_ITMP1) *
316 * in the static case the method pointer can be computed using the *
317 * return address and the lda function following the jmp instruction *
319 *******************************************************************************/
321 asm_call_jit_compiler:
322 L_asm_call_jit_compiler: /* required for PIC code */
323 /* keep stack 16-byte aligned */
324 sub $((3+ARG_CNT)*8+sizestackframeinfo),sp
326 mov t0,0*8(sp) /* save register */
328 mov (3+ARG_CNT)*8+sizestackframeinfo(sp),itmp3 /* get return address */
329 mov -1(itmp3),%bl /* get function code */
330 cmp $0xd2,%bl /* called with `call *REG_ITMP2'? */
331 jne L_not_static_special
333 sub $11,itmp3 /* calculate address of immediate */
334 jmp L_call_jit_compile
336 L_not_static_special:
337 cmp $0xd0,%bl /* called with `call *REG_ITMP1' */
338 jne L_not_virtual_interface
340 sub $7,itmp3 /* calculate address of offset */
341 mov (itmp3),itmp3l /* get offset (32-bit) */
342 add itmp2,itmp3 /* add base address to get method addr*/
343 jmp L_call_jit_compile
345 L_not_virtual_interface: /* a call from asm_calljavamethod */
349 mov 0*8(sp),t0 /* restore register */
350 mov itmp3,0*8(sp) /* save address for method pointer */
351 mov itmp1,1*8(sp) /* save method pointer */
353 SAVE_ARGUMENT_REGISTERS(3)
355 mov sp,a0 /* create stackframe info */
356 add $((3+ARG_CNT)*8),a0 /* pass sfi */
357 xor a1,a1 /* if pv is NULL, use findmethod */
358 mov sp,a2 /* pass java sp */
359 add $((1+3+ARG_CNT)*8+sizestackframeinfo),a2
360 /* pass ra to java function */
361 mov ((3+ARG_CNT)*8+sizestackframeinfo)(sp),a3
362 mov a3,a4 /* xpc is equal to ra */
363 call stacktrace_create_extern_stackframeinfo@PLT
365 mov 1*8(sp),a0 /* pass method pointer */
367 mov v0,1*8(sp) /* save return value */
369 mov sp,a0 /* remove stackframe info */
370 add $((3+ARG_CNT)*8),a0 /* pass sfi */
371 call stacktrace_remove_stackframeinfo@PLT
373 mov 0*8(sp),itmp3 /* restore address for method pointer */
374 mov 1*8(sp),v0 /* restore return value */
376 RESTORE_ARGUMENT_REGISTERS(3)
378 add $((3+ARG_CNT)*8+sizestackframeinfo),sp /* remove stack frame */
380 test v0,v0 /* check for exception */
381 je L_asm_call_jit_compiler_exception
383 test itmp3,itmp3 /* is address == 0 (asm_calljavamethod*/
386 mov v0,(itmp3) /* and now save the new pointer */
389 jmp *v0 /* ...and now call the new method */
391 L_asm_call_jit_compiler_exception:
392 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
393 call builtin_asm_get_exceptionptrptr@PLT
394 mov v0,itmp2 /* v0 == xptr */
396 lea _no_threads_exceptionptr(%rip),itmp2
398 mov (itmp2),xptr /* get the exception pointer */
399 movl $0,(itmp2) /* clear exception pointer */
401 pop xpc /* delete return address */
402 sub $5,xpc /* faulting address is ra - 5 */
403 jmp L_asm_handle_exception
406 /* asm_handle_exception ********************************************************
408 * This function handles an exception. It does not use the usual calling *
409 * conventions. The exception pointer is passed in REG_ITMP1 and the *
410 * pc from the exception raising position is passed in REG_ITMP2. It searches *
411 * the local exception table for a handler. If no one is found, it unwinds *
412 * stacks and continues searching the callers. *
414 *******************************************************************************/
416 asm_handle_nat_exception:
417 add $8,sp /* clear return address of native stub*/
419 asm_handle_exception:
420 L_asm_handle_exception: /* required for PIC code */
421 sub $((ARG_CNT+TMP_CNT)*8),sp /* create maybe-leaf stackframe */
423 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
424 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
426 mov $((ARG_CNT+TMP_CNT)*8),a3 /* prepare a3 for handle_exception */
427 mov $1,t0 /* set maybe-leaf flag */
429 L_asm_handle_exception_stack_loop:
431 mov xptr,0*8(sp) /* save exception pointer */
432 mov xpc,1*8(sp) /* save exception pc */
433 add sp,a3 /* calculate Java sp into a3... */
435 mov a3,3*8(sp) /* ...and save it */
436 mov t0,4*8(sp) /* save maybe-leaf flag */
438 mov xpc,a0 /* exception pc */
439 call codegen_findmethod@PLT
440 mov v0,2*8(sp) /* save data segment pointer */
442 mov 0*8(sp),a0 /* pass exception pointer */
443 mov 1*8(sp),a1 /* pass exception pc */
444 mov v0,a2 /* pass data segment pointer */
445 mov 3*8(sp),a3 /* pass Java stack pointer */
446 call exceptions_handle_exception@PLT
449 jz L_asm_handle_exception_not_catched
451 mov v0,xpc /* move handlerpc into xpc */
452 mov 0*8(sp),xptr /* restore exception pointer */
453 mov 4*8(sp),t0 /* get maybe-leaf flag */
454 add $(6*8),sp /* free stack frame */
456 test t0,t0 /* test for maybe-leaf flag */
457 jz L_asm_handle_exception_no_leaf
459 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
460 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
462 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
464 L_asm_handle_exception_no_leaf:
465 jmp *xpc /* jump to the handler */
467 L_asm_handle_exception_not_catched:
468 mov 0*8(sp),xptr /* restore exception pointer */
469 mov 2*8(sp),itmp3 /* restore data segment pointer */
470 mov 4*8(sp),t0 /* get maybe-leaf flag */
474 jz L_asm_handle_exception_no_leaf_stack
476 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
477 xor t0,t0 /* clear the isleaf flags */
479 L_asm_handle_exception_no_leaf_stack:
480 mov FrameSize(itmp3),itmp2l /* get frame size */
481 add sp,itmp2 /* pointer to save area */
483 mov IntSave(itmp3),a0l /* a0l = saved int register count */
506 shl $3,a0l /* multiply by 8 bytes */
511 mov FltSave(itmp3),a0l /* a0l = saved flt register count */
524 movq -5*8(itmp2),%xmm11
526 movq -4*8(itmp2),%xmm12
528 movq -3*8(itmp2),%xmm13
530 movq -2*8(itmp2),%xmm14
532 movq -1*8(itmp2),%xmm15
536 mov FrameSize(itmp3),itmp2l /* get frame size */
537 add itmp2,sp /* unwind stack */
539 /* exception pointer is still set */
540 pop xpc /* the new xpc is return address */
541 sub $3,xpc /* subtract 3 bytes for call */
543 xor a3,a3 /* prepare a3 for handle_exception */
545 jmp L_asm_handle_exception_stack_loop
548 /* asm_wrapper_patcher *********************************************************
554 32 pointer to virtual java_objectheader
555 24 machine code (which is patched back later)
556 16 unresolved class/method/field reference
557 8 data segment displacement from load instructions
558 0 pointer to patcher function
561 *******************************************************************************/
564 push bp /* save base pointer */
565 mov sp,bp /* move actual sp to bp */
566 sub $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),sp
567 and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
568 /* leaf functions) */
570 SAVE_ARGUMENT_REGISTERS(3)
571 SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
573 mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
574 mov itmp2,1*8(sp) /* can be used by some instructions */
576 mov sp,a0 /* create stackframe info */
577 add $((3+ARG_CNT+TMP_CNT)*8),a0
578 xor a1,a1 /* if pv is NULL, use findmethod */
579 mov bp,a2 /* pass java sp */
581 mov ((5+1)*8)(bp),a3 /* pass ra to java function */
582 mov a3,a4 /* xpc is equal to ra */
583 call stacktrace_create_extern_stackframeinfo@PLT
585 mov bp,a0 /* pass stack pointer */
586 add $((1+1)*8),a0 /* skip function pointer */
587 mov 1*8(bp),itmp3 /* get function pointer */
588 call *itmp3 /* call the patcher function */
589 mov v0,2*8(sp) /* save return value */
591 mov sp,a0 /* remove stackframe info */
592 add $((3+ARG_CNT+TMP_CNT)*8),a0
593 call stacktrace_remove_stackframeinfo@PLT
595 RESTORE_ARGUMENT_REGISTERS(3)
596 RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
598 mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
599 mov 1*8(sp),itmp2 /* can be used by some instructions */
600 mov 2*8(sp),itmp3 /* restore return value */
602 mov bp,sp /* restore original sp */
603 pop bp /* restore bp */
604 add $(5*8),sp /* remove patcher stackframe, keep ra */
606 test itmp3,itmp3 /* exception thrown? */
607 jz L_asm_wrapper_patcher_exception
608 ret /* call new patched code */
610 L_asm_wrapper_patcher_exception:
611 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
612 call builtin_asm_get_exceptionptrptr@PLT
613 mov v0,itmp2 /* v0 == xptr */
615 mov _no_threads_exceptionptr,itmp2
617 mov (itmp2),xptr /* get the exception pointer */
618 movl $0,(itmp2) /* clear exception pointer */
620 pop xpc /* get and remove return address */
621 jmp L_asm_handle_exception
624 /* asm_replacement_out *********************************************************
626 This code is jumped to from the replacement-out stubs that are executed
627 when a thread reaches an activated replacement point.
629 The purpose of asm_replacement_out is to read out the parts of the
630 execution state that cannot be accessed from C code, store this state,
631 and then call the C function replace_me.
634 8 start of stack inside method to replace
635 0 rplpoint * info on the replacement point that was reached
637 *******************************************************************************/
639 /* some room to accomodate changes of the stack frame size during replacement */
640 /* XXX we should find a cleaner solution here */
641 #define REPLACEMENT_ROOM 512
644 /* create stack frame */
645 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
647 /* save registers in execution state */
648 mov %rax,(RAX*8+offes_intregs)(sp)
649 mov %rbx,(RBX*8+offes_intregs)(sp)
650 mov %rcx,(RCX*8+offes_intregs)(sp)
651 mov %rdx,(RDX*8+offes_intregs)(sp)
652 mov %rsi,(RSI*8+offes_intregs)(sp)
653 mov %rdi,(RDI*8+offes_intregs)(sp)
654 mov %rbp,(RBP*8+offes_intregs)(sp)
655 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
656 mov %r8 ,(R8 *8+offes_intregs)(sp)
657 mov %r9 ,(R9 *8+offes_intregs)(sp)
658 mov %r10,(R10*8+offes_intregs)(sp)
659 mov %r11,(R11*8+offes_intregs)(sp)
660 mov %r12,(R12*8+offes_intregs)(sp)
661 mov %r13,(R13*8+offes_intregs)(sp)
662 mov %r14,(R14*8+offes_intregs)(sp)
663 mov %r15,(R15*8+offes_intregs)(sp)
665 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
666 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
667 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
668 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
669 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
670 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
671 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
672 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
673 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
674 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
675 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
676 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
677 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
678 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
679 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
680 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
682 /* calculate sp of method */
684 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
685 mov itmp1,(offes_sp)(sp)
687 /* pv must be looked up via AVL tree */
688 movq $0,(offes_pv)(sp)
690 /* call replace_me */
691 mov -8(itmp1),a0 /* rplpoint * */
692 mov sp,a1 /* arg1: execution state */
693 call replace_me@PLT /* call C function replace_me */
694 call abort@PLT /* NEVER REACHED */
696 /* asm_replacement_in **********************************************************
698 This code writes the given execution state and jumps to the replacement
701 This function never returns!
704 void asm_replacement_in(executionstate *es);
706 *******************************************************************************/
709 mov a0,%rbp /* executionstate *es */
712 mov (offes_sp)(%rbp),%rsp
714 /* store address of new code */
715 push (offes_pc)(%rbp)
717 /* copy registers from execution state */
718 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
719 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
720 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
721 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
722 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
723 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
724 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
725 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
726 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
727 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
728 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
729 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
730 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
731 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
732 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
733 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
735 mov (RAX*8+offes_intregs)(%rbp),%rax
736 mov (RBX*8+offes_intregs)(%rbp),%rbx
737 mov (RCX*8+offes_intregs)(%rbp),%rcx
738 mov (RDX*8+offes_intregs)(%rbp),%rdx
739 mov (RSI*8+offes_intregs)(%rbp),%rsi
740 mov (RDI*8+offes_intregs)(%rbp),%rdi
741 mov (R8 *8+offes_intregs)(%rbp),%r8
742 mov (R9 *8+offes_intregs)(%rbp),%r9
743 mov (R10*8+offes_intregs)(%rbp),%r10
744 mov (R11*8+offes_intregs)(%rbp),%r11
745 mov (R12*8+offes_intregs)(%rbp),%r12
746 mov (R13*8+offes_intregs)(%rbp),%r13
747 mov (R14*8+offes_intregs)(%rbp),%r14
748 mov (R15*8+offes_intregs)(%rbp),%r15
750 mov (RBP*8+offes_intregs)(%rbp),%rbp
752 /* jump to new code */
755 /* asm_builtin_x2x *************************************************************
757 * Wrapper functions for float to int corner cases *
759 *******************************************************************************/
764 SAVE_ARGUMENT_REGISTERS(0)
769 RESTORE_ARGUMENT_REGISTERS(0)
778 SAVE_ARGUMENT_REGISTERS(0)
783 RESTORE_ARGUMENT_REGISTERS(0)
792 SAVE_ARGUMENT_REGISTERS(0)
797 RESTORE_ARGUMENT_REGISTERS(0)
806 SAVE_ARGUMENT_REGISTERS(0)
811 RESTORE_ARGUMENT_REGISTERS(0)
817 /******************* function asm_initialize_thread_stack **********************
819 * initialized a thread stack *
820 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
822 *******************************************************************************/
824 asm_initialize_thread_stack:
835 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
836 mov %rsi,%rax /* return restorepoint in %rax */
840 /******************* function asm_perform_threadswitch *************************
842 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
844 * performs a threadswitch *
846 *******************************************************************************/
848 asm_perform_threadswitch:
849 sub $(7*8),%rsp /* allocate stack frame */
858 mov 7*8(%rsp),%rax /* save current return address */
861 mov %rsp,(%rdi) /* first argument **from */
862 mov %rsp,(%rdx) /* third argument **stackTop */
864 mov (%rsi),%rsp /* load new stack pointer */
873 mov 6*8(%rsp),%rax /* restore return address */
874 add $(7*8),%rsp /* free stack frame */
879 /********************* function asm_switchstackandcall *************************
881 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
884 * Switches to a new stack, calls a function and switches back. *
885 * a0 (%rdi) new stack pointer *
886 * a1 (%rsi) function pointer *
887 * a2 (%rdx) pointer to variable where stack top should be stored *
888 * a3 (%rcx) pointer to user data, is passed to the function *
890 *******************************************************************************/
892 asm_switchstackandcall:
893 sub $(1*8),%rsp /* keep stack 16-byte aligned */
894 sub $16,%rdi /* allocate new stack */
896 mov 8(%rsp),%rax /* save return address on new stack */
898 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
899 mov %rsp,(%rdx) /* save old stack pointer to variable */
901 mov %rdi,%rsp /* switch to new stack */
903 mov %rcx,%rdi /* pass pointer */
904 call *%rsi /* and call function */
906 mov (%rsp),%r10 /* load return address */
907 mov 8(%rsp),%rsp /* switch to old stack */
908 add $(1*8),%rsp /* free stack space */
909 mov %r10,(%rsp) /* write return adress */
913 asm_getclassvalues_atomic:
916 movl offbaseval(a0),itmp1l
917 movl offdiffval(a0),itmp2l
918 movl offbaseval(a1),itmp3l
920 movl itmp1l,offcast_super_baseval(a2)
921 movl itmp2l,offcast_super_diffval(a2)
922 movl itmp3l,offcast_sub_baseval(a2)
927 asm_criticalsections:
928 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
936 /* Disable exec-stacks, required for Gentoo ***********************************/
938 #if defined(__GCC__) && defined(__ELF__)
939 .section .note.GNU-stack,"",@progbits
944 * These are local overrides for various environment variables in Emacs.
945 * Please do not remove this and leave it at the end of the file, where
946 * Emacs will automagically detect them.
947 * ---------------------------------------------------------------------
950 * indent-tabs-mode: t
954 * vim:noexpandtab:sw=4:ts=4: