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 7414 2007-02-28 07:22:04Z 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
418 l a0, offvmargdata+4(itmp1)
421 l a1, offvmargdata+4(itmp1)
424 l a2, offvmargdata+4(itmp1)
427 l a3, offvmargdata+4(itmp1)
430 l a4, offvmargdata+4(itmp1)
434 lm a0, a1, offvmargdata(itmp1)
437 lm a1, a2, offvmargdata(itmp1)
440 lm a2, a3, offvmargdata(itmp1)
443 lm a3, a4, offvmargdata(itmp1)
447 le fa0, offvmargdata(itmp1)
450 le fa1, offvmargdata(itmp1)
454 ld fa0, offvmargdata(itmp1)
457 ld fa1, offvmargdata(itmp1)
461 /****************** function asm_call_jit_compiler *****************************
463 * invokes the compiler for untranslated JavaVM methods. *
465 * itmp1: methodinfo pointer *
466 * itmp2: method pointer *
468 *******************************************************************************/
472 argument registers: arguments (like in JIT)
474 arguments on stack (like in JIT)
475 ------------------------------------------------------------- <- SP on entry
477 saved return address \
478 stored volatile (in terms of C ABI) floag argument registers |
479 96 stored volatile (in terms of C ABI) integer argument registers | ACJC_STACKFRAME
480 0 - 96 register save area (C ABI) /
481 -------------------------------------------------- <- SP for jit_asm_compile
484 /* This is called from a compiler stub.
485 * Arguments are already in registers and the stack is setup like in CACAO.
488 asm_call_jit_compiler:
489 L_asm_call_jit_compiler:
491 # define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96)
493 ahi sp,-ACJC_STACKFRAME /* allocate stack space */
495 stm %r2,%r5,96(sp) /* store volatile int arg regs */
496 std %f0,96+16(sp) /* store volatile float arg regs */
498 st %r14,96+32(sp) /* store return address */
502 lr a0,itmp1 /* pass methodinfo pointer */
503 lr a1,itmp2 /* pass method pointer */
504 la a2,ACJC_STACKFRAME(sp) /* pass java sp */
505 la a3,0(%r14) /* pass return address, make sure bit 32 is 0 */
507 /* call jit_asm_compile in a PIC way */
509 bras itmp2, L_bras_jac
510 .long jit_asm_compile
515 lr pv, v0 /* save return value */
517 lm %r2,%r5,96(sp) /* restore volatile int arg regs */
518 ld %f0,96+16(sp) /* restore volatile float arg regs */
519 ld %f2,96+24(sp) /* restore volatile float arg regs */
522 je L_asm_call_jit_compiler_exception
524 l %r14,96+32(sp) /* restore return address */
525 ahi sp, ACJC_STACKFRAME /* remove stack frame */
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:
532 bras itmp2, L_bras_acjce
533 .long exceptions_get_and_clear_exception
538 l xpc,96+32(sp) /* restore return address */
539 ahi sp, ACJC_STACKFRAME /* remove stack frame */
540 j L_asm_handle_nat_exception
544 /* asm_handle_exception ********************************************************
546 * This function handles an exception. It does not use the usual calling *
547 * conventions. The exception pointer is passed in REG_ITMP1 and the *
548 * pc from the exception raising position is passed in REG_ITMP2. It searches *
549 * the local exception table for a handler. If no one is found, it unwinds *
550 * stacks and continues searching the callers. *
552 *******************************************************************************/
556 asm_handle_nat_exception:
557 L_asm_handle_nat_exception:
558 /* TODO really nothing here ? */
559 asm_handle_exception:
560 L_asm_handle_exception: /* required for PIC code */
562 ahi sp, -(ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* create maybe-leaf stackframe */
563 STORE_ARGUMENT_REGISTERS(0)
564 STORE_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
565 lhi a3, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* prepare a3 for handle_exception */
567 lhi %r0, 1 /* set maybe-leaf flag */
569 L_asm_handle_exception_stack_loop:
571 st xptr,0*4(sp) /* save exception pointer */
572 st xpc,1*4(sp) /* save exception pc */
573 la a3,(6*4)(a3,sp) /* calculate Java sp into a3... */
574 st a3,3*4(sp) /* ...and save it */
575 st %r0,4*4(sp) /* save maybe-leaf flag */
577 lr a0,xpc /* exception pc */
579 ahi sp,-96 /* add register save area for C code */
581 bras %r14,L_ahe_bras /* call codegen_get_pv_from_pc */
582 .long codegen_get_pv_from_pc
586 st v0,2*4+96(sp) /* save data segment pointer */
588 lr a2,v0 /* pass data segment pointer */
589 l a0,0*4+96(sp) /* pass exception pointer */
590 l a1,1*4+96(sp) /* pass exception pc */
591 l a3,3*4+96(sp) /* pass Java stack pointer */
593 bras %r14,L_ahe_bras2 /* call exceptions_handle_exception */
594 .long exceptions_handle_exception
599 ahi sp,96 /* remove regiser save area for C code */
602 jz L_asm_handle_exception_not_catched
604 lr xpc,v0 /* move handlerpc into xpc */
605 l xptr,0*4(sp) /* restore exception pointer */
606 l %r0,4*4(sp) /* get maybe-leaf flag */
607 ahi sp,(6*4) /* free stack frame */
610 jz L_asm_handle_exception_no_leaf
612 LOAD_ARGUMENT_REGISTERS(0)
613 LOAD_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
615 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
617 L_asm_handle_exception_no_leaf:
618 br xpc /* jump to the handler */
620 L_asm_handle_exception_not_catched:
621 l xptr,0*4(sp) /* restore exception pointer */
622 l itmp3,2*4(sp) /* restore data segment pointer */
623 ahi itmp3,-0xfff /* for negative displacements */
624 l %r0,4*4(sp) /* get maybe-leaf flag */
628 jz L_asm_handle_exception_no_leaf_stack
630 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
631 lhi %r0,0 /* clear the isleaf flags */
634 +-----------------+-----------+---------+----+
635 | Memuse | Float Sav | Int Sav | RA |
636 | | 0 ... n | 0 ... n | |
637 +-----------------+-----------+---------+----+
642 L_asm_handle_exception_no_leaf_stack:
644 l itmp2,0xfff+FrameSize(itmp3)/* get frame size */
645 la itmp2,0(itmp2,sp) /* pointer to save area */
646 ahi itmp2,-4 /* skip RA */
648 l a0,0xfff+IntSave(itmp3) /* a0 = saved int register count */
653 sll a0,2 /* a0 = saved int register count * 4 */
654 sr itmp2, a0 /* skip Int Sav */
677 l a0,0xfff+FltSave(itmp3)
678 ltr a0,a0 /* Number of saved floating point registers */
681 sll a0,3 /* Number of saved floating point registers * 8 */
696 l itmp3,0xfff+FrameSize(itmp3)/* get frame size (at least 4 - RA) */
697 ahi itmp3,-4 /* substract 4 */
698 l xpc,0(itmp3,sp) /* load the new xpc - return address */
699 la sp, 4(itmp3,sp) /* unwind stack */
701 /* exception pointer is still set */
703 sub $3,xpc /* subtract 3 bytes for call */
706 lhi a3,0 /* prepare a3 for handle_exception */
708 j L_asm_handle_exception_stack_loop
713 /* asm_abstractmethoderror *****************************************************
715 Creates and throws an AbstractMethodError.
717 *******************************************************************************/
719 asm_abstractmethoderror:
720 mov sp,a0 /* pass java sp */
722 mov 0*8(sp),a1 /* pass exception address */
724 call exceptions_asm_new_abstractmethoderror@PLT
725 /* exception pointer is return value */
726 pop xpc /* get exception address */
727 sub $3,xpc /* exception address is ra - 3 */
728 jmp L_asm_handle_exception
732 /* asm_patcher_wrapper *********************************************************
737 20 return address into JIT code (patch position)
738 16 pointer to virtual java_objectheader
739 12 machine code (which is patched back later)
740 8 unresolved class/method/field reference
741 4 data segment displacement from load instructions
742 0 patcher function pointer to call (pv afterwards)
744 *******************************************************************************/
747 # define apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
749 ahi sp, -apw_sfs /* create stack frame */
751 /* store all volatile registers and a2, because we will touch it */
754 STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
755 STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
759 la a0, apw_sfs(sp) /* pass SP of patcher stub */
760 lr a1, pv /* pass PV (if NULL, use findmethod) */
761 lhi a2, 0 /* pass RA */
763 /* call patcher_wrapper */
765 bras itmp1, L_apw_bras /* call patcher_wrapper */
766 .long patcher_wrapper
771 /* store return value */
773 st v0,0(sp) /* save return value */
775 /* restore volatile registers */
778 LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
779 LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
781 l itmp3, 0(sp) /* restore return value */
782 ltr itmp3, itmp3 /* exception thrown ? */
783 jne L_asm_patcher_wrapper_exception /* handle exception */
784 l itmp3, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
785 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
786 br itmp3 /* return */
788 L_asm_patcher_wrapper_exception:
789 lr xptr,itmp3 /* get exception */
790 l xpc, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
791 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
792 j L_asm_handle_exception
796 /* asm_replacement_out *********************************************************
798 This code is jumped to from the replacement-out stubs that are executed
799 when a thread reaches an activated replacement point.
801 The purpose of asm_replacement_out is to read out the parts of the
802 execution state that cannot be accessed from C code, store this state,
803 and then call the C function replace_me.
806 8 start of stack inside method to replace
807 0 rplpoint * info on the replacement point that was reached
809 *******************************************************************************/
811 /* some room to accomodate changes of the stack frame size during replacement */
812 /* XXX we should find a cleaner solution here */
813 #define REPLACEMENT_ROOM 512
816 /* create stack frame */
817 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
819 /* save registers in execution state */
820 mov %rax,(RAX*8+offes_intregs)(sp)
821 mov %rbx,(RBX*8+offes_intregs)(sp)
822 mov %rcx,(RCX*8+offes_intregs)(sp)
823 mov %rdx,(RDX*8+offes_intregs)(sp)
824 mov %rsi,(RSI*8+offes_intregs)(sp)
825 mov %rdi,(RDI*8+offes_intregs)(sp)
826 mov %rbp,(RBP*8+offes_intregs)(sp)
827 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
828 mov %r8 ,(R8 *8+offes_intregs)(sp)
829 mov %r9 ,(R9 *8+offes_intregs)(sp)
830 mov %r10,(R10*8+offes_intregs)(sp)
831 mov %r11,(R11*8+offes_intregs)(sp)
832 mov %r12,(R12*8+offes_intregs)(sp)
833 mov %r13,(R13*8+offes_intregs)(sp)
834 mov %r14,(R14*8+offes_intregs)(sp)
835 mov %r15,(R15*8+offes_intregs)(sp)
837 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
838 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
839 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
840 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
841 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
842 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
843 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
844 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
845 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
846 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
847 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
848 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
849 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
850 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
851 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
852 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
854 /* calculate sp of method */
856 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
857 mov itmp1,(offes_sp)(sp)
859 /* pv must be looked up via AVL tree */
860 movq $0,(offes_pv)(sp)
862 /* call replace_me */
863 mov -8(itmp1),a0 /* rplpoint * */
864 mov sp,a1 /* arg1: execution state */
865 call replace_me@PLT /* call C function replace_me */
866 call abort@PLT /* NEVER REACHED */
868 /* asm_replacement_in **********************************************************
870 This code writes the given execution state and jumps to the replacement
873 This function never returns!
876 void asm_replacement_in(executionstate *es);
878 *******************************************************************************/
881 mov a0,%rbp /* executionstate *es */
884 mov (offes_sp)(%rbp),%rsp
886 /* store address of new code */
887 push (offes_pc)(%rbp)
889 /* copy registers from execution state */
890 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
891 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
892 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
893 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
894 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
895 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
896 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
897 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
898 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
899 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
900 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
901 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
902 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
903 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
904 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
905 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
907 mov (RAX*8+offes_intregs)(%rbp),%rax
908 mov (RBX*8+offes_intregs)(%rbp),%rbx
909 mov (RCX*8+offes_intregs)(%rbp),%rcx
910 mov (RDX*8+offes_intregs)(%rbp),%rdx
911 mov (RSI*8+offes_intregs)(%rbp),%rsi
912 mov (RDI*8+offes_intregs)(%rbp),%rdi
913 mov (R8 *8+offes_intregs)(%rbp),%r8
914 mov (R9 *8+offes_intregs)(%rbp),%r9
915 mov (R10*8+offes_intregs)(%rbp),%r10
916 mov (R11*8+offes_intregs)(%rbp),%r11
917 mov (R12*8+offes_intregs)(%rbp),%r12
918 mov (R13*8+offes_intregs)(%rbp),%r13
919 mov (R14*8+offes_intregs)(%rbp),%r14
920 mov (R15*8+offes_intregs)(%rbp),%r15
922 mov (RBP*8+offes_intregs)(%rbp),%rbp
924 /* jump to new code */
928 /* asm_builtin_x2x *************************************************************
930 * Wrapper functions for float to int corner cases *
932 *******************************************************************************/
937 SAVE_ARGUMENT_REGISTERS(0)
942 RESTORE_ARGUMENT_REGISTERS(0)
951 SAVE_ARGUMENT_REGISTERS(0)
956 RESTORE_ARGUMENT_REGISTERS(0)
965 SAVE_ARGUMENT_REGISTERS(0)
970 RESTORE_ARGUMENT_REGISTERS(0)
979 SAVE_ARGUMENT_REGISTERS(0)
984 RESTORE_ARGUMENT_REGISTERS(0)
991 /* TODO use move here ? */
993 asm_getclassvalues_atomic:
1000 st %r0,offcast_super_baseval(a2)
1001 st %r1,offcast_super_diffval(a2)
1002 st a3,offcast_sub_baseval(a2)
1007 asm_criticalsections:
1008 #if defined(ENABLE_THREADS)
1016 /* Disable exec-stacks, required for Gentoo ***********************************/
1020 #if defined(__GCC__) && defined(__ELF__)
1021 .section .note.GNU-stack,"",@progbits
1028 * These are local overrides for various environment variables in Emacs.
1029 * Please do not remove this and leave it at the end of the file, where
1030 * Emacs will automagically detect them.
1031 * ---------------------------------------------------------------------
1034 * indent-tabs-mode: t
1038 * vim:noexpandtab:sw=4:ts=4: