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 2238 2005-04-06 12:13:57Z 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 /* define it like the risc way */
81 /********************* exported functions and variables ***********************/
83 .globl asm_calljavafunction
84 .globl asm_calljavafunction_int
86 .globl asm_calljavafunction2
87 .globl asm_calljavafunction2int
88 .globl asm_calljavafunction2long
89 .globl asm_calljavafunction2float
90 .globl asm_calljavafunction2double
92 .globl asm_call_jit_compiler
93 .globl asm_handle_exception
94 .globl asm_handle_nat_exception
96 .globl asm_check_clinit
98 .globl asm_builtin_new
99 .globl asm_invokespecial
101 .globl asm_builtin_checkarraycast
102 .globl asm_builtin_aastore
104 #if defined(USE_THREADS)
105 .globl asm_builtin_monitorenter
106 .globl asm_builtin_monitorexit
109 .globl asm_builtin_f2i
110 .globl asm_builtin_f2l
111 .globl asm_builtin_d2i
112 .globl asm_builtin_d2l
114 .globl asm_perform_threadswitch
115 .globl asm_initialize_thread_stack
116 .globl asm_switchstackandcall
117 .globl asm_criticalsections
118 .globl asm_getclassvalues_atomic
121 /********************* function asm_calljavafunction ***************************
123 * This function calls a Java-method (which possibly needs compilation) *
124 * with up to 4 address parameters. *
126 * This functions calls the JIT-compiler which eventually translates the *
127 * method into machine code. *
130 * javaobject_header *asm_calljavamethod (methodinfo *m, *
131 * void *arg1, void *arg2, void *arg3, void *arg4); *
133 *******************************************************************************/
138 .quad 0 /* catch type all */
139 .quad calljava_xhandler /* handler pc */
140 .quad calljava_xhandler /* end pc */
141 .quad asm_calljavafunction /* start pc */
142 .long 1 /* extable size */
143 .long 0 /* fltsave */
144 .long 0 /* intsave */
147 .long 8 /* frame size */
148 .quad 0 /* method pointer (pointer to name) */
150 asm_calljavafunction:
151 asm_calljavafunction_int:
152 sub $(3*8),%rsp /* keep stack 16-byte aligned */
154 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
155 mov %rdi,%rax /* move function pointer to %rax */
156 /* compilerstub uses this */
158 mov %rsi,%rdi /* pass remaining parameters */
163 lea asm_call_jit_compiler,%r11
164 call *%r11 /* call JIT compiler */
168 add $(3*8),%rsp /* free stack space */
172 mov %rax,%rdi /* pass exception pointer */
173 call builtin_throw_exception
177 xor %rax,%rax /* return NULL */
181 /********************* function asm_calljavafunction ***************************
183 * This function calls a Java-method (which possibly needs compilation) *
184 * with up to 4 address parameters. *
186 * This functions calls the JIT-compiler which eventually translates the *
187 * method into machine code. *
190 * javaobject_header *asm_calljavamethod (methodinfo *m, *
191 * void *arg1, void *arg2, void *arg3, void *arg4); *
193 *******************************************************************************/
198 .quad 0 /* catch type all */
199 .quad calljava_xhandler2 /* handler pc */
200 .quad calljava_xhandler2 /* end pc */
201 .quad asm_calljavafunction2 /* start pc */
202 .long 1 /* extable size */
203 .long 0 /* fltsave */
204 .long 0 /* intsave */
207 .long 24 /* frame size */
208 .quad 0 /* method pointer (pointer to name) */
210 asm_calljavafunction2:
211 asm_calljavafunction2int:
212 asm_calljavafunction2long:
213 asm_calljavafunction2float:
214 asm_calljavafunction2double:
215 sub $(7*8),%rsp /* keep stack 16-byte aligned */
216 mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
223 mov %rdi,%rax /* move method pointer for compiler */
224 xor %rbp,%rbp /* set argument stack frame to zero */
226 test %rsi,%rsi /* maybe we have no args... */
229 mov %rsi,itmp3 /* arg count */
230 mov %rcx,itmp2 /* pointer to arg block */
232 mov itmp2,%r14 /* save argument block pointer */
233 mov itmp3,%r15 /* save argument count */
235 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
236 add $1,itmp3 /* initialize argument count */
237 xor %r12,%r12 /* initialize integer argument counter */
238 xor %r13,%r13 /* initialize float argument counter */
241 add $sizejniblock,itmp2 /* goto next argument block */
242 dec itmp3 /* argument count - 1 */
243 jz L_register_copy_done
244 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
245 jnz L_register_handle_float /* yes, handle it */
247 cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
248 je L_register_copy /* register? yes, next loop */
250 lea jumptable_integer,%rbp
251 mov 0(%rbp,%r12,8),%rbx
252 inc %r12 /* integer argument counter + 1 */
255 L_register_handle_float:
256 cmp $FLT_ARG_CNT,%r13 /* are we out of float argument */
257 je L_register_copy /* register? yes, next loop */
259 lea jumptable_float,%rbp
260 mov 0(%rbp,%r13,8),%rbx
261 inc %r13 /* float argument counter + 1 */
264 L_register_copy_done:
265 mov %r15,%rbp /* calculate remaining arguments */
266 sub %r12,%rbp /* - integer arguments in registers */
267 sub %r13,%rbp /* - float arguments in registers */
268 jle L_copy_done /* are all assigned to registers? */
270 shl $3,%rbp /* calculate stack size */
271 sub %rbp,%rsp /* stack frame for arguments */
272 mov %rsp,%rbx /* use %rbx as temp sp */
274 sub $sizejniblock,%r14 /* initialize pointer (smaller code) */
275 add $1,%r15 /* initialize argument count */
278 add $sizejniblock,%r14 /* goto next argument block */
279 dec %r15 /* are there any arguments left? */
280 jz L_copy_done /* no test needed after dec */
282 andb $0x02,offjniitemtype(%r14) /* is this a float/double type? */
283 jnz L_stack_handle_float
284 dec %r12 /* arguments assigned to registers */
285 jge L_stack_copy_loop
288 L_stack_handle_float:
289 dec %r13 /* arguments assigned to registers */
290 jge L_stack_copy_loop
293 mov offjniitem(%r14),itmp3 /* copy s8 argument onto stack */
295 add $8,%rbx /* increase sp to next argument */
296 jmp L_stack_copy_loop
299 lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
300 call *%r11 /* call JIT compiler */
302 add %rbp,%rsp /* remove argument stack frame if any */
304 mov 5*8(%rsp),%r15 /* restore callee saved registers */
310 add $(7*8),%rsp /* free stack space */
314 mov %rax,%rdi /* pass exception pointer */
315 call builtin_throw_exception
317 mov 5*8(%rsp),%r15 /* restore callee saved registers */
323 add $(7*8),%rsp /* free stack space */
324 xor %rax,%rax /* return NULL */
337 mov offjniitem(itmp2),a0
340 mov offjniitem(itmp2),a1
343 mov offjniitem(itmp2),a2
346 mov offjniitem(itmp2),a3
349 mov offjniitem(itmp2),a4
352 mov offjniitem(itmp2),a5
367 movq offjniitem(itmp2),fa0
370 movq offjniitem(itmp2),fa1
373 movq offjniitem(itmp2),fa2
376 movq offjniitem(itmp2),fa3
379 movq offjniitem(itmp2),fa4
382 movq offjniitem(itmp2),fa5
385 movq offjniitem(itmp2),fa6
388 movq offjniitem(itmp2),fa7
392 /****************** function asm_call_jit_compiler *****************************
394 * invokes the compiler for untranslated JavaVM methods. *
396 * Register R0 contains a pointer to the method info structure (prepared *
397 * by createcompilerstub). Using the return address in R26 and the *
398 * offset in the LDA instruction or using the value in methodptr R28 the *
399 * patching address for storing the method address can be computed: *
401 * method address was either loaded using *
403 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
404 * i386_call_reg(REG_ITMP2) *
408 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
409 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
410 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
411 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
412 * i386_call_reg(REG_ITMP1) *
414 * in the static case the method pointer can be computed using the *
415 * return address and the lda function following the jmp instruction *
417 *******************************************************************************/
419 asm_call_jit_compiler:
420 sub $8,%rsp /* keep stack 16-byte aligned */
422 mov %rbx,(%rsp) /* save register */
424 mov 8(%rsp),%r11 /* get return address */
425 mov -1(%r11),%bl /* get function code */
426 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
427 jne L_not_static_special
429 sub $11,%r11 /* calculate address of immediate */
430 jmp L_call_jit_compile
432 L_not_static_special:
433 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
434 jne L_not_virtual_interface
436 sub $7,%r11 /* calculate address of offset */
437 mov (%r11),%r11d /* get offset (32-bit) */
438 add %r10,%r11 /* add base address to get method address */
439 jmp L_call_jit_compile
441 L_not_virtual_interface: /* a call from asm_calljavamethod */
445 mov (%rsp),%rbx /* restore register */
447 sub $(24*8),%rsp /* 8 + 6*8 + 8*8 + 8*8 */
449 mov %r11,0*8(%rsp) /* save address for method pointer */
451 mov a0,1*8(%rsp) /* save arguments */
467 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
468 movq %xmm9,16*8(%rsp)
469 movq %xmm10,17*8(%rsp)
470 movq %xmm11,18*8(%rsp)
471 movq %xmm12,19*8(%rsp)
472 movq %xmm13,20*8(%rsp)
473 movq %xmm14,21*8(%rsp)
474 movq %xmm15,22*8(%rsp)
476 mov %rax,%rdi /* pass method pointer */
497 movq 15*8(%rsp),%xmm8
498 movq 16*8(%rsp),%xmm9
499 movq 17*8(%rsp),%xmm10
500 movq 18*8(%rsp),%xmm11
501 movq 19*8(%rsp),%xmm12
502 movq 20*8(%rsp),%xmm13
503 movq 21*8(%rsp),%xmm14
504 movq 22*8(%rsp),%xmm15
507 add $8,%rsp /* keep stack 16-byte aligned */
509 test %rax,%rax /* check for exception */
510 je L_asm_call_jit_compiler_exception
512 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
515 mov %rax,(%r11) /* and now save the new pointer */
518 jmp *%rax /* ...and now call the new method */
520 L_asm_call_jit_compiler_exception:
521 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
522 call builtin_asm_get_exceptionptrptr
525 lea _exceptionptr,itmp2
527 mov (itmp2),xptr /* get the exception pointer */
528 movl $0,(itmp2) /* clear the exception pointer */
530 pop xpc /* delete return address */
531 sub $5,xpc /* faulting address is ra - 5 */
533 jmp asm_handle_exception
536 /********************* function asm_handle_exception ***************************
538 * This function handles an exception. It does not use the usual calling *
539 * conventions. The exception pointer is passed in REG_ITMP1 and the *
540 * pc from the exception raising position is passed in REG_ITMP2. It searches *
541 * the local exception table for a handler. If no one is found, it unwinds *
542 * stacks and continues searching the callers. *
544 * void asm_handle_exception (exceptionptr, exceptionpc); *
546 *******************************************************************************/
548 asm_handle_nat_exception:
549 add $8,%rsp /* clear return address of native stub*/
551 asm_handle_exception:
553 mov xptr,0*8(%rsp) /* save exception pointer */
554 mov xpc,1*8(%rsp) /* save exception pc */
556 mov xpc,%rdi /* exception pc */
557 call codegen_findmethod
559 mov %rax,2*8(%rsp) /* save data segment pointer */
561 mov 0*8(%rsp),%rax /* restore exception pointer */
562 mov 1*8(%rsp),%r10 /* restore exception pc */
565 mov %rax,%rdi /* exception pointer */
566 mov MethodPointer(itmp3),%rsi /* method pointer */
567 mov xpc,%rdx /* exception pc */
569 mov $1,%r8 /* set noindent flag */
570 call builtin_trace_exception
572 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
573 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
574 test %rcx,%rcx /* if empty table skip */
577 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
578 mov 0*8(%rsp),xptr /* get xptr */
581 mov 1*8(%rsp),xpc /* get xpc */
583 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
584 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
585 jg ex_table_cont /* if (false) continue */
586 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
587 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
588 jge ex_table_cont /* if (false) continue */
589 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
590 test %rdx,%rdx /* NULL catches everything */
593 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
603 call load_class_bootstrap
612 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
631 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
639 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
640 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
641 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
642 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
643 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
645 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
647 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
651 cmp %edx,%esi /* xptr is instanceof catchtype */
655 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
657 mov 0*8(%rsp),%rax /* restore exception pointer */
658 add $(4*8),%rsp /* free stack frame */
660 jmp *xpc /* jump to the handler */
663 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
664 dec %rcx /* decrement entry counter */
665 test %rcx,%rcx /* if (t0 > 0) next entry */
669 mov 0*8(%rsp),%rax /* restore exception pointer */
670 mov 1*8(%rsp),%r10 /* restore exception pc */
671 mov 2*8(%rsp),%r11 /* restore data segment pointer */
674 mov %rax,%rcx /* save exception pointer */
677 movl IsSync(%r11),%eax /* %rax = SyncOffset */
678 test %rax,%rax /* if zero no monitorexit */
681 #if defined(USE_THREADS)
690 call builtin_monitorexit
699 mov FrameSize(%r11),%eax /* %eax = frame size */
700 add %rax,%rsp /* unwind stack */
701 mov %rsp,%rax /* %rax = pointer to save area */
703 mov IntSave(%r11),%edx /* %edx = saved int register count*/
730 shl $3,%edx /* multiply by 8 bytes */
734 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
757 movq -48(%rax),%xmm10
759 movq -40(%rax),%xmm11
761 movq -32(%rax),%xmm12
763 movq -24(%rax),%xmm13
765 movq -16(%rax),%xmm14
770 pop %r10 /* the new xpc is return address */
771 sub $3,%r10 /* subtract 3 bytes for call */
778 call codegen_findmethod /* get the new data segment ptr */
785 mov %rcx,%rax /* restore saved exception pointer*/
789 mov %rax,0*8(%rsp) /* save exception pointer */
790 mov %r10,1*8(%rsp) /* save exception pc */
791 mov %r11,2*8(%rsp) /* save data segment pointer */
796 /* asm_check_clinit ************************************************************
802 itmp1 class ; pointer to class
803 itmp2 mcode ; machine code to patch back in
807 0 ra ; return address of patched call in java machine code
809 *******************************************************************************/
812 mov offclassinit(itmp1),itmp3l /* get initialized flag (int) */
816 sub $(17*8),%rsp /* keep stack 16-byte aligned */
818 mov a0,0*8(%rsp) /* save argument registers */
825 movq fa0,6*8(%rsp) /* maybe cacao does not use all 8 */
826 movq fa1,7*8(%rsp) /* argument register, but who knows */
834 mov itmp2,14*8(%rsp) /* save machine code */
836 mov itmp1,a0 /* pass classinfo pointer */
837 call initialize_class /* call class initialize function */
839 mov 0*8(%rsp),a0 /* restore argument registers */
855 mov 14*8(%rsp),itmp2 /* restore machine code */
857 add $(17*8),%rsp /* remove stack frame */
859 test v0,v0 /* we had an exception */
860 je L_initializererror
863 pop itmp1 /* get return address */
864 sub $5,itmp1 /* remove size of `call rel32' */
865 mov itmp2,(itmp1) /* patch back in 8 bytes */
866 jmp *itmp1 /* jump to patched code an execute it */
869 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
870 call builtin_asm_get_exceptionptrptr
873 lea _exceptionptr,itmp2
875 mov (itmp2),xptr /* get the exception pointer */
876 movl $0,(itmp2) /* clear the exception pointer */
878 pop xpc /* delete return address */
879 sub $5,xpc /* faulting address is ra - 5 */
880 jmp asm_handle_exception
883 /* asm_builtin_new *************************************************************
888 a0 contains the class reference
890 *******************************************************************************/
893 sub $(8*1),%rsp /* stack frame (16-byte aligned) */
894 mov 8*1(%rsp),a1 /* get return address */
895 call asm_builtin_new_helper /* call the helper function */
896 add $(8*1),%rsp /* remove stack frame */
897 test v0,v0 /* exception thrown? */
898 jz L_asm_builtin_new_exception
900 pop itmp2 /* get return address */
901 sub $(3+10+10),itmp2 /* 3 (callq) + 10 (movi) + 10 (movi) */
902 mov v0,2(itmp2) /* patch in new classinfo*: 2 (mov) */
904 lea builtin_new,itmp1 /* get address from builtin_new */
905 mov itmp1,12(itmp2) /* patch back in function address */
906 jmp *itmp2 /* call new patched code */
908 L_asm_builtin_new_exception:
909 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
910 call builtin_asm_get_exceptionptrptr
913 lea _exceptionptr,itmp2
915 mov (itmp2),xptr /* get the exception pointer */
916 movl $0,(itmp2) /* clear the exception pointer */
918 pop xpc /* delete return address */
919 sub $5,xpc /* faulting address is ra - 5 */
920 jmp asm_handle_exception
923 /* asm_builtin_new *************************************************************
928 itmp1 contains the method reference
929 itmp2 machine code (which is patched back later)
931 *******************************************************************************/
934 sub $(7*8),%rsp /* stack frame (16-byte aligned) */
935 mov a0,0*8(%rsp) /* save argument registers */
942 mov itmp2,6*8(%rsp) /* save machine code */
944 mov itmp1,a0 /* pass unresolved_method pointer */
945 call asm_invokespecial_helper /* call the helper function */
947 mov 0*8(%rsp),a0 /* restore argument registers */
954 mov 6*8(%rsp),itmp3 /* restore machine code */
956 add $(7*8),%rsp /* remove stack frame */
957 test v0,v0 /* exception thrown? */
958 jz L_asm_builtin_new_exception
960 pop itmp2 /* get return address */
961 sub $5,itmp2 /* remove size of `call rel32' */
962 mov itmp3,(itmp2) /* patch back original code (8 bytes) */
964 mov v0,5(itmp2) /* patch stubroutine: 3 + 2 (mov) */
965 jmp *itmp2 /* call new patched code */
968 /********************* function asm_builtin_monitorenter ***********************
970 * Does null check and calls monitorenter or throws an exception *
972 *******************************************************************************/
974 #if defined(USE_THREADS)
975 asm_builtin_monitorenter:
977 je nb_monitorenter /* if (null) throw exception */
978 jmp builtin_monitorenter /* else call builtin_monitorenter */
981 call new_nullpointerexception
982 pop %r10 /* delete return address */
983 sub $3,%r10 /* faulting address is ra - 3 */
984 jmp asm_handle_exception
988 /********************* function asm_builtin_monitorexit ************************
990 * Does null check and calls monitorexit or throws an exception *
992 *******************************************************************************/
994 #if defined(USE_THREADS)
995 asm_builtin_monitorexit:
997 je nb_monitorexit /* if (null) throw exception */
998 jmp builtin_monitorexit /* else call builtin_monitorenter */
1001 call new_nullpointerexception
1002 pop %r10 /* delete return address */
1003 sub $3,%r10 /* faulting address is ra - 3 */
1004 jmp asm_handle_exception
1008 /********************* function asm_builtin_x2x ********************************
1010 * Wrapper functions for float to int corner cases *
1012 *******************************************************************************/
1024 movq %xmm0,6*8(%rsp)
1025 movq %xmm1,7*8(%rsp)
1026 movq %xmm2,8*8(%rsp)
1027 movq %xmm3,9*8(%rsp)
1028 movq %xmm4,10*8(%rsp)
1029 movq %xmm5,11*8(%rsp)
1030 movq %xmm6,12*8(%rsp)
1031 movq %xmm7,13*8(%rsp)
1043 movq 6*8(%rsp),%xmm0
1044 movq 7*8(%rsp),%xmm1
1045 movq 8*8(%rsp),%xmm2
1046 movq 9*8(%rsp),%xmm3
1047 movq 10*8(%rsp),%xmm4
1048 movq 11*8(%rsp),%xmm5
1049 movq 12*8(%rsp),%xmm6
1050 movq 13*8(%rsp),%xmm7
1066 movq %xmm0,6*8(%rsp)
1067 movq %xmm1,7*8(%rsp)
1068 movq %xmm2,8*8(%rsp)
1069 movq %xmm3,9*8(%rsp)
1070 movq %xmm4,10*8(%rsp)
1071 movq %xmm5,11*8(%rsp)
1072 movq %xmm6,12*8(%rsp)
1073 movq %xmm7,13*8(%rsp)
1085 movq 6*8(%rsp),%xmm0
1086 movq 7*8(%rsp),%xmm1
1087 movq 8*8(%rsp),%xmm2
1088 movq 9*8(%rsp),%xmm3
1089 movq 10*8(%rsp),%xmm4
1090 movq 11*8(%rsp),%xmm5
1091 movq 12*8(%rsp),%xmm6
1092 movq 13*8(%rsp),%xmm7
1108 movq %xmm0,6*8(%rsp)
1109 movq %xmm1,7*8(%rsp)
1110 movq %xmm2,8*8(%rsp)
1111 movq %xmm3,9*8(%rsp)
1112 movq %xmm4,10*8(%rsp)
1113 movq %xmm5,11*8(%rsp)
1114 movq %xmm6,12*8(%rsp)
1115 movq %xmm7,13*8(%rsp)
1127 movq 6*8(%rsp),%xmm0
1128 movq 7*8(%rsp),%xmm1
1129 movq 8*8(%rsp),%xmm2
1130 movq 9*8(%rsp),%xmm3
1131 movq 10*8(%rsp),%xmm4
1132 movq 11*8(%rsp),%xmm5
1133 movq 12*8(%rsp),%xmm6
1134 movq 13*8(%rsp),%xmm7
1150 movq %xmm0,6*8(%rsp)
1151 movq %xmm1,7*8(%rsp)
1152 movq %xmm2,8*8(%rsp)
1153 movq %xmm3,9*8(%rsp)
1154 movq %xmm4,10*8(%rsp)
1155 movq %xmm5,11*8(%rsp)
1156 movq %xmm6,12*8(%rsp)
1157 movq %xmm7,13*8(%rsp)
1169 movq 6*8(%rsp),%xmm0
1170 movq 7*8(%rsp),%xmm1
1171 movq 8*8(%rsp),%xmm2
1172 movq 9*8(%rsp),%xmm3
1173 movq 10*8(%rsp),%xmm4
1174 movq 11*8(%rsp),%xmm5
1175 movq 12*8(%rsp),%xmm6
1176 movq 13*8(%rsp),%xmm7
1182 /* asm_builtin_checkarraycast **************************************************
1184 Does the cast check and eventually throws an exception.
1186 *******************************************************************************/
1188 asm_builtin_checkarraycast:
1189 sub $24,%rsp /* keep stack 16-byte aligned */
1190 mov %rdi,(%rsp) /* save object pointer */
1191 call builtin_checkarraycast /* builtin_checkarraycast */
1192 test %rax,%rax /* if (false) throw exception */
1194 mov (%rsp),%rax /* return object pointer */
1195 add $24,%rsp /* free stack space */
1199 call new_classcastexception
1201 pop %r10 /* delete return address */
1202 sub $3,%r10 /* faulting address is ra - 3 */
1203 jmp asm_handle_exception
1206 /* asm_builtin_aastore *********************************************************
1208 Checks if the object can be stored in the given array and stores the
1209 address if it's possible. This function can also throw some exceptions.
1211 *******************************************************************************/
1213 asm_builtin_aastore:
1214 sub $(3*8),%rsp /* allocate stack space */
1215 test %rdi,%rdi /* if null pointer throw exception */
1218 movl offarraysize(%rdi),%eax /* load size */
1219 cmpl %eax,%esi /* do bound check */
1220 jae nb_aastore_bound /* if out of bounds throw exception */
1222 shl $3,%rsi /* index * 8 */
1224 add %rsi,%r10 /* add index * 8 to arrayref */
1226 mov %r10,(%rsp) /* save store position */
1227 mov %rdx,8(%rsp) /* save object */
1229 mov %rdx,%rsi /* object is second argument */
1230 call builtin_canstore /* builtin_canstore(arrayref,object) */
1231 test %rax,%rax /* if (false) throw exception */
1234 mov (%rsp),%r10 /* restore store position */
1235 mov 8(%rsp),%rdx /* restore object */
1236 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1237 add $(3*8),%rsp /* free stack space */
1241 call new_nullpointerexception
1243 pop %r10 /* delete return address */
1244 sub $3,%r10 /* faulting address is return adress - 3 */
1245 jmp asm_handle_exception
1248 mov %rsi,%rdi /* move index into a0 */
1249 call new_arrayindexoutofboundsexception
1251 pop %r10 /* delete return address */
1252 sub $3,%r10 /* faulting address is return adress - 3 */
1253 jmp asm_handle_exception
1256 call new_arraystoreexception
1258 pop %r10 /* delete return address */
1259 sub $3,%r10 /* faulting address is return adress - 3 */
1260 jmp asm_handle_exception
1263 /******************* function asm_initialize_thread_stack **********************
1265 * initialized a thread stack *
1266 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1268 *******************************************************************************/
1270 asm_initialize_thread_stack:
1281 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1282 mov %rsi,%rax /* return restorepoint in %rax */
1286 /******************* function asm_perform_threadswitch *************************
1288 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1290 * performs a threadswitch *
1292 *******************************************************************************/
1294 asm_perform_threadswitch:
1295 sub $(7*8),%rsp /* allocate stack frame */
1304 mov 7*8(%rsp),%rax /* save current return address */
1307 mov %rsp,(%rdi) /* first argument **from */
1308 mov %rsp,(%rdx) /* third argument **stackTop */
1310 mov (%rsi),%rsp /* load new stack pointer */
1319 mov 6*8(%rsp),%rax /* restore return address */
1320 add $(7*8),%rsp /* free stack frame */
1325 /********************* function asm_switchstackandcall *************************
1327 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1330 * Switches to a new stack, calls a function and switches back. *
1331 * a0 (%rdi) new stack pointer *
1332 * a1 (%rsi) function pointer *
1333 * a2 (%rdx) pointer to variable where stack top should be stored *
1334 * a3 (%rcx) pointer to user data, is passed to the function *
1336 *******************************************************************************/
1338 asm_switchstackandcall:
1339 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1340 sub $16,%rdi /* allocate new stack */
1342 mov 8(%rsp),%rax /* save return address on new stack */
1344 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1345 mov %rsp,(%rdx) /* save old stack pointer to variable */
1347 mov %rdi,%rsp /* switch to new stack */
1349 mov %rcx,%rdi /* pass pointer */
1350 call *%rsi /* and call function */
1352 mov (%rsp),%r10 /* load return address */
1353 mov 8(%rsp),%rsp /* switch to old stack */
1354 add $(1*8),%rsp /* free stack space */
1355 mov %r10,(%rsp) /* write return adress */
1359 asm_getclassvalues_atomic:
1362 movl offbaseval(a0),itmp1l
1363 movl offdiffval(a0),itmp2l
1364 movl offbaseval(a1),itmp3l
1366 movl itmp1l,offcast_super_baseval(a2)
1367 movl itmp2l,offcast_super_diffval(a2)
1368 movl itmp3l,offcast_sub_baseval(a2)
1373 asm_criticalsections:
1374 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1377 .quad _crit_restart1
1380 .quad _crit_restart2
1386 * These are local overrides for various environment variables in Emacs.
1387 * Please do not remove this and leave it at the end of the file, where
1388 * Emacs will automagically detect them.
1389 * ---------------------------------------------------------------------
1392 * indent-tabs-mode: t