1 /* src/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 2374 2005-04-25 14:13:56Z twisti $
39 #include "vm/jit/i386/offsets.h"
40 #include "vm/jit/i386/asmoffsets.h"
43 /* define it like the risc way */
62 /********************* exported functions and variables ***********************/
64 .globl asm_calljavafunction
65 .globl asm_calljavafunction_int
67 .globl asm_calljavafunction2
68 .globl asm_calljavafunction2int
69 .globl asm_calljavafunction2long
70 .globl asm_calljavafunction2float
71 .globl asm_calljavafunction2double
73 .globl asm_call_jit_compiler
74 .globl asm_handle_builtin_exception
75 .globl asm_handle_nat_exception
76 .globl asm_handle_exception
78 .globl asm_wrapper_patcher
80 .globl asm_builtin_checkarraycast
81 .globl asm_builtin_aastore
83 .globl asm_builtin_ldiv
84 .globl asm_builtin_lrem
86 .globl asm_builtin_f2i
87 .globl asm_builtin_f2l
88 .globl asm_builtin_d2i
89 .globl asm_builtin_d2l
91 .globl asm_perform_threadswitch
92 .globl asm_initialize_thread_stack
93 .globl asm_switchstackandcall
94 .globl asm_getcallingmethod
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 *******************************************************************************/
122 .long 0 /* catch type all */
123 .long calljava_xhandler /* handler pc */
124 .long calljava_xhandler /* end pc */
125 .long asm_calljavafunction /* start pc */
126 .long 1 /* extable size */
127 .long 0 /* line number table start */
128 .long 0 /* line number table size */
129 .long 0 /* fltsave */
130 .long 0 /* intsave */
133 .long 32 /* frame size */
134 .long 0 /* method pointer (pointer to name) */
136 asm_calljavafunction:
137 asm_calljavafunction_int:
138 push %ebp /* allocate stack space */
141 push %ebx /* save registers */
146 sub $16,%esp /* 4 adress parameters * 4 Bytes */
147 mov 24(%ebp),%eax /* copy adress parameters to new block */
159 mov 8(%ebp),%eax /* move function pointer to %eax */
161 lea asm_call_jit_compiler,%edx
162 call *%edx /* call JIT compiler */
165 pop %edi /* restore registers */
172 push %eax /* pass exception pointer */
173 call builtin_throw_exception
177 pop %edi /* restore registers */
181 xor %eax,%eax /* return NULL */
185 /********************* function asm_calljavafunction ***************************
187 * This function calls a Java-method (which possibly needs compilation) *
188 * with up to 4 address parameters. *
190 * This functions calls the JIT-compiler which eventually translates the *
191 * method into machine code. *
194 * javaobject_header *asm_calljavafunction2(methodinfo *m, *
195 * u4 count, u4 size, void *callblock); *
197 *******************************************************************************/
202 .long 0 /* catch type all */
203 .long calljava_xhandler2 /* handler pc */
204 .long calljava_xhandler2 /* end pc */
205 .long asm_calljavafunction2 /* start pc */
206 .long 1 /* extable size */
207 .long 0 /* line number table start */
208 .long 0 /* line number table size */
209 .long 0 /* fltsave */
210 .long 0 /* intsave */
213 .long 32 /* frame size */
214 .long 0 /* method pointer (pointer to name) */
216 asm_calljavafunction2:
217 asm_calljavafunction2int:
218 asm_calljavafunction2long:
219 asm_calljavafunction2float:
220 asm_calljavafunction2double:
222 mov %esp,%ebp /* save stackptr */
224 push %ebx /* save registers */
228 mov 20(%ebp),%eax /* pointer to arg block (4(push)+4(return)+4+4+4)*/
229 mov 12(%ebp),%ecx /* arg count (4(push)+4(return)+4 */
230 test %ecx,%ecx /* maybe we have no args */
231 jle calljava_copydone
233 mov %ecx,%edx /* calculate stack size */
235 mov %eax,%edi /* save pointer to arg block */
236 calljava_calcstacksize:
237 mov offjniitemtype(%eax),%ebx
238 test $1,%ebx /* Two Word Type? */
239 jz calljava_onewordtype
241 calljava_onewordtype:
244 test %edx,%edx /* any args left ?*/
246 add $sizejniblock,%eax /* goto next argument block */
247 jmp calljava_calcstacksize
250 mov %edi,%eax /* restore pointer to arg block */
251 sub %esi,%esp /* stack frame for arguments */
255 mov offjniitem(%eax),%edx /* copy 4 Byte of Argument */
257 add $4,%edi /* increase sp to next argument */
258 mov offjniitemtype(%eax),%ebx /* type -> ebx */
259 test $1,%ebx /* Two Word Type? */
261 mov offjniitem+4(%eax),%edx /* copy upper 4 Byte of 2 Word Type */
263 add $4,%edi /* increase sp to next argument */
265 sub $1,%ecx /* are there any args left? */
267 jle calljava_copydone
269 add $sizejniblock,%eax /* goto next argument block */
270 jmp calljava_copyloop
273 mov 8(%ebp),%eax /* move function pointer to %eax */
275 lea asm_call_jit_compiler,%edx
276 call *%edx /* call JIT compiler */
279 add %esi,%esp /* remove arg stack frame */
280 pop %edi /* restore registers */
287 push %eax /* pass exception pointer */
288 call builtin_throw_exception
291 add %esi,%esp /* remove arg stack frame */
292 pop %edi /* restore registers */
296 xor %eax,%eax /* return NULL */
300 /****************** function asm_call_jit_compiler *****************************
302 * invokes the compiler for untranslated JavaVM methods. *
304 * Register R0 contains a pointer to the method info structure (prepared *
305 * by createcompilerstub). Using the return address in R26 and the *
306 * offset in the LDA instruction or using the value in methodptr R28 the *
307 * patching address for storing the method address can be computed: *
309 * method address was either loaded using *
311 * i386_mov_imm_reg(a, REG_ITMP2) ; invokestatic/special *
312 * i386_call_reg(REG_ITMP2) *
316 * i386_mov_membase_reg(REG_SP, 0, REG_ITMP1) ; invokevirtual/interface *
317 * i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2) *
318 * i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \ *
319 * sizeof(methodptr) * m->vftblindex, REG_ITMP1) *
320 * i386_call_reg(REG_ITMP1) *
322 * in the static case the method pointer can be computed using the *
323 * return address and the lda function following the jmp instruction *
325 *******************************************************************************/
327 asm_call_jit_compiler:
328 push %ebx /* save register */
331 mov 2*4(%esp),%ebp /* get return address (2 push) */
332 mov -1(%ebp),%bl /* get function code */
333 cmp $0xd1,%bl /* called with `call *REG_ITMP2' (%ecx)? */
334 jne L_not_static_special
336 sub $6,%ebp /* calculate address of immediate */
337 jmp L_call_jit_compile
339 L_not_static_special:
340 cmp $0xd0,%bl /* called with `call *REG_ITMP1' (%eax) */
341 jne L_not_virtual_interface
343 sub $6,%ebp /* calculate address of offset */
344 mov (%ebp),%ebp /* get offset */
345 add itmp2,%ebp /* add base address to get method address */
346 jmp L_call_jit_compile
348 L_not_virtual_interface: /* a call from asm_calljavafunction */
352 push %ebp /* save address for method pointer */
354 push %eax /* push methodpointer on stack */
358 pop %ebp /* restore address for method pointer */
360 test %eax,%eax /* check for exception */
361 je L_asm_call_jit_compiler_exception
363 test %ebp,%ebp /* is address == 0 (asm_calljavafunction) */
366 mov %eax,(%ebp) /* and now save the new pointer */
369 pop %ebp /* restore registers */
372 jmp *%eax /* ...and now call the new method */
374 L_asm_call_jit_compiler_exception:
375 pop %ebp /* restore registers */
378 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
379 call builtin_asm_get_exceptionptrptr
382 lea _exceptionptr,%ecx
384 mov (%ecx),%eax /* get the exception pointer */
385 movl $0,(%ecx) /* clear the exception pointer */
387 pop %ecx /* delete return address */
388 sub $2,%ecx /* faulting address is return adress - 2 */
390 L_refillinStacktrace: /*a compilation error should cause a stacktrace
391 which starts at the method call, which caused
392 the compilation of the new function. Until this
393 point the trace is invalid anyways, since it is
394 not complete. Compared to other runtimes it will
395 not be correct either, since we report eg class
396 not found errors too early, since we always
397 compile methods completely. The native info
398 should be moved around the jit call to get
399 a more compliant trace for the "exception in
401 push %ecx /* store fault adress */
402 push %eax /* temporarily save exception pointer*/
403 push $0 /* internal function */
404 call builtin_asm_get_stackframeinfo
405 push %eax /* save location of thread specific stack info head pointer */
406 mov (%eax),%ecx /* save old value of pointer*/
408 mov %esp,(%eax) /*store pointer to this structure*/
409 mov 12(%esp),%eax /* get the exception pointer again*/
410 movl $0,12(%esp) /*java stack begins just above structure*/
411 push $0 /*used for the jni_callblock structure*/
412 push %eax /*save eax for later */
413 /* get fillInStackTrace method*/
414 push utf_void__java_lang_Throwable
415 push utf_fillInStackTrace
416 mov offobjvftbl(%eax),%ecx
417 mov offclass(%ecx),%eax
419 call class_resolvemethod
427 call asm_calljavafunction2
430 /*remove native stack info */
439 jmp asm_handle_exception
442 /********************* function asm_handle_exception ***************************
444 * This function handles an exception. It does not use the usual calling *
445 * conventions. The exception pointer is passed in REG_ITMP1 and the *
446 * pc from the exception raising position is passed in REG_ITMP2. It searches *
447 * the local exception table for a handler. If no one is found, it unwinds *
448 * stacks and continues searching the callers. *
450 * void asm_handle_exception (exceptionptr, exceptionpc); *
452 *******************************************************************************/
454 asm_handle_nat_exception:
455 add $4,%esp /* clear return address of native stub */
457 asm_handle_exception:
458 asm_handle_exception_loop:
462 push %eax /* save exception pointer */
463 push %ecx /* save exception pc */
465 call codegen_findmethod /* get the data segment ptr */
469 mov -8(%ebp),%ecx /* could be changed in findmethod */
471 push %edx /* save data segment pointer */
478 mov %eax,(%esp) /* exception pointer */
479 mov MethodPointer(%edx),%eax /* method pointer */
481 mov %ecx,8(%esp) /* exception pc */
482 movl $0,12(%esp) /* line number */
483 movl $1,16(%esp) /* set no unwind flag */
484 call builtin_trace_exception
486 mov -12(%ebp),%esi /* %esi = data segment pointer */
487 mov ExTableSize(%esi),%ecx /* %ecx = exception table size */
488 test %ecx,%ecx /* if empty table skip */
491 lea ExTableStart(%esi),%edi /* %edi = start of exception table*/
492 mov -4(%ebp),%eax /* get xptr */
495 mov -8(%ebp),%edx /* get xpc */
497 mov ExStartPC(%edi),%ebx /* %ebx = exception start pc */
498 cmp %edx,%ebx /* %ebx = (startpc <= xpc) */
499 jg ex_table_cont /* if (false) continue */
500 mov ExEndPC(%edi),%ebx /* %ebx = exception end pc */
501 cmp %ebx,%edx /* %ebx = (xpc < endpc) */
502 jge ex_table_cont /* if (false) continue */
503 mov ExCatchType(%edi),%ebx /* arg1 = exception catch type */
504 test %ebx,%ebx /* NULL catches everything */
507 cmpl $0,offclassloaded(%ebx) /* check if class is loaded */
511 mov %eax,1*4(%esp) /* save not callee saved regs */
514 mov %ebx,0*4(%esp) /* exception class is argument */
515 call load_class_bootstrap
523 cmpl $0,offclasslinked(%ebx)
527 mov %eax,1*4(%esp) /* save not callee saved regs */
530 mov %ebx,0*4(%esp) /* exception class is argument */
539 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
547 mov offobjvftbl(%eax),%esi /* %esi = vftblptr(xptr) */
548 mov offclassvftbl(%ebx),%ebx /* %ebx = vftblptr(catchtype) class (not obj) */
549 mov offbaseval(%esi),%esi /* %esi = baseval(xptr) */
550 mov offbaseval(%ebx),%edx /* %edx = baseval(catchtype) */
551 mov offdiffval(%ebx),%ebx /* %ebx = diffval(catchtype) */
553 sub %edx,%esi /* %esi = baseval(xptr) - baseval(catchtype) */
555 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
559 cmp %ebx,%esi /* xptr is instanceof catchtype */
563 mov ExHandlerPC(%edi),%edx
565 pop %edi /* restore registers */
568 add $8,%esp /* suck %ecx, %edx */
569 pop %eax /* restore xptr */
572 jmp *%edx /* jump to exception handler */
575 lea ExEntrySize(%edi),%edi
584 pop %edx /* restore data segment pointer */
589 push %eax /* save exception pointer */
592 mov IsSync(%edx),%eax /* %eax = SyncOffset */
593 test %eax,%eax /* if zero no monitorexit */
596 #if defined(USE_THREADS)
598 mov (%eax),%eax /* we have the xptr on the stack (+4-4=0) */
599 push %edx /* save regs */
601 call builtin_monitorexit
603 pop %edx /* restore regs */
608 add FrameSize(%edx),%eax /* %eax = frame size */
609 add $4,%eax /* we have the xptr on the stack */
611 mov IntSave(%edx),%ecx /* %ecx = saved int register count*/
633 shl $2,%ecx /* multiply by 4 bytes */
637 mov FltSave(%edx),%ecx /* %ecx = saved flt register count */
664 pop %eax /* restore exception pointer */
666 mov FrameSize(%edx),%ecx /* %ecx = frame size */
667 add %ecx,%esp /* unwind stack */
669 pop %ecx /* the new xpc is return address */
670 sub $2,%ecx /* -2 -> call */
672 jmp asm_handle_exception_loop
675 /* asm_wrapper_patcher *********************************************************
681 12 last byte of machine code (xmcode)
682 8 machine code (which is patched back later)
683 4 unresolved field reference
684 0 patcher function pointer to call
686 *******************************************************************************/
689 sub $(2*4),%esp /* create stack frame */
691 mov itmp1,0*4(%esp) /* save itmp1 and itmp2 */
692 mov itmp2,1*4(%esp) /* may be used by some instructions */
696 mov 3*4(%esp),itmp1 /* return adress into java code */
697 mov %esp,itmp2 /* begin of java stack frame */
701 pushl $0 /* internal (invisible) method */
702 call asm_prepare_native_stackinfo /* puts additional 2 *4 bytes of
703 data onto the stack */
706 mov %esp,itmp1 /* pass stack pointer */
707 add $(3*4),itmp1 /* also skip patcher function pointer */
709 mov 3*4(%esp),itmp1 /* get function pointer from stack */
710 call *itmp1 /* call the patcher function */
712 mov v0,itmp3 /* save return value */
715 call asm_remove_native_stackinfo /* removes 4* 4 bytes and leaves ret
716 into java machine code on stack */
717 add $4,%esp /* ret address no longer needed, is still
718 on stack a few bytes above */
721 mov 0*4(%esp),itmp1 /* restore itmp1 and itmp2 */
722 mov 1*4(%esp),itmp2 /* may be used by some instructions */
724 add $((4+2)*4),%esp /* remove stack frame, keep ra */
725 test itmp3,itmp3 /* exception thrown? */
726 jz L_asm_wrapper_patcher_exception
727 ret /* call new patched code */
729 L_asm_wrapper_patcher_exception:
730 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
731 call builtin_asm_get_exceptionptrptr
734 lea _exceptionptr,itmp2
736 mov (itmp2),xptr /* get the exception pointer */
737 movl $0,(itmp2) /* clear the exception pointer */
739 pop xpc /* get and remove return address */
740 jmp asm_handle_exception
743 /************************ function asm_builtin_ldiv ****************************
745 * Does null check and calls ldiv or throws an exception *
747 *******************************************************************************/
752 test %eax,%eax /* if (null) throw exception */
760 jmp asm_throw_and_handle_hardware_arithmetic_exception
762 push string_java_lang_ArithmeticException_message
763 push string_java_lang_ArithmeticException
764 call new_exception_message
767 pop %ecx /* delete return address */
768 sub $2,%ecx /* faulting address is return adress - 2 */
769 jmp asm_handle_exception
772 /************************ function asm_builtin_lrem ****************************
774 * Does null check and calls lrem or throws an exception *
776 *******************************************************************************/
781 test %eax,%eax /* if (null) throw exception */
789 jmp asm_throw_and_handle_hardware_arithmetic_exception
791 push string_java_lang_ArithmeticException_message
792 push string_java_lang_ArithmeticException
793 call new_exception_message
796 pop %ecx /* delete return address */
797 sub $2,%ecx /* faulting address is return adress - 2 */
798 jmp asm_handle_exception
801 /************************ function asm_builtin_x2x *****************************
803 * Wrapper functions for corner cases *
805 *******************************************************************************/
836 /******************* function asm_builtin_checkarraycast ***********************
838 * Does the cast check and eventually throws an exception *
840 *******************************************************************************/
842 asm_builtin_checkarraycast:
843 sub $8,%esp /* build stack frame (2 * 4 bytes) */
845 mov 12(%esp),%eax /* first param: 8 (frame) + 4 (return)*/
846 mov %eax,(%esp) /* save object pointer */
848 mov 16(%esp),%eax /* second param: 8 (frame) + 4 (return) + 4*/
851 call builtin_checkarraycast /* builtin_checkarraycast */
853 test %eax,%eax /* if (false) throw exception */
856 mov 12(%esp),%eax /* return object pointer */
862 mov string_java_lang_ClassCastException,%eax
865 jmp asm_throw_and_handle_exception
867 push string_java_lang_ClassCastException
873 pop %ecx /* delete return address */
874 sub $2,%ecx /* faulting address is return adress - 2 */
875 jmp asm_handle_exception
879 /******************* function asm_builtin_aastore ******************************
881 * Does the cast check and eventually throws an exception *
882 * void asm_builtin_aastore(java_objectarray *a, s4 index, java_objectheader *o)*
883 *******************************************************************************/
886 sub $12,%esp /* build stack frame (3 * 4 bytes) */
888 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
889 test %eax,%eax /* if null pointer throw exception */
892 mov offarraysize(%eax),%edx /* load size */
893 mov 20(%esp),%ecx /* index (12 + 4 + 4) */
894 cmp %edx,%ecx /* do bound check */
895 jae nb_aastore_bound /* if out of bounds throw exception */
897 shl $2,%ecx /* index * 4 */
898 add %eax,%ecx /* add index * 4 to arrayref */
900 mov %ecx,8(%esp) /* save store position */
902 mov 16(%esp),%eax /* 12 (frame) + 4 (return) */
905 mov 24(%esp),%eax /* object is second argument (12+4+4+4) */
908 call builtin_canstore /* builtin_canstore(arrayref,object) */
910 test %eax,%eax /* if (false) throw exception */
915 mov %eax,offobjarrdata(%ecx) /* store objectptr in array */
922 mov string_java_lang_NullPointerException,%eax
925 jmp asm_throw_and_handle_exception
928 push string_java_lang_NullPointerException
933 pop %ecx /* delete return address */
934 sub $2,%ecx /* faulting address is return adress - 2 */
935 jmp asm_handle_exception
939 mov %ecx,%eax /* itmp2 contains array index */
940 pushl $0 /*directly below return adress*/
941 pushl $0 /*internal (invisible) method*/
942 call asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
945 call new_arrayindexoutofboundsexception
948 call asm_remove_native_stackinfo /*return adress is the first on stack again*/
950 pop %ecx /* delete return address */
951 sub $2,%ecx /* faulting address is return adress - 2 */
952 jmp asm_handle_exception
957 mov string_java_lang_ArrayStoreException,%eax
960 jmp asm_throw_and_handle_exception
963 push string_java_lang_ArrayStoreException
968 pop %ecx /* delete return address */
969 sub $2,%ecx /* faulting address is return adress - 2 */
970 jmp asm_handle_exception
974 /******************* function asm_initialize_thread_stack **********************
976 * initialized a thread stack *
977 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
979 *******************************************************************************/
981 asm_initialize_thread_stack:
982 mov 8(%esp),%eax /* (to)->stackEnd */
983 sub $36,%eax /* 4 bytes * 8 regs + 4 bytes func */
995 mov 4(%esp),%edx /* save (u1*) (func) */
998 ret /* return restorepoint in %eax */
1001 /******************* function asm_perform_threadswitch *************************
1003 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1005 * performs a threadswitch *
1007 *******************************************************************************/
1009 asm_perform_threadswitch:
1021 mov 36(%esp),%eax /* save current return address */
1024 mov 40(%esp),%eax /* first argument **from */
1027 mov 48(%esp),%eax /* third argument **stackTop */
1030 mov 44(%esp),%eax /* second argument **to */
1031 mov 0(%eax),%esp /* load new stack pointer */
1037 /* skip stack pointer */
1042 add $32,%esp /* leave return address on stack */
1046 /********************* function asm_switchstackandcall *************************
1048 * int asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1051 * Switches to a new stack, calls a function and switches back. *
1052 * a0 new stack pointer *
1053 * a1 function pointer *
1054 * a2 pointer to variable where stack top should be stored *
1055 * a3 pointer to user data, is passed to the function *
1057 *******************************************************************************/
1059 asm_switchstackandcall:
1060 mov 4(%esp),%edx /* first argument *stack */
1061 sub $8,%edx /* allocate new stack */
1063 mov (%esp),%eax /* save return address on new stack */
1066 mov %esp,4(%edx) /* save old stack pointer on new stack */
1068 mov 12(%esp),%eax /* third argument **stacktopsave */
1069 mov %esp,(%eax) /* save old stack pointer to variable */
1071 mov 8(%esp),%eax /* load function pointer */
1072 mov 16(%esp),%ecx /* fourth argument *p */
1074 mov %edx,%esp /* switch to new stack */
1077 mov %ecx,0(%esp) /* pass pointer */
1078 call *%eax /* and call function */
1081 mov (%esp),%edx /* load return address */
1082 mov 4(%esp),%esp /* switch to old stack */
1087 asm_throw_and_handle_exception:
1089 pushl $0 /* the pushed XPC is directly below the java frame*/
1091 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1095 add $4,%esp /*remove parameter*/
1097 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1100 jmp asm_handle_exception
1101 ret /*should never be reached */
1103 asm_throw_and_handle_hardware_arithmetic_exception:
1106 pushl $0 /* the pushed XPC is directly below the java frame*/
1108 call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1110 mov string_java_lang_ArithmeticException_message,%eax
1112 mov string_java_lang_ArithmeticException,%eax
1115 call new_exception_message
1116 add $8,%esp /*remove parameters */
1118 call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1121 jmp asm_handle_exception
1122 ret /*should never be reached */
1125 /*optimize a littlebit */
1129 call i386_native_stub_debug
1133 mov offclassinit(%eax),%ecx /* get initialized flag */
1135 jnz L_builtin_new_noinit
1137 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1139 /* 2 *4 bytes, the return adress is used directy */
1140 pushl $0 /* the structure is placed directly below the java stackframe*/
1141 pushl $0 /* builtin (invisible) method */
1142 call asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1144 sub $16,%esp /* build stack frame (4 * 4 bytes) */
1149 call builtin_asm_get_stackframeinfo
1162 call asm_remove_native_stackinfo /*first element on stack is return adress again*/
1171 jmp L_builtin_new_patch
1174 L_builtin_new_noinit:
1179 /*jmp L_builtin_new_patch*/
1181 L_builtin_new_patch:
1182 /*add patching code here */
1183 lea builtin_new,%edx
1185 mov %edx,-6(%ecx) /*patch calling instruction, t directly call builtin_new the next time*/
1193 asm_getclassvalues_atomic:
1195 mov 4(%esp),%ecx /* super */
1196 mov 8(%esp),%edx /* sub */
1198 mov offbaseval(%ecx),%eax
1199 mov offdiffval(%ecx),%ecx
1200 mov offbaseval(%edx),%edx
1203 mov 16(%esp),%ebx /* out */
1204 mov %eax,offcast_super_baseval(%ebx)
1205 mov %ecx,offcast_super_diffval(%ebx)
1206 mov %edx,offcast_sub_baseval(%ebx)
1212 asm_criticalsections:
1213 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1216 .long _crit_restart1
1219 .long _crit_restart2
1225 /************************ function asm_prepare_native_stackinfo ****************************
1227 * creates a stackfame for the begin of a native function (either builtin or not ) *
1228 * expected stack at begin of function *
1230 * address of the jit call which invokes the native *
1231 * begin address of stack frame of the java method *
1232 * method pointer or 0 (for built ins) *
1235 * at end of function: *
1237 * address of the jit call which invokes the native *
1238 * begin address of stack frame of the java method *
1239 * method pointer or 0 (for built ins) *
1240 * address of thread specific top of native list *
1241 * old value of thread specific head *
1245 * This thing is less efficient than the original #define (callerside) *
1246 * destroyes REG_ITMP2, keeps REG_ITMP1 *
1247 ********************************************************************************************/
1250 asm_prepare_native_stackinfo:
1255 lea builtin_asm_get_stackframeinfo,%ecx
1266 #define PREPARE_NATIVE_STACKINFO \
1267 i386_push_reg(cd, REG_ITMP1); /*save itmp1, needed by some stubs */ \
1268 i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1269 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1270 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/ \
1271 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1272 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/ \
1273 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/ \
1274 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1275 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */ \
1276 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1277 i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1278 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
1282 /************************ function asm_remove _native_stackinfo *******************************************
1284 * creates a stackfame for the begin of a native function (either builtin or not) *
1285 * expected stack at begin of function *
1286 * address of the jit call which invokes the native *
1287 * begin address of stack frame of the java method *
1288 * method pointer or 0 (for built ins) *
1289 * address thread specific top of native list *
1290 * old value of thread specific head *
1293 * at end of function: *
1295 * return adresss of the jit call which invokes the native *
1298 * REG_ITMP2_XPC = address of the jit call which invokes the native *
1301 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1 *
1302 ***********************************************************************************************************/
1304 asm_remove_native_stackinfo:
1314 #define REMOVE_NATIVE_STACKINFO \
1315 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1316 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1317 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1318 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1325 * These are local overrides for various environment variables in Emacs.
1326 * Please do not remove this and leave it at the end of the file, where
1327 * Emacs will automagically detect them.
1328 * ---------------------------------------------------------------------
1331 * indent-tabs-mode: t