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 1680 2004-12-04 12:02:08Z jowenn $
38 #include "vm/jit/x86_64/arch.h"
39 #include "vm/jit/x86_64/offsets.h"
40 #include "vm/jit/x86_64/asmoffsets.h"
43 /* define it like the risc way */
82 /********************* exported functions and variables ***********************/
84 .globl asm_calljavafunction
85 .globl calljava_xhandler
86 .globl asm_calljavafunction2
87 .globl asm_calljavafunction2long
88 .globl asm_calljavafunction2double
89 .globl calljava_xhandler2
90 .globl asm_call_jit_compiler
91 .globl asm_handle_exception
92 .globl asm_handle_nat_exception
93 .globl asm_check_clinit
94 .globl asm_builtin_checkarraycast
95 .globl asm_builtin_anewarray
96 .globl asm_builtin_newarray_array
97 .globl asm_builtin_aastore
98 .globl asm_builtin_monitorenter
99 .globl asm_builtin_monitorexit
100 .globl asm_builtin_f2i
101 .globl asm_builtin_f2l
102 .globl asm_builtin_d2i
103 .globl asm_builtin_d2l
104 .globl asm_builtin_arrayinstanceof
105 .globl asm_perform_threadswitch
106 .globl asm_initialize_thread_stack
107 .globl asm_switchstackandcall
108 .globl asm_criticalsections
109 .globl asm_getclassvalues_atomic
112 /*************************** imported functions *******************************/
115 .globl builtin_monitorexit
116 .globl builtin_throw_exception
117 .globl builtin_trace_exception
118 .globl codegen_findmethod
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 sub $(3*8),%rsp /* keep stack 16-byte aligned */
153 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
154 mov %rdi,%rax /* move function pointer to %rax */
155 /* compilerstub uses this */
157 mov %rsi,%rdi /* pass remaining parameters */
162 lea asm_call_jit_compiler,%r11
163 call *%r11 /* call JIT compiler */
167 add $(3*8),%rsp /* free stack space */
171 mov %rax,%rdi /* pass exception pointer */
172 call builtin_throw_exception
179 /********************* function asm_calljavafunction ***************************
181 * This function calls a Java-method (which possibly needs compilation) *
182 * with up to 4 address parameters. *
184 * This functions calls the JIT-compiler which eventually translates the *
185 * method into machine code. *
188 * javaobject_header *asm_calljavamethod (methodinfo *m, *
189 * void *arg1, void *arg2, void *arg3, void *arg4); *
191 *******************************************************************************/
196 .quad 0 /* catch type all */
197 .quad calljava_xhandler2 /* handler pc */
198 .quad calljava_xhandler2 /* end pc */
199 .quad asm_calljavafunction2 /* start pc */
200 .long 1 /* extable size */
201 .long 0 /* fltsave */
202 .long 0 /* intsave */
205 .long 24 /* frame size */
206 .quad 0 /* method pointer (pointer to name) */
208 asm_calljavafunction2:
209 asm_calljavafunction2double:
210 asm_calljavafunction2long:
211 sub $(7*8),%rsp /* keep stack 16-byte aligned */
212 mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
219 mov %rdi,%rax /* move method pointer for compiler */
221 mov %rsi,itmp3 /* arg count */
222 mov %rcx,itmp2 /* pointer to arg block */
224 test itmp3,itmp3 /* maybe we have no args... */
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 - 1),%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 - 1),%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,itmp3 /* calculate remaining arguments after */
261 sub %r12,itmp3 /* register copy */
263 jle L_copy_done /* are all assigned to registers? */
265 shl $3,itmp3 /* calculate stack size */
266 sub itmp3,%rsp /* stack frame for arguments */
267 mov %rsp,%rbx /* use %rbx as temp sp */
269 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
270 add $1,%r15 /* initialize argument count */
273 add $sizejniblock,itmp2 /* 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(itmp2) /* 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(itmp2),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 mov 5*8(%rsp),%r15 /* restore callee saved registers */
303 add $(7*8),%rsp /* free stack space */
307 mov %rax,%rdi /* pass exception pointer */
308 call builtin_throw_exception
310 mov 5*8(%rsp),%r15 /* restore callee saved registers */
316 add $(7*8),%rsp /* free stack space */
329 mov offjniitem(itmp2),a0
332 mov offjniitem(itmp2),a1
335 mov offjniitem(itmp2),a2
338 mov offjniitem(itmp2),a3
341 mov offjniitem(itmp2),a4
344 mov offjniitem(itmp2),a5
359 movq offjniitem(itmp2),fa0
362 movq offjniitem(itmp2),fa1
365 movq offjniitem(itmp2),fa2
368 movq offjniitem(itmp2),fa3
371 movq offjniitem(itmp2),fa4
374 movq offjniitem(itmp2),fa5
377 movq offjniitem(itmp2),fa6
380 movq offjniitem(itmp2),fa7
384 /****************** function asm_call_jit_compiler *****************************
386 * invokes the compiler for untranslated JavaVM methods. *
388 * Register R0 contains a pointer to the method info structure (prepared *
389 * by createcompilerstub). Using the return address in R26 and the *
390 * offset in the LDA instruction or using the value in methodptr R28 the *
391 * patching address for storing the method address can be computed: *
393 * method address was either loaded using *
395 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
396 * i386_call_reg(REG_ITMP2) *
400 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
401 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
402 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
403 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
404 * i386_call_reg(REG_ITMP1) *
406 * in the static case the method pointer can be computed using the *
407 * return address and the lda function following the jmp instruction *
409 *******************************************************************************/
411 asm_call_jit_compiler:
412 sub $8,%rsp /* keep stack 16-byte aligned */
414 mov %rbx,(%rsp) /* save register */
416 mov 8(%rsp),%r11 /* get return address */
417 mov -1(%r11),%bl /* get function code */
418 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
419 jne L_not_static_special
421 sub $11,%r11 /* calculate address of immediate */
422 jmp L_call_jit_compile
424 L_not_static_special:
425 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
426 jne L_not_virtual_interface
428 sub $7,%r11 /* calculate address of offset */
429 mov (%r11),%r11d /* get offset (32-bit) */
430 add %r10,%r11 /* add base address to get method address */
431 jmp L_call_jit_compile
433 L_not_virtual_interface: /* a call from asm_calljavamethod */
437 mov (%rsp),%rbx /* restore register */
439 sub $(24*8),%rsp /* 8 + 48 + 64 + 64 */
441 mov %r11,0*8(%rsp) /* save address for method pointer */
443 mov %rdi,1*8(%rsp) /* save arguments */
453 movq %xmm3,10*8(%rsp)
454 movq %xmm4,11*8(%rsp)
455 movq %xmm5,12*8(%rsp)
456 movq %xmm6,13*8(%rsp)
457 movq %xmm7,14*8(%rsp)
459 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
460 movq %xmm9,16*8(%rsp)
461 movq %xmm10,17*8(%rsp)
462 movq %xmm11,18*8(%rsp)
463 movq %xmm12,19*8(%rsp)
464 movq %xmm13,20*8(%rsp)
465 movq %xmm14,21*8(%rsp)
466 movq %xmm15,22*8(%rsp)
468 mov %rax,%rdi /* pass method pointer */
483 movq 10*8(%rsp),%xmm3
484 movq 11*8(%rsp),%xmm4
485 movq 12*8(%rsp),%xmm5
486 movq 13*8(%rsp),%xmm6
487 movq 14*8(%rsp),%xmm7
489 movq 15*8(%rsp),%xmm8
490 movq 16*8(%rsp),%xmm9
491 movq 17*8(%rsp),%xmm10
492 movq 18*8(%rsp),%xmm11
493 movq 19*8(%rsp),%xmm12
494 movq 20*8(%rsp),%xmm13
495 movq 21*8(%rsp),%xmm14
496 movq 22*8(%rsp),%xmm15
500 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
503 mov %rax,(%r11) /* and now save the new pointer */
506 add $8,%rsp /* keep stack 16-byte aligned */
507 jmp *%rax /* ...and now call the new method */
510 /********************* function asm_handle_exception ***************************
512 * This function handles an exception. It does not use the usual calling *
513 * conventions. The exception pointer is passed in REG_ITMP1 and the *
514 * pc from the exception raising position is passed in REG_ITMP2. It searches *
515 * the local exception table for a handler. If no one is found, it unwinds *
516 * stacks and continues searching the callers. *
518 * void asm_handle_exception (exceptionptr, exceptionpc); *
520 *******************************************************************************/
522 asm_handle_nat_exception:
523 add $8,%rsp /* clear return address of native stub*/
525 asm_handle_exception:
527 mov xptr,0*8(%rsp) /* save exception pointer */
528 mov xpc,1*8(%rsp) /* save exception pc */
530 mov xpc,%rdi /* exception pc */
531 call codegen_findmethod
533 mov %rax,2*8(%rsp) /* save data segment pointer */
535 mov 0*8(%rsp),%rax /* restore exception pointer */
536 mov 1*8(%rsp),%r10 /* restore exception pc */
539 mov %rax,%rdi /* exception pointer */
540 mov MethodPointer(itmp3),%rsi /* method pointer */
541 mov xpc,%rdx /* exception pc */
543 mov $1,%r8 /* set noindent flag */
544 call builtin_trace_exception
546 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
547 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
548 test %rcx,%rcx /* if empty table skip */
551 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
552 mov 0*8(%rsp),xptr /* get xptr */
555 mov 1*8(%rsp),xpc /* get xpc */
557 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
558 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
559 jg ex_table_cont /* if (false) continue */
560 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
561 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
562 jge ex_table_cont /* if (false) continue */
563 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
564 test %rdx,%rdx /* NULL catches everything */
567 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
586 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
605 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
613 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
614 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
615 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
616 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
617 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
619 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
621 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
625 cmp %edx,%esi /* xptr is instanceof catchtype */
629 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
631 mov 0*8(%rsp),%rax /* restore exception pointer */
632 add $(4*8),%rsp /* free stack frame */
634 jmp *xpc /* jump to the handler */
637 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
638 dec %rcx /* decrement entry counter */
639 test %rcx,%rcx /* if (t0 > 0) next entry */
643 mov 0*8(%rsp),%rax /* restore exception pointer */
644 mov 1*8(%rsp),%r10 /* restore exception pc */
645 mov 2*8(%rsp),%r11 /* restore data segment pointer */
648 mov %rax,%rcx /* save exception pointer */
651 movl IsSync(%r11),%eax /* %rax = SyncOffset */
652 test %rax,%rax /* if zero no monitorexit */
663 call builtin_monitorexit
671 mov FrameSize(%r11),%eax /* %eax = frame size */
672 add %rax,%rsp /* unwind stack */
673 mov %rsp,%rax /* %rax = pointer to save area */
675 mov IntSave(%r11),%edx /* %edx = saved int register count*/
702 shl $3,%edx /* multiply by 8 bytes */
706 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
729 movq -48(%rax),%xmm10
731 movq -40(%rax),%xmm11
733 movq -32(%rax),%xmm12
735 movq -24(%rax),%xmm13
737 movq -16(%rax),%xmm14
742 pop %r10 /* the new xpc is return address */
743 sub $3,%r10 /* subtract 3 bytes for call */
750 call codegen_findmethod /* get the new data segment ptr */
757 mov %rcx,%rax /* restore saved exception pointer*/
761 mov %rax,0*8(%rsp) /* save exception pointer */
762 mov %r10,1*8(%rsp) /* save exception pc */
763 mov %r11,2*8(%rsp) /* save data segment pointer */
768 /* asm_check_clinit ************************************************************
774 32 ra ; return address of patched call in java machine code
775 24 xmcode ; additional machine code (only for i386 and x86_64)
776 16 mcode ; machine code to patch back in
777 8 class ; pointer to class
778 0 sp ; stack pointer of java stack frame + return address
780 *******************************************************************************/
784 mov offclassinit(itmp1),itmp1l /* get initialized flag (int) */
788 sub $(15*8),%rsp /* keep stack 16-byte aligned */
790 mov %rdi,0*8(%rsp) /* save argument registers */
797 movq %xmm0,6*8(%rsp) /* maybe cacao does not use all 8 */
798 movq %xmm1,7*8(%rsp) /* argument register, but who knows */
801 movq %xmm4,10*8(%rsp)
802 movq %xmm5,11*8(%rsp)
803 movq %xmm6,12*8(%rsp)
804 movq %xmm7,13*8(%rsp)
806 mov 8+15*8(%rsp),%rdi /* pass classinfo pointer */
807 call class_init /* call class_init function */
809 mov 0*8(%rsp),%rdi /* restore argument registers */
820 movq 10*8(%rsp),%xmm4
821 movq 11*8(%rsp),%xmm5
822 movq 12*8(%rsp),%xmm6
823 movq 13*8(%rsp),%xmm7
827 test v0,v0 /* we had an exception */
828 je L_initializererror
831 mov 32(%rsp),itmp1 /* get return address */
832 sub $5,itmp1 /* remove size of `call rel32' */
834 mov 24(%rsp),itmp2 /* get xmcode machine code */
835 movb itmp2b,(itmp1) /* patch back in 1 byte */
836 mov 16(%rsp),itmp2 /* get mcode machine code */
837 movl itmp2l,1(itmp1) /* patch back in 4 bytes */
839 add $(5*8),%rsp /* remove stub stack frame incl. ra */
841 jmp *itmp1 /* jump to patched code an execute it */
844 add $(4*8),%rsp /* remove stub stack frame */
846 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
847 call builtin_asm_get_exceptionptrptr
849 mov (itmp2),xptr /* get the exception pointer */
850 movl $0,(itmp2) /* clear the exception pointer */
852 lea _exceptionptr,itmp2
853 mov (itmp2),xptr /* get the exception pointer */
854 movl $0,(itmp2) /* clear the exception pointer */
857 pop xpc /* delete return address */
858 sub $5,xpc /* faulting address is ra - 5 */
860 jmp asm_handle_exception
863 /********************* function asm_builtin_monitorenter ***********************
865 * Does null check and calls monitorenter or throws an exception *
867 *******************************************************************************/
869 asm_builtin_monitorenter:
871 je nb_monitorenter /* if (null) throw exception */
872 jmp builtin_monitorenter /* else call builtin_monitorenter */
875 call new_nullpointerexception
876 pop %r10 /* delete return address */
877 sub $3,%r10 /* faulting address is return adress - 3 */
878 jmp asm_handle_exception
881 /********************* function asm_builtin_monitorexit ************************
883 * Does null check and calls monitorexit or throws an exception *
885 *******************************************************************************/
887 asm_builtin_monitorexit:
889 je nb_monitorexit /* if (null) throw exception */
890 jmp builtin_monitorexit /* else call builtin_monitorenter */
893 call new_nullpointerexception
894 pop %r10 /* delete return address */
895 sub $3,%r10 /* faulting address is return adress - 3 */
896 jmp asm_handle_exception
899 /********************* function asm_builtin_x2x ********************************
901 * Wrapper functions for float to int corner cases *
903 *******************************************************************************/
919 movq %xmm4,10*8(%rsp)
920 movq %xmm5,11*8(%rsp)
921 movq %xmm6,12*8(%rsp)
922 movq %xmm7,13*8(%rsp)
938 movq 10*8(%rsp),%xmm4
939 movq 11*8(%rsp),%xmm5
940 movq 12*8(%rsp),%xmm6
941 movq 13*8(%rsp),%xmm7
961 movq %xmm4,10*8(%rsp)
962 movq %xmm5,11*8(%rsp)
963 movq %xmm6,12*8(%rsp)
964 movq %xmm7,13*8(%rsp)
980 movq 10*8(%rsp),%xmm4
981 movq 11*8(%rsp),%xmm5
982 movq 12*8(%rsp),%xmm6
983 movq 13*8(%rsp),%xmm7
1000 movq %xmm1,7*8(%rsp)
1001 movq %xmm2,8*8(%rsp)
1002 movq %xmm3,9*8(%rsp)
1003 movq %xmm4,10*8(%rsp)
1004 movq %xmm5,11*8(%rsp)
1005 movq %xmm6,12*8(%rsp)
1006 movq %xmm7,13*8(%rsp)
1018 movq 6*8(%rsp),%xmm0
1019 movq 7*8(%rsp),%xmm1
1020 movq 8*8(%rsp),%xmm2
1021 movq 9*8(%rsp),%xmm3
1022 movq 10*8(%rsp),%xmm4
1023 movq 11*8(%rsp),%xmm5
1024 movq 12*8(%rsp),%xmm6
1025 movq 13*8(%rsp),%xmm7
1041 movq %xmm0,6*8(%rsp)
1042 movq %xmm1,7*8(%rsp)
1043 movq %xmm2,8*8(%rsp)
1044 movq %xmm3,9*8(%rsp)
1045 movq %xmm4,10*8(%rsp)
1046 movq %xmm5,11*8(%rsp)
1047 movq %xmm6,12*8(%rsp)
1048 movq %xmm7,13*8(%rsp)
1060 movq 6*8(%rsp),%xmm0
1061 movq 7*8(%rsp),%xmm1
1062 movq 8*8(%rsp),%xmm2
1063 movq 9*8(%rsp),%xmm3
1064 movq 10*8(%rsp),%xmm4
1065 movq 11*8(%rsp),%xmm5
1066 movq 12*8(%rsp),%xmm6
1067 movq 13*8(%rsp),%xmm7
1073 /******************* function asm_builtin_checkarraycast ***********************
1075 * Does the cast check and eventually throws an exception *
1077 *******************************************************************************/
1079 asm_builtin_checkarraycast:
1080 sub $24,%rsp /* keep stack 16-byte aligned */
1081 mov %rdi,(%rsp) /* save object pointer */
1082 call builtin_checkarraycast /* builtin_checkarraycast */
1083 test %rax,%rax /* if (false) throw exception */
1085 mov (%rsp),%rax /* return object pointer */
1086 add $24,%rsp /* free stack space */
1090 call new_classcastexception
1092 pop %r10 /* delete return address */
1093 sub $3,%r10 /* faulting address is return adress - 3 */
1094 jmp asm_handle_exception
1097 /******************* function asm_builtin_aastore ******************************
1099 * Does the cast check and eventually throws an exception *
1101 *******************************************************************************/
1103 asm_builtin_aastore:
1104 sub $(3*8),%rsp /* allocate stack space */
1105 test %rdi,%rdi /* if null pointer throw exception */
1108 movl offarraysize(%rdi),%eax /* load size */
1109 cmpl %eax,%esi /* do bound check */
1110 jae nb_aastore_bound /* if out of bounds throw exception */
1112 shl $3,%rsi /* index * 8 */
1114 add %rsi,%r10 /* add index * 8 to arrayref */
1116 mov %r10,(%rsp) /* save store position */
1117 mov %rdx,8(%rsp) /* save object */
1119 mov %rdx,%rsi /* object is second argument */
1120 call builtin_canstore /* builtin_canstore(arrayref,object) */
1121 test %rax,%rax /* if (false) throw exception */
1124 mov (%rsp),%r10 /* restore store position */
1125 mov 8(%rsp),%rdx /* restore object */
1126 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1127 add $(3*8),%rsp /* free stack space */
1131 call new_nullpointerexception
1133 pop %r10 /* delete return address */
1134 sub $3,%r10 /* faulting address is return adress - 3 */
1135 jmp asm_handle_exception
1138 mov %rsi,%rdi /* move index into a0 */
1139 call new_arrayindexoutofboundsexception
1141 pop %r10 /* delete return address */
1142 sub $3,%r10 /* faulting address is return adress - 3 */
1143 jmp asm_handle_exception
1146 call new_arraystoreexception
1148 pop %r10 /* delete return address */
1149 sub $3,%r10 /* faulting address is return adress - 3 */
1150 jmp asm_handle_exception
1153 /******************* function asm_initialize_thread_stack **********************
1155 * initialized a thread stack *
1156 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1158 *******************************************************************************/
1160 asm_initialize_thread_stack:
1171 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1172 mov %rsi,%rax /* return restorepoint in %rax */
1176 /******************* function asm_perform_threadswitch *************************
1178 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1180 * performs a threadswitch *
1182 *******************************************************************************/
1184 asm_perform_threadswitch:
1185 sub $(7*8),%rsp /* allocate stack frame */
1194 mov 7*8(%rsp),%rax /* save current return address */
1197 mov %rsp,(%rdi) /* first argument **from */
1198 mov %rsp,(%rdx) /* third argument **stackTop */
1200 mov (%rsi),%rsp /* load new stack pointer */
1209 mov 6*8(%rsp),%rax /* restore return address */
1210 add $(7*8),%rsp /* free stack frame */
1215 /********************* function asm_switchstackandcall *************************
1217 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1220 * Switches to a new stack, calls a function and switches back. *
1221 * a0 (%rdi) new stack pointer *
1222 * a1 (%rsi) function pointer *
1223 * a2 (%rdx) pointer to variable where stack top should be stored *
1224 * a3 (%rcx) pointer to user data, is passed to the function *
1226 *******************************************************************************/
1228 asm_switchstackandcall:
1229 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1230 sub $16,%rdi /* allocate new stack */
1232 mov 8(%rsp),%rax /* save return address on new stack */
1234 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1235 mov %rsp,(%rdx) /* save old stack pointer to variable */
1237 mov %rdi,%rsp /* switch to new stack */
1239 mov %rcx,%rdi /* pass pointer */
1240 call *%rsi /* and call function */
1242 mov (%rsp),%r10 /* load return address */
1243 mov 8(%rsp),%rsp /* switch to old stack */
1244 add $(1*8),%rsp /* free stack space */
1245 mov %r10,(%rsp) /* write return adress */
1249 asm_getclassvalues_atomic:
1252 movl offbaseval(a0),itmp1l
1253 movl offdiffval(a0),itmp2l
1254 movl offbaseval(a1),itmp3l
1256 movl itmp1l,offcast_super_baseval(a2)
1257 movl itmp2l,offcast_super_diffval(a2)
1258 movl itmp3l,offcast_sub_baseval(a2)
1263 asm_criticalsections:
1264 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1267 .quad _crit_restart1
1270 .quad _crit_restart2
1276 * These are local overrides for various environment variables in Emacs.
1277 * Please do not remove this and leave it at the end of the file, where
1278 * Emacs will automagically detect them.
1279 * ---------------------------------------------------------------------
1282 * indent-tabs-mode: t