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 7839 2007-04-29 22:46:56Z 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"
43 /* export functions ***********************************************************/
45 .globl asm_vm_call_method
46 .globl asm_vm_call_method_int
47 .globl asm_vm_call_method_long
48 .globl asm_vm_call_method_float
49 .globl asm_vm_call_method_double
50 .globl asm_vm_call_method_exception_handler
51 .globl asm_vm_call_method_end
53 .globl asm_call_jit_compiler
55 .globl asm_handle_exception
56 .globl asm_handle_nat_exception
58 .globl asm_abstractmethoderror
60 .globl asm_patcher_wrapper
62 .globl asm_replacement_out
63 .globl asm_replacement_in
65 .globl asm_builtin_f2i
66 .globl asm_builtin_f2l
67 .globl asm_builtin_d2i
68 .globl asm_builtin_d2l
70 .globl asm_criticalsections
71 .globl asm_getclassvalues_atomic
74 asm_abstractmethoderror:
89 /********************* function asm_calljavafunction ***************************
91 * This function calls a Java-method (which possibly needs compilation) *
92 * with up to 4 address parameters. *
94 * This functions calls the JIT-compiler which eventually translates the *
95 * method into machine code. *
98 * javaobject_header *asm_calljavamethod (methodinfo *m, *
99 * void *arg1, void *arg2, void *arg3, void *arg4); *
101 *******************************************************************************/
103 .long 0 /* catch type all */
104 .long 0 /* exception handler pc */
106 .long 0 /* start pc */
107 .long 1 /* extable size */
108 .long 0 /* line number table start */
109 .long 0 /* line number table size */
110 .long 0 /* fltsave */
111 .long 0 /* intsave */
114 .long 0 /* frame size */
115 .long 0 /* codeinfo pointer */
118 asm_vm_call_method_int:
119 asm_vm_call_method_long:
120 asm_vm_call_method_float:
121 asm_vm_call_method_double:
126 a1: s4 vmargscount ---> v0: java_objectheader *
130 96 ... on stack parameters (none)
131 0 - 96 register save area
132 -------------------------------------------------- <- SP on asm_vm_... entry
134 saved return address (important to be at 0(sp) because of md_stacktrace_get_returnaddress)
135 ----------------------------------------- <- SP after stack frame allocation
137 ---------------------------------------------------- <- SP on JIT code entry
138 saved return address (callee saved)
145 itmp1: argument block pointer
146 itmp2: argument counter
147 s0: integer argument counter
148 s1: float argument counter
149 s2: integer register counter
150 s3: backup argument block pointer
151 s4: backup argument count
154 stm %r6, %r15, 24(sp) /* save callers regiters */
155 stm a0, a2, 8(sp) /* save arguments */
156 ahi sp, -8 /* allocate stack space for local variables */
157 st %r14, 0(sp) /* store RA once more at bottom of stack frame */
159 ltr a1, a1 /* maybe we have no args... */
162 lr itmp2, a1 /* load arg count */
163 lr itmp1, a2 /* load arg pointer */
165 ahi itmp1, -sizevmarg /* initialize arg pointer */
166 ahi itmp2, 1 /* initialize arg count */
167 lhi s0, 0 /* initialize integer arg counter */
168 lhi s2, 0 /* initialize integer register counter */
169 lhi s1, 0 /* initialize float arg counter */
171 lr s4, a1 /* backup arg count */
172 lr s3, a2 /* backup arg pointer */
176 ahi itmp1, sizevmarg /* forward arg pointer */
177 ahi itmp2, -1 /* decrement arg count */
178 je L_register_copy_done /* no arguments left */
180 tm offvmargtype+7(itmp1), 0x02 /* is this a float/double type? */
181 jne L_register_handle_float
183 L_register_handle_int:
185 chi s2, INT_ARG_CNT /* are we out of integer arg registers ? */
186 je L_register_copy /* yes, next loop */
188 tm offvmargtype+7(itmp1), 0x01 /* is this a 2 word type ? */
189 jne L_register_handle_long
191 ahi s0, 1 /* increment integer arg counter */
192 ahi s2, 1 /* increment integer register counter */
194 /* handle argument */
207 L_register_handle_long:
209 chi s2, (INT_ARG_CNT - 1) /* are there 2 integer arg registers left ? */
210 jl L_register_handle_long_continue /* yes */
211 lhi s2, INT_ARG_CNT /* no, drop last register */
214 L_register_handle_long_continue:
216 ahi s0, 1 /* increment integer arg counter */
217 ahi s2, 2 /* consume 2 integer arg registers */
219 /* handle argument */
230 L_register_handle_float:
232 chi s1, FLT_ARG_CNT /* are we out of float arg registers */
233 je L_register_copy /* no arg regisers left */
235 ahi s1, 1 /* increment float argument counter */
237 tm offvmargtype+7(itmp1), 0x01 /* is this a 2 word type ? */
238 jne L_register_handle_double
240 /* handle argument */
247 L_register_handle_double:
249 /* handle argument */
256 L_register_copy_done:
260 itmp1: argument block pointer
261 itmp2: argument counter
262 s0: integer argument counter (initialized by previous code)
263 s1: float argument counter (initialized by previous code)
264 s2: pointer to current argument on stack
265 s3: backup argument block pointer (used to initialize itmp1)
266 after used as backup of original stack pointer
267 s4: backup argument count (used to initialize itmp2)
268 after used as size of parameters on stack
271 lr itmp2, s4 /* restore argument counter */
272 lr itmp1, s3 /* restore argument block pointer */
274 /* calculate remaining arguments */
275 sr s4, s0 /* - integer arguments in registers */
276 sr s4, s1 /* - float arguments in registers */
278 lr s3, sp /* backup stack pointer (does not alter CC) */
280 je L_copy_done /* no arguments left for stack */
282 sll s4, 3 /* allocate 8 bytes per parameter on stack */
283 sr sp, s4 /* allocate stack space for arguments */
285 lr s2, sp /* points now to current argument on stack */
287 ahi itmp1, -sizevmarg /* initialize argument block pointer */
288 ahi itmp2, 1 /* initialize argument counter */
292 ahi itmp1, sizevmarg /* forward argument block pointer */
293 ahi itmp2, -1 /* decrement argument counter */
294 je L_copy_done /* all arguments done */
296 tm offvmargtype+7(itmp1), 0x02 /* is this a float/double type? */
297 jne L_stack_handle_float
301 ahi s0, -1 /* decrement number of integer arguments in regs */
302 jhe L_stack_copy_loop /* argument is in register */
304 tm offvmargtype+7(itmp1), 0x01 /* is this a 2 word type ? */
305 jne L_stack_handle_long
307 mvc 0(4, s2), offvmargdata+4(itmp1)/* copy integer value */
313 mvc 0(8, s2), offvmargdata(itmp1) /* copy long value */
317 L_stack_handle_float:
319 ahi s1, -1 /* decrement number of float arguments in regs */
320 jhe L_stack_copy_loop /* argument is in register */
322 tm offvmargtype+7(itmp1), 0x01 /* is this a 2 word type ? */
323 jne L_stack_handle_double
325 mvc 0(4, s2), offvmargdata(itmp1) /* copy float value */
329 L_stack_handle_double:
331 mvc 0(8, s2), offvmargdata(itmp1) /* copy double value */
337 /* Now we call the compiler in a rather questionable way i needed
338 * some days to understand:
340 * We can't simply call asm_call_jit_compiler, but we have to call an
341 * address loaded from memory like it is done in JIT code.
343 * This is because the compiler will intercept the instruction before
344 * the call instruction, extract the address where the function pointer
345 * has been loaded from and overwrite it with the code entry.
347 * Arguments are passed in temporary registers.
350 /* load address of L_asm_call_jit_compiler into memory */
352 basr mptr, 0 /* store PC */
354 la mptr, L_asm_call_jit_compiler-L_basr(mptr) /* add offset to PC */
355 st mptr, 4(s3) /* store on stack */
357 l itmp1, 8+8(s3) /* load methodinfo for compiler */
358 la mptr, 4(s3) /* store **function in mptr for compiler */
360 /* call L_asm_call_jit_compiler like JIT code would do */
362 l itmp3, 0(mptr) /* load address of target from memory */
363 basr %r14, itmp3 /* jump to target */
365 /* todo will s4 survive the call? */
366 ar sp, s4 /* remove stack space for arguments */
368 L_asm_vm_call_method_return:
370 ahi sp, 8 /* remove stack space for local variables */
371 lm %r6, %r15, 24(sp) /* restore callers registers */
374 asm_vm_call_method_exception_handler:
377 bras %r14, L_avcmeh_bras
378 .long builtin_throw_exception
385 j L_asm_vm_call_method_return
395 l a0, offvmargdata+4(itmp1)
398 l a1, offvmargdata+4(itmp1)
401 l a2, offvmargdata+4(itmp1)
404 l a3, offvmargdata+4(itmp1)
407 l a4, offvmargdata+4(itmp1)
411 lm a0, a1, offvmargdata(itmp1)
414 lm a1, a2, offvmargdata(itmp1)
417 lm a2, a3, offvmargdata(itmp1)
420 lm a3, a4, offvmargdata(itmp1)
424 le fa0, offvmargdata(itmp1)
427 le fa1, offvmargdata(itmp1)
431 ld fa0, offvmargdata(itmp1)
434 ld fa1, offvmargdata(itmp1)
437 asm_vm_call_method_end:
440 /****************** function asm_call_jit_compiler *****************************
442 * invokes the compiler for untranslated JavaVM methods. *
444 * itmp1: methodinfo pointer *
445 * itmp2: method pointer *
447 *******************************************************************************/
451 argument registers: arguments (like in JIT)
453 arguments on stack (like in JIT)
454 ------------------------------------------------------------- <- SP on entry
456 saved return address \
457 stored volatile (in terms of C ABI) floag argument registers |
458 96 stored volatile (in terms of C ABI) integer argument registers | ACJC_STACKFRAME
459 0 - 96 register save area (C ABI) /
460 -------------------------------------------------- <- SP for jit_asm_compile
463 /* This is called from a compiler stub.
464 * Arguments are already in registers and the stack is setup like in CACAO.
467 asm_call_jit_compiler:
468 L_asm_call_jit_compiler:
470 # define ACJC_STACKFRAME (4 + (4 * 4) + (2 * 8) + 96)
472 ahi sp,-ACJC_STACKFRAME /* allocate stack space */
474 stm %r2,%r5,96(sp) /* store volatile int arg regs */
475 std %f0,96+16(sp) /* store volatile float arg regs */
477 st %r14,96+32(sp) /* store return address */
481 lr a0,itmp1 /* pass methodinfo pointer */
482 lr a1,itmp2 /* pass method pointer */
483 la a2,ACJC_STACKFRAME(sp) /* pass java sp */
484 la a3,0(%r14) /* pass return address, make sure bit 32 is 0 */
486 /* call jit_asm_compile in a PIC way */
488 bras itmp2, L_bras_jac
489 .long jit_asm_compile
494 lr pv, v0 /* save return value */
496 lm %r2,%r5,96(sp) /* restore volatile int arg regs */
497 ld %f0,96+16(sp) /* restore volatile float arg regs */
498 ld %f2,96+24(sp) /* restore volatile float arg regs */
501 je L_asm_call_jit_compiler_exception
503 l %r14,96+32(sp) /* restore return address */
504 ahi sp, ACJC_STACKFRAME /* remove stack frame */
506 jit_code_entry: /* label to set breakpoint on */
507 br pv /* call the method, it will return to the caller */
510 L_asm_call_jit_compiler_exception:
511 bras itmp2, L_bras_acjce
512 .long exceptions_get_and_clear_exception
517 l xpc,96+32(sp) /* restore return address */
518 ahi sp, ACJC_STACKFRAME /* remove stack frame */
519 j L_asm_handle_nat_exception
523 /* asm_handle_exception ********************************************************
525 * This function handles an exception. It does not use the usual calling *
526 * conventions. The exception pointer is passed in REG_ITMP1 and the *
527 * pc from the exception raising position is passed in REG_ITMP2. It searches *
528 * the local exception table for a handler. If no one is found, it unwinds *
529 * stacks and continues searching the callers. *
531 *******************************************************************************/
535 asm_handle_nat_exception:
536 L_asm_handle_nat_exception:
537 /* TODO really nothing here ? */
538 asm_handle_exception:
539 L_asm_handle_exception: /* required for PIC code */
541 ahi sp, -(ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* create maybe-leaf stackframe */
542 STORE_ARGUMENT_REGISTERS(0)
543 STORE_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
544 lhi a3, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* prepare a3 for handle_exception */
546 lhi %r0, 1 /* set maybe-leaf flag */
548 L_asm_handle_exception_stack_loop:
550 st xptr,0*4(sp) /* save exception pointer */
551 st xpc,1*4(sp) /* save exception pc */
552 la a3,(6*4)(a3,sp) /* calculate Java sp into a3... */
553 st a3,3*4(sp) /* ...and save it */
554 st %r0,4*4(sp) /* save maybe-leaf flag */
556 lr a0,xpc /* exception pc */
558 ahi sp,-96 /* add register save area for C code */
560 bras %r14,L_ahe_bras /* call codegen_get_pv_from_pc */
561 .long codegen_get_pv_from_pc
565 st v0,2*4+96(sp) /* save data segment pointer */
567 lr a2,v0 /* pass data segment pointer */
568 l a0,0*4+96(sp) /* pass exception pointer */
569 l a1,1*4+96(sp) /* pass exception pc */
570 l a3,3*4+96(sp) /* pass Java stack pointer */
572 bras %r14,L_ahe_bras2 /* call exceptions_handle_exception */
573 .long exceptions_handle_exception
578 ahi sp,96 /* remove regiser save area for C code */
581 jz L_asm_handle_exception_not_catched
583 lr xpc,v0 /* move handlerpc into xpc */
584 l xptr,0*4(sp) /* restore exception pointer */
585 l pv,2*4(sp) /* restore PV */
586 l %r0,4*4(sp) /* get maybe-leaf flag */
587 ahi sp,(6*4) /* free stack frame */
590 jz L_asm_handle_exception_no_leaf
592 LOAD_ARGUMENT_REGISTERS(0)
593 LOAD_TEMPORARY_REGISTERS(ARGUMENT_REGISTERS_SIZE)
595 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
597 L_asm_handle_exception_no_leaf:
598 br xpc /* jump to the handler */
600 L_asm_handle_exception_not_catched:
601 l xptr,0*4(sp) /* restore exception pointer */
602 l itmp3,2*4(sp) /* restore data segment pointer */
603 ahi itmp3,-0xfff /* for negative displacements */
604 l %r0,4*4(sp) /* get maybe-leaf flag */
608 jz L_asm_handle_exception_no_leaf_stack
610 ahi sp, (ARGUMENT_REGISTERS_SIZE + TEMPORARY_REGISTERS_SIZE) /* Remove maybe-leaf stackframe */
611 lhi %r0,0 /* clear the isleaf flag */
614 +-----------------+-----------+---------+----+
615 | Memuse | Float Sav | Int Sav | RA |
616 | | 0 ... n | 0 ... n | |
617 +-----------------+-----------+---------+----+
625 L_asm_handle_exception_no_leaf_stack:
627 l itmp2,0xfff+FrameSize(itmp3)/* get frame size */
628 la itmp2,0(itmp2,sp) /* pointer to save area (p1) */
629 ahi itmp2,-4 /* skip RA (p2) */
630 ahi itmp2,-0xfff /* for negative displacements */
632 l a0,0xfff+IntSave(itmp3) /* a0 = saved int register count */
647 l s0,0xfff-5*4(itmp2)
649 l s1,0xfff-4*4(itmp2)
651 l s2,0xfff-3*4(itmp2)
653 l s3,0xfff-2*4(itmp2)
655 l s4,0xfff-1*4(itmp2)
659 sll a0,2 /* a0 = saved int register count * 4 */
660 sr itmp2, a0 /* skip Int Sav (p3) */
662 l a0,0xfff+FltSave(itmp3)
663 ltr a0,a0 /* Number of saved floating point registers */
670 ld %f4,0xfff-2*8(itmp2)
672 ld %f6,0xfff-1*8(itmp2)
676 l itmp3,0xfff+FrameSize(itmp3)/* get frame size (at least 4 - RA) */
677 ahi itmp3,-4 /* substract 4 */
678 l xpc,0(itmp3,sp) /* load the new xpc - return address */
679 la sp, 4(itmp3,sp) /* unwind stack */
681 /* exception pointer is still set */
683 sub $3,xpc /* subtract 3 bytes for call */
686 lhi a3,0 /* prepare a3 for handle_exception */
688 j L_asm_handle_exception_stack_loop
693 /* asm_abstractmethoderror *****************************************************
695 Creates and throws an AbstractMethodError.
697 *******************************************************************************/
699 asm_abstractmethoderror:
700 mov sp,a0 /* pass java sp */
702 mov 0*8(sp),a1 /* pass exception address */
704 call exceptions_asm_new_abstractmethoderror@PLT
705 /* exception pointer is return value */
706 pop xpc /* get exception address */
707 sub $3,xpc /* exception address is ra - 3 */
708 jmp L_asm_handle_exception
712 /* asm_patcher_wrapper *********************************************************
717 20 return address into JIT code (patch position)
718 16 pointer to virtual java_objectheader
719 12 machine code (which is patched back later)
720 8 unresolved class/method/field reference
721 4 data segment displacement from load instructions
722 0 patcher function pointer to call (pv afterwards)
724 *******************************************************************************/
727 # define apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
729 ahi sp, -apw_sfs /* create stack frame */
731 /* store all volatile registers and a2, because we will touch it */
734 STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
735 STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
739 la a0, apw_sfs(sp) /* pass SP of patcher stub */
740 lr a1, pv /* pass PV (if NULL, use findmethod) */
741 lhi a2, 0 /* pass RA */
743 /* call patcher_wrapper */
745 bras itmp1, L_apw_bras /* call patcher_wrapper */
746 .long patcher_wrapper
751 /* store return value */
753 st v0,0(sp) /* save return value */
755 /* restore volatile registers */
758 LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
759 LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
761 l itmp3, 0(sp) /* restore return value */
762 ltr itmp3, itmp3 /* exception thrown ? */
763 jne L_asm_patcher_wrapper_exception /* handle exception */
764 l itmp3, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
765 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
766 br itmp3 /* return */
768 L_asm_patcher_wrapper_exception:
769 lr xptr,itmp3 /* get exception */
770 l xpc, apw_sfs + (5 * 4)(sp) /* load return address to JIT from stack */
771 ahi sp, apw_sfs + (6 * 4) /* remove stack frame, and stack frame by patcher stub */
772 j L_asm_handle_exception
776 /* asm_replacement_out *********************************************************
778 This code is jumped to from the replacement-out stubs that are executed
779 when a thread reaches an activated replacement point.
781 The purpose of asm_replacement_out is to read out the parts of the
782 execution state that cannot be accessed from C code, store this state,
783 and then call the C function replace_me.
786 8 start of stack inside method to replace
787 0 rplpoint * info on the replacement point that was reached
789 *******************************************************************************/
791 /* some room to accomodate changes of the stack frame size during replacement */
792 /* XXX we should find a cleaner solution here */
793 #define REPLACEMENT_ROOM 512
796 /* create stack frame */
797 sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
799 /* save registers in execution state */
800 mov %rax,(RAX*8+offes_intregs)(sp)
801 mov %rbx,(RBX*8+offes_intregs)(sp)
802 mov %rcx,(RCX*8+offes_intregs)(sp)
803 mov %rdx,(RDX*8+offes_intregs)(sp)
804 mov %rsi,(RSI*8+offes_intregs)(sp)
805 mov %rdi,(RDI*8+offes_intregs)(sp)
806 mov %rbp,(RBP*8+offes_intregs)(sp)
807 movq $0 ,(RSP*8+offes_intregs)(sp) /* not used */
808 mov %r8 ,(R8 *8+offes_intregs)(sp)
809 mov %r9 ,(R9 *8+offes_intregs)(sp)
810 mov %r10,(R10*8+offes_intregs)(sp)
811 mov %r11,(R11*8+offes_intregs)(sp)
812 mov %r12,(R12*8+offes_intregs)(sp)
813 mov %r13,(R13*8+offes_intregs)(sp)
814 mov %r14,(R14*8+offes_intregs)(sp)
815 mov %r15,(R15*8+offes_intregs)(sp)
817 movq %xmm0 ,(XMM0 *8+offes_fltregs)(sp)
818 movq %xmm1 ,(XMM1 *8+offes_fltregs)(sp)
819 movq %xmm2 ,(XMM2 *8+offes_fltregs)(sp)
820 movq %xmm3 ,(XMM3 *8+offes_fltregs)(sp)
821 movq %xmm4 ,(XMM4 *8+offes_fltregs)(sp)
822 movq %xmm5 ,(XMM5 *8+offes_fltregs)(sp)
823 movq %xmm6 ,(XMM6 *8+offes_fltregs)(sp)
824 movq %xmm7 ,(XMM7 *8+offes_fltregs)(sp)
825 movq %xmm8 ,(XMM8 *8+offes_fltregs)(sp)
826 movq %xmm9 ,(XMM9 *8+offes_fltregs)(sp)
827 movq %xmm10,(XMM10*8+offes_fltregs)(sp)
828 movq %xmm11,(XMM11*8+offes_fltregs)(sp)
829 movq %xmm12,(XMM12*8+offes_fltregs)(sp)
830 movq %xmm13,(XMM13*8+offes_fltregs)(sp)
831 movq %xmm14,(XMM14*8+offes_fltregs)(sp)
832 movq %xmm15,(XMM15*8+offes_fltregs)(sp)
834 /* calculate sp of method */
836 add $(sizeexecutionstate + REPLACEMENT_ROOM + 8),itmp1
837 mov itmp1,(offes_sp)(sp)
839 /* pv must be looked up via AVL tree */
840 movq $0,(offes_pv)(sp)
842 /* call replace_me */
843 mov -8(itmp1),a0 /* rplpoint * */
844 mov sp,a1 /* arg1: execution state */
845 call replace_me@PLT /* call C function replace_me */
846 call abort@PLT /* NEVER REACHED */
848 /* asm_replacement_in **********************************************************
850 This code writes the given execution state and jumps to the replacement
853 This function never returns!
856 void asm_replacement_in(executionstate *es);
858 *******************************************************************************/
861 mov a0,%rbp /* executionstate *es */
864 mov (offes_sp)(%rbp),%rsp
866 /* store address of new code */
867 push (offes_pc)(%rbp)
869 /* copy registers from execution state */
870 movq (XMM0 *8+offes_fltregs)(%rbp),%xmm0
871 movq (XMM1 *8+offes_fltregs)(%rbp),%xmm1
872 movq (XMM2 *8+offes_fltregs)(%rbp),%xmm2
873 movq (XMM3 *8+offes_fltregs)(%rbp),%xmm3
874 movq (XMM4 *8+offes_fltregs)(%rbp),%xmm4
875 movq (XMM5 *8+offes_fltregs)(%rbp),%xmm5
876 movq (XMM6 *8+offes_fltregs)(%rbp),%xmm6
877 movq (XMM7 *8+offes_fltregs)(%rbp),%xmm7
878 movq (XMM8 *8+offes_fltregs)(%rbp),%xmm8
879 movq (XMM9 *8+offes_fltregs)(%rbp),%xmm9
880 movq (XMM10*8+offes_fltregs)(%rbp),%xmm10
881 movq (XMM11*8+offes_fltregs)(%rbp),%xmm11
882 movq (XMM12*8+offes_fltregs)(%rbp),%xmm12
883 movq (XMM13*8+offes_fltregs)(%rbp),%xmm13
884 movq (XMM14*8+offes_fltregs)(%rbp),%xmm14
885 movq (XMM15*8+offes_fltregs)(%rbp),%xmm15
887 mov (RAX*8+offes_intregs)(%rbp),%rax
888 mov (RBX*8+offes_intregs)(%rbp),%rbx
889 mov (RCX*8+offes_intregs)(%rbp),%rcx
890 mov (RDX*8+offes_intregs)(%rbp),%rdx
891 mov (RSI*8+offes_intregs)(%rbp),%rsi
892 mov (RDI*8+offes_intregs)(%rbp),%rdi
893 mov (R8 *8+offes_intregs)(%rbp),%r8
894 mov (R9 *8+offes_intregs)(%rbp),%r9
895 mov (R10*8+offes_intregs)(%rbp),%r10
896 mov (R11*8+offes_intregs)(%rbp),%r11
897 mov (R12*8+offes_intregs)(%rbp),%r12
898 mov (R13*8+offes_intregs)(%rbp),%r13
899 mov (R14*8+offes_intregs)(%rbp),%r14
900 mov (R15*8+offes_intregs)(%rbp),%r15
902 mov (RBP*8+offes_intregs)(%rbp),%rbp
904 /* jump to new code */
908 /* asm_builtin_x2x *************************************************************
910 * Wrapper functions for float to int corner cases *
912 *******************************************************************************/
917 SAVE_ARGUMENT_REGISTERS(0)
922 RESTORE_ARGUMENT_REGISTERS(0)
931 SAVE_ARGUMENT_REGISTERS(0)
936 RESTORE_ARGUMENT_REGISTERS(0)
945 SAVE_ARGUMENT_REGISTERS(0)
950 RESTORE_ARGUMENT_REGISTERS(0)
959 SAVE_ARGUMENT_REGISTERS(0)
964 RESTORE_ARGUMENT_REGISTERS(0)
971 /* TODO use move here ? */
973 asm_getclassvalues_atomic:
980 st %r0,offcast_super_baseval(a2)
981 st %r1,offcast_super_diffval(a2)
982 st a3,offcast_sub_baseval(a2)
987 asm_criticalsections:
988 #if defined(ENABLE_THREADS)
996 /* disable exec-stacks ********************************************************/
1000 #if defined(__linux__) && defined(__ELF__)
1001 .section .note.GNU-stack,"",%progbits
1008 * These are local overrides for various environment variables in Emacs.
1009 * Please do not remove this and leave it at the end of the file, where
1010 * Emacs will automagically detect them.
1011 * ---------------------------------------------------------------------
1014 * indent-tabs-mode: t
1018 * vim:noexpandtab:sw=4:ts=4: