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 2448 2005-05-11 13:03:20Z 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 */
79 /* save and restore macros ****************************************************/
81 #define SAVE_ARGUMENT_REGISTERS \
88 movq fa0,6*8(%rsp) ; \
89 movq fa1,7*8(%rsp) ; \
90 movq fa2,8*8(%rsp) ; \
91 movq fa3,9*8(%rsp) ; \
92 movq fa4,10*8(%rsp) ; \
93 movq fa5,11*8(%rsp) ; \
94 movq fa6,12*8(%rsp) ; \
98 #define RESTORE_ARGUMENT_REGISTERS \
105 movq 6*8(%rsp),fa0 ; \
106 movq 7*8(%rsp),fa1 ; \
107 movq 8*8(%rsp),fa2 ; \
108 movq 9*8(%rsp),fa3 ; \
109 movq 10*8(%rsp),fa4 ; \
110 movq 11*8(%rsp),fa5 ; \
111 movq 12*8(%rsp),fa6 ; \
112 movq 13*8(%rsp),fa7 ;
115 #define SAVE_TEMPORARY_REGISTERS \
119 #define RESTORE_TEMPORARY_REGISTERS \
126 /********************* exported functions and variables ***********************/
128 .globl asm_calljavafunction
129 .globl asm_calljavafunction_int
131 .globl asm_calljavafunction2
132 .globl asm_calljavafunction2int
133 .globl asm_calljavafunction2long
134 .globl asm_calljavafunction2float
135 .globl asm_calljavafunction2double
137 .globl asm_call_jit_compiler
138 .globl asm_handle_exception
139 .globl asm_handle_nat_exception
141 .globl asm_wrapper_patcher
143 .globl asm_builtin_arraycheckcast
144 .globl asm_builtin_aastore
146 .globl asm_builtin_f2i
147 .globl asm_builtin_f2l
148 .globl asm_builtin_d2i
149 .globl asm_builtin_d2l
151 .globl asm_perform_threadswitch
152 .globl asm_initialize_thread_stack
153 .globl asm_switchstackandcall
154 .globl asm_criticalsections
155 .globl asm_getclassvalues_atomic
157 .globl asm_prepare_native_stackinfo
158 .globl asm_remove_native_stackinfo
159 .globl asm_throw_and_handle_exception
160 .globl asm_throw_and_handle_hardware_arithmetic_exception
163 /********************* function asm_calljavafunction ***************************
165 * This function calls a Java-method (which possibly needs compilation) *
166 * with up to 4 address parameters. *
168 * This functions calls the JIT-compiler which eventually translates the *
169 * method into machine code. *
172 * javaobject_header *asm_calljavamethod (methodinfo *m, *
173 * void *arg1, void *arg2, void *arg3, void *arg4); *
175 *******************************************************************************/
180 .quad 0 /* catch type all */
181 .quad calljava_xhandler /* handler pc */
182 .quad calljava_xhandler /* end pc */
183 .quad asm_calljavafunction /* start pc */
184 .long 1 /* extable size */
186 .quad 0 /* line number table start */
187 .quad 0 /* line number table size */
189 .long 0 /* fltsave */
190 .long 0 /* intsave */
193 .long 8 /* frame size */
194 .quad 0 /* method pointer (pointer to name) */
196 asm_calljavafunction:
197 asm_calljavafunction_int:
198 sub $(3*8),%rsp /* keep stack 16-byte aligned */
200 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
201 mov %rdi,%rax /* move function pointer to %rax */
202 /* compilerstub uses this */
204 mov %rsi,%rdi /* pass remaining parameters */
209 lea asm_call_jit_compiler,%r11
210 call *%r11 /* call JIT compiler */
214 add $(3*8),%rsp /* free stack space */
218 mov %rax,%rdi /* pass exception pointer */
219 call builtin_throw_exception
223 xor %rax,%rax /* return NULL */
227 /********************* function asm_calljavafunction ***************************
229 * This function calls a Java-method (which possibly needs compilation) *
230 * with up to 4 address parameters. *
232 * This functions calls the JIT-compiler which eventually translates the *
233 * method into machine code. *
236 * javaobject_header *asm_calljavamethod (methodinfo *m, *
237 * void *arg1, void *arg2, void *arg3, void *arg4); *
239 *******************************************************************************/
244 .quad 0 /* catch type all */
245 .quad calljava_xhandler2 /* handler pc */
246 .quad calljava_xhandler2 /* end pc */
247 .quad asm_calljavafunction2 /* start pc */
248 .long 1 /* extable size */
250 .quad 0 /* line number table start */
251 .quad 0 /* line number table size */
253 .long 0 /* fltsave */
254 .long 0 /* intsave */
257 .long 24 /* frame size */
258 .quad 0 /* method pointer (pointer to name) */
260 asm_calljavafunction2:
261 asm_calljavafunction2int:
262 asm_calljavafunction2long:
263 asm_calljavafunction2float:
264 asm_calljavafunction2double:
265 sub $(7*8),%rsp /* keep stack 16-byte aligned */
266 mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
273 mov %rdi,%rax /* move method pointer for compiler */
274 xor %rbp,%rbp /* set argument stack frame to zero */
276 test %rsi,%rsi /* maybe we have no args... */
279 mov %rsi,itmp3 /* arg count */
280 mov %rcx,itmp2 /* pointer to arg block */
282 mov itmp2,%r14 /* save argument block pointer */
283 mov itmp3,%r15 /* save argument count */
285 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
286 add $1,itmp3 /* initialize argument count */
287 xor %r12,%r12 /* initialize integer argument counter */
288 xor %r13,%r13 /* initialize float argument counter */
291 add $sizejniblock,itmp2 /* goto next argument block */
292 dec itmp3 /* argument count - 1 */
293 jz L_register_copy_done
294 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
295 jnz L_register_handle_float /* yes, handle it */
297 cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
298 je L_register_copy /* register? yes, next loop */
300 lea jumptable_integer,%rbp
301 mov 0(%rbp,%r12,8),%rbx
302 inc %r12 /* integer argument counter + 1 */
305 L_register_handle_float:
306 cmp $FLT_ARG_CNT,%r13 /* are we out of float argument */
307 je L_register_copy /* register? yes, next loop */
309 lea jumptable_float,%rbp
310 mov 0(%rbp,%r13,8),%rbx
311 inc %r13 /* float argument counter + 1 */
314 L_register_copy_done:
315 mov %r15,%rbp /* calculate remaining arguments */
316 sub %r12,%rbp /* - integer arguments in registers */
317 sub %r13,%rbp /* - float arguments in registers */
318 jle L_copy_done /* are all assigned to registers? */
320 shl $3,%rbp /* calculate stack size */
321 sub %rbp,%rsp /* stack frame for arguments */
322 mov %rsp,%rbx /* use %rbx as temp sp */
324 sub $sizejniblock,%r14 /* initialize pointer (smaller code) */
325 add $1,%r15 /* initialize argument count */
328 add $sizejniblock,%r14 /* goto next argument block */
329 dec %r15 /* are there any arguments left? */
330 jz L_copy_done /* no test needed after dec */
332 andb $0x02,offjniitemtype(%r14) /* is this a float/double type? */
333 jnz L_stack_handle_float
334 dec %r12 /* arguments assigned to registers */
335 jge L_stack_copy_loop
338 L_stack_handle_float:
339 dec %r13 /* arguments assigned to registers */
340 jge L_stack_copy_loop
343 mov offjniitem(%r14),itmp3 /* copy s8 argument onto stack */
345 add $8,%rbx /* increase sp to next argument */
346 jmp L_stack_copy_loop
349 lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
350 call *%r11 /* call JIT compiler */
352 add %rbp,%rsp /* remove argument stack frame if any */
354 mov 5*8(%rsp),%r15 /* restore callee saved registers */
360 add $(7*8),%rsp /* free stack space */
364 mov %rax,%rdi /* pass exception pointer */
365 call builtin_throw_exception
367 mov 5*8(%rsp),%r15 /* restore callee saved registers */
373 add $(7*8),%rsp /* free stack space */
374 xor %rax,%rax /* return NULL */
387 mov offjniitem(itmp2),a0
390 mov offjniitem(itmp2),a1
393 mov offjniitem(itmp2),a2
396 mov offjniitem(itmp2),a3
399 mov offjniitem(itmp2),a4
402 mov offjniitem(itmp2),a5
417 movq offjniitem(itmp2),fa0
420 movq offjniitem(itmp2),fa1
423 movq offjniitem(itmp2),fa2
426 movq offjniitem(itmp2),fa3
429 movq offjniitem(itmp2),fa4
432 movq offjniitem(itmp2),fa5
435 movq offjniitem(itmp2),fa6
438 movq offjniitem(itmp2),fa7
442 /****************** function asm_call_jit_compiler *****************************
444 * invokes the compiler for untranslated JavaVM methods. *
446 * Register R0 contains a pointer to the method info structure (prepared *
447 * by createcompilerstub). Using the return address in R26 and the *
448 * offset in the LDA instruction or using the value in methodptr R28 the *
449 * patching address for storing the method address can be computed: *
451 * method address was either loaded using *
453 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
454 * i386_call_reg(REG_ITMP2) *
458 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
459 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
460 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
461 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
462 * i386_call_reg(REG_ITMP1) *
464 * in the static case the method pointer can be computed using the *
465 * return address and the lda function following the jmp instruction *
467 *******************************************************************************/
469 asm_call_jit_compiler:
470 sub $8,%rsp /* keep stack 16-byte aligned */
472 mov %rbx,(%rsp) /* save register */
474 mov 8(%rsp),%r11 /* get return address */
475 mov -1(%r11),%bl /* get function code */
476 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
477 jne L_not_static_special
479 sub $11,%r11 /* calculate address of immediate */
480 jmp L_call_jit_compile
482 L_not_static_special:
483 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
484 jne L_not_virtual_interface
486 sub $7,%r11 /* calculate address of offset */
487 mov (%r11),%r11d /* get offset (32-bit) */
488 add %r10,%r11 /* add base address to get method address */
489 jmp L_call_jit_compile
491 L_not_virtual_interface: /* a call from asm_calljavamethod */
495 mov (%rsp),%rbx /* restore register */
497 sub $(24*8),%rsp /* 8 + 6*8 + 8*8 + 8*8 */
499 mov %r11,0*8(%rsp) /* save address for method pointer */
501 mov a0,1*8(%rsp) /* save arguments */
517 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
518 movq %xmm9,16*8(%rsp)
519 movq %xmm10,17*8(%rsp)
520 movq %xmm11,18*8(%rsp)
521 movq %xmm12,19*8(%rsp)
522 movq %xmm13,20*8(%rsp)
523 movq %xmm14,21*8(%rsp)
524 movq %xmm15,22*8(%rsp)
526 mov %rax,%rdi /* pass method pointer */
547 movq 15*8(%rsp),%xmm8
548 movq 16*8(%rsp),%xmm9
549 movq 17*8(%rsp),%xmm10
550 movq 18*8(%rsp),%xmm11
551 movq 19*8(%rsp),%xmm12
552 movq 20*8(%rsp),%xmm13
553 movq 21*8(%rsp),%xmm14
554 movq 22*8(%rsp),%xmm15
557 add $8,%rsp /* keep stack 16-byte aligned */
559 test %rax,%rax /* check for exception */
560 je L_asm_call_jit_compiler_exception
562 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
565 mov %rax,(%r11) /* and now save the new pointer */
568 jmp *%rax /* ...and now call the new method */
570 L_asm_call_jit_compiler_exception:
571 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
572 call builtin_asm_get_exceptionptrptr
575 lea _exceptionptr,itmp2
577 mov (itmp2),xptr /* get the exception pointer */
578 movl $0,(itmp2) /* clear the exception pointer */
580 pop xpc /* delete return address */
581 sub $5,xpc /* faulting address is ra - 5 */
583 jmp asm_handle_exception
586 /********************* function asm_handle_exception ***************************
588 * This function handles an exception. It does not use the usual calling *
589 * conventions. The exception pointer is passed in REG_ITMP1 and the *
590 * pc from the exception raising position is passed in REG_ITMP2. It searches *
591 * the local exception table for a handler. If no one is found, it unwinds *
592 * stacks and continues searching the callers. *
594 * void asm_handle_exception (exceptionptr, exceptionpc); *
596 *******************************************************************************/
598 asm_handle_nat_exception:
599 add $8,%rsp /* clear return address of native stub*/
601 asm_handle_exception:
603 mov xptr,0*8(%rsp) /* save exception pointer */
604 mov xpc,1*8(%rsp) /* save exception pc */
606 mov xpc,%rdi /* exception pc */
607 call codegen_findmethod
609 mov %rax,2*8(%rsp) /* save data segment pointer */
611 mov 0*8(%rsp),%rax /* restore exception pointer */
612 mov 1*8(%rsp),%r10 /* restore exception pc */
615 mov %rax,%rdi /* exception pointer */
616 mov MethodPointer(itmp3),%rsi /* method pointer */
617 mov xpc,%rdx /* exception pc */
619 mov $1,%r8 /* set noindent flag */
620 call builtin_trace_exception
622 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
623 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
624 test %rcx,%rcx /* if empty table skip */
627 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
628 mov 0*8(%rsp),xptr /* get xptr */
631 mov 1*8(%rsp),xpc /* get xpc */
633 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
634 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
635 jg ex_table_cont /* if (false) continue */
636 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
637 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
638 jge ex_table_cont /* if (false) continue */
639 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
640 test %rdx,%rdx /* NULL catches everything */
643 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
653 call load_class_bootstrap
662 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
681 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
689 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
690 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
691 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
692 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
693 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
695 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
697 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
701 cmp %edx,%esi /* xptr is instanceof catchtype */
705 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
707 mov 0*8(%rsp),%rax /* restore exception pointer */
708 add $(4*8),%rsp /* free stack frame */
710 jmp *xpc /* jump to the handler */
713 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
714 dec %rcx /* decrement entry counter */
715 test %rcx,%rcx /* if (t0 > 0) next entry */
719 mov 0*8(%rsp),%rax /* restore exception pointer */
720 mov 1*8(%rsp),%r10 /* restore exception pc */
721 mov 2*8(%rsp),%r11 /* restore data segment pointer */
724 mov %rax,%rcx /* save exception pointer */
727 movl IsSync(%r11),%eax /* %rax = SyncOffset */
728 test %rax,%rax /* if zero no monitorexit */
731 #if defined(USE_THREADS)
740 call builtin_monitorexit
749 mov FrameSize(%r11),%eax /* %eax = frame size */
750 add %rax,%rsp /* unwind stack */
751 mov %rsp,%rax /* %rax = pointer to save area */
753 mov IntSave(%r11),%edx /* %edx = saved int register count*/
780 shl $3,%edx /* multiply by 8 bytes */
784 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
807 movq -48(%rax),%xmm10
809 movq -40(%rax),%xmm11
811 movq -32(%rax),%xmm12
813 movq -24(%rax),%xmm13
815 movq -16(%rax),%xmm14
820 pop %r10 /* the new xpc is return address */
821 sub $3,%r10 /* subtract 3 bytes for call */
828 call codegen_findmethod /* get the new data segment ptr */
835 mov %rcx,%rax /* restore saved exception pointer*/
839 mov %rax,0*8(%rsp) /* save exception pointer */
840 mov %r10,1*8(%rsp) /* save exception pc */
841 mov %r11,2*8(%rsp) /* save data segment pointer */
846 /* asm_wrapper_patcher *********************************************************
852 24 pointer to virtual java_objectheader
853 16 machine code (which is patched back later)
854 8 unresolved class/method/field reference
855 0 pointer to patcher function
857 *******************************************************************************/
860 sub $(17*8),%rsp /* stack frame (16-byte aligned) */
862 SAVE_ARGUMENT_REGISTERS
863 SAVE_TEMPORARY_REGISTERS
865 mov itmp1,15*8(%rsp) /* save itmp1 and itmp2 */
866 mov itmp2,16*8(%rsp) /* can be used by some instructions */
868 mov %rsp,a0 /* pass stack pointer */
869 add $(18*8),a0 /* skip patcher function pointer */
870 mov 17*8(%rsp),itmp3 /* get function pointer */
871 call *itmp3 /* call the patcher function */
872 mov v0,itmp3 /* save return value */
874 RESTORE_ARGUMENT_REGISTERS
875 RESTORE_TEMPORARY_REGISTERS
877 mov 15*8(%rsp),itmp1 /* restore itmp1 and itmp2 */
878 mov 16*8(%rsp),itmp2 /* can be used by some instructions */
880 add $((4+17)*8),%rsp /* remove stack frame, keep ra */
882 test itmp3,itmp3 /* exception thrown? */
883 jz L_asm_wrapper_patcher_exception
884 ret /* call new patched code */
886 L_asm_wrapper_patcher_exception:
887 /*stack bottom is xpc and it is directly below the last java stackframe*/
891 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
893 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
894 call builtin_asm_get_exceptionptrptr
897 lea _exceptionptr,itmp2
899 mov (itmp2),a0 /* get the exception pointer */
900 movl $0,(itmp2) /* clear exception pointer */
901 call helper_fillin_stacktrace
905 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
908 pop xpc /* get and remove return address */
909 jmp asm_handle_exception
912 /* asm_builtin_x2x *************************************************************
914 * Wrapper functions for float to int corner cases *
916 *******************************************************************************/
921 SAVE_ARGUMENT_REGISTERS
926 RESTORE_ARGUMENT_REGISTERS
935 SAVE_ARGUMENT_REGISTERS
940 RESTORE_ARGUMENT_REGISTERS
949 SAVE_ARGUMENT_REGISTERS
954 RESTORE_ARGUMENT_REGISTERS
963 SAVE_ARGUMENT_REGISTERS
968 RESTORE_ARGUMENT_REGISTERS
974 /* asm_builtin_arraycheckcast **************************************************
976 Does the cast check and eventually throws an exception.
978 *******************************************************************************/
980 asm_builtin_arraycheckcast:
981 sub $24,%rsp /* keep stack 16-byte aligned */
982 mov %rdi,(%rsp) /* save object pointer */
983 call builtin_arraycheckcast
984 test %rax,%rax /* if (false) throw exception */
986 mov (%rsp),%rax /* return object pointer */
987 add $24,%rsp /* free stack space */
991 /*call new_classcastexception*/
993 pop xpc /* delete return address */
994 sub $3,xpc /* faulting address is ra - 3 */
995 mov string_java_lang_ClassCastException,xptr
996 jmp asm_throw_and_handle_exception
999 /* asm_builtin_aastore *********************************************************
1001 Checks if the object can be stored in the given array and stores the
1002 address if it's possible. This function can also throw some exceptions.
1004 *******************************************************************************/
1006 asm_builtin_aastore:
1007 sub $(3*8),%rsp /* allocate stack space */
1008 test %rdi,%rdi /* if null pointer throw exception */
1011 movl offarraysize(%rdi),%eax /* load size */
1012 cmpl %eax,%esi /* do bound check */
1013 jae nb_aastore_bound /* if out of bounds throw exception */
1015 shl $3,%rsi /* index * 8 */
1017 add %rsi,%r10 /* add index * 8 to arrayref */
1019 mov %r10,(%rsp) /* save store position */
1020 mov %rdx,8(%rsp) /* save object */
1022 mov %rdx,%rsi /* object is second argument */
1023 call builtin_canstore /* builtin_canstore(arrayref,object) */
1024 test %rax,%rax /* if (false) throw exception */
1027 mov (%rsp),%r10 /* restore store position */
1028 mov 8(%rsp),%rdx /* restore object */
1029 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1030 add $(3*8),%rsp /* free stack space */
1035 pop xpc /* delete return address from stack */
1036 sub $3,xpc /* faulting address is return adress - 3 */
1037 mov string_java_lang_NullPointerException,xptr
1038 jmp asm_throw_and_handle_exception
1042 push $0 /*directly below return address*/
1043 push $0 /*internal*/
1047 call asm_prepare_native_stackinfo
1049 mov itmp1,%rdi /* move index into a0 */
1050 call new_arrayindexoutofboundsexception
1052 call asm_remove_native_stackinfo
1054 pop xpc /* just remove one quadword */
1055 pop xpc /* delete return address */
1056 sub $3,xpc /* faulting address is return adress - 3 */
1057 jmp asm_handle_exception
1060 /*call new_arraystoreexception*/
1062 pop xpc /* delete return address */
1063 sub $3,xpc /* faulting address is return adress - 3 */
1064 mov string_java_lang_ArrayStoreException,xptr
1065 jmp asm_throw_and_handle_exception
1068 /******************* function asm_initialize_thread_stack **********************
1070 * initialized a thread stack *
1071 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1073 *******************************************************************************/
1075 asm_initialize_thread_stack:
1086 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1087 mov %rsi,%rax /* return restorepoint in %rax */
1091 /******************* function asm_perform_threadswitch *************************
1093 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1095 * performs a threadswitch *
1097 *******************************************************************************/
1099 asm_perform_threadswitch:
1100 sub $(7*8),%rsp /* allocate stack frame */
1109 mov 7*8(%rsp),%rax /* save current return address */
1112 mov %rsp,(%rdi) /* first argument **from */
1113 mov %rsp,(%rdx) /* third argument **stackTop */
1115 mov (%rsi),%rsp /* load new stack pointer */
1124 mov 6*8(%rsp),%rax /* restore return address */
1125 add $(7*8),%rsp /* free stack frame */
1130 /********************* function asm_switchstackandcall *************************
1132 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1135 * Switches to a new stack, calls a function and switches back. *
1136 * a0 (%rdi) new stack pointer *
1137 * a1 (%rsi) function pointer *
1138 * a2 (%rdx) pointer to variable where stack top should be stored *
1139 * a3 (%rcx) pointer to user data, is passed to the function *
1141 *******************************************************************************/
1143 asm_switchstackandcall:
1144 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1145 sub $16,%rdi /* allocate new stack */
1147 mov 8(%rsp),%rax /* save return address on new stack */
1149 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1150 mov %rsp,(%rdx) /* save old stack pointer to variable */
1152 mov %rdi,%rsp /* switch to new stack */
1154 mov %rcx,%rdi /* pass pointer */
1155 call *%rsi /* and call function */
1157 mov (%rsp),%r10 /* load return address */
1158 mov 8(%rsp),%rsp /* switch to old stack */
1159 add $(1*8),%rsp /* free stack space */
1160 mov %r10,(%rsp) /* write return adress */
1166 /************************ function asm_prepare_native_stackinfo ****************************
1168 * creates a stackfame for the begin of a native function (either builtin or not ) *
1169 * expected stack at begin of function *
1171 * address of the jit call which invokes the native *
1172 * begin address of stack frame of the java method *
1173 * method pointer or 0 (for built ins) *
1174 * padding for stackframesize 16*n+8 *
1177 * at end of function: *
1179 * address of the jit call which invokes the native *
1180 * begin address of stack frame of the java method *
1181 * method pointer or 0 (for built ins) *
1182 * address of thread specific top of native list *
1183 * old value of thread specific head *
1184 * padding for stackframesize 16*n+8) *
1188 * This thing is less efficient than the original #define (callerside) *
1189 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1190 ********************************************************************************************/
1193 asm_prepare_native_stackinfo:
1194 sub $16,%rsp /*space for the 2 new pointers*/
1198 call builtin_asm_get_stackframeinfo
1211 /************************ function asm_remove _native_stackinfo *******************************************
1213 * removes a stackfame for the begin of a native function (either builtin or not) *
1214 * expected stack at begin of function *
1215 * address of the jit call which invokes the native *
1216 * begin address of stack frame of the java method *
1217 * method pointer or 0 (for built ins) *
1218 * address thread specific top of native list *
1219 * old value of thread specific head *
1223 * at end of function: *
1225 * return adresss of the jit call which invokes the native *
1231 * This thing is less efficient than the original #define (callerside), uses ITMP2,uses ITMP3,keeps ITMP1 *
1232 ***********************************************************************************************************/
1234 asm_remove_native_stackinfo:
1245 asm_throw_and_handle_exception:
1246 push xpc /* the pushed XPC is directly below the java frame*/
1250 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1255 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1260 jmp asm_handle_exception
1261 ret /*should never be reached */
1264 asm_throw_and_handle_hardware_arithmetic_exception:
1267 push $0 /* the pushed XPC is directly below the java frame*/
1270 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1272 mov string_java_lang_ArithmeticException_message,%rsi
1273 mov string_java_lang_ArithmeticException,%rdi
1275 call new_exception_message
1277 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1281 jmp asm_handle_exception
1282 ret /*should never be reached */
1285 asm_getclassvalues_atomic:
1288 movl offbaseval(a0),itmp1l
1289 movl offdiffval(a0),itmp2l
1290 movl offbaseval(a1),itmp3l
1292 movl itmp1l,offcast_super_baseval(a2)
1293 movl itmp2l,offcast_super_diffval(a2)
1294 movl itmp3l,offcast_sub_baseval(a2)
1299 asm_criticalsections:
1300 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1303 .quad _crit_restart1
1306 .quad _crit_restart2
1312 * These are local overrides for various environment variables in Emacs.
1313 * Please do not remove this and leave it at the end of the file, where
1314 * Emacs will automagically detect them.
1315 * ---------------------------------------------------------------------
1318 * indent-tabs-mode: t