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 7442 2007-03-02 23:28:37Z 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
98 asm_abstractmethoderror:
113 /********************* function asm_calljavafunction ***************************
115 * This function calls a Java-method (which possibly needs compilation) *
116 * with up to 4 address parameters. *
118 * This functions calls the JIT-compiler which eventually translates the *
119 * method into machine code. *
122 * javaobject_header *asm_calljavamethod (methodinfo *m, *
123 * void *arg1, void *arg2, void *arg3, void *arg4); *
125 *******************************************************************************/
127 .long 0 /* catch type all */
128 .long 0 /* exception handler pc */
130 .long 0 /* start pc */
131 .long 1 /* extable size */
132 .long 0 /* line number table start */
133 .long 0 /* line number table size */
134 .long 0 /* fltsave */
135 .long 0 /* intsave */
138 .long 0 /* frame size */
139 .long 0 /* codeinfo pointer */
142 asm_vm_call_method_int:
143 asm_vm_call_method_long:
144 asm_vm_call_method_float:
145 asm_vm_call_method_double:
150 a1: s4 vmargscount ---> v0: java_objectheader *
154 96 ... on stack parameters (none)
155 0 - 96 register save area
156 -------------------------------------------------- <- SP on asm_vm_... entry
158 saved return address (important to be at 0(sp) because of md_stacktrace_get_returnaddress)
159 ----------------------------------------- <- SP after stack frame allocation
161 ---------------------------------------------------- <- SP on JIT code entry
162 saved return address (callee saved)
169 itmp1: argument block pointer
170 itmp2: argument counter
171 s0: integer argument counter
172 s1: float argument counter
173 s2: integer register counter
174 s3: backup argument block pointer
175 s4: backup argument count
178 stm %r6, %r15, 24(sp) /* save callers regiters */
179 stm a0, a2, 8(sp) /* save arguments */
180 ahi sp, -8 /* allocate stack space for local variables */
181 st %r14, 0(sp) /* store RA once more at bottom of stack frame */
183 ltr a1, a1 /* maybe we have no args... */
186 lr itmp2, a1 /* load arg count */
187 lr itmp1, a2 /* load arg pointer */
189 ahi itmp1, -sizevmarg /* initialize arg pointer */
190 ahi itmp2, 1 /* initialize arg count */
191 lhi s0, 0 /* initialize integer arg counter */
192 lhi s2, 0 /* initialize integer register counter */
193 lhi s1, 0 /* initialize float arg counter */
195 lr s4, a1 /* backup arg count */
196 lr s3, a2 /* backup arg pointer */
200 ahi itmp1, sizevmarg /* forward arg pointer */
201 ahi itmp2, -1 /* decrement arg count */
202 je L_register_copy_done /* no arguments left */
204 tm offvmargtype(itmp1), 0x02 /* is this a float/double type? */
205 jne L_register_handle_float
207 L_register_handle_int:
209 chi s2, INT_ARG_CNT /* are we out of integer arg registers ? */
210 je L_register_copy /* yes, next loop */
212 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
213 jne L_register_handle_long
215 ahi s0, 1 /* increment integer arg counter */
216 ahi s2, 1 /* increment integer register counter */
218 /* handle argument */
231 L_register_handle_long:
233 chi s2, (INT_ARG_CNT - 1) /* are there 2 integer arg registers left ? */
234 jl L_register_handle_long_continue /* yes */
235 lhi s2, INT_ARG_CNT /* no, drop last register */
238 L_register_handle_long_continue:
240 ahi s0, 1 /* increment integer arg counter */
241 ahi s2, 2 /* consume 2 integer arg registers */
243 /* handle argument */
254 L_register_handle_float:
256 chi s1, FLT_ARG_CNT /* are we out of float arg registers */
257 je L_register_copy /* no arg regisers left */
259 ahi s1, 1 /* increment float argument counter */
261 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
262 jne L_register_handle_double
264 /* handle argument */
271 L_register_handle_double:
273 /* handle argument */
280 L_register_copy_done:
284 itmp1: argument block pointer
285 itmp2: argument counter
286 s0: integer argument counter (initialized by previous code)
287 s1: float argument counter (initialized by previous code)
288 s2: pointer to current argument on stack
289 s3: backup argument block pointer (used to initialize itmp1)
290 after used as backup of original stack pointer
291 s4: backup argument count (used to initialize itmp2)
292 after used as size of parameters on stack
295 lr itmp2, s4 /* restore argument counter */
296 lr itmp1, s3 /* restore argument block pointer */
298 /* calculate remaining arguments */
299 sr s4, s0 /* - integer arguments in registers */
300 sr s4, s1 /* - float arguments in registers */
302 lr s3, sp /* backup stack pointer (does not alter CC) */
304 je L_copy_done /* no arguments left for stack */
306 sll s4, 3 /* allocate 8 bytes per parameter on stack */
307 sr sp, s4 /* allocate stack space for arguments */
309 lr s2, sp /* points now to current argument on stack */
311 ahi itmp1, -sizevmarg /* initialize argument block pointer */
312 ahi itmp2, 1 /* initialize argument counter */
316 ahi itmp1, sizevmarg /* forward argument block pointer */
317 ahi itmp2, -1 /* decrement argument counter */
318 je L_copy_done /* all arguments done */
320 tm offvmargtype(itmp1), 0x0 /* is this a float/double type? */
321 jne L_stack_handle_float
325 ahi s0, -1 /* decrement number of integer arguments in regs */
326 jhe L_stack_copy_loop /* argument is in register */
328 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
329 jne L_stack_handle_long
331 mvc 0(4, s2), offvmargdata+4(itmp1) /* copy integer value */
337 mvc 0(8, s2), offvmargdata(itmp1) /* copy long value */
341 L_stack_handle_float:
343 ahi s1, -1 /* decrement number of float arguments in regs */
344 jhe L_stack_copy_loop /* argument is in register */
346 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
347 jne L_stack_handle_double
349 mvc 0(4, s2), offvmargdata(itmp1) /* copy float value */
353 L_stack_handle_double:
355 mvc 0(8, s2), offvmargdata(itmp1) /* copy double value */
361 /* Now we call the compiler in a rather questionable way i needed
362 * some days to understand:
364 * We can't simply call asm_call_jit_compiler, but we have to call an
365 * address loaded from memory like it is done in JIT code.
367 * This is because the compiler will intercept the instruction before
368 * the call instruction, extract the address where the function pointer
369 * has been loaded from and overwrite it with the code entry.
371 * Arguments are passed in temporary registers.
374 /* load address of L_asm_call_jit_compiler into memory */
376 basr mptr, 0 /* store PC */
378 la mptr, L_asm_call_jit_compiler-L_basr(mptr) /* add offset to PC */
379 st mptr, 4(s3) /* store on stack */
381 l itmp1, 8+8(s3) /* load methodinfo for compiler */
382 la mptr, 4(s3) /* store **function in mptr for compiler */
384 /* call L_asm_call_jit_compiler like JIT code would do */
386 l itmp3, 0(mptr) /* load address of target from memory */
387 basr %r14, itmp3 /* jump to target */
389 /* todo will s4 survive the call? */
390 ar sp, s4 /* remove stack space for arguments */
392 L_asm_vm_call_method_return:
394 ahi sp, 8 /* remove stack space for local variables */
395 lm %r6, %r15, 24(sp) /* restore callers registers */
398 asm_vm_call_method_exception_handler:
401 bras %r14, L_avcmeh_bras
402 .long builtin_throw_exception
409 j L_asm_vm_call_method_return
419 l a0, offvmargdata+4(itmp1)
422 l a1, offvmargdata+4(itmp1)
425 l a2, offvmargdata+4(itmp1)
428 l a3, offvmargdata+4(itmp1)
431 l a4, offvmargdata+4(itmp1)
435 lm a0, a1, offvmargdata(itmp1)
438 lm a1, a2, offvmargdata(itmp1)
441 lm a2, a3, offvmargdata(itmp1)
444 lm a3, a4, offvmargdata(itmp1)
448 le fa0, offvmargdata(itmp1)
451 le fa1, offvmargdata(itmp1)
455 ld fa0, offvmargdata(itmp1)
458 ld fa1, offvmargdata(itmp1)
462 /****************** function asm_call_jit_compiler *****************************
464 * invokes the compiler for untranslated JavaVM methods. *
466 * itmp1: methodinfo pointer *
467 * itmp2: method pointer *
469 *******************************************************************************/
473 argument registers: arguments (like in JIT)
475 arguments on stack (like in JIT)
476 ------------------------------------------------------------- <- SP on entry
478 saved return address \
479 stored volatile (in terms of C ABI) floag argument registers |
480 96 stored volatile (in terms of C ABI) integer argument registers | ACJC_STACKFRAME
481 0 - 96 register save area (C ABI) /
482 -------------------------------------------------- <- SP for jit_asm_compile
485 /* This is called from a compiler stub.
486 * Arguments are already in registers and the stack is setup like in CACAO.
489 asm_call_jit_compiler:
490 L_asm_call_jit_compiler:
492 # define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96)
494 ahi sp,-ACJC_STACKFRAME /* allocate stack space */
496 stm %r2,%r5,96(sp) /* store volatile int arg regs */
497 std %f0,96+16(sp) /* store volatile float arg regs */
499 st %r14,96+32(sp) /* store return address */
503 lr a0,itmp1 /* pass methodinfo pointer */
504 lr a1,itmp2 /* pass method pointer */
505 la a2,ACJC_STACKFRAME(sp) /* pass java sp */
506 la a3,0(%r14) /* pass return address, make sure bit 32 is 0 */
508 /* call jit_asm_compile in a PIC way */
510 bras itmp2, L_bras_jac
511 .long jit_asm_compile
516 lr pv, v0 /* save return value */
518 lm %r2,%r5,96(sp) /* restore volatile int arg regs */
519 ld %f0,96+16(sp) /* restore volatile float arg regs */
520 ld %f2,96+24(sp) /* restore volatile float arg regs */
523 je L_asm_call_jit_compiler_exception
525 l %r14,96+32(sp) /* restore return address */
526 ahi sp, ACJC_STACKFRAME /* remove stack frame */
528 jit_code_entry: /* label to set breakpoint on */
529 br pv /* call the method, it will return to the caller */
532 L_asm_call_jit_compiler_exception:
533 bras itmp2, L_bras_acjce
534 .long exceptions_get_and_clear_exception
539 l xpc,96+32(sp) /* restore return address */
540 ahi sp, ACJC_STACKFRAME /* remove stack frame */
541 j L_asm_handle_nat_exception
545 /* asm_handle_exception ********************************************************
547 * This function handles an exception. It does not use the usual calling *
548 * conventions. The exception pointer is passed in REG_ITMP1 and the *
549 * pc from the exception raising position is passed in REG_ITMP2. It searches *
550 * the local exception table for a handler. If no one is found, it unwinds *
551 * stacks and continues searching the callers. *
553 *******************************************************************************/
557 asm_handle_nat_exception:
558 L_asm_handle_nat_exception:
559 /* TODO really nothing here ? */
560 asm_handle_exception:
561 L_asm_handle_exception: /* required for PIC code */
563 ahi sp, -(ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* create maybe-leaf stackframe */
564 STORE_ARGUMENT_REGISTERS(0)
565 STORE_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
566 lhi a3, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* prepare a3 for handle_exception */
568 lhi %r0, 1 /* set maybe-leaf flag */
570 L_asm_handle_exception_stack_loop:
572 st xptr,0*4(sp) /* save exception pointer */
573 st xpc,1*4(sp) /* save exception pc */
574 la a3,(6*4)(a3,sp) /* calculate Java sp into a3... */
575 st a3,3*4(sp) /* ...and save it */
576 st %r0,4*4(sp) /* save maybe-leaf flag */
578 lr a0,xpc /* exception pc */
580 ahi sp,-96 /* add register save area for C code */
582 bras %r14,L_ahe_bras /* call codegen_get_pv_from_pc */
583 .long codegen_get_pv_from_pc
587 st v0,2*4+96(sp) /* save data segment pointer */
589 lr a2,v0 /* pass data segment pointer */
590 l a0,0*4+96(sp) /* pass exception pointer */
591 l a1,1*4+96(sp) /* pass exception pc */
592 l a3,3*4+96(sp) /* pass Java stack pointer */
594 bras %r14,L_ahe_bras2 /* call exceptions_handle_exception */
595 .long exceptions_handle_exception
600 ahi sp,96 /* remove regiser save area for C code */
603 jz L_asm_handle_exception_not_catched
605 lr xpc,v0 /* move handlerpc into xpc */
606 l xptr,0*4(sp) /* restore exception pointer */
607 l %r0,4*4(sp) /* get maybe-leaf flag */
608 ahi sp,(6*4) /* free stack frame */
611 jz L_asm_handle_exception_no_leaf
613 LOAD_ARGUMENT_REGISTERS(0)
614 LOAD_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
616 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
618 L_asm_handle_exception_no_leaf:
619 br xpc /* jump to the handler */
621 L_asm_handle_exception_not_catched:
622 l xptr,0*4(sp) /* restore exception pointer */
623 l itmp3,2*4(sp) /* restore data segment pointer */
624 ahi itmp3,-0xfff /* for negative displacements */
625 l %r0,4*4(sp) /* get maybe-leaf flag */
629 jz L_asm_handle_exception_no_leaf_stack
631 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
632 lhi %r0,0 /* clear the isleaf flags */
635 +-----------------+-----------+---------+----+
636 | Memuse | Float Sav | Int Sav | RA |
637 | | 0 ... n | 0 ... n | |
638 +-----------------+-----------+---------+----+
643 L_asm_handle_exception_no_leaf_stack:
645 l itmp2,0xfff+FrameSize(itmp3)/* get frame size */
646 la itmp2,0(itmp2,sp) /* pointer to save area */
647 ahi itmp2,-4 /* skip RA */
649 l a0,0xfff+IntSave(itmp3) /* a0 = saved int register count */
654 sll a0,2 /* a0 = saved int register count * 4 */
655 sr itmp2, a0 /* skip Int Sav */
678 l a0,0xfff+FltSave(itmp3)
679 ltr a0,a0 /* Number of saved floating point registers */
682 sll a0,3 /* Number of saved floating point registers * 8 */
697 l itmp3,0xfff+FrameSize(itmp3)/* get frame size (at least 4 - RA) */
698 ahi itmp3,-4 /* substract 4 */
699 l xpc,0(itmp3,sp) /* load the new xpc - return address */
700 la sp, 4(itmp3,sp) /* unwind stack */
702 /* exception pointer is still set */
704 sub $3,xpc /* subtract 3 bytes for call */
707 lhi a3,0 /* prepare a3 for handle_exception */
709 j L_asm_handle_exception_stack_loop
714 /* asm_abstractmethoderror *****************************************************
716 Creates and throws an AbstractMethodError.
718 *******************************************************************************/
720 asm_abstractmethoderror:
721 mov sp,a0 /* pass java sp */
723 mov 0*8(sp),a1 /* pass exception address */
725 call exceptions_asm_new_abstractmethoderror@PLT
726 /* exception pointer is return value */
727 pop xpc /* get exception address */
728 sub $3,xpc /* exception address is ra - 3 */
729 jmp L_asm_handle_exception
733 /* asm_patcher_wrapper *********************************************************
738 20 return address into JIT code (patch position)
739 16 pointer to virtual java_objectheader
740 12 machine code (which is patched back later)
741 8 unresolved class/method/field reference
742 4 data segment displacement from load instructions
743 0 patcher function pointer to call (pv afterwards)
745 *******************************************************************************/
748 # define apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
750 ahi sp, -apw_sfs /* create stack frame */
752 /* store all volatile registers and a2, because we will touch it */
755 STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
756 STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
760 la a0, apw_sfs(sp) /* pass SP of patcher stub */
761 lr a1, pv /* pass PV (if NULL, use findmethod) */
762 lhi a2, 0 /* pass RA */
764 /* call patcher_wrapper */
766 bras itmp1, L_apw_bras /* call patcher_wrapper */
767 .long patcher_wrapper
772 /* store return value */
774 st v0,0(sp) /* save return value */
776 /* restore volatile registers */
779 LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
780 LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
782 l itmp3, 0(sp) /* restore return value */
783 ltr itmp3, itmp3 /* exception thrown ? */
784 jne L_asm_patcher_wrapper_exception /* handle exception */
785 l itmp3, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
786 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
787 br itmp3 /* return */
789 L_asm_patcher_wrapper_exception:
790 lr xptr,itmp3 /* get exception */
791 l xpc, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
792 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
793 j L_asm_handle_exception
797 /* asm_replacement_out *********************************************************
799 This code is jumped to from the replacement-out stubs that are executed
800 when a thread reaches an activated replacement point.
802 The purpose of asm_replacement_out is to read out the parts of the
803 execution state that cannot be accessed from C code, store this state,
804 and then call the C function replace_me.
807 8 start of stack inside method to replace
808 0 rplpoint * info on the replacement point that was reached
810 *******************************************************************************/
812 /* some room to accomodate changes of the stack frame size during replacement */
813 /* XXX we should find a cleaner solution here */
814 #define REPLACEMENT_ROOM 512
817 /* create stack frame */
818 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
820 /* save registers in execution state */
821 mov %rax,(RAX*8+offes_intregs)(sp)
822 mov %rbx,(RBX*8+offes_intregs)(sp)
823 mov %rcx,(RCX*8+offes_intregs)(sp)
824 mov %rdx,(RDX*8+offes_intregs)(sp)
825 mov %rsi,(RSI*8+offes_intregs)(sp)
826 mov %rdi,(RDI*8+offes_intregs)(sp)
827 mov %rbp,(RBP*8+offes_intregs)(sp)
828 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
829 mov %r8 ,(R8 *8+offes_intregs)(sp)
830 mov %r9 ,(R9 *8+offes_intregs)(sp)
831 mov %r10,(R10*8+offes_intregs)(sp)
832 mov %r11,(R11*8+offes_intregs)(sp)
833 mov %r12,(R12*8+offes_intregs)(sp)
834 mov %r13,(R13*8+offes_intregs)(sp)
835 mov %r14,(R14*8+offes_intregs)(sp)
836 mov %r15,(R15*8+offes_intregs)(sp)
838 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
839 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
840 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
841 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
842 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
843 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
844 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
845 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
846 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
847 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
848 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
849 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
850 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
851 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
852 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
853 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
855 /* calculate sp of method */
857 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
858 mov itmp1,(offes_sp)(sp)
860 /* pv must be looked up via AVL tree */
861 movq $0,(offes_pv)(sp)
863 /* call replace_me */
864 mov -8(itmp1),a0 /* rplpoint * */
865 mov sp,a1 /* arg1: execution state */
866 call replace_me@PLT /* call C function replace_me */
867 call abort@PLT /* NEVER REACHED */
869 /* asm_replacement_in **********************************************************
871 This code writes the given execution state and jumps to the replacement
874 This function never returns!
877 void asm_replacement_in(executionstate *es);
879 *******************************************************************************/
882 mov a0,%rbp /* executionstate *es */
885 mov (offes_sp)(%rbp),%rsp
887 /* store address of new code */
888 push (offes_pc)(%rbp)
890 /* copy registers from execution state */
891 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
892 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
893 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
894 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
895 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
896 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
897 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
898 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
899 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
900 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
901 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
902 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
903 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
904 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
905 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
906 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
908 mov (RAX*8+offes_intregs)(%rbp),%rax
909 mov (RBX*8+offes_intregs)(%rbp),%rbx
910 mov (RCX*8+offes_intregs)(%rbp),%rcx
911 mov (RDX*8+offes_intregs)(%rbp),%rdx
912 mov (RSI*8+offes_intregs)(%rbp),%rsi
913 mov (RDI*8+offes_intregs)(%rbp),%rdi
914 mov (R8 *8+offes_intregs)(%rbp),%r8
915 mov (R9 *8+offes_intregs)(%rbp),%r9
916 mov (R10*8+offes_intregs)(%rbp),%r10
917 mov (R11*8+offes_intregs)(%rbp),%r11
918 mov (R12*8+offes_intregs)(%rbp),%r12
919 mov (R13*8+offes_intregs)(%rbp),%r13
920 mov (R14*8+offes_intregs)(%rbp),%r14
921 mov (R15*8+offes_intregs)(%rbp),%r15
923 mov (RBP*8+offes_intregs)(%rbp),%rbp
925 /* jump to new code */
929 /* asm_builtin_x2x *************************************************************
931 * Wrapper functions for float to int corner cases *
933 *******************************************************************************/
938 SAVE_ARGUMENT_REGISTERS(0)
943 RESTORE_ARGUMENT_REGISTERS(0)
952 SAVE_ARGUMENT_REGISTERS(0)
957 RESTORE_ARGUMENT_REGISTERS(0)
966 SAVE_ARGUMENT_REGISTERS(0)
971 RESTORE_ARGUMENT_REGISTERS(0)
980 SAVE_ARGUMENT_REGISTERS(0)
985 RESTORE_ARGUMENT_REGISTERS(0)
992 /* TODO use move here ? */
994 asm_getclassvalues_atomic:
1001 st %r0,offcast_super_baseval(a2)
1002 st %r1,offcast_super_diffval(a2)
1003 st a3,offcast_sub_baseval(a2)
1008 asm_criticalsections:
1009 #if defined(ENABLE_THREADS)
1017 /* Disable exec-stacks, required for Gentoo ***********************************/
1021 #if defined(__GCC__) && defined(__ELF__)
1022 .section .note.GNU-stack,"",@progbits
1029 * These are local overrides for various environment variables in Emacs.
1030 * Please do not remove this and leave it at the end of the file, where
1031 * Emacs will automagically detect them.
1032 * ---------------------------------------------------------------------
1035 * indent-tabs-mode: t
1039 * vim:noexpandtab:sw=4:ts=4: