1 /* src/vm/jit/s390/asmpart.S - Java-C interface functions for s390
3 Copyright (C) 2006, 2007 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 $Id: asmpart.S 7678 2007-04-09 17:23:55Z twisti $
32 #include "vm/jit/s390/arch.h"
33 #include "vm/jit/s390/md-abi.h"
34 #include "vm/jit/s390/md-asm.h"
35 #include "vm/jit/s390/offsets.h"
37 #include "vm/jit/abi-asm.h"
38 #include "vm/jit/methodheader.h"
40 /* Copy a call to a PIC function from gcc -S
41 * We setup a temporary literal pool pointer.
44 #define PIC_CALL(fun, magic) \
45 bras itmp3, L_##magic##_lp_end ; \
50 .long _GLOBAL_OFFSET_TABLE_-L_##magic##_lp ; \
51 L_##magic##_lp_end: ; \
52 l itmp2,L_##magic##_lp_4-L_##magic##_lp(itmp3) ; \
53 la itmp2,0(itmp2,itmp3) ; \
54 l itmp1,L_##magic##_lp_5-L_##magic##_lp(itmp3) ; \
55 bas %r14,0(itmp1,itmp2)
60 /* export functions ***********************************************************/
62 .globl asm_vm_call_method
63 .globl asm_vm_call_method_int
64 .globl asm_vm_call_method_long
65 .globl asm_vm_call_method_float
66 .globl asm_vm_call_method_double
67 .globl asm_vm_call_method_exception_handler
68 .globl asm_vm_call_method_end
70 .globl asm_call_jit_compiler
72 .globl asm_handle_exception
73 .globl asm_handle_nat_exception
75 .globl asm_abstractmethoderror
77 .globl asm_patcher_wrapper
79 .globl asm_replacement_out
80 .globl asm_replacement_in
82 .globl asm_builtin_f2i
83 .globl asm_builtin_f2l
84 .globl asm_builtin_d2i
85 .globl asm_builtin_d2l
87 .globl asm_criticalsections
88 .globl asm_getclassvalues_atomic
91 asm_abstractmethoderror:
106 /********************* function asm_calljavafunction ***************************
108 * This function calls a Java-method (which possibly needs compilation) *
109 * with up to 4 address parameters. *
111 * This functions calls the JIT-compiler which eventually translates the *
112 * method into machine code. *
115 * javaobject_header *asm_calljavamethod (methodinfo *m, *
116 * void *arg1, void *arg2, void *arg3, void *arg4); *
118 *******************************************************************************/
120 .long 0 /* catch type all */
121 .long 0 /* exception handler pc */
123 .long 0 /* start pc */
124 .long 1 /* extable size */
125 .long 0 /* line number table start */
126 .long 0 /* line number table size */
127 .long 0 /* fltsave */
128 .long 0 /* intsave */
131 .long 0 /* frame size */
132 .long 0 /* codeinfo pointer */
135 asm_vm_call_method_int:
136 asm_vm_call_method_long:
137 asm_vm_call_method_float:
138 asm_vm_call_method_double:
143 a1: s4 vmargscount ---> v0: java_objectheader *
147 96 ... on stack parameters (none)
148 0 - 96 register save area
149 -------------------------------------------------- <- SP on asm_vm_... entry
151 saved return address (important to be at 0(sp) because of md_stacktrace_get_returnaddress)
152 ----------------------------------------- <- SP after stack frame allocation
154 ---------------------------------------------------- <- SP on JIT code entry
155 saved return address (callee saved)
162 itmp1: argument block pointer
163 itmp2: argument counter
164 s0: integer argument counter
165 s1: float argument counter
166 s2: integer register counter
167 s3: backup argument block pointer
168 s4: backup argument count
171 stm %r6, %r15, 24(sp) /* save callers regiters */
172 stm a0, a2, 8(sp) /* save arguments */
173 ahi sp, -8 /* allocate stack space for local variables */
174 st %r14, 0(sp) /* store RA once more at bottom of stack frame */
176 ltr a1, a1 /* maybe we have no args... */
179 lr itmp2, a1 /* load arg count */
180 lr itmp1, a2 /* load arg pointer */
182 ahi itmp1, -sizevmarg /* initialize arg pointer */
183 ahi itmp2, 1 /* initialize arg count */
184 lhi s0, 0 /* initialize integer arg counter */
185 lhi s2, 0 /* initialize integer register counter */
186 lhi s1, 0 /* initialize float arg counter */
188 lr s4, a1 /* backup arg count */
189 lr s3, a2 /* backup arg pointer */
193 ahi itmp1, sizevmarg /* forward arg pointer */
194 ahi itmp2, -1 /* decrement arg count */
195 je L_register_copy_done /* no arguments left */
197 tm offvmargtype(itmp1), 0x02 /* is this a float/double type? */
198 jne L_register_handle_float
200 L_register_handle_int:
202 chi s2, INT_ARG_CNT /* are we out of integer arg registers ? */
203 je L_register_copy /* yes, next loop */
205 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
206 jne L_register_handle_long
208 ahi s0, 1 /* increment integer arg counter */
209 ahi s2, 1 /* increment integer register counter */
211 /* handle argument */
224 L_register_handle_long:
226 chi s2, (INT_ARG_CNT - 1) /* are there 2 integer arg registers left ? */
227 jl L_register_handle_long_continue /* yes */
228 lhi s2, INT_ARG_CNT /* no, drop last register */
231 L_register_handle_long_continue:
233 ahi s0, 1 /* increment integer arg counter */
234 ahi s2, 2 /* consume 2 integer arg registers */
236 /* handle argument */
247 L_register_handle_float:
249 chi s1, FLT_ARG_CNT /* are we out of float arg registers */
250 je L_register_copy /* no arg regisers left */
252 ahi s1, 1 /* increment float argument counter */
254 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
255 jne L_register_handle_double
257 /* handle argument */
264 L_register_handle_double:
266 /* handle argument */
273 L_register_copy_done:
277 itmp1: argument block pointer
278 itmp2: argument counter
279 s0: integer argument counter (initialized by previous code)
280 s1: float argument counter (initialized by previous code)
281 s2: pointer to current argument on stack
282 s3: backup argument block pointer (used to initialize itmp1)
283 after used as backup of original stack pointer
284 s4: backup argument count (used to initialize itmp2)
285 after used as size of parameters on stack
288 lr itmp2, s4 /* restore argument counter */
289 lr itmp1, s3 /* restore argument block pointer */
291 /* calculate remaining arguments */
292 sr s4, s0 /* - integer arguments in registers */
293 sr s4, s1 /* - float arguments in registers */
295 lr s3, sp /* backup stack pointer (does not alter CC) */
297 je L_copy_done /* no arguments left for stack */
299 sll s4, 3 /* allocate 8 bytes per parameter on stack */
300 sr sp, s4 /* allocate stack space for arguments */
302 lr s2, sp /* points now to current argument on stack */
304 ahi itmp1, -sizevmarg /* initialize argument block pointer */
305 ahi itmp2, 1 /* initialize argument counter */
309 ahi itmp1, sizevmarg /* forward argument block pointer */
310 ahi itmp2, -1 /* decrement argument counter */
311 je L_copy_done /* all arguments done */
313 tm offvmargtype(itmp1), 0x0 /* is this a float/double type? */
314 jne L_stack_handle_float
318 ahi s0, -1 /* decrement number of integer arguments in regs */
319 jhe L_stack_copy_loop /* argument is in register */
321 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
322 jne L_stack_handle_long
324 mvc 0(4, s2), offvmargdata+4(itmp1) /* copy integer value */
330 mvc 0(8, s2), offvmargdata(itmp1) /* copy long value */
334 L_stack_handle_float:
336 ahi s1, -1 /* decrement number of float arguments in regs */
337 jhe L_stack_copy_loop /* argument is in register */
339 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
340 jne L_stack_handle_double
342 mvc 0(4, s2), offvmargdata(itmp1) /* copy float value */
346 L_stack_handle_double:
348 mvc 0(8, s2), offvmargdata(itmp1) /* copy double value */
354 /* Now we call the compiler in a rather questionable way i needed
355 * some days to understand:
357 * We can't simply call asm_call_jit_compiler, but we have to call an
358 * address loaded from memory like it is done in JIT code.
360 * This is because the compiler will intercept the instruction before
361 * the call instruction, extract the address where the function pointer
362 * has been loaded from and overwrite it with the code entry.
364 * Arguments are passed in temporary registers.
367 /* load address of L_asm_call_jit_compiler into memory */
369 basr mptr, 0 /* store PC */
371 la mptr, L_asm_call_jit_compiler-L_basr(mptr) /* add offset to PC */
372 st mptr, 4(s3) /* store on stack */
374 l itmp1, 8+8(s3) /* load methodinfo for compiler */
375 la mptr, 4(s3) /* store **function in mptr for compiler */
377 /* call L_asm_call_jit_compiler like JIT code would do */
379 l itmp3, 0(mptr) /* load address of target from memory */
380 basr %r14, itmp3 /* jump to target */
382 /* todo will s4 survive the call? */
383 ar sp, s4 /* remove stack space for arguments */
385 L_asm_vm_call_method_return:
387 ahi sp, 8 /* remove stack space for local variables */
388 lm %r6, %r15, 24(sp) /* restore callers registers */
391 asm_vm_call_method_exception_handler:
394 bras %r14, L_avcmeh_bras
395 .long builtin_throw_exception
402 j L_asm_vm_call_method_return
412 l a0, offvmargdata+4(itmp1)
415 l a1, offvmargdata+4(itmp1)
418 l a2, offvmargdata+4(itmp1)
421 l a3, offvmargdata+4(itmp1)
424 l a4, offvmargdata+4(itmp1)
428 lm a0, a1, offvmargdata(itmp1)
431 lm a1, a2, offvmargdata(itmp1)
434 lm a2, a3, offvmargdata(itmp1)
437 lm a3, a4, offvmargdata(itmp1)
441 le fa0, offvmargdata(itmp1)
444 le fa1, offvmargdata(itmp1)
448 ld fa0, offvmargdata(itmp1)
451 ld fa1, offvmargdata(itmp1)
454 asm_vm_call_method_end:
457 /****************** function asm_call_jit_compiler *****************************
459 * invokes the compiler for untranslated JavaVM methods. *
461 * itmp1: methodinfo pointer *
462 * itmp2: method pointer *
464 *******************************************************************************/
468 argument registers: arguments (like in JIT)
470 arguments on stack (like in JIT)
471 ------------------------------------------------------------- <- SP on entry
473 saved return address \
474 stored volatile (in terms of C ABI) floag argument registers |
475 96 stored volatile (in terms of C ABI) integer argument registers | ACJC_STACKFRAME
476 0 - 96 register save area (C ABI) /
477 -------------------------------------------------- <- SP for jit_asm_compile
480 /* This is called from a compiler stub.
481 * Arguments are already in registers and the stack is setup like in CACAO.
484 asm_call_jit_compiler:
485 L_asm_call_jit_compiler:
487 # define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96)
489 ahi sp,-ACJC_STACKFRAME /* allocate stack space */
491 stm %r2,%r5,96(sp) /* store volatile int arg regs */
492 std %f0,96+16(sp) /* store volatile float arg regs */
494 st %r14,96+32(sp) /* store return address */
498 lr a0,itmp1 /* pass methodinfo pointer */
499 lr a1,itmp2 /* pass method pointer */
500 la a2,ACJC_STACKFRAME(sp) /* pass java sp */
501 la a3,0(%r14) /* pass return address, make sure bit 32 is 0 */
503 /* call jit_asm_compile in a PIC way */
505 bras itmp2, L_bras_jac
506 .long jit_asm_compile
511 lr pv, v0 /* save return value */
513 lm %r2,%r5,96(sp) /* restore volatile int arg regs */
514 ld %f0,96+16(sp) /* restore volatile float arg regs */
515 ld %f2,96+24(sp) /* restore volatile float arg regs */
518 je L_asm_call_jit_compiler_exception
520 l %r14,96+32(sp) /* restore return address */
521 ahi sp, ACJC_STACKFRAME /* remove stack frame */
523 jit_code_entry: /* label to set breakpoint on */
524 br pv /* call the method, it will return to the caller */
527 L_asm_call_jit_compiler_exception:
528 bras itmp2, L_bras_acjce
529 .long exceptions_get_and_clear_exception
534 l xpc,96+32(sp) /* restore return address */
535 ahi sp, ACJC_STACKFRAME /* remove stack frame */
536 j L_asm_handle_nat_exception
540 /* asm_handle_exception ********************************************************
542 * This function handles an exception. It does not use the usual calling *
543 * conventions. The exception pointer is passed in REG_ITMP1 and the *
544 * pc from the exception raising position is passed in REG_ITMP2. It searches *
545 * the local exception table for a handler. If no one is found, it unwinds *
546 * stacks and continues searching the callers. *
548 *******************************************************************************/
552 asm_handle_nat_exception:
553 L_asm_handle_nat_exception:
554 /* TODO really nothing here ? */
555 asm_handle_exception:
556 L_asm_handle_exception: /* required for PIC code */
558 ahi sp, -(ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* create maybe-leaf stackframe */
559 STORE_ARGUMENT_REGISTERS(0)
560 STORE_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
561 lhi a3, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* prepare a3 for handle_exception */
563 lhi %r0, 1 /* set maybe-leaf flag */
565 L_asm_handle_exception_stack_loop:
567 st xptr,0*4(sp) /* save exception pointer */
568 st xpc,1*4(sp) /* save exception pc */
569 la a3,(6*4)(a3,sp) /* calculate Java sp into a3... */
570 st a3,3*4(sp) /* ...and save it */
571 st %r0,4*4(sp) /* save maybe-leaf flag */
573 lr a0,xpc /* exception pc */
575 ahi sp,-96 /* add register save area for C code */
577 bras %r14,L_ahe_bras /* call codegen_get_pv_from_pc */
578 .long codegen_get_pv_from_pc
582 st v0,2*4+96(sp) /* save data segment pointer */
584 lr a2,v0 /* pass data segment pointer */
585 l a0,0*4+96(sp) /* pass exception pointer */
586 l a1,1*4+96(sp) /* pass exception pc */
587 l a3,3*4+96(sp) /* pass Java stack pointer */
589 bras %r14,L_ahe_bras2 /* call exceptions_handle_exception */
590 .long exceptions_handle_exception
595 ahi sp,96 /* remove regiser save area for C code */
598 jz L_asm_handle_exception_not_catched
600 lr xpc,v0 /* move handlerpc into xpc */
601 l xptr,0*4(sp) /* restore exception pointer */
602 l %r0,4*4(sp) /* get maybe-leaf flag */
603 ahi sp,(6*4) /* free stack frame */
606 jz L_asm_handle_exception_no_leaf
608 LOAD_ARGUMENT_REGISTERS(0)
609 LOAD_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
611 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
613 L_asm_handle_exception_no_leaf:
614 br xpc /* jump to the handler */
616 L_asm_handle_exception_not_catched:
617 l xptr,0*4(sp) /* restore exception pointer */
618 l itmp3,2*4(sp) /* restore data segment pointer */
619 ahi itmp3,-0xfff /* for negative displacements */
620 l %r0,4*4(sp) /* get maybe-leaf flag */
624 jz L_asm_handle_exception_no_leaf_stack
626 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
627 lhi %r0,0 /* clear the isleaf flags */
630 +-----------------+-----------+---------+----+
631 | Memuse | Float Sav | Int Sav | RA |
632 | | 0 ... n | 0 ... n | |
633 +-----------------+-----------+---------+----+
638 L_asm_handle_exception_no_leaf_stack:
640 l itmp2,0xfff+FrameSize(itmp3)/* get frame size */
641 la itmp2,0(itmp2,sp) /* pointer to save area */
642 ahi itmp2,-4 /* skip RA */
644 l a0,0xfff+IntSave(itmp3) /* a0 = saved int register count */
649 sll a0,2 /* a0 = saved int register count * 4 */
650 sr itmp2, a0 /* skip Int Sav */
673 l a0,0xfff+FltSave(itmp3)
674 ltr a0,a0 /* Number of saved floating point registers */
677 sll a0,3 /* Number of saved floating point registers * 8 */
692 l itmp3,0xfff+FrameSize(itmp3)/* get frame size (at least 4 - RA) */
693 ahi itmp3,-4 /* substract 4 */
694 l xpc,0(itmp3,sp) /* load the new xpc - return address */
695 la sp, 4(itmp3,sp) /* unwind stack */
697 /* exception pointer is still set */
699 sub $3,xpc /* subtract 3 bytes for call */
702 lhi a3,0 /* prepare a3 for handle_exception */
704 j L_asm_handle_exception_stack_loop
709 /* asm_abstractmethoderror *****************************************************
711 Creates and throws an AbstractMethodError.
713 *******************************************************************************/
715 asm_abstractmethoderror:
716 mov sp,a0 /* pass java sp */
718 mov 0*8(sp),a1 /* pass exception address */
720 call exceptions_asm_new_abstractmethoderror@PLT
721 /* exception pointer is return value */
722 pop xpc /* get exception address */
723 sub $3,xpc /* exception address is ra - 3 */
724 jmp L_asm_handle_exception
728 /* asm_patcher_wrapper *********************************************************
733 20 return address into JIT code (patch position)
734 16 pointer to virtual java_objectheader
735 12 machine code (which is patched back later)
736 8 unresolved class/method/field reference
737 4 data segment displacement from load instructions
738 0 patcher function pointer to call (pv afterwards)
740 *******************************************************************************/
743 # define apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
745 ahi sp, -apw_sfs /* create stack frame */
747 /* store all volatile registers and a2, because we will touch it */
750 STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
751 STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
755 la a0, apw_sfs(sp) /* pass SP of patcher stub */
756 lr a1, pv /* pass PV (if NULL, use findmethod) */
757 lhi a2, 0 /* pass RA */
759 /* call patcher_wrapper */
761 bras itmp1, L_apw_bras /* call patcher_wrapper */
762 .long patcher_wrapper
767 /* store return value */
769 st v0,0(sp) /* save return value */
771 /* restore volatile registers */
774 LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
775 LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
777 l itmp3, 0(sp) /* restore return value */
778 ltr itmp3, itmp3 /* exception thrown ? */
779 jne L_asm_patcher_wrapper_exception /* handle exception */
780 l itmp3, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
781 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
782 br itmp3 /* return */
784 L_asm_patcher_wrapper_exception:
785 lr xptr,itmp3 /* get exception */
786 l xpc, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
787 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
788 j L_asm_handle_exception
792 /* asm_replacement_out *********************************************************
794 This code is jumped to from the replacement-out stubs that are executed
795 when a thread reaches an activated replacement point.
797 The purpose of asm_replacement_out is to read out the parts of the
798 execution state that cannot be accessed from C code, store this state,
799 and then call the C function replace_me.
802 8 start of stack inside method to replace
803 0 rplpoint * info on the replacement point that was reached
805 *******************************************************************************/
807 /* some room to accomodate changes of the stack frame size during replacement */
808 /* XXX we should find a cleaner solution here */
809 #define REPLACEMENT_ROOM 512
812 /* create stack frame */
813 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
815 /* save registers in execution state */
816 mov %rax,(RAX*8+offes_intregs)(sp)
817 mov %rbx,(RBX*8+offes_intregs)(sp)
818 mov %rcx,(RCX*8+offes_intregs)(sp)
819 mov %rdx,(RDX*8+offes_intregs)(sp)
820 mov %rsi,(RSI*8+offes_intregs)(sp)
821 mov %rdi,(RDI*8+offes_intregs)(sp)
822 mov %rbp,(RBP*8+offes_intregs)(sp)
823 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
824 mov %r8 ,(R8 *8+offes_intregs)(sp)
825 mov %r9 ,(R9 *8+offes_intregs)(sp)
826 mov %r10,(R10*8+offes_intregs)(sp)
827 mov %r11,(R11*8+offes_intregs)(sp)
828 mov %r12,(R12*8+offes_intregs)(sp)
829 mov %r13,(R13*8+offes_intregs)(sp)
830 mov %r14,(R14*8+offes_intregs)(sp)
831 mov %r15,(R15*8+offes_intregs)(sp)
833 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
834 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
835 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
836 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
837 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
838 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
839 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
840 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
841 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
842 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
843 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
844 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
845 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
846 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
847 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
848 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
850 /* calculate sp of method */
852 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
853 mov itmp1,(offes_sp)(sp)
855 /* pv must be looked up via AVL tree */
856 movq $0,(offes_pv)(sp)
858 /* call replace_me */
859 mov -8(itmp1),a0 /* rplpoint * */
860 mov sp,a1 /* arg1: execution state */
861 call replace_me@PLT /* call C function replace_me */
862 call abort@PLT /* NEVER REACHED */
864 /* asm_replacement_in **********************************************************
866 This code writes the given execution state and jumps to the replacement
869 This function never returns!
872 void asm_replacement_in(executionstate *es);
874 *******************************************************************************/
877 mov a0,%rbp /* executionstate *es */
880 mov (offes_sp)(%rbp),%rsp
882 /* store address of new code */
883 push (offes_pc)(%rbp)
885 /* copy registers from execution state */
886 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
887 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
888 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
889 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
890 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
891 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
892 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
893 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
894 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
895 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
896 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
897 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
898 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
899 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
900 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
901 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
903 mov (RAX*8+offes_intregs)(%rbp),%rax
904 mov (RBX*8+offes_intregs)(%rbp),%rbx
905 mov (RCX*8+offes_intregs)(%rbp),%rcx
906 mov (RDX*8+offes_intregs)(%rbp),%rdx
907 mov (RSI*8+offes_intregs)(%rbp),%rsi
908 mov (RDI*8+offes_intregs)(%rbp),%rdi
909 mov (R8 *8+offes_intregs)(%rbp),%r8
910 mov (R9 *8+offes_intregs)(%rbp),%r9
911 mov (R10*8+offes_intregs)(%rbp),%r10
912 mov (R11*8+offes_intregs)(%rbp),%r11
913 mov (R12*8+offes_intregs)(%rbp),%r12
914 mov (R13*8+offes_intregs)(%rbp),%r13
915 mov (R14*8+offes_intregs)(%rbp),%r14
916 mov (R15*8+offes_intregs)(%rbp),%r15
918 mov (RBP*8+offes_intregs)(%rbp),%rbp
920 /* jump to new code */
924 /* asm_builtin_x2x *************************************************************
926 * Wrapper functions for float to int corner cases *
928 *******************************************************************************/
933 SAVE_ARGUMENT_REGISTERS(0)
938 RESTORE_ARGUMENT_REGISTERS(0)
947 SAVE_ARGUMENT_REGISTERS(0)
952 RESTORE_ARGUMENT_REGISTERS(0)
961 SAVE_ARGUMENT_REGISTERS(0)
966 RESTORE_ARGUMENT_REGISTERS(0)
975 SAVE_ARGUMENT_REGISTERS(0)
980 RESTORE_ARGUMENT_REGISTERS(0)
987 /* TODO use move here ? */
989 asm_getclassvalues_atomic:
996 st %r0,offcast_super_baseval(a2)
997 st %r1,offcast_super_diffval(a2)
998 st a3,offcast_sub_baseval(a2)
1003 asm_criticalsections:
1004 #if defined(ENABLE_THREADS)
1012 /* disable exec-stacks ********************************************************/
1016 #if defined(__linux__) && defined(__ELF__)
1017 .section .note.GNU-stack,"",%progbits
1024 * These are local overrides for various environment variables in Emacs.
1025 * Please do not remove this and leave it at the end of the file, where
1026 * Emacs will automagically detect them.
1027 * ---------------------------------------------------------------------
1030 * indent-tabs-mode: t
1034 * vim:noexpandtab:sw=4:ts=4: