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 1830 2004-12-29 13:47:15Z twisti $
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
75 #if defined(USE_THREADS)
76 .globl asm_builtin_monitorenter
77 .globl asm_builtin_monitorexit
80 .globl asm_builtin_ldiv
81 .globl asm_builtin_lrem
82 .globl asm_builtin_f2i
83 .globl asm_builtin_f2l
84 .globl asm_builtin_d2i
85 .globl asm_builtin_d2l
86 .globl asm_builtin_arrayinstanceof
87 .globl asm_perform_threadswitch
88 .globl asm_initialize_thread_stack
89 .globl asm_switchstackandcall
90 .globl asm_getcallingmethod
91 .globl asm_builtin_new
92 .globl asm_criticalsections
93 .globl asm_getclassvalues_atomic
95 .globl asm_throw_and_handle_exception
96 .globl asm_throw_and_handle_hardware_arithmetic_exception
98 .globl asm_prepare_native_stackinfo
99 .globl asm_remove_native_stackinfo
102 /********************* function asm_calljavafunction ***************************
104 * This function calls a Java-method (which possibly needs compilation) *
105 * with up to 4 address parameters. *
107 * This functions calls the JIT-compiler which eventually translates the *
108 * method into machine code. *
111 * javaobject_header *asm_calljavamethod (methodinfo *m, *
112 * void *arg1, void *arg2, void *arg3, void *arg4); *
114 *******************************************************************************/
117 .ascii "calljavafunction\0\0"
120 .long 0 /* catch type all */
121 .long calljava_xhandler /* handler pc */
122 .long calljava_xhandler /* end pc */
123 .long asm_calljavafunction /* start pc */
124 .long 1 /* extable size */
125 .long 0 /* line number table start */
126 .long 0 /* line number table size */
127 .long 0 /* fltsave */
128 .long 0 /* intsave */
131 .long 32 /* frame size */
132 .long 0 /* method pointer (pointer to name) */
134 asm_calljavafunction:
135 push %ebp /* allocate stack space */
138 push %ebx /* save registers */
142 sub $32,%esp /* pass the remaining parameters */
145 mov %edx,28(%esp) /* convert parms to 8 byte */
161 mov 8(%ebp),%eax /* move function pointer to %eax */
163 lea asm_call_jit_compiler,%edx
164 call *%edx /* call JIT compiler */
167 pop %edi /* restore registers */
174 push %eax /* pass exception pointer */
175 call builtin_throw_exception
179 pop %edi /* restore registers */
186 /********************* function asm_calljavafunction ***************************
188 * This function calls a Java-method (which possibly needs compilation) *
189 * with up to 4 address parameters. *
191 * This functions calls the JIT-compiler which eventually translates the *
192 * method into machine code. *
195 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
196 * u4 count, u4 size, void *callblock); *
198 *******************************************************************************/
201 .ascii "calljavafunction2\0\0"
204 .long 0 /* catch type all */
205 .long calljava_xhandler2 /* handler pc */
206 .long calljava_xhandler2 /* end pc */
207 .long asm_calljavafunction2 /* start pc */
208 .long 1 /* extable size */
209 .long 0 /* line number table start */
210 .long 0 /* line number table size */
211 .long 0 /* fltsave */
212 .long 0 /* intsave */
215 .long 32 /* frame size */
216 .long 0 /* method pointer (pointer to name) */
218 asm_calljavafunction2:
219 asm_calljavafunction2double:
220 asm_calljavafunction2long:
222 mov %esp,%ebp /* save stackptr */
224 push %ebx /* save registers */
228 mov 20(%ebp),%eax /* pointer to arg block */
229 mov 12(%ebp),%ecx /* arg count */
230 test %ecx,%ecx /* maybe we have no args */
231 jle calljava_copydone
233 mov %ecx,%edx /* calculate stack size */
235 mov %edx,%esi /* save in callee saved register */
236 sub %esi,%esp /* stack frame for arguments */
240 mov offjniitem(%eax),%edx
242 mov offjniitem+4(%eax),%edx
245 sub $1,%ecx /* are there any args left? */
247 jle calljava_copydone
249 add $sizejniblock,%eax /* goto next argument block */
250 add $8,%edi /* increase sp to next argument */
251 jmp calljava_copyloop
254 mov 8(%ebp),%eax /* move function pointer to %eax */
256 lea asm_call_jit_compiler,%edx
257 call *%edx /* call JIT compiler */
260 add %esi,%esp /* remove arg stack frame */
261 pop %edi /* restore registers */
268 push %eax /* pass exception pointer */
269 call builtin_throw_exception
272 add %esi,%esp /* remove arg stack frame */
273 pop %edi /* restore registers */
280 /****************** function asm_call_jit_compiler *****************************
282 * invokes the compiler for untranslated JavaVM methods. *
284 * Register R0 contains a pointer to the method info structure (prepared *
285 * by createcompilerstub). Using the return address in R26 and the *
286 * offset in the LDA instruction or using the value in methodptr R28 the *
287 * patching address for storing the method address can be computed: *
289 * method address was either loaded using *
291 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
292 * i386_call_reg(REG_ITMP2) *
296 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
297 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
298 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
299 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
300 * i386_call_reg(REG_ITMP1) *
302 * in the static case the method pointer can be computed using the *
303 * return address and the lda function following the jmp instruction *
305 *******************************************************************************/
307 asm_call_jit_compiler:
308 push %ebx /* save register */
311 mov 8(%esp),%ebp /* get return address (2 push) */
312 mov -1(%ebp),%bl /* get function code */
313 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
314 jne L_not_static_special
316 sub $6,%ebp /* calculate address of immediate */
317 jmp L_call_jit_compile
319 L_not_static_special:
320 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
321 jne L_not_virtual_interface
323 sub $6,%ebp /* calculate address of offset */
324 mov (%ebp),%ebp /* get offset */
325 add itmp2,%ebp /* add base address to get method address */
326 jmp L_call_jit_compile
328 L_not_virtual_interface: /* a call from asm_calljavafunction */
332 push %ebp /* save address for method pointer */
334 push %eax /* push methodpointer on stack */
338 pop %ebp /* restore address for method pointer */
340 test %eax,%eax /* check for exception */
343 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
346 mov %eax,(%ebp) /* and now save the new pointer */
349 pop %ebp /* restore registers */
352 jmp *%eax /* ...and now call the new method */
355 pop %ebp /* restore registers */
358 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
359 call builtin_asm_get_exceptionptrptr
361 mov (%ecx),%eax /* get the exception pointer */
362 movl $0,(%ecx) /* clear the exception pointer */
364 lea _exceptionptr,%ecx
365 mov (%ecx),%eax /* get the exception pointer */
366 movl $0,(%ecx) /* clear the exception pointer */
369 pop %ecx /* delete return address */
370 sub $2,%ecx /* faulting address is return adress - 2 */
372 L_refillinStacktrace: /*a compilation error should cause a stacktrace
373 which starts at the method call, which caused
374 the compilation of the new function. Until this
375 point the trace is invalid anyways, since it is
376 not complete. Compared to other runtimes it will
377 not be correct either, since we report eg class
378 not found errors too early, since we always
379 compile methods completely. The native info
380 should be moved around the jit call to get
381 a more compliant trace for the "exception in
383 push %ecx /* store fault adress */
384 push %eax /* temporarily save exception pointer*/
385 push $0 /* internal function */
386 call builtin_asm_get_stackframeinfo
387 push %eax /* save location of thread specific stack info head pointer */
388 mov (%eax),%ecx /* save old value of pointer*/
390 mov %esp,(%eax) /*store pointer to this structure*/
391 mov 12(%esp),%eax /* get the exception pointer again*/
392 movl $0,12(%esp) /*java stack begins just above structure*/
393 push $0 /*used for the jni_callblock structure*/
394 push %eax /*save eax for later */
395 /* get fillInStackTrace method*/
396 push utf_fillInStackTrace_desc
397 push utf_fillInStackTrace_name
398 mov offobjvftbl(%eax),%ecx
399 mov offclass(%ecx),%eax
401 call class_resolvemethod
409 call asm_calljavafunction2
412 /*remove native stack info */
421 jmp asm_handle_exception
424 /********************* function asm_handle_exception ***************************
426 * This function handles an exception. It does not use the usual calling *
427 * conventions. The exception pointer is passed in REG_ITMP1 and the *
428 * pc from the exception raising position is passed in REG_ITMP2. It searches *
429 * the local exception table for a handler. If no one is found, it unwinds *
430 * stacks and continues searching the callers. *
432 * void asm_handle_exception (exceptionptr, exceptionpc); *
434 *******************************************************************************/
436 asm_handle_nat_exception:
437 add $4,%esp /* clear return address of native stub */
439 asm_handle_exception:
440 asm_handle_exception_loop:
444 push %eax /* save exception pointer */
445 push %ecx /* save exception pc */
447 call codegen_findmethod /* get the data segment ptr */
451 mov -8(%ebp),%ecx /* could be changed in findmethod */
453 push %edx /* save data segment pointer */
460 mov %eax,(%esp) /* exception pointer */
461 mov MethodPointer(%edx),%eax /* method pointer */
463 mov %ecx,8(%esp) /* exception pc */
464 movl $0,12(%esp) /* line number */
465 movl $1,16(%esp) /* set no unwind flag */
466 call builtin_trace_exception
468 mov -12(%ebp),%esi /* %esi = data segment pointer */
469 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
470 test %ecx,%ecx /* if empty table skip */
473 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
474 mov -4(%ebp),%eax /* get xptr */
477 mov -8(%ebp),%edx /* get xpc */
479 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
480 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
481 jg ex_table_cont /* if (false) continue */
482 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
483 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
484 jge ex_table_cont /* if (false) continue */
485 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
486 test %ebx,%ebx /* NULL catches everything */
489 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
493 mov %eax,1*4(%esp) /* save not callee saved regs */
496 mov %ebx,0*4(%esp) /* exception class is argument */
505 cmpl $0,offclasslinked(%ebx)
509 mov %eax,1*4(%esp) /* save not callee saved regs */
512 mov %ebx,0*4(%esp) /* exception class is argument */
521 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
529 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
530 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
531 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
532 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
533 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
535 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
537 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
541 cmp %ebx,%esi /* xptr is instanceof catchtype */
545 mov ExHandlerPC(%edi),%edx
547 pop %edi /* restore registers */
550 add $8,%esp /* suck %ecx, %edx */
551 pop %eax /* restore xptr */
554 jmp *%edx /* jump to exception handler */
557 lea ExEntrySize(%edi),%edi
566 pop %edx /* restore data segment pointer */
571 push %eax /* save exception pointer */
574 mov IsSync(%edx),%eax /* %eax = SyncOffset */
575 test %eax,%eax /* if zero no monitorexit */
578 #if defined(USE_THREADS)
580 mov -4(%eax),%eax /* we have the xptr on the stack */
581 push %edx /* save regs */
583 call builtin_monitorexit
585 pop %edx /* restore regs */
590 add FrameSize(%edx),%eax /* %eax = frame size */
591 add $4,%eax /* we have the xptr on the stack */
593 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
615 shl $3,%ecx /* multiply by 8 bytes */
619 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
646 pop %eax /* restore exception pointer */
648 mov FrameSize(%edx),%ecx /* %ecx = frame size */
649 add %ecx,%esp /* unwind stack */
651 pop %ecx /* the new xpc is return address */
654 jmp asm_handle_exception_loop
657 /* asm_check_clinit ************************************************************
663 16 ra ; return address of patched call in java machine code
664 12 xmcode ; additional machine code (only for i386 and x86_64)
665 8 mcode ; machine code to patch back in
666 4 class ; pointer to class
667 0 sp ; stack pointer of java stack frame + return address
669 *******************************************************************************/
672 mov 4(%esp),%eax /* get fieldinfo's class pointer */
673 mov offclassinit(%eax),%eax /* get initialized flag */
679 push itmp1 /*return adress into java machine code */
681 push itmp1 /*begin of java stack frame*/
682 pushl $0 /*internal (invisible) method*/
683 call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
684 data onto the stack */
687 mov 20+4+4(%esp),itmp1 /* get class pointer */
688 mov itmp1,(%esp) /* store class pointer as a0 */
689 call class_init /* call class_init function */
692 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
693 into java machine code on stack */
694 add $4,%esp /* ret address no longer needed, is still
695 on stack a few bytes above */
697 test %eax,%eax /* we had an exception */
698 je L_initializererror
701 mov 16(%esp),itmp1 /* get return address */
702 sub $5,itmp1 /* remove size of `call rel32' */
704 mov 12(%esp),itmp2 /* get xmcode machine code */
705 movb itmp2b,(itmp1) /* patch back in 1 byte */
706 mov 8(%esp),itmp2 /* get mcode machine code */
707 mov itmp2,1(itmp1) /* patch back in 4 bytes */
709 add $(5*4),%esp /* remove stub stack frame incl. ra */
711 jmp *itmp1 /* jump to patched code an execute it */
714 add $(4*4),%esp /* remove stub stack frame */
716 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
717 call builtin_asm_get_exceptionptrptr
719 mov (%ecx),%eax /* get the exception pointer */
720 movl $0,(%ecx) /* clear the exception pointer */
722 lea _exceptionptr,%ecx
723 mov (%ecx),%eax /* get the exception pointer */
724 movl $0,(%ecx) /* clear the exception pointer */
727 pop itmp2 /* get and delete ra */
728 sub $5,itmp2 /* faulting address is ra - 5 */
730 jmp asm_handle_exception
733 /********************* function asm_builtin_monitorenter ***********************
735 * Does null check and calls monitorenter or throws an exception *
737 *******************************************************************************/
739 #if defined(USE_THREADS)
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
763 /********************* function asm_builtin_monitorexit ************************
765 * Does null check and calls monitorexit or throws an exception *
767 *******************************************************************************/
769 #if defined(USE_THREADS)
770 asm_builtin_monitorexit:
773 je nb_monitorexit /* if (null) throw exception */
774 push %ecx /* save registers which could be used */
777 call builtin_monitorexit /* else call builtin_monitorenter */
779 pop %edx /* restore registers which could be used */
784 mov string_java_lang_NullPointerException,%eax
787 jmp asm_throw_and_handle_exception
790 push string_java_lang_NullPointerException
794 pop %ecx /* delete return address */
795 sub $2,%ecx /* faulting address is return adress - 2 */
796 jmp asm_handle_exception
801 /************************ function asm_builtin_ldiv ****************************
803 * Does null check and calls ldiv or throws an exception *
805 *******************************************************************************/
810 test %eax,%eax /* if (null) throw exception */
818 jmp asm_throw_and_handle_hardware_arithmetic_exception
820 push string_java_lang_ArithmeticException_message
821 push string_java_lang_ArithmeticException
822 call new_exception_message
825 pop %ecx /* delete return address */
826 sub $2,%ecx /* faulting address is return adress - 2 */
827 jmp asm_handle_exception
830 /************************ function asm_builtin_lrem ****************************
832 * Does null check and calls lrem or throws an exception *
834 *******************************************************************************/
839 test %eax,%eax /* if (null) throw exception */
847 jmp asm_throw_and_handle_hardware_arithmetic_exception
849 push string_java_lang_ArithmeticException_message
850 push string_java_lang_ArithmeticException
851 call new_exception_message
854 pop %ecx /* delete return address */
855 sub $2,%ecx /* faulting address is return adress - 2 */
856 jmp asm_handle_exception
859 /************************ function asm_builtin_x2x *****************************
861 * Wrapper functions for corner cases *
863 *******************************************************************************/
894 /******************* function asm_builtin_checkarraycast ***********************
896 * Does the cast check and eventually throws an exception *
898 *******************************************************************************/
900 asm_builtin_checkarraycast:
901 sub $8,%esp /* build stack frame (2 * 4 bytes) */
903 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
904 mov %eax,(%esp) /* save object pointer */
909 call builtin_checkarraycast /* builtin_checkarraycast */
911 test %eax,%eax /* if (false) throw exception */
914 mov 12(%esp),%eax /* return object pointer */
920 mov string_java_lang_ClassCastException,%eax
923 jmp asm_throw_and_handle_exception
925 push string_java_lang_ClassCastException
931 pop %ecx /* delete return address */
932 sub $2,%ecx /* faulting address is return adress - 2 */
933 jmp asm_handle_exception
936 /******************* function asm_builtin_newarray *****************************
938 * Does the cast check and eventually throws an exception *
940 *******************************************************************************/
942 asm_builtin_newarray:
943 sub $8,%esp /* build stack frame (2 * 4 bytes) */
951 call builtin_newarray
957 /******************* function asm_builtin_aastore ******************************
959 * Does the cast check and eventually throws an exception *
961 *******************************************************************************/
964 sub $12,%esp /* build stack frame (3 * 4 bytes) */
966 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
967 test %eax,%eax /* if null pointer throw exception */
970 mov offarraysize(%eax),%edx /* load size */
971 mov 24(%esp),%ecx /* index */
972 cmp %edx,%ecx /* do bound check */
973 jae nb_aastore_bound /* if out of bounds throw exception */
975 shl $2,%ecx /* index * 4 */
976 add %eax,%ecx /* add index * 4 to arrayref */
978 mov %ecx,8(%esp) /* save store position */
980 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
983 mov 32(%esp),%eax /* object is second argument */
986 call builtin_canstore /* builtin_canstore(arrayref,object) */
988 test %eax,%eax /* if (false) throw exception */
993 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
1000 mov string_java_lang_NullPointerException,%eax
1003 jmp asm_throw_and_handle_exception
1006 push string_java_lang_NullPointerException
1011 pop %ecx /* delete return address */
1012 sub $2,%ecx /* faulting address is return adress - 2 */
1013 jmp asm_handle_exception
1017 mov %ecx,%eax /* itmp2 contains array index */
1018 pushl $0 /*directly below return adress*/
1019 pushl $0 /*internal (invisible) method*/
1020 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1023 call new_arrayindexoutofboundsexception
1026 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
1028 pop %ecx /* delete return address */
1029 sub $2,%ecx /* faulting address is return adress - 2 */
1030 jmp asm_handle_exception
1035 mov string_java_lang_ArrayStoreException,%eax
1038 jmp asm_throw_and_handle_exception
1041 push string_java_lang_ArrayStoreException
1046 pop %ecx /* delete return address */
1047 sub $2,%ecx /* faulting address is return adress - 2 */
1048 jmp asm_handle_exception
1051 /******************* function asm_builtin_arrayinstanceof **********************
1053 * Does the instanceof check of arrays *
1055 *******************************************************************************/
1057 asm_builtin_arrayinstanceof:
1058 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1066 call builtin_arrayinstanceof
1072 /******************* function asm_initialize_thread_stack **********************
1074 * initialized a thread stack *
1075 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1077 *******************************************************************************/
1079 asm_initialize_thread_stack:
1080 mov 8(%esp),%eax /* (to)->stackEnd */
1081 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1093 mov 4(%esp),%edx /* save (u1*) (func) */
1096 ret /* return restorepoint in %eax */
1099 /******************* function asm_perform_threadswitch *************************
1101 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1103 * performs a threadswitch *
1105 *******************************************************************************/
1107 asm_perform_threadswitch:
1119 mov 36(%esp),%eax /* save current return address */
1122 mov 40(%esp),%eax /* first argument **from */
1125 mov 48(%esp),%eax /* third argument **stackTop */
1128 mov 44(%esp),%eax /* second argument **to */
1129 mov 0(%eax),%esp /* load new stack pointer */
1135 /* skip stack pointer */
1140 add $32,%esp /* leave return address on stack */
1144 /********************* function asm_switchstackandcall *************************
1146 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1149 * Switches to a new stack, calls a function and switches back. *
1150 * a0 new stack pointer *
1151 * a1 function pointer *
1152 * a2 pointer to variable where stack top should be stored *
1153 * a3 pointer to user data, is passed to the function *
1155 *******************************************************************************/
1157 asm_switchstackandcall:
1158 mov 4(%esp),%edx /* first argument *stack */
1159 sub $8,%edx /* allocate new stack */
1161 mov (%esp),%eax /* save return address on new stack */
1164 mov %esp,4(%edx) /* save old stack pointer on new stack */
1166 mov 12(%esp),%eax /* third argument **stacktopsave */
1167 mov %esp,(%eax) /* save old stack pointer to variable */
1169 mov 8(%esp),%eax /* load function pointer */
1170 mov 16(%esp),%ecx /* fourth argument *p */
1172 mov %edx,%esp /* switch to new stack */
1175 mov %ecx,0(%esp) /* pass pointer */
1176 call *%eax /* and call function */
1179 mov (%esp),%edx /* load return address */
1180 mov 4(%esp),%esp /* switch to old stack */
1185 asm_throw_and_handle_exception:
1187 pushl $0 /* the pushed XPC is directly below the java frame*/
1189 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1193 add $4,%esp /*remove parameter*/
1195 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1198 jmp asm_handle_exception
1199 ret /*should never be reached */
1201 asm_throw_and_handle_hardware_arithmetic_exception:
1204 pushl $0 /* the pushed XPC is directly below the java frame*/
1206 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1208 mov string_java_lang_ArithmeticException_message,%eax
1210 mov string_java_lang_ArithmeticException,%eax
1213 call new_exception_message
1214 add $8,%esp /*remove parameters */
1216 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1219 jmp asm_handle_exception
1220 ret /*should never be reached */
1223 /*optimize a littlebit */
1227 call i386_native_stub_debug
1231 mov offclassinit(%eax),%ecx /* get initialized flag */
1233 jnz L_builtin_new_noinit
1235 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1237 /* 2 *4 bytes, the return adress is used directy */
1238 pushl $0 /* the structure is placed directly below the java stackframe*/
1239 pushl $0 /* builtin (invisible) method */
1240 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1242 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1247 call builtin_asm_get_stackframeinfo
1260 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1269 jmp L_builtin_new_patch
1272 L_builtin_new_noinit:
1277 /*jmp L_builtin_new_patch*/
1279 L_builtin_new_patch:
1280 /*add patching code here */
1281 lea builtin_new,%edx
1283 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1291 asm_getclassvalues_atomic:
1293 mov 4(%esp),%ecx /* super */
1294 mov 8(%esp),%edx /* sub */
1296 mov offbaseval(%ecx),%eax
1297 mov offdiffval(%ecx),%ecx
1298 mov offbaseval(%edx),%edx
1301 mov 16(%esp),%ebx /* out */
1302 mov %eax,offcast_super_baseval(%ebx)
1303 mov %ecx,offcast_super_diffval(%ebx)
1304 mov %edx,offcast_sub_baseval(%ebx)
1310 asm_criticalsections:
1311 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1314 .long _crit_restart1
1317 .long _crit_restart2
1323 /************************ function asm_prepare_native_stackinfo ****************************
1325 * creates a stackfame for the begin of a native function (either builtin or not ) *
1326 * expected stack at begin of function *
1328 * address of the jit call which invokes the native *
1329 * begin address of stack frame of the java method *
1330 * method pointer or 0 (for built ins) *
1333 * at end of function: *
1335 * address of the jit call which invokes the native *
1336 * begin address of stack frame of the java method *
1337 * method pointer or 0 (for built ins) *
1338 * address of thread specific top of native list *
1339 * old value of thread specific head *
1343 * This thing is less efficient than the original #define (callerside) *
1344 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1345 ********************************************************************************************/
1348 asm_prepare_native_stackinfo:
1353 lea builtin_asm_get_stackframeinfo,%ecx
1364 #define PREPARE_NATIVE_STACKINFO \
1365 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1366 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1367 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1368 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1369 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1370 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1371 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1372 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1373 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1374 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1375 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1376 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1380 /************************ function asm_remove _native_stackinfo *******************************************
1382 * creates a stackfame for the begin of a native function (either builtin or not) *
1383 * expected stack at begin of function *
1384 * address of the jit call which invokes the native *
1385 * begin address of stack frame of the java method *
1386 * method pointer or 0 (for built ins) *
1387 * address thread specific top of native list *
1388 * old value of thread specific head *
1391 * at end of function: *
1393 * return adresss of the jit call which invokes the native *
1396 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1399 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1400 ***********************************************************************************************************/
1402 asm_remove_native_stackinfo:
1412 #define REMOVE_NATIVE_STACKINFO \
1413 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1414 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1415 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1416 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1423 * These are local overrides for various environment variables in Emacs.
1424 * Please do not remove this and leave it at the end of the file, where
1425 * Emacs will automagically detect them.
1426 * ---------------------------------------------------------------------
1429 * indent-tabs-mode: t