1 /* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
31 $Id: asmpart.S 2285 2005-04-12 20:32:34Z twisti $
37 #include "vm/jit/x86_64/arch.h"
38 #include "vm/jit/x86_64/offsets.h"
39 #include "vm/jit/x86_64/asmoffsets.h"
42 /* XXX Don't remove this!!! ***************************************************/
45 #error OFFSET(java_objectheader, vftbl) != 0: this will break code patching!
48 #if offvftblinterfacetable != 0
49 #error OFFSET(vftbl_t, interfacetable[0]) != 0: this will break code patching!
52 /******************************************************************************/
55 /* define it like the risc way */
92 /* save and restore macros ****************************************************/
94 #define SAVE_ARGUMENT_REGISTERS \
101 movq fa0,6*8(%rsp) ; \
102 movq fa1,7*8(%rsp) ; \
103 movq fa2,8*8(%rsp) ; \
104 movq fa3,9*8(%rsp) ; \
105 movq fa4,10*8(%rsp) ; \
106 movq fa5,11*8(%rsp) ; \
107 movq fa6,12*8(%rsp) ; \
108 movq fa7,13*8(%rsp) ;
111 #define RESTORE_ARGUMENT_REGISTERS \
118 movq 6*8(%rsp),fa0 ; \
119 movq 7*8(%rsp),fa1 ; \
120 movq 8*8(%rsp),fa2 ; \
121 movq 9*8(%rsp),fa3 ; \
122 movq 10*8(%rsp),fa4 ; \
123 movq 11*8(%rsp),fa5 ; \
124 movq 12*8(%rsp),fa6 ; \
125 movq 13*8(%rsp),fa7 ;
128 #define SAVE_TEMPORARY_REGISTERS \
132 #define RESTORE_TEMPORARY_REGISTERS \
139 /********************* exported functions and variables ***********************/
141 .globl asm_calljavafunction
142 .globl asm_calljavafunction_int
144 .globl asm_calljavafunction2
145 .globl asm_calljavafunction2int
146 .globl asm_calljavafunction2long
147 .globl asm_calljavafunction2float
148 .globl asm_calljavafunction2double
150 .globl asm_call_jit_compiler
151 .globl asm_handle_exception
152 .globl asm_handle_nat_exception
154 .globl asm_patcher_get_putstatic
155 .globl asm_patcher_get_putfield
156 .globl asm_patcher_builtin_new
157 .globl asm_patcher_builtin_newarray
158 .globl asm_patcher_builtin_multianewarray
159 .globl asm_patcher_builtin_checkarraycast
160 .globl asm_patcher_builtin_arrayinstanceof
161 .globl asm_patcher_invokestatic_special
162 .globl asm_patcher_invokevirtual
163 .globl asm_patcher_invokeinterface
164 .globl asm_patcher_checkcast_instanceof_flags
165 .globl asm_patcher_checkcast_instanceof_interface
166 .globl asm_patcher_checkcast_class
167 .globl asm_patcher_instanceof_class
169 .globl asm_check_clinit
171 .globl asm_builtin_checkarraycast
172 .globl asm_builtin_aastore
174 #if defined(USE_THREADS)
175 .globl asm_builtin_monitorenter
176 .globl asm_builtin_monitorexit
179 .globl asm_builtin_f2i
180 .globl asm_builtin_f2l
181 .globl asm_builtin_d2i
182 .globl asm_builtin_d2l
184 .globl asm_perform_threadswitch
185 .globl asm_initialize_thread_stack
186 .globl asm_switchstackandcall
187 .globl asm_criticalsections
188 .globl asm_getclassvalues_atomic
191 /********************* function asm_calljavafunction ***************************
193 * This function calls a Java-method (which possibly needs compilation) *
194 * with up to 4 address parameters. *
196 * This functions calls the JIT-compiler which eventually translates the *
197 * method into machine code. *
200 * javaobject_header *asm_calljavamethod (methodinfo *m, *
201 * void *arg1, void *arg2, void *arg3, void *arg4); *
203 *******************************************************************************/
208 .quad 0 /* catch type all */
209 .quad calljava_xhandler /* handler pc */
210 .quad calljava_xhandler /* end pc */
211 .quad asm_calljavafunction /* start pc */
212 .long 1 /* extable size */
213 .long 0 /* fltsave */
214 .long 0 /* intsave */
217 .long 8 /* frame size */
218 .quad 0 /* method pointer (pointer to name) */
220 asm_calljavafunction:
221 asm_calljavafunction_int:
222 sub $(3*8),%rsp /* keep stack 16-byte aligned */
224 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
225 mov %rdi,%rax /* move function pointer to %rax */
226 /* compilerstub uses this */
228 mov %rsi,%rdi /* pass remaining parameters */
233 lea asm_call_jit_compiler,%r11
234 call *%r11 /* call JIT compiler */
238 add $(3*8),%rsp /* free stack space */
242 mov %rax,%rdi /* pass exception pointer */
243 call builtin_throw_exception
247 xor %rax,%rax /* return NULL */
251 /********************* function asm_calljavafunction ***************************
253 * This function calls a Java-method (which possibly needs compilation) *
254 * with up to 4 address parameters. *
256 * This functions calls the JIT-compiler which eventually translates the *
257 * method into machine code. *
260 * javaobject_header *asm_calljavamethod (methodinfo *m, *
261 * void *arg1, void *arg2, void *arg3, void *arg4); *
263 *******************************************************************************/
268 .quad 0 /* catch type all */
269 .quad calljava_xhandler2 /* handler pc */
270 .quad calljava_xhandler2 /* end pc */
271 .quad asm_calljavafunction2 /* start pc */
272 .long 1 /* extable size */
273 .long 0 /* fltsave */
274 .long 0 /* intsave */
277 .long 24 /* frame size */
278 .quad 0 /* method pointer (pointer to name) */
280 asm_calljavafunction2:
281 asm_calljavafunction2int:
282 asm_calljavafunction2long:
283 asm_calljavafunction2float:
284 asm_calljavafunction2double:
285 sub $(7*8),%rsp /* keep stack 16-byte aligned */
286 mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
293 mov %rdi,%rax /* move method pointer for compiler */
294 xor %rbp,%rbp /* set argument stack frame to zero */
296 test %rsi,%rsi /* maybe we have no args... */
299 mov %rsi,itmp3 /* arg count */
300 mov %rcx,itmp2 /* pointer to arg block */
302 mov itmp2,%r14 /* save argument block pointer */
303 mov itmp3,%r15 /* save argument count */
305 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
306 add $1,itmp3 /* initialize argument count */
307 xor %r12,%r12 /* initialize integer argument counter */
308 xor %r13,%r13 /* initialize float argument counter */
311 add $sizejniblock,itmp2 /* goto next argument block */
312 dec itmp3 /* argument count - 1 */
313 jz L_register_copy_done
314 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
315 jnz L_register_handle_float /* yes, handle it */
317 cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
318 je L_register_copy /* register? yes, next loop */
320 lea jumptable_integer,%rbp
321 mov 0(%rbp,%r12,8),%rbx
322 inc %r12 /* integer argument counter + 1 */
325 L_register_handle_float:
326 cmp $FLT_ARG_CNT,%r13 /* are we out of float argument */
327 je L_register_copy /* register? yes, next loop */
329 lea jumptable_float,%rbp
330 mov 0(%rbp,%r13,8),%rbx
331 inc %r13 /* float argument counter + 1 */
334 L_register_copy_done:
335 mov %r15,%rbp /* calculate remaining arguments */
336 sub %r12,%rbp /* - integer arguments in registers */
337 sub %r13,%rbp /* - float arguments in registers */
338 jle L_copy_done /* are all assigned to registers? */
340 shl $3,%rbp /* calculate stack size */
341 sub %rbp,%rsp /* stack frame for arguments */
342 mov %rsp,%rbx /* use %rbx as temp sp */
344 sub $sizejniblock,%r14 /* initialize pointer (smaller code) */
345 add $1,%r15 /* initialize argument count */
348 add $sizejniblock,%r14 /* goto next argument block */
349 dec %r15 /* are there any arguments left? */
350 jz L_copy_done /* no test needed after dec */
352 andb $0x02,offjniitemtype(%r14) /* is this a float/double type? */
353 jnz L_stack_handle_float
354 dec %r12 /* arguments assigned to registers */
355 jge L_stack_copy_loop
358 L_stack_handle_float:
359 dec %r13 /* arguments assigned to registers */
360 jge L_stack_copy_loop
363 mov offjniitem(%r14),itmp3 /* copy s8 argument onto stack */
365 add $8,%rbx /* increase sp to next argument */
366 jmp L_stack_copy_loop
369 lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
370 call *%r11 /* call JIT compiler */
372 add %rbp,%rsp /* remove argument stack frame if any */
374 mov 5*8(%rsp),%r15 /* restore callee saved registers */
380 add $(7*8),%rsp /* free stack space */
384 mov %rax,%rdi /* pass exception pointer */
385 call builtin_throw_exception
387 mov 5*8(%rsp),%r15 /* restore callee saved registers */
393 add $(7*8),%rsp /* free stack space */
394 xor %rax,%rax /* return NULL */
407 mov offjniitem(itmp2),a0
410 mov offjniitem(itmp2),a1
413 mov offjniitem(itmp2),a2
416 mov offjniitem(itmp2),a3
419 mov offjniitem(itmp2),a4
422 mov offjniitem(itmp2),a5
437 movq offjniitem(itmp2),fa0
440 movq offjniitem(itmp2),fa1
443 movq offjniitem(itmp2),fa2
446 movq offjniitem(itmp2),fa3
449 movq offjniitem(itmp2),fa4
452 movq offjniitem(itmp2),fa5
455 movq offjniitem(itmp2),fa6
458 movq offjniitem(itmp2),fa7
462 /****************** function asm_call_jit_compiler *****************************
464 * invokes the compiler for untranslated JavaVM methods. *
466 * Register R0 contains a pointer to the method info structure (prepared *
467 * by createcompilerstub). Using the return address in R26 and the *
468 * offset in the LDA instruction or using the value in methodptr R28 the *
469 * patching address for storing the method address can be computed: *
471 * method address was either loaded using *
473 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
474 * i386_call_reg(REG_ITMP2) *
478 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
479 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
480 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
481 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
482 * i386_call_reg(REG_ITMP1) *
484 * in the static case the method pointer can be computed using the *
485 * return address and the lda function following the jmp instruction *
487 *******************************************************************************/
489 asm_call_jit_compiler:
490 sub $8,%rsp /* keep stack 16-byte aligned */
492 mov %rbx,(%rsp) /* save register */
494 mov 8(%rsp),%r11 /* get return address */
495 mov -1(%r11),%bl /* get function code */
496 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
497 jne L_not_static_special
499 sub $11,%r11 /* calculate address of immediate */
500 jmp L_call_jit_compile
502 L_not_static_special:
503 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
504 jne L_not_virtual_interface
506 sub $7,%r11 /* calculate address of offset */
507 mov (%r11),%r11d /* get offset (32-bit) */
508 add %r10,%r11 /* add base address to get method address */
509 jmp L_call_jit_compile
511 L_not_virtual_interface: /* a call from asm_calljavamethod */
515 mov (%rsp),%rbx /* restore register */
517 sub $(24*8),%rsp /* 8 + 6*8 + 8*8 + 8*8 */
519 mov %r11,0*8(%rsp) /* save address for method pointer */
521 mov a0,1*8(%rsp) /* save arguments */
537 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
538 movq %xmm9,16*8(%rsp)
539 movq %xmm10,17*8(%rsp)
540 movq %xmm11,18*8(%rsp)
541 movq %xmm12,19*8(%rsp)
542 movq %xmm13,20*8(%rsp)
543 movq %xmm14,21*8(%rsp)
544 movq %xmm15,22*8(%rsp)
546 mov %rax,%rdi /* pass method pointer */
567 movq 15*8(%rsp),%xmm8
568 movq 16*8(%rsp),%xmm9
569 movq 17*8(%rsp),%xmm10
570 movq 18*8(%rsp),%xmm11
571 movq 19*8(%rsp),%xmm12
572 movq 20*8(%rsp),%xmm13
573 movq 21*8(%rsp),%xmm14
574 movq 22*8(%rsp),%xmm15
577 add $8,%rsp /* keep stack 16-byte aligned */
579 test %rax,%rax /* check for exception */
580 je L_asm_call_jit_compiler_exception
582 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
585 mov %rax,(%r11) /* and now save the new pointer */
588 jmp *%rax /* ...and now call the new method */
590 L_asm_call_jit_compiler_exception:
591 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
592 call builtin_asm_get_exceptionptrptr
595 lea _exceptionptr,itmp2
597 mov (itmp2),xptr /* get the exception pointer */
598 movl $0,(itmp2) /* clear the exception pointer */
600 pop xpc /* delete return address */
601 sub $5,xpc /* faulting address is ra - 5 */
603 jmp asm_handle_exception
606 /********************* function asm_handle_exception ***************************
608 * This function handles an exception. It does not use the usual calling *
609 * conventions. The exception pointer is passed in REG_ITMP1 and the *
610 * pc from the exception raising position is passed in REG_ITMP2. It searches *
611 * the local exception table for a handler. If no one is found, it unwinds *
612 * stacks and continues searching the callers. *
614 * void asm_handle_exception (exceptionptr, exceptionpc); *
616 *******************************************************************************/
618 asm_handle_nat_exception:
619 add $8,%rsp /* clear return address of native stub*/
621 asm_handle_exception:
623 mov xptr,0*8(%rsp) /* save exception pointer */
624 mov xpc,1*8(%rsp) /* save exception pc */
626 mov xpc,%rdi /* exception pc */
627 call codegen_findmethod
629 mov %rax,2*8(%rsp) /* save data segment pointer */
631 mov 0*8(%rsp),%rax /* restore exception pointer */
632 mov 1*8(%rsp),%r10 /* restore exception pc */
635 mov %rax,%rdi /* exception pointer */
636 mov MethodPointer(itmp3),%rsi /* method pointer */
637 mov xpc,%rdx /* exception pc */
639 mov $1,%r8 /* set noindent flag */
640 call builtin_trace_exception
642 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
643 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
644 test %rcx,%rcx /* if empty table skip */
647 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
648 mov 0*8(%rsp),xptr /* get xptr */
651 mov 1*8(%rsp),xpc /* get xpc */
653 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
654 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
655 jg ex_table_cont /* if (false) continue */
656 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
657 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
658 jge ex_table_cont /* if (false) continue */
659 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
660 test %rdx,%rdx /* NULL catches everything */
663 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
673 call load_class_bootstrap
682 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
701 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
709 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
710 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
711 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
712 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
713 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
715 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
717 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
721 cmp %edx,%esi /* xptr is instanceof catchtype */
725 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
727 mov 0*8(%rsp),%rax /* restore exception pointer */
728 add $(4*8),%rsp /* free stack frame */
730 jmp *xpc /* jump to the handler */
733 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
734 dec %rcx /* decrement entry counter */
735 test %rcx,%rcx /* if (t0 > 0) next entry */
739 mov 0*8(%rsp),%rax /* restore exception pointer */
740 mov 1*8(%rsp),%r10 /* restore exception pc */
741 mov 2*8(%rsp),%r11 /* restore data segment pointer */
744 mov %rax,%rcx /* save exception pointer */
747 movl IsSync(%r11),%eax /* %rax = SyncOffset */
748 test %rax,%rax /* if zero no monitorexit */
751 #if defined(USE_THREADS)
760 call builtin_monitorexit
769 mov FrameSize(%r11),%eax /* %eax = frame size */
770 add %rax,%rsp /* unwind stack */
771 mov %rsp,%rax /* %rax = pointer to save area */
773 mov IntSave(%r11),%edx /* %edx = saved int register count*/
800 shl $3,%edx /* multiply by 8 bytes */
804 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
827 movq -48(%rax),%xmm10
829 movq -40(%rax),%xmm11
831 movq -32(%rax),%xmm12
833 movq -24(%rax),%xmm13
835 movq -16(%rax),%xmm14
840 pop %r10 /* the new xpc is return address */
841 sub $3,%r10 /* subtract 3 bytes for call */
848 call codegen_findmethod /* get the new data segment ptr */
855 mov %rcx,%rax /* restore saved exception pointer*/
859 mov %rax,0*8(%rsp) /* save exception pointer */
860 mov %r10,1*8(%rsp) /* save exception pc */
861 mov %r11,2*8(%rsp) /* save data segment pointer */
866 /* asm_patcher_get_putstatic ***************************************************
872 8 machine code (which is patched back later)
873 0 unresolved field reference
875 *******************************************************************************/
877 asm_patcher_get_putstatic:
878 sub $(15*8),%rsp /* stack frame (16-byte aligned) */
880 SAVE_ARGUMENT_REGISTERS
881 SAVE_TEMPORARY_REGISTERS
883 mov (0+15)*8(%rsp),a0 /* pass unresolved_field pointer */
884 call helper_resolve_fieldinfo_value_address /* call the helper function*/
886 RESTORE_ARGUMENT_REGISTERS
887 RESTORE_TEMPORARY_REGISTERS
889 mov (1+15)*8(%rsp),itmp3 /* get machine code */
890 add $((2+15)*8),%rsp /* remove stack frame, keep ra */
892 test v0,v0 /* exception thrown? */
893 jz L_asm_patcher_exception
895 pop itmp2 /* get return address */
896 sub $5,itmp2 /* remove size of `call rel32' */
897 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
899 movswq 3(itmp2),itmp3 /* get %rip offset */
900 add itmp2,itmp3 /* add return address (%rip) */
901 add $7,itmp3 /* add mov instruction size */
902 mov v0,(itmp3) /* move field address to data segment */
903 jmp *itmp2 /* call new patched code */
905 L_asm_patcher_exception:
906 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
907 call builtin_asm_get_exceptionptrptr
910 lea _exceptionptr,itmp2
912 mov (itmp2),xptr /* get the exception pointer */
913 movl $0,(itmp2) /* clear the exception pointer */
915 pop xpc /* get and remove return address */
916 sub $5,xpc /* faulting address is ra - 5 */
917 jmp asm_handle_exception
920 /* asm_patcher_get_putfield ****************************************************
926 8 machine code (which is patched back later)
927 0 unresolved field reference
929 *******************************************************************************/
931 asm_patcher_get_putfield:
932 sub $(17*8),%rsp /* stack frame (16-byte aligned) */
934 SAVE_ARGUMENT_REGISTERS
935 SAVE_TEMPORARY_REGISTERS
937 mov itmp1,15*8(%rsp) /* save itmp1 and itmp2 */
938 mov itmp2,16*8(%rsp) /* can be used by field instructions */
940 mov (0+17)*8(%rsp),a0 /* pass unresolved_method pointer */
941 call helper_resolve_fieldinfo_offset /* call the helper function */
943 RESTORE_ARGUMENT_REGISTERS
944 RESTORE_TEMPORARY_REGISTERS
946 cmp $-1,v0l /* exception thrown? test for -1, */
947 /* because field offset can be 0 */
948 jz L_asm_patcher_exception_with_stack_frame
950 mov (1+17)*8(%rsp),itmp3 /* get machine code */
951 mov (2+17)*8(%rsp),itmp2 /* get return address */
952 sub $5,itmp2 /* remove size of `call rel32' */
953 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
955 cmpb $0xf2,(itmp2) /* test for movsd */
956 je L_asm_patcher_get_putfield_float
957 cmpb $0xf3,(itmp2) /* test for movss */
958 je L_asm_patcher_get_putfield_float
959 cmpb $0x24,3(itmp2) /* check for (%rsp) or (%r12) */
960 je L_asm_patcher_get_putfield_r12_membase
962 mov v0l,3(itmp2) /* patch field offset */
963 jmp L_asm_patcher_get_putfield_normal
965 L_asm_patcher_get_putfield_float:
966 mov v0l,5(itmp2) /* patch field offset (position + 2) */
967 jmp L_asm_patcher_get_putfield_normal
969 L_asm_patcher_get_putfield_r12_membase:
970 mov v0l,4(itmp2) /* patch field offset (position + 1) */
972 L_asm_patcher_get_putfield_normal:
975 mov 15*8(%rsp),itmp1 /* restore itmp1 and itmp2 */
976 mov 16*8(%rsp),itmp2 /* can be used by field instructions */
978 add $((3+17)*8),%rsp /* remove stack frame */
979 jmp *itmp3 /* call new patched code */
981 L_asm_patcher_exception_with_stack_frame:
982 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
983 call builtin_asm_get_exceptionptrptr
986 lea _exceptionptr,itmp2
988 mov (itmp2),xptr /* get the exception pointer */
989 movl $0,(itmp2) /* clear the exception pointer */
991 mov (2+17)*8(%rsp),xpc /* get return address */
992 sub $5,xpc /* faulting address is ra - 5 */
993 add $((3+17)*8),%rsp /* remove stack frame */
994 jmp asm_handle_exception
997 /* asm_patcher_builtin_new *****************************************************
1002 a0 contains the class reference
1004 *******************************************************************************/
1006 asm_patcher_builtin_new:
1007 sub $(8*1),%rsp /* stack frame (16-byte aligned) */
1008 call helper_resolve_classinfo /* call the helper function */
1009 add $(8*1),%rsp /* remove stack frame */
1010 test v0,v0 /* exception thrown? */
1011 jz L_asm_patcher_exception
1013 pop itmp2 /* get return address */
1014 sub $(10+10+3),itmp2 /* 10 (movi) + 10 (movi) + 3 (callq) */
1015 mov v0,2(itmp2) /* patch in new classinfo*: 2 (mov) */
1017 lea builtin_new,itmp1 /* get address from builtin_new */
1018 mov itmp1,12(itmp2) /* patch back function address */
1019 jmp *itmp2 /* call new patched code */
1022 /* asm_patcher_builtin_newarray ************************************************
1027 a1 contains the class reference
1029 *******************************************************************************/
1031 asm_patcher_builtin_newarray:
1032 sub $(8*1),%rsp /* stack frame (16-byte aligned) */
1033 mov a0,0*8(%rsp) /* save argument */
1034 mov a1,a0 /* pass class reference */
1035 call helper_resolve_classinfo_vftbl /* call the helper function */
1036 mov 0*8(%rsp),a0 /* restore argument */
1037 add $(8*1),%rsp /* remove stack frame */
1038 test v0,v0 /* exception thrown? */
1039 jz L_asm_patcher_exception
1041 pop itmp2 /* get return address */
1042 sub $(10+10+3),itmp2 /* 10 (movi) + 10 (movi) + 3 (callq) */
1043 mov v0,2(itmp2) /* patch in new vftbl*: 2 (mov) */
1045 lea builtin_newarray,itmp1 /* get address from builtin_newarray */
1046 mov itmp1,12(itmp2) /* patch back function address */
1047 jmp *itmp2 /* call new patched code */
1050 /* asm_patcher_builtin_multianewarray ******************************************
1055 a1 contains the class reference
1057 *******************************************************************************/
1059 asm_patcher_builtin_multianewarray:
1060 sub $(1*8),%rsp /* stack frame (16-byte aligned) */
1061 mov a1,a0 /* pass class reference */
1062 call helper_resolve_classinfo_vftbl /* call the helper function */
1063 add $(1*8),%rsp /* remove stack frame */
1064 test v0,v0 /* exception thrown? */
1065 jz L_asm_patcher_exception
1067 pop itmp2 /* get return address */
1068 sub $(3+10+3+10+10),itmp2 /* go back to a0 mov */
1069 mov v0,10+2(itmp2) /* patch in new vftbl*: 10 (movi) + 2 */
1071 lea builtin_nmultianewarray,itmp1 /* get function address */
1072 mov itmp1,10+10+3+2(itmp2) /* patch back function address */
1073 jmp *itmp2 /* call new patched code */
1076 /* asm_patcher_builtin_checkarraycast ******************************************
1081 a1 contains the class reference
1083 *******************************************************************************/
1085 asm_patcher_builtin_checkarraycast:
1086 sub $(8*1),%rsp /* stack frame (16-byte aligned) */
1087 mov a0,0*8(%rsp) /* save argument */
1088 mov a1,a0 /* pass class reference */
1089 call helper_resolve_classinfo_vftbl /* call the helper function */
1090 mov 0*8(%rsp),a0 /* restore argument */
1091 add $(8*1),%rsp /* remove stack frame */
1092 test v0,v0 /* exception thrown? */
1093 jz L_asm_patcher_exception
1095 pop itmp2 /* get return address */
1096 sub $(10+10+3),itmp2 /* 10 (movi) + 10 (movi) + 3 (callq) */
1097 mov v0,2(itmp2) /* patch in new vftbl*: 2 (mov) */
1099 lea asm_builtin_checkarraycast,itmp1 /* get function address */
1100 mov itmp1,12(itmp2) /* patch back function address */
1101 jmp *itmp2 /* call new patched code */
1104 /* asm_patcher_builtin_arrayinstanceof *****************************************
1109 a1 contains the class reference
1111 *******************************************************************************/
1113 asm_patcher_builtin_arrayinstanceof:
1114 sub $(8*1),%rsp /* stack frame (16-byte aligned) */
1115 mov a0,0*8(%rsp) /* save argument */
1116 mov a1,a0 /* pass class reference */
1117 call helper_resolve_classinfo_vftbl /* call the helper function */
1118 mov 0*8(%rsp),a0 /* restore argument */
1119 add $(8*1),%rsp /* remove stack frame */
1120 test v0,v0 /* exception thrown? */
1121 jz L_asm_patcher_exception
1123 pop itmp2 /* get return address */
1124 sub $(10+10+3),itmp2 /* 10 (movi) + 10 (movi) + 3 (callq) */
1125 mov v0,2(itmp2) /* patch in new vftbl*: 2 (mov) */
1127 lea builtin_arrayinstanceof,itmp1 /* get function address */
1128 mov itmp1,12(itmp2) /* patch back function address */
1129 jmp *itmp2 /* call new patched code */
1132 /* asm_patcher_invokestatic_special ********************************************
1138 8 machine code (which is patched back later)
1139 0 unresolved method reference
1141 *******************************************************************************/
1143 asm_patcher_invokestatic_special:
1144 sub $(15*8),%rsp /* stack frame (16-byte aligned) */
1146 SAVE_ARGUMENT_REGISTERS
1148 mov (0+15)*8(%rsp),a0 /* pass unresolved_method pointer */
1149 call helper_resolve_methodinfo_stubroutine /* call the helper function */
1151 RESTORE_ARGUMENT_REGISTERS
1153 mov (1+15)*8(%rsp),itmp3 /* get machine code */
1154 add $((2+15)*8),%rsp /* remove stack frame, keep ra */
1156 test v0,v0 /* exception thrown? */
1157 jz L_asm_patcher_exception
1159 pop itmp2 /* get return address */
1160 sub $5,itmp2 /* remove size of `call rel32' */
1161 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
1163 mov v0,2(itmp2) /* patch stubroutine: 2 (mov) */
1164 jmp *itmp2 /* call new patched code */
1167 /* asm_patcher_invokevirtual ***************************************************
1173 8 machine code (which is patched back later)
1174 0 unresolved method reference
1176 *******************************************************************************/
1178 asm_patcher_invokevirtual:
1179 sub $(15*8),%rsp /* stack frame (16-byte aligned) */
1181 SAVE_ARGUMENT_REGISTERS
1183 mov (0+15)*8(%rsp),a0 /* pass unresolved_method pointer */
1184 call helper_resolve_methodinfo_vftblindex /* call the helper function */
1186 RESTORE_ARGUMENT_REGISTERS
1188 mov (1+15)*8(%rsp),itmp3 /* get machine code */
1189 add $((2+15)*8),%rsp /* remove stack frame, keep ra */
1191 cmp $-1,v0l /* exception thrown? test for -1, */
1192 /* because vftblindex can be 0 */
1193 je L_asm_patcher_exception
1195 pop itmp2 /* get return address */
1196 sub $5,itmp2 /* remove size of `call rel32' */
1197 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
1199 shl $3,v0l /* sizeof(methodptr) * lm->vftblindex */
1200 add $offvftbltable,v0l /* + OFFSET(vftbl_t, table[0]) */
1201 movl v0l,3+3(itmp2) /* patch 32 bit offset: 3 (mov) + 3 */
1202 jmp *itmp2 /* call new patched code */
1205 /* asm_patcher_invokeinterface *************************************************
1211 8 machine code (which is patched back later)
1212 0 unresolved method reference
1214 *******************************************************************************/
1216 asm_patcher_invokeinterface:
1217 sub $(15*8),%rsp /* stack frame (16-byte aligned) */
1219 SAVE_ARGUMENT_REGISTERS
1221 mov (0+15)*8(%rsp),a0 /* pass unresolved_method pointer */
1222 call helper_resolve_methodinfo /* call the helper function */
1224 RESTORE_ARGUMENT_REGISTERS
1226 mov (1+15)*8(%rsp),itmp3 /* get machine code */
1227 add $((2+15)*8),%rsp /* remove stack frame, keep ra */
1229 test v0,v0 /* exception thrown? */
1230 jz L_asm_patcher_exception
1232 pop itmp2 /* get return address */
1233 sub $5,itmp2 /* remove size of `call rel32' */
1234 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
1236 mov offmethodclass(v0),itmp3 /* ci = lm->class */
1237 mov offclassindex(itmp3),itmp3l /* ci->index (s4) */
1238 shl $3,itmp3l /* * sizeof(methodptr) */
1239 neg itmp3l /* OFFSET(vftbl_t, interfacetable[0]) */
1240 /* XXX the offset is always 0!!! */
1241 mov itmp3l,3+3(itmp2) /* patch 32 bit offset: 3 (mov) + 3 */
1243 mov offmethodclass(v0),itmp3 /* ci = lm->class */
1244 sub offclassmethods(itmp3),v0 /* lm - ci->methods */
1248 mov $sizemethodinfo,itmp3l
1252 shl $3,v0 /* * sizeof(methodptr) */
1253 mov v0l,3+7+3(itmp2) /* patch 32bit offset: 3 + 7 (mov) + 3*/
1254 jmp *itmp2 /* call new patched code */
1257 /* asm_patcher_checkcast_instanceof_flags **************************************
1263 8 machine code (which is patched back later)
1264 0 unresolved field reference
1266 *******************************************************************************/
1268 asm_patcher_checkcast_instanceof_flags:
1269 sub $(17*8),%rsp /* stack frame (16-byte aligned) */
1271 SAVE_ARGUMENT_REGISTERS
1272 SAVE_TEMPORARY_REGISTERS
1274 mov itmp1,15*8(%rsp) /* save itmp1 and itmp2 */
1275 mov itmp2,16*8(%rsp) /* can be used by CHECKCAST */
1277 mov (0+17)*8(%rsp),a0 /* pass unresolved_method pointer */
1278 call helper_resolve_classinfo_flags /* call the helper function */
1280 RESTORE_ARGUMENT_REGISTERS
1281 RESTORE_TEMPORARY_REGISTERS
1283 cmp $-1,v0l /* exception thrown? test for -1, */
1284 /* because class flags can be 0 */
1285 jz L_asm_patcher_exception_with_stack_frame
1287 mov (1+17)*8(%rsp),itmp3 /* get machine code */
1288 mov (2+17)*8(%rsp),itmp2 /* get return address */
1289 sub $5,itmp2 /* remove size of `call rel32' */
1290 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
1292 mov v0l,2(itmp2) /* patch super->flags */
1294 mov itmp2,itmp3 /* move return address */
1295 mov 15*8(%rsp),itmp1 /* restore itmp1 and itmp2 */
1296 mov 16*8(%rsp),itmp2 /* can be used by field instructions */
1297 add $((3+17)*8),%rsp /* remove stack frame */
1298 jmp *itmp3 /* call new patched code */
1301 /* asm_patcher_checkcast_instanceof_interface **********************************
1307 8 machine code (which is patched back later)
1308 0 unresolved field reference
1310 *******************************************************************************/
1312 asm_patcher_checkcast_instanceof_interface:
1313 sub $(17*8),%rsp /* stack frame (16-byte aligned) */
1315 SAVE_ARGUMENT_REGISTERS
1316 SAVE_TEMPORARY_REGISTERS
1318 mov itmp1,15*8(%rsp) /* save itmp1 and itmp2 */
1319 mov itmp2,16*8(%rsp) /* can be used by CHECKCAST */
1321 mov (0+17)*8(%rsp),a0 /* pass unresolved_method pointer */
1322 call helper_resolve_classinfo_index /* call the helper function */
1324 RESTORE_ARGUMENT_REGISTERS
1325 RESTORE_TEMPORARY_REGISTERS
1327 cmp $-1,v0l /* exception thrown? test for -1, */
1328 /* because class index can be 0 */
1329 jz L_asm_patcher_exception_with_stack_frame
1331 mov (1+17)*8(%rsp),itmp3 /* get machine code */
1332 mov (2+17)*8(%rsp),itmp2 /* get return address */
1333 sub $5,itmp2 /* remove size of `call rel32' */
1334 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
1336 mov v0l,7+3(itmp2) /* patch super->index */
1338 shl $3,v0l /* super->index * sizeof(methodptr) */
1339 neg v0l /* OFFSET(vftbl_t, interfacetable[0]) */
1340 /* XXX the offset is always 0!!! */
1341 mov v0l,7+7+3+6+3(itmp2) /* patch calculated value */
1343 mov itmp2,itmp3 /* move return address */
1344 mov 15*8(%rsp),itmp1 /* restore itmp1 and itmp2 */
1345 mov 16*8(%rsp),itmp2 /* can be used by field instructions */
1346 add $((3+17)*8),%rsp /* remove stack frame */
1347 jmp *itmp3 /* call new patched code */
1350 /* asm_patcher_checkcast_class *************************************************
1356 8 machine code (which is patched back later)
1357 0 unresolved field reference
1359 *******************************************************************************/
1361 asm_patcher_checkcast_class:
1362 sub $(17*8),%rsp /* stack frame (16-byte aligned) */
1364 SAVE_ARGUMENT_REGISTERS
1365 SAVE_TEMPORARY_REGISTERS
1367 mov itmp1,15*8(%rsp) /* save itmp1 and itmp2 */
1368 mov itmp2,16*8(%rsp) /* can be used by CHECKCAST */
1370 mov (0+17)*8(%rsp),a0 /* pass unresolved_method pointer */
1371 call helper_resolve_classinfo_vftbl /* call the helper function */
1373 RESTORE_ARGUMENT_REGISTERS
1374 RESTORE_TEMPORARY_REGISTERS
1376 test v0,v0 /* exception thrown? */
1377 jz L_asm_patcher_exception_with_stack_frame
1379 mov (1+17)*8(%rsp),itmp3 /* get machine code */
1380 mov (2+17)*8(%rsp),itmp2 /* get return address */
1381 sub $5,itmp2 /* remove size of `call rel32' */
1382 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
1384 mov v0,2(itmp2) /* patch super->vftbl */
1385 mov v0,10+7+7+3+2(itmp2) /* patch super->vftbl */
1387 mov itmp2,itmp3 /* move return address */
1388 mov 15*8(%rsp),itmp1 /* restore itmp1 and itmp2 */
1389 mov 16*8(%rsp),itmp2
1390 add $((3+17)*8),%rsp /* remove stack frame */
1391 jmp *itmp3 /* call new patched code */
1394 /* asm_patcher_instanceof_class ************************************************
1400 8 machine code (which is patched back later)
1401 0 unresolved field reference
1403 *******************************************************************************/
1405 asm_patcher_instanceof_class:
1406 sub $(17*8),%rsp /* stack frame (16-byte aligned) */
1408 SAVE_ARGUMENT_REGISTERS
1409 SAVE_TEMPORARY_REGISTERS
1411 mov itmp1,15*8(%rsp) /* save itmp1 and itmp2 */
1412 mov itmp2,16*8(%rsp) /* can be used by INSTANCEOF */
1414 mov (0+17)*8(%rsp),a0 /* pass unresolved_method pointer */
1415 call helper_resolve_classinfo_vftbl /* call the helper function */
1417 RESTORE_ARGUMENT_REGISTERS
1418 RESTORE_TEMPORARY_REGISTERS
1420 test v0,v0 /* exception thrown? */
1421 jz L_asm_patcher_exception_with_stack_frame
1423 mov (1+17)*8(%rsp),itmp3 /* get machine code */
1424 mov (2+17)*8(%rsp),itmp2 /* get return address */
1425 sub $5,itmp2 /* remove size of `call rel32' */
1426 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
1428 mov v0,2(itmp2) /* patch super->vftbl */
1430 mov itmp2,itmp3 /* move return address */
1431 mov 15*8(%rsp),itmp1 /* restore itmp1 and itmp2 */
1432 mov 16*8(%rsp),itmp2
1433 add $((3+17)*8),%rsp /* remove stack frame */
1434 jmp *itmp3 /* call new patched code */
1437 /* asm_check_clinit ************************************************************
1443 8 machine code (which is patched back later)
1446 *******************************************************************************/
1449 mov 0*8(%rsp),itmp1 /* get classinfo pointer */
1450 mov offclassinit(itmp1),itmp2l /* get initialized flag (int) */
1452 jnz L_asm_check_clinit_is_initialized
1454 sub $(15*8),%rsp /* keep stack 16-byte aligned */
1456 SAVE_ARGUMENT_REGISTERS
1457 SAVE_TEMPORARY_REGISTERS
1459 mov (0+15)*8(%rsp),a0 /* pass classinfo pointer */
1460 call initialize_class /* call class initialize function */
1462 RESTORE_ARGUMENT_REGISTERS
1463 RESTORE_TEMPORARY_REGISTERS
1465 add $(15*8),%rsp /* remove stack frame, keep ra */
1467 test v0,v0 /* exception thrown? */
1468 je L_asm_check_clinit_exception
1470 L_asm_check_clinit_is_initialized:
1471 add $(1*8),%rsp /* remove classinfo pointer */
1472 pop itmp3 /* get machine code */
1473 pop itmp2 /* get return address */
1474 sub $5,itmp2 /* remove size of `call rel32' */
1475 mov itmp3,(itmp2) /* patch back in 8 bytes */
1476 jmp *itmp2 /* jump to patched code an execute it */
1478 L_asm_check_clinit_exception:
1479 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1480 call builtin_asm_get_exceptionptrptr
1483 lea _exceptionptr,itmp2
1485 mov (itmp2),xptr /* get the exception pointer */
1486 movl $0,(itmp2) /* clear the exception pointer */
1488 add $(2*8),%rsp /* remove stack frame, keep ra */
1489 pop xpc /* delete return address */
1490 sub $5,xpc /* faulting address is ra - 5 */
1491 jmp asm_handle_exception
1494 /********************* function asm_builtin_monitorenter ***********************
1496 * Does null check and calls monitorenter or throws an exception *
1498 *******************************************************************************/
1500 #if defined(USE_THREADS)
1501 asm_builtin_monitorenter:
1503 je nb_monitorenter /* if (null) throw exception */
1504 jmp builtin_monitorenter /* else call builtin_monitorenter */
1507 call new_nullpointerexception
1508 pop %r10 /* delete return address */
1509 sub $3,%r10 /* faulting address is ra - 3 */
1510 jmp asm_handle_exception
1514 /********************* function asm_builtin_monitorexit ************************
1516 * Does null check and calls monitorexit or throws an exception *
1518 *******************************************************************************/
1520 #if defined(USE_THREADS)
1521 asm_builtin_monitorexit:
1523 je nb_monitorexit /* if (null) throw exception */
1524 jmp builtin_monitorexit /* else call builtin_monitorenter */
1527 call new_nullpointerexception
1528 pop %r10 /* delete return address */
1529 sub $3,%r10 /* faulting address is ra - 3 */
1530 jmp asm_handle_exception
1534 /********************* function asm_builtin_x2x ********************************
1536 * Wrapper functions for float to int corner cases *
1538 *******************************************************************************/
1543 SAVE_ARGUMENT_REGISTERS
1548 RESTORE_ARGUMENT_REGISTERS
1557 SAVE_ARGUMENT_REGISTERS
1562 RESTORE_ARGUMENT_REGISTERS
1571 SAVE_ARGUMENT_REGISTERS
1576 RESTORE_ARGUMENT_REGISTERS
1585 SAVE_ARGUMENT_REGISTERS
1590 RESTORE_ARGUMENT_REGISTERS
1596 /* asm_builtin_checkarraycast **************************************************
1598 Does the cast check and eventually throws an exception.
1600 *******************************************************************************/
1602 asm_builtin_checkarraycast:
1603 sub $24,%rsp /* keep stack 16-byte aligned */
1604 mov %rdi,(%rsp) /* save object pointer */
1605 call builtin_checkarraycast /* builtin_checkarraycast */
1606 test %rax,%rax /* if (false) throw exception */
1608 mov (%rsp),%rax /* return object pointer */
1609 add $24,%rsp /* free stack space */
1613 call new_classcastexception
1615 pop %r10 /* delete return address */
1616 sub $3,%r10 /* faulting address is ra - 3 */
1617 jmp asm_handle_exception
1620 /* asm_builtin_aastore *********************************************************
1622 Checks if the object can be stored in the given array and stores the
1623 address if it's possible. This function can also throw some exceptions.
1625 *******************************************************************************/
1627 asm_builtin_aastore:
1628 sub $(3*8),%rsp /* allocate stack space */
1629 test %rdi,%rdi /* if null pointer throw exception */
1632 movl offarraysize(%rdi),%eax /* load size */
1633 cmpl %eax,%esi /* do bound check */
1634 jae nb_aastore_bound /* if out of bounds throw exception */
1636 shl $3,%rsi /* index * 8 */
1638 add %rsi,%r10 /* add index * 8 to arrayref */
1640 mov %r10,(%rsp) /* save store position */
1641 mov %rdx,8(%rsp) /* save object */
1643 mov %rdx,%rsi /* object is second argument */
1644 call builtin_canstore /* builtin_canstore(arrayref,object) */
1645 test %rax,%rax /* if (false) throw exception */
1648 mov (%rsp),%r10 /* restore store position */
1649 mov 8(%rsp),%rdx /* restore object */
1650 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1651 add $(3*8),%rsp /* free stack space */
1655 call new_nullpointerexception
1657 pop %r10 /* delete return address */
1658 sub $3,%r10 /* faulting address is return adress - 3 */
1659 jmp asm_handle_exception
1662 mov %rsi,%rdi /* move index into a0 */
1663 call new_arrayindexoutofboundsexception
1665 pop %r10 /* delete return address */
1666 sub $3,%r10 /* faulting address is return adress - 3 */
1667 jmp asm_handle_exception
1670 call new_arraystoreexception
1672 pop %r10 /* delete return address */
1673 sub $3,%r10 /* faulting address is return adress - 3 */
1674 jmp asm_handle_exception
1677 /******************* function asm_initialize_thread_stack **********************
1679 * initialized a thread stack *
1680 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1682 *******************************************************************************/
1684 asm_initialize_thread_stack:
1695 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1696 mov %rsi,%rax /* return restorepoint in %rax */
1700 /******************* function asm_perform_threadswitch *************************
1702 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1704 * performs a threadswitch *
1706 *******************************************************************************/
1708 asm_perform_threadswitch:
1709 sub $(7*8),%rsp /* allocate stack frame */
1718 mov 7*8(%rsp),%rax /* save current return address */
1721 mov %rsp,(%rdi) /* first argument **from */
1722 mov %rsp,(%rdx) /* third argument **stackTop */
1724 mov (%rsi),%rsp /* load new stack pointer */
1733 mov 6*8(%rsp),%rax /* restore return address */
1734 add $(7*8),%rsp /* free stack frame */
1739 /********************* function asm_switchstackandcall *************************
1741 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1744 * Switches to a new stack, calls a function and switches back. *
1745 * a0 (%rdi) new stack pointer *
1746 * a1 (%rsi) function pointer *
1747 * a2 (%rdx) pointer to variable where stack top should be stored *
1748 * a3 (%rcx) pointer to user data, is passed to the function *
1750 *******************************************************************************/
1752 asm_switchstackandcall:
1753 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1754 sub $16,%rdi /* allocate new stack */
1756 mov 8(%rsp),%rax /* save return address on new stack */
1758 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1759 mov %rsp,(%rdx) /* save old stack pointer to variable */
1761 mov %rdi,%rsp /* switch to new stack */
1763 mov %rcx,%rdi /* pass pointer */
1764 call *%rsi /* and call function */
1766 mov (%rsp),%r10 /* load return address */
1767 mov 8(%rsp),%rsp /* switch to old stack */
1768 add $(1*8),%rsp /* free stack space */
1769 mov %r10,(%rsp) /* write return adress */
1773 asm_getclassvalues_atomic:
1776 movl offbaseval(a0),itmp1l
1777 movl offdiffval(a0),itmp2l
1778 movl offbaseval(a1),itmp3l
1780 movl itmp1l,offcast_super_baseval(a2)
1781 movl itmp2l,offcast_super_diffval(a2)
1782 movl itmp3l,offcast_sub_baseval(a2)
1787 asm_criticalsections:
1788 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1791 .quad _crit_restart1
1794 .quad _crit_restart2
1800 * These are local overrides for various environment variables in Emacs.
1801 * Please do not remove this and leave it at the end of the file, where
1802 * Emacs will automagically detect them.
1803 * ---------------------------------------------------------------------
1806 * indent-tabs-mode: t