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 Changes: Joseph Wenninger
34 $Id: asmpart.S 1683 2004-12-05 21:33:36Z jowenn $
40 #include "vm/jit/i386/offsets.h"
41 #include "vm/jit/i386/asmoffsets.h"
55 /********************* exported functions and variables ***********************/
57 .globl asm_calljavafunction
58 .globl calljava_xhandler
59 .globl asm_calljavafunction2
60 .globl asm_calljavafunction2long
61 .globl asm_calljavafunction2double
62 .globl calljava_xhandler2
64 .globl asm_call_jit_compiler
65 .globl asm_handle_builtin_exception
66 .globl asm_handle_nat_exception
67 .globl asm_handle_exception
68 .globl asm_check_clinit
69 .globl asm_builtin_checkcast
70 .globl asm_builtin_checkarraycast
71 .globl asm_builtin_newarray
72 .globl asm_builtin_anewarray
73 .globl asm_builtin_newarray_array
74 .globl asm_builtin_aastore
75 .globl asm_builtin_monitorenter
76 .globl asm_builtin_monitorexit
77 .globl asm_builtin_ldiv
78 .globl asm_builtin_lrem
79 .globl asm_builtin_f2i
80 .globl asm_builtin_f2l
81 .globl asm_builtin_d2i
82 .globl asm_builtin_d2l
83 .globl asm_builtin_arrayinstanceof
84 .globl asm_perform_threadswitch
85 .globl asm_initialize_thread_stack
86 .globl asm_switchstackandcall
87 .globl asm_getcallingmethod
88 .globl asm_builtin_new
89 .globl asm_criticalsections
90 .globl asm_getclassvalues_atomic
91 .globl asm_prepare_native_stackinfo
92 .globl asm_remove_native_stackinfo
93 /*************************** imported functions *******************************/
96 .globl builtin_monitorexit
97 .globl builtin_throw_exception
98 .globl builtin_trace_exception
99 .globl class_java_lang_Object
100 .globl codegen_findmethod
101 .globl callgetexceptionptrptr
102 .globl asm_throw_and_handle_exception
103 .globl asm_throw_and_handle_hardware_arithmetic_exception
106 /********************* function asm_calljavafunction ***************************
108 * This function calls a Java-method (which possibly needs compilation) *
109 * with up to 4 address parameters. *
111 * This functions calls the JIT-compiler which eventually translates the *
112 * method into machine code. *
115 * javaobject_header *asm_calljavamethod (methodinfo *m, *
116 * void *arg1, void *arg2, void *arg3, void *arg4); *
118 *******************************************************************************/
121 .ascii "calljavafunction\0\0"
124 .long 0 /* catch type all */
125 .long calljava_xhandler /* handler pc */
126 .long calljava_xhandler /* end pc */
127 .long asm_calljavafunction /* start pc */
128 .long 1 /* extable size */
129 .long 0 /* line number table start */
130 .long 0 /* line number table size */
131 .long 0 /* fltsave */
132 .long 0 /* intsave */
135 .long 32 /* frame size */
136 .long 0 /* method pointer (pointer to name) */
138 asm_calljavafunction:
139 push %ebp /* allocate stack space */
142 push %ebx /* save registers */
146 sub $32,%esp /* pass the remaining parameters */
149 mov %edx,28(%esp) /* convert parms to 8 byte */
165 mov 8(%ebp),%eax /* move function pointer to %eax */
167 lea asm_call_jit_compiler,%edx
168 call *%edx /* call JIT compiler */
171 pop %edi /* restore registers */
178 push %eax /* pass exception pointer */
179 call builtin_throw_exception
183 pop %edi /* restore registers */
190 /********************* function asm_calljavafunction ***************************
192 * This function calls a Java-method (which possibly needs compilation) *
193 * with up to 4 address parameters. *
195 * This functions calls the JIT-compiler which eventually translates the *
196 * method into machine code. *
199 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
200 * u4 count, u4 size, void *callblock); *
202 *******************************************************************************/
205 .ascii "calljavafunction2\0\0"
208 .long 0 /* catch type all */
209 .long calljava_xhandler2 /* handler pc */
210 .long calljava_xhandler2 /* end pc */
211 .long asm_calljavafunction2 /* start pc */
212 .long 1 /* extable size */
213 .long 0 /* line number table start */
214 .long 0 /* line number table size */
215 .long 0 /* fltsave */
216 .long 0 /* intsave */
219 .long 32 /* frame size */
220 .long 0 /* method pointer (pointer to name) */
222 asm_calljavafunction2:
223 asm_calljavafunction2double:
224 asm_calljavafunction2long:
226 mov %esp,%ebp /* save stackptr */
228 push %ebx /* save registers */
232 mov 20(%ebp),%eax /* pointer to arg block */
233 mov 12(%ebp),%ecx /* arg count */
234 test %ecx,%ecx /* maybe we have no args */
235 jle calljava_copydone
237 mov %ecx,%edx /* calculate stack size */
239 mov %edx,%esi /* save in callee saved register */
240 sub %esi,%esp /* stack frame for arguments */
244 mov offjniitem(%eax),%edx
246 mov offjniitem+4(%eax),%edx
249 sub $1,%ecx /* are there any args left? */
251 jle calljava_copydone
253 add $sizejniblock,%eax /* goto next argument block */
254 add $8,%edi /* increase sp to next argument */
255 jmp calljava_copyloop
258 mov 8(%ebp),%eax /* move function pointer to %eax */
260 lea asm_call_jit_compiler,%edx
261 call *%edx /* call JIT compiler */
264 add %esi,%esp /* remove arg stack frame */
265 pop %edi /* restore registers */
272 push %eax /* pass exception pointer */
273 call builtin_throw_exception
276 add %esi,%esp /* remove arg stack frame */
277 pop %edi /* restore registers */
284 /****************** function asm_call_jit_compiler *****************************
286 * invokes the compiler for untranslated JavaVM methods. *
288 * Register R0 contains a pointer to the method info structure (prepared *
289 * by createcompilerstub). Using the return address in R26 and the *
290 * offset in the LDA instruction or using the value in methodptr R28 the *
291 * patching address for storing the method address can be computed: *
293 * method address was either loaded using *
295 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
296 * i386_call_reg(REG_ITMP2) *
300 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
301 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
302 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
303 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
304 * i386_call_reg(REG_ITMP1) *
306 * in the static case the method pointer can be computed using the *
307 * return address and the lda function following the jmp instruction *
309 *******************************************************************************/
311 asm_call_jit_compiler:
312 push %ebx /* save register */
315 mov 8(%esp),%ebp /* get return address (2 push) */
316 mov -1(%ebp),%bl /* get function code */
317 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
318 jne L_not_static_special
320 sub $6,%ebp /* calculate address of immediate */
321 jmp L_call_jit_compile
323 L_not_static_special:
324 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
325 jne L_not_virtual_interface
327 sub $6,%ebp /* calculate address of offset */
328 mov (%ebp),%ebp /* get offset */
329 add itmp2,%ebp /* add base address to get method address */
330 jmp L_call_jit_compile
332 L_not_virtual_interface: /* a call from asm_calljavafunction */
336 push %ebp /* save address for method pointer */
338 push %eax /* push methodpointer on stack */
342 pop %ebp /* restore address for method pointer */
344 test %eax,%eax /* check for exception */
347 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
350 mov %eax,(%ebp) /* and now save the new pointer */
353 pop %ebp /* restore registers */
356 jmp *%eax /* ...and now call the new method */
359 pop %ebp /* restore registers */
362 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
363 call builtin_asm_get_exceptionptrptr
365 mov (%ecx),%eax /* get the exception pointer */
366 movl $0,(%ecx) /* clear the exception pointer */
368 lea _exceptionptr,%ecx
369 mov (%ecx),%eax /* get the exception pointer */
370 movl $0,(%ecx) /* clear the exception pointer */
373 pop %ecx /* delete return address */
374 sub $2,%ecx /* faulting address is return adress - 2 */
376 L_refillinStacktrace: /*a compilation error should cause a stacktrace
377 which starts at the method call, which caused
378 the compilation of the new function. Until this
379 point the trace is invalid anyways, since it is
380 not complete. Compared to other runtimes it will
381 not be correct either, since we report eg class
382 not found errors too early, since we always
383 compile methods completely*/
384 push %ecx /* store fault adress */
385 push %eax /* temporarily save exception pointer*/
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 8(%esp),%eax /* get the exception pointer again*/
392 movl $0,8(%esp) /*mark this block as native*/
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 */
579 mov -4(%eax),%eax /* we have the xptr on the stack */
580 push %edx /* save regs */
582 call builtin_monitorexit
584 pop %edx /* restore regs */
588 add FrameSize(%edx),%eax /* %eax = frame size */
589 add $4,%eax /* we have the xptr on the stack */
591 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
613 shl $3,%ecx /* multiply by 8 bytes */
617 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
644 pop %eax /* restore exception pointer */
646 mov FrameSize(%edx),%ecx /* %ecx = frame size */
647 add %ecx,%esp /* unwind stack */
649 pop %ecx /* the new xpc is return address */
652 jmp asm_handle_exception_loop
655 /* asm_check_clinit ************************************************************
661 16 ra ; return address of patched call in java machine code
662 12 xmcode ; additional machine code (only for i386 and x86_64)
663 8 mcode ; machine code to patch back in
664 4 class ; pointer to class
665 0 sp ; stack pointer of java stack frame + return address
667 *******************************************************************************/
670 mov 4(%esp),%eax /* get fieldinfo's class pointer */
671 mov offclassinit(%eax),%eax /* get initialized flag */
677 push itmp1 /*return adress into java machine code */
679 push itmp1 /*begin of java stack frame*/
680 pushl $0 /*internal (invisible) method*/
681 call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
682 data onto the stack */
685 mov 20+4+4(%esp),itmp1 /* get class pointer */
686 mov itmp1,(%esp) /* store class pointer as a0 */
687 call class_init /* call class_init function */
690 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
691 into java machine code on stack */
692 add $4,%esp /* ret address no longer needed, is still
693 on stack a few bytes above */
695 test %eax,%eax /* we had an exception */
696 je L_initializererror
699 mov 16(%esp),itmp1 /* get return address */
700 sub $5,itmp1 /* remove size of `call rel32' */
702 mov 12(%esp),itmp2 /* get xmcode machine code */
703 movb itmp2b,(itmp1) /* patch back in 1 byte */
704 mov 8(%esp),itmp2 /* get mcode machine code */
705 mov itmp2,1(itmp1) /* patch back in 4 bytes */
707 add $(5*4),%esp /* remove stub stack frame incl. ra */
709 jmp *itmp1 /* jump to patched code an execute it */
712 add $(4*4),%esp /* remove stub stack frame */
714 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
715 call builtin_asm_get_exceptionptrptr
717 mov (%ecx),%eax /* get the exception pointer */
718 movl $0,(%ecx) /* clear the exception pointer */
720 lea _exceptionptr,%ecx
721 mov (%ecx),%eax /* get the exception pointer */
722 movl $0,(%ecx) /* clear the exception pointer */
725 pop itmp2 /* get and delete ra */
726 sub $5,itmp2 /* faulting address is ra - 5 */
728 jmp asm_handle_exception
731 /********************* function asm_builtin_monitorenter ***********************
733 * Does null check and calls monitorenter or throws an exception *
735 *******************************************************************************/
737 asm_builtin_monitorenter:
739 je nb_monitorenter /* if (null) throw exception */
740 jmp builtin_monitorenter /* else call builtin_monitorenter */
743 mov string_java_lang_NullPointerException,%eax
746 jmp asm_throw_and_handle_exception
749 push string_java_lang_NullPointerException
753 pop %ecx /* delete return address */
754 sub $2,%ecx /* faulting address is return adress - 2 */
755 jmp asm_handle_exception
758 /********************* function asm_builtin_monitorexit ************************
760 * Does null check and calls monitorexit or throws an exception *
762 *******************************************************************************/
764 asm_builtin_monitorexit:
767 je nb_monitorexit /* if (null) throw exception */
768 push %ecx /* save registers which could be used */
771 call builtin_monitorexit /* else call builtin_monitorenter */
773 pop %edx /* restore registers which could be used */
778 mov string_java_lang_NullPointerException,%eax
781 jmp asm_throw_and_handle_exception
784 push string_java_lang_NullPointerException
788 pop %ecx /* delete return address */
789 sub $2,%ecx /* faulting address is return adress - 2 */
790 jmp asm_handle_exception
793 /************************ function asm_builtin_ldiv ****************************
795 * Does null check and calls ldiv or throws an exception *
797 *******************************************************************************/
802 test %eax,%eax /* if (null) throw exception */
810 jmp asm_throw_and_handle_hardware_arithmetic_exception
812 push string_java_lang_ArithmeticException_message
813 push string_java_lang_ArithmeticException
814 call new_exception_message
817 pop %ecx /* delete return address */
818 sub $2,%ecx /* faulting address is return adress - 2 */
819 jmp asm_handle_exception
822 /************************ function asm_builtin_lrem ****************************
824 * Does null check and calls lrem or throws an exception *
826 *******************************************************************************/
831 test %eax,%eax /* if (null) throw exception */
839 jmp asm_throw_and_handle_hardware_arithmetic_exception
841 push string_java_lang_ArithmeticException_message
842 push string_java_lang_ArithmeticException
843 call new_exception_message
846 pop %ecx /* delete return address */
847 sub $2,%ecx /* faulting address is return adress - 2 */
848 jmp asm_handle_exception
851 /************************ function asm_builtin_x2x *****************************
853 * Wrapper functions for corner cases *
855 *******************************************************************************/
886 /******************* function asm_builtin_checkarraycast ***********************
888 * Does the cast check and eventually throws an exception *
890 *******************************************************************************/
892 asm_builtin_checkarraycast:
893 sub $8,%esp /* build stack frame (2 * 4 bytes) */
895 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
896 mov %eax,(%esp) /* save object pointer */
901 call builtin_checkarraycast /* builtin_checkarraycast */
903 test %eax,%eax /* if (false) throw exception */
906 mov 12(%esp),%eax /* return object pointer */
912 mov string_java_lang_ClassCastException,%eax
915 jmp asm_throw_and_handle_exception
917 push string_java_lang_ClassCastException
923 pop %ecx /* delete return address */
924 sub $2,%ecx /* faulting address is return adress - 2 */
925 jmp asm_handle_exception
928 /******************* function asm_builtin_newarray *****************************
930 * Does the cast check and eventually throws an exception *
932 *******************************************************************************/
934 asm_builtin_newarray:
935 sub $8,%esp /* build stack frame (2 * 4 bytes) */
943 call builtin_newarray
949 /******************* function asm_builtin_aastore ******************************
951 * Does the cast check and eventually throws an exception *
953 *******************************************************************************/
956 sub $12,%esp /* build stack frame (3 * 4 bytes) */
958 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
959 test %eax,%eax /* if null pointer throw exception */
962 mov offarraysize(%eax),%edx /* load size */
963 mov 24(%esp),%ecx /* index */
964 cmp %edx,%ecx /* do bound check */
965 jae nb_aastore_bound /* if out of bounds throw exception */
967 shl $2,%ecx /* index * 4 */
968 add %eax,%ecx /* add index * 4 to arrayref */
970 mov %ecx,8(%esp) /* save store position */
972 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
975 mov 32(%esp),%eax /* object is second argument */
978 call builtin_canstore /* builtin_canstore(arrayref,object) */
980 test %eax,%eax /* if (false) throw exception */
985 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
992 mov string_java_lang_NullPointerException,%eax
995 jmp asm_throw_and_handle_exception
998 push string_java_lang_NullPointerException
1003 pop %ecx /* delete return address */
1004 sub $2,%ecx /* faulting address is return adress - 2 */
1005 jmp asm_handle_exception
1009 mov %ecx,%eax /* itmp2 contains array index */
1010 pushl $0 /*directly below return adress*/
1011 pushl $0 /*internal (invisible) method*/
1012 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1015 call new_arrayindexoutofboundsexception
1018 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
1020 pop %ecx /* delete return address */
1021 sub $2,%ecx /* faulting address is return adress - 2 */
1022 jmp asm_handle_exception
1027 mov string_java_lang_ArrayStoreException,%eax
1030 jmp asm_throw_and_handle_exception
1033 push string_java_lang_ArrayStoreException
1038 pop %ecx /* delete return address */
1039 sub $2,%ecx /* faulting address is return adress - 2 */
1040 jmp asm_handle_exception
1043 /******************* function asm_builtin_arrayinstanceof **********************
1045 * Does the instanceof check of arrays *
1047 *******************************************************************************/
1049 asm_builtin_arrayinstanceof:
1050 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1058 call builtin_arrayinstanceof
1064 /******************* function asm_initialize_thread_stack **********************
1066 * initialized a thread stack *
1067 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1069 *******************************************************************************/
1071 asm_initialize_thread_stack:
1072 mov 8(%esp),%eax /* (to)->stackEnd */
1073 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1085 mov 4(%esp),%edx /* save (u1*) (func) */
1088 ret /* return restorepoint in %eax */
1091 /******************* function asm_perform_threadswitch *************************
1093 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1095 * performs a threadswitch *
1097 *******************************************************************************/
1099 asm_perform_threadswitch:
1111 mov 36(%esp),%eax /* save current return address */
1114 mov 40(%esp),%eax /* first argument **from */
1117 mov 48(%esp),%eax /* third argument **stackTop */
1120 mov 44(%esp),%eax /* second argument **to */
1121 mov 0(%eax),%esp /* load new stack pointer */
1127 /* skip stack pointer */
1132 add $32,%esp /* leave return address on stack */
1136 /********************* function asm_switchstackandcall *************************
1138 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1141 * Switches to a new stack, calls a function and switches back. *
1142 * a0 new stack pointer *
1143 * a1 function pointer *
1144 * a2 pointer to variable where stack top should be stored *
1145 * a3 pointer to user data, is passed to the function *
1147 *******************************************************************************/
1149 asm_switchstackandcall:
1150 mov 4(%esp),%edx /* first argument *stack */
1151 sub $8,%edx /* allocate new stack */
1153 mov (%esp),%eax /* save return address on new stack */
1156 mov %esp,4(%edx) /* save old stack pointer on new stack */
1158 mov 12(%esp),%eax /* third argument **stacktopsave */
1159 mov %esp,(%eax) /* save old stack pointer to variable */
1161 mov 8(%esp),%eax /* load function pointer */
1162 mov 16(%esp),%ecx /* fourth argument *p */
1164 mov %edx,%esp /* switch to new stack */
1167 mov %ecx,0(%esp) /* pass pointer */
1168 call *%eax /* and call function */
1171 mov (%esp),%edx /* load return address */
1172 mov 4(%esp),%esp /* switch to old stack */
1177 asm_throw_and_handle_exception:
1179 pushl $0 /* the pushed XPC is directly below the java frame*/
1181 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1185 add $4,%esp /*remove parameter*/
1187 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1190 jmp asm_handle_exception
1191 ret /*should never be reached */
1193 asm_throw_and_handle_hardware_arithmetic_exception:
1196 pushl $0 /* the pushed XPC is directly below the java frame*/
1198 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1200 mov string_java_lang_ArithmeticException_message,%eax
1202 mov string_java_lang_ArithmeticException,%eax
1205 call new_exception_message
1206 add $8,%esp /*remove parameters */
1208 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1211 jmp asm_handle_exception
1212 ret /*should never be reached */
1215 /*optimize a littlebit */
1219 call i386_native_stub_debug
1223 mov offclassinit(%eax),%ecx /* get initialized flag */
1225 jnz L_builtin_new_noinit
1227 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1229 /* 2 *4 bytes, the return adress is used directy */
1230 pushl $0 /* the structure is placed directly below the java stackframe*/
1231 pushl $0 /* builtin (invisible) method */
1232 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1234 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1239 call builtin_asm_get_stackframeinfo
1252 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1261 jmp L_builtin_new_patch
1264 L_builtin_new_noinit:
1269 /*jmp L_builtin_new_patch*/
1271 L_builtin_new_patch:
1272 /*add patching code here */
1273 lea builtin_new,%edx
1275 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1283 asm_getclassvalues_atomic:
1285 mov 4(%esp),%ecx /* super */
1286 mov 8(%esp),%edx /* sub */
1288 mov offbaseval(%ecx),%eax
1289 mov offdiffval(%ecx),%ecx
1290 mov offbaseval(%edx),%edx
1293 mov 16(%esp),%ebx /* out */
1294 mov %eax,offcast_super_baseval(%ebx)
1295 mov %ecx,offcast_super_diffval(%ebx)
1296 mov %edx,offcast_sub_baseval(%ebx)
1302 asm_criticalsections:
1303 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1306 .long _crit_restart1
1309 .long _crit_restart2
1315 /************************ function asm_prepare_native_stackinfo ****************************
1317 * creates a stackfame for the begin of a native function (either builtin or not ) *
1318 * expected stack at begin of function *
1320 * address of the jit call which invokes the native *
1321 * begin address of stack frame of the java method *
1322 * method pointer or 0 (for built ins) *
1325 * at end of function: *
1327 * address of the jit call which invokes the native *
1328 * begin address of stack frame of the java method *
1329 * method pointer or 0 (for built ins) *
1330 * address of thread specific top of native list *
1331 * old value of thread specific head *
1335 * This thing is less efficient than the original #define (callerside) *
1336 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1337 ********************************************************************************************/
1340 asm_prepare_native_stackinfo:
1345 lea builtin_asm_get_stackframeinfo,%ecx
1356 #define PREPARE_NATIVE_STACKINFO \
1357 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1358 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1359 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1360 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1361 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1362 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1363 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1364 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1365 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1366 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1367 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1368 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1372 /************************ function asm_remove _native_stackinfo *******************************************
1374 * creates a stackfame for the begin of a native function (either builtin or not) *
1375 * expected stack at begin of function *
1376 * address of the jit call which invokes the native *
1377 * begin address of stack frame of the java method *
1378 * method pointer or 0 (for built ins) *
1379 * address thread specific top of native list *
1380 * old value of thread specific head *
1383 * at end of function: *
1385 * return adresss of the jit call which invokes the native *
1388 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1391 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1392 ***********************************************************************************************************/
1394 asm_remove_native_stackinfo:
1404 #define REMOVE_NATIVE_STACKINFO \
1405 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1406 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1407 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1408 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1415 * These are local overrides for various environment variables in Emacs.
1416 * Please do not remove this and leave it at the end of the file, where
1417 * Emacs will automagically detect them.
1418 * ---------------------------------------------------------------------
1421 * indent-tabs-mode: t