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 2201 2005-04-03 21:48:11Z 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
95 .globl asm_check_clinit
96 .globl asm_builtin_checkarraycast
97 .globl asm_builtin_aastore
99 #if defined(USE_THREADS)
100 .globl asm_builtin_monitorenter
101 .globl asm_builtin_monitorexit
104 .globl asm_builtin_f2i
105 .globl asm_builtin_f2l
106 .globl asm_builtin_d2i
107 .globl asm_builtin_d2l
109 .globl asm_perform_threadswitch
110 .globl asm_initialize_thread_stack
111 .globl asm_switchstackandcall
112 .globl asm_criticalsections
113 .globl asm_getclassvalues_atomic
116 /********************* function asm_calljavafunction ***************************
118 * This function calls a Java-method (which possibly needs compilation) *
119 * with up to 4 address parameters. *
121 * This functions calls the JIT-compiler which eventually translates the *
122 * method into machine code. *
125 * javaobject_header *asm_calljavamethod (methodinfo *m, *
126 * void *arg1, void *arg2, void *arg3, void *arg4); *
128 *******************************************************************************/
133 .quad 0 /* catch type all */
134 .quad calljava_xhandler /* handler pc */
135 .quad calljava_xhandler /* end pc */
136 .quad asm_calljavafunction /* start pc */
137 .long 1 /* extable size */
138 .long 0 /* fltsave */
139 .long 0 /* intsave */
142 .long 8 /* frame size */
143 .quad 0 /* method pointer (pointer to name) */
145 asm_calljavafunction:
146 asm_calljavafunction_int:
147 sub $(3*8),%rsp /* keep stack 16-byte aligned */
149 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
150 mov %rdi,%rax /* move function pointer to %rax */
151 /* compilerstub uses this */
153 mov %rsi,%rdi /* pass remaining parameters */
158 lea asm_call_jit_compiler,%r11
159 call *%r11 /* call JIT compiler */
163 add $(3*8),%rsp /* free stack space */
167 mov %rax,%rdi /* pass exception pointer */
168 call builtin_throw_exception
172 xor %rax,%rax /* return NULL */
176 /********************* function asm_calljavafunction ***************************
178 * This function calls a Java-method (which possibly needs compilation) *
179 * with up to 4 address parameters. *
181 * This functions calls the JIT-compiler which eventually translates the *
182 * method into machine code. *
185 * javaobject_header *asm_calljavamethod (methodinfo *m, *
186 * void *arg1, void *arg2, void *arg3, void *arg4); *
188 *******************************************************************************/
193 .quad 0 /* catch type all */
194 .quad calljava_xhandler2 /* handler pc */
195 .quad calljava_xhandler2 /* end pc */
196 .quad asm_calljavafunction2 /* start pc */
197 .long 1 /* extable size */
198 .long 0 /* fltsave */
199 .long 0 /* intsave */
202 .long 24 /* frame size */
203 .quad 0 /* method pointer (pointer to name) */
205 asm_calljavafunction2:
206 asm_calljavafunction2int:
207 asm_calljavafunction2long:
208 asm_calljavafunction2float:
209 asm_calljavafunction2double:
210 sub $(7*8),%rsp /* keep stack 16-byte aligned */
211 mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
218 mov %rdi,%rax /* move method pointer for compiler */
219 xor %rbp,%rbp /* set argument stack frame to zero */
221 test %rsi,%rsi /* maybe we have no args... */
224 mov %rsi,itmp3 /* arg count */
225 mov %rcx,itmp2 /* pointer to arg block */
227 mov itmp2,%r14 /* save argument block pointer */
228 mov itmp3,%r15 /* save argument count */
230 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
231 add $1,itmp3 /* initialize argument count */
232 xor %r12,%r12 /* initialize integer argument counter */
233 xor %r13,%r13 /* initialize float argument counter */
236 add $sizejniblock,itmp2 /* goto next argument block */
237 dec itmp3 /* argument count - 1 */
238 jz L_register_copy_done
239 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
240 jnz L_register_handle_float /* yes, handle it */
242 cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
243 je L_register_copy /* register? yes, next loop */
245 lea jumptable_integer,%rbp
246 mov 0(%rbp,%r12,8),%rbx
247 inc %r12 /* integer argument counter + 1 */
250 L_register_handle_float:
251 cmp $FLT_ARG_CNT,%r13 /* are we out of float argument */
252 je L_register_copy /* register? yes, next loop */
254 lea jumptable_float,%rbp
255 mov 0(%rbp,%r13,8),%rbx
256 inc %r13 /* float argument counter + 1 */
259 L_register_copy_done:
260 mov %r15,%rbp /* calculate remaining arguments */
261 sub %r12,%rbp /* - integer arguments in registers */
262 sub %r13,%rbp /* - float arguments in registers */
263 jle L_copy_done /* are all assigned to registers? */
265 shl $3,%rbp /* calculate stack size */
266 sub %rbp,%rsp /* stack frame for arguments */
267 mov %rsp,%rbx /* use %rbx as temp sp */
269 sub $sizejniblock,%r14 /* initialize pointer (smaller code) */
270 add $1,%r15 /* initialize argument count */
273 add $sizejniblock,%r14 /* goto next argument block */
274 dec %r15 /* are there any arguments left? */
275 jz L_copy_done /* no test needed after dec */
277 andb $0x02,offjniitemtype(%r14) /* is this a float/double type? */
278 jnz L_stack_handle_float
279 dec %r12 /* arguments assigned to registers */
280 jge L_stack_copy_loop
283 L_stack_handle_float:
284 dec %r13 /* arguments assigned to registers */
285 jge L_stack_copy_loop
288 mov offjniitem(%r14),itmp3 /* copy s8 argument onto stack */
290 add $8,%rbx /* increase sp to next argument */
291 jmp L_stack_copy_loop
294 lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
295 call *%r11 /* call JIT compiler */
297 add %rbp,%rsp /* remove argument stack frame if any */
299 mov 5*8(%rsp),%r15 /* restore callee saved registers */
305 add $(7*8),%rsp /* free stack space */
309 mov %rax,%rdi /* pass exception pointer */
310 call builtin_throw_exception
312 mov 5*8(%rsp),%r15 /* restore callee saved registers */
318 add $(7*8),%rsp /* free stack space */
319 xor %rax,%rax /* return NULL */
332 mov offjniitem(itmp2),a0
335 mov offjniitem(itmp2),a1
338 mov offjniitem(itmp2),a2
341 mov offjniitem(itmp2),a3
344 mov offjniitem(itmp2),a4
347 mov offjniitem(itmp2),a5
362 movq offjniitem(itmp2),fa0
365 movq offjniitem(itmp2),fa1
368 movq offjniitem(itmp2),fa2
371 movq offjniitem(itmp2),fa3
374 movq offjniitem(itmp2),fa4
377 movq offjniitem(itmp2),fa5
380 movq offjniitem(itmp2),fa6
383 movq offjniitem(itmp2),fa7
387 /****************** function asm_call_jit_compiler *****************************
389 * invokes the compiler for untranslated JavaVM methods. *
391 * Register R0 contains a pointer to the method info structure (prepared *
392 * by createcompilerstub). Using the return address in R26 and the *
393 * offset in the LDA instruction or using the value in methodptr R28 the *
394 * patching address for storing the method address can be computed: *
396 * method address was either loaded using *
398 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
399 * i386_call_reg(REG_ITMP2) *
403 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
404 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
405 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
406 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
407 * i386_call_reg(REG_ITMP1) *
409 * in the static case the method pointer can be computed using the *
410 * return address and the lda function following the jmp instruction *
412 *******************************************************************************/
414 asm_call_jit_compiler:
415 sub $8,%rsp /* keep stack 16-byte aligned */
417 mov %rbx,(%rsp) /* save register */
419 mov 8(%rsp),%r11 /* get return address */
420 mov -1(%r11),%bl /* get function code */
421 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
422 jne L_not_static_special
424 sub $11,%r11 /* calculate address of immediate */
425 jmp L_call_jit_compile
427 L_not_static_special:
428 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
429 jne L_not_virtual_interface
431 sub $7,%r11 /* calculate address of offset */
432 mov (%r11),%r11d /* get offset (32-bit) */
433 add %r10,%r11 /* add base address to get method address */
434 jmp L_call_jit_compile
436 L_not_virtual_interface: /* a call from asm_calljavamethod */
440 mov (%rsp),%rbx /* restore register */
442 sub $(24*8),%rsp /* 8 + 6*8 + 8*8 + 8*8 */
444 mov %r11,0*8(%rsp) /* save address for method pointer */
446 mov a0,1*8(%rsp) /* save arguments */
462 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
463 movq %xmm9,16*8(%rsp)
464 movq %xmm10,17*8(%rsp)
465 movq %xmm11,18*8(%rsp)
466 movq %xmm12,19*8(%rsp)
467 movq %xmm13,20*8(%rsp)
468 movq %xmm14,21*8(%rsp)
469 movq %xmm15,22*8(%rsp)
471 mov %rax,%rdi /* pass method pointer */
492 movq 15*8(%rsp),%xmm8
493 movq 16*8(%rsp),%xmm9
494 movq 17*8(%rsp),%xmm10
495 movq 18*8(%rsp),%xmm11
496 movq 19*8(%rsp),%xmm12
497 movq 20*8(%rsp),%xmm13
498 movq 21*8(%rsp),%xmm14
499 movq 22*8(%rsp),%xmm15
502 add $8,%rsp /* keep stack 16-byte aligned */
504 test %rax,%rax /* check for exception */
505 je L_asm_call_jit_compiler_exception
507 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
510 mov %rax,(%r11) /* and now save the new pointer */
513 jmp *%rax /* ...and now call the new method */
515 L_asm_call_jit_compiler_exception:
516 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
517 call builtin_asm_get_exceptionptrptr
520 lea _exceptionptr,itmp2
522 mov (itmp2),xptr /* get the exception pointer */
523 movl $0,(itmp2) /* clear the exception pointer */
525 pop xpc /* delete return address */
526 sub $5,xpc /* faulting address is ra - 5 */
528 jmp asm_handle_exception
531 /********************* function asm_handle_exception ***************************
533 * This function handles an exception. It does not use the usual calling *
534 * conventions. The exception pointer is passed in REG_ITMP1 and the *
535 * pc from the exception raising position is passed in REG_ITMP2. It searches *
536 * the local exception table for a handler. If no one is found, it unwinds *
537 * stacks and continues searching the callers. *
539 * void asm_handle_exception (exceptionptr, exceptionpc); *
541 *******************************************************************************/
543 asm_handle_nat_exception:
544 add $8,%rsp /* clear return address of native stub*/
546 asm_handle_exception:
548 mov xptr,0*8(%rsp) /* save exception pointer */
549 mov xpc,1*8(%rsp) /* save exception pc */
551 mov xpc,%rdi /* exception pc */
552 call codegen_findmethod
554 mov %rax,2*8(%rsp) /* save data segment pointer */
556 mov 0*8(%rsp),%rax /* restore exception pointer */
557 mov 1*8(%rsp),%r10 /* restore exception pc */
560 mov %rax,%rdi /* exception pointer */
561 mov MethodPointer(itmp3),%rsi /* method pointer */
562 mov xpc,%rdx /* exception pc */
564 mov $1,%r8 /* set noindent flag */
565 call builtin_trace_exception
567 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
568 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
569 test %rcx,%rcx /* if empty table skip */
572 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
573 mov 0*8(%rsp),xptr /* get xptr */
576 mov 1*8(%rsp),xpc /* get xpc */
578 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
579 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
580 jg ex_table_cont /* if (false) continue */
581 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
582 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
583 jge ex_table_cont /* if (false) continue */
584 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
585 test %rdx,%rdx /* NULL catches everything */
588 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
598 call load_class_bootstrap
607 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
626 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
634 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
635 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
636 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
637 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
638 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
640 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
642 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
646 cmp %edx,%esi /* xptr is instanceof catchtype */
650 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
652 mov 0*8(%rsp),%rax /* restore exception pointer */
653 add $(4*8),%rsp /* free stack frame */
655 jmp *xpc /* jump to the handler */
658 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
659 dec %rcx /* decrement entry counter */
660 test %rcx,%rcx /* if (t0 > 0) next entry */
664 mov 0*8(%rsp),%rax /* restore exception pointer */
665 mov 1*8(%rsp),%r10 /* restore exception pc */
666 mov 2*8(%rsp),%r11 /* restore data segment pointer */
669 mov %rax,%rcx /* save exception pointer */
672 movl IsSync(%r11),%eax /* %rax = SyncOffset */
673 test %rax,%rax /* if zero no monitorexit */
676 #if defined(USE_THREADS)
685 call builtin_monitorexit
694 mov FrameSize(%r11),%eax /* %eax = frame size */
695 add %rax,%rsp /* unwind stack */
696 mov %rsp,%rax /* %rax = pointer to save area */
698 mov IntSave(%r11),%edx /* %edx = saved int register count*/
725 shl $3,%edx /* multiply by 8 bytes */
729 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
752 movq -48(%rax),%xmm10
754 movq -40(%rax),%xmm11
756 movq -32(%rax),%xmm12
758 movq -24(%rax),%xmm13
760 movq -16(%rax),%xmm14
765 pop %r10 /* the new xpc is return address */
766 sub $3,%r10 /* subtract 3 bytes for call */
773 call codegen_findmethod /* get the new data segment ptr */
780 mov %rcx,%rax /* restore saved exception pointer*/
784 mov %rax,0*8(%rsp) /* save exception pointer */
785 mov %r10,1*8(%rsp) /* save exception pc */
786 mov %r11,2*8(%rsp) /* save data segment pointer */
791 /* asm_check_clinit ************************************************************
797 24 ra ; return address of patched call in java machine code
798 16 xmcode ; additional machine code (only for i386 and x86_64)
799 8 mcode ; machine code to patch back in
800 0 class ; pointer to class
802 *******************************************************************************/
806 mov offclassinit(itmp1),itmp1l /* get initialized flag (int) */
810 sub $(14*8),%rsp /* keep stack 16-byte aligned */
812 mov a0,0*8(%rsp) /* save argument registers */
819 movq fa0,6*8(%rsp) /* maybe cacao does not use all 8 */
820 movq fa1,7*8(%rsp) /* argument register, but who knows */
828 mov 14*8(%rsp),%rdi /* pass classinfo pointer */
829 call initialize_class /* call class initialize function */
831 mov 0*8(%rsp),a0 /* restore argument registers */
847 add $(14*8),%rsp /* remove stack frame */
849 test v0,v0 /* we had an exception */
850 je L_initializererror
853 mov 24(%rsp),itmp1 /* get return address */
854 sub $5,itmp1 /* remove size of `call rel32' */
856 mov 16(%rsp),itmp2 /* get xmcode machine code */
857 movb itmp2b,(itmp1) /* patch back in 1 byte */
858 mov 8(%rsp),itmp2 /* get mcode machine code */
859 movl itmp2l,1(itmp1) /* patch back in 4 bytes */
861 add $((3+1)*8),%rsp /* remove stub stack frame incl. ra */
863 jmp *itmp1 /* jump to patched code an execute it */
866 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
867 call builtin_asm_get_exceptionptrptr
870 lea _exceptionptr,itmp2
872 mov (itmp2),xptr /* get the exception pointer */
873 movl $0,(itmp2) /* clear the exception pointer */
875 add $(3*8),%rsp /* remove stub stack frame */
877 pop xpc /* delete return address */
878 sub $5,xpc /* faulting address is ra - 5 */
880 jmp asm_handle_exception
883 /********************* function asm_builtin_monitorenter ***********************
885 * Does null check and calls monitorenter or throws an exception *
887 *******************************************************************************/
889 #if defined(USE_THREADS)
890 asm_builtin_monitorenter:
892 je nb_monitorenter /* if (null) throw exception */
893 jmp builtin_monitorenter /* else call builtin_monitorenter */
896 call new_nullpointerexception
897 pop %r10 /* delete return address */
898 sub $3,%r10 /* faulting address is ra - 3 */
899 jmp asm_handle_exception
903 /********************* function asm_builtin_monitorexit ************************
905 * Does null check and calls monitorexit or throws an exception *
907 *******************************************************************************/
909 #if defined(USE_THREADS)
910 asm_builtin_monitorexit:
912 je nb_monitorexit /* if (null) throw exception */
913 jmp builtin_monitorexit /* else call builtin_monitorenter */
916 call new_nullpointerexception
917 pop %r10 /* delete return address */
918 sub $3,%r10 /* faulting address is ra - 3 */
919 jmp asm_handle_exception
923 /********************* function asm_builtin_x2x ********************************
925 * Wrapper functions for float to int corner cases *
927 *******************************************************************************/
943 movq %xmm4,10*8(%rsp)
944 movq %xmm5,11*8(%rsp)
945 movq %xmm6,12*8(%rsp)
946 movq %xmm7,13*8(%rsp)
962 movq 10*8(%rsp),%xmm4
963 movq 11*8(%rsp),%xmm5
964 movq 12*8(%rsp),%xmm6
965 movq 13*8(%rsp),%xmm7
985 movq %xmm4,10*8(%rsp)
986 movq %xmm5,11*8(%rsp)
987 movq %xmm6,12*8(%rsp)
988 movq %xmm7,13*8(%rsp)
1000 movq 6*8(%rsp),%xmm0
1001 movq 7*8(%rsp),%xmm1
1002 movq 8*8(%rsp),%xmm2
1003 movq 9*8(%rsp),%xmm3
1004 movq 10*8(%rsp),%xmm4
1005 movq 11*8(%rsp),%xmm5
1006 movq 12*8(%rsp),%xmm6
1007 movq 13*8(%rsp),%xmm7
1023 movq %xmm0,6*8(%rsp)
1024 movq %xmm1,7*8(%rsp)
1025 movq %xmm2,8*8(%rsp)
1026 movq %xmm3,9*8(%rsp)
1027 movq %xmm4,10*8(%rsp)
1028 movq %xmm5,11*8(%rsp)
1029 movq %xmm6,12*8(%rsp)
1030 movq %xmm7,13*8(%rsp)
1042 movq 6*8(%rsp),%xmm0
1043 movq 7*8(%rsp),%xmm1
1044 movq 8*8(%rsp),%xmm2
1045 movq 9*8(%rsp),%xmm3
1046 movq 10*8(%rsp),%xmm4
1047 movq 11*8(%rsp),%xmm5
1048 movq 12*8(%rsp),%xmm6
1049 movq 13*8(%rsp),%xmm7
1065 movq %xmm0,6*8(%rsp)
1066 movq %xmm1,7*8(%rsp)
1067 movq %xmm2,8*8(%rsp)
1068 movq %xmm3,9*8(%rsp)
1069 movq %xmm4,10*8(%rsp)
1070 movq %xmm5,11*8(%rsp)
1071 movq %xmm6,12*8(%rsp)
1072 movq %xmm7,13*8(%rsp)
1084 movq 6*8(%rsp),%xmm0
1085 movq 7*8(%rsp),%xmm1
1086 movq 8*8(%rsp),%xmm2
1087 movq 9*8(%rsp),%xmm3
1088 movq 10*8(%rsp),%xmm4
1089 movq 11*8(%rsp),%xmm5
1090 movq 12*8(%rsp),%xmm6
1091 movq 13*8(%rsp),%xmm7
1097 /* asm_builtin_checkarraycast **************************************************
1099 Does the cast check and eventually throws an exception.
1101 *******************************************************************************/
1103 asm_builtin_checkarraycast:
1104 sub $24,%rsp /* keep stack 16-byte aligned */
1105 mov %rdi,(%rsp) /* save object pointer */
1106 call builtin_checkarraycast /* builtin_checkarraycast */
1107 test %rax,%rax /* if (false) throw exception */
1109 mov (%rsp),%rax /* return object pointer */
1110 add $24,%rsp /* free stack space */
1114 call new_classcastexception
1116 pop %r10 /* delete return address */
1117 sub $3,%r10 /* faulting address is ra - 3 */
1118 jmp asm_handle_exception
1121 /* asm_builtin_aastore *********************************************************
1123 Checks if the object can be stored in the given array and stores the
1124 address if it's possible. This function can also throw some exceptions.
1126 *******************************************************************************/
1128 asm_builtin_aastore:
1129 sub $(3*8),%rsp /* allocate stack space */
1130 test %rdi,%rdi /* if null pointer throw exception */
1133 movl offarraysize(%rdi),%eax /* load size */
1134 cmpl %eax,%esi /* do bound check */
1135 jae nb_aastore_bound /* if out of bounds throw exception */
1137 shl $3,%rsi /* index * 8 */
1139 add %rsi,%r10 /* add index * 8 to arrayref */
1141 mov %r10,(%rsp) /* save store position */
1142 mov %rdx,8(%rsp) /* save object */
1144 mov %rdx,%rsi /* object is second argument */
1145 call builtin_canstore /* builtin_canstore(arrayref,object) */
1146 test %rax,%rax /* if (false) throw exception */
1149 mov (%rsp),%r10 /* restore store position */
1150 mov 8(%rsp),%rdx /* restore object */
1151 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1152 add $(3*8),%rsp /* free stack space */
1156 call new_nullpointerexception
1158 pop %r10 /* delete return address */
1159 sub $3,%r10 /* faulting address is return adress - 3 */
1160 jmp asm_handle_exception
1163 mov %rsi,%rdi /* move index into a0 */
1164 call new_arrayindexoutofboundsexception
1166 pop %r10 /* delete return address */
1167 sub $3,%r10 /* faulting address is return adress - 3 */
1168 jmp asm_handle_exception
1171 call new_arraystoreexception
1173 pop %r10 /* delete return address */
1174 sub $3,%r10 /* faulting address is return adress - 3 */
1175 jmp asm_handle_exception
1178 /******************* function asm_initialize_thread_stack **********************
1180 * initialized a thread stack *
1181 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1183 *******************************************************************************/
1185 asm_initialize_thread_stack:
1196 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1197 mov %rsi,%rax /* return restorepoint in %rax */
1201 /******************* function asm_perform_threadswitch *************************
1203 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1205 * performs a threadswitch *
1207 *******************************************************************************/
1209 asm_perform_threadswitch:
1210 sub $(7*8),%rsp /* allocate stack frame */
1219 mov 7*8(%rsp),%rax /* save current return address */
1222 mov %rsp,(%rdi) /* first argument **from */
1223 mov %rsp,(%rdx) /* third argument **stackTop */
1225 mov (%rsi),%rsp /* load new stack pointer */
1234 mov 6*8(%rsp),%rax /* restore return address */
1235 add $(7*8),%rsp /* free stack frame */
1240 /********************* function asm_switchstackandcall *************************
1242 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1245 * Switches to a new stack, calls a function and switches back. *
1246 * a0 (%rdi) new stack pointer *
1247 * a1 (%rsi) function pointer *
1248 * a2 (%rdx) pointer to variable where stack top should be stored *
1249 * a3 (%rcx) pointer to user data, is passed to the function *
1251 *******************************************************************************/
1253 asm_switchstackandcall:
1254 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1255 sub $16,%rdi /* allocate new stack */
1257 mov 8(%rsp),%rax /* save return address on new stack */
1259 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1260 mov %rsp,(%rdx) /* save old stack pointer to variable */
1262 mov %rdi,%rsp /* switch to new stack */
1264 mov %rcx,%rdi /* pass pointer */
1265 call *%rsi /* and call function */
1267 mov (%rsp),%r10 /* load return address */
1268 mov 8(%rsp),%rsp /* switch to old stack */
1269 add $(1*8),%rsp /* free stack space */
1270 mov %r10,(%rsp) /* write return adress */
1274 asm_getclassvalues_atomic:
1277 movl offbaseval(a0),itmp1l
1278 movl offdiffval(a0),itmp2l
1279 movl offbaseval(a1),itmp3l
1281 movl itmp1l,offcast_super_baseval(a2)
1282 movl itmp2l,offcast_super_diffval(a2)
1283 movl itmp3l,offcast_sub_baseval(a2)
1288 asm_criticalsections:
1289 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1292 .quad _crit_restart1
1295 .quad _crit_restart2
1301 * These are local overrides for various environment variables in Emacs.
1302 * Please do not remove this and leave it at the end of the file, where
1303 * Emacs will automagically detect them.
1304 * ---------------------------------------------------------------------
1307 * indent-tabs-mode: t