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 2290 2005-04-12 21:57:56Z twisti $
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_check_clinit
80 .globl asm_patcher_builtin_new
81 .globl asm_patcher_invokestatic_special
83 .globl asm_builtin_checkarraycast
84 .globl asm_builtin_newarray
85 .globl asm_builtin_aastore
87 #if defined(USE_THREADS)
88 .globl asm_builtin_monitorenter
89 .globl asm_builtin_monitorexit
92 .globl asm_builtin_ldiv
93 .globl asm_builtin_lrem
94 .globl asm_builtin_f2i
95 .globl asm_builtin_f2l
96 .globl asm_builtin_d2i
97 .globl asm_builtin_d2l
98 .globl asm_builtin_arrayinstanceof
99 .globl asm_perform_threadswitch
100 .globl asm_initialize_thread_stack
101 .globl asm_switchstackandcall
102 .globl asm_getcallingmethod
103 .globl asm_criticalsections
104 .globl asm_getclassvalues_atomic
106 .globl asm_throw_and_handle_exception
107 .globl asm_throw_and_handle_hardware_arithmetic_exception
109 .globl asm_prepare_native_stackinfo
110 .globl asm_remove_native_stackinfo
113 /********************* function asm_calljavafunction ***************************
115 * This function calls a Java-method (which possibly needs compilation) *
116 * with up to 4 address parameters. *
118 * This functions calls the JIT-compiler which eventually translates the *
119 * method into machine code. *
122 * javaobject_header *asm_calljavamethod (methodinfo *m, *
123 * void *arg1, void *arg2, void *arg3, void *arg4); *
125 *******************************************************************************/
130 .long 0 /* catch type all */
131 .long calljava_xhandler /* handler pc */
132 .long calljava_xhandler /* end pc */
133 .long asm_calljavafunction /* start pc */
134 .long 1 /* extable size */
135 .long 0 /* line number table start */
136 .long 0 /* line number table size */
137 .long 0 /* fltsave */
138 .long 0 /* intsave */
141 .long 32 /* frame size */
142 .long 0 /* method pointer (pointer to name) */
144 asm_calljavafunction:
145 asm_calljavafunction_int:
146 push %ebp /* allocate stack space */
149 push %ebx /* save registers */
153 sub $32,%esp /* pass the remaining parameters */
156 mov %edx,28(%esp) /* convert parms to 8 byte */
172 mov 8(%ebp),%eax /* move function pointer to %eax */
174 lea asm_call_jit_compiler,%edx
175 call *%edx /* call JIT compiler */
178 pop %edi /* restore registers */
185 push %eax /* pass exception pointer */
186 call builtin_throw_exception
190 pop %edi /* restore registers */
194 xor %eax,%eax /* return NULL */
198 /********************* function asm_calljavafunction ***************************
200 * This function calls a Java-method (which possibly needs compilation) *
201 * with up to 4 address parameters. *
203 * This functions calls the JIT-compiler which eventually translates the *
204 * method into machine code. *
207 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
208 * u4 count, u4 size, void *callblock); *
210 *******************************************************************************/
215 .long 0 /* catch type all */
216 .long calljava_xhandler2 /* handler pc */
217 .long calljava_xhandler2 /* end pc */
218 .long asm_calljavafunction2 /* start pc */
219 .long 1 /* extable size */
220 .long 0 /* line number table start */
221 .long 0 /* line number table size */
222 .long 0 /* fltsave */
223 .long 0 /* intsave */
226 .long 32 /* frame size */
227 .long 0 /* method pointer (pointer to name) */
229 asm_calljavafunction2:
230 asm_calljavafunction2int:
231 asm_calljavafunction2long:
232 asm_calljavafunction2float:
233 asm_calljavafunction2double:
235 mov %esp,%ebp /* save stackptr */
237 push %ebx /* save registers */
241 mov 20(%ebp),%eax /* pointer to arg block */
242 mov 12(%ebp),%ecx /* arg count */
243 test %ecx,%ecx /* maybe we have no args */
244 jle calljava_copydone
246 mov %ecx,%edx /* calculate stack size */
248 mov %edx,%esi /* save in callee saved register */
249 sub %esi,%esp /* stack frame for arguments */
253 mov offjniitem(%eax),%edx
255 mov offjniitem+4(%eax),%edx
258 sub $1,%ecx /* are there any args left? */
260 jle calljava_copydone
262 add $sizejniblock,%eax /* goto next argument block */
263 add $8,%edi /* increase sp to next argument */
264 jmp calljava_copyloop
267 mov 8(%ebp),%eax /* move function pointer to %eax */
269 lea asm_call_jit_compiler,%edx
270 call *%edx /* call JIT compiler */
273 add %esi,%esp /* remove arg stack frame */
274 pop %edi /* restore registers */
281 push %eax /* pass exception pointer */
282 call builtin_throw_exception
285 add %esi,%esp /* remove arg stack frame */
286 pop %edi /* restore registers */
290 xor %eax,%eax /* return NULL */
294 /****************** function asm_call_jit_compiler *****************************
296 * invokes the compiler for untranslated JavaVM methods. *
298 * Register R0 contains a pointer to the method info structure (prepared *
299 * by createcompilerstub). Using the return address in R26 and the *
300 * offset in the LDA instruction or using the value in methodptr R28 the *
301 * patching address for storing the method address can be computed: *
303 * method address was either loaded using *
305 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
306 * i386_call_reg(REG_ITMP2) *
310 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
311 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
312 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
313 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
314 * i386_call_reg(REG_ITMP1) *
316 * in the static case the method pointer can be computed using the *
317 * return address and the lda function following the jmp instruction *
319 *******************************************************************************/
321 asm_call_jit_compiler:
322 push %ebx /* save register */
325 mov 8(%esp),%ebp /* get return address (2 push) */
326 mov -1(%ebp),%bl /* get function code */
327 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
328 jne L_not_static_special
330 sub $6,%ebp /* calculate address of immediate */
331 jmp L_call_jit_compile
333 L_not_static_special:
334 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
335 jne L_not_virtual_interface
337 sub $6,%ebp /* calculate address of offset */
338 mov (%ebp),%ebp /* get offset */
339 add itmp2,%ebp /* add base address to get method address */
340 jmp L_call_jit_compile
342 L_not_virtual_interface: /* a call from asm_calljavafunction */
346 push %ebp /* save address for method pointer */
348 push %eax /* push methodpointer on stack */
352 pop %ebp /* restore address for method pointer */
354 test %eax,%eax /* check for exception */
355 je L_asm_call_jit_compiler_exception
357 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
360 mov %eax,(%ebp) /* and now save the new pointer */
363 pop %ebp /* restore registers */
366 jmp *%eax /* ...and now call the new method */
368 L_asm_call_jit_compiler_exception:
369 pop %ebp /* restore registers */
372 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
373 call builtin_asm_get_exceptionptrptr
376 lea _exceptionptr,%ecx
378 mov (%ecx),%eax /* get the exception pointer */
379 movl $0,(%ecx) /* clear the exception pointer */
381 pop %ecx /* delete return address */
382 sub $2,%ecx /* faulting address is return adress - 2 */
384 L_refillinStacktrace: /*a compilation error should cause a stacktrace
385 which starts at the method call, which caused
386 the compilation of the new function. Until this
387 point the trace is invalid anyways, since it is
388 not complete. Compared to other runtimes it will
389 not be correct either, since we report eg class
390 not found errors too early, since we always
391 compile methods completely. The native info
392 should be moved around the jit call to get
393 a more compliant trace for the "exception in
395 push %ecx /* store fault adress */
396 push %eax /* temporarily save exception pointer*/
397 push $0 /* internal function */
398 call builtin_asm_get_stackframeinfo
399 push %eax /* save location of thread specific stack info head pointer */
400 mov (%eax),%ecx /* save old value of pointer*/
402 mov %esp,(%eax) /*store pointer to this structure*/
403 mov 12(%esp),%eax /* get the exception pointer again*/
404 movl $0,12(%esp) /*java stack begins just above structure*/
405 push $0 /*used for the jni_callblock structure*/
406 push %eax /*save eax for later */
407 /* get fillInStackTrace method*/
408 push utf_void__java_lang_Throwable
409 push utf_fillInStackTrace
410 mov offobjvftbl(%eax),%ecx
411 mov offclass(%ecx),%eax
413 call class_resolvemethod
421 call asm_calljavafunction2
424 /*remove native stack info */
433 jmp asm_handle_exception
436 /********************* function asm_handle_exception ***************************
438 * This function handles an exception. It does not use the usual calling *
439 * conventions. The exception pointer is passed in REG_ITMP1 and the *
440 * pc from the exception raising position is passed in REG_ITMP2. It searches *
441 * the local exception table for a handler. If no one is found, it unwinds *
442 * stacks and continues searching the callers. *
444 * void asm_handle_exception (exceptionptr, exceptionpc); *
446 *******************************************************************************/
448 asm_handle_nat_exception:
449 add $4,%esp /* clear return address of native stub */
451 asm_handle_exception:
452 asm_handle_exception_loop:
456 push %eax /* save exception pointer */
457 push %ecx /* save exception pc */
459 call codegen_findmethod /* get the data segment ptr */
463 mov -8(%ebp),%ecx /* could be changed in findmethod */
465 push %edx /* save data segment pointer */
472 mov %eax,(%esp) /* exception pointer */
473 mov MethodPointer(%edx),%eax /* method pointer */
475 mov %ecx,8(%esp) /* exception pc */
476 movl $0,12(%esp) /* line number */
477 movl $1,16(%esp) /* set no unwind flag */
478 call builtin_trace_exception
480 mov -12(%ebp),%esi /* %esi = data segment pointer */
481 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
482 test %ecx,%ecx /* if empty table skip */
485 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
486 mov -4(%ebp),%eax /* get xptr */
489 mov -8(%ebp),%edx /* get xpc */
491 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
492 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
493 jg ex_table_cont /* if (false) continue */
494 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
495 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
496 jge ex_table_cont /* if (false) continue */
497 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
498 test %ebx,%ebx /* NULL catches everything */
501 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
505 mov %eax,1*4(%esp) /* save not callee saved regs */
508 mov %ebx,0*4(%esp) /* exception class is argument */
509 call load_class_bootstrap
517 cmpl $0,offclasslinked(%ebx)
521 mov %eax,1*4(%esp) /* save not callee saved regs */
524 mov %ebx,0*4(%esp) /* exception class is argument */
533 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
541 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
542 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
543 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
544 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
545 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
547 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
549 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
553 cmp %ebx,%esi /* xptr is instanceof catchtype */
557 mov ExHandlerPC(%edi),%edx
559 pop %edi /* restore registers */
562 add $8,%esp /* suck %ecx, %edx */
563 pop %eax /* restore xptr */
566 jmp *%edx /* jump to exception handler */
569 lea ExEntrySize(%edi),%edi
578 pop %edx /* restore data segment pointer */
583 push %eax /* save exception pointer */
586 mov IsSync(%edx),%eax /* %eax = SyncOffset */
587 test %eax,%eax /* if zero no monitorexit */
590 #if defined(USE_THREADS)
592 mov -4(%eax),%eax /* we have the xptr on the stack */
593 push %edx /* save regs */
595 call builtin_monitorexit
597 pop %edx /* restore regs */
602 add FrameSize(%edx),%eax /* %eax = frame size */
603 add $4,%eax /* we have the xptr on the stack */
605 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
627 shl $3,%ecx /* multiply by 8 bytes */
631 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
658 pop %eax /* restore exception pointer */
660 mov FrameSize(%edx),%ecx /* %ecx = frame size */
661 add %ecx,%esp /* unwind stack */
663 pop %ecx /* the new xpc is return address */
666 jmp asm_handle_exception_loop
669 /* asm_check_clinit ************************************************************
675 16 ra ; return address of patched call in java machine code
676 12 xmcode ; additional machine code (only for i386 and x86_64)
677 8 mcode ; machine code to patch back in
678 4 class ; pointer to class
679 0 sp ; stack pointer of java stack frame + return address
681 *******************************************************************************/
684 mov 4(%esp),%eax /* get fieldinfo's class pointer */
685 mov offclassinit(%eax),%eax /* get initialized flag */
691 push itmp1 /*return adress into java machine code */
693 push itmp1 /*begin of java stack frame*/
694 pushl $0 /*internal (invisible) method*/
695 call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
696 data onto the stack */
699 mov 20+4+4(%esp),itmp1 /* get class pointer */
700 mov itmp1,(%esp) /* store class pointer as a0 */
701 call initialize_class /* call initialize class function */
704 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
705 into java machine code on stack */
706 add $4,%esp /* ret address no longer needed, is still
707 on stack a few bytes above */
709 test %eax,%eax /* we had an exception */
710 je L_initializererror
713 mov 16(%esp),itmp1 /* get return address */
714 sub $5,itmp1 /* remove size of `call rel32' */
716 mov 12(%esp),itmp2 /* get xmcode machine code */
717 movb itmp2b,(itmp1) /* patch back in 1 byte */
718 mov 8(%esp),itmp2 /* get mcode machine code */
719 mov itmp2,1(itmp1) /* patch back in 4 bytes */
721 add $(5*4),%esp /* remove stub stack frame incl. ra */
723 jmp *itmp1 /* jump to patched code an execute it */
726 add $(4*4),%esp /* remove stub stack frame */
728 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
729 call builtin_asm_get_exceptionptrptr
731 mov (%ecx),%eax /* get the exception pointer */
732 movl $0,(%ecx) /* clear the exception pointer */
734 lea _exceptionptr,%ecx
735 mov (%ecx),%eax /* get the exception pointer */
736 movl $0,(%ecx) /* clear the exception pointer */
739 pop itmp2 /* get and delete ra */
740 sub $5,itmp2 /* faulting address is ra - 5 */
742 jmp asm_handle_exception
745 /* asm_patcher_builtin_new *****************************************************
750 a0 contains the class reference
752 *******************************************************************************/
754 asm_patcher_builtin_new:
755 mov 4*1(%esp),itmp1 /* get the class reference */
757 call helper_resolve_classinfo /* call the helper function */
758 add $(4*1),%esp /* remove stack frame */
760 test v0,v0 /* exception thrown? */
761 jz L_asm_patcher_exception
763 pop itmp2 /* get return address */
764 sub $(2+5+7),itmp2 /* 2 (call) + 5 (movi) + 7 (movi) */
765 mov v0,3(itmp2) /* patch in new classinfo*: 3 (mov) */
767 lea builtin_new,itmp1 /* get address from builtin_new */
768 mov itmp1,8(itmp2) /* patch back function address */
769 jmp *itmp2 /* call new patched code */
771 L_asm_patcher_exception:
772 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
773 call builtin_asm_get_exceptionptrptr
776 lea _exceptionptr,itmp2
778 mov (itmp2),xptr /* get the exception pointer */
779 movl $0,(itmp2) /* clear the exception pointer */
781 pop itmp2 /* get and remove return address */
782 sub $5,itmp2 /* faulting address is ra - 5 */
783 jmp asm_handle_exception
786 /* asm_patcher_invokespecial ***************************************************
792 16 ra ; return address of patched call in java machine code
793 12 xmcode ; additional machine code (only for i386 and x86_64)
794 8 mcode ; machine code to patch back in
795 4 class ; pointer to class
796 0 sp ; stack pointer of java stack frame + return address
798 *******************************************************************************/
800 asm_patcher_invokestatic_special:
801 mov 4*1(%esp),itmp1 /* pass unresolved_method pointer */
803 call helper_resolve_methodinfo_stubroutine /* call the helper function */
804 add $(4*1),%esp /* remove stack frame */
806 test v0,v0 /* exception thrown? */
807 jz L_asm_patcher_exception
809 mov 16(%esp),itmp2 /* get return address */
810 sub $5,itmp2 /* remove size of `call rel32' */
812 mov 12(%esp),itmp3 /* get xmcode machine code */
813 movb itmp3b,(itmp2) /* patch back in 1 byte */
814 mov 8(%esp),itmp3 /* get mcode machine code */
815 mov itmp3,1(itmp2) /* patch back in 4 bytes */
817 add $(5*4),%esp /* remove stub stack frame incl. ra */
819 mov v0,3+2+1(itmp2) /* patch stubroutine: 3 + 2 + 1 (mov) */
820 jmp *itmp2 /* call new patched code */
823 /********************* function asm_builtin_monitorenter ***********************
825 * Does null check and calls monitorenter or throws an exception *
827 *******************************************************************************/
829 #if defined(USE_THREADS)
830 asm_builtin_monitorenter:
832 je nb_monitorenter /* if (null) throw exception */
833 jmp builtin_monitorenter /* else call builtin_monitorenter */
836 mov string_java_lang_NullPointerException,%eax
839 jmp asm_throw_and_handle_exception
842 push string_java_lang_NullPointerException
846 pop %ecx /* delete return address */
847 sub $2,%ecx /* faulting address is return adress - 2 */
848 jmp asm_handle_exception
853 /********************* function asm_builtin_monitorexit ************************
855 * Does null check and calls monitorexit or throws an exception *
857 *******************************************************************************/
859 #if defined(USE_THREADS)
860 asm_builtin_monitorexit:
863 je nb_monitorexit /* if (null) throw exception */
864 push %ecx /* save registers which could be used */
867 call builtin_monitorexit /* else call builtin_monitorenter */
869 pop %edx /* restore registers which could be used */
874 mov string_java_lang_NullPointerException,%eax
877 jmp asm_throw_and_handle_exception
880 push string_java_lang_NullPointerException
884 pop %ecx /* delete return address */
885 sub $2,%ecx /* faulting address is return adress - 2 */
886 jmp asm_handle_exception
891 /************************ function asm_builtin_ldiv ****************************
893 * Does null check and calls ldiv or throws an exception *
895 *******************************************************************************/
900 test %eax,%eax /* if (null) throw exception */
908 jmp asm_throw_and_handle_hardware_arithmetic_exception
910 push string_java_lang_ArithmeticException_message
911 push string_java_lang_ArithmeticException
912 call new_exception_message
915 pop %ecx /* delete return address */
916 sub $2,%ecx /* faulting address is return adress - 2 */
917 jmp asm_handle_exception
920 /************************ function asm_builtin_lrem ****************************
922 * Does null check and calls lrem or throws an exception *
924 *******************************************************************************/
929 test %eax,%eax /* if (null) throw exception */
937 jmp asm_throw_and_handle_hardware_arithmetic_exception
939 push string_java_lang_ArithmeticException_message
940 push string_java_lang_ArithmeticException
941 call new_exception_message
944 pop %ecx /* delete return address */
945 sub $2,%ecx /* faulting address is return adress - 2 */
946 jmp asm_handle_exception
949 /************************ function asm_builtin_x2x *****************************
951 * Wrapper functions for corner cases *
953 *******************************************************************************/
984 /******************* function asm_builtin_checkarraycast ***********************
986 * Does the cast check and eventually throws an exception *
988 *******************************************************************************/
990 asm_builtin_checkarraycast:
991 sub $8,%esp /* build stack frame (2 * 4 bytes) */
993 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
994 mov %eax,(%esp) /* save object pointer */
999 call builtin_checkarraycast /* builtin_checkarraycast */
1001 test %eax,%eax /* if (false) throw exception */
1004 mov 12(%esp),%eax /* return object pointer */
1010 mov string_java_lang_ClassCastException,%eax
1013 jmp asm_throw_and_handle_exception
1015 push string_java_lang_ClassCastException
1021 pop %ecx /* delete return address */
1022 sub $2,%ecx /* faulting address is return adress - 2 */
1023 jmp asm_handle_exception
1026 /* asm_builtin_newarray ********************************************************
1028 * Does the cast check and eventually throws an exception *
1030 *******************************************************************************/
1032 asm_builtin_newarray:
1033 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1041 call builtin_newarray
1047 /******************* function asm_builtin_aastore ******************************
1049 * Does the cast check and eventually throws an exception *
1051 *******************************************************************************/
1053 asm_builtin_aastore:
1054 sub $12,%esp /* build stack frame (3 * 4 bytes) */
1056 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
1057 test %eax,%eax /* if null pointer throw exception */
1060 mov offarraysize(%eax),%edx /* load size */
1061 mov 24(%esp),%ecx /* index */
1062 cmp %edx,%ecx /* do bound check */
1063 jae nb_aastore_bound /* if out of bounds throw exception */
1065 shl $2,%ecx /* index * 4 */
1066 add %eax,%ecx /* add index * 4 to arrayref */
1068 mov %ecx,8(%esp) /* save store position */
1070 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
1073 mov 32(%esp),%eax /* object is second argument */
1076 call builtin_canstore /* builtin_canstore(arrayref,object) */
1078 test %eax,%eax /* if (false) throw exception */
1083 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
1090 mov string_java_lang_NullPointerException,%eax
1093 jmp asm_throw_and_handle_exception
1096 push string_java_lang_NullPointerException
1101 pop %ecx /* delete return address */
1102 sub $2,%ecx /* faulting address is return adress - 2 */
1103 jmp asm_handle_exception
1107 mov %ecx,%eax /* itmp2 contains array index */
1108 pushl $0 /*directly below return adress*/
1109 pushl $0 /*internal (invisible) method*/
1110 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1113 call new_arrayindexoutofboundsexception
1116 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
1118 pop %ecx /* delete return address */
1119 sub $2,%ecx /* faulting address is return adress - 2 */
1120 jmp asm_handle_exception
1125 mov string_java_lang_ArrayStoreException,%eax
1128 jmp asm_throw_and_handle_exception
1131 push string_java_lang_ArrayStoreException
1136 pop %ecx /* delete return address */
1137 sub $2,%ecx /* faulting address is return adress - 2 */
1138 jmp asm_handle_exception
1141 /******************* function asm_builtin_arrayinstanceof **********************
1143 * Does the instanceof check of arrays *
1145 *******************************************************************************/
1147 asm_builtin_arrayinstanceof:
1148 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1156 call builtin_arrayinstanceof
1162 /******************* function asm_initialize_thread_stack **********************
1164 * initialized a thread stack *
1165 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1167 *******************************************************************************/
1169 asm_initialize_thread_stack:
1170 mov 8(%esp),%eax /* (to)->stackEnd */
1171 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1183 mov 4(%esp),%edx /* save (u1*) (func) */
1186 ret /* return restorepoint in %eax */
1189 /******************* function asm_perform_threadswitch *************************
1191 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1193 * performs a threadswitch *
1195 *******************************************************************************/
1197 asm_perform_threadswitch:
1209 mov 36(%esp),%eax /* save current return address */
1212 mov 40(%esp),%eax /* first argument **from */
1215 mov 48(%esp),%eax /* third argument **stackTop */
1218 mov 44(%esp),%eax /* second argument **to */
1219 mov 0(%eax),%esp /* load new stack pointer */
1225 /* skip stack pointer */
1230 add $32,%esp /* leave return address on stack */
1234 /********************* function asm_switchstackandcall *************************
1236 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1239 * Switches to a new stack, calls a function and switches back. *
1240 * a0 new stack pointer *
1241 * a1 function pointer *
1242 * a2 pointer to variable where stack top should be stored *
1243 * a3 pointer to user data, is passed to the function *
1245 *******************************************************************************/
1247 asm_switchstackandcall:
1248 mov 4(%esp),%edx /* first argument *stack */
1249 sub $8,%edx /* allocate new stack */
1251 mov (%esp),%eax /* save return address on new stack */
1254 mov %esp,4(%edx) /* save old stack pointer on new stack */
1256 mov 12(%esp),%eax /* third argument **stacktopsave */
1257 mov %esp,(%eax) /* save old stack pointer to variable */
1259 mov 8(%esp),%eax /* load function pointer */
1260 mov 16(%esp),%ecx /* fourth argument *p */
1262 mov %edx,%esp /* switch to new stack */
1265 mov %ecx,0(%esp) /* pass pointer */
1266 call *%eax /* and call function */
1269 mov (%esp),%edx /* load return address */
1270 mov 4(%esp),%esp /* switch to old stack */
1275 asm_throw_and_handle_exception:
1277 pushl $0 /* the pushed XPC is directly below the java frame*/
1279 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1283 add $4,%esp /*remove parameter*/
1285 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1288 jmp asm_handle_exception
1289 ret /*should never be reached */
1291 asm_throw_and_handle_hardware_arithmetic_exception:
1294 pushl $0 /* the pushed XPC is directly below the java frame*/
1296 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1298 mov string_java_lang_ArithmeticException_message,%eax
1300 mov string_java_lang_ArithmeticException,%eax
1303 call new_exception_message
1304 add $8,%esp /*remove parameters */
1306 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1309 jmp asm_handle_exception
1310 ret /*should never be reached */
1313 /*optimize a littlebit */
1317 call i386_native_stub_debug
1321 mov offclassinit(%eax),%ecx /* get initialized flag */
1323 jnz L_builtin_new_noinit
1325 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1327 /* 2 *4 bytes, the return adress is used directy */
1328 pushl $0 /* the structure is placed directly below the java stackframe*/
1329 pushl $0 /* builtin (invisible) method */
1330 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1332 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1337 call builtin_asm_get_stackframeinfo
1350 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1359 jmp L_builtin_new_patch
1362 L_builtin_new_noinit:
1367 /*jmp L_builtin_new_patch*/
1369 L_builtin_new_patch:
1370 /*add patching code here */
1371 lea builtin_new,%edx
1373 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1381 asm_getclassvalues_atomic:
1383 mov 4(%esp),%ecx /* super */
1384 mov 8(%esp),%edx /* sub */
1386 mov offbaseval(%ecx),%eax
1387 mov offdiffval(%ecx),%ecx
1388 mov offbaseval(%edx),%edx
1391 mov 16(%esp),%ebx /* out */
1392 mov %eax,offcast_super_baseval(%ebx)
1393 mov %ecx,offcast_super_diffval(%ebx)
1394 mov %edx,offcast_sub_baseval(%ebx)
1400 asm_criticalsections:
1401 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1404 .long _crit_restart1
1407 .long _crit_restart2
1413 /************************ function asm_prepare_native_stackinfo ****************************
1415 * creates a stackfame for the begin of a native function (either builtin or not ) *
1416 * expected stack at begin of function *
1418 * address of the jit call which invokes the native *
1419 * begin address of stack frame of the java method *
1420 * method pointer or 0 (for built ins) *
1423 * at end of function: *
1425 * address of the jit call which invokes the native *
1426 * begin address of stack frame of the java method *
1427 * method pointer or 0 (for built ins) *
1428 * address of thread specific top of native list *
1429 * old value of thread specific head *
1433 * This thing is less efficient than the original #define (callerside) *
1434 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1435 ********************************************************************************************/
1438 asm_prepare_native_stackinfo:
1443 lea builtin_asm_get_stackframeinfo,%ecx
1454 #define PREPARE_NATIVE_STACKINFO \
1455 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1456 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1457 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1458 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1459 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1460 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1461 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1462 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1463 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1464 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1465 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1466 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1470 /************************ function asm_remove _native_stackinfo *******************************************
1472 * creates a stackfame for the begin of a native function (either builtin or not) *
1473 * expected stack at begin of function *
1474 * address of the jit call which invokes the native *
1475 * begin address of stack frame of the java method *
1476 * method pointer or 0 (for built ins) *
1477 * address thread specific top of native list *
1478 * old value of thread specific head *
1481 * at end of function: *
1483 * return adresss of the jit call which invokes the native *
1486 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1489 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1490 ***********************************************************************************************************/
1492 asm_remove_native_stackinfo:
1502 #define REMOVE_NATIVE_STACKINFO \
1503 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1504 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1505 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1506 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1513 * These are local overrides for various environment variables in Emacs.
1514 * Please do not remove this and leave it at the end of the file, where
1515 * Emacs will automagically detect them.
1516 * ---------------------------------------------------------------------
1519 * indent-tabs-mode: t