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 7367 2007-02-16 07:17:01Z pm $
40 #include "vm/jit/s390/arch.h"
41 #include "vm/jit/s390/md-abi.h"
42 #include "vm/jit/s390/md-asm.h"
43 #include "vm/jit/s390/offsets.h"
45 #include "vm/jit/abi-asm.h"
46 #include "vm/jit/methodheader.h"
48 /* Copy a call to a PIC function from gcc -S
49 * We setup a temporary literal pool pointer.
52 #define PIC_CALL(fun, magic) \
53 bras itmp3, L_##magic##_lp_end ; \
58 .long _GLOBAL_OFFSET_TABLE_-L_##magic##_lp ; \
59 L_##magic##_lp_end: ; \
60 l itmp2,L_##magic##_lp_4-L_##magic##_lp(itmp3) ; \
61 la itmp2,0(itmp2,itmp3) ; \
62 l itmp1,L_##magic##_lp_5-L_##magic##_lp(itmp3) ; \
63 bas %r14,0(itmp1,itmp2)
68 /* export functions ***********************************************************/
70 .globl asm_vm_call_method
71 .globl asm_vm_call_method_int
72 .globl asm_vm_call_method_long
73 .globl asm_vm_call_method_float
74 .globl asm_vm_call_method_double
75 .globl asm_vm_call_method_exception_handler
77 .globl asm_call_jit_compiler
79 .globl asm_handle_exception
80 .globl asm_handle_nat_exception
82 .globl asm_abstractmethoderror
84 .globl asm_patcher_wrapper
86 .globl asm_replacement_out
87 .globl asm_replacement_in
89 .globl asm_builtin_f2i
90 .globl asm_builtin_f2l
91 .globl asm_builtin_d2i
92 .globl asm_builtin_d2l
94 .globl asm_criticalsections
95 .globl asm_getclassvalues_atomic
100 asm_vm_call_method_int:
101 asm_vm_call_method_long:
102 asm_vm_call_method_float:
103 asm_vm_call_method_double:
105 asm_vm_call_method_exception_handler:
107 asm_call_jit_compiler:
109 asm_handle_exception:
110 asm_handle_nat_exception:
111 asm_abstractmethoderror:
118 asm_criticalsections:
119 asm_getclassvalues_atomic:
122 /********************* function asm_calljavafunction ***************************
124 * This function calls a Java-method (which possibly needs compilation) *
125 * with up to 4 address parameters. *
127 * This functions calls the JIT-compiler which eventually translates the *
128 * method into machine code. *
131 * javaobject_header *asm_calljavamethod (methodinfo *m, *
132 * void *arg1, void *arg2, void *arg3, void *arg4); *
134 *******************************************************************************/
136 .long 0 /* catch type all */
137 .long 0 /* handler pc */
139 .long 0 /* start pc */
140 .long 1 /* extable size */
141 .long 0 /* ALIGNMENT PADDING */
142 .long 0 /* line number table start */
143 .long 0 /* line number table size */
144 .long 0 /* ALIGNMENT PADDING */
145 .long 0 /* fltsave */
146 .long 0 /* intsave */
149 .long 0 /* frame size */
150 .long 0 /* codeinfo pointer */
154 asm_vm_call_method_int:
155 asm_vm_call_method_long:
156 asm_vm_call_method_float:
157 asm_vm_call_method_double:
162 a1: s4 vmargscount ---> v0: java_objectheader *
166 96 ... on stack parameters (none)
167 0 - 96 register save area
168 -------------------------------------------------- <- SP on asm_vm_... entry
170 saved return address (important to be at 0(sp) because of md_stacktrace_get_returnaddress)
171 ----------------------------------------- <- SP after stack frame allocation
173 ---------------------------------------------------- <- SP on JIT code entry
174 saved return address (callee saved)
181 itmp1: argument block pointer
182 itmp2: argument counter
183 s0: integer argument counter
184 s1: float argument counter
185 s2: integer register counter
186 s3: backup argument block pointer
187 s4: backup argument count
190 stm %r6, %r15, 24(sp) /* save callers regiters */
191 stm a0, a2, 8(sp) /* save arguments */
192 ahi sp, -8 /* allocate stack space for local variables */
193 st %r14, 0(sp) /* store RA once more at bottom of stack frame */
195 ltr a1, a1 /* maybe we have no args... */
198 lr itmp2, a1 /* load arg count */
199 lr itmp1, a2 /* load arg pointer */
201 ahi itmp1, -sizevmarg /* initialize arg pointer */
202 ahi itmp2, 1 /* initialize arg count */
203 lhi s0, 0 /* initialize integer arg counter */
204 lhi s2, 0 /* initialize integer register counter */
205 lhi s1, 0 /* initialize float arg counter */
207 lr s4, a1 /* backup arg count */
208 lr s3, a2 /* backup arg pointer */
212 ahi itmp1, sizevmarg /* forward arg pointer */
213 ahi itmp2, -1 /* decrement arg count */
214 je L_register_copy_done /* no arguments left */
216 tm offvmargtype(itmp1), 0x02 /* is this a float/double type? */
217 jne L_register_handle_float
219 L_register_handle_int:
221 chi s2, INT_ARG_CNT /* are we out of integer arg registers ? */
222 je L_register_copy /* yes, next loop */
224 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
225 jne L_register_handle_long
227 ahi s0, 1 /* increment integer arg counter */
228 ahi s2, 1 /* increment integer register counter */
230 /* handle argument */
243 L_register_handle_long:
245 chi s2, (INT_ARG_CNT - 1) /* are there 2 integer arg registers left ? */
246 jl L_register_handle_long_continue /* yes */
247 lhi s2, INT_ARG_CNT /* no, drop last register */
250 L_register_handle_long_continue:
252 ahi s0, 1 /* increment integer arg counter */
253 ahi s2, 2 /* consume 2 integer arg registers */
255 /* handle argument */
266 L_register_handle_float:
268 chi s1, FLT_ARG_CNT /* are we out of float arg registers */
269 je L_register_copy /* no arg regisers left */
271 ahi s1, 1 /* increment float argument counter */
273 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
274 jne L_register_handle_double
276 /* handle argument */
283 L_register_handle_double:
285 /* handle argument */
292 L_register_copy_done:
296 itmp1: argument block pointer
297 itmp2: argument counter
298 s0: integer argument counter (initialized by previous code)
299 s1: float argument counter (initialized by previous code)
300 s2: pointer to current argument on stack
301 s3: backup argument block pointer (used to initialize itmp1)
302 after used as backup of original stack pointer
303 s4: backup argument count (used to initialize itmp2)
304 after used as size of parameters on stack
307 lr itmp2, s4 /* restore argument counter */
308 lr itmp1, s3 /* restore argument block pointer */
310 /* calculate remaining arguments */
311 sr s4, s0 /* - integer arguments in registers */
312 sr s4, s1 /* - float arguments in registers */
314 lr s3, sp /* backup stack pointer (does not alter CC) */
316 je L_copy_done /* no arguments left for stack */
318 sll s4, 3 /* allocate 8 bytes per parameter on stack */
319 sr sp, s4 /* allocate stack space for arguments */
321 lr s2, sp /* points now to current argument on stack */
323 ahi itmp1, -sizevmarg /* initialize argument block pointer */
324 ahi itmp2, 1 /* initialize argument counter */
328 ahi itmp1, sizevmarg /* forward argument block pointer */
329 ahi itmp2, -1 /* decrement argument counter */
330 je L_copy_done /* all arguments done */
332 tm offvmargtype(itmp1), 0x0 /* is this a float/double type? */
333 jne L_stack_handle_float
337 ahi s0, -1 /* decrement number of integer arguments in regs */
338 jhe L_stack_copy_loop /* argument is in register */
340 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
341 jne L_stack_handle_long
343 mvc 0(4, s2), offvmargdata+4(itmp1) /* copy integer value */
349 mvc 0(8, s2), offvmargdata(itmp1) /* copy long value */
353 L_stack_handle_float:
355 ahi s1, -1 /* decrement number of float arguments in regs */
356 jhe L_stack_copy_loop /* argument is in register */
358 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
359 jne L_stack_handle_double
361 mvc 0(4, s2), offvmargdata(itmp1) /* copy float value */
365 L_stack_handle_double:
367 mvc 0(8, s2), offvmargdata(itmp1) /* copy double value */
373 /* Now we call the compiler in a rather questionable way i needed
374 * some days to understand:
376 * We can't simply call asm_call_jit_compiler, but we have to call an
377 * address loaded from memory like it is done in JIT code.
379 * This is because the compiler will intercept the instruction before
380 * the call instruction, extract the address where the function pointer
381 * has been loaded from and overwrite it with the code entry.
383 * Arguments are passed in temporary registers.
386 /* load address of L_asm_call_jit_compiler into memory */
388 basr mptr, 0 /* store PC */
390 la mptr, L_asm_call_jit_compiler-L_basr(mptr) /* add offset to PC */
391 st mptr, 4(s3) /* store on stack */
393 l itmp1, 8+8(s3) /* load methodinfo for compiler */
394 la mptr, 4(s3) /* store **function in mptr for compiler */
396 /* call L_asm_call_jit_compiler like JIT code would do */
398 l itmp3, 0(mptr) /* load address of target from memory */
399 basr %r14, itmp3 /* jump to target */
401 /* todo will s4 survive the call? */
402 ar sp, s4 /* remove stack space for arguments */
404 L_asm_vm_call_method_return:
406 ahi sp, 8 /* remove stack space for local variables */
407 lm %r6, %r15, 24(sp) /* restore callers registers */
417 l a0, offvmargdata+4(itmp1)
420 l a1, offvmargdata+4(itmp1)
423 l a2, offvmargdata+4(itmp1)
426 l a3, offvmargdata+4(itmp1)
429 l a4, offvmargdata+4(itmp1)
433 lm a0, a1, offvmargdata(itmp1)
436 lm a1, a2, offvmargdata(itmp1)
439 lm a2, a3, offvmargdata(itmp1)
442 lm a3, a4, offvmargdata(itmp1)
446 le fa0, offvmargdata(itmp1)
449 le fa1, offvmargdata(itmp1)
453 ld fa0, offvmargdata(itmp1)
456 ld fa1, offvmargdata(itmp1)
460 /****************** function asm_call_jit_compiler *****************************
462 * invokes the compiler for untranslated JavaVM methods. *
464 * itmp1: methodinfo pointer *
465 * itmp2: method pointer *
467 *******************************************************************************/
471 argument registers: arguments (like in JIT)
473 arguments on stack (like in JIT)
474 ------------------------------------------------------------- <- SP on entry
476 saved return address \
477 stored volatile (in terms of C ABI) floag argument registers |
478 96 stored volatile (in terms of C ABI) integer argument registers | ACJC_STACKFRAME
479 0 - 96 register save area (C ABI) /
480 -------------------------------------------------- <- SP for jit_asm_compile
483 /* This is called from a compiler stub.
484 * Arguments are already in registers and the stack is setup like in CACAO.
487 asm_call_jit_compiler:
488 L_asm_call_jit_compiler:
490 # define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96)
492 ahi sp,-ACJC_STACKFRAME /* allocate stack space */
494 stm %r2,%r5,96(sp) /* store volatile int arg regs */
495 std %f0,96+16(sp) /* store volatile float arg regs */
497 st %r14,96+32(sp) /* store return address */
501 lr a0,itmp1 /* pass methodinfo pointer */
502 lr a1,itmp2 /* pass method pointer */
503 la a2,ACJC_STACKFRAME(sp) /* pass java sp */
504 la a3,0(%r14) /* pass return address, make sure bit 32 is 0 */
506 /* call jit_asm_compile in a PIC way */
508 bras itmp2, L_bras_jac
509 .long jit_asm_compile
514 lr pv, v0 /* save return value */
516 lm %r2,%r5,96(sp) /* restore volatile int arg regs */
517 ld %f0,96+16(sp) /* restore volatile float arg regs */
518 ld %f2,96+24(sp) /* restore volatile float arg regs */
519 l %r14,96+32(sp) /* restore return address */
520 ahi sp, ACJC_STACKFRAME /* remove stack frame */
524 je L_asm_call_jit_compiler_exception
527 jit_code_entry: /* label to set breakpoint on */
528 br pv /* call the method, it will return to the caller */
531 L_asm_call_jit_compiler_exception:
533 call exceptions_get_and_clear_exception@PLT
534 pop xpc /* delete return address */
535 sub $3,xpc /* faulting address is ra - 3 */
536 jmp L_asm_handle_exception
542 /* asm_handle_exception ********************************************************
544 * This function handles an exception. It does not use the usual calling *
545 * conventions. The exception pointer is passed in REG_ITMP1 and the *
546 * pc from the exception raising position is passed in REG_ITMP2. It searches *
547 * the local exception table for a handler. If no one is found, it unwinds *
548 * stacks and continues searching the callers. *
550 *******************************************************************************/
552 asm_handle_nat_exception:
553 add $8,sp /* clear return address of native stub*/
555 asm_handle_exception:
556 L_asm_handle_exception: /* required for PIC code */
557 sub $((ARG_CNT+TMP_CNT)*8),sp /* create maybe-leaf stackframe */
559 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
560 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
562 mov $((ARG_CNT+TMP_CNT)*8),a3 /* prepare a3 for handle_exception */
563 mov $1,t0 /* set maybe-leaf flag */
565 L_asm_handle_exception_stack_loop:
567 mov xptr,0*8(sp) /* save exception pointer */
568 mov xpc,1*8(sp) /* save exception pc */
569 add sp,a3 /* calculate Java sp into a3... */
571 mov a3,3*8(sp) /* ...and save it */
572 mov t0,4*8(sp) /* save maybe-leaf flag */
574 mov xpc,a0 /* exception pc */
575 call codegen_get_pv_from_pc@PLT
576 mov v0,2*8(sp) /* save data segment pointer */
578 mov 0*8(sp),a0 /* pass exception pointer */
579 mov 1*8(sp),a1 /* pass exception pc */
580 mov v0,a2 /* pass data segment pointer */
581 mov 3*8(sp),a3 /* pass Java stack pointer */
582 call exceptions_handle_exception@PLT
585 jz L_asm_handle_exception_not_catched
587 mov v0,xpc /* move handlerpc into xpc */
588 mov 0*8(sp),xptr /* restore exception pointer */
589 mov 4*8(sp),t0 /* get maybe-leaf flag */
590 add $(6*8),sp /* free stack frame */
592 test t0,t0 /* test for maybe-leaf flag */
593 jz L_asm_handle_exception_no_leaf
595 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
596 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
598 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
600 L_asm_handle_exception_no_leaf:
601 jmp *xpc /* jump to the handler */
603 L_asm_handle_exception_not_catched:
604 mov 0*8(sp),xptr /* restore exception pointer */
605 mov 2*8(sp),itmp3 /* restore data segment pointer */
606 mov 4*8(sp),t0 /* get maybe-leaf flag */
610 jz L_asm_handle_exception_no_leaf_stack
612 add $((ARG_CNT+TMP_CNT)*8),sp /* remove maybe-leaf stackframe */
613 xor t0,t0 /* clear the isleaf flags */
615 L_asm_handle_exception_no_leaf_stack:
616 mov FrameSize(itmp3),itmp2l /* get frame size */
617 add sp,itmp2 /* pointer to save area */
619 mov IntSave(itmp3),a0l /* a0l = saved int register count */
642 shl $3,a0l /* multiply by 8 bytes */
647 mov FltSave(itmp3),a0l /* a0l = saved flt register count */
660 movq -5*8(itmp2),%xmm11
662 movq -4*8(itmp2),%xmm12
664 movq -3*8(itmp2),%xmm13
666 movq -2*8(itmp2),%xmm14
668 movq -1*8(itmp2),%xmm15
672 mov FrameSize(itmp3),itmp2l /* get frame size */
673 add itmp2,sp /* unwind stack */
675 /* exception pointer is still set */
676 pop xpc /* the new xpc is return address */
677 sub $3,xpc /* subtract 3 bytes for call */
679 xor a3,a3 /* prepare a3 for handle_exception */
681 jmp L_asm_handle_exception_stack_loop
684 /* asm_abstractmethoderror *****************************************************
686 Creates and throws an AbstractMethodError.
688 *******************************************************************************/
690 asm_abstractmethoderror:
691 mov sp,a0 /* pass java sp */
693 mov 0*8(sp),a1 /* pass exception address */
695 call exceptions_asm_new_abstractmethoderror@PLT
696 /* exception pointer is return value */
697 pop xpc /* get exception address */
698 sub $3,xpc /* exception address is ra - 3 */
699 jmp L_asm_handle_exception
703 /* asm_patcher_wrapper *********************************************************
708 20 return address into JIT code (patch position)
709 16 pointer to virtual java_objectheader
710 12 machine code (which is patched back later)
711 8 unresolved class/method/field reference
712 4 data segment displacement from load instructions
713 0 patcher function pointer to call (pv afterwards)
715 *******************************************************************************/
718 # define apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
720 ahi sp, -apw_sfs /* create stack frame */
722 /* store all volatile registers and a2, because we will touch it */
725 STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
726 STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
730 la a0, apw_sfs(sp) /* pass SP of patcher stub */
731 lr a1, pv /* pass PV (if NULL, use findmethod) */
732 lhi a2, 0 /* pass RA (it's on the stack) */
734 /* call patcher_wrapper */
736 bras itmp1, L_apw_bras /* call patcher_wrapper */
737 .long patcher_wrapper
742 /* store return value */
744 st v0,0(sp) /* save return value */
746 /* restore volatile registers */
749 LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
750 LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
752 l itmp3, 0(sp) /* restore return value */
753 ltr itmp3, itmp3 /* exception thrown ? */
754 jne L_asm_patcher_wrapper_exception /* handle exception */
755 ahi sp, apw_sfs /* remove stack frame */
756 l itmp3, 20(sp) /* load return address to JIT from stack */
757 br itmp3 /* return */
759 L_asm_patcher_wrapper_exception:
762 mov itmp3,xptr /* get exception */
763 pop xpc /* get and remove return address */
764 jmp L_asm_handle_exception
769 /* asm_replacement_out *********************************************************
771 This code is jumped to from the replacement-out stubs that are executed
772 when a thread reaches an activated replacement point.
774 The purpose of asm_replacement_out is to read out the parts of the
775 execution state that cannot be accessed from C code, store this state,
776 and then call the C function replace_me.
779 8 start of stack inside method to replace
780 0 rplpoint * info on the replacement point that was reached
782 *******************************************************************************/
784 /* some room to accomodate changes of the stack frame size during replacement */
785 /* XXX we should find a cleaner solution here */
786 #define REPLACEMENT_ROOM 512
789 /* create stack frame */
790 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
792 /* save registers in execution state */
793 mov %rax,(RAX*8+offes_intregs)(sp)
794 mov %rbx,(RBX*8+offes_intregs)(sp)
795 mov %rcx,(RCX*8+offes_intregs)(sp)
796 mov %rdx,(RDX*8+offes_intregs)(sp)
797 mov %rsi,(RSI*8+offes_intregs)(sp)
798 mov %rdi,(RDI*8+offes_intregs)(sp)
799 mov %rbp,(RBP*8+offes_intregs)(sp)
800 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
801 mov %r8 ,(R8 *8+offes_intregs)(sp)
802 mov %r9 ,(R9 *8+offes_intregs)(sp)
803 mov %r10,(R10*8+offes_intregs)(sp)
804 mov %r11,(R11*8+offes_intregs)(sp)
805 mov %r12,(R12*8+offes_intregs)(sp)
806 mov %r13,(R13*8+offes_intregs)(sp)
807 mov %r14,(R14*8+offes_intregs)(sp)
808 mov %r15,(R15*8+offes_intregs)(sp)
810 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
811 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
812 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
813 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
814 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
815 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
816 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
817 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
818 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
819 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
820 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
821 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
822 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
823 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
824 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
825 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
827 /* calculate sp of method */
829 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
830 mov itmp1,(offes_sp)(sp)
832 /* pv must be looked up via AVL tree */
833 movq $0,(offes_pv)(sp)
835 /* call replace_me */
836 mov -8(itmp1),a0 /* rplpoint * */
837 mov sp,a1 /* arg1: execution state */
838 call replace_me@PLT /* call C function replace_me */
839 call abort@PLT /* NEVER REACHED */
841 /* asm_replacement_in **********************************************************
843 This code writes the given execution state and jumps to the replacement
846 This function never returns!
849 void asm_replacement_in(executionstate *es);
851 *******************************************************************************/
854 mov a0,%rbp /* executionstate *es */
857 mov (offes_sp)(%rbp),%rsp
859 /* store address of new code */
860 push (offes_pc)(%rbp)
862 /* copy registers from execution state */
863 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
864 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
865 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
866 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
867 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
868 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
869 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
870 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
871 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
872 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
873 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
874 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
875 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
876 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
877 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
878 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
880 mov (RAX*8+offes_intregs)(%rbp),%rax
881 mov (RBX*8+offes_intregs)(%rbp),%rbx
882 mov (RCX*8+offes_intregs)(%rbp),%rcx
883 mov (RDX*8+offes_intregs)(%rbp),%rdx
884 mov (RSI*8+offes_intregs)(%rbp),%rsi
885 mov (RDI*8+offes_intregs)(%rbp),%rdi
886 mov (R8 *8+offes_intregs)(%rbp),%r8
887 mov (R9 *8+offes_intregs)(%rbp),%r9
888 mov (R10*8+offes_intregs)(%rbp),%r10
889 mov (R11*8+offes_intregs)(%rbp),%r11
890 mov (R12*8+offes_intregs)(%rbp),%r12
891 mov (R13*8+offes_intregs)(%rbp),%r13
892 mov (R14*8+offes_intregs)(%rbp),%r14
893 mov (R15*8+offes_intregs)(%rbp),%r15
895 mov (RBP*8+offes_intregs)(%rbp),%rbp
897 /* jump to new code */
901 /* asm_builtin_x2x *************************************************************
903 * Wrapper functions for float to int corner cases *
905 *******************************************************************************/
910 SAVE_ARGUMENT_REGISTERS(0)
915 RESTORE_ARGUMENT_REGISTERS(0)
924 SAVE_ARGUMENT_REGISTERS(0)
929 RESTORE_ARGUMENT_REGISTERS(0)
938 SAVE_ARGUMENT_REGISTERS(0)
943 RESTORE_ARGUMENT_REGISTERS(0)
952 SAVE_ARGUMENT_REGISTERS(0)
957 RESTORE_ARGUMENT_REGISTERS(0)
963 asm_getclassvalues_atomic:
966 movl offbaseval(a0),itmp1l
967 movl offdiffval(a0),itmp2l
968 movl offbaseval(a1),itmp3l
970 movl itmp1l,offcast_super_baseval(a2)
971 movl itmp2l,offcast_super_diffval(a2)
972 movl itmp3l,offcast_sub_baseval(a2)
977 asm_criticalsections:
978 #if defined(ENABLE_THREADS)
986 /* Disable exec-stacks, required for Gentoo ***********************************/
988 #if defined(__GCC__) && defined(__ELF__)
989 .section .note.GNU-stack,"",@progbits
996 * These are local overrides for various environment variables in Emacs.
997 * Please do not remove this and leave it at the end of the file, where
998 * Emacs will automagically detect them.
999 * ---------------------------------------------------------------------
1002 * indent-tabs-mode: t
1006 * vim:noexpandtab:sw=4:ts=4: