1 /* 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 1735 2004-12-07 14:33:27Z 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 calljava_xhandler
85 .globl asm_calljavafunction2
86 .globl asm_calljavafunction2long
87 .globl asm_calljavafunction2double
88 .globl calljava_xhandler2
89 .globl asm_call_jit_compiler
90 .globl asm_handle_exception
91 .globl asm_handle_nat_exception
92 .globl asm_check_clinit
93 .globl asm_builtin_checkarraycast
94 .globl asm_builtin_anewarray
95 .globl asm_builtin_newarray_array
96 .globl asm_builtin_aastore
97 .globl asm_builtin_monitorenter
98 .globl asm_builtin_monitorexit
99 .globl asm_builtin_f2i
100 .globl asm_builtin_f2l
101 .globl asm_builtin_d2i
102 .globl asm_builtin_d2l
103 .globl asm_builtin_arrayinstanceof
104 .globl asm_perform_threadswitch
105 .globl asm_initialize_thread_stack
106 .globl asm_switchstackandcall
107 .globl asm_criticalsections
108 .globl asm_getclassvalues_atomic
111 /*************************** imported functions *******************************/
114 .globl builtin_monitorexit
115 .globl builtin_throw_exception
116 .globl builtin_trace_exception
117 .globl codegen_findmethod
120 /********************* function asm_calljavafunction ***************************
122 * This function calls a Java-method (which possibly needs compilation) *
123 * with up to 4 address parameters. *
125 * This functions calls the JIT-compiler which eventually translates the *
126 * method into machine code. *
129 * javaobject_header *asm_calljavamethod (methodinfo *m, *
130 * void *arg1, void *arg2, void *arg3, void *arg4); *
132 *******************************************************************************/
137 .quad 0 /* catch type all */
138 .quad calljava_xhandler /* handler pc */
139 .quad calljava_xhandler /* end pc */
140 .quad asm_calljavafunction /* start pc */
141 .long 1 /* extable size */
142 .long 0 /* fltsave */
143 .long 0 /* intsave */
146 .long 8 /* frame size */
147 .quad 0 /* method pointer (pointer to name) */
149 asm_calljavafunction:
150 sub $(3*8),%rsp /* keep stack 16-byte aligned */
152 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
153 mov %rdi,%rax /* move function pointer to %rax */
154 /* compilerstub uses this */
156 mov %rsi,%rdi /* pass remaining parameters */
161 lea asm_call_jit_compiler,%r11
162 call *%r11 /* call JIT compiler */
166 add $(3*8),%rsp /* free stack space */
170 mov %rax,%rdi /* pass exception pointer */
171 call builtin_throw_exception
178 /********************* function asm_calljavafunction ***************************
180 * This function calls a Java-method (which possibly needs compilation) *
181 * with up to 4 address parameters. *
183 * This functions calls the JIT-compiler which eventually translates the *
184 * method into machine code. *
187 * javaobject_header *asm_calljavamethod (methodinfo *m, *
188 * void *arg1, void *arg2, void *arg3, void *arg4); *
190 *******************************************************************************/
195 .quad 0 /* catch type all */
196 .quad calljava_xhandler2 /* handler pc */
197 .quad calljava_xhandler2 /* end pc */
198 .quad asm_calljavafunction2 /* start pc */
199 .long 1 /* extable size */
200 .long 0 /* fltsave */
201 .long 0 /* intsave */
204 .long 24 /* frame size */
205 .quad 0 /* method pointer (pointer to name) */
207 asm_calljavafunction2:
208 asm_calljavafunction2double:
209 asm_calljavafunction2long:
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 */
220 mov %rsi,itmp3 /* arg count */
221 mov %rcx,itmp2 /* pointer to arg block */
223 test itmp3,itmp3 /* maybe we have no args... */
226 mov itmp2,%r14 /* save argument block pointer */
227 mov itmp3,%r15 /* save argument count */
229 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
230 add $1,itmp3 /* initialize argument count */
231 xor %r12,%r12 /* initialize integer argument counter */
232 xor %r13,%r13 /* initialize float argument counter */
235 add $sizejniblock,itmp2 /* goto next argument block */
236 dec itmp3 /* argument count - 1 */
237 jz L_register_copy_done
238 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
239 jnz L_register_handle_float /* yes, handle it */
241 cmp $(INT_ARG_CNT - 1),%r12 /* are we out of integer argument */
242 je L_register_copy /* register? yes, next loop */
244 lea jumptable_integer,%rbp
245 mov 0(%rbp,%r12,8),%rbx
246 inc %r12 /* integer argument counter + 1 */
249 L_register_handle_float:
250 cmp $(FLT_ARG_CNT - 1),%r13 /* are we out of float argument */
251 je L_register_copy /* register? yes, next loop */
253 lea jumptable_float,%rbp
254 mov 0(%rbp,%r13,8),%rbx
255 inc %r13 /* float argument counter + 1 */
258 L_register_copy_done:
259 mov %r15,itmp3 /* calculate remaining arguments after */
260 sub %r12,itmp3 /* register copy */
262 jle L_copy_done /* are all assigned to registers? */
264 shl $3,itmp3 /* calculate stack size */
265 sub itmp3,%rsp /* stack frame for arguments */
266 mov %rsp,%rbx /* use %rbx as temp sp */
268 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
269 add $1,%r15 /* initialize argument count */
272 add $sizejniblock,itmp2 /* goto next argument block */
273 dec %r15 /* are there any arguments left? */
274 jz L_copy_done /* no test needed after dec */
276 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
277 jnz L_stack_handle_float
278 dec %r12 /* arguments assigned to registers */
279 jge L_stack_copy_loop
282 L_stack_handle_float:
283 dec %r13 /* arguments assigned to registers */
284 jge L_stack_copy_loop
287 mov offjniitem(itmp2),itmp3 /* copy s8 argument onto stack */
289 add $8,%rbx /* increase sp to next argument */
290 jmp L_stack_copy_loop
293 lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
294 call *%r11 /* call JIT compiler */
296 mov 5*8(%rsp),%r15 /* restore callee saved registers */
302 add $(7*8),%rsp /* free stack space */
306 mov %rax,%rdi /* pass exception pointer */
307 call builtin_throw_exception
309 mov 5*8(%rsp),%r15 /* restore callee saved registers */
315 add $(7*8),%rsp /* free stack space */
328 mov offjniitem(itmp2),a0
331 mov offjniitem(itmp2),a1
334 mov offjniitem(itmp2),a2
337 mov offjniitem(itmp2),a3
340 mov offjniitem(itmp2),a4
343 mov offjniitem(itmp2),a5
358 movq offjniitem(itmp2),fa0
361 movq offjniitem(itmp2),fa1
364 movq offjniitem(itmp2),fa2
367 movq offjniitem(itmp2),fa3
370 movq offjniitem(itmp2),fa4
373 movq offjniitem(itmp2),fa5
376 movq offjniitem(itmp2),fa6
379 movq offjniitem(itmp2),fa7
383 /****************** function asm_call_jit_compiler *****************************
385 * invokes the compiler for untranslated JavaVM methods. *
387 * Register R0 contains a pointer to the method info structure (prepared *
388 * by createcompilerstub). Using the return address in R26 and the *
389 * offset in the LDA instruction or using the value in methodptr R28 the *
390 * patching address for storing the method address can be computed: *
392 * method address was either loaded using *
394 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
395 * i386_call_reg(REG_ITMP2) *
399 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
400 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
401 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
402 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
403 * i386_call_reg(REG_ITMP1) *
405 * in the static case the method pointer can be computed using the *
406 * return address and the lda function following the jmp instruction *
408 *******************************************************************************/
410 asm_call_jit_compiler:
411 sub $8,%rsp /* keep stack 16-byte aligned */
413 mov %rbx,(%rsp) /* save register */
415 mov 8(%rsp),%r11 /* get return address */
416 mov -1(%r11),%bl /* get function code */
417 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
418 jne L_not_static_special
420 sub $11,%r11 /* calculate address of immediate */
421 jmp L_call_jit_compile
423 L_not_static_special:
424 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
425 jne L_not_virtual_interface
427 sub $7,%r11 /* calculate address of offset */
428 mov (%r11),%r11d /* get offset (32-bit) */
429 add %r10,%r11 /* add base address to get method address */
430 jmp L_call_jit_compile
432 L_not_virtual_interface: /* a call from asm_calljavamethod */
436 mov (%rsp),%rbx /* restore register */
438 sub $(24*8),%rsp /* 8 + 48 + 64 + 64 */
440 mov %r11,0*8(%rsp) /* save address for method pointer */
442 mov %rdi,1*8(%rsp) /* save arguments */
452 movq %xmm3,10*8(%rsp)
453 movq %xmm4,11*8(%rsp)
454 movq %xmm5,12*8(%rsp)
455 movq %xmm6,13*8(%rsp)
456 movq %xmm7,14*8(%rsp)
458 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
459 movq %xmm9,16*8(%rsp)
460 movq %xmm10,17*8(%rsp)
461 movq %xmm11,18*8(%rsp)
462 movq %xmm12,19*8(%rsp)
463 movq %xmm13,20*8(%rsp)
464 movq %xmm14,21*8(%rsp)
465 movq %xmm15,22*8(%rsp)
467 mov %rax,%rdi /* pass method pointer */
482 movq 10*8(%rsp),%xmm3
483 movq 11*8(%rsp),%xmm4
484 movq 12*8(%rsp),%xmm5
485 movq 13*8(%rsp),%xmm6
486 movq 14*8(%rsp),%xmm7
488 movq 15*8(%rsp),%xmm8
489 movq 16*8(%rsp),%xmm9
490 movq 17*8(%rsp),%xmm10
491 movq 18*8(%rsp),%xmm11
492 movq 19*8(%rsp),%xmm12
493 movq 20*8(%rsp),%xmm13
494 movq 21*8(%rsp),%xmm14
495 movq 22*8(%rsp),%xmm15
499 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
502 mov %rax,(%r11) /* and now save the new pointer */
505 add $8,%rsp /* keep stack 16-byte aligned */
506 jmp *%rax /* ...and now call the new method */
509 /********************* function asm_handle_exception ***************************
511 * This function handles an exception. It does not use the usual calling *
512 * conventions. The exception pointer is passed in REG_ITMP1 and the *
513 * pc from the exception raising position is passed in REG_ITMP2. It searches *
514 * the local exception table for a handler. If no one is found, it unwinds *
515 * stacks and continues searching the callers. *
517 * void asm_handle_exception (exceptionptr, exceptionpc); *
519 *******************************************************************************/
521 asm_handle_nat_exception:
522 add $8,%rsp /* clear return address of native stub*/
524 asm_handle_exception:
526 mov xptr,0*8(%rsp) /* save exception pointer */
527 mov xpc,1*8(%rsp) /* save exception pc */
529 mov xpc,%rdi /* exception pc */
530 call codegen_findmethod
532 mov %rax,2*8(%rsp) /* save data segment pointer */
534 mov 0*8(%rsp),%rax /* restore exception pointer */
535 mov 1*8(%rsp),%r10 /* restore exception pc */
538 mov %rax,%rdi /* exception pointer */
539 mov MethodPointer(itmp3),%rsi /* method pointer */
540 mov xpc,%rdx /* exception pc */
542 mov $1,%r8 /* set noindent flag */
543 call builtin_trace_exception
545 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
546 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
547 test %rcx,%rcx /* if empty table skip */
550 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
551 mov 0*8(%rsp),xptr /* get xptr */
554 mov 1*8(%rsp),xpc /* get xpc */
556 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
557 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
558 jg ex_table_cont /* if (false) continue */
559 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
560 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
561 jge ex_table_cont /* if (false) continue */
562 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
563 test %rdx,%rdx /* NULL catches everything */
566 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
585 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
604 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
612 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
613 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
614 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
615 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
616 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
618 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
620 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
624 cmp %edx,%esi /* xptr is instanceof catchtype */
628 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
630 mov 0*8(%rsp),%rax /* restore exception pointer */
631 add $(4*8),%rsp /* free stack frame */
633 jmp *xpc /* jump to the handler */
636 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
637 dec %rcx /* decrement entry counter */
638 test %rcx,%rcx /* if (t0 > 0) next entry */
642 mov 0*8(%rsp),%rax /* restore exception pointer */
643 mov 1*8(%rsp),%r10 /* restore exception pc */
644 mov 2*8(%rsp),%r11 /* restore data segment pointer */
647 mov %rax,%rcx /* save exception pointer */
650 movl IsSync(%r11),%eax /* %rax = SyncOffset */
651 test %rax,%rax /* if zero no monitorexit */
662 call builtin_monitorexit
670 mov FrameSize(%r11),%eax /* %eax = frame size */
671 add %rax,%rsp /* unwind stack */
672 mov %rsp,%rax /* %rax = pointer to save area */
674 mov IntSave(%r11),%edx /* %edx = saved int register count*/
701 shl $3,%edx /* multiply by 8 bytes */
705 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
728 movq -48(%rax),%xmm10
730 movq -40(%rax),%xmm11
732 movq -32(%rax),%xmm12
734 movq -24(%rax),%xmm13
736 movq -16(%rax),%xmm14
741 pop %r10 /* the new xpc is return address */
742 sub $3,%r10 /* subtract 3 bytes for call */
749 call codegen_findmethod /* get the new data segment ptr */
756 mov %rcx,%rax /* restore saved exception pointer*/
760 mov %rax,0*8(%rsp) /* save exception pointer */
761 mov %r10,1*8(%rsp) /* save exception pc */
762 mov %r11,2*8(%rsp) /* save data segment pointer */
767 /* asm_check_clinit ************************************************************
773 32 ra ; return address of patched call in java machine code
774 24 xmcode ; additional machine code (only for i386 and x86_64)
775 16 mcode ; machine code to patch back in
776 8 class ; pointer to class
777 0 sp ; stack pointer of java stack frame + return address
779 *******************************************************************************/
783 mov offclassinit(itmp1),itmp1l /* get initialized flag (int) */
787 sub $(15*8),%rsp /* keep stack 16-byte aligned */
789 mov %rdi,0*8(%rsp) /* save argument registers */
796 movq %xmm0,6*8(%rsp) /* maybe cacao does not use all 8 */
797 movq %xmm1,7*8(%rsp) /* argument register, but who knows */
800 movq %xmm4,10*8(%rsp)
801 movq %xmm5,11*8(%rsp)
802 movq %xmm6,12*8(%rsp)
803 movq %xmm7,13*8(%rsp)
805 mov 8+15*8(%rsp),%rdi /* pass classinfo pointer */
806 call class_init /* call class_init function */
808 mov 0*8(%rsp),%rdi /* restore argument registers */
819 movq 10*8(%rsp),%xmm4
820 movq 11*8(%rsp),%xmm5
821 movq 12*8(%rsp),%xmm6
822 movq 13*8(%rsp),%xmm7
826 test v0,v0 /* we had an exception */
827 je L_initializererror
830 mov 32(%rsp),itmp1 /* get return address */
831 sub $5,itmp1 /* remove size of `call rel32' */
833 mov 24(%rsp),itmp2 /* get xmcode machine code */
834 movb itmp2b,(itmp1) /* patch back in 1 byte */
835 mov 16(%rsp),itmp2 /* get mcode machine code */
836 movl itmp2l,1(itmp1) /* patch back in 4 bytes */
838 add $(5*8),%rsp /* remove stub stack frame incl. ra */
840 jmp *itmp1 /* jump to patched code an execute it */
843 add $(4*8),%rsp /* remove stub stack frame */
845 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
846 call builtin_asm_get_exceptionptrptr
848 mov (itmp2),xptr /* get the exception pointer */
849 movl $0,(itmp2) /* clear the exception pointer */
851 lea _exceptionptr,itmp2
852 mov (itmp2),xptr /* get the exception pointer */
853 movl $0,(itmp2) /* clear the exception pointer */
856 pop xpc /* delete return address */
857 sub $5,xpc /* faulting address is ra - 5 */
859 jmp asm_handle_exception
862 /********************* function asm_builtin_monitorenter ***********************
864 * Does null check and calls monitorenter or throws an exception *
866 *******************************************************************************/
868 asm_builtin_monitorenter:
870 je nb_monitorenter /* if (null) throw exception */
871 jmp builtin_monitorenter /* else call builtin_monitorenter */
874 call new_nullpointerexception
875 pop %r10 /* delete return address */
876 sub $3,%r10 /* faulting address is return adress - 3 */
877 jmp asm_handle_exception
880 /********************* function asm_builtin_monitorexit ************************
882 * Does null check and calls monitorexit or throws an exception *
884 *******************************************************************************/
886 asm_builtin_monitorexit:
888 je nb_monitorexit /* if (null) throw exception */
889 jmp builtin_monitorexit /* else call builtin_monitorenter */
892 call new_nullpointerexception
893 pop %r10 /* delete return address */
894 sub $3,%r10 /* faulting address is return adress - 3 */
895 jmp asm_handle_exception
898 /********************* function asm_builtin_x2x ********************************
900 * Wrapper functions for float to int corner cases *
902 *******************************************************************************/
918 movq %xmm4,10*8(%rsp)
919 movq %xmm5,11*8(%rsp)
920 movq %xmm6,12*8(%rsp)
921 movq %xmm7,13*8(%rsp)
937 movq 10*8(%rsp),%xmm4
938 movq 11*8(%rsp),%xmm5
939 movq 12*8(%rsp),%xmm6
940 movq 13*8(%rsp),%xmm7
960 movq %xmm4,10*8(%rsp)
961 movq %xmm5,11*8(%rsp)
962 movq %xmm6,12*8(%rsp)
963 movq %xmm7,13*8(%rsp)
979 movq 10*8(%rsp),%xmm4
980 movq 11*8(%rsp),%xmm5
981 movq 12*8(%rsp),%xmm6
982 movq 13*8(%rsp),%xmm7
1000 movq %xmm2,8*8(%rsp)
1001 movq %xmm3,9*8(%rsp)
1002 movq %xmm4,10*8(%rsp)
1003 movq %xmm5,11*8(%rsp)
1004 movq %xmm6,12*8(%rsp)
1005 movq %xmm7,13*8(%rsp)
1017 movq 6*8(%rsp),%xmm0
1018 movq 7*8(%rsp),%xmm1
1019 movq 8*8(%rsp),%xmm2
1020 movq 9*8(%rsp),%xmm3
1021 movq 10*8(%rsp),%xmm4
1022 movq 11*8(%rsp),%xmm5
1023 movq 12*8(%rsp),%xmm6
1024 movq 13*8(%rsp),%xmm7
1040 movq %xmm0,6*8(%rsp)
1041 movq %xmm1,7*8(%rsp)
1042 movq %xmm2,8*8(%rsp)
1043 movq %xmm3,9*8(%rsp)
1044 movq %xmm4,10*8(%rsp)
1045 movq %xmm5,11*8(%rsp)
1046 movq %xmm6,12*8(%rsp)
1047 movq %xmm7,13*8(%rsp)
1059 movq 6*8(%rsp),%xmm0
1060 movq 7*8(%rsp),%xmm1
1061 movq 8*8(%rsp),%xmm2
1062 movq 9*8(%rsp),%xmm3
1063 movq 10*8(%rsp),%xmm4
1064 movq 11*8(%rsp),%xmm5
1065 movq 12*8(%rsp),%xmm6
1066 movq 13*8(%rsp),%xmm7
1072 /******************* function asm_builtin_checkarraycast ***********************
1074 * Does the cast check and eventually throws an exception *
1076 *******************************************************************************/
1078 asm_builtin_checkarraycast:
1079 sub $24,%rsp /* keep stack 16-byte aligned */
1080 mov %rdi,(%rsp) /* save object pointer */
1081 call builtin_checkarraycast /* builtin_checkarraycast */
1082 test %rax,%rax /* if (false) throw exception */
1084 mov (%rsp),%rax /* return object pointer */
1085 add $24,%rsp /* free stack space */
1089 call new_classcastexception
1091 pop %r10 /* delete return address */
1092 sub $3,%r10 /* faulting address is return adress - 3 */
1093 jmp asm_handle_exception
1096 /******************* function asm_builtin_aastore ******************************
1098 * Does the cast check and eventually throws an exception *
1100 *******************************************************************************/
1102 asm_builtin_aastore:
1103 sub $(3*8),%rsp /* allocate stack space */
1104 test %rdi,%rdi /* if null pointer throw exception */
1107 movl offarraysize(%rdi),%eax /* load size */
1108 cmpl %eax,%esi /* do bound check */
1109 jae nb_aastore_bound /* if out of bounds throw exception */
1111 shl $3,%rsi /* index * 8 */
1113 add %rsi,%r10 /* add index * 8 to arrayref */
1115 mov %r10,(%rsp) /* save store position */
1116 mov %rdx,8(%rsp) /* save object */
1118 mov %rdx,%rsi /* object is second argument */
1119 call builtin_canstore /* builtin_canstore(arrayref,object) */
1120 test %rax,%rax /* if (false) throw exception */
1123 mov (%rsp),%r10 /* restore store position */
1124 mov 8(%rsp),%rdx /* restore object */
1125 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1126 add $(3*8),%rsp /* free stack space */
1130 call new_nullpointerexception
1132 pop %r10 /* delete return address */
1133 sub $3,%r10 /* faulting address is return adress - 3 */
1134 jmp asm_handle_exception
1137 mov %rsi,%rdi /* move index into a0 */
1138 call new_arrayindexoutofboundsexception
1140 pop %r10 /* delete return address */
1141 sub $3,%r10 /* faulting address is return adress - 3 */
1142 jmp asm_handle_exception
1145 call new_arraystoreexception
1147 pop %r10 /* delete return address */
1148 sub $3,%r10 /* faulting address is return adress - 3 */
1149 jmp asm_handle_exception
1152 /******************* function asm_initialize_thread_stack **********************
1154 * initialized a thread stack *
1155 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1157 *******************************************************************************/
1159 asm_initialize_thread_stack:
1170 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1171 mov %rsi,%rax /* return restorepoint in %rax */
1175 /******************* function asm_perform_threadswitch *************************
1177 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1179 * performs a threadswitch *
1181 *******************************************************************************/
1183 asm_perform_threadswitch:
1184 sub $(7*8),%rsp /* allocate stack frame */
1193 mov 7*8(%rsp),%rax /* save current return address */
1196 mov %rsp,(%rdi) /* first argument **from */
1197 mov %rsp,(%rdx) /* third argument **stackTop */
1199 mov (%rsi),%rsp /* load new stack pointer */
1208 mov 6*8(%rsp),%rax /* restore return address */
1209 add $(7*8),%rsp /* free stack frame */
1214 /********************* function asm_switchstackandcall *************************
1216 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1219 * Switches to a new stack, calls a function and switches back. *
1220 * a0 (%rdi) new stack pointer *
1221 * a1 (%rsi) function pointer *
1222 * a2 (%rdx) pointer to variable where stack top should be stored *
1223 * a3 (%rcx) pointer to user data, is passed to the function *
1225 *******************************************************************************/
1227 asm_switchstackandcall:
1228 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1229 sub $16,%rdi /* allocate new stack */
1231 mov 8(%rsp),%rax /* save return address on new stack */
1233 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1234 mov %rsp,(%rdx) /* save old stack pointer to variable */
1236 mov %rdi,%rsp /* switch to new stack */
1238 mov %rcx,%rdi /* pass pointer */
1239 call *%rsi /* and call function */
1241 mov (%rsp),%r10 /* load return address */
1242 mov 8(%rsp),%rsp /* switch to old stack */
1243 add $(1*8),%rsp /* free stack space */
1244 mov %r10,(%rsp) /* write return adress */
1248 asm_getclassvalues_atomic:
1251 movl offbaseval(a0),itmp1l
1252 movl offdiffval(a0),itmp2l
1253 movl offbaseval(a1),itmp3l
1255 movl itmp1l,offcast_super_baseval(a2)
1256 movl itmp2l,offcast_super_diffval(a2)
1257 movl itmp3l,offcast_sub_baseval(a2)
1262 asm_criticalsections:
1263 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1266 .quad _crit_restart1
1269 .quad _crit_restart2
1275 * These are local overrides for various environment variables in Emacs.
1276 * Please do not remove this and leave it at the end of the file, where
1277 * Emacs will automagically detect them.
1278 * ---------------------------------------------------------------------
1281 * indent-tabs-mode: t