1 /* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
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 Changes: Joseph Wenninger
33 $Id: asmpart.S 2364 2005-04-25 08:50:52Z christian $
39 #include "vm/jit/i386/offsets.h"
40 #include "vm/jit/i386/asmoffsets.h"
43 /* define it like the risc way */
62 /********************* exported functions and variables ***********************/
64 .globl asm_calljavafunction
65 .globl asm_calljavafunction_int
67 .globl asm_calljavafunction2
68 .globl asm_calljavafunction2int
69 .globl asm_calljavafunction2long
70 .globl asm_calljavafunction2float
71 .globl asm_calljavafunction2double
73 .globl asm_call_jit_compiler
74 .globl asm_handle_builtin_exception
75 .globl asm_handle_nat_exception
76 .globl asm_handle_exception
78 .globl asm_wrapper_patcher
79 .globl asm_wrapper_patcher_builtin_new
80 .globl asm_wrapper_patcher_builtin_newarray
81 .globl asm_wrapper_patcher_builtin_multianewarray
82 .globl asm_wrapper_patcher_builtin_checkarraycast
83 .globl asm_wrapper_patcher_builtin_arrayinstanceof
85 .globl asm_builtin_checkarraycast
86 .globl asm_builtin_newarray
87 .globl asm_builtin_multianewarray
88 .globl asm_builtin_aastore
90 #if defined(USE_THREADS)
91 .globl asm_builtin_monitorenter
92 .globl asm_builtin_monitorexit
95 .globl asm_builtin_ldiv
96 .globl asm_builtin_lrem
97 .globl asm_builtin_f2i
98 .globl asm_builtin_f2l
99 .globl asm_builtin_d2i
100 .globl asm_builtin_d2l
101 .globl asm_builtin_arrayinstanceof
102 .globl asm_perform_threadswitch
103 .globl asm_initialize_thread_stack
104 .globl asm_switchstackandcall
105 .globl asm_getcallingmethod
106 .globl asm_criticalsections
107 .globl asm_getclassvalues_atomic
109 .globl asm_throw_and_handle_exception
110 .globl asm_throw_and_handle_hardware_arithmetic_exception
112 .globl asm_prepare_native_stackinfo
113 .globl asm_remove_native_stackinfo
116 /********************* function asm_calljavafunction ***************************
118 * This function calls a Java-method (which possibly needs compilation) *
119 * with up to 4 address parameters. *
121 * This functions calls the JIT-compiler which eventually translates the *
122 * method into machine code. *
125 * javaobject_header *asm_calljavamethod (methodinfo *m, *
126 * void *arg1, void *arg2, void *arg3, void *arg4); *
128 *******************************************************************************/
133 .long 0 /* catch type all */
134 .long calljava_xhandler /* handler pc */
135 .long calljava_xhandler /* end pc */
136 .long asm_calljavafunction /* start pc */
137 .long 1 /* extable size */
138 .long 0 /* line number table start */
139 .long 0 /* line number table size */
140 .long 0 /* fltsave */
141 .long 0 /* intsave */
144 .long 32 /* frame size */
145 .long 0 /* method pointer (pointer to name) */
147 asm_calljavafunction:
148 asm_calljavafunction_int:
149 push %ebp /* allocate stack space */
152 push %ebx /* save registers */
157 sub $16,%esp /* 4 adress parameters * 4 Bytes */
158 mov 24(%ebp),%eax /* copy adress parameters to new block */
170 mov 8(%ebp),%eax /* move function pointer to %eax */
172 lea asm_call_jit_compiler,%edx
173 call *%edx /* call JIT compiler */
176 pop %edi /* restore registers */
183 push %eax /* pass exception pointer */
184 call builtin_throw_exception
188 pop %edi /* restore registers */
192 xor %eax,%eax /* return NULL */
196 /********************* function asm_calljavafunction ***************************
198 * This function calls a Java-method (which possibly needs compilation) *
199 * with up to 4 address parameters. *
201 * This functions calls the JIT-compiler which eventually translates the *
202 * method into machine code. *
205 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
206 * u4 count, u4 size, void *callblock); *
208 *******************************************************************************/
213 .long 0 /* catch type all */
214 .long calljava_xhandler2 /* handler pc */
215 .long calljava_xhandler2 /* end pc */
216 .long asm_calljavafunction2 /* start pc */
217 .long 1 /* extable size */
218 .long 0 /* line number table start */
219 .long 0 /* line number table size */
220 .long 0 /* fltsave */
221 .long 0 /* intsave */
224 .long 32 /* frame size */
225 .long 0 /* method pointer (pointer to name) */
227 asm_calljavafunction2:
228 asm_calljavafunction2int:
229 asm_calljavafunction2long:
230 asm_calljavafunction2float:
231 asm_calljavafunction2double:
233 mov %esp,%ebp /* save stackptr */
235 push %ebx /* save registers */
239 mov 20(%ebp),%eax /* pointer to arg block (4(push)+4(return)+4+4+4)*/
240 mov 12(%ebp),%ecx /* arg count (4(push)+4(return)+4 */
241 test %ecx,%ecx /* maybe we have no args */
242 jle calljava_copydone
244 mov %ecx,%edx /* calculate stack size */
246 mov %eax,%edi /* save pointer to arg block */
247 calljava_calcstacksize:
248 mov offjniitemtype(%eax),%ebx
249 test $1,%ebx /* Two Word Type? */
250 jz calljava_onewordtype
252 calljava_onewordtype:
255 test %edx,%edx /* any args left ?*/
257 add $sizejniblock,%eax /* goto next argument block */
258 jmp calljava_calcstacksize
261 mov %edi,%eax /* restore pointer to arg block */
262 sub %esi,%esp /* stack frame for arguments */
266 mov offjniitem(%eax),%edx /* copy 4 Byte of Argument */
268 add $4,%edi /* increase sp to next argument */
269 mov offjniitemtype(%eax),%ebx /* type -> ebx */
270 test $1,%ebx /* Two Word Type? */
272 mov offjniitem+4(%eax),%edx /* copy upper 4 Byte of 2 Word Type */
274 add $4,%edi /* increase sp to next argument */
276 sub $1,%ecx /* are there any args left? */
278 jle calljava_copydone
280 add $sizejniblock,%eax /* goto next argument block */
281 jmp calljava_copyloop
284 mov 8(%ebp),%eax /* move function pointer to %eax */
286 lea asm_call_jit_compiler,%edx
287 call *%edx /* call JIT compiler */
290 add %esi,%esp /* remove arg stack frame */
291 pop %edi /* restore registers */
298 push %eax /* pass exception pointer */
299 call builtin_throw_exception
302 add %esi,%esp /* remove arg stack frame */
303 pop %edi /* restore registers */
307 xor %eax,%eax /* return NULL */
311 /****************** function asm_call_jit_compiler *****************************
313 * invokes the compiler for untranslated JavaVM methods. *
315 * Register R0 contains a pointer to the method info structure (prepared *
316 * by createcompilerstub). Using the return address in R26 and the *
317 * offset in the LDA instruction or using the value in methodptr R28 the *
318 * patching address for storing the method address can be computed: *
320 * method address was either loaded using *
322 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
323 * i386_call_reg(REG_ITMP2) *
327 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
328 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
329 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
330 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
331 * i386_call_reg(REG_ITMP1) *
333 * in the static case the method pointer can be computed using the *
334 * return address and the lda function following the jmp instruction *
336 *******************************************************************************/
338 asm_call_jit_compiler:
339 push %ebx /* save register */
342 mov 2*4(%esp),%ebp /* get return address (2 push) */
343 mov -1(%ebp),%bl /* get function code */
344 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
345 jne L_not_static_special
347 sub $6,%ebp /* calculate address of immediate */
348 jmp L_call_jit_compile
350 L_not_static_special:
351 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
352 jne L_not_virtual_interface
354 sub $6,%ebp /* calculate address of offset */
355 mov (%ebp),%ebp /* get offset */
356 add itmp2,%ebp /* add base address to get method address */
357 jmp L_call_jit_compile
359 L_not_virtual_interface: /* a call from asm_calljavafunction */
363 push %ebp /* save address for method pointer */
365 push %eax /* push methodpointer on stack */
369 pop %ebp /* restore address for method pointer */
371 test %eax,%eax /* check for exception */
372 je L_asm_call_jit_compiler_exception
374 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
377 mov %eax,(%ebp) /* and now save the new pointer */
380 pop %ebp /* restore registers */
383 jmp *%eax /* ...and now call the new method */
385 L_asm_call_jit_compiler_exception:
386 pop %ebp /* restore registers */
389 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
390 call builtin_asm_get_exceptionptrptr
393 lea _exceptionptr,%ecx
395 mov (%ecx),%eax /* get the exception pointer */
396 movl $0,(%ecx) /* clear the exception pointer */
398 pop %ecx /* delete return address */
399 sub $2,%ecx /* faulting address is return adress - 2 */
401 L_refillinStacktrace: /*a compilation error should cause a stacktrace
402 which starts at the method call, which caused
403 the compilation of the new function. Until this
404 point the trace is invalid anyways, since it is
405 not complete. Compared to other runtimes it will
406 not be correct either, since we report eg class
407 not found errors too early, since we always
408 compile methods completely. The native info
409 should be moved around the jit call to get
410 a more compliant trace for the "exception in
412 push %ecx /* store fault adress */
413 push %eax /* temporarily save exception pointer*/
414 push $0 /* internal function */
415 call builtin_asm_get_stackframeinfo
416 push %eax /* save location of thread specific stack info head pointer */
417 mov (%eax),%ecx /* save old value of pointer*/
419 mov %esp,(%eax) /*store pointer to this structure*/
420 mov 12(%esp),%eax /* get the exception pointer again*/
421 movl $0,12(%esp) /*java stack begins just above structure*/
422 push $0 /*used for the jni_callblock structure*/
423 push %eax /*save eax for later */
424 /* get fillInStackTrace method*/
425 push utf_void__java_lang_Throwable
426 push utf_fillInStackTrace
427 mov offobjvftbl(%eax),%ecx
428 mov offclass(%ecx),%eax
430 call class_resolvemethod
438 call asm_calljavafunction2
441 /*remove native stack info */
450 jmp asm_handle_exception
453 /********************* function asm_handle_exception ***************************
455 * This function handles an exception. It does not use the usual calling *
456 * conventions. The exception pointer is passed in REG_ITMP1 and the *
457 * pc from the exception raising position is passed in REG_ITMP2. It searches *
458 * the local exception table for a handler. If no one is found, it unwinds *
459 * stacks and continues searching the callers. *
461 * void asm_handle_exception (exceptionptr, exceptionpc); *
463 *******************************************************************************/
465 asm_handle_nat_exception:
466 add $4,%esp /* clear return address of native stub */
468 asm_handle_exception:
469 asm_handle_exception_loop:
473 push %eax /* save exception pointer */
474 push %ecx /* save exception pc */
476 call codegen_findmethod /* get the data segment ptr */
480 mov -8(%ebp),%ecx /* could be changed in findmethod */
482 push %edx /* save data segment pointer */
489 mov %eax,(%esp) /* exception pointer */
490 mov MethodPointer(%edx),%eax /* method pointer */
492 mov %ecx,8(%esp) /* exception pc */
493 movl $0,12(%esp) /* line number */
494 movl $1,16(%esp) /* set no unwind flag */
495 call builtin_trace_exception
497 mov -12(%ebp),%esi /* %esi = data segment pointer */
498 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
499 test %ecx,%ecx /* if empty table skip */
502 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
503 mov -4(%ebp),%eax /* get xptr */
506 mov -8(%ebp),%edx /* get xpc */
508 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
509 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
510 jg ex_table_cont /* if (false) continue */
511 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
512 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
513 jge ex_table_cont /* if (false) continue */
514 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
515 test %ebx,%ebx /* NULL catches everything */
518 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
522 mov %eax,1*4(%esp) /* save not callee saved regs */
525 mov %ebx,0*4(%esp) /* exception class is argument */
526 call load_class_bootstrap
534 cmpl $0,offclasslinked(%ebx)
538 mov %eax,1*4(%esp) /* save not callee saved regs */
541 mov %ebx,0*4(%esp) /* exception class is argument */
550 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
558 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
559 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
560 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
561 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
562 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
564 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
566 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
570 cmp %ebx,%esi /* xptr is instanceof catchtype */
574 mov ExHandlerPC(%edi),%edx
576 pop %edi /* restore registers */
579 add $8,%esp /* suck %ecx, %edx */
580 pop %eax /* restore xptr */
583 jmp *%edx /* jump to exception handler */
586 lea ExEntrySize(%edi),%edi
595 pop %edx /* restore data segment pointer */
600 push %eax /* save exception pointer */
603 mov IsSync(%edx),%eax /* %eax = SyncOffset */
604 test %eax,%eax /* if zero no monitorexit */
607 #if defined(USE_THREADS)
609 mov (%eax),%eax /* we have the xptr on the stack (+4-4=0) */
610 push %edx /* save regs */
612 call builtin_monitorexit
614 pop %edx /* restore regs */
619 add FrameSize(%edx),%eax /* %eax = frame size */
620 add $4,%eax /* we have the xptr on the stack */
622 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
644 shl $2,%ecx /* multiply by 4 bytes */
648 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
675 pop %eax /* restore exception pointer */
677 mov FrameSize(%edx),%ecx /* %ecx = frame size */
678 add %ecx,%esp /* unwind stack */
680 pop %ecx /* the new xpc is return address */
681 sub $2,%ecx /* -2 -> call */
683 jmp asm_handle_exception_loop
686 /* asm_wrapper_patcher *********************************************************
692 12 last byte of machine code (xmcode)
693 8 machine code (which is patched back later)
694 4 unresolved field reference
695 0 patcher function pointer to call
697 *******************************************************************************/
700 sub $(2*4),%esp /* create stack frame */
702 mov itmp1,0*4(%esp) /* save itmp1 and itmp2 */
703 mov itmp2,1*4(%esp) /* may be used by some instructions */
707 mov 3*4(%esp),itmp1 /* return adress into java code */
708 mov %esp,itmp2 /* begin of java stack frame */
712 pushl $0 /* internal (invisible) method */
713 call asm_prepare_native_stackinfo /* puts additional 2 *4 bytes of
714 data onto the stack */
717 mov %esp,itmp1 /* pass stack pointer */
718 add $(3*4),itmp1 /* also skip patcher function pointer */
720 mov 3*4(%esp),itmp1 /* get function pointer from stack */
721 call *itmp1 /* call the patcher function */
723 mov v0,itmp3 /* save return value */
726 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
727 into java machine code on stack */
728 add $4,%esp /* ret address no longer needed, is still
729 on stack a few bytes above */
732 mov 0*4(%esp),itmp1 /* restore itmp1 and itmp2 */
733 mov 1*4(%esp),itmp2 /* may be used by some instructions */
735 add $((4+2)*4),%esp /* remove stack frame, keep ra */
736 test itmp3,itmp3 /* exception thrown? */
737 jz L_asm_wrapper_patcher_exception
738 ret /* call new patched code */
740 L_asm_wrapper_patcher_exception:
741 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
742 call builtin_asm_get_exceptionptrptr
745 lea _exceptionptr,itmp2
747 mov (itmp2),xptr /* get the exception pointer */
748 movl $0,(itmp2) /* clear the exception pointer */
750 pop xpc /* get and remove return address */
751 jmp asm_handle_exception
754 /* asm_wrapper_patcher_builtin_new *********************************************
759 4 contains the class reference
762 *******************************************************************************/
764 asm_wrapper_patcher_builtin_new:
765 mov 1*4(%esp),itmp1 /* get class reference */
766 mov %esp,itmp2 /* get stack pointer */
767 push itmp2 /* pass stack pointer */
768 push itmp1 /* pass class reference */
769 call patcher_builtin_new /* call the patcher function */
770 add $(2*4),%esp /* clear arguments */
771 test v0,v0 /* exception thrown? */
772 jz L_asm_wrapper_patcher_exception
773 ret /* call new patched code */
776 /* asm_wrapper_patcher_builtin_* ***********************************************
781 8 contains the class reference
785 *******************************************************************************/
787 asm_wrapper_patcher_builtin_newarray:
788 lea patcher_builtin_newarray,itmp3
789 jmp L_asm_wrapper_patcher_builtin_main
791 asm_wrapper_patcher_builtin_multianewarray:
792 lea patcher_builtin_multianewarray,itmp3
793 jmp L_asm_wrapper_patcher_builtin_main
795 asm_wrapper_patcher_builtin_checkarraycast:
796 lea patcher_builtin_checkarraycast,itmp3
797 jmp L_asm_wrapper_patcher_builtin_main
799 asm_wrapper_patcher_builtin_arrayinstanceof:
800 lea patcher_builtin_arrayinstanceof,itmp3
802 L_asm_wrapper_patcher_builtin_main:
803 mov 2*4(%esp),itmp1 /* get class reference */
804 mov %esp,itmp2 /* save stack pointer */
805 push itmp1 /* pass class reference */
806 push itmp2 /* pass stack pointer */
807 call *itmp3 /* call the patcher function */
808 add $(2*4),%esp /* clear arguments */
809 test v0,v0 /* exception thrown? */
810 jz L_asm_wrapper_patcher_exception
811 ret /* call new patched code */
814 /********************* function asm_builtin_monitorenter ***********************
816 * Does null check and calls monitorenter or throws an exception *
818 *******************************************************************************/
820 #if defined(USE_THREADS)
821 asm_builtin_monitorenter:
823 je nb_monitorenter /* if (null) throw exception */
824 jmp builtin_monitorenter /* else call builtin_monitorenter */
827 mov string_java_lang_NullPointerException,%eax
830 jmp asm_throw_and_handle_exception
833 push string_java_lang_NullPointerException
837 pop %ecx /* delete return address */
838 sub $2,%ecx /* faulting address is return adress - 2 */
839 jmp asm_handle_exception
844 /********************* function asm_builtin_monitorexit ************************
846 * Does null check and calls monitorexit or throws an exception *
848 *******************************************************************************/
850 #if defined(USE_THREADS)
851 asm_builtin_monitorexit:
854 je nb_monitorexit /* if (null) throw exception */
855 push %ecx /* save registers which could be used */
858 call builtin_monitorexit /* else call builtin_monitorenter */
860 pop %edx /* restore registers which could be used */
865 mov string_java_lang_NullPointerException,%eax
868 jmp asm_throw_and_handle_exception
871 push string_java_lang_NullPointerException
875 pop %ecx /* delete return address */
876 sub $2,%ecx /* faulting address is return adress - 2 */
877 jmp asm_handle_exception
882 /************************ function asm_builtin_ldiv ****************************
884 * Does null check and calls ldiv or throws an exception *
886 *******************************************************************************/
891 test %eax,%eax /* if (null) throw exception */
899 jmp asm_throw_and_handle_hardware_arithmetic_exception
901 push string_java_lang_ArithmeticException_message
902 push string_java_lang_ArithmeticException
903 call new_exception_message
906 pop %ecx /* delete return address */
907 sub $2,%ecx /* faulting address is return adress - 2 */
908 jmp asm_handle_exception
911 /************************ function asm_builtin_lrem ****************************
913 * Does null check and calls lrem or throws an exception *
915 *******************************************************************************/
920 test %eax,%eax /* if (null) throw exception */
928 jmp asm_throw_and_handle_hardware_arithmetic_exception
930 push string_java_lang_ArithmeticException_message
931 push string_java_lang_ArithmeticException
932 call new_exception_message
935 pop %ecx /* delete return address */
936 sub $2,%ecx /* faulting address is return adress - 2 */
937 jmp asm_handle_exception
940 /************************ function asm_builtin_x2x *****************************
942 * Wrapper functions for corner cases *
944 *******************************************************************************/
975 /******************* function asm_builtin_checkarraycast ***********************
977 * Does the cast check and eventually throws an exception *
979 *******************************************************************************/
981 asm_builtin_checkarraycast:
982 sub $8,%esp /* build stack frame (2 * 4 bytes) */
984 mov 12(%esp),%eax /* first param: 8 (frame) + 4 (return)*/
985 mov %eax,(%esp) /* save object pointer */
987 mov 16(%esp),%eax /* second param: 8 (frame) + 4 (return) + 4*/
990 call builtin_checkarraycast /* builtin_checkarraycast */
992 test %eax,%eax /* if (false) throw exception */
995 mov 12(%esp),%eax /* return object pointer */
1001 mov string_java_lang_ClassCastException,%eax
1004 jmp asm_throw_and_handle_exception
1006 push string_java_lang_ClassCastException
1012 pop %ecx /* delete return address */
1013 sub $2,%ecx /* faulting address is return adress - 2 */
1014 jmp asm_handle_exception
1018 /* asm_builtin_newarray ********************************************************
1020 * Does the cast check and eventually throws an exception *
1021 * asm_builtin_checkarraycast(java_objectheader *obj, vftbl_t *target) *
1022 *******************************************************************************/
1024 asm_builtin_newarray:
1025 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1027 mov 12(%esp),%eax /* copy first param (8 + 4(return)) */
1030 mov 16(%esp),%eax /* copy second param (8 + 4 + 4) */
1033 call builtin_newarray
1038 /******************* function asm_builtin_aastore ******************************
1040 * Does the cast check and eventually throws an exception *
1041 * void asm_builtin_aastore(java_objectarray *a, s4 index, java_objectheader *o)*
1042 *******************************************************************************/
1044 asm_builtin_aastore:
1045 sub $12,%esp /* build stack frame (3 * 4 bytes) */
1047 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
1048 test %eax,%eax /* if null pointer throw exception */
1051 mov offarraysize(%eax),%edx /* load size */
1052 mov 20(%esp),%ecx /* index (12 + 4 + 4) */
1053 cmp %edx,%ecx /* do bound check */
1054 jae nb_aastore_bound /* if out of bounds throw exception */
1056 shl $2,%ecx /* index * 4 */
1057 add %eax,%ecx /* add index * 4 to arrayref */
1059 mov %ecx,8(%esp) /* save store position */
1061 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
1064 mov 24(%esp),%eax /* object is second argument (12+4+4+4) */
1067 call builtin_canstore /* builtin_canstore(arrayref,object) */
1069 test %eax,%eax /* if (false) throw exception */
1074 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
1081 mov string_java_lang_NullPointerException,%eax
1084 jmp asm_throw_and_handle_exception
1087 push string_java_lang_NullPointerException
1092 pop %ecx /* delete return address */
1093 sub $2,%ecx /* faulting address is return adress - 2 */
1094 jmp asm_handle_exception
1098 mov %ecx,%eax /* itmp2 contains array index */
1099 pushl $0 /*directly below return adress*/
1100 pushl $0 /*internal (invisible) method*/
1101 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1104 call new_arrayindexoutofboundsexception
1107 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
1109 pop %ecx /* delete return address */
1110 sub $2,%ecx /* faulting address is return adress - 2 */
1111 jmp asm_handle_exception
1116 mov string_java_lang_ArrayStoreException,%eax
1119 jmp asm_throw_and_handle_exception
1122 push string_java_lang_ArrayStoreException
1127 pop %ecx /* delete return address */
1128 sub $2,%ecx /* faulting address is return adress - 2 */
1129 jmp asm_handle_exception
1132 /******************* function asm_builtin_arrayinstanceof **********************
1134 * Does the instanceof check of arrays *
1135 * asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class) *
1136 *******************************************************************************/
1138 asm_builtin_arrayinstanceof:
1139 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1141 mov 12(%esp),%eax /* obj (8+4(return)) */
1144 mov 16(%esp),%eax /* class (8+4(return)+4(obj)) */
1147 call builtin_arrayinstanceof
1153 /******************* function asm_initialize_thread_stack **********************
1155 * initialized a thread stack *
1156 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1158 *******************************************************************************/
1160 asm_initialize_thread_stack:
1161 mov 8(%esp),%eax /* (to)->stackEnd */
1162 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1174 mov 4(%esp),%edx /* save (u1*) (func) */
1177 ret /* return restorepoint in %eax */
1180 /******************* function asm_perform_threadswitch *************************
1182 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1184 * performs a threadswitch *
1186 *******************************************************************************/
1188 asm_perform_threadswitch:
1200 mov 36(%esp),%eax /* save current return address */
1203 mov 40(%esp),%eax /* first argument **from */
1206 mov 48(%esp),%eax /* third argument **stackTop */
1209 mov 44(%esp),%eax /* second argument **to */
1210 mov 0(%eax),%esp /* load new stack pointer */
1216 /* skip stack pointer */
1221 add $32,%esp /* leave return address on stack */
1225 /********************* function asm_switchstackandcall *************************
1227 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1230 * Switches to a new stack, calls a function and switches back. *
1231 * a0 new stack pointer *
1232 * a1 function pointer *
1233 * a2 pointer to variable where stack top should be stored *
1234 * a3 pointer to user data, is passed to the function *
1236 *******************************************************************************/
1238 asm_switchstackandcall:
1239 mov 4(%esp),%edx /* first argument *stack */
1240 sub $8,%edx /* allocate new stack */
1242 mov (%esp),%eax /* save return address on new stack */
1245 mov %esp,4(%edx) /* save old stack pointer on new stack */
1247 mov 12(%esp),%eax /* third argument **stacktopsave */
1248 mov %esp,(%eax) /* save old stack pointer to variable */
1250 mov 8(%esp),%eax /* load function pointer */
1251 mov 16(%esp),%ecx /* fourth argument *p */
1253 mov %edx,%esp /* switch to new stack */
1256 mov %ecx,0(%esp) /* pass pointer */
1257 call *%eax /* and call function */
1260 mov (%esp),%edx /* load return address */
1261 mov 4(%esp),%esp /* switch to old stack */
1266 asm_throw_and_handle_exception:
1268 pushl $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 below*/
1274 add $4,%esp /*remove parameter*/
1276 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1279 jmp asm_handle_exception
1280 ret /*should never be reached */
1282 asm_throw_and_handle_hardware_arithmetic_exception:
1285 pushl $0 /* the pushed XPC is directly below the java frame*/
1287 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1289 mov string_java_lang_ArithmeticException_message,%eax
1291 mov string_java_lang_ArithmeticException,%eax
1294 call new_exception_message
1295 add $8,%esp /*remove parameters */
1297 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1300 jmp asm_handle_exception
1301 ret /*should never be reached */
1304 /*optimize a littlebit */
1308 call i386_native_stub_debug
1312 mov offclassinit(%eax),%ecx /* get initialized flag */
1314 jnz L_builtin_new_noinit
1316 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1318 /* 2 *4 bytes, the return adress is used directy */
1319 pushl $0 /* the structure is placed directly below the java stackframe*/
1320 pushl $0 /* builtin (invisible) method */
1321 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1323 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1328 call builtin_asm_get_stackframeinfo
1341 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1350 jmp L_builtin_new_patch
1353 L_builtin_new_noinit:
1358 /*jmp L_builtin_new_patch*/
1360 L_builtin_new_patch:
1361 /*add patching code here */
1362 lea builtin_new,%edx
1364 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1372 asm_getclassvalues_atomic:
1374 mov 4(%esp),%ecx /* super */
1375 mov 8(%esp),%edx /* sub */
1377 mov offbaseval(%ecx),%eax
1378 mov offdiffval(%ecx),%ecx
1379 mov offbaseval(%edx),%edx
1382 mov 16(%esp),%ebx /* out */
1383 mov %eax,offcast_super_baseval(%ebx)
1384 mov %ecx,offcast_super_diffval(%ebx)
1385 mov %edx,offcast_sub_baseval(%ebx)
1391 asm_criticalsections:
1392 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1395 .long _crit_restart1
1398 .long _crit_restart2
1404 /************************ function asm_prepare_native_stackinfo ****************************
1406 * creates a stackfame for the begin of a native function (either builtin or not ) *
1407 * expected stack at begin of function *
1409 * address of the jit call which invokes the native *
1410 * begin address of stack frame of the java method *
1411 * method pointer or 0 (for built ins) *
1414 * at end of function: *
1416 * address of the jit call which invokes the native *
1417 * begin address of stack frame of the java method *
1418 * method pointer or 0 (for built ins) *
1419 * address of thread specific top of native list *
1420 * old value of thread specific head *
1424 * This thing is less efficient than the original #define (callerside) *
1425 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1426 ********************************************************************************************/
1429 asm_prepare_native_stackinfo:
1434 lea builtin_asm_get_stackframeinfo,%ecx
1445 #define PREPARE_NATIVE_STACKINFO \
1446 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1447 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1448 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1449 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1450 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1451 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1452 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1453 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1454 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1455 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1456 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1457 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1461 /************************ function asm_remove _native_stackinfo *******************************************
1463 * creates a stackfame for the begin of a native function (either builtin or not) *
1464 * expected stack at begin of function *
1465 * address of the jit call which invokes the native *
1466 * begin address of stack frame of the java method *
1467 * method pointer or 0 (for built ins) *
1468 * address thread specific top of native list *
1469 * old value of thread specific head *
1472 * at end of function: *
1474 * return adresss of the jit call which invokes the native *
1477 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1480 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1481 ***********************************************************************************************************/
1483 asm_remove_native_stackinfo:
1493 #define REMOVE_NATIVE_STACKINFO \
1494 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1495 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1496 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1497 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1504 * These are local overrides for various environment variables in Emacs.
1505 * Please do not remove this and leave it at the end of the file, where
1506 * Emacs will automagically detect them.
1507 * ---------------------------------------------------------------------
1510 * indent-tabs-mode: t