1 /* 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 1801 2004-12-21 20:19:19Z jowenn $
39 #include "vm/jit/i386/offsets.h"
40 #include "vm/jit/i386/asmoffsets.h"
54 /********************* exported functions and variables ***********************/
56 .globl asm_calljavafunction
57 .globl calljava_xhandler
58 .globl asm_calljavafunction2
59 .globl asm_calljavafunction2long
60 .globl asm_calljavafunction2double
61 .globl calljava_xhandler2
63 .globl asm_call_jit_compiler
64 .globl asm_handle_builtin_exception
65 .globl asm_handle_nat_exception
66 .globl asm_handle_exception
67 .globl asm_check_clinit
68 .globl asm_builtin_checkcast
69 .globl asm_builtin_checkarraycast
70 .globl asm_builtin_newarray
71 .globl asm_builtin_anewarray
72 .globl asm_builtin_newarray_array
73 .globl asm_builtin_aastore
74 .globl asm_builtin_monitorenter
75 .globl asm_builtin_monitorexit
76 .globl asm_builtin_ldiv
77 .globl asm_builtin_lrem
78 .globl asm_builtin_f2i
79 .globl asm_builtin_f2l
80 .globl asm_builtin_d2i
81 .globl asm_builtin_d2l
82 .globl asm_builtin_arrayinstanceof
83 .globl asm_perform_threadswitch
84 .globl asm_initialize_thread_stack
85 .globl asm_switchstackandcall
86 .globl asm_getcallingmethod
87 .globl asm_builtin_new
88 .globl asm_criticalsections
89 .globl asm_getclassvalues_atomic
90 .globl asm_prepare_native_stackinfo
91 .globl asm_remove_native_stackinfo
92 /*************************** imported functions *******************************/
95 .globl builtin_monitorexit
96 .globl builtin_throw_exception
97 .globl builtin_trace_exception
98 .globl class_java_lang_Object
99 .globl codegen_findmethod
100 .globl callgetexceptionptrptr
101 .globl asm_throw_and_handle_exception
102 .globl asm_throw_and_handle_hardware_arithmetic_exception
105 /********************* function asm_calljavafunction ***************************
107 * This function calls a Java-method (which possibly needs compilation) *
108 * with up to 4 address parameters. *
110 * This functions calls the JIT-compiler which eventually translates the *
111 * method into machine code. *
114 * javaobject_header *asm_calljavamethod (methodinfo *m, *
115 * void *arg1, void *arg2, void *arg3, void *arg4); *
117 *******************************************************************************/
120 .ascii "calljavafunction\0\0"
123 .long 0 /* catch type all */
124 .long calljava_xhandler /* handler pc */
125 .long calljava_xhandler /* end pc */
126 .long asm_calljavafunction /* start pc */
127 .long 1 /* extable size */
128 .long 0 /* line number table start */
129 .long 0 /* line number table size */
130 .long 0 /* fltsave */
131 .long 0 /* intsave */
134 .long 32 /* frame size */
135 .long 0 /* method pointer (pointer to name) */
137 asm_calljavafunction:
138 push %ebp /* allocate stack space */
141 push %ebx /* save registers */
145 sub $32,%esp /* pass the remaining parameters */
148 mov %edx,28(%esp) /* convert parms to 8 byte */
164 mov 8(%ebp),%eax /* move function pointer to %eax */
166 lea asm_call_jit_compiler,%edx
167 call *%edx /* call JIT compiler */
170 pop %edi /* restore registers */
177 push %eax /* pass exception pointer */
178 call builtin_throw_exception
182 pop %edi /* restore registers */
189 /********************* function asm_calljavafunction ***************************
191 * This function calls a Java-method (which possibly needs compilation) *
192 * with up to 4 address parameters. *
194 * This functions calls the JIT-compiler which eventually translates the *
195 * method into machine code. *
198 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
199 * u4 count, u4 size, void *callblock); *
201 *******************************************************************************/
204 .ascii "calljavafunction2\0\0"
207 .long 0 /* catch type all */
208 .long calljava_xhandler2 /* handler pc */
209 .long calljava_xhandler2 /* end pc */
210 .long asm_calljavafunction2 /* start pc */
211 .long 1 /* extable size */
212 .long 0 /* line number table start */
213 .long 0 /* line number table size */
214 .long 0 /* fltsave */
215 .long 0 /* intsave */
218 .long 32 /* frame size */
219 .long 0 /* method pointer (pointer to name) */
221 asm_calljavafunction2:
222 asm_calljavafunction2double:
223 asm_calljavafunction2long:
225 mov %esp,%ebp /* save stackptr */
227 push %ebx /* save registers */
231 mov 20(%ebp),%eax /* pointer to arg block */
232 mov 12(%ebp),%ecx /* arg count */
233 test %ecx,%ecx /* maybe we have no args */
234 jle calljava_copydone
236 mov %ecx,%edx /* calculate stack size */
238 mov %edx,%esi /* save in callee saved register */
239 sub %esi,%esp /* stack frame for arguments */
243 mov offjniitem(%eax),%edx
245 mov offjniitem+4(%eax),%edx
248 sub $1,%ecx /* are there any args left? */
250 jle calljava_copydone
252 add $sizejniblock,%eax /* goto next argument block */
253 add $8,%edi /* increase sp to next argument */
254 jmp calljava_copyloop
257 mov 8(%ebp),%eax /* move function pointer to %eax */
259 lea asm_call_jit_compiler,%edx
260 call *%edx /* call JIT compiler */
263 add %esi,%esp /* remove arg stack frame */
264 pop %edi /* restore registers */
271 push %eax /* pass exception pointer */
272 call builtin_throw_exception
275 add %esi,%esp /* remove arg stack frame */
276 pop %edi /* restore registers */
283 /****************** function asm_call_jit_compiler *****************************
285 * invokes the compiler for untranslated JavaVM methods. *
287 * Register R0 contains a pointer to the method info structure (prepared *
288 * by createcompilerstub). Using the return address in R26 and the *
289 * offset in the LDA instruction or using the value in methodptr R28 the *
290 * patching address for storing the method address can be computed: *
292 * method address was either loaded using *
294 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
295 * i386_call_reg(REG_ITMP2) *
299 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
300 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
301 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
302 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
303 * i386_call_reg(REG_ITMP1) *
305 * in the static case the method pointer can be computed using the *
306 * return address and the lda function following the jmp instruction *
308 *******************************************************************************/
310 asm_call_jit_compiler:
311 push %ebx /* save register */
314 mov 8(%esp),%ebp /* get return address (2 push) */
315 mov -1(%ebp),%bl /* get function code */
316 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
317 jne L_not_static_special
319 sub $6,%ebp /* calculate address of immediate */
320 jmp L_call_jit_compile
322 L_not_static_special:
323 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
324 jne L_not_virtual_interface
326 sub $6,%ebp /* calculate address of offset */
327 mov (%ebp),%ebp /* get offset */
328 add itmp2,%ebp /* add base address to get method address */
329 jmp L_call_jit_compile
331 L_not_virtual_interface: /* a call from asm_calljavafunction */
335 push %ebp /* save address for method pointer */
337 push %eax /* push methodpointer on stack */
341 pop %ebp /* restore address for method pointer */
343 test %eax,%eax /* check for exception */
346 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
349 mov %eax,(%ebp) /* and now save the new pointer */
352 pop %ebp /* restore registers */
355 jmp *%eax /* ...and now call the new method */
358 pop %ebp /* restore registers */
361 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
362 call builtin_asm_get_exceptionptrptr
364 mov (%ecx),%eax /* get the exception pointer */
365 movl $0,(%ecx) /* clear the exception pointer */
367 lea _exceptionptr,%ecx
368 mov (%ecx),%eax /* get the exception pointer */
369 movl $0,(%ecx) /* clear the exception pointer */
372 pop %ecx /* delete return address */
373 sub $2,%ecx /* faulting address is return adress - 2 */
375 L_refillinStacktrace: /*a compilation error should cause a stacktrace
376 which starts at the method call, which caused
377 the compilation of the new function. Until this
378 point the trace is invalid anyways, since it is
379 not complete. Compared to other runtimes it will
380 not be correct either, since we report eg class
381 not found errors too early, since we always
382 compile methods completely. The native info
383 should be moved around the jit call to get
384 a more compliant trace for the "exception in
386 push %ecx /* store fault adress */
387 push %eax /* temporarily save exception pointer*/
388 push $0 /* internal function */
389 call builtin_asm_get_stackframeinfo
390 push %eax /* save location of thread specific stack info head pointer */
391 mov (%eax),%ecx /* save old value of pointer*/
393 mov %esp,(%eax) /*store pointer to this structure*/
394 mov 12(%esp),%eax /* get the exception pointer again*/
395 movl $0,12(%esp) /*java stack begins just above structure*/
396 push $0 /*used for the jni_callblock structure*/
397 push %eax /*save eax for later */
398 /* get fillInStackTrace method*/
399 push utf_fillInStackTrace_desc
400 push utf_fillInStackTrace_name
401 mov offobjvftbl(%eax),%ecx
402 mov offclass(%ecx),%eax
404 call class_resolvemethod
412 call asm_calljavafunction2
415 /*remove native stack info */
424 jmp asm_handle_exception
427 /********************* function asm_handle_exception ***************************
429 * This function handles an exception. It does not use the usual calling *
430 * conventions. The exception pointer is passed in REG_ITMP1 and the *
431 * pc from the exception raising position is passed in REG_ITMP2. It searches *
432 * the local exception table for a handler. If no one is found, it unwinds *
433 * stacks and continues searching the callers. *
435 * void asm_handle_exception (exceptionptr, exceptionpc); *
437 *******************************************************************************/
439 asm_handle_nat_exception:
440 add $4,%esp /* clear return address of native stub */
442 asm_handle_exception:
443 asm_handle_exception_loop:
447 push %eax /* save exception pointer */
448 push %ecx /* save exception pc */
450 call codegen_findmethod /* get the data segment ptr */
454 mov -8(%ebp),%ecx /* could be changed in findmethod */
456 push %edx /* save data segment pointer */
463 mov %eax,(%esp) /* exception pointer */
464 mov MethodPointer(%edx),%eax /* method pointer */
466 mov %ecx,8(%esp) /* exception pc */
467 movl $0,12(%esp) /* line number */
468 movl $1,16(%esp) /* set no unwind flag */
469 call builtin_trace_exception
471 mov -12(%ebp),%esi /* %esi = data segment pointer */
472 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
473 test %ecx,%ecx /* if empty table skip */
476 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
477 mov -4(%ebp),%eax /* get xptr */
480 mov -8(%ebp),%edx /* get xpc */
482 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
483 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
484 jg ex_table_cont /* if (false) continue */
485 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
486 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
487 jge ex_table_cont /* if (false) continue */
488 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
489 test %ebx,%ebx /* NULL catches everything */
492 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
496 mov %eax,1*4(%esp) /* save not callee saved regs */
499 mov %ebx,0*4(%esp) /* exception class is argument */
508 cmpl $0,offclasslinked(%ebx)
512 mov %eax,1*4(%esp) /* save not callee saved regs */
515 mov %ebx,0*4(%esp) /* exception class is argument */
524 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
532 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
533 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
534 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
535 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
536 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
538 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
540 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
544 cmp %ebx,%esi /* xptr is instanceof catchtype */
548 mov ExHandlerPC(%edi),%edx
550 pop %edi /* restore registers */
553 add $8,%esp /* suck %ecx, %edx */
554 pop %eax /* restore xptr */
557 jmp *%edx /* jump to exception handler */
560 lea ExEntrySize(%edi),%edi
569 pop %edx /* restore data segment pointer */
574 push %eax /* save exception pointer */
577 mov IsSync(%edx),%eax /* %eax = SyncOffset */
578 test %eax,%eax /* if zero no monitorexit */
582 mov -4(%eax),%eax /* we have the xptr on the stack */
583 push %edx /* save regs */
585 call builtin_monitorexit
587 pop %edx /* restore regs */
591 add FrameSize(%edx),%eax /* %eax = frame size */
592 add $4,%eax /* we have the xptr on the stack */
594 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
616 shl $3,%ecx /* multiply by 8 bytes */
620 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
647 pop %eax /* restore exception pointer */
649 mov FrameSize(%edx),%ecx /* %ecx = frame size */
650 add %ecx,%esp /* unwind stack */
652 pop %ecx /* the new xpc is return address */
655 jmp asm_handle_exception_loop
658 /* asm_check_clinit ************************************************************
664 16 ra ; return address of patched call in java machine code
665 12 xmcode ; additional machine code (only for i386 and x86_64)
666 8 mcode ; machine code to patch back in
667 4 class ; pointer to class
668 0 sp ; stack pointer of java stack frame + return address
670 *******************************************************************************/
673 mov 4(%esp),%eax /* get fieldinfo's class pointer */
674 mov offclassinit(%eax),%eax /* get initialized flag */
680 push itmp1 /*return adress into java machine code */
682 push itmp1 /*begin of java stack frame*/
683 pushl $0 /*internal (invisible) method*/
684 call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
685 data onto the stack */
688 mov 20+4+4(%esp),itmp1 /* get class pointer */
689 mov itmp1,(%esp) /* store class pointer as a0 */
690 call class_init /* call class_init function */
693 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
694 into java machine code on stack */
695 add $4,%esp /* ret address no longer needed, is still
696 on stack a few bytes above */
698 test %eax,%eax /* we had an exception */
699 je L_initializererror
702 mov 16(%esp),itmp1 /* get return address */
703 sub $5,itmp1 /* remove size of `call rel32' */
705 mov 12(%esp),itmp2 /* get xmcode machine code */
706 movb itmp2b,(itmp1) /* patch back in 1 byte */
707 mov 8(%esp),itmp2 /* get mcode machine code */
708 mov itmp2,1(itmp1) /* patch back in 4 bytes */
710 add $(5*4),%esp /* remove stub stack frame incl. ra */
712 jmp *itmp1 /* jump to patched code an execute it */
715 add $(4*4),%esp /* remove stub stack frame */
717 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
718 call builtin_asm_get_exceptionptrptr
720 mov (%ecx),%eax /* get the exception pointer */
721 movl $0,(%ecx) /* clear the exception pointer */
723 lea _exceptionptr,%ecx
724 mov (%ecx),%eax /* get the exception pointer */
725 movl $0,(%ecx) /* clear the exception pointer */
728 pop itmp2 /* get and delete ra */
729 sub $5,itmp2 /* faulting address is ra - 5 */
731 jmp asm_handle_exception
734 /********************* function asm_builtin_monitorenter ***********************
736 * Does null check and calls monitorenter or throws an exception *
738 *******************************************************************************/
740 asm_builtin_monitorenter:
742 je nb_monitorenter /* if (null) throw exception */
743 jmp builtin_monitorenter /* else call builtin_monitorenter */
746 mov string_java_lang_NullPointerException,%eax
749 jmp asm_throw_and_handle_exception
752 push string_java_lang_NullPointerException
756 pop %ecx /* delete return address */
757 sub $2,%ecx /* faulting address is return adress - 2 */
758 jmp asm_handle_exception
761 /********************* function asm_builtin_monitorexit ************************
763 * Does null check and calls monitorexit or throws an exception *
765 *******************************************************************************/
767 asm_builtin_monitorexit:
770 je nb_monitorexit /* if (null) throw exception */
771 push %ecx /* save registers which could be used */
774 call builtin_monitorexit /* else call builtin_monitorenter */
776 pop %edx /* restore registers which could be used */
781 mov string_java_lang_NullPointerException,%eax
784 jmp asm_throw_and_handle_exception
787 push string_java_lang_NullPointerException
791 pop %ecx /* delete return address */
792 sub $2,%ecx /* faulting address is return adress - 2 */
793 jmp asm_handle_exception
796 /************************ function asm_builtin_ldiv ****************************
798 * Does null check and calls ldiv or throws an exception *
800 *******************************************************************************/
805 test %eax,%eax /* if (null) throw exception */
813 jmp asm_throw_and_handle_hardware_arithmetic_exception
815 push string_java_lang_ArithmeticException_message
816 push string_java_lang_ArithmeticException
817 call new_exception_message
820 pop %ecx /* delete return address */
821 sub $2,%ecx /* faulting address is return adress - 2 */
822 jmp asm_handle_exception
825 /************************ function asm_builtin_lrem ****************************
827 * Does null check and calls lrem or throws an exception *
829 *******************************************************************************/
834 test %eax,%eax /* if (null) throw exception */
842 jmp asm_throw_and_handle_hardware_arithmetic_exception
844 push string_java_lang_ArithmeticException_message
845 push string_java_lang_ArithmeticException
846 call new_exception_message
849 pop %ecx /* delete return address */
850 sub $2,%ecx /* faulting address is return adress - 2 */
851 jmp asm_handle_exception
854 /************************ function asm_builtin_x2x *****************************
856 * Wrapper functions for corner cases *
858 *******************************************************************************/
889 /******************* function asm_builtin_checkarraycast ***********************
891 * Does the cast check and eventually throws an exception *
893 *******************************************************************************/
895 asm_builtin_checkarraycast:
896 sub $8,%esp /* build stack frame (2 * 4 bytes) */
898 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
899 mov %eax,(%esp) /* save object pointer */
904 call builtin_checkarraycast /* builtin_checkarraycast */
906 test %eax,%eax /* if (false) throw exception */
909 mov 12(%esp),%eax /* return object pointer */
915 mov string_java_lang_ClassCastException,%eax
918 jmp asm_throw_and_handle_exception
920 push string_java_lang_ClassCastException
926 pop %ecx /* delete return address */
927 sub $2,%ecx /* faulting address is return adress - 2 */
928 jmp asm_handle_exception
931 /******************* function asm_builtin_newarray *****************************
933 * Does the cast check and eventually throws an exception *
935 *******************************************************************************/
937 asm_builtin_newarray:
938 sub $8,%esp /* build stack frame (2 * 4 bytes) */
946 call builtin_newarray
952 /******************* function asm_builtin_aastore ******************************
954 * Does the cast check and eventually throws an exception *
956 *******************************************************************************/
959 sub $12,%esp /* build stack frame (3 * 4 bytes) */
961 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
962 test %eax,%eax /* if null pointer throw exception */
965 mov offarraysize(%eax),%edx /* load size */
966 mov 24(%esp),%ecx /* index */
967 cmp %edx,%ecx /* do bound check */
968 jae nb_aastore_bound /* if out of bounds throw exception */
970 shl $2,%ecx /* index * 4 */
971 add %eax,%ecx /* add index * 4 to arrayref */
973 mov %ecx,8(%esp) /* save store position */
975 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
978 mov 32(%esp),%eax /* object is second argument */
981 call builtin_canstore /* builtin_canstore(arrayref,object) */
983 test %eax,%eax /* if (false) throw exception */
988 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
995 mov string_java_lang_NullPointerException,%eax
998 jmp asm_throw_and_handle_exception
1001 push string_java_lang_NullPointerException
1006 pop %ecx /* delete return address */
1007 sub $2,%ecx /* faulting address is return adress - 2 */
1008 jmp asm_handle_exception
1012 mov %ecx,%eax /* itmp2 contains array index */
1013 pushl $0 /*directly below return adress*/
1014 pushl $0 /*internal (invisible) method*/
1015 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1018 call new_arrayindexoutofboundsexception
1021 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
1023 pop %ecx /* delete return address */
1024 sub $2,%ecx /* faulting address is return adress - 2 */
1025 jmp asm_handle_exception
1030 mov string_java_lang_ArrayStoreException,%eax
1033 jmp asm_throw_and_handle_exception
1036 push string_java_lang_ArrayStoreException
1041 pop %ecx /* delete return address */
1042 sub $2,%ecx /* faulting address is return adress - 2 */
1043 jmp asm_handle_exception
1046 /******************* function asm_builtin_arrayinstanceof **********************
1048 * Does the instanceof check of arrays *
1050 *******************************************************************************/
1052 asm_builtin_arrayinstanceof:
1053 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1061 call builtin_arrayinstanceof
1067 /******************* function asm_initialize_thread_stack **********************
1069 * initialized a thread stack *
1070 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1072 *******************************************************************************/
1074 asm_initialize_thread_stack:
1075 mov 8(%esp),%eax /* (to)->stackEnd */
1076 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1088 mov 4(%esp),%edx /* save (u1*) (func) */
1091 ret /* return restorepoint in %eax */
1094 /******************* function asm_perform_threadswitch *************************
1096 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1098 * performs a threadswitch *
1100 *******************************************************************************/
1102 asm_perform_threadswitch:
1114 mov 36(%esp),%eax /* save current return address */
1117 mov 40(%esp),%eax /* first argument **from */
1120 mov 48(%esp),%eax /* third argument **stackTop */
1123 mov 44(%esp),%eax /* second argument **to */
1124 mov 0(%eax),%esp /* load new stack pointer */
1130 /* skip stack pointer */
1135 add $32,%esp /* leave return address on stack */
1139 /********************* function asm_switchstackandcall *************************
1141 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1144 * Switches to a new stack, calls a function and switches back. *
1145 * a0 new stack pointer *
1146 * a1 function pointer *
1147 * a2 pointer to variable where stack top should be stored *
1148 * a3 pointer to user data, is passed to the function *
1150 *******************************************************************************/
1152 asm_switchstackandcall:
1153 mov 4(%esp),%edx /* first argument *stack */
1154 sub $8,%edx /* allocate new stack */
1156 mov (%esp),%eax /* save return address on new stack */
1159 mov %esp,4(%edx) /* save old stack pointer on new stack */
1161 mov 12(%esp),%eax /* third argument **stacktopsave */
1162 mov %esp,(%eax) /* save old stack pointer to variable */
1164 mov 8(%esp),%eax /* load function pointer */
1165 mov 16(%esp),%ecx /* fourth argument *p */
1167 mov %edx,%esp /* switch to new stack */
1170 mov %ecx,0(%esp) /* pass pointer */
1171 call *%eax /* and call function */
1174 mov (%esp),%edx /* load return address */
1175 mov 4(%esp),%esp /* switch to old stack */
1180 asm_throw_and_handle_exception:
1182 pushl $0 /* the pushed XPC is directly below the java frame*/
1184 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1188 add $4,%esp /*remove parameter*/
1190 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1193 jmp asm_handle_exception
1194 ret /*should never be reached */
1196 asm_throw_and_handle_hardware_arithmetic_exception:
1199 pushl $0 /* the pushed XPC is directly below the java frame*/
1201 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1203 mov string_java_lang_ArithmeticException_message,%eax
1205 mov string_java_lang_ArithmeticException,%eax
1208 call new_exception_message
1209 add $8,%esp /*remove parameters */
1211 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1214 jmp asm_handle_exception
1215 ret /*should never be reached */
1218 /*optimize a littlebit */
1222 call i386_native_stub_debug
1226 mov offclassinit(%eax),%ecx /* get initialized flag */
1228 jnz L_builtin_new_noinit
1230 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1232 /* 2 *4 bytes, the return adress is used directy */
1233 pushl $0 /* the structure is placed directly below the java stackframe*/
1234 pushl $0 /* builtin (invisible) method */
1235 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1237 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1242 call builtin_asm_get_stackframeinfo
1255 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1264 jmp L_builtin_new_patch
1267 L_builtin_new_noinit:
1272 /*jmp L_builtin_new_patch*/
1274 L_builtin_new_patch:
1275 /*add patching code here */
1276 lea builtin_new,%edx
1278 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1286 asm_getclassvalues_atomic:
1288 mov 4(%esp),%ecx /* super */
1289 mov 8(%esp),%edx /* sub */
1291 mov offbaseval(%ecx),%eax
1292 mov offdiffval(%ecx),%ecx
1293 mov offbaseval(%edx),%edx
1296 mov 16(%esp),%ebx /* out */
1297 mov %eax,offcast_super_baseval(%ebx)
1298 mov %ecx,offcast_super_diffval(%ebx)
1299 mov %edx,offcast_sub_baseval(%ebx)
1305 asm_criticalsections:
1306 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1309 .long _crit_restart1
1312 .long _crit_restart2
1318 /************************ function asm_prepare_native_stackinfo ****************************
1320 * creates a stackfame for the begin of a native function (either builtin or not ) *
1321 * 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) *
1328 * at end of function: *
1330 * address of the jit call which invokes the native *
1331 * begin address of stack frame of the java method *
1332 * method pointer or 0 (for built ins) *
1333 * address of thread specific top of native list *
1334 * old value of thread specific head *
1338 * This thing is less efficient than the original #define (callerside) *
1339 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1340 ********************************************************************************************/
1343 asm_prepare_native_stackinfo:
1348 lea builtin_asm_get_stackframeinfo,%ecx
1359 #define PREPARE_NATIVE_STACKINFO \
1360 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1361 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1362 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1363 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1364 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1365 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1366 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1367 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1368 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1369 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1370 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1371 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1375 /************************ function asm_remove _native_stackinfo *******************************************
1377 * creates a stackfame for the begin of a native function (either builtin or not) *
1378 * expected stack at begin of function *
1379 * address of the jit call which invokes the native *
1380 * begin address of stack frame of the java method *
1381 * method pointer or 0 (for built ins) *
1382 * address thread specific top of native list *
1383 * old value of thread specific head *
1386 * at end of function: *
1388 * return adresss of the jit call which invokes the native *
1391 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1394 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1395 ***********************************************************************************************************/
1397 asm_remove_native_stackinfo:
1407 #define REMOVE_NATIVE_STACKINFO \
1408 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1409 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1410 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1411 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1418 * These are local overrides for various environment variables in Emacs.
1419 * Please do not remove this and leave it at the end of the file, where
1420 * Emacs will automagically detect them.
1421 * ---------------------------------------------------------------------
1424 * indent-tabs-mode: t