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 1858 2005-01-04 12:36:07Z 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
59 .globl asm_calljavafunction2
60 .globl asm_calljavafunction2int
61 .globl asm_calljavafunction2long
62 .globl asm_calljavafunction2float
63 .globl asm_calljavafunction2double
64 .globl calljava_xhandler2
66 .globl asm_call_jit_compiler
67 .globl asm_handle_builtin_exception
68 .globl asm_handle_nat_exception
69 .globl asm_handle_exception
70 .globl asm_check_clinit
71 .globl asm_builtin_checkcast
72 .globl asm_builtin_checkarraycast
73 .globl asm_builtin_newarray
74 .globl asm_builtin_anewarray
75 .globl asm_builtin_newarray_array
76 .globl asm_builtin_aastore
78 #if defined(USE_THREADS)
79 .globl asm_builtin_monitorenter
80 .globl asm_builtin_monitorexit
83 .globl asm_builtin_ldiv
84 .globl asm_builtin_lrem
85 .globl asm_builtin_f2i
86 .globl asm_builtin_f2l
87 .globl asm_builtin_d2i
88 .globl asm_builtin_d2l
89 .globl asm_builtin_arrayinstanceof
90 .globl asm_perform_threadswitch
91 .globl asm_initialize_thread_stack
92 .globl asm_switchstackandcall
93 .globl asm_getcallingmethod
94 .globl asm_builtin_new
95 .globl asm_criticalsections
96 .globl asm_getclassvalues_atomic
98 .globl asm_throw_and_handle_exception
99 .globl asm_throw_and_handle_hardware_arithmetic_exception
101 .globl asm_prepare_native_stackinfo
102 .globl asm_remove_native_stackinfo
105 /********************* function asm_calljavafunction ***************************
107 * This function calls a Java-method (which possibly needs compilation) *
108 * with up to 4 address parameters. *
110 * This functions calls the JIT-compiler which eventually translates the *
111 * method into machine code. *
114 * javaobject_header *asm_calljavamethod (methodinfo *m, *
115 * void *arg1, void *arg2, void *arg3, void *arg4); *
117 *******************************************************************************/
120 .ascii "calljavafunction\0\0"
123 .long 0 /* catch type all */
124 .long calljava_xhandler /* handler pc */
125 .long calljava_xhandler /* end pc */
126 .long asm_calljavafunction /* start pc */
127 .long 1 /* extable size */
128 .long 0 /* line number table start */
129 .long 0 /* line number table size */
130 .long 0 /* fltsave */
131 .long 0 /* intsave */
134 .long 32 /* frame size */
135 .long 0 /* method pointer (pointer to name) */
137 asm_calljavafunction:
138 push %ebp /* allocate stack space */
141 push %ebx /* save registers */
145 sub $32,%esp /* pass the remaining parameters */
148 mov %edx,28(%esp) /* convert parms to 8 byte */
164 mov 8(%ebp),%eax /* move function pointer to %eax */
166 lea asm_call_jit_compiler,%edx
167 call *%edx /* call JIT compiler */
170 pop %edi /* restore registers */
177 push %eax /* pass exception pointer */
178 call builtin_throw_exception
182 pop %edi /* restore registers */
189 /********************* function asm_calljavafunction ***************************
191 * This function calls a Java-method (which possibly needs compilation) *
192 * with up to 4 address parameters. *
194 * This functions calls the JIT-compiler which eventually translates the *
195 * method into machine code. *
198 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
199 * u4 count, u4 size, void *callblock); *
201 *******************************************************************************/
204 .ascii "calljavafunction2\0\0"
207 .long 0 /* catch type all */
208 .long calljava_xhandler2 /* handler pc */
209 .long calljava_xhandler2 /* end pc */
210 .long asm_calljavafunction2 /* start pc */
211 .long 1 /* extable size */
212 .long 0 /* line number table start */
213 .long 0 /* line number table size */
214 .long 0 /* fltsave */
215 .long 0 /* intsave */
218 .long 32 /* frame size */
219 .long 0 /* method pointer (pointer to name) */
221 asm_calljavafunction2:
222 asm_calljavafunction2int:
223 asm_calljavafunction2long:
224 asm_calljavafunction2float:
225 asm_calljavafunction2double:
227 mov %esp,%ebp /* save stackptr */
229 push %ebx /* save registers */
233 mov 20(%ebp),%eax /* pointer to arg block */
234 mov 12(%ebp),%ecx /* arg count */
235 test %ecx,%ecx /* maybe we have no args */
236 jle calljava_copydone
238 mov %ecx,%edx /* calculate stack size */
240 mov %edx,%esi /* save in callee saved register */
241 sub %esi,%esp /* stack frame for arguments */
245 mov offjniitem(%eax),%edx
247 mov offjniitem+4(%eax),%edx
250 sub $1,%ecx /* are there any args left? */
252 jle calljava_copydone
254 add $sizejniblock,%eax /* goto next argument block */
255 add $8,%edi /* increase sp to next argument */
256 jmp calljava_copyloop
259 mov 8(%ebp),%eax /* move function pointer to %eax */
261 lea asm_call_jit_compiler,%edx
262 call *%edx /* call JIT compiler */
265 add %esi,%esp /* remove arg stack frame */
266 pop %edi /* restore registers */
273 push %eax /* pass exception pointer */
274 call builtin_throw_exception
277 add %esi,%esp /* remove arg stack frame */
278 pop %edi /* restore registers */
285 /****************** function asm_call_jit_compiler *****************************
287 * invokes the compiler for untranslated JavaVM methods. *
289 * Register R0 contains a pointer to the method info structure (prepared *
290 * by createcompilerstub). Using the return address in R26 and the *
291 * offset in the LDA instruction or using the value in methodptr R28 the *
292 * patching address for storing the method address can be computed: *
294 * method address was either loaded using *
296 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
297 * i386_call_reg(REG_ITMP2) *
301 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
302 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
303 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
304 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
305 * i386_call_reg(REG_ITMP1) *
307 * in the static case the method pointer can be computed using the *
308 * return address and the lda function following the jmp instruction *
310 *******************************************************************************/
312 asm_call_jit_compiler:
313 push %ebx /* save register */
316 mov 8(%esp),%ebp /* get return address (2 push) */
317 mov -1(%ebp),%bl /* get function code */
318 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
319 jne L_not_static_special
321 sub $6,%ebp /* calculate address of immediate */
322 jmp L_call_jit_compile
324 L_not_static_special:
325 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
326 jne L_not_virtual_interface
328 sub $6,%ebp /* calculate address of offset */
329 mov (%ebp),%ebp /* get offset */
330 add itmp2,%ebp /* add base address to get method address */
331 jmp L_call_jit_compile
333 L_not_virtual_interface: /* a call from asm_calljavafunction */
337 push %ebp /* save address for method pointer */
339 push %eax /* push methodpointer on stack */
343 pop %ebp /* restore address for method pointer */
345 test %eax,%eax /* check for exception */
348 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
351 mov %eax,(%ebp) /* and now save the new pointer */
354 pop %ebp /* restore registers */
357 jmp *%eax /* ...and now call the new method */
360 pop %ebp /* restore registers */
363 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
364 call builtin_asm_get_exceptionptrptr
366 mov (%ecx),%eax /* get the exception pointer */
367 movl $0,(%ecx) /* clear the exception pointer */
369 lea _exceptionptr,%ecx
370 mov (%ecx),%eax /* get the exception pointer */
371 movl $0,(%ecx) /* clear the exception pointer */
374 pop %ecx /* delete return address */
375 sub $2,%ecx /* faulting address is return adress - 2 */
377 L_refillinStacktrace: /*a compilation error should cause a stacktrace
378 which starts at the method call, which caused
379 the compilation of the new function. Until this
380 point the trace is invalid anyways, since it is
381 not complete. Compared to other runtimes it will
382 not be correct either, since we report eg class
383 not found errors too early, since we always
384 compile methods completely. The native info
385 should be moved around the jit call to get
386 a more compliant trace for the "exception in
388 push %ecx /* store fault adress */
389 push %eax /* temporarily save exception pointer*/
390 push $0 /* internal function */
391 call builtin_asm_get_stackframeinfo
392 push %eax /* save location of thread specific stack info head pointer */
393 mov (%eax),%ecx /* save old value of pointer*/
395 mov %esp,(%eax) /*store pointer to this structure*/
396 mov 12(%esp),%eax /* get the exception pointer again*/
397 movl $0,12(%esp) /*java stack begins just above structure*/
398 push $0 /*used for the jni_callblock structure*/
399 push %eax /*save eax for later */
400 /* get fillInStackTrace method*/
401 push utf_fillInStackTrace_desc
402 push utf_fillInStackTrace_name
403 mov offobjvftbl(%eax),%ecx
404 mov offclass(%ecx),%eax
406 call class_resolvemethod
414 call asm_calljavafunction2
417 /*remove native stack info */
426 jmp asm_handle_exception
429 /********************* function asm_handle_exception ***************************
431 * This function handles an exception. It does not use the usual calling *
432 * conventions. The exception pointer is passed in REG_ITMP1 and the *
433 * pc from the exception raising position is passed in REG_ITMP2. It searches *
434 * the local exception table for a handler. If no one is found, it unwinds *
435 * stacks and continues searching the callers. *
437 * void asm_handle_exception (exceptionptr, exceptionpc); *
439 *******************************************************************************/
441 asm_handle_nat_exception:
442 add $4,%esp /* clear return address of native stub */
444 asm_handle_exception:
445 asm_handle_exception_loop:
449 push %eax /* save exception pointer */
450 push %ecx /* save exception pc */
452 call codegen_findmethod /* get the data segment ptr */
456 mov -8(%ebp),%ecx /* could be changed in findmethod */
458 push %edx /* save data segment pointer */
465 mov %eax,(%esp) /* exception pointer */
466 mov MethodPointer(%edx),%eax /* method pointer */
468 mov %ecx,8(%esp) /* exception pc */
469 movl $0,12(%esp) /* line number */
470 movl $1,16(%esp) /* set no unwind flag */
471 call builtin_trace_exception
473 mov -12(%ebp),%esi /* %esi = data segment pointer */
474 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
475 test %ecx,%ecx /* if empty table skip */
478 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
479 mov -4(%ebp),%eax /* get xptr */
482 mov -8(%ebp),%edx /* get xpc */
484 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
485 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
486 jg ex_table_cont /* if (false) continue */
487 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
488 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
489 jge ex_table_cont /* if (false) continue */
490 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
491 test %ebx,%ebx /* NULL catches everything */
494 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
498 mov %eax,1*4(%esp) /* save not callee saved regs */
501 mov %ebx,0*4(%esp) /* exception class is argument */
510 cmpl $0,offclasslinked(%ebx)
514 mov %eax,1*4(%esp) /* save not callee saved regs */
517 mov %ebx,0*4(%esp) /* exception class is argument */
526 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
534 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
535 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
536 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
537 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
538 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
540 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
542 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
546 cmp %ebx,%esi /* xptr is instanceof catchtype */
550 mov ExHandlerPC(%edi),%edx
552 pop %edi /* restore registers */
555 add $8,%esp /* suck %ecx, %edx */
556 pop %eax /* restore xptr */
559 jmp *%edx /* jump to exception handler */
562 lea ExEntrySize(%edi),%edi
571 pop %edx /* restore data segment pointer */
576 push %eax /* save exception pointer */
579 mov IsSync(%edx),%eax /* %eax = SyncOffset */
580 test %eax,%eax /* if zero no monitorexit */
583 #if defined(USE_THREADS)
585 mov -4(%eax),%eax /* we have the xptr on the stack */
586 push %edx /* save regs */
588 call builtin_monitorexit
590 pop %edx /* restore regs */
595 add FrameSize(%edx),%eax /* %eax = frame size */
596 add $4,%eax /* we have the xptr on the stack */
598 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
620 shl $3,%ecx /* multiply by 8 bytes */
624 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
651 pop %eax /* restore exception pointer */
653 mov FrameSize(%edx),%ecx /* %ecx = frame size */
654 add %ecx,%esp /* unwind stack */
656 pop %ecx /* the new xpc is return address */
659 jmp asm_handle_exception_loop
662 /* asm_check_clinit ************************************************************
668 16 ra ; return address of patched call in java machine code
669 12 xmcode ; additional machine code (only for i386 and x86_64)
670 8 mcode ; machine code to patch back in
671 4 class ; pointer to class
672 0 sp ; stack pointer of java stack frame + return address
674 *******************************************************************************/
677 mov 4(%esp),%eax /* get fieldinfo's class pointer */
678 mov offclassinit(%eax),%eax /* get initialized flag */
684 push itmp1 /*return adress into java machine code */
686 push itmp1 /*begin of java stack frame*/
687 pushl $0 /*internal (invisible) method*/
688 call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
689 data onto the stack */
692 mov 20+4+4(%esp),itmp1 /* get class pointer */
693 mov itmp1,(%esp) /* store class pointer as a0 */
694 call class_init /* call class_init function */
697 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
698 into java machine code on stack */
699 add $4,%esp /* ret address no longer needed, is still
700 on stack a few bytes above */
702 test %eax,%eax /* we had an exception */
703 je L_initializererror
706 mov 16(%esp),itmp1 /* get return address */
707 sub $5,itmp1 /* remove size of `call rel32' */
709 mov 12(%esp),itmp2 /* get xmcode machine code */
710 movb itmp2b,(itmp1) /* patch back in 1 byte */
711 mov 8(%esp),itmp2 /* get mcode machine code */
712 mov itmp2,1(itmp1) /* patch back in 4 bytes */
714 add $(5*4),%esp /* remove stub stack frame incl. ra */
716 jmp *itmp1 /* jump to patched code an execute it */
719 add $(4*4),%esp /* remove stub stack frame */
721 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
722 call builtin_asm_get_exceptionptrptr
724 mov (%ecx),%eax /* get the exception pointer */
725 movl $0,(%ecx) /* clear the exception pointer */
727 lea _exceptionptr,%ecx
728 mov (%ecx),%eax /* get the exception pointer */
729 movl $0,(%ecx) /* clear the exception pointer */
732 pop itmp2 /* get and delete ra */
733 sub $5,itmp2 /* faulting address is ra - 5 */
735 jmp asm_handle_exception
738 /********************* function asm_builtin_monitorenter ***********************
740 * Does null check and calls monitorenter or throws an exception *
742 *******************************************************************************/
744 #if defined(USE_THREADS)
745 asm_builtin_monitorenter:
747 je nb_monitorenter /* if (null) throw exception */
748 jmp builtin_monitorenter /* else call builtin_monitorenter */
751 mov string_java_lang_NullPointerException,%eax
754 jmp asm_throw_and_handle_exception
757 push string_java_lang_NullPointerException
761 pop %ecx /* delete return address */
762 sub $2,%ecx /* faulting address is return adress - 2 */
763 jmp asm_handle_exception
768 /********************* function asm_builtin_monitorexit ************************
770 * Does null check and calls monitorexit or throws an exception *
772 *******************************************************************************/
774 #if defined(USE_THREADS)
775 asm_builtin_monitorexit:
778 je nb_monitorexit /* if (null) throw exception */
779 push %ecx /* save registers which could be used */
782 call builtin_monitorexit /* else call builtin_monitorenter */
784 pop %edx /* restore registers which could be used */
789 mov string_java_lang_NullPointerException,%eax
792 jmp asm_throw_and_handle_exception
795 push string_java_lang_NullPointerException
799 pop %ecx /* delete return address */
800 sub $2,%ecx /* faulting address is return adress - 2 */
801 jmp asm_handle_exception
806 /************************ function asm_builtin_ldiv ****************************
808 * Does null check and calls ldiv or throws an exception *
810 *******************************************************************************/
815 test %eax,%eax /* if (null) throw exception */
823 jmp asm_throw_and_handle_hardware_arithmetic_exception
825 push string_java_lang_ArithmeticException_message
826 push string_java_lang_ArithmeticException
827 call new_exception_message
830 pop %ecx /* delete return address */
831 sub $2,%ecx /* faulting address is return adress - 2 */
832 jmp asm_handle_exception
835 /************************ function asm_builtin_lrem ****************************
837 * Does null check and calls lrem or throws an exception *
839 *******************************************************************************/
844 test %eax,%eax /* if (null) throw exception */
852 jmp asm_throw_and_handle_hardware_arithmetic_exception
854 push string_java_lang_ArithmeticException_message
855 push string_java_lang_ArithmeticException
856 call new_exception_message
859 pop %ecx /* delete return address */
860 sub $2,%ecx /* faulting address is return adress - 2 */
861 jmp asm_handle_exception
864 /************************ function asm_builtin_x2x *****************************
866 * Wrapper functions for corner cases *
868 *******************************************************************************/
899 /******************* function asm_builtin_checkarraycast ***********************
901 * Does the cast check and eventually throws an exception *
903 *******************************************************************************/
905 asm_builtin_checkarraycast:
906 sub $8,%esp /* build stack frame (2 * 4 bytes) */
908 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
909 mov %eax,(%esp) /* save object pointer */
914 call builtin_checkarraycast /* builtin_checkarraycast */
916 test %eax,%eax /* if (false) throw exception */
919 mov 12(%esp),%eax /* return object pointer */
925 mov string_java_lang_ClassCastException,%eax
928 jmp asm_throw_and_handle_exception
930 push string_java_lang_ClassCastException
936 pop %ecx /* delete return address */
937 sub $2,%ecx /* faulting address is return adress - 2 */
938 jmp asm_handle_exception
941 /******************* function asm_builtin_newarray *****************************
943 * Does the cast check and eventually throws an exception *
945 *******************************************************************************/
947 asm_builtin_newarray:
948 sub $8,%esp /* build stack frame (2 * 4 bytes) */
956 call builtin_newarray
962 /******************* function asm_builtin_aastore ******************************
964 * Does the cast check and eventually throws an exception *
966 *******************************************************************************/
969 sub $12,%esp /* build stack frame (3 * 4 bytes) */
971 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
972 test %eax,%eax /* if null pointer throw exception */
975 mov offarraysize(%eax),%edx /* load size */
976 mov 24(%esp),%ecx /* index */
977 cmp %edx,%ecx /* do bound check */
978 jae nb_aastore_bound /* if out of bounds throw exception */
980 shl $2,%ecx /* index * 4 */
981 add %eax,%ecx /* add index * 4 to arrayref */
983 mov %ecx,8(%esp) /* save store position */
985 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
988 mov 32(%esp),%eax /* object is second argument */
991 call builtin_canstore /* builtin_canstore(arrayref,object) */
993 test %eax,%eax /* if (false) throw exception */
998 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
1005 mov string_java_lang_NullPointerException,%eax
1008 jmp asm_throw_and_handle_exception
1011 push string_java_lang_NullPointerException
1016 pop %ecx /* delete return address */
1017 sub $2,%ecx /* faulting address is return adress - 2 */
1018 jmp asm_handle_exception
1022 mov %ecx,%eax /* itmp2 contains array index */
1023 pushl $0 /*directly below return adress*/
1024 pushl $0 /*internal (invisible) method*/
1025 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1028 call new_arrayindexoutofboundsexception
1031 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
1033 pop %ecx /* delete return address */
1034 sub $2,%ecx /* faulting address is return adress - 2 */
1035 jmp asm_handle_exception
1040 mov string_java_lang_ArrayStoreException,%eax
1043 jmp asm_throw_and_handle_exception
1046 push string_java_lang_ArrayStoreException
1051 pop %ecx /* delete return address */
1052 sub $2,%ecx /* faulting address is return adress - 2 */
1053 jmp asm_handle_exception
1056 /******************* function asm_builtin_arrayinstanceof **********************
1058 * Does the instanceof check of arrays *
1060 *******************************************************************************/
1062 asm_builtin_arrayinstanceof:
1063 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1071 call builtin_arrayinstanceof
1077 /******************* function asm_initialize_thread_stack **********************
1079 * initialized a thread stack *
1080 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1082 *******************************************************************************/
1084 asm_initialize_thread_stack:
1085 mov 8(%esp),%eax /* (to)->stackEnd */
1086 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1098 mov 4(%esp),%edx /* save (u1*) (func) */
1101 ret /* return restorepoint in %eax */
1104 /******************* function asm_perform_threadswitch *************************
1106 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1108 * performs a threadswitch *
1110 *******************************************************************************/
1112 asm_perform_threadswitch:
1124 mov 36(%esp),%eax /* save current return address */
1127 mov 40(%esp),%eax /* first argument **from */
1130 mov 48(%esp),%eax /* third argument **stackTop */
1133 mov 44(%esp),%eax /* second argument **to */
1134 mov 0(%eax),%esp /* load new stack pointer */
1140 /* skip stack pointer */
1145 add $32,%esp /* leave return address on stack */
1149 /********************* function asm_switchstackandcall *************************
1151 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1154 * Switches to a new stack, calls a function and switches back. *
1155 * a0 new stack pointer *
1156 * a1 function pointer *
1157 * a2 pointer to variable where stack top should be stored *
1158 * a3 pointer to user data, is passed to the function *
1160 *******************************************************************************/
1162 asm_switchstackandcall:
1163 mov 4(%esp),%edx /* first argument *stack */
1164 sub $8,%edx /* allocate new stack */
1166 mov (%esp),%eax /* save return address on new stack */
1169 mov %esp,4(%edx) /* save old stack pointer on new stack */
1171 mov 12(%esp),%eax /* third argument **stacktopsave */
1172 mov %esp,(%eax) /* save old stack pointer to variable */
1174 mov 8(%esp),%eax /* load function pointer */
1175 mov 16(%esp),%ecx /* fourth argument *p */
1177 mov %edx,%esp /* switch to new stack */
1180 mov %ecx,0(%esp) /* pass pointer */
1181 call *%eax /* and call function */
1184 mov (%esp),%edx /* load return address */
1185 mov 4(%esp),%esp /* switch to old stack */
1190 asm_throw_and_handle_exception:
1192 pushl $0 /* the pushed XPC is directly below the java frame*/
1194 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1198 add $4,%esp /*remove parameter*/
1200 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1203 jmp asm_handle_exception
1204 ret /*should never be reached */
1206 asm_throw_and_handle_hardware_arithmetic_exception:
1209 pushl $0 /* the pushed XPC is directly below the java frame*/
1211 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1213 mov string_java_lang_ArithmeticException_message,%eax
1215 mov string_java_lang_ArithmeticException,%eax
1218 call new_exception_message
1219 add $8,%esp /*remove parameters */
1221 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1224 jmp asm_handle_exception
1225 ret /*should never be reached */
1228 /*optimize a littlebit */
1232 call i386_native_stub_debug
1236 mov offclassinit(%eax),%ecx /* get initialized flag */
1238 jnz L_builtin_new_noinit
1240 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1242 /* 2 *4 bytes, the return adress is used directy */
1243 pushl $0 /* the structure is placed directly below the java stackframe*/
1244 pushl $0 /* builtin (invisible) method */
1245 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1247 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1252 call builtin_asm_get_stackframeinfo
1265 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1274 jmp L_builtin_new_patch
1277 L_builtin_new_noinit:
1282 /*jmp L_builtin_new_patch*/
1284 L_builtin_new_patch:
1285 /*add patching code here */
1286 lea builtin_new,%edx
1288 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1296 asm_getclassvalues_atomic:
1298 mov 4(%esp),%ecx /* super */
1299 mov 8(%esp),%edx /* sub */
1301 mov offbaseval(%ecx),%eax
1302 mov offdiffval(%ecx),%ecx
1303 mov offbaseval(%edx),%edx
1306 mov 16(%esp),%ebx /* out */
1307 mov %eax,offcast_super_baseval(%ebx)
1308 mov %ecx,offcast_super_diffval(%ebx)
1309 mov %edx,offcast_sub_baseval(%ebx)
1315 asm_criticalsections:
1316 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1319 .long _crit_restart1
1322 .long _crit_restart2
1328 /************************ function asm_prepare_native_stackinfo ****************************
1330 * creates a stackfame for the begin of a native function (either builtin or not ) *
1331 * expected stack at begin of function *
1333 * address of the jit call which invokes the native *
1334 * begin address of stack frame of the java method *
1335 * method pointer or 0 (for built ins) *
1338 * at end of function: *
1340 * address of the jit call which invokes the native *
1341 * begin address of stack frame of the java method *
1342 * method pointer or 0 (for built ins) *
1343 * address of thread specific top of native list *
1344 * old value of thread specific head *
1348 * This thing is less efficient than the original #define (callerside) *
1349 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1350 ********************************************************************************************/
1353 asm_prepare_native_stackinfo:
1358 lea builtin_asm_get_stackframeinfo,%ecx
1369 #define PREPARE_NATIVE_STACKINFO \
1370 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1371 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1372 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1373 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1374 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1375 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1376 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1377 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1378 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1379 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1380 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1381 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1385 /************************ function asm_remove _native_stackinfo *******************************************
1387 * creates a stackfame for the begin of a native function (either builtin or not) *
1388 * expected stack at begin of function *
1389 * address of the jit call which invokes the native *
1390 * begin address of stack frame of the java method *
1391 * method pointer or 0 (for built ins) *
1392 * address thread specific top of native list *
1393 * old value of thread specific head *
1396 * at end of function: *
1398 * return adresss of the jit call which invokes the native *
1401 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1404 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1405 ***********************************************************************************************************/
1407 asm_remove_native_stackinfo:
1417 #define REMOVE_NATIVE_STACKINFO \
1418 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1419 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1420 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1421 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1428 * These are local overrides for various environment variables in Emacs.
1429 * Please do not remove this and leave it at the end of the file, where
1430 * Emacs will automagically detect them.
1431 * ---------------------------------------------------------------------
1434 * indent-tabs-mode: t