1 /* vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
32 $Id: asmpart.S 1621 2004-11-30 13:06:55Z twisti $
38 #include "vm/jit/x86_64/arch.h"
39 #include "vm/jit/x86_64/offsets.h"
42 #define MethodPointer -8
48 #define ExTableSize -32
49 #define ExTableStart -32
51 #define ExEntrySize -32
54 #define ExHandlerPC -24
55 #define ExCatchType -32
58 /* define it like the risc way */
97 /********************* exported functions and variables ***********************/
99 .globl asm_calljavafunction
100 .globl calljava_xhandler
101 .globl asm_calljavafunction2
102 .globl asm_calljavafunction2long
103 .globl asm_calljavafunction2double
104 .globl calljava_xhandler2
105 .globl asm_call_jit_compiler
106 .globl asm_handle_exception
107 .globl asm_handle_nat_exception
108 .globl asm_check_clinit
109 .globl asm_builtin_checkarraycast
110 .globl asm_builtin_anewarray
111 .globl asm_builtin_newarray_array
112 .globl asm_builtin_aastore
113 .globl asm_builtin_monitorenter
114 .globl asm_builtin_monitorexit
115 .globl asm_builtin_f2i
116 .globl asm_builtin_f2l
117 .globl asm_builtin_d2i
118 .globl asm_builtin_d2l
119 .globl asm_builtin_arrayinstanceof
120 .globl asm_perform_threadswitch
121 .globl asm_initialize_thread_stack
122 .globl asm_switchstackandcall
123 .globl asm_criticalsections
124 .globl asm_getclassvalues_atomic
127 /*************************** imported functions *******************************/
130 .globl builtin_monitorexit
131 .globl builtin_throw_exception
132 .globl builtin_trace_exception
133 .globl codegen_findmethod
136 /********************* function asm_calljavafunction ***************************
138 * This function calls a Java-method (which possibly needs compilation) *
139 * with up to 4 address parameters. *
141 * This functions calls the JIT-compiler which eventually translates the *
142 * method into machine code. *
145 * javaobject_header *asm_calljavamethod (methodinfo *m, *
146 * void *arg1, void *arg2, void *arg3, void *arg4); *
148 *******************************************************************************/
153 .quad 0 /* catch type all */
154 .quad calljava_xhandler /* handler pc */
155 .quad calljava_xhandler /* end pc */
156 .quad asm_calljavafunction /* start pc */
157 .long 1 /* extable size */
158 .long 0 /* fltsave */
159 .long 0 /* intsave */
162 .long 8 /* frame size */
163 .quad 0 /* method pointer (pointer to name) */
165 asm_calljavafunction:
166 sub $(3*8),%rsp /* keep stack 16-byte aligned */
168 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
169 mov %rdi,%rax /* move function pointer to %rax */
170 /* compilerstub uses this */
172 mov %rsi,%rdi /* pass remaining parameters */
177 lea asm_call_jit_compiler,%r11
178 call *%r11 /* call JIT compiler */
182 add $(3*8),%rsp /* free stack space */
186 mov %rax,%rdi /* pass exception pointer */
187 call builtin_throw_exception
194 /********************* function asm_calljavafunction ***************************
196 * This function calls a Java-method (which possibly needs compilation) *
197 * with up to 4 address parameters. *
199 * This functions calls the JIT-compiler which eventually translates the *
200 * method into machine code. *
203 * javaobject_header *asm_calljavamethod (methodinfo *m, *
204 * void *arg1, void *arg2, void *arg3, void *arg4); *
206 *******************************************************************************/
211 .quad 0 /* catch type all */
212 .quad calljava_xhandler2 /* handler pc */
213 .quad calljava_xhandler2 /* end pc */
214 .quad asm_calljavafunction2 /* start pc */
215 .long 1 /* extable size */
216 .long 0 /* fltsave */
217 .long 0 /* intsave */
220 .long 24 /* frame size */
221 .quad 0 /* method pointer (pointer to name) */
223 asm_calljavafunction2:
224 asm_calljavafunction2double:
225 asm_calljavafunction2long:
226 sub $(7*8),%rsp /* keep stack 16-byte aligned */
227 mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
234 mov %rdi,%rax /* move method pointer for compiler */
236 mov %rsi,itmp3 /* arg count */
237 mov %rcx,itmp2 /* pointer to arg block */
239 test itmp3,itmp3 /* maybe we have no args... */
242 mov itmp2,%r14 /* save argument block pointer */
243 mov itmp3,%r15 /* save argument count */
245 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
246 add $1,itmp3 /* initialize argument count */
247 xor %r12,%r12 /* initialize integer argument counter */
248 xor %r13,%r13 /* initialize float argument counter */
251 add $sizejniblock,itmp2 /* goto next argument block */
252 dec itmp3 /* argument count - 1 */
253 jz L_register_copy_done
254 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
255 jnz L_register_handle_float /* yes, handle it */
257 cmp $(INT_ARG_CNT - 1),%r12 /* are we out of integer argument */
258 je L_register_copy /* register? yes, next loop */
260 lea jumptable_integer,%rbp
261 mov 0(%rbp,%r12,8),%rbx
262 inc %r12 /* integer argument counter + 1 */
265 L_register_handle_float:
266 cmp $(FLT_ARG_CNT - 1),%r13 /* are we out of float argument */
267 je L_register_copy /* register? yes, next loop */
269 lea jumptable_float,%rbp
270 mov 0(%rbp,%r13,8),%rbx
271 inc %r13 /* float argument counter + 1 */
274 L_register_copy_done:
275 mov %r15,itmp3 /* calculate remaining arguments after */
276 sub %r12,itmp3 /* register copy */
278 jle L_copy_done /* are all assigned to registers? */
280 shl $3,itmp3 /* calculate stack size */
281 sub itmp3,%rsp /* stack frame for arguments */
282 mov %rsp,%rbx /* use %rbx as temp sp */
284 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
285 add $1,%r15 /* initialize argument count */
288 add $sizejniblock,itmp2 /* goto next argument block */
289 dec %r15 /* are there any arguments left? */
290 jz L_copy_done /* no test needed after dec */
292 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
293 jnz L_stack_handle_float
294 dec %r12 /* arguments assigned to registers */
295 jge L_stack_copy_loop
298 L_stack_handle_float:
299 dec %r13 /* arguments assigned to registers */
300 jge L_stack_copy_loop
303 mov offjniitem(itmp2),itmp3 /* copy s8 argument onto stack */
305 add $8,%rbx /* increase sp to next argument */
306 jmp L_stack_copy_loop
309 lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
310 call *%r11 /* call JIT compiler */
312 mov 5*8(%rsp),%r15 /* restore callee saved registers */
318 add $(7*8),%rsp /* free stack space */
322 mov %rax,%rdi /* pass exception pointer */
323 call builtin_throw_exception
325 mov 5*8(%rsp),%r15 /* restore callee saved registers */
331 add $(7*8),%rsp /* free stack space */
344 mov offjniitem(itmp2),a0
347 mov offjniitem(itmp2),a1
350 mov offjniitem(itmp2),a2
353 mov offjniitem(itmp2),a3
356 mov offjniitem(itmp2),a4
359 mov offjniitem(itmp2),a5
374 movq offjniitem(itmp2),fa0
377 movq offjniitem(itmp2),fa1
380 movq offjniitem(itmp2),fa2
383 movq offjniitem(itmp2),fa3
386 movq offjniitem(itmp2),fa4
389 movq offjniitem(itmp2),fa5
392 movq offjniitem(itmp2),fa6
395 movq offjniitem(itmp2),fa7
399 /****************** function asm_call_jit_compiler *****************************
401 * invokes the compiler for untranslated JavaVM methods. *
403 * Register R0 contains a pointer to the method info structure (prepared *
404 * by createcompilerstub). Using the return address in R26 and the *
405 * offset in the LDA instruction or using the value in methodptr R28 the *
406 * patching address for storing the method address can be computed: *
408 * method address was either loaded using *
410 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
411 * i386_call_reg(REG_ITMP2) *
415 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
416 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
417 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
418 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
419 * i386_call_reg(REG_ITMP1) *
421 * in the static case the method pointer can be computed using the *
422 * return address and the lda function following the jmp instruction *
424 *******************************************************************************/
426 asm_call_jit_compiler:
427 sub $8,%rsp /* keep stack 16-byte aligned */
429 mov %rbx,(%rsp) /* save register */
431 mov 8(%rsp),%r11 /* get return address */
432 mov -1(%r11),%bl /* get function code */
433 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
434 jne L_not_static_special
436 sub $11,%r11 /* calculate address of immediate */
437 jmp L_call_jit_compile
439 L_not_static_special:
440 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
441 jne L_not_virtual_interface
443 sub $7,%r11 /* calculate address of offset */
444 mov (%r11),%r11d /* get offset (32-bit) */
445 add %r10,%r11 /* add base address to get method address */
446 jmp L_call_jit_compile
448 L_not_virtual_interface: /* a call from asm_calljavamethod */
452 mov (%rsp),%rbx /* restore register */
454 sub $(24*8),%rsp /* 8 + 48 + 64 + 64 */
456 mov %r11,0*8(%rsp) /* save address for method pointer */
458 mov %rdi,1*8(%rsp) /* save arguments */
468 movq %xmm3,10*8(%rsp)
469 movq %xmm4,11*8(%rsp)
470 movq %xmm5,12*8(%rsp)
471 movq %xmm6,13*8(%rsp)
472 movq %xmm7,14*8(%rsp)
474 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
475 movq %xmm9,16*8(%rsp)
476 movq %xmm10,17*8(%rsp)
477 movq %xmm11,18*8(%rsp)
478 movq %xmm12,19*8(%rsp)
479 movq %xmm13,20*8(%rsp)
480 movq %xmm14,21*8(%rsp)
481 movq %xmm15,22*8(%rsp)
483 mov %rax,%rdi /* pass method pointer */
498 movq 10*8(%rsp),%xmm3
499 movq 11*8(%rsp),%xmm4
500 movq 12*8(%rsp),%xmm5
501 movq 13*8(%rsp),%xmm6
502 movq 14*8(%rsp),%xmm7
504 movq 15*8(%rsp),%xmm8
505 movq 16*8(%rsp),%xmm9
506 movq 17*8(%rsp),%xmm10
507 movq 18*8(%rsp),%xmm11
508 movq 19*8(%rsp),%xmm12
509 movq 20*8(%rsp),%xmm13
510 movq 21*8(%rsp),%xmm14
511 movq 22*8(%rsp),%xmm15
515 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
518 mov %rax,(%r11) /* and now save the new pointer */
521 add $8,%rsp /* keep stack 16-byte aligned */
522 jmp *%rax /* ...and now call the new method */
525 /********************* function asm_handle_exception ***************************
527 * This function handles an exception. It does not use the usual calling *
528 * conventions. The exception pointer is passed in REG_ITMP1 and the *
529 * pc from the exception raising position is passed in REG_ITMP2. It searches *
530 * the local exception table for a handler. If no one is found, it unwinds *
531 * stacks and continues searching the callers. *
533 * void asm_handle_exception (exceptionptr, exceptionpc); *
535 *******************************************************************************/
537 asm_handle_nat_exception:
538 add $8,%rsp /* clear return address of native stub*/
540 asm_handle_exception:
542 mov xptr,0*8(%rsp) /* save exception pointer */
543 mov xpc,1*8(%rsp) /* save exception pc */
545 mov xpc,%rdi /* exception pc */
546 call codegen_findmethod
548 mov %rax,2*8(%rsp) /* save data segment pointer */
550 mov 0*8(%rsp),%rax /* restore exception pointer */
551 mov 1*8(%rsp),%r10 /* restore exception pc */
554 mov %rax,%rdi /* exception pointer */
555 mov MethodPointer(itmp3),%rsi /* method pointer */
556 mov xpc,%rdx /* exception pc */
558 mov $1,%r8 /* set noindent flag */
559 call builtin_trace_exception
561 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
562 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
563 test %rcx,%rcx /* if empty table skip */
566 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
567 mov 0*8(%rsp),xptr /* get xptr */
570 mov 1*8(%rsp),xpc /* get xpc */
572 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
573 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
574 jg ex_table_cont /* if (false) continue */
575 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
576 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
577 jge ex_table_cont /* if (false) continue */
578 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
579 test %rdx,%rdx /* NULL catches everything */
582 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
601 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
620 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
628 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
629 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
630 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
631 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
632 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
634 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
636 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
640 cmp %edx,%esi /* xptr is instanceof catchtype */
644 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
646 mov 0*8(%rsp),%rax /* restore exception pointer */
647 add $(4*8),%rsp /* free stack frame */
649 jmp *xpc /* jump to the handler */
652 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
653 dec %rcx /* decrement entry counter */
654 test %rcx,%rcx /* if (t0 > 0) next entry */
658 mov 0*8(%rsp),%rax /* restore exception pointer */
659 mov 1*8(%rsp),%r10 /* restore exception pc */
660 mov 2*8(%rsp),%r11 /* restore data segment pointer */
663 mov %rax,%rcx /* save exception pointer */
666 movl IsSync(%r11),%eax /* %rax = SyncOffset */
667 test %rax,%rax /* if zero no monitorexit */
678 call builtin_monitorexit
686 mov FrameSize(%r11),%eax /* %eax = frame size */
687 add %rax,%rsp /* unwind stack */
688 mov %rsp,%rax /* %rax = pointer to save area */
690 mov IntSave(%r11),%edx /* %edx = saved int register count*/
717 shl $3,%edx /* multiply by 8 bytes */
721 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
744 movq -48(%rax),%xmm10
746 movq -40(%rax),%xmm11
748 movq -32(%rax),%xmm12
750 movq -24(%rax),%xmm13
752 movq -16(%rax),%xmm14
757 pop %r10 /* the new xpc is return address */
758 sub $3,%r10 /* subtract 3 bytes for call */
765 call codegen_findmethod /* get the new data segment ptr */
772 mov %rcx,%rax /* restore saved exception pointer*/
776 mov %rax,0*8(%rsp) /* save exception pointer */
777 mov %r10,1*8(%rsp) /* save exception pc */
778 mov %r11,2*8(%rsp) /* save data segment pointer */
783 /* asm_check_clinit ************************************************************
789 32 ra ; return address of patched call in java machine code
790 24 xmcode ; additional machine code (only for i386 and x86_64)
791 16 mcode ; machine code to patch back in
792 8 class ; pointer to class
793 0 sp ; stack pointer of java stack frame + return address
795 *******************************************************************************/
799 mov offclassinit(itmp1),itmp1l /* get initialized flag (int) */
803 sub $(15*8),%rsp /* keep stack 16-byte aligned */
805 mov %rdi,0*8(%rsp) /* save argument registers */
812 movq %xmm0,6*8(%rsp) /* maybe cacao does not use all 8 */
813 movq %xmm1,7*8(%rsp) /* argument register, but who knows */
816 movq %xmm4,10*8(%rsp)
817 movq %xmm5,11*8(%rsp)
818 movq %xmm6,12*8(%rsp)
819 movq %xmm7,13*8(%rsp)
821 mov 8+15*8(%rsp),%rdi /* pass classinfo pointer */
822 call class_init /* call class_init function */
824 mov 0*8(%rsp),%rdi /* restore argument registers */
835 movq 10*8(%rsp),%xmm4
836 movq 11*8(%rsp),%xmm5
837 movq 12*8(%rsp),%xmm6
838 movq 13*8(%rsp),%xmm7
842 test v0,v0 /* we had an exception */
843 je L_initializererror
846 mov 32(%rsp),itmp1 /* get return address */
847 sub $5,itmp1 /* remove size of `call rel32' */
849 mov 24(%rsp),itmp2 /* get xmcode machine code */
850 movb itmp2b,(itmp1) /* patch back in 1 byte */
851 mov 16(%rsp),itmp2 /* get mcode machine code */
852 movl itmp2l,1(itmp1) /* patch back in 4 bytes */
854 add $(5*8),%rsp /* remove stub stack frame incl. ra */
856 jmp *itmp1 /* jump to patched code an execute it */
859 add $(4*8),%rsp /* remove stub stack frame */
861 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
862 call builtin_asm_get_exceptionptrptr
864 mov (itmp2),xptr /* get the exception pointer */
865 movl $0,(itmp2) /* clear the exception pointer */
867 lea _exceptionptr,itmp2
868 mov (itmp2),xptr /* get the exception pointer */
869 movl $0,(itmp2) /* clear the exception pointer */
872 pop xpc /* delete return address */
873 sub $5,xpc /* faulting address is ra - 5 */
875 jmp asm_handle_exception
878 /********************* function asm_builtin_monitorenter ***********************
880 * Does null check and calls monitorenter or throws an exception *
882 *******************************************************************************/
884 asm_builtin_monitorenter:
886 je nb_monitorenter /* if (null) throw exception */
887 jmp builtin_monitorenter /* else call builtin_monitorenter */
890 call new_nullpointerexception
891 pop %r10 /* delete return address */
892 sub $3,%r10 /* faulting address is return adress - 3 */
893 jmp asm_handle_exception
896 /********************* function asm_builtin_monitorexit ************************
898 * Does null check and calls monitorexit or throws an exception *
900 *******************************************************************************/
902 asm_builtin_monitorexit:
904 je nb_monitorexit /* if (null) throw exception */
905 jmp builtin_monitorexit /* else call builtin_monitorenter */
908 call new_nullpointerexception
909 pop %r10 /* delete return address */
910 sub $3,%r10 /* faulting address is return adress - 3 */
911 jmp asm_handle_exception
914 /********************* function asm_builtin_x2x ********************************
916 * Wrapper functions for float to int corner cases *
918 *******************************************************************************/
934 movq %xmm4,10*8(%rsp)
935 movq %xmm5,11*8(%rsp)
936 movq %xmm6,12*8(%rsp)
937 movq %xmm7,13*8(%rsp)
953 movq 10*8(%rsp),%xmm4
954 movq 11*8(%rsp),%xmm5
955 movq 12*8(%rsp),%xmm6
956 movq 13*8(%rsp),%xmm7
976 movq %xmm4,10*8(%rsp)
977 movq %xmm5,11*8(%rsp)
978 movq %xmm6,12*8(%rsp)
979 movq %xmm7,13*8(%rsp)
995 movq 10*8(%rsp),%xmm4
996 movq 11*8(%rsp),%xmm5
997 movq 12*8(%rsp),%xmm6
998 movq 13*8(%rsp),%xmm7
1014 movq %xmm0,6*8(%rsp)
1015 movq %xmm1,7*8(%rsp)
1016 movq %xmm2,8*8(%rsp)
1017 movq %xmm3,9*8(%rsp)
1018 movq %xmm4,10*8(%rsp)
1019 movq %xmm5,11*8(%rsp)
1020 movq %xmm6,12*8(%rsp)
1021 movq %xmm7,13*8(%rsp)
1033 movq 6*8(%rsp),%xmm0
1034 movq 7*8(%rsp),%xmm1
1035 movq 8*8(%rsp),%xmm2
1036 movq 9*8(%rsp),%xmm3
1037 movq 10*8(%rsp),%xmm4
1038 movq 11*8(%rsp),%xmm5
1039 movq 12*8(%rsp),%xmm6
1040 movq 13*8(%rsp),%xmm7
1056 movq %xmm0,6*8(%rsp)
1057 movq %xmm1,7*8(%rsp)
1058 movq %xmm2,8*8(%rsp)
1059 movq %xmm3,9*8(%rsp)
1060 movq %xmm4,10*8(%rsp)
1061 movq %xmm5,11*8(%rsp)
1062 movq %xmm6,12*8(%rsp)
1063 movq %xmm7,13*8(%rsp)
1075 movq 6*8(%rsp),%xmm0
1076 movq 7*8(%rsp),%xmm1
1077 movq 8*8(%rsp),%xmm2
1078 movq 9*8(%rsp),%xmm3
1079 movq 10*8(%rsp),%xmm4
1080 movq 11*8(%rsp),%xmm5
1081 movq 12*8(%rsp),%xmm6
1082 movq 13*8(%rsp),%xmm7
1088 /******************* function asm_builtin_checkarraycast ***********************
1090 * Does the cast check and eventually throws an exception *
1092 *******************************************************************************/
1094 asm_builtin_checkarraycast:
1095 sub $24,%rsp /* keep stack 16-byte aligned */
1096 mov %rdi,(%rsp) /* save object pointer */
1097 call builtin_checkarraycast /* builtin_checkarraycast */
1098 test %rax,%rax /* if (false) throw exception */
1100 mov (%rsp),%rax /* return object pointer */
1101 add $24,%rsp /* free stack space */
1105 call new_classcastexception
1107 pop %r10 /* delete return address */
1108 sub $3,%r10 /* faulting address is return adress - 3 */
1109 jmp asm_handle_exception
1112 /******************* function asm_builtin_aastore ******************************
1114 * Does the cast check and eventually throws an exception *
1116 *******************************************************************************/
1118 asm_builtin_aastore:
1119 sub $(3*8),%rsp /* allocate stack space */
1120 test %rdi,%rdi /* if null pointer throw exception */
1123 movl offarraysize(%rdi),%eax /* load size */
1124 cmpl %eax,%esi /* do bound check */
1125 jae nb_aastore_bound /* if out of bounds throw exception */
1127 shl $3,%rsi /* index * 8 */
1129 add %rsi,%r10 /* add index * 8 to arrayref */
1131 mov %r10,(%rsp) /* save store position */
1132 mov %rdx,8(%rsp) /* save object */
1134 mov %rdx,%rsi /* object is second argument */
1135 call builtin_canstore /* builtin_canstore(arrayref,object) */
1136 test %rax,%rax /* if (false) throw exception */
1139 mov (%rsp),%r10 /* restore store position */
1140 mov 8(%rsp),%rdx /* restore object */
1141 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1142 add $(3*8),%rsp /* free stack space */
1146 call new_nullpointerexception
1148 pop %r10 /* delete return address */
1149 sub $3,%r10 /* faulting address is return adress - 3 */
1150 jmp asm_handle_exception
1153 mov %rsi,%rdi /* move index into a0 */
1154 call new_arrayindexoutofboundsexception
1156 pop %r10 /* delete return address */
1157 sub $3,%r10 /* faulting address is return adress - 3 */
1158 jmp asm_handle_exception
1161 call new_arraystoreexception
1163 pop %r10 /* delete return address */
1164 sub $3,%r10 /* faulting address is return adress - 3 */
1165 jmp asm_handle_exception
1168 /******************* function asm_initialize_thread_stack **********************
1170 * initialized a thread stack *
1171 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1173 *******************************************************************************/
1175 asm_initialize_thread_stack:
1186 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1187 mov %rsi,%rax /* return restorepoint in %rax */
1191 /******************* function asm_perform_threadswitch *************************
1193 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1195 * performs a threadswitch *
1197 *******************************************************************************/
1199 asm_perform_threadswitch:
1200 sub $(7*8),%rsp /* allocate stack frame */
1209 mov 7*8(%rsp),%rax /* save current return address */
1212 mov %rsp,(%rdi) /* first argument **from */
1213 mov %rsp,(%rdx) /* third argument **stackTop */
1215 mov (%rsi),%rsp /* load new stack pointer */
1224 mov 6*8(%rsp),%rax /* restore return address */
1225 add $(7*8),%rsp /* free stack frame */
1230 /********************* function asm_switchstackandcall *************************
1232 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1235 * Switches to a new stack, calls a function and switches back. *
1236 * a0 (%rdi) new stack pointer *
1237 * a1 (%rsi) function pointer *
1238 * a2 (%rdx) pointer to variable where stack top should be stored *
1239 * a3 (%rcx) pointer to user data, is passed to the function *
1241 *******************************************************************************/
1243 asm_switchstackandcall:
1244 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1245 sub $16,%rdi /* allocate new stack */
1247 mov 8(%rsp),%rax /* save return address on new stack */
1249 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1250 mov %rsp,(%rdx) /* save old stack pointer to variable */
1252 mov %rdi,%rsp /* switch to new stack */
1254 mov %rcx,%rdi /* pass pointer */
1255 call *%rsi /* and call function */
1257 mov (%rsp),%r10 /* load return address */
1258 mov 8(%rsp),%rsp /* switch to old stack */
1259 add $(1*8),%rsp /* free stack space */
1260 mov %r10,(%rsp) /* write return adress */
1264 asm_getclassvalues_atomic:
1267 movl offbaseval(a0),itmp1l
1268 movl offdiffval(a0),itmp2l
1269 movl offbaseval(a1),itmp3l
1271 movl itmp1l,offcast_super_baseval(a2)
1272 movl itmp2l,offcast_super_diffval(a2)
1273 movl itmp3l,offcast_sub_baseval(a2)
1278 asm_criticalsections:
1279 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1282 .quad _crit_restart1
1285 .quad _crit_restart2
1291 * These are local overrides for various environment variables in Emacs.
1292 * Please do not remove this and leave it at the end of the file, where
1293 * Emacs will automagically detect them.
1294 * ---------------------------------------------------------------------
1297 * indent-tabs-mode: t