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 7680 2007-04-10 05:02:20Z pm $
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.
47 /* export functions ***********************************************************/
49 .globl asm_vm_call_method
50 .globl asm_vm_call_method_int
51 .globl asm_vm_call_method_long
52 .globl asm_vm_call_method_float
53 .globl asm_vm_call_method_double
54 .globl asm_vm_call_method_exception_handler
55 .globl asm_vm_call_method_end
57 .globl asm_call_jit_compiler
59 .globl asm_handle_exception
60 .globl asm_handle_nat_exception
62 .globl asm_abstractmethoderror
64 .globl asm_patcher_wrapper
66 .globl asm_replacement_out
67 .globl asm_replacement_in
69 .globl asm_builtin_f2i
70 .globl asm_builtin_f2l
71 .globl asm_builtin_d2i
72 .globl asm_builtin_d2l
74 .globl asm_criticalsections
75 .globl asm_getclassvalues_atomic
78 asm_abstractmethoderror:
93 /********************* function asm_calljavafunction ***************************
95 * This function calls a Java-method (which possibly needs compilation) *
96 * with up to 4 address parameters. *
98 * This functions calls the JIT-compiler which eventually translates the *
99 * method into machine code. *
102 * javaobject_header *asm_calljavamethod (methodinfo *m, *
103 * void *arg1, void *arg2, void *arg3, void *arg4); *
105 *******************************************************************************/
107 .long 0 /* catch type all */
108 .long 0 /* exception handler pc */
110 .long 0 /* start pc */
111 .long 1 /* extable size */
112 .long 0 /* line number table start */
113 .long 0 /* line number table size */
114 .long 0 /* fltsave */
115 .long 0 /* intsave */
118 .long 0 /* frame size */
119 .long 0 /* codeinfo pointer */
122 asm_vm_call_method_int:
123 asm_vm_call_method_long:
124 asm_vm_call_method_float:
125 asm_vm_call_method_double:
130 a1: s4 vmargscount ---> v0: java_objectheader *
134 96 ... on stack parameters (none)
135 0 - 96 register save area
136 -------------------------------------------------- <- SP on asm_vm_... entry
138 saved return address (important to be at 0(sp) because of md_stacktrace_get_returnaddress)
139 ----------------------------------------- <- SP after stack frame allocation
141 ---------------------------------------------------- <- SP on JIT code entry
142 saved return address (callee saved)
149 itmp1: argument block pointer
150 itmp2: argument counter
151 s0: integer argument counter
152 s1: float argument counter
153 s2: integer register counter
154 s3: backup argument block pointer
155 s4: backup argument count
158 stm %r6, %r15, 24(sp) /* save callers regiters */
159 stm a0, a2, 8(sp) /* save arguments */
160 ahi sp, -8 /* allocate stack space for local variables */
161 st %r14, 0(sp) /* store RA once more at bottom of stack frame */
163 ltr a1, a1 /* maybe we have no args... */
166 lr itmp2, a1 /* load arg count */
167 lr itmp1, a2 /* load arg pointer */
169 ahi itmp1, -sizevmarg /* initialize arg pointer */
170 ahi itmp2, 1 /* initialize arg count */
171 lhi s0, 0 /* initialize integer arg counter */
172 lhi s2, 0 /* initialize integer register counter */
173 lhi s1, 0 /* initialize float arg counter */
175 lr s4, a1 /* backup arg count */
176 lr s3, a2 /* backup arg pointer */
180 ahi itmp1, sizevmarg /* forward arg pointer */
181 ahi itmp2, -1 /* decrement arg count */
182 je L_register_copy_done /* no arguments left */
184 tm offvmargtype(itmp1), 0x02 /* is this a float/double type? */
185 jne L_register_handle_float
187 L_register_handle_int:
189 chi s2, INT_ARG_CNT /* are we out of integer arg registers ? */
190 je L_register_copy /* yes, next loop */
192 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
193 jne L_register_handle_long
195 ahi s0, 1 /* increment integer arg counter */
196 ahi s2, 1 /* increment integer register counter */
198 /* handle argument */
211 L_register_handle_long:
213 chi s2, (INT_ARG_CNT - 1) /* are there 2 integer arg registers left ? */
214 jl L_register_handle_long_continue /* yes */
215 lhi s2, INT_ARG_CNT /* no, drop last register */
218 L_register_handle_long_continue:
220 ahi s0, 1 /* increment integer arg counter */
221 ahi s2, 2 /* consume 2 integer arg registers */
223 /* handle argument */
234 L_register_handle_float:
236 chi s1, FLT_ARG_CNT /* are we out of float arg registers */
237 je L_register_copy /* no arg regisers left */
239 ahi s1, 1 /* increment float argument counter */
241 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
242 jne L_register_handle_double
244 /* handle argument */
251 L_register_handle_double:
253 /* handle argument */
260 L_register_copy_done:
264 itmp1: argument block pointer
265 itmp2: argument counter
266 s0: integer argument counter (initialized by previous code)
267 s1: float argument counter (initialized by previous code)
268 s2: pointer to current argument on stack
269 s3: backup argument block pointer (used to initialize itmp1)
270 after used as backup of original stack pointer
271 s4: backup argument count (used to initialize itmp2)
272 after used as size of parameters on stack
275 lr itmp2, s4 /* restore argument counter */
276 lr itmp1, s3 /* restore argument block pointer */
278 /* calculate remaining arguments */
279 sr s4, s0 /* - integer arguments in registers */
280 sr s4, s1 /* - float arguments in registers */
282 lr s3, sp /* backup stack pointer (does not alter CC) */
284 je L_copy_done /* no arguments left for stack */
286 sll s4, 3 /* allocate 8 bytes per parameter on stack */
287 sr sp, s4 /* allocate stack space for arguments */
289 lr s2, sp /* points now to current argument on stack */
291 ahi itmp1, -sizevmarg /* initialize argument block pointer */
292 ahi itmp2, 1 /* initialize argument counter */
296 ahi itmp1, sizevmarg /* forward argument block pointer */
297 ahi itmp2, -1 /* decrement argument counter */
298 je L_copy_done /* all arguments done */
300 tm offvmargtype(itmp1), 0x0 /* is this a float/double type? */
301 jne L_stack_handle_float
305 ahi s0, -1 /* decrement number of integer arguments in regs */
306 jhe L_stack_copy_loop /* argument is in register */
308 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
309 jne L_stack_handle_long
311 mvc 0(4, s2), offvmargdata+4(itmp1) /* copy integer value */
317 mvc 0(8, s2), offvmargdata(itmp1) /* copy long value */
321 L_stack_handle_float:
323 ahi s1, -1 /* decrement number of float arguments in regs */
324 jhe L_stack_copy_loop /* argument is in register */
326 tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
327 jne L_stack_handle_double
329 mvc 0(4, s2), offvmargdata(itmp1) /* copy float value */
333 L_stack_handle_double:
335 mvc 0(8, s2), offvmargdata(itmp1) /* copy double value */
341 /* Now we call the compiler in a rather questionable way i needed
342 * some days to understand:
344 * We can't simply call asm_call_jit_compiler, but we have to call an
345 * address loaded from memory like it is done in JIT code.
347 * This is because the compiler will intercept the instruction before
348 * the call instruction, extract the address where the function pointer
349 * has been loaded from and overwrite it with the code entry.
351 * Arguments are passed in temporary registers.
354 /* load address of L_asm_call_jit_compiler into memory */
356 basr mptr, 0 /* store PC */
358 la mptr, L_asm_call_jit_compiler-L_basr(mptr) /* add offset to PC */
359 st mptr, 4(s3) /* store on stack */
361 l itmp1, 8+8(s3) /* load methodinfo for compiler */
362 la mptr, 4(s3) /* store **function in mptr for compiler */
364 /* call L_asm_call_jit_compiler like JIT code would do */
366 l itmp3, 0(mptr) /* load address of target from memory */
367 basr %r14, itmp3 /* jump to target */
369 /* todo will s4 survive the call? */
370 ar sp, s4 /* remove stack space for arguments */
372 L_asm_vm_call_method_return:
374 ahi sp, 8 /* remove stack space for local variables */
375 lm %r6, %r15, 24(sp) /* restore callers registers */
378 asm_vm_call_method_exception_handler:
381 bras %r14, L_avcmeh_bras
382 .long builtin_throw_exception
389 j L_asm_vm_call_method_return
399 l a0, offvmargdata+4(itmp1)
402 l a1, offvmargdata+4(itmp1)
405 l a2, offvmargdata+4(itmp1)
408 l a3, offvmargdata+4(itmp1)
411 l a4, offvmargdata+4(itmp1)
415 lm a0, a1, offvmargdata(itmp1)
418 lm a1, a2, offvmargdata(itmp1)
421 lm a2, a3, offvmargdata(itmp1)
424 lm a3, a4, offvmargdata(itmp1)
428 le fa0, offvmargdata(itmp1)
431 le fa1, offvmargdata(itmp1)
435 ld fa0, offvmargdata(itmp1)
438 ld fa1, offvmargdata(itmp1)
441 asm_vm_call_method_end:
444 /****************** function asm_call_jit_compiler *****************************
446 * invokes the compiler for untranslated JavaVM methods. *
448 * itmp1: methodinfo pointer *
449 * itmp2: method pointer *
451 *******************************************************************************/
455 argument registers: arguments (like in JIT)
457 arguments on stack (like in JIT)
458 ------------------------------------------------------------- <- SP on entry
460 saved return address \
461 stored volatile (in terms of C ABI) floag argument registers |
462 96 stored volatile (in terms of C ABI) integer argument registers | ACJC_STACKFRAME
463 0 - 96 register save area (C ABI) /
464 -------------------------------------------------- <- SP for jit_asm_compile
467 /* This is called from a compiler stub.
468 * Arguments are already in registers and the stack is setup like in CACAO.
471 asm_call_jit_compiler:
472 L_asm_call_jit_compiler:
474 # define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96)
476 ahi sp,-ACJC_STACKFRAME /* allocate stack space */
478 stm %r2,%r5,96(sp) /* store volatile int arg regs */
479 std %f0,96+16(sp) /* store volatile float arg regs */
481 st %r14,96+32(sp) /* store return address */
485 lr a0,itmp1 /* pass methodinfo pointer */
486 lr a1,itmp2 /* pass method pointer */
487 la a2,ACJC_STACKFRAME(sp) /* pass java sp */
488 la a3,0(%r14) /* pass return address, make sure bit 32 is 0 */
490 /* call jit_asm_compile in a PIC way */
492 bras itmp2, L_bras_jac
493 .long jit_asm_compile
498 lr pv, v0 /* save return value */
500 lm %r2,%r5,96(sp) /* restore volatile int arg regs */
501 ld %f0,96+16(sp) /* restore volatile float arg regs */
502 ld %f2,96+24(sp) /* restore volatile float arg regs */
505 je L_asm_call_jit_compiler_exception
507 l %r14,96+32(sp) /* restore return address */
508 ahi sp, ACJC_STACKFRAME /* remove stack frame */
510 jit_code_entry: /* label to set breakpoint on */
511 br pv /* call the method, it will return to the caller */
514 L_asm_call_jit_compiler_exception:
515 bras itmp2, L_bras_acjce
516 .long exceptions_get_and_clear_exception
521 l xpc,96+32(sp) /* restore return address */
522 ahi sp, ACJC_STACKFRAME /* remove stack frame */
523 j L_asm_handle_nat_exception
527 /* asm_handle_exception ********************************************************
529 * This function handles an exception. It does not use the usual calling *
530 * conventions. The exception pointer is passed in REG_ITMP1 and the *
531 * pc from the exception raising position is passed in REG_ITMP2. It searches *
532 * the local exception table for a handler. If no one is found, it unwinds *
533 * stacks and continues searching the callers. *
535 *******************************************************************************/
539 asm_handle_nat_exception:
540 L_asm_handle_nat_exception:
541 /* TODO really nothing here ? */
542 asm_handle_exception:
543 L_asm_handle_exception: /* required for PIC code */
545 ahi sp, -(ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* create maybe-leaf stackframe */
546 STORE_ARGUMENT_REGISTERS(0)
547 STORE_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
548 lhi a3, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* prepare a3 for handle_exception */
550 lhi %r0, 1 /* set maybe-leaf flag */
552 L_asm_handle_exception_stack_loop:
554 st xptr,0*4(sp) /* save exception pointer */
555 st xpc,1*4(sp) /* save exception pc */
556 la a3,(6*4)(a3,sp) /* calculate Java sp into a3... */
557 st a3,3*4(sp) /* ...and save it */
558 st %r0,4*4(sp) /* save maybe-leaf flag */
560 lr a0,xpc /* exception pc */
562 ahi sp,-96 /* add register save area for C code */
564 bras %r14,L_ahe_bras /* call codegen_get_pv_from_pc */
565 .long codegen_get_pv_from_pc
569 st v0,2*4+96(sp) /* save data segment pointer */
571 lr a2,v0 /* pass data segment pointer */
572 l a0,0*4+96(sp) /* pass exception pointer */
573 l a1,1*4+96(sp) /* pass exception pc */
574 l a3,3*4+96(sp) /* pass Java stack pointer */
576 bras %r14,L_ahe_bras2 /* call exceptions_handle_exception */
577 .long exceptions_handle_exception
582 ahi sp,96 /* remove regiser save area for C code */
585 jz L_asm_handle_exception_not_catched
587 lr xpc,v0 /* move handlerpc into xpc */
588 l xptr,0*4(sp) /* restore exception pointer */
589 l pv,2*4(sp) /* restore PV */
590 l %r0,4*4(sp) /* get maybe-leaf flag */
591 ahi sp,(6*4) /* free stack frame */
594 jz L_asm_handle_exception_no_leaf
596 LOAD_ARGUMENT_REGISTERS(0)
597 LOAD_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
599 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
601 L_asm_handle_exception_no_leaf:
602 br xpc /* jump to the handler */
604 L_asm_handle_exception_not_catched:
605 l xptr,0*4(sp) /* restore exception pointer */
606 l itmp3,2*4(sp) /* restore data segment pointer */
607 ahi itmp3,-0xfff /* for negative displacements */
608 l %r0,4*4(sp) /* get maybe-leaf flag */
612 jz L_asm_handle_exception_no_leaf_stack
614 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
615 lhi %r0,0 /* clear the isleaf flag */
618 +-----------------+-----------+---------+----+
619 | Memuse | Float Sav | Int Sav | RA |
620 | | 0 ... n | 0 ... n | |
621 +-----------------+-----------+---------+----+
629 L_asm_handle_exception_no_leaf_stack:
631 l itmp2,0xfff+FrameSize(itmp3)/* get frame size */
632 la itmp2,0(itmp2,sp) /* pointer to save area (p1) */
633 ahi itmp2,-4 /* skip RA (p2) */
634 ahi itmp2,-0xfff /* for negative displacements */
636 l a0,0xfff+IntSave(itmp3) /* a0 = saved int register count */
651 l s0,0xfff-5*4(itmp2)
653 l s1,0xfff-4*4(itmp2)
655 l s2,0xfff-3*4(itmp2)
657 l s3,0xfff-2*4(itmp2)
659 l s4,0xfff-1*4(itmp2)
663 sll a0,2 /* a0 = saved int register count * 4 */
664 sr itmp2, a0 /* skip Int Sav (p3) */
666 l a0,0xfff+FltSave(itmp3)
667 ltr a0,a0 /* Number of saved floating point registers */
674 ld %f4,0xfff-2*8(itmp2)
676 ld %f6,0xfff-1*8(itmp2)
680 l itmp3,0xfff+FrameSize(itmp3)/* get frame size (at least 4 - RA) */
681 ahi itmp3,-4 /* substract 4 */
682 l xpc,0(itmp3,sp) /* load the new xpc - return address */
683 la sp, 4(itmp3,sp) /* unwind stack */
685 /* exception pointer is still set */
687 sub $3,xpc /* subtract 3 bytes for call */
690 lhi a3,0 /* prepare a3 for handle_exception */
692 j L_asm_handle_exception_stack_loop
697 /* asm_abstractmethoderror *****************************************************
699 Creates and throws an AbstractMethodError.
701 *******************************************************************************/
703 asm_abstractmethoderror:
704 mov sp,a0 /* pass java sp */
706 mov 0*8(sp),a1 /* pass exception address */
708 call exceptions_asm_new_abstractmethoderror@PLT
709 /* exception pointer is return value */
710 pop xpc /* get exception address */
711 sub $3,xpc /* exception address is ra - 3 */
712 jmp L_asm_handle_exception
716 /* asm_patcher_wrapper *********************************************************
721 20 return address into JIT code (patch position)
722 16 pointer to virtual java_objectheader
723 12 machine code (which is patched back later)
724 8 unresolved class/method/field reference
725 4 data segment displacement from load instructions
726 0 patcher function pointer to call (pv afterwards)
728 *******************************************************************************/
731 # define apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
733 ahi sp, -apw_sfs /* create stack frame */
735 /* store all volatile registers and a2, because we will touch it */
738 STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
739 STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
743 la a0, apw_sfs(sp) /* pass SP of patcher stub */
744 lr a1, pv /* pass PV (if NULL, use findmethod) */
745 lhi a2, 0 /* pass RA */
747 /* call patcher_wrapper */
749 bras itmp1, L_apw_bras /* call patcher_wrapper */
750 .long patcher_wrapper
755 /* store return value */
757 st v0,0(sp) /* save return value */
759 /* restore volatile registers */
762 LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
763 LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
765 l itmp3, 0(sp) /* restore return value */
766 ltr itmp3, itmp3 /* exception thrown ? */
767 jne L_asm_patcher_wrapper_exception /* handle exception */
768 l itmp3, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
769 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
770 br itmp3 /* return */
772 L_asm_patcher_wrapper_exception:
773 lr xptr,itmp3 /* get exception */
774 l xpc, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
775 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
776 j L_asm_handle_exception
780 /* asm_replacement_out *********************************************************
782 This code is jumped to from the replacement-out stubs that are executed
783 when a thread reaches an activated replacement point.
785 The purpose of asm_replacement_out is to read out the parts of the
786 execution state that cannot be accessed from C code, store this state,
787 and then call the C function replace_me.
790 8 start of stack inside method to replace
791 0 rplpoint * info on the replacement point that was reached
793 *******************************************************************************/
795 /* some room to accomodate changes of the stack frame size during replacement */
796 /* XXX we should find a cleaner solution here */
797 #define REPLACEMENT_ROOM 512
800 /* create stack frame */
801 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
803 /* save registers in execution state */
804 mov %rax,(RAX*8+offes_intregs)(sp)
805 mov %rbx,(RBX*8+offes_intregs)(sp)
806 mov %rcx,(RCX*8+offes_intregs)(sp)
807 mov %rdx,(RDX*8+offes_intregs)(sp)
808 mov %rsi,(RSI*8+offes_intregs)(sp)
809 mov %rdi,(RDI*8+offes_intregs)(sp)
810 mov %rbp,(RBP*8+offes_intregs)(sp)
811 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
812 mov %r8 ,(R8 *8+offes_intregs)(sp)
813 mov %r9 ,(R9 *8+offes_intregs)(sp)
814 mov %r10,(R10*8+offes_intregs)(sp)
815 mov %r11,(R11*8+offes_intregs)(sp)
816 mov %r12,(R12*8+offes_intregs)(sp)
817 mov %r13,(R13*8+offes_intregs)(sp)
818 mov %r14,(R14*8+offes_intregs)(sp)
819 mov %r15,(R15*8+offes_intregs)(sp)
821 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
822 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
823 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
824 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
825 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
826 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
827 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
828 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
829 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
830 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
831 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
832 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
833 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
834 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
835 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
836 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
838 /* calculate sp of method */
840 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
841 mov itmp1,(offes_sp)(sp)
843 /* pv must be looked up via AVL tree */
844 movq $0,(offes_pv)(sp)
846 /* call replace_me */
847 mov -8(itmp1),a0 /* rplpoint * */
848 mov sp,a1 /* arg1: execution state */
849 call replace_me@PLT /* call C function replace_me */
850 call abort@PLT /* NEVER REACHED */
852 /* asm_replacement_in **********************************************************
854 This code writes the given execution state and jumps to the replacement
857 This function never returns!
860 void asm_replacement_in(executionstate *es);
862 *******************************************************************************/
865 mov a0,%rbp /* executionstate *es */
868 mov (offes_sp)(%rbp),%rsp
870 /* store address of new code */
871 push (offes_pc)(%rbp)
873 /* copy registers from execution state */
874 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
875 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
876 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
877 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
878 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
879 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
880 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
881 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
882 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
883 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
884 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
885 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
886 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
887 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
888 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
889 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
891 mov (RAX*8+offes_intregs)(%rbp),%rax
892 mov (RBX*8+offes_intregs)(%rbp),%rbx
893 mov (RCX*8+offes_intregs)(%rbp),%rcx
894 mov (RDX*8+offes_intregs)(%rbp),%rdx
895 mov (RSI*8+offes_intregs)(%rbp),%rsi
896 mov (RDI*8+offes_intregs)(%rbp),%rdi
897 mov (R8 *8+offes_intregs)(%rbp),%r8
898 mov (R9 *8+offes_intregs)(%rbp),%r9
899 mov (R10*8+offes_intregs)(%rbp),%r10
900 mov (R11*8+offes_intregs)(%rbp),%r11
901 mov (R12*8+offes_intregs)(%rbp),%r12
902 mov (R13*8+offes_intregs)(%rbp),%r13
903 mov (R14*8+offes_intregs)(%rbp),%r14
904 mov (R15*8+offes_intregs)(%rbp),%r15
906 mov (RBP*8+offes_intregs)(%rbp),%rbp
908 /* jump to new code */
912 /* asm_builtin_x2x *************************************************************
914 * Wrapper functions for float to int corner cases *
916 *******************************************************************************/
921 SAVE_ARGUMENT_REGISTERS(0)
926 RESTORE_ARGUMENT_REGISTERS(0)
935 SAVE_ARGUMENT_REGISTERS(0)
940 RESTORE_ARGUMENT_REGISTERS(0)
949 SAVE_ARGUMENT_REGISTERS(0)
954 RESTORE_ARGUMENT_REGISTERS(0)
963 SAVE_ARGUMENT_REGISTERS(0)
968 RESTORE_ARGUMENT_REGISTERS(0)
975 /* TODO use move here ? */
977 asm_getclassvalues_atomic:
984 st %r0,offcast_super_baseval(a2)
985 st %r1,offcast_super_diffval(a2)
986 st a3,offcast_sub_baseval(a2)
991 asm_criticalsections:
992 #if defined(ENABLE_THREADS)
1000 /* disable exec-stacks ********************************************************/
1004 #if defined(__linux__) && defined(__ELF__)
1005 .section .note.GNU-stack,"",%progbits
1012 * These are local overrides for various environment variables in Emacs.
1013 * Please do not remove this and leave it at the end of the file, where
1014 * Emacs will automagically detect them.
1015 * ---------------------------------------------------------------------
1018 * indent-tabs-mode: t
1022 * vim:noexpandtab:sw=4:ts=4: