1 /* vm/jit/i386/asmpart.S - Java-C interface functions for i386
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
32 $Id: asmpart.S 1680 2004-12-04 12:02:08Z jowenn $
38 #include "vm/jit/i386/offsets.h"
39 #include "vm/jit/i386/asmoffsets.h"
53 /********************* exported functions and variables ***********************/
55 .globl asm_calljavafunction
56 .globl calljava_xhandler
57 .globl asm_calljavafunction2
58 .globl asm_calljavafunction2long
59 .globl asm_calljavafunction2double
60 .globl calljava_xhandler2
62 .globl asm_call_jit_compiler
63 .globl asm_handle_builtin_exception
64 .globl asm_handle_nat_exception
65 .globl asm_handle_exception
66 .globl asm_check_clinit
67 .globl asm_builtin_checkcast
68 .globl asm_builtin_checkarraycast
69 .globl asm_builtin_newarray
70 .globl asm_builtin_anewarray
71 .globl asm_builtin_newarray_array
72 .globl asm_builtin_aastore
73 .globl asm_builtin_monitorenter
74 .globl asm_builtin_monitorexit
75 .globl asm_builtin_ldiv
76 .globl asm_builtin_lrem
77 .globl asm_builtin_f2i
78 .globl asm_builtin_f2l
79 .globl asm_builtin_d2i
80 .globl asm_builtin_d2l
81 .globl asm_builtin_arrayinstanceof
82 .globl asm_perform_threadswitch
83 .globl asm_initialize_thread_stack
84 .globl asm_switchstackandcall
85 .globl asm_getcallingmethod
86 .globl asm_builtin_new
87 .globl asm_criticalsections
88 .globl asm_getclassvalues_atomic
89 .globl asm_prepare_native_stackinfo
90 .globl asm_remove_native_stackinfo
91 /*************************** imported functions *******************************/
94 .globl builtin_monitorexit
95 .globl builtin_throw_exception
96 .globl builtin_trace_exception
97 .globl class_java_lang_Object
98 .globl codegen_findmethod
99 .globl callgetexceptionptrptr
100 .globl asm_throw_and_handle_exception
101 .globl asm_throw_and_handle_hardware_arithmetic_exception
104 /********************* function asm_calljavafunction ***************************
106 * This function calls a Java-method (which possibly needs compilation) *
107 * with up to 4 address parameters. *
109 * This functions calls the JIT-compiler which eventually translates the *
110 * method into machine code. *
113 * javaobject_header *asm_calljavamethod (methodinfo *m, *
114 * void *arg1, void *arg2, void *arg3, void *arg4); *
116 *******************************************************************************/
119 .ascii "calljavafunction\0\0"
122 .long 0 /* catch type all */
123 .long calljava_xhandler /* handler pc */
124 .long calljava_xhandler /* end pc */
125 .long asm_calljavafunction /* start pc */
126 .long 1 /* extable size */
127 .long 0 /* line number table start */
128 .long 0 /* line number table size */
129 .long 0 /* fltsave */
130 .long 0 /* intsave */
133 .long 32 /* frame size */
134 .long 0 /* method pointer (pointer to name) */
136 asm_calljavafunction:
137 push %ebp /* allocate stack space */
140 push %ebx /* save registers */
144 sub $32,%esp /* pass the remaining parameters */
147 mov %edx,28(%esp) /* convert parms to 8 byte */
163 mov 8(%ebp),%eax /* move function pointer to %eax */
165 lea asm_call_jit_compiler,%edx
166 call *%edx /* call JIT compiler */
169 pop %edi /* restore registers */
176 push %eax /* pass exception pointer */
177 call builtin_throw_exception
181 pop %edi /* restore registers */
188 /********************* function asm_calljavafunction ***************************
190 * This function calls a Java-method (which possibly needs compilation) *
191 * with up to 4 address parameters. *
193 * This functions calls the JIT-compiler which eventually translates the *
194 * method into machine code. *
197 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
198 * u4 count, u4 size, void *callblock); *
200 *******************************************************************************/
203 .ascii "calljavafunction2\0\0"
206 .long 0 /* catch type all */
207 .long calljava_xhandler2 /* handler pc */
208 .long calljava_xhandler2 /* end pc */
209 .long asm_calljavafunction2 /* start pc */
210 .long 1 /* extable size */
211 .long 0 /* line number table start */
212 .long 0 /* line number table size */
213 .long 0 /* fltsave */
214 .long 0 /* intsave */
217 .long 32 /* frame size */
218 .long 0 /* method pointer (pointer to name) */
220 asm_calljavafunction2:
221 asm_calljavafunction2double:
222 asm_calljavafunction2long:
224 mov %esp,%ebp /* save stackptr */
226 push %ebx /* save registers */
230 mov 20(%ebp),%eax /* pointer to arg block */
231 mov 12(%ebp),%ecx /* arg count */
232 test %ecx,%ecx /* maybe we have no args */
233 jle calljava_copydone
235 mov %ecx,%edx /* calculate stack size */
237 mov %edx,%esi /* save in callee saved register */
238 sub %esi,%esp /* stack frame for arguments */
242 mov offjniitem(%eax),%edx
244 mov offjniitem+4(%eax),%edx
247 sub $1,%ecx /* are there any args left? */
249 jle calljava_copydone
251 add $sizejniblock,%eax /* goto next argument block */
252 add $8,%edi /* increase sp to next argument */
253 jmp calljava_copyloop
256 mov 8(%ebp),%eax /* move function pointer to %eax */
258 lea asm_call_jit_compiler,%edx
259 call *%edx /* call JIT compiler */
262 add %esi,%esp /* remove arg stack frame */
263 pop %edi /* restore registers */
270 push %eax /* pass exception pointer */
271 call builtin_throw_exception
274 add %esi,%esp /* remove arg stack frame */
275 pop %edi /* restore registers */
282 /****************** function asm_call_jit_compiler *****************************
284 * invokes the compiler for untranslated JavaVM methods. *
286 * Register R0 contains a pointer to the method info structure (prepared *
287 * by createcompilerstub). Using the return address in R26 and the *
288 * offset in the LDA instruction or using the value in methodptr R28 the *
289 * patching address for storing the method address can be computed: *
291 * method address was either loaded using *
293 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
294 * i386_call_reg(REG_ITMP2) *
298 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
299 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
300 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
301 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
302 * i386_call_reg(REG_ITMP1) *
304 * in the static case the method pointer can be computed using the *
305 * return address and the lda function following the jmp instruction *
307 *******************************************************************************/
309 asm_call_jit_compiler:
310 push %ebx /* save register */
313 mov 8(%esp),%ebp /* get return address (2 push) */
314 mov -1(%ebp),%bl /* get function code */
315 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
316 jne L_not_static_special
318 sub $6,%ebp /* calculate address of immediate */
319 jmp L_call_jit_compile
321 L_not_static_special:
322 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
323 jne L_not_virtual_interface
325 sub $6,%ebp /* calculate address of offset */
326 mov (%ebp),%ebp /* get offset */
327 add itmp2,%ebp /* add base address to get method address */
328 jmp L_call_jit_compile
330 L_not_virtual_interface: /* a call from asm_calljavafunction */
334 push %ebp /* save address for method pointer */
336 push %eax /* push methodpointer on stack */
340 pop %ebp /* restore address for method pointer */
342 test %eax,%eax /* check for exception */
345 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
348 mov %eax,(%ebp) /* and now save the new pointer */
351 pop %ebp /* restore registers */
354 jmp *%eax /* ...and now call the new method */
357 pop %ebp /* restore registers */
360 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
361 call builtin_asm_get_exceptionptrptr
363 mov (%ecx),%eax /* get the exception pointer */
364 movl $0,(%ecx) /* clear the exception pointer */
366 lea _exceptionptr,%ecx
367 mov (%ecx),%eax /* get the exception pointer */
368 movl $0,(%ecx) /* clear the exception pointer */
371 pop %ecx /* delete return address */
372 sub $2,%ecx /* faulting address is return adress - 2 */
374 L_refillinStacktrace: /*a compilation error should cause a stacktrace
375 which starts at the method call, which caused
376 the compilation of the new function. Until this
377 point the trace is invalid anyways, since it is
378 not complete. Compared to other runtimes it will
379 not be correct either, since we report eg class
380 not found errors too early, since we always
381 compile methods completely*/
382 push %ecx /* store fault adress */
383 push %eax /* temporarily save exception pointer*/
384 call builtin_asm_get_stackframeinfo
385 push %eax /* save location of thread specific stack info head pointer */
386 mov (%eax),%ecx /* save old value of pointer*/
388 mov %esp,(%eax) /*store pointer to this structure*/
389 mov 8(%esp),%eax /* get the exception pointer again*/
390 movl $0,8(%esp) /*mark this block as native*/
391 push $0 /*used for the jni_callblock structure*/
392 push %eax /*save eax for later */
393 /* get fillInStackTrace method*/
394 push utf_fillInStackTrace_desc
395 push utf_fillInStackTrace_name
396 mov offobjvftbl(%eax),%ecx
397 mov offclass(%ecx),%eax
399 call class_resolvemethod
407 call asm_calljavafunction2
410 /*remove native stack info */
419 jmp asm_handle_exception
422 /********************* function asm_handle_exception ***************************
424 * This function handles an exception. It does not use the usual calling *
425 * conventions. The exception pointer is passed in REG_ITMP1 and the *
426 * pc from the exception raising position is passed in REG_ITMP2. It searches *
427 * the local exception table for a handler. If no one is found, it unwinds *
428 * stacks and continues searching the callers. *
430 * void asm_handle_exception (exceptionptr, exceptionpc); *
432 *******************************************************************************/
434 asm_handle_nat_exception:
435 add $4,%esp /* clear return address of native stub */
437 asm_handle_exception:
438 asm_handle_exception_loop:
442 push %eax /* save exception pointer */
443 push %ecx /* save exception pc */
445 call codegen_findmethod /* get the data segment ptr */
449 mov -8(%ebp),%ecx /* could be changed in findmethod */
451 push %edx /* save data segment pointer */
458 mov %eax,(%esp) /* exception pointer */
459 mov MethodPointer(%edx),%eax /* method pointer */
461 mov %ecx,8(%esp) /* exception pc */
462 movl $0,12(%esp) /* line number */
463 movl $1,16(%esp) /* set no unwind flag */
464 call builtin_trace_exception
466 mov -12(%ebp),%esi /* %esi = data segment pointer */
467 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
468 test %ecx,%ecx /* if empty table skip */
471 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
472 mov -4(%ebp),%eax /* get xptr */
475 mov -8(%ebp),%edx /* get xpc */
477 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
478 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
479 jg ex_table_cont /* if (false) continue */
480 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
481 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
482 jge ex_table_cont /* if (false) continue */
483 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
484 test %ebx,%ebx /* NULL catches everything */
487 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
491 mov %eax,1*4(%esp) /* save not callee saved regs */
494 mov %ebx,0*4(%esp) /* exception class is argument */
503 cmpl $0,offclasslinked(%ebx)
507 mov %eax,1*4(%esp) /* save not callee saved regs */
510 mov %ebx,0*4(%esp) /* exception class is argument */
519 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
527 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
528 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
529 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
530 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
531 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
533 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
535 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
539 cmp %ebx,%esi /* xptr is instanceof catchtype */
543 mov ExHandlerPC(%edi),%edx
545 pop %edi /* restore registers */
548 add $8,%esp /* suck %ecx, %edx */
549 pop %eax /* restore xptr */
552 jmp *%edx /* jump to exception handler */
555 lea ExEntrySize(%edi),%edi
564 pop %edx /* restore data segment pointer */
569 push %eax /* save exception pointer */
572 mov IsSync(%edx),%eax /* %eax = SyncOffset */
573 test %eax,%eax /* if zero no monitorexit */
577 mov -4(%eax),%eax /* we have the xptr on the stack */
578 push %edx /* save regs */
580 call builtin_monitorexit
582 pop %edx /* restore regs */
586 add FrameSize(%edx),%eax /* %eax = frame size */
587 add $4,%eax /* we have the xptr on the stack */
589 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
611 shl $3,%ecx /* multiply by 8 bytes */
615 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
642 pop %eax /* restore exception pointer */
644 mov FrameSize(%edx),%ecx /* %ecx = frame size */
645 add %ecx,%esp /* unwind stack */
647 pop %ecx /* the new xpc is return address */
650 jmp asm_handle_exception_loop
653 /* asm_check_clinit ************************************************************
659 16 ra ; return address of patched call in java machine code
660 12 xmcode ; additional machine code (only for i386 and x86_64)
661 8 mcode ; machine code to patch back in
662 4 class ; pointer to class
663 0 sp ; stack pointer of java stack frame + return address
665 *******************************************************************************/
668 mov 4(%esp),%eax /* get fieldinfo's class pointer */
669 mov offclassinit(%eax),%eax /* get initialized flag */
675 push itmp1 /*return adress into java machine code */
677 push itmp1 /*begin of java stack frame*/
678 pushl $0 /*internal (invisible) method*/
679 call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
680 data onto the stack */
683 mov 20+4+4(%esp),itmp1 /* get class pointer */
684 mov itmp1,(%esp) /* store class pointer as a0 */
685 call class_init /* call class_init function */
688 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
689 into java machine code on stack */
690 add $4,%esp /* ret address no longer needed, is still
691 on stack a few bytes above */
693 test %eax,%eax /* we had an exception */
694 je L_initializererror
697 mov 16(%esp),itmp1 /* get return address */
698 sub $5,itmp1 /* remove size of `call rel32' */
700 mov 12(%esp),itmp2 /* get xmcode machine code */
701 movb itmp2b,(itmp1) /* patch back in 1 byte */
702 mov 8(%esp),itmp2 /* get mcode machine code */
703 mov itmp2,1(itmp1) /* patch back in 4 bytes */
705 add $(5*4),%esp /* remove stub stack frame incl. ra */
707 jmp *itmp1 /* jump to patched code an execute it */
710 add $(4*4),%esp /* remove stub stack frame */
712 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
713 call builtin_asm_get_exceptionptrptr
715 mov (%ecx),%eax /* get the exception pointer */
716 movl $0,(%ecx) /* clear the exception pointer */
718 lea _exceptionptr,%ecx
719 mov (%ecx),%eax /* get the exception pointer */
720 movl $0,(%ecx) /* clear the exception pointer */
723 pop itmp2 /* get and delete ra */
724 sub $5,itmp2 /* faulting address is ra - 5 */
726 jmp asm_handle_exception
729 /********************* function asm_builtin_monitorenter ***********************
731 * Does null check and calls monitorenter or throws an exception *
733 *******************************************************************************/
735 asm_builtin_monitorenter:
737 je nb_monitorenter /* if (null) throw exception */
738 jmp builtin_monitorenter /* else call builtin_monitorenter */
741 mov string_java_lang_NullPointerException,%eax
744 jmp asm_throw_and_handle_exception
747 push string_java_lang_NullPointerException
751 pop %ecx /* delete return address */
752 sub $2,%ecx /* faulting address is return adress - 2 */
753 jmp asm_handle_exception
756 /********************* function asm_builtin_monitorexit ************************
758 * Does null check and calls monitorexit or throws an exception *
760 *******************************************************************************/
762 asm_builtin_monitorexit:
765 je nb_monitorexit /* if (null) throw exception */
766 push %ecx /* save registers which could be used */
769 call builtin_monitorexit /* else call builtin_monitorenter */
771 pop %edx /* restore registers which could be used */
776 mov string_java_lang_NullPointerException,%eax
779 jmp asm_throw_and_handle_exception
782 push string_java_lang_NullPointerException
786 pop %ecx /* delete return address */
787 sub $2,%ecx /* faulting address is return adress - 2 */
788 jmp asm_handle_exception
791 /************************ function asm_builtin_ldiv ****************************
793 * Does null check and calls ldiv or throws an exception *
795 *******************************************************************************/
800 test %eax,%eax /* if (null) throw exception */
808 jmp asm_throw_and_handle_hardware_arithmetic_exception
810 push string_java_lang_ArithmeticException_message
811 push string_java_lang_ArithmeticException
812 call new_exception_message
815 pop %ecx /* delete return address */
816 sub $2,%ecx /* faulting address is return adress - 2 */
817 jmp asm_handle_exception
820 /************************ function asm_builtin_lrem ****************************
822 * Does null check and calls lrem or throws an exception *
824 *******************************************************************************/
829 test %eax,%eax /* if (null) throw exception */
837 jmp asm_throw_and_handle_hardware_arithmetic_exception
839 push string_java_lang_ArithmeticException_message
840 push string_java_lang_ArithmeticException
841 call new_exception_message
844 pop %ecx /* delete return address */
845 sub $2,%ecx /* faulting address is return adress - 2 */
846 jmp asm_handle_exception
849 /************************ function asm_builtin_x2x *****************************
851 * Wrapper functions for corner cases *
853 *******************************************************************************/
884 /******************* function asm_builtin_checkarraycast ***********************
886 * Does the cast check and eventually throws an exception *
888 *******************************************************************************/
890 asm_builtin_checkarraycast:
891 sub $8,%esp /* build stack frame (2 * 4 bytes) */
893 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
894 mov %eax,(%esp) /* save object pointer */
899 call builtin_checkarraycast /* builtin_checkarraycast */
901 test %eax,%eax /* if (false) throw exception */
904 mov 12(%esp),%eax /* return object pointer */
910 mov string_java_lang_ClassCastException,%eax
913 jmp asm_throw_and_handle_exception
915 push string_java_lang_ClassCastException
921 pop %ecx /* delete return address */
922 sub $2,%ecx /* faulting address is return adress - 2 */
923 jmp asm_handle_exception
926 /******************* function asm_builtin_newarray *****************************
928 * Does the cast check and eventually throws an exception *
930 *******************************************************************************/
932 asm_builtin_newarray:
933 sub $8,%esp /* build stack frame (2 * 4 bytes) */
941 call builtin_newarray
947 /******************* function asm_builtin_aastore ******************************
949 * Does the cast check and eventually throws an exception *
951 *******************************************************************************/
954 sub $12,%esp /* build stack frame (3 * 4 bytes) */
956 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
957 test %eax,%eax /* if null pointer throw exception */
960 mov offarraysize(%eax),%edx /* load size */
961 mov 24(%esp),%ecx /* index */
962 cmp %edx,%ecx /* do bound check */
963 jae nb_aastore_bound /* if out of bounds throw exception */
965 shl $2,%ecx /* index * 4 */
966 add %eax,%ecx /* add index * 4 to arrayref */
968 mov %ecx,8(%esp) /* save store position */
970 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
973 mov 32(%esp),%eax /* object is second argument */
976 call builtin_canstore /* builtin_canstore(arrayref,object) */
978 test %eax,%eax /* if (false) throw exception */
983 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
990 mov string_java_lang_NullPointerException,%eax
993 jmp asm_throw_and_handle_exception
996 push string_java_lang_NullPointerException
1001 pop %ecx /* delete return address */
1002 sub $2,%ecx /* faulting address is return adress - 2 */
1003 jmp asm_handle_exception
1007 mov %ecx,%eax /* itmp2 contains array index */
1008 pushl $0 /*directly below return adress*/
1009 pushl $0 /*internal (invisible) method*/
1010 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1013 call new_arrayindexoutofboundsexception
1016 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
1018 pop %ecx /* delete return address */
1019 sub $2,%ecx /* faulting address is return adress - 2 */
1020 jmp asm_handle_exception
1025 mov string_java_lang_ArrayStoreException,%eax
1028 jmp asm_throw_and_handle_exception
1031 push string_java_lang_ArrayStoreException
1036 pop %ecx /* delete return address */
1037 sub $2,%ecx /* faulting address is return adress - 2 */
1038 jmp asm_handle_exception
1041 /******************* function asm_builtin_arrayinstanceof **********************
1043 * Does the instanceof check of arrays *
1045 *******************************************************************************/
1047 asm_builtin_arrayinstanceof:
1048 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1056 call builtin_arrayinstanceof
1062 /******************* function asm_initialize_thread_stack **********************
1064 * initialized a thread stack *
1065 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1067 *******************************************************************************/
1069 asm_initialize_thread_stack:
1070 mov 8(%esp),%eax /* (to)->stackEnd */
1071 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1083 mov 4(%esp),%edx /* save (u1*) (func) */
1086 ret /* return restorepoint in %eax */
1089 /******************* function asm_perform_threadswitch *************************
1091 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1093 * performs a threadswitch *
1095 *******************************************************************************/
1097 asm_perform_threadswitch:
1109 mov 36(%esp),%eax /* save current return address */
1112 mov 40(%esp),%eax /* first argument **from */
1115 mov 48(%esp),%eax /* third argument **stackTop */
1118 mov 44(%esp),%eax /* second argument **to */
1119 mov 0(%eax),%esp /* load new stack pointer */
1125 /* skip stack pointer */
1130 add $32,%esp /* leave return address on stack */
1134 /********************* function asm_switchstackandcall *************************
1136 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1139 * Switches to a new stack, calls a function and switches back. *
1140 * a0 new stack pointer *
1141 * a1 function pointer *
1142 * a2 pointer to variable where stack top should be stored *
1143 * a3 pointer to user data, is passed to the function *
1145 *******************************************************************************/
1147 asm_switchstackandcall:
1148 mov 4(%esp),%edx /* first argument *stack */
1149 sub $8,%edx /* allocate new stack */
1151 mov (%esp),%eax /* save return address on new stack */
1154 mov %esp,4(%edx) /* save old stack pointer on new stack */
1156 mov 12(%esp),%eax /* third argument **stacktopsave */
1157 mov %esp,(%eax) /* save old stack pointer to variable */
1159 mov 8(%esp),%eax /* load function pointer */
1160 mov 16(%esp),%ecx /* fourth argument *p */
1162 mov %edx,%esp /* switch to new stack */
1165 mov %ecx,0(%esp) /* pass pointer */
1166 call *%eax /* and call function */
1169 mov (%esp),%edx /* load return address */
1170 mov 4(%esp),%esp /* switch to old stack */
1175 asm_throw_and_handle_exception:
1177 pushl $0 /* the pushed XPC is directly below the java frame*/
1179 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1183 add $4,%esp /*remove parameter*/
1185 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1188 jmp asm_handle_exception
1189 ret /*should never be reached */
1191 asm_throw_and_handle_hardware_arithmetic_exception:
1194 pushl $0 /* the pushed XPC is directly below the java frame*/
1196 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1198 mov string_java_lang_ArithmeticException_message,%eax
1200 mov string_java_lang_ArithmeticException,%eax
1203 call new_exception_message
1204 add $8,%esp /*remove parameters */
1206 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1209 jmp asm_handle_exception
1210 ret /*should never be reached */
1213 /*optimize a littlebit */
1217 call i386_native_stub_debug
1221 mov offclassinit(%eax),%ecx /* get initialized flag */
1223 jnz L_builtin_new_noinit
1225 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1227 /* 2 *4 bytes, the return adress is used directy */
1228 pushl $0 /* the structure is placed directly below the java stackframe*/
1229 pushl $0 /* builtin (invisible) method */
1230 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1232 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1237 call builtin_asm_get_stackframeinfo
1250 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1259 jmp L_builtin_new_patch
1262 L_builtin_new_noinit:
1267 /*jmp L_builtin_new_patch*/
1269 L_builtin_new_patch:
1270 /*add patching code here */
1271 lea builtin_new,%edx
1273 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1281 asm_getclassvalues_atomic:
1283 mov 4(%esp),%ecx /* super */
1284 mov 8(%esp),%edx /* sub */
1286 mov offbaseval(%ecx),%eax
1287 mov offdiffval(%ecx),%ecx
1288 mov offbaseval(%edx),%edx
1291 mov 16(%esp),%ebx /* out */
1292 mov %eax,offcast_super_baseval(%ebx)
1293 mov %ecx,offcast_super_diffval(%ebx)
1294 mov %edx,offcast_sub_baseval(%ebx)
1300 asm_criticalsections:
1301 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1304 .long _crit_restart1
1307 .long _crit_restart2
1313 /************************ function asm_prepare_native_stackinfo ****************************
1315 * creates a stackfame for the begin of a native function (either builtin or not ) *
1316 * expected stack at begin of function *
1318 * address of the jit call which invokes the native *
1319 * begin address of stack frame of the java method *
1320 * method pointer or 0 (for built ins) *
1323 * at end of function: *
1325 * address of the jit call which invokes the native *
1326 * begin address of stack frame of the java method *
1327 * method pointer or 0 (for built ins) *
1328 * address of thread specific top of native list *
1329 * old value of thread specific head *
1333 * This thing is less efficient than the original #define (callerside) *
1334 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1335 ********************************************************************************************/
1338 asm_prepare_native_stackinfo:
1343 lea builtin_asm_get_stackframeinfo,%ecx
1354 #define PREPARE_NATIVE_STACKINFO \
1355 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1356 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1357 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1358 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1359 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1360 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1361 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1362 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1363 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1364 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1365 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1366 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1370 /************************ function asm_remove _native_stackinfo *******************************************
1372 * creates a stackfame for the begin of a native function (either builtin or not) *
1373 * expected stack at begin of function *
1374 * address of the jit call which invokes the native *
1375 * begin address of stack frame of the java method *
1376 * method pointer or 0 (for built ins) *
1377 * address thread specific top of native list *
1378 * old value of thread specific head *
1381 * at end of function: *
1383 * return adresss of the jit call which invokes the native *
1386 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1389 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1390 ***********************************************************************************************************/
1392 asm_remove_native_stackinfo:
1402 #define REMOVE_NATIVE_STACKINFO \
1403 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1404 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1405 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1406 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1413 * These are local overrides for various environment variables in Emacs.
1414 * Please do not remove this and leave it at the end of the file, where
1415 * Emacs will automagically detect them.
1416 * ---------------------------------------------------------------------
1419 * indent-tabs-mode: t