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 2360 2005-04-24 13:07:57Z jowenn $
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
142 .globl asm_wrapper_patcher_builtin_new
144 .globl asm_wrapper_patcher_builtin_newarray
145 .globl asm_wrapper_patcher_builtin_multianewarray
146 .globl asm_wrapper_patcher_builtin_checkarraycast
147 .globl asm_wrapper_patcher_builtin_arrayinstanceof
149 .globl asm_builtin_checkarraycast
150 .globl asm_builtin_aastore
152 #if defined(USE_THREADS)
153 .globl asm_builtin_monitorenter
154 .globl asm_builtin_monitorexit
157 .globl asm_builtin_f2i
158 .globl asm_builtin_f2l
159 .globl asm_builtin_d2i
160 .globl asm_builtin_d2l
162 .globl asm_perform_threadswitch
163 .globl asm_initialize_thread_stack
164 .globl asm_switchstackandcall
165 .globl asm_criticalsections
166 .globl asm_getclassvalues_atomic
168 .globl asm_prepare_native_stackinfo
169 .globl asm_remove_native_stackinfo
170 .globl asm_throw_and_handle_exception
171 .globl asm_throw_and_handle_hardware_arithmetic_exception
173 /********************* function asm_calljavafunction ***************************
175 * This function calls a Java-method (which possibly needs compilation) *
176 * with up to 4 address parameters. *
178 * This functions calls the JIT-compiler which eventually translates the *
179 * method into machine code. *
182 * javaobject_header *asm_calljavamethod (methodinfo *m, *
183 * void *arg1, void *arg2, void *arg3, void *arg4); *
185 *******************************************************************************/
190 .quad 0 /* catch type all */
191 .quad calljava_xhandler /* handler pc */
192 .quad calljava_xhandler /* end pc */
193 .quad asm_calljavafunction /* start pc */
194 .long 1 /* extable size */
196 .quad 0 /* line number table start */
197 .quad 0 /* line number table size */
199 .long 0 /* fltsave */
200 .long 0 /* intsave */
203 .long 8 /* frame size */
204 .quad 0 /* method pointer (pointer to name) */
206 asm_calljavafunction:
207 asm_calljavafunction_int:
208 sub $(3*8),%rsp /* keep stack 16-byte aligned */
210 mov %rbx,1*8(%rsp) /* %rbx is not a callee saved in cacao */
211 mov %rdi,%rax /* move function pointer to %rax */
212 /* compilerstub uses this */
214 mov %rsi,%rdi /* pass remaining parameters */
219 lea asm_call_jit_compiler,%r11
220 call *%r11 /* call JIT compiler */
224 add $(3*8),%rsp /* free stack space */
228 mov %rax,%rdi /* pass exception pointer */
229 call builtin_throw_exception
233 xor %rax,%rax /* return NULL */
237 /********************* function asm_calljavafunction ***************************
239 * This function calls a Java-method (which possibly needs compilation) *
240 * with up to 4 address parameters. *
242 * This functions calls the JIT-compiler which eventually translates the *
243 * method into machine code. *
246 * javaobject_header *asm_calljavamethod (methodinfo *m, *
247 * void *arg1, void *arg2, void *arg3, void *arg4); *
249 *******************************************************************************/
254 .quad 0 /* catch type all */
255 .quad calljava_xhandler2 /* handler pc */
256 .quad calljava_xhandler2 /* end pc */
257 .quad asm_calljavafunction2 /* start pc */
258 .long 1 /* extable size */
259 .quad 0 /* line number table start */
260 .quad 0 /* line number table size */
261 .long 0 /* fltsave */
262 .long 0 /* intsave */
265 .long 24 /* frame size */
266 .quad 0 /* method pointer (pointer to name) */
268 asm_calljavafunction2:
269 asm_calljavafunction2int:
270 asm_calljavafunction2long:
271 asm_calljavafunction2float:
272 asm_calljavafunction2double:
273 sub $(7*8),%rsp /* keep stack 16-byte aligned */
274 mov %rbx,0*8(%rsp) /* %rbx is not a callee saved in cacao */
281 mov %rdi,%rax /* move method pointer for compiler */
282 xor %rbp,%rbp /* set argument stack frame to zero */
284 test %rsi,%rsi /* maybe we have no args... */
287 mov %rsi,itmp3 /* arg count */
288 mov %rcx,itmp2 /* pointer to arg block */
290 mov itmp2,%r14 /* save argument block pointer */
291 mov itmp3,%r15 /* save argument count */
293 sub $sizejniblock,itmp2 /* initialize pointer (smaller code) */
294 add $1,itmp3 /* initialize argument count */
295 xor %r12,%r12 /* initialize integer argument counter */
296 xor %r13,%r13 /* initialize float argument counter */
299 add $sizejniblock,itmp2 /* goto next argument block */
300 dec itmp3 /* argument count - 1 */
301 jz L_register_copy_done
302 andb $0x02,offjniitemtype(itmp2) /* is this a float/double type? */
303 jnz L_register_handle_float /* yes, handle it */
305 cmp $INT_ARG_CNT,%r12 /* are we out of integer argument */
306 je L_register_copy /* register? yes, next loop */
308 lea jumptable_integer,%rbp
309 mov 0(%rbp,%r12,8),%rbx
310 inc %r12 /* integer argument counter + 1 */
313 L_register_handle_float:
314 cmp $FLT_ARG_CNT,%r13 /* are we out of float argument */
315 je L_register_copy /* register? yes, next loop */
317 lea jumptable_float,%rbp
318 mov 0(%rbp,%r13,8),%rbx
319 inc %r13 /* float argument counter + 1 */
322 L_register_copy_done:
323 mov %r15,%rbp /* calculate remaining arguments */
324 sub %r12,%rbp /* - integer arguments in registers */
325 sub %r13,%rbp /* - float arguments in registers */
326 jle L_copy_done /* are all assigned to registers? */
328 shl $3,%rbp /* calculate stack size */
329 sub %rbp,%rsp /* stack frame for arguments */
330 mov %rsp,%rbx /* use %rbx as temp sp */
332 sub $sizejniblock,%r14 /* initialize pointer (smaller code) */
333 add $1,%r15 /* initialize argument count */
336 add $sizejniblock,%r14 /* goto next argument block */
337 dec %r15 /* are there any arguments left? */
338 jz L_copy_done /* no test needed after dec */
340 andb $0x02,offjniitemtype(%r14) /* is this a float/double type? */
341 jnz L_stack_handle_float
342 dec %r12 /* arguments assigned to registers */
343 jge L_stack_copy_loop
346 L_stack_handle_float:
347 dec %r13 /* arguments assigned to registers */
348 jge L_stack_copy_loop
351 mov offjniitem(%r14),itmp3 /* copy s8 argument onto stack */
353 add $8,%rbx /* increase sp to next argument */
354 jmp L_stack_copy_loop
357 lea asm_call_jit_compiler,%r11/* %rax still contains method pointer */
358 call *%r11 /* call JIT compiler */
360 add %rbp,%rsp /* remove argument stack frame if any */
362 mov 5*8(%rsp),%r15 /* restore callee saved registers */
368 add $(7*8),%rsp /* free stack space */
372 mov %rax,%rdi /* pass exception pointer */
373 call builtin_throw_exception
375 mov 5*8(%rsp),%r15 /* restore callee saved registers */
381 add $(7*8),%rsp /* free stack space */
382 xor %rax,%rax /* return NULL */
395 mov offjniitem(itmp2),a0
398 mov offjniitem(itmp2),a1
401 mov offjniitem(itmp2),a2
404 mov offjniitem(itmp2),a3
407 mov offjniitem(itmp2),a4
410 mov offjniitem(itmp2),a5
425 movq offjniitem(itmp2),fa0
428 movq offjniitem(itmp2),fa1
431 movq offjniitem(itmp2),fa2
434 movq offjniitem(itmp2),fa3
437 movq offjniitem(itmp2),fa4
440 movq offjniitem(itmp2),fa5
443 movq offjniitem(itmp2),fa6
446 movq offjniitem(itmp2),fa7
450 /****************** function asm_call_jit_compiler *****************************
452 * invokes the compiler for untranslated JavaVM methods. *
454 * Register R0 contains a pointer to the method info structure (prepared *
455 * by createcompilerstub). Using the return address in R26 and the *
456 * offset in the LDA instruction or using the value in methodptr R28 the *
457 * patching address for storing the method address can be computed: *
459 * method address was either loaded using *
461 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
462 * i386_call_reg(REG_ITMP2) *
466 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP2) ; invokevirtual/interface *
467 * i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3) *
468 * i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \ *
469 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
470 * i386_call_reg(REG_ITMP1) *
472 * in the static case the method pointer can be computed using the *
473 * return address and the lda function following the jmp instruction *
475 *******************************************************************************/
477 asm_call_jit_compiler:
478 sub $8,%rsp /* keep stack 16-byte aligned */
480 mov %rbx,(%rsp) /* save register */
482 mov 8(%rsp),%r11 /* get return address */
483 mov -1(%r11),%bl /* get function code */
484 cmp $0xd2,%bl /* called with `call *REG_ITMP2' (%r10)? */
485 jne L_not_static_special
487 sub $11,%r11 /* calculate address of immediate */
488 jmp L_call_jit_compile
490 L_not_static_special:
491 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%rax) */
492 jne L_not_virtual_interface
494 sub $7,%r11 /* calculate address of offset */
495 mov (%r11),%r11d /* get offset (32-bit) */
496 add %r10,%r11 /* add base address to get method address */
497 jmp L_call_jit_compile
499 L_not_virtual_interface: /* a call from asm_calljavamethod */
503 mov (%rsp),%rbx /* restore register */
505 sub $(24*8),%rsp /* 8 + 6*8 + 8*8 + 8*8 */
507 mov %r11,0*8(%rsp) /* save address for method pointer */
509 mov a0,1*8(%rsp) /* save arguments */
525 movq %xmm8,15*8(%rsp)/* we use them as callee saved registers */
526 movq %xmm9,16*8(%rsp)
527 movq %xmm10,17*8(%rsp)
528 movq %xmm11,18*8(%rsp)
529 movq %xmm12,19*8(%rsp)
530 movq %xmm13,20*8(%rsp)
531 movq %xmm14,21*8(%rsp)
532 movq %xmm15,22*8(%rsp)
534 mov %rax,%rdi /* pass method pointer */
555 movq 15*8(%rsp),%xmm8
556 movq 16*8(%rsp),%xmm9
557 movq 17*8(%rsp),%xmm10
558 movq 18*8(%rsp),%xmm11
559 movq 19*8(%rsp),%xmm12
560 movq 20*8(%rsp),%xmm13
561 movq 21*8(%rsp),%xmm14
562 movq 22*8(%rsp),%xmm15
565 add $8,%rsp /* keep stack 16-byte aligned */
567 test %rax,%rax /* check for exception */
568 je L_asm_call_jit_compiler_exception
570 test %r11,%r11 /* is address == 0 (asm_calljavamethod) */
573 mov %rax,(%r11) /* and now save the new pointer */
576 jmp *%rax /* ...and now call the new method */
578 L_asm_call_jit_compiler_exception:
579 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
580 call builtin_asm_get_exceptionptrptr
583 lea _exceptionptr,itmp2
585 mov (itmp2),xptr /* get the exception pointer */
586 movl $0,(itmp2) /* clear the exception pointer */
588 pop xpc /* delete return address */
589 sub $5,xpc /* faulting address is ra - 5 */
591 jmp asm_handle_exception
594 /********************* function asm_handle_exception ***************************
596 * This function handles an exception. It does not use the usual calling *
597 * conventions. The exception pointer is passed in REG_ITMP1 and the *
598 * pc from the exception raising position is passed in REG_ITMP2. It searches *
599 * the local exception table for a handler. If no one is found, it unwinds *
600 * stacks and continues searching the callers. *
602 * void asm_handle_exception (exceptionptr, exceptionpc); *
604 *******************************************************************************/
606 asm_handle_nat_exception:
607 add $8,%rsp /* clear return address of native stub*/
609 asm_handle_exception:
611 mov xptr,0*8(%rsp) /* save exception pointer */
612 mov xpc,1*8(%rsp) /* save exception pc */
614 mov xpc,%rdi /* exception pc */
615 call codegen_findmethod
617 mov %rax,2*8(%rsp) /* save data segment pointer */
619 mov 0*8(%rsp),%rax /* restore exception pointer */
620 mov 1*8(%rsp),%r10 /* restore exception pc */
623 mov %rax,%rdi /* exception pointer */
624 mov MethodPointer(itmp3),%rsi /* method pointer */
625 mov xpc,%rdx /* exception pc */
627 mov $1,%r8 /* set noindent flag */
628 call builtin_trace_exception
630 mov 2*8(%rsp),itmp3 /* %r11 = data segment pointer */
631 mov ExTableSize(itmp3),%rcx /* %rcx = exception table size */
632 test %rcx,%rcx /* if empty table skip */
635 lea ExTableStart(itmp3),%rdi /* %rdi = start of exception table */
636 mov 0*8(%rsp),xptr /* get xptr */
639 mov 1*8(%rsp),xpc /* get xpc */
641 mov ExStartPC(%rdi),%rdx /* %rdx = exception start pc */
642 cmp xpc,%rdx /* %rdx = (startpc <= xpc) */
643 jg ex_table_cont /* if (false) continue */
644 mov ExEndPC(%rdi),%rdx /* %rdx = exception end pc */
645 cmp %rdx,xpc /* %rdx = (xpc < endpc) */
646 jge ex_table_cont /* if (false) continue */
647 mov ExCatchType(%rdi),%rdx /* %rdx = exception catch type */
648 test %rdx,%rdx /* NULL catches everything */
651 cmpl $0,offclassloaded(%rdx) /* check if class is loaded */
661 call load_class_bootstrap
670 cmpl $0,offclasslinked(%rdx) /* check if class is linked */
689 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
697 mov offobjvftbl(%rax),%rsi /* %rsi = vftblptr(xptr) */
698 mov offclassvftbl(%rdx),%rdx /* %rdx = vftblptr(catchtype) class (not obj) */
699 mov offbaseval(%rsi),%esi /* %esi = baseval(xptr) */
700 mov offbaseval(%rdx),%r10d /* %r10d = baseval(catchtype) */
701 mov offdiffval(%rdx),%edx /* %edx = diffval(catchtype) */
703 sub %r10d,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
705 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
709 cmp %edx,%esi /* xptr is instanceof catchtype */
713 mov ExHandlerPC(%rdi),xpc /* xpc = exception handler pc */
715 mov 0*8(%rsp),%rax /* restore exception pointer */
716 add $(4*8),%rsp /* free stack frame */
718 jmp *xpc /* jump to the handler */
721 lea ExEntrySize(%rdi),%rdi /* next exception table entry */
722 dec %rcx /* decrement entry counter */
723 test %rcx,%rcx /* if (t0 > 0) next entry */
727 mov 0*8(%rsp),%rax /* restore exception pointer */
728 mov 1*8(%rsp),%r10 /* restore exception pc */
729 mov 2*8(%rsp),%r11 /* restore data segment pointer */
732 mov %rax,%rcx /* save exception pointer */
735 movl IsSync(%r11),%eax /* %rax = SyncOffset */
736 test %rax,%rax /* if zero no monitorexit */
739 #if defined(USE_THREADS)
748 call builtin_monitorexit
757 mov FrameSize(%r11),%eax /* %eax = frame size */
758 add %rax,%rsp /* unwind stack */
759 mov %rsp,%rax /* %rax = pointer to save area */
761 mov IntSave(%r11),%edx /* %edx = saved int register count*/
788 shl $3,%edx /* multiply by 8 bytes */
792 mov FltSave(%r11),%edx /* %edx = saved flt register count*/
815 movq -48(%rax),%xmm10
817 movq -40(%rax),%xmm11
819 movq -32(%rax),%xmm12
821 movq -24(%rax),%xmm13
823 movq -16(%rax),%xmm14
828 pop %r10 /* the new xpc is return address */
829 sub $3,%r10 /* subtract 3 bytes for call */
836 call codegen_findmethod /* get the new data segment ptr */
843 mov %rcx,%rax /* restore saved exception pointer*/
847 mov %rax,0*8(%rsp) /* save exception pointer */
848 mov %r10,1*8(%rsp) /* save exception pc */
849 mov %r11,2*8(%rsp) /* save data segment pointer */
854 /* asm_wrapper_patcher *********************************************************
860 16 machine code (which is patched back later)
861 8 unresolved class/method/field reference
862 0 pointer to patcher function
864 *******************************************************************************/
867 sub $(18*8),%rsp /* stack frame (16-byte aligned) */
869 SAVE_ARGUMENT_REGISTERS
870 SAVE_TEMPORARY_REGISTERS
872 mov itmp1,15*8(%rsp) /* save itmp1 and itmp2 */
873 mov itmp2,16*8(%rsp) /* can be used by some instructions */
875 mov %rsp,a0 /* pass stack pointer */
876 add $(19*8),a0 /* skip patcher function pointer */
877 mov 18*8(%rsp),itmp3 /* get function pointer */
878 call *itmp3 /* call the patcher function */
879 mov v0,itmp3 /* save return value */
881 RESTORE_ARGUMENT_REGISTERS
882 RESTORE_TEMPORARY_REGISTERS
884 mov 15*8(%rsp),itmp1 /* restore itmp1 and itmp2 */
885 mov 16*8(%rsp),itmp2 /* can be used by some instructions */
887 add $((3+18)*8),%rsp /* remove stack frame, keep ra */
889 test itmp3,itmp3 /* exception thrown? */
890 jz L_asm_wrapper_patcher_exception
891 ret /* call new patched code */
893 L_asm_wrapper_patcher_exception:
894 /*stack bottom is xpc and it is directly below the last java stackframe*/
898 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
900 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
901 call builtin_asm_get_exceptionptrptr
904 lea _exceptionptr,itmp2
906 mov (itmp2),a0 /* get the exception pointer */
907 movl $0,(itmp2) /* clear exception pointer */
908 call helper_fillin_stacktrace
912 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
915 pop xpc /* get and remove return address */
916 jmp asm_handle_exception
919 /* asm_wrapper_patcher_builtin_new *********************************************
924 a0 contains the class reference
926 *******************************************************************************/
928 asm_wrapper_patcher_builtin_new:
929 sub $(1*8),%rsp /* stack frame (16-byte aligned) */
930 mov %rsp,a1 /* pass stack pointer */
932 call patcher_builtin_new /* call the helper function */
933 add $(1*8),%rsp /* remove stack frame */
934 test v0,v0 /* exception thrown? */
935 jz L_asm_wrapper_patcher_exception
936 ret /* call new patched code */
939 /* asm_wrapper_patcher_builtin_* ***********************************************
944 a1 contains the class reference
946 *******************************************************************************/
948 asm_wrapper_patcher_builtin_newarray:
949 lea patcher_builtin_newarray,itmp1
950 jmp L_asm_wrapper_patcher_builtin_main
952 asm_wrapper_patcher_builtin_multianewarray:
953 lea patcher_builtin_multianewarray,itmp1
954 jmp L_asm_wrapper_patcher_builtin_main
956 asm_wrapper_patcher_builtin_checkarraycast:
957 lea patcher_builtin_checkarraycast,itmp1
958 jmp L_asm_wrapper_patcher_builtin_main
960 asm_wrapper_patcher_builtin_arrayinstanceof:
961 lea patcher_builtin_arrayinstanceof,itmp1
963 L_asm_wrapper_patcher_builtin_main:
964 sub $(1*8),%rsp /* stack frame (16-byte aligned) */
965 mov a0,0*8(%rsp) /* save argument */
966 mov %rsp,a0 /* pass stack pointer */
968 call *itmp1 /* call the patcher function */
969 mov 0*8(%rsp),a0 /* restore argument */
970 add $(1*8),%rsp /* remove stack frame */
971 test v0,v0 /* exception thrown? */
972 jz L_asm_wrapper_patcher_exception
973 ret /* call new patched code */
978 /********************* function asm_builtin_monitorenter ***********************
980 * Does null check and calls monitorenter or throws an exception *
982 *******************************************************************************/
984 #if defined(USE_THREADS)
985 asm_builtin_monitorenter:
987 je nb_monitorenter /* if (null) throw exception */
988 jmp builtin_monitorenter /* else call builtin_monitorenter */
991 /*call new_nullpointerexception*/
992 pop xpc /* delete return address */
993 sub $3,xpc /* faulting address is ra - 3 */
994 mov string_java_lang_NullPointerException,xptr
995 jmp asm_throw_and_handle_exception
999 /********************* function asm_builtin_monitorexit ************************
1001 * Does null check and calls monitorexit or throws an exception *
1003 *******************************************************************************/
1005 #if defined(USE_THREADS)
1006 asm_builtin_monitorexit:
1008 je nb_monitorexit /* if (null) throw exception */
1009 jmp builtin_monitorexit /* else call builtin_monitorenter */
1012 /*call new_nullpointerexception*/
1013 pop xpc /* delete return address */
1014 sub $3,xpc /* faulting address is ra - 3 */
1015 mov string_java_lang_NullPointerException,xptr
1016 jmp asm_throw_and_handle_exception
1020 /********************* function asm_builtin_x2x ********************************
1022 * Wrapper functions for float to int corner cases *
1024 *******************************************************************************/
1029 SAVE_ARGUMENT_REGISTERS
1034 RESTORE_ARGUMENT_REGISTERS
1043 SAVE_ARGUMENT_REGISTERS
1048 RESTORE_ARGUMENT_REGISTERS
1057 SAVE_ARGUMENT_REGISTERS
1062 RESTORE_ARGUMENT_REGISTERS
1071 SAVE_ARGUMENT_REGISTERS
1076 RESTORE_ARGUMENT_REGISTERS
1082 /* asm_builtin_checkarraycast **************************************************
1084 Does the cast check and eventually throws an exception.
1086 *******************************************************************************/
1088 asm_builtin_checkarraycast:
1089 sub $24,%rsp /* keep stack 16-byte aligned */
1090 mov %rdi,(%rsp) /* save object pointer */
1091 call builtin_checkarraycast /* builtin_checkarraycast */
1092 test %rax,%rax /* if (false) throw exception */
1094 mov (%rsp),%rax /* return object pointer */
1095 add $24,%rsp /* free stack space */
1099 /*call new_classcastexception*/
1101 pop xpc /* delete return address */
1102 sub $3,xpc /* faulting address is ra - 3 */
1103 mov string_java_lang_ClassCastException,xptr
1104 jmp asm_throw_and_handle_exception
1107 /* asm_builtin_aastore *********************************************************
1109 Checks if the object can be stored in the given array and stores the
1110 address if it's possible. This function can also throw some exceptions.
1112 *******************************************************************************/
1114 asm_builtin_aastore:
1115 sub $(3*8),%rsp /* allocate stack space */
1116 test %rdi,%rdi /* if null pointer throw exception */
1119 movl offarraysize(%rdi),%eax /* load size */
1120 cmpl %eax,%esi /* do bound check */
1121 jae nb_aastore_bound /* if out of bounds throw exception */
1123 shl $3,%rsi /* index * 8 */
1125 add %rsi,%r10 /* add index * 8 to arrayref */
1127 mov %r10,(%rsp) /* save store position */
1128 mov %rdx,8(%rsp) /* save object */
1130 mov %rdx,%rsi /* object is second argument */
1131 call builtin_canstore /* builtin_canstore(arrayref,object) */
1132 test %rax,%rax /* if (false) throw exception */
1135 mov (%rsp),%r10 /* restore store position */
1136 mov 8(%rsp),%rdx /* restore object */
1137 mov %rdx,offobjarrdata(%r10)/* store objectptr in array */
1138 add $(3*8),%rsp /* free stack space */
1143 pop xpc /* delete return address from stack */
1144 sub $3,xpc /* faulting address is return adress - 3 */
1145 mov string_java_lang_NullPointerException,xptr
1146 jmp asm_throw_and_handle_exception
1150 push $0 /*directly below return address*/
1151 push $0 /*internal*/
1155 call asm_prepare_native_stackinfo
1157 mov itmp1,%rdi /* move index into a0 */
1158 call new_arrayindexoutofboundsexception
1160 call asm_remove_native_stackinfo
1162 pop xpc /* just remove one quadword */
1163 pop xpc /* delete return address */
1164 sub $3,xpc /* faulting address is return adress - 3 */
1165 jmp asm_handle_exception
1168 /*call new_arraystoreexception*/
1170 pop xpc /* delete return address */
1171 sub $3,xpc /* faulting address is return adress - 3 */
1172 mov string_java_lang_ArrayStoreException,xptr
1173 jmp asm_throw_and_handle_exception
1176 /******************* function asm_initialize_thread_stack **********************
1178 * initialized a thread stack *
1179 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1181 *******************************************************************************/
1183 asm_initialize_thread_stack:
1194 mov %rdi,6*8(%rsi) /* save (u1*) (func) */
1195 mov %rsi,%rax /* return restorepoint in %rax */
1199 /******************* function asm_perform_threadswitch *************************
1201 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1203 * performs a threadswitch *
1205 *******************************************************************************/
1207 asm_perform_threadswitch:
1208 sub $(7*8),%rsp /* allocate stack frame */
1217 mov 7*8(%rsp),%rax /* save current return address */
1220 mov %rsp,(%rdi) /* first argument **from */
1221 mov %rsp,(%rdx) /* third argument **stackTop */
1223 mov (%rsi),%rsp /* load new stack pointer */
1232 mov 6*8(%rsp),%rax /* restore return address */
1233 add $(7*8),%rsp /* free stack frame */
1238 /********************* function asm_switchstackandcall *************************
1240 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1243 * Switches to a new stack, calls a function and switches back. *
1244 * a0 (%rdi) new stack pointer *
1245 * a1 (%rsi) function pointer *
1246 * a2 (%rdx) pointer to variable where stack top should be stored *
1247 * a3 (%rcx) pointer to user data, is passed to the function *
1249 *******************************************************************************/
1251 asm_switchstackandcall:
1252 sub $(1*8),%rsp /* keep stack 16-byte aligned */
1253 sub $16,%rdi /* allocate new stack */
1255 mov 8(%rsp),%rax /* save return address on new stack */
1257 mov %rsp,8(%rdi) /* save old stack pointer on new stack*/
1258 mov %rsp,(%rdx) /* save old stack pointer to variable */
1260 mov %rdi,%rsp /* switch to new stack */
1262 mov %rcx,%rdi /* pass pointer */
1263 call *%rsi /* and call function */
1265 mov (%rsp),%r10 /* load return address */
1266 mov 8(%rsp),%rsp /* switch to old stack */
1267 add $(1*8),%rsp /* free stack space */
1268 mov %r10,(%rsp) /* write return adress */
1274 /************************ function asm_prepare_native_stackinfo ****************************
1276 * creates a stackfame for the begin of a native function (either builtin or not ) *
1277 * expected stack at begin of function *
1279 * address of the jit call which invokes the native *
1280 * begin address of stack frame of the java method *
1281 * method pointer or 0 (for built ins) *
1282 * padding for stackframesize 16*n+8 *
1285 * at end of function: *
1287 * address of the jit call which invokes the native *
1288 * begin address of stack frame of the java method *
1289 * method pointer or 0 (for built ins) *
1290 * address of thread specific top of native list *
1291 * old value of thread specific head *
1292 * padding for stackframesize 16*n+8) *
1296 * This thing is less efficient than the original #define (callerside) *
1297 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1298 ********************************************************************************************/
1301 asm_prepare_native_stackinfo:
1302 sub $16,%rsp /*space for the 2 new pointers*/
1306 call builtin_asm_get_stackframeinfo
1319 /************************ function asm_remove _native_stackinfo *******************************************
1321 * removes a stackfame for the begin of a native function (either builtin or not) *
1322 * expected stack at begin of function *
1323 * address of the jit call which invokes the native *
1324 * begin address of stack frame of the java method *
1325 * method pointer or 0 (for built ins) *
1326 * address thread specific top of native list *
1327 * old value of thread specific head *
1331 * at end of function: *
1333 * return adresss of the jit call which invokes the native *
1339 * This thing is less efficient than the original #define (callerside), uses ITMP2,uses ITMP3,keeps ITMP1 *
1340 ***********************************************************************************************************/
1342 asm_remove_native_stackinfo:
1353 asm_throw_and_handle_exception:
1354 push xpc /* the pushed XPC is directly below the java frame*/
1358 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1363 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1368 jmp asm_handle_exception
1369 ret /*should never be reached */
1372 asm_throw_and_handle_hardware_arithmetic_exception:
1375 push $0 /* the pushed XPC is directly below the java frame*/
1378 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1380 mov string_java_lang_ArithmeticException_message,%rsi
1381 mov string_java_lang_ArithmeticException,%rdi
1383 call new_exception_message
1385 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1389 jmp asm_handle_exception
1390 ret /*should never be reached */
1393 asm_getclassvalues_atomic:
1396 movl offbaseval(a0),itmp1l
1397 movl offdiffval(a0),itmp2l
1398 movl offbaseval(a1),itmp3l
1400 movl itmp1l,offcast_super_baseval(a2)
1401 movl itmp2l,offcast_super_diffval(a2)
1402 movl itmp3l,offcast_sub_baseval(a2)
1407 asm_criticalsections:
1408 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1411 .quad _crit_restart1
1414 .quad _crit_restart2
1420 * These are local overrides for various environment variables in Emacs.
1421 * Please do not remove this and leave it at the end of the file, where
1422 * Emacs will automagically detect them.
1423 * ---------------------------------------------------------------------
1426 * indent-tabs-mode: t