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 1735 2004-12-07 14:33:27Z 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
74 .globl asm_builtin_monitorenter
75 .globl asm_builtin_monitorexit
76 .globl asm_builtin_ldiv
77 .globl asm_builtin_lrem
78 .globl asm_builtin_f2i
79 .globl asm_builtin_f2l
80 .globl asm_builtin_d2i
81 .globl asm_builtin_d2l
82 .globl asm_builtin_arrayinstanceof
83 .globl asm_perform_threadswitch
84 .globl asm_initialize_thread_stack
85 .globl asm_switchstackandcall
86 .globl asm_getcallingmethod
87 .globl asm_builtin_new
88 .globl asm_criticalsections
89 .globl asm_getclassvalues_atomic
90 .globl asm_prepare_native_stackinfo
91 .globl asm_remove_native_stackinfo
92 /*************************** imported functions *******************************/
95 .globl builtin_monitorexit
96 .globl builtin_throw_exception
97 .globl builtin_trace_exception
98 .globl class_java_lang_Object
99 .globl codegen_findmethod
100 .globl callgetexceptionptrptr
101 .globl asm_throw_and_handle_exception
102 .globl asm_throw_and_handle_hardware_arithmetic_exception
105 /********************* function asm_calljavafunction ***************************
107 * This function calls a Java-method (which possibly needs compilation) *
108 * with up to 4 address parameters. *
110 * This functions calls the JIT-compiler which eventually translates the *
111 * method into machine code. *
114 * javaobject_header *asm_calljavamethod (methodinfo *m, *
115 * void *arg1, void *arg2, void *arg3, void *arg4); *
117 *******************************************************************************/
120 .ascii "calljavafunction\0\0"
123 .long 0 /* catch type all */
124 .long calljava_xhandler /* handler pc */
125 .long calljava_xhandler /* end pc */
126 .long asm_calljavafunction /* start pc */
127 .long 1 /* extable size */
128 .long 0 /* line number table start */
129 .long 0 /* line number table size */
130 .long 0 /* fltsave */
131 .long 0 /* intsave */
134 .long 32 /* frame size */
135 .long 0 /* method pointer (pointer to name) */
137 asm_calljavafunction:
138 push %ebp /* allocate stack space */
141 push %ebx /* save registers */
145 sub $32,%esp /* pass the remaining parameters */
148 mov %edx,28(%esp) /* convert parms to 8 byte */
164 mov 8(%ebp),%eax /* move function pointer to %eax */
166 lea asm_call_jit_compiler,%edx
167 call *%edx /* call JIT compiler */
170 pop %edi /* restore registers */
177 push %eax /* pass exception pointer */
178 call builtin_throw_exception
182 pop %edi /* restore registers */
189 /********************* function asm_calljavafunction ***************************
191 * This function calls a Java-method (which possibly needs compilation) *
192 * with up to 4 address parameters. *
194 * This functions calls the JIT-compiler which eventually translates the *
195 * method into machine code. *
198 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
199 * u4 count, u4 size, void *callblock); *
201 *******************************************************************************/
204 .ascii "calljavafunction2\0\0"
207 .long 0 /* catch type all */
208 .long calljava_xhandler2 /* handler pc */
209 .long calljava_xhandler2 /* end pc */
210 .long asm_calljavafunction2 /* start pc */
211 .long 1 /* extable size */
212 .long 0 /* line number table start */
213 .long 0 /* line number table size */
214 .long 0 /* fltsave */
215 .long 0 /* intsave */
218 .long 32 /* frame size */
219 .long 0 /* method pointer (pointer to name) */
221 asm_calljavafunction2:
222 asm_calljavafunction2double:
223 asm_calljavafunction2long:
225 mov %esp,%ebp /* save stackptr */
227 push %ebx /* save registers */
231 mov 20(%ebp),%eax /* pointer to arg block */
232 mov 12(%ebp),%ecx /* arg count */
233 test %ecx,%ecx /* maybe we have no args */
234 jle calljava_copydone
236 mov %ecx,%edx /* calculate stack size */
238 mov %edx,%esi /* save in callee saved register */
239 sub %esi,%esp /* stack frame for arguments */
243 mov offjniitem(%eax),%edx
245 mov offjniitem+4(%eax),%edx
248 sub $1,%ecx /* are there any args left? */
250 jle calljava_copydone
252 add $sizejniblock,%eax /* goto next argument block */
253 add $8,%edi /* increase sp to next argument */
254 jmp calljava_copyloop
257 mov 8(%ebp),%eax /* move function pointer to %eax */
259 lea asm_call_jit_compiler,%edx
260 call *%edx /* call JIT compiler */
263 add %esi,%esp /* remove arg stack frame */
264 pop %edi /* restore registers */
271 push %eax /* pass exception pointer */
272 call builtin_throw_exception
275 add %esi,%esp /* remove arg stack frame */
276 pop %edi /* restore registers */
283 /****************** function asm_call_jit_compiler *****************************
285 * invokes the compiler for untranslated JavaVM methods. *
287 * Register R0 contains a pointer to the method info structure (prepared *
288 * by createcompilerstub). Using the return address in R26 and the *
289 * offset in the LDA instruction or using the value in methodptr R28 the *
290 * patching address for storing the method address can be computed: *
292 * method address was either loaded using *
294 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
295 * i386_call_reg(REG_ITMP2) *
299 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
300 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
301 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
302 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
303 * i386_call_reg(REG_ITMP1) *
305 * in the static case the method pointer can be computed using the *
306 * return address and the lda function following the jmp instruction *
308 *******************************************************************************/
310 asm_call_jit_compiler:
311 push %ebx /* save register */
314 mov 8(%esp),%ebp /* get return address (2 push) */
315 mov -1(%ebp),%bl /* get function code */
316 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
317 jne L_not_static_special
319 sub $6,%ebp /* calculate address of immediate */
320 jmp L_call_jit_compile
322 L_not_static_special:
323 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
324 jne L_not_virtual_interface
326 sub $6,%ebp /* calculate address of offset */
327 mov (%ebp),%ebp /* get offset */
328 add itmp2,%ebp /* add base address to get method address */
329 jmp L_call_jit_compile
331 L_not_virtual_interface: /* a call from asm_calljavafunction */
335 push %ebp /* save address for method pointer */
337 push %eax /* push methodpointer on stack */
341 pop %ebp /* restore address for method pointer */
343 test %eax,%eax /* check for exception */
346 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
349 mov %eax,(%ebp) /* and now save the new pointer */
352 pop %ebp /* restore registers */
355 jmp *%eax /* ...and now call the new method */
358 pop %ebp /* restore registers */
361 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
362 call builtin_asm_get_exceptionptrptr
364 mov (%ecx),%eax /* get the exception pointer */
365 movl $0,(%ecx) /* clear the exception pointer */
367 lea _exceptionptr,%ecx
368 mov (%ecx),%eax /* get the exception pointer */
369 movl $0,(%ecx) /* clear the exception pointer */
372 pop %ecx /* delete return address */
373 sub $2,%ecx /* faulting address is return adress - 2 */
375 L_refillinStacktrace: /*a compilation error should cause a stacktrace
376 which starts at the method call, which caused
377 the compilation of the new function. Until this
378 point the trace is invalid anyways, since it is
379 not complete. Compared to other runtimes it will
380 not be correct either, since we report eg class
381 not found errors too early, since we always
382 compile methods completely*/
383 push %ecx /* store fault adress */
384 push %eax /* temporarily save exception pointer*/
385 call builtin_asm_get_stackframeinfo
386 push %eax /* save location of thread specific stack info head pointer */
387 mov (%eax),%ecx /* save old value of pointer*/
389 mov %esp,(%eax) /*store pointer to this structure*/
390 mov 8(%esp),%eax /* get the exception pointer again*/
391 movl $0,8(%esp) /*mark this block as native*/
392 push $0 /*used for the jni_callblock structure*/
393 push %eax /*save eax for later */
394 /* get fillInStackTrace method*/
395 push utf_fillInStackTrace_desc
396 push utf_fillInStackTrace_name
397 mov offobjvftbl(%eax),%ecx
398 mov offclass(%ecx),%eax
400 call class_resolvemethod
408 call asm_calljavafunction2
411 /*remove native stack info */
420 jmp asm_handle_exception
423 /********************* function asm_handle_exception ***************************
425 * This function handles an exception. It does not use the usual calling *
426 * conventions. The exception pointer is passed in REG_ITMP1 and the *
427 * pc from the exception raising position is passed in REG_ITMP2. It searches *
428 * the local exception table for a handler. If no one is found, it unwinds *
429 * stacks and continues searching the callers. *
431 * void asm_handle_exception (exceptionptr, exceptionpc); *
433 *******************************************************************************/
435 asm_handle_nat_exception:
436 add $4,%esp /* clear return address of native stub */
438 asm_handle_exception:
439 asm_handle_exception_loop:
443 push %eax /* save exception pointer */
444 push %ecx /* save exception pc */
446 call codegen_findmethod /* get the data segment ptr */
450 mov -8(%ebp),%ecx /* could be changed in findmethod */
452 push %edx /* save data segment pointer */
459 mov %eax,(%esp) /* exception pointer */
460 mov MethodPointer(%edx),%eax /* method pointer */
462 mov %ecx,8(%esp) /* exception pc */
463 movl $0,12(%esp) /* line number */
464 movl $1,16(%esp) /* set no unwind flag */
465 call builtin_trace_exception
467 mov -12(%ebp),%esi /* %esi = data segment pointer */
468 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
469 test %ecx,%ecx /* if empty table skip */
472 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
473 mov -4(%ebp),%eax /* get xptr */
476 mov -8(%ebp),%edx /* get xpc */
478 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
479 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
480 jg ex_table_cont /* if (false) continue */
481 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
482 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
483 jge ex_table_cont /* if (false) continue */
484 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
485 test %ebx,%ebx /* NULL catches everything */
488 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
492 mov %eax,1*4(%esp) /* save not callee saved regs */
495 mov %ebx,0*4(%esp) /* exception class is argument */
504 cmpl $0,offclasslinked(%ebx)
508 mov %eax,1*4(%esp) /* save not callee saved regs */
511 mov %ebx,0*4(%esp) /* exception class is argument */
520 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
528 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
529 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
530 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
531 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
532 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
534 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
536 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
540 cmp %ebx,%esi /* xptr is instanceof catchtype */
544 mov ExHandlerPC(%edi),%edx
546 pop %edi /* restore registers */
549 add $8,%esp /* suck %ecx, %edx */
550 pop %eax /* restore xptr */
553 jmp *%edx /* jump to exception handler */
556 lea ExEntrySize(%edi),%edi
565 pop %edx /* restore data segment pointer */
570 push %eax /* save exception pointer */
573 mov IsSync(%edx),%eax /* %eax = SyncOffset */
574 test %eax,%eax /* if zero no monitorexit */
578 mov -4(%eax),%eax /* we have the xptr on the stack */
579 push %edx /* save regs */
581 call builtin_monitorexit
583 pop %edx /* restore regs */
587 add FrameSize(%edx),%eax /* %eax = frame size */
588 add $4,%eax /* we have the xptr on the stack */
590 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
612 shl $3,%ecx /* multiply by 8 bytes */
616 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
643 pop %eax /* restore exception pointer */
645 mov FrameSize(%edx),%ecx /* %ecx = frame size */
646 add %ecx,%esp /* unwind stack */
648 pop %ecx /* the new xpc is return address */
651 jmp asm_handle_exception_loop
654 /* asm_check_clinit ************************************************************
660 16 ra ; return address of patched call in java machine code
661 12 xmcode ; additional machine code (only for i386 and x86_64)
662 8 mcode ; machine code to patch back in
663 4 class ; pointer to class
664 0 sp ; stack pointer of java stack frame + return address
666 *******************************************************************************/
669 mov 4(%esp),%eax /* get fieldinfo's class pointer */
670 mov offclassinit(%eax),%eax /* get initialized flag */
676 push itmp1 /*return adress into java machine code */
678 push itmp1 /*begin of java stack frame*/
679 pushl $0 /*internal (invisible) method*/
680 call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
681 data onto the stack */
684 mov 20+4+4(%esp),itmp1 /* get class pointer */
685 mov itmp1,(%esp) /* store class pointer as a0 */
686 call class_init /* call class_init function */
689 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
690 into java machine code on stack */
691 add $4,%esp /* ret address no longer needed, is still
692 on stack a few bytes above */
694 test %eax,%eax /* we had an exception */
695 je L_initializererror
698 mov 16(%esp),itmp1 /* get return address */
699 sub $5,itmp1 /* remove size of `call rel32' */
701 mov 12(%esp),itmp2 /* get xmcode machine code */
702 movb itmp2b,(itmp1) /* patch back in 1 byte */
703 mov 8(%esp),itmp2 /* get mcode machine code */
704 mov itmp2,1(itmp1) /* patch back in 4 bytes */
706 add $(5*4),%esp /* remove stub stack frame incl. ra */
708 jmp *itmp1 /* jump to patched code an execute it */
711 add $(4*4),%esp /* remove stub stack frame */
713 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
714 call builtin_asm_get_exceptionptrptr
716 mov (%ecx),%eax /* get the exception pointer */
717 movl $0,(%ecx) /* clear the exception pointer */
719 lea _exceptionptr,%ecx
720 mov (%ecx),%eax /* get the exception pointer */
721 movl $0,(%ecx) /* clear the exception pointer */
724 pop itmp2 /* get and delete ra */
725 sub $5,itmp2 /* faulting address is ra - 5 */
727 jmp asm_handle_exception
730 /********************* function asm_builtin_monitorenter ***********************
732 * Does null check and calls monitorenter or throws an exception *
734 *******************************************************************************/
736 asm_builtin_monitorenter:
738 je nb_monitorenter /* if (null) throw exception */
739 jmp builtin_monitorenter /* else call builtin_monitorenter */
742 mov string_java_lang_NullPointerException,%eax
745 jmp asm_throw_and_handle_exception
748 push string_java_lang_NullPointerException
752 pop %ecx /* delete return address */
753 sub $2,%ecx /* faulting address is return adress - 2 */
754 jmp asm_handle_exception
757 /********************* function asm_builtin_monitorexit ************************
759 * Does null check and calls monitorexit or throws an exception *
761 *******************************************************************************/
763 asm_builtin_monitorexit:
766 je nb_monitorexit /* if (null) throw exception */
767 push %ecx /* save registers which could be used */
770 call builtin_monitorexit /* else call builtin_monitorenter */
772 pop %edx /* restore registers which could be used */
777 mov string_java_lang_NullPointerException,%eax
780 jmp asm_throw_and_handle_exception
783 push string_java_lang_NullPointerException
787 pop %ecx /* delete return address */
788 sub $2,%ecx /* faulting address is return adress - 2 */
789 jmp asm_handle_exception
792 /************************ function asm_builtin_ldiv ****************************
794 * Does null check and calls ldiv or throws an exception *
796 *******************************************************************************/
801 test %eax,%eax /* if (null) throw exception */
809 jmp asm_throw_and_handle_hardware_arithmetic_exception
811 push string_java_lang_ArithmeticException_message
812 push string_java_lang_ArithmeticException
813 call new_exception_message
816 pop %ecx /* delete return address */
817 sub $2,%ecx /* faulting address is return adress - 2 */
818 jmp asm_handle_exception
821 /************************ function asm_builtin_lrem ****************************
823 * Does null check and calls lrem or throws an exception *
825 *******************************************************************************/
830 test %eax,%eax /* if (null) throw exception */
838 jmp asm_throw_and_handle_hardware_arithmetic_exception
840 push string_java_lang_ArithmeticException_message
841 push string_java_lang_ArithmeticException
842 call new_exception_message
845 pop %ecx /* delete return address */
846 sub $2,%ecx /* faulting address is return adress - 2 */
847 jmp asm_handle_exception
850 /************************ function asm_builtin_x2x *****************************
852 * Wrapper functions for corner cases *
854 *******************************************************************************/
885 /******************* function asm_builtin_checkarraycast ***********************
887 * Does the cast check and eventually throws an exception *
889 *******************************************************************************/
891 asm_builtin_checkarraycast:
892 sub $8,%esp /* build stack frame (2 * 4 bytes) */
894 mov 12(%esp),%eax /* 8 (frame) + 4 (return) */
895 mov %eax,(%esp) /* save object pointer */
900 call builtin_checkarraycast /* builtin_checkarraycast */
902 test %eax,%eax /* if (false) throw exception */
905 mov 12(%esp),%eax /* return object pointer */
911 mov string_java_lang_ClassCastException,%eax
914 jmp asm_throw_and_handle_exception
916 push string_java_lang_ClassCastException
922 pop %ecx /* delete return address */
923 sub $2,%ecx /* faulting address is return adress - 2 */
924 jmp asm_handle_exception
927 /******************* function asm_builtin_newarray *****************************
929 * Does the cast check and eventually throws an exception *
931 *******************************************************************************/
933 asm_builtin_newarray:
934 sub $8,%esp /* build stack frame (2 * 4 bytes) */
942 call builtin_newarray
948 /******************* function asm_builtin_aastore ******************************
950 * Does the cast check and eventually throws an exception *
952 *******************************************************************************/
955 sub $12,%esp /* build stack frame (3 * 4 bytes) */
957 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
958 test %eax,%eax /* if null pointer throw exception */
961 mov offarraysize(%eax),%edx /* load size */
962 mov 24(%esp),%ecx /* index */
963 cmp %edx,%ecx /* do bound check */
964 jae nb_aastore_bound /* if out of bounds throw exception */
966 shl $2,%ecx /* index * 4 */
967 add %eax,%ecx /* add index * 4 to arrayref */
969 mov %ecx,8(%esp) /* save store position */
971 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
974 mov 32(%esp),%eax /* object is second argument */
977 call builtin_canstore /* builtin_canstore(arrayref,object) */
979 test %eax,%eax /* if (false) throw exception */
984 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
991 mov string_java_lang_NullPointerException,%eax
994 jmp asm_throw_and_handle_exception
997 push string_java_lang_NullPointerException
1002 pop %ecx /* delete return address */
1003 sub $2,%ecx /* faulting address is return adress - 2 */
1004 jmp asm_handle_exception
1008 mov %ecx,%eax /* itmp2 contains array index */
1009 pushl $0 /*directly below return adress*/
1010 pushl $0 /*internal (invisible) method*/
1011 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1014 call new_arrayindexoutofboundsexception
1017 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
1019 pop %ecx /* delete return address */
1020 sub $2,%ecx /* faulting address is return adress - 2 */
1021 jmp asm_handle_exception
1026 mov string_java_lang_ArrayStoreException,%eax
1029 jmp asm_throw_and_handle_exception
1032 push string_java_lang_ArrayStoreException
1037 pop %ecx /* delete return address */
1038 sub $2,%ecx /* faulting address is return adress - 2 */
1039 jmp asm_handle_exception
1042 /******************* function asm_builtin_arrayinstanceof **********************
1044 * Does the instanceof check of arrays *
1046 *******************************************************************************/
1048 asm_builtin_arrayinstanceof:
1049 sub $8,%esp /* build stack frame (2 * 4 bytes) */
1057 call builtin_arrayinstanceof
1063 /******************* function asm_initialize_thread_stack **********************
1065 * initialized a thread stack *
1066 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1068 *******************************************************************************/
1070 asm_initialize_thread_stack:
1071 mov 8(%esp),%eax /* (to)->stackEnd */
1072 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
1084 mov 4(%esp),%edx /* save (u1*) (func) */
1087 ret /* return restorepoint in %eax */
1090 /******************* function asm_perform_threadswitch *************************
1092 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1094 * performs a threadswitch *
1096 *******************************************************************************/
1098 asm_perform_threadswitch:
1110 mov 36(%esp),%eax /* save current return address */
1113 mov 40(%esp),%eax /* first argument **from */
1116 mov 48(%esp),%eax /* third argument **stackTop */
1119 mov 44(%esp),%eax /* second argument **to */
1120 mov 0(%eax),%esp /* load new stack pointer */
1126 /* skip stack pointer */
1131 add $32,%esp /* leave return address on stack */
1135 /********************* function asm_switchstackandcall *************************
1137 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1140 * Switches to a new stack, calls a function and switches back. *
1141 * a0 new stack pointer *
1142 * a1 function pointer *
1143 * a2 pointer to variable where stack top should be stored *
1144 * a3 pointer to user data, is passed to the function *
1146 *******************************************************************************/
1148 asm_switchstackandcall:
1149 mov 4(%esp),%edx /* first argument *stack */
1150 sub $8,%edx /* allocate new stack */
1152 mov (%esp),%eax /* save return address on new stack */
1155 mov %esp,4(%edx) /* save old stack pointer on new stack */
1157 mov 12(%esp),%eax /* third argument **stacktopsave */
1158 mov %esp,(%eax) /* save old stack pointer to variable */
1160 mov 8(%esp),%eax /* load function pointer */
1161 mov 16(%esp),%ecx /* fourth argument *p */
1163 mov %edx,%esp /* switch to new stack */
1166 mov %ecx,0(%esp) /* pass pointer */
1167 call *%eax /* and call function */
1170 mov (%esp),%edx /* load return address */
1171 mov 4(%esp),%esp /* switch to old stack */
1176 asm_throw_and_handle_exception:
1178 pushl $0 /* the pushed XPC is directly below the java frame*/
1180 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1184 add $4,%esp /*remove parameter*/
1186 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1189 jmp asm_handle_exception
1190 ret /*should never be reached */
1192 asm_throw_and_handle_hardware_arithmetic_exception:
1195 pushl $0 /* the pushed XPC is directly below the java frame*/
1197 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1199 mov string_java_lang_ArithmeticException_message,%eax
1201 mov string_java_lang_ArithmeticException,%eax
1204 call new_exception_message
1205 add $8,%esp /*remove parameters */
1207 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1210 jmp asm_handle_exception
1211 ret /*should never be reached */
1214 /*optimize a littlebit */
1218 call i386_native_stub_debug
1222 mov offclassinit(%eax),%ecx /* get initialized flag */
1224 jnz L_builtin_new_noinit
1226 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1228 /* 2 *4 bytes, the return adress is used directy */
1229 pushl $0 /* the structure is placed directly below the java stackframe*/
1230 pushl $0 /* builtin (invisible) method */
1231 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1233 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1238 call builtin_asm_get_stackframeinfo
1251 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1260 jmp L_builtin_new_patch
1263 L_builtin_new_noinit:
1268 /*jmp L_builtin_new_patch*/
1270 L_builtin_new_patch:
1271 /*add patching code here */
1272 lea builtin_new,%edx
1274 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1282 asm_getclassvalues_atomic:
1284 mov 4(%esp),%ecx /* super */
1285 mov 8(%esp),%edx /* sub */
1287 mov offbaseval(%ecx),%eax
1288 mov offdiffval(%ecx),%ecx
1289 mov offbaseval(%edx),%edx
1292 mov 16(%esp),%ebx /* out */
1293 mov %eax,offcast_super_baseval(%ebx)
1294 mov %ecx,offcast_super_diffval(%ebx)
1295 mov %edx,offcast_sub_baseval(%ebx)
1301 asm_criticalsections:
1302 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1305 .long _crit_restart1
1308 .long _crit_restart2
1314 /************************ function asm_prepare_native_stackinfo ****************************
1316 * creates a stackfame for the begin of a native function (either builtin or not ) *
1317 * expected stack at begin of function *
1319 * address of the jit call which invokes the native *
1320 * begin address of stack frame of the java method *
1321 * method pointer or 0 (for built ins) *
1324 * at end of function: *
1326 * address of the jit call which invokes the native *
1327 * begin address of stack frame of the java method *
1328 * method pointer or 0 (for built ins) *
1329 * address of thread specific top of native list *
1330 * old value of thread specific head *
1334 * This thing is less efficient than the original #define (callerside) *
1335 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1336 ********************************************************************************************/
1339 asm_prepare_native_stackinfo:
1344 lea builtin_asm_get_stackframeinfo,%ecx
1355 #define PREPARE_NATIVE_STACKINFO \
1356 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1357 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1358 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1359 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1360 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1361 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1362 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1363 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1364 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1365 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1366 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1367 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1371 /************************ function asm_remove _native_stackinfo *******************************************
1373 * creates a stackfame for the begin of a native function (either builtin or not) *
1374 * expected stack at begin of function *
1375 * address of the jit call which invokes the native *
1376 * begin address of stack frame of the java method *
1377 * method pointer or 0 (for built ins) *
1378 * address thread specific top of native list *
1379 * old value of thread specific head *
1382 * at end of function: *
1384 * return adresss of the jit call which invokes the native *
1387 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1390 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1391 ***********************************************************************************************************/
1393 asm_remove_native_stackinfo:
1403 #define REMOVE_NATIVE_STACKINFO \
1404 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1405 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1406 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1407 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1414 * These are local overrides for various environment variables in Emacs.
1415 * Please do not remove this and leave it at the end of the file, where
1416 * Emacs will automagically detect them.
1417 * ---------------------------------------------------------------------
1420 * indent-tabs-mode: t