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 1810 2004-12-22 11:07:18Z 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
85 .globl asm_calljavafunction2
86 .globl asm_calljavafunction2int
87 .globl asm_calljavafunction2long
88 .globl asm_calljavafunction2float
89 .globl asm_calljavafunction2double
91 .globl asm_call_jit_compiler
92 .globl asm_handle_exception
93 .globl asm_handle_nat_exception
94 .globl asm_check_clinit
95 .globl asm_builtin_checkarraycast
96 .globl asm_builtin_anewarray
97 .globl asm_builtin_newarray_array
98 .globl asm_builtin_aastore
100 #if defined(USE_THREADS)
101 .globl asm_builtin_monitorenter
102 .globl asm_builtin_monitorexit
105 .globl asm_builtin_f2i
106 .globl asm_builtin_f2l
107 .globl asm_builtin_d2i
108 .globl asm_builtin_d2l
110 .globl asm_builtin_arrayinstanceof
111 .globl asm_perform_threadswitch
112 .globl asm_initialize_thread_stack
113 .globl asm_switchstackandcall
114 .globl asm_criticalsections
115 .globl asm_getclassvalues_atomic
118 /********************* function asm_calljavafunction ***************************
120 * This function calls a Java-method (which possibly needs compilation) *
121 * with up to 4 address parameters. *
123 * This functions calls the JIT-compiler which eventually translates the *
124 * method into machine code. *
127 * javaobject_header *asm_calljavamethod (methodinfo *m, *
128 * void *arg1, void *arg2, void *arg3, void *arg4); *
130 *******************************************************************************/
135 .quad 0 /* catch type all */
136 .quad calljava_xhandler /* handler pc */
137 .quad calljava_xhandler /* end pc */
138 .quad asm_calljavafunction /* start pc */
139 .long 1 /* extable size */
140 .long 0 /* fltsave */
141 .long 0 /* intsave */
144 .long 8 /* frame size */
145 .quad 0 /* method pointer (pointer to name) */
147 asm_calljavafunction:
148 sub $(3*8),%rsp /* keep stack 16-byte aligned */
150 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
151 mov %rdi,%rax /* move function pointer to %rax */
152 /* compilerstub uses this */
154 mov %rsi,%rdi /* pass remaining parameters */
159 lea asm_call_jit_compiler,%r11
160 call *%r11 /* call JIT compiler */
164 add $(3*8),%rsp /* free stack space */
168 mov %rax,%rdi /* pass exception pointer */
169 call builtin_throw_exception
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 */
331 mov offjniitem(itmp2),a0
334 mov offjniitem(itmp2),a1
337 mov offjniitem(itmp2),a2
340 mov offjniitem(itmp2),a3
343 mov offjniitem(itmp2),a4
346 mov offjniitem(itmp2),a5
361 movq offjniitem(itmp2),fa0
364 movq offjniitem(itmp2),fa1
367 movq offjniitem(itmp2),fa2
370 movq offjniitem(itmp2),fa3
373 movq offjniitem(itmp2),fa4
376 movq offjniitem(itmp2),fa5
379 movq offjniitem(itmp2),fa6
382 movq offjniitem(itmp2),fa7
386 /****************** function asm_call_jit_compiler *****************************
388 * invokes the compiler for untranslated JavaVM methods. *
390 * Register R0 contains a pointer to the method info structure (prepared *
391 * by createcompilerstub). Using the return address in R26 and the *
392 * offset in the LDA instruction or using the value in methodptr R28 the *
393 * patching address for storing the method address can be computed: *
395 * method address was either loaded using *
397 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
398 * i386_call_reg(REG_ITMP2) *
402 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
403 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
404 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
405 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
406 * i386_call_reg(REG_ITMP1) *
408 * in the static case the method pointer can be computed using the *
409 * return address and the lda function following the jmp instruction *
411 *******************************************************************************/
413 asm_call_jit_compiler:
414 sub $8,%rsp /* keep stack 16-byte aligned */
416 mov %rbx,(%rsp) /* save register */
418 mov 8(%rsp),%r11 /* get return address */
419 mov -1(%r11),%bl /* get function code */
420 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
421 jne L_not_static_special
423 sub $11,%r11 /* calculate address of immediate */
424 jmp L_call_jit_compile
426 L_not_static_special:
427 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
428 jne L_not_virtual_interface
430 sub $7,%r11 /* calculate address of offset */
431 mov (%r11),%r11d /* get offset (32-bit) */
432 add %r10,%r11 /* add base address to get method address */
433 jmp L_call_jit_compile
435 L_not_virtual_interface: /* a call from asm_calljavamethod */
439 mov (%rsp),%rbx /* restore register */
441 sub $(24*8),%rsp /* 8 + 48 + 64 + 64 */
443 mov %r11,0*8(%rsp) /* save address for method pointer */
445 mov a0,1*8(%rsp) /* save arguments */
461 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
462 movq %xmm9,16*8(%rsp)
463 movq %xmm10,17*8(%rsp)
464 movq %xmm11,18*8(%rsp)
465 movq %xmm12,19*8(%rsp)
466 movq %xmm13,20*8(%rsp)
467 movq %xmm14,21*8(%rsp)
468 movq %xmm15,22*8(%rsp)
470 mov %rax,%rdi /* pass method pointer */
491 movq 15*8(%rsp),%xmm8
492 movq 16*8(%rsp),%xmm9
493 movq 17*8(%rsp),%xmm10
494 movq 18*8(%rsp),%xmm11
495 movq 19*8(%rsp),%xmm12
496 movq 20*8(%rsp),%xmm13
497 movq 21*8(%rsp),%xmm14
498 movq 22*8(%rsp),%xmm15
502 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
505 mov %rax,(%r11) /* and now save the new pointer */
508 add $8,%rsp /* keep stack 16-byte aligned */
509 jmp *%rax /* ...and now call the new method */
512 /********************* function asm_handle_exception ***************************
514 * This function handles an exception. It does not use the usual calling *
515 * conventions. The exception pointer is passed in REG_ITMP1 and the *
516 * pc from the exception raising position is passed in REG_ITMP2. It searches *
517 * the local exception table for a handler. If no one is found, it unwinds *
518 * stacks and continues searching the callers. *
520 * void asm_handle_exception (exceptionptr, exceptionpc); *
522 *******************************************************************************/
524 asm_handle_nat_exception:
525 add $8,%rsp /* clear return address of native stub*/
527 asm_handle_exception:
529 mov xptr,0*8(%rsp) /* save exception pointer */
530 mov xpc,1*8(%rsp) /* save exception pc */
532 mov xpc,%rdi /* exception pc */
533 call codegen_findmethod
535 mov %rax,2*8(%rsp) /* save data segment pointer */
537 mov 0*8(%rsp),%rax /* restore exception pointer */
538 mov 1*8(%rsp),%r10 /* restore exception pc */
541 mov %rax,%rdi /* exception pointer */
542 mov MethodPointer(itmp3),%rsi /* method pointer */
543 mov xpc,%rdx /* exception pc */
545 mov $1,%r8 /* set noindent flag */
546 call builtin_trace_exception
548 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
549 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
550 test %rcx,%rcx /* if empty table skip */
553 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
554 mov 0*8(%rsp),xptr /* get xptr */
557 mov 1*8(%rsp),xpc /* get xpc */
559 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
560 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
561 jg ex_table_cont /* if (false) continue */
562 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
563 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
564 jge ex_table_cont /* if (false) continue */
565 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
566 test %rdx,%rdx /* NULL catches everything */
569 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
588 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
607 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
615 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
616 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
617 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
618 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
619 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
621 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
623 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
627 cmp %edx,%esi /* xptr is instanceof catchtype */
631 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
633 mov 0*8(%rsp),%rax /* restore exception pointer */
634 add $(4*8),%rsp /* free stack frame */
636 jmp *xpc /* jump to the handler */
639 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
640 dec %rcx /* decrement entry counter */
641 test %rcx,%rcx /* if (t0 > 0) next entry */
645 mov 0*8(%rsp),%rax /* restore exception pointer */
646 mov 1*8(%rsp),%r10 /* restore exception pc */
647 mov 2*8(%rsp),%r11 /* restore data segment pointer */
650 mov %rax,%rcx /* save exception pointer */
653 movl IsSync(%r11),%eax /* %rax = SyncOffset */
654 test %rax,%rax /* if zero no monitorexit */
657 #if defined(USE_THREADS)
666 call builtin_monitorexit
675 mov FrameSize(%r11),%eax /* %eax = frame size */
676 add %rax,%rsp /* unwind stack */
677 mov %rsp,%rax /* %rax = pointer to save area */
679 mov IntSave(%r11),%edx /* %edx = saved int register count*/
706 shl $3,%edx /* multiply by 8 bytes */
710 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
733 movq -48(%rax),%xmm10
735 movq -40(%rax),%xmm11
737 movq -32(%rax),%xmm12
739 movq -24(%rax),%xmm13
741 movq -16(%rax),%xmm14
746 pop %r10 /* the new xpc is return address */
747 sub $3,%r10 /* subtract 3 bytes for call */
754 call codegen_findmethod /* get the new data segment ptr */
761 mov %rcx,%rax /* restore saved exception pointer*/
765 mov %rax,0*8(%rsp) /* save exception pointer */
766 mov %r10,1*8(%rsp) /* save exception pc */
767 mov %r11,2*8(%rsp) /* save data segment pointer */
772 /* asm_check_clinit ************************************************************
778 32 ra ; return address of patched call in java machine code
779 24 xmcode ; additional machine code (only for i386 and x86_64)
780 16 mcode ; machine code to patch back in
781 8 class ; pointer to class
782 0 sp ; stack pointer of java stack frame + return address
784 *******************************************************************************/
788 mov offclassinit(itmp1),itmp1l /* get initialized flag (int) */
792 sub $(15*8),%rsp /* keep stack 16-byte aligned */
794 mov a0,0*8(%rsp) /* save argument registers */
801 movq fa0,6*8(%rsp) /* maybe cacao does not use all 8 */
802 movq fa1,7*8(%rsp) /* argument register, but who knows */
810 mov (15+1)*8(%rsp),%rdi /* pass classinfo pointer */
811 call class_init /* call class_init function */
813 mov 0*8(%rsp),a0 /* restore argument registers */
831 test v0,v0 /* we had an exception */
832 je L_initializererror
835 mov 32(%rsp),itmp1 /* get return address */
836 sub $5,itmp1 /* remove size of `call rel32' */
838 mov 24(%rsp),itmp2 /* get xmcode machine code */
839 movb itmp2b,(itmp1) /* patch back in 1 byte */
840 mov 16(%rsp),itmp2 /* get mcode machine code */
841 movl itmp2l,1(itmp1) /* patch back in 4 bytes */
843 add $((4+1)*8),%rsp /* remove stub stack frame incl. ra */
845 jmp *itmp1 /* jump to patched code an execute it */
848 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
849 call builtin_asm_get_exceptionptrptr
852 lea _exceptionptr,itmp2
854 mov (itmp2),xptr /* get the exception pointer */
855 movl $0,(itmp2) /* clear the exception pointer */
857 add $(4*8),%rsp /* remove stub stack frame */
859 pop xpc /* delete return address */
860 sub $5,xpc /* faulting address is ra - 5 */
862 jmp asm_handle_exception
865 /********************* function asm_builtin_monitorenter ***********************
867 * Does null check and calls monitorenter or throws an exception *
869 *******************************************************************************/
871 #if defined(USE_THREADS)
872 asm_builtin_monitorenter:
874 je nb_monitorenter /* if (null) throw exception */
875 jmp builtin_monitorenter /* else call builtin_monitorenter */
878 call new_nullpointerexception
879 pop %r10 /* delete return address */
880 sub $3,%r10 /* faulting address is ra - 3 */
881 jmp asm_handle_exception
885 /********************* function asm_builtin_monitorexit ************************
887 * Does null check and calls monitorexit or throws an exception *
889 *******************************************************************************/
891 #if defined(USE_THREADS)
892 asm_builtin_monitorexit:
894 je nb_monitorexit /* if (null) throw exception */
895 jmp builtin_monitorexit /* else call builtin_monitorenter */
898 call new_nullpointerexception
899 pop %r10 /* delete return address */
900 sub $3,%r10 /* faulting address is ra - 3 */
901 jmp asm_handle_exception
905 /********************* function asm_builtin_x2x ********************************
907 * Wrapper functions for float to int corner cases *
909 *******************************************************************************/
925 movq %xmm4,10*8(%rsp)
926 movq %xmm5,11*8(%rsp)
927 movq %xmm6,12*8(%rsp)
928 movq %xmm7,13*8(%rsp)
944 movq 10*8(%rsp),%xmm4
945 movq 11*8(%rsp),%xmm5
946 movq 12*8(%rsp),%xmm6
947 movq 13*8(%rsp),%xmm7
967 movq %xmm4,10*8(%rsp)
968 movq %xmm5,11*8(%rsp)
969 movq %xmm6,12*8(%rsp)
970 movq %xmm7,13*8(%rsp)
986 movq 10*8(%rsp),%xmm4
987 movq 11*8(%rsp),%xmm5
988 movq 12*8(%rsp),%xmm6
989 movq 13*8(%rsp),%xmm7
1005 movq %xmm0,6*8(%rsp)
1006 movq %xmm1,7*8(%rsp)
1007 movq %xmm2,8*8(%rsp)
1008 movq %xmm3,9*8(%rsp)
1009 movq %xmm4,10*8(%rsp)
1010 movq %xmm5,11*8(%rsp)
1011 movq %xmm6,12*8(%rsp)
1012 movq %xmm7,13*8(%rsp)
1024 movq 6*8(%rsp),%xmm0
1025 movq 7*8(%rsp),%xmm1
1026 movq 8*8(%rsp),%xmm2
1027 movq 9*8(%rsp),%xmm3
1028 movq 10*8(%rsp),%xmm4
1029 movq 11*8(%rsp),%xmm5
1030 movq 12*8(%rsp),%xmm6
1031 movq 13*8(%rsp),%xmm7
1047 movq %xmm0,6*8(%rsp)
1048 movq %xmm1,7*8(%rsp)
1049 movq %xmm2,8*8(%rsp)
1050 movq %xmm3,9*8(%rsp)
1051 movq %xmm4,10*8(%rsp)
1052 movq %xmm5,11*8(%rsp)
1053 movq %xmm6,12*8(%rsp)
1054 movq %xmm7,13*8(%rsp)
1066 movq 6*8(%rsp),%xmm0
1067 movq 7*8(%rsp),%xmm1
1068 movq 8*8(%rsp),%xmm2
1069 movq 9*8(%rsp),%xmm3
1070 movq 10*8(%rsp),%xmm4
1071 movq 11*8(%rsp),%xmm5
1072 movq 12*8(%rsp),%xmm6
1073 movq 13*8(%rsp),%xmm7
1079 /* asm_builtin_checkarraycast **************************************************
1081 Does the cast check and eventually throws an exception.
1083 *******************************************************************************/
1085 asm_builtin_checkarraycast:
1086 sub $24,%rsp /* keep stack 16-byte aligned */
1087 mov %rdi,(%rsp) /* save object pointer */
1088 call builtin_checkarraycast /* builtin_checkarraycast */
1089 test %rax,%rax /* if (false) throw exception */
1091 mov (%rsp),%rax /* return object pointer */
1092 add $24,%rsp /* free stack space */
1096 call new_classcastexception
1098 pop %r10 /* delete return address */
1099 sub $3,%r10 /* faulting address is ra - 3 */
1100 jmp asm_handle_exception
1103 /* asm_builtin_aastore *********************************************************
1105 Checks if the object can be stored in the given array and stores the
1106 address if it's possible. This function can also throw some exceptions.
1108 *******************************************************************************/
1110 asm_builtin_aastore:
1111 sub $(3*8),%rsp /* allocate stack space */
1112 test %rdi,%rdi /* if null pointer throw exception */
1115 movl offarraysize(%rdi),%eax /* load size */
1116 cmpl %eax,%esi /* do bound check */
1117 jae nb_aastore_bound /* if out of bounds throw exception */
1119 shl $3,%rsi /* index * 8 */
1121 add %rsi,%r10 /* add index * 8 to arrayref */
1123 mov %r10,(%rsp) /* save store position */
1124 mov %rdx,8(%rsp) /* save object */
1126 mov %rdx,%rsi /* object is second argument */
1127 call builtin_canstore /* builtin_canstore(arrayref,object) */
1128 test %rax,%rax /* if (false) throw exception */
1131 mov (%rsp),%r10 /* restore store position */
1132 mov 8(%rsp),%rdx /* restore object */
1133 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1134 add $(3*8),%rsp /* free stack space */
1138 call new_nullpointerexception
1140 pop %r10 /* delete return address */
1141 sub $3,%r10 /* faulting address is return adress - 3 */
1142 jmp asm_handle_exception
1145 mov %rsi,%rdi /* move index into a0 */
1146 call new_arrayindexoutofboundsexception
1148 pop %r10 /* delete return address */
1149 sub $3,%r10 /* faulting address is return adress - 3 */
1150 jmp asm_handle_exception
1153 call new_arraystoreexception
1155 pop %r10 /* delete return address */
1156 sub $3,%r10 /* faulting address is return adress - 3 */
1157 jmp asm_handle_exception
1160 /******************* function asm_initialize_thread_stack **********************
1162 * initialized a thread stack *
1163 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1165 *******************************************************************************/
1167 asm_initialize_thread_stack:
1178 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1179 mov %rsi,%rax /* return restorepoint in %rax */
1183 /******************* function asm_perform_threadswitch *************************
1185 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1187 * performs a threadswitch *
1189 *******************************************************************************/
1191 asm_perform_threadswitch:
1192 sub $(7*8),%rsp /* allocate stack frame */
1201 mov 7*8(%rsp),%rax /* save current return address */
1204 mov %rsp,(%rdi) /* first argument **from */
1205 mov %rsp,(%rdx) /* third argument **stackTop */
1207 mov (%rsi),%rsp /* load new stack pointer */
1216 mov 6*8(%rsp),%rax /* restore return address */
1217 add $(7*8),%rsp /* free stack frame */
1222 /********************* function asm_switchstackandcall *************************
1224 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1227 * Switches to a new stack, calls a function and switches back. *
1228 * a0 (%rdi) new stack pointer *
1229 * a1 (%rsi) function pointer *
1230 * a2 (%rdx) pointer to variable where stack top should be stored *
1231 * a3 (%rcx) pointer to user data, is passed to the function *
1233 *******************************************************************************/
1235 asm_switchstackandcall:
1236 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1237 sub $16,%rdi /* allocate new stack */
1239 mov 8(%rsp),%rax /* save return address on new stack */
1241 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1242 mov %rsp,(%rdx) /* save old stack pointer to variable */
1244 mov %rdi,%rsp /* switch to new stack */
1246 mov %rcx,%rdi /* pass pointer */
1247 call *%rsi /* and call function */
1249 mov (%rsp),%r10 /* load return address */
1250 mov 8(%rsp),%rsp /* switch to old stack */
1251 add $(1*8),%rsp /* free stack space */
1252 mov %r10,(%rsp) /* write return adress */
1256 asm_getclassvalues_atomic:
1259 movl offbaseval(a0),itmp1l
1260 movl offdiffval(a0),itmp2l
1261 movl offbaseval(a1),itmp3l
1263 movl itmp1l,offcast_super_baseval(a2)
1264 movl itmp2l,offcast_super_diffval(a2)
1265 movl itmp3l,offcast_sub_baseval(a2)
1270 asm_criticalsections:
1271 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1274 .quad _crit_restart1
1277 .quad _crit_restart2
1283 * These are local overrides for various environment variables in Emacs.
1284 * Please do not remove this and leave it at the end of the file, where
1285 * Emacs will automagically detect them.
1286 * ---------------------------------------------------------------------
1289 * indent-tabs-mode: t