* Implemented new stacktrace system
authortwisti <none@none>
Sun, 10 Jul 2005 15:33:54 +0000 (15:33 +0000)
committertwisti <none@none>
Sun, 10 Jul 2005 15:33:54 +0000 (15:33 +0000)
* Implemented remaining asmpart functions inline

src/vm/jit/i386/asmpart.S
src/vm/jit/i386/codegen.c
src/vm/jit/i386/codegen.h
src/vm/jit/i386/linux/md-os.c
src/vm/jit/i386/patcher.c

index 907f122267d5e25f35a95bc859c096e784ae6d20..b684fdaced86caa8e2bfd392cdc355f2de6f63bc 100644 (file)
@@ -30,7 +30,7 @@
 
    Changes: Joseph Wenninger
 
-   $Id: asmpart.S 2947 2005-07-09 12:17:14Z twisti $
+   $Id: asmpart.S 2971 2005-07-10 15:33:54Z twisti $
 
 */
 
@@ -44,6 +44,8 @@
 
 #define v0       %eax
 
+#define sp       %esp
+
 #define itmp1    %eax
 #define itmp2    %ecx
 #define itmp3    %edx
        .globl asm_calljavafunction2double
 
        .globl asm_call_jit_compiler
-       .globl asm_handle_builtin_exception
        .globl asm_handle_nat_exception
        .globl asm_handle_exception
 
        .globl asm_wrapper_patcher
 
-       .globl asm_builtin_arraycheckcast
-       .globl asm_builtin_aastore
-
-       .globl asm_builtin_ldiv
-       .globl asm_builtin_lrem
-
        .globl asm_builtin_f2i
        .globl asm_builtin_f2l
        .globl asm_builtin_d2i
        .globl asm_perform_threadswitch
        .globl asm_initialize_thread_stack
        .globl asm_switchstackandcall
-       .globl asm_getcallingmethod
        .globl asm_criticalsections
        .globl asm_getclassvalues_atomic
 
-       .globl asm_throw_and_handle_exception
-       .globl asm_throw_and_handle_hardware_arithmetic_exception
-
-       .globl asm_prepare_native_stackinfo
-       .globl asm_remove_native_stackinfo
-
 
 /********************* function asm_calljavafunction ***************************
 *                                                                              *
@@ -377,65 +365,41 @@ L_asm_call_jit_compiler_exception:
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
        call    builtin_asm_get_exceptionptrptr
-       mov     %eax,%ecx
+       mov     v0,itmp2
 #else
-       lea     _exceptionptr,%ecx
+       lea     _exceptionptr,itmp2
 #endif
-       mov     (%ecx),%eax         /* get the exception pointer                  */
-       movl    $0,(%ecx)           /* clear the exception pointer                */
-
-       pop     %ecx                /* delete return address                      */
-       sub     $2,%ecx             /* faulting address is return adress - 2      */
-
-L_refillinStacktrace:               /*a compilation error should cause a stacktrace
-                                    which starts at the method call, which caused
-                                    the compilation of the new function. Until this
-                                    point the trace is invalid anyways, since it is
-                                    not complete. Compared to other runtimes it will
-                                    not be correct either, since we report eg class
-                                    not found errors too early, since we always
-                                    compile methods completely. The native info
-                                    should be moved around the jit call to get
-                                    a more compliant trace for the "exception in
-                                    initializer" case*/
-       push %ecx               /* store fault adress */
-       push %eax               /* temporarily save exception pointer*/
-       push $0                 /* internal function */
-       call builtin_asm_get_stackframeinfo
-       push %eax       /* save location of thread specific stack info head pointer */
-       mov (%eax),%ecx /* save old value of pointer*/
-       push %ecx
-       mov %esp,(%eax) /*store pointer to this structure*/
-       mov 12(%esp),%eax  /* get the exception pointer again*/
-       movl $0,12(%esp) /*java stack begins just above structure*/
-       push $0 /*used for the jni_callblock structure*/
-       push %eax /*save eax for later */
-       /* get fillInStackTrace method*/
-       push utf_void__java_lang_Throwable
-       push utf_fillInStackTrace
-       mov offobjvftbl(%eax),%ecx
-       mov offclass(%ecx),%eax
-       push %eax
-       call class_resolvemethod
-       add $12,%esp
-       push $0
-       push $4 /*TYPE_ADR*/
-       push %esp
-       push $sizejniblock
-       push $1
-       push %eax
-       call asm_calljavafunction2
-       add $24,%esp
-
-       /*remove native stack info */
-       mov 8(%esp),%ecx
-       mov 12(%esp),%eax
-       mov %ecx,(%eax)
-       mov (%esp),%eax
-       add $24,%esp
-       pop %ecx
-
+       mov     (itmp2),xptr        /* get the exception pointer                  */
+       movl    $0,(itmp2)          /* clear the exception pointer                */
+
+       sub     $(5*4+sizestackframeinfo),sp
+       mov     xptr,4*4(sp)                /* save exception pointer             */
+
+       mov     sp,itmp1                    /* create stackframe info             */
+       add     $(5*4),itmp1
+       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
+       movl    $0,1*4(sp)                  /* if pv is NULL, use findmethod      */
+       mov     sp,itmp2
+       add     $(6*4+sizestackframeinfo),itmp2
+       mov     itmp2,2*4(sp)
+       mov     (5*4+sizestackframeinfo)(sp),itmp3
+       mov     itmp3,3*4(sp)
+       call    stacktrace_create_inline_stackframeinfo
+
+       mov     4*4(sp),itmp1               /* fill in stacktrace                 */
+       mov     itmp1,0*4(sp)
+       call    stacktrace_call_fillInStackTrace
        
+       mov     sp,itmp1                    /* remove stackframe info             */
+       add     $(5*4),itmp1
+       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
+       call    stacktrace_remove_stackframeinfo
+
+       mov     4*4(sp),xptr                /* restore exception pointer          */
+       add     $(5*4+sizestackframeinfo),sp
+
+       pop     xpc                 /* delete return address                      */
+       sub     $2,xpc              /* faulting address is return adress - 2      */
        jmp     asm_handle_exception
 
 
@@ -687,42 +651,39 @@ noflt:
 *******************************************************************************/
 
 asm_wrapper_patcher:
-       sub     $(2*4),%esp                 /* create stack frame                 */
-
-       mov     itmp1,0*4(%esp)             /* save itmp1 and itmp2               */
-       mov     itmp2,1*4(%esp)             /* may be used by some instructions   */
-
-#if 0
-       /* 3*4 bytes */
-       mov     3*4(%esp),itmp1             /* return adress into java code       */
-       mov     %esp,itmp2                  /* begin of java stack frame          */
-       add     $(3*4),itmp2
-       push    itmp1
-       push    itmp2
-       pushl   $0                          /* internal (invisible) method        */
-       call    asm_prepare_native_stackinfo /* puts additional 2 *4 bytes of
-                                               data onto the stack */
-#endif
-
-       mov     %esp,itmp1                  /* pass stack pointer                 */
-       add     $(3*4),itmp1                /* also skip patcher function pointer */
-       push    itmp1
-       mov     3*4(%esp),itmp1             /* get function pointer from stack    */
+       sub     $((2+4)*4+sizestackframeinfo),sp /* create stack frame            */
+
+       mov     itmp1,(0+4)*4(sp)           /* save itmp1 and itmp2               */
+       mov     itmp2,(1+4)*4(sp)           /* may be used by some instructions   */
+
+       mov     sp,itmp1                    /* create stackframe info             */
+       add     $((2+4)*4),itmp1
+       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
+       movl    $0,1*4(sp)                  /* if pv is NULL, use findmethod      */
+       mov     sp,itmp2
+       add     $((6+2+4)*4+sizestackframeinfo),itmp2
+       mov     itmp2,2*4(sp)
+       mov     ((5+2+4)*4+sizestackframeinfo)(sp),itmp3
+       mov     itmp3,3*4(sp)
+       call    stacktrace_create_inline_stackframeinfo
+
+       mov     sp,itmp1                    /* pass stack pointer                 */
+       add     $((1+2+4)*4+sizestackframeinfo),itmp1  /* skip function pointer   */
+       mov     itmp1,0*4(sp)
+       mov     (0+2+4)*4+sizestackframeinfo(sp),itmp1 /* get function pointer    */
        call    *itmp1                      /* call the patcher function          */
-       add     $4,%esp
-       mov     v0,itmp3                    /* save return value                  */
+       mov     v0,1*4(sp)                  /* save return value                  */
 
-#if 0
-       call    asm_remove_native_stackinfo  /* removes 4* 4 bytes and leaves ret
-                                                into java machine code on stack  */
-       add     $4,%esp                   /* ret address no longer needed, is still
-                                               on stack a few bytes above */
-#endif
+       mov     sp,itmp1                    /* remove stackframe info             */
+       add     $((2+4)*4),itmp1
+       mov     itmp1,0*4(sp)               /* stackframeinfo pointer             */
+       call    stacktrace_remove_stackframeinfo
 
-       mov     0*4(%esp),itmp1             /* restore itmp1 and itmp2            */
-       mov     1*4(%esp),itmp2             /* may be used by some instructions   */
+       mov     (0+4)*4(sp),itmp1           /* restore itmp1 and itmp2            */
+       mov     (1+4)*4(sp),itmp2           /* may be used by some instructions   */
+       mov     1*4(sp),itmp3               /* restore return value               */
 
-       add     $((5+2)*4),%esp             /* remove stack frame, keep ra        */
+       add     $((5+2+4)*4+sizestackframeinfo),sp /* remove stack frame, keep ra */
        test    itmp3,itmp3                 /* exception thrown?                  */
        jz      L_asm_wrapper_patcher_exception
        ret                                 /* call new patched code              */
@@ -741,64 +702,6 @@ L_asm_wrapper_patcher_exception:
        jmp     asm_handle_exception
 
 
-/************************ function asm_builtin_ldiv ****************************
-*                                                                              *
-*   Does null check and calls ldiv or throws an exception                      *
-*                                                                              *
-*******************************************************************************/
-
-asm_builtin_ldiv:
-       mov     12(%esp),%eax
-       or      16(%esp),%eax
-       test    %eax,%eax                   /* if (null) throw exception          */
-       je      nb_ldiv
-
-       jmp     builtin_ldiv
-
-nb_ldiv:
-       pop %ecx
-       sub $2,%ecx
-       jmp asm_throw_and_handle_hardware_arithmetic_exception
-#if 0
-       push    string_java_lang_ArithmeticException_message
-       push    string_java_lang_ArithmeticException
-       call    new_exception_message
-       add     $(2*4),%esp
-       
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-#endif                         
-
-/************************ function asm_builtin_lrem ****************************
-*                                                                              *
-*   Does null check and calls lrem or throws an exception                      *
-*                                                                              *
-*******************************************************************************/
-
-asm_builtin_lrem:
-       mov     12(%esp),%eax
-       or      16(%esp),%eax
-       test    %eax,%eax                   /* if (null) throw exception          */
-       je      nb_lrem
-
-       jmp     builtin_lrem
-
-nb_lrem:
-       pop %ecx
-       sub $2,%ecx
-       jmp asm_throw_and_handle_hardware_arithmetic_exception
-#if 0
-       push    string_java_lang_ArithmeticException_message
-       push    string_java_lang_ArithmeticException
-       call    new_exception_message
-       add     $(2*4),%esp
-
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-#endif         
-
 /************************ function asm_builtin_x2x *****************************
 *                                                                              *
 *   Wrapper functions for corner cases                                         *
@@ -834,144 +737,6 @@ asm_builtin_d2l:
        ret
 
 
-/* asm_builtin_arraycheckcast **************************************************
-
-   Does the cast check and eventually throws an exception.
-
-*******************************************************************************/
-
-asm_builtin_arraycheckcast:
-       sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
-
-       mov             12(%esp),%eax               /* first param:     8 (frame) + 4 (return)*/
-       mov             %eax,(%esp)                 /* save object pointer                */
-
-       mov             16(%esp),%eax                           /* second param:        8 (frame) + 4 (return) + 4*/
-       mov             %eax,4(%esp)
-
-       call    builtin_arraycheckcast
-
-       test    %eax,%eax                   /* if (false) throw exception         */
-       je              nb_carray_throw
-
-       mov             12(%esp),%eax               /* return object pointer              */
-       add             $8,%esp
-       ret
-
-nb_carray_throw:
-       add $8,%esp
-       mov string_java_lang_ClassCastException,%eax
-       pop %ecx
-       sub $2,%ecx
-       jmp asm_throw_and_handle_exception
-#if 0
-       push    string_java_lang_ClassCastException
-       call    new_exception
-       add     $(1*4),%esp
-       
-       add             $8,%esp
-       
-       pop             %ecx                        /* delete return address              */
-       sub             $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp             asm_handle_exception
-#endif
-
-               
-/******************* function asm_builtin_aastore ******************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-* void asm_builtin_aastore(java_objectarray *a, s4 index, java_objectheader *o)*
-*******************************************************************************/
-
-asm_builtin_aastore:
-       sub     $12,%esp                    /* build stack frame (3 * 4 bytes)    */
-
-       mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
-       test    %eax,%eax                   /* if null pointer throw exception    */
-       je      nb_aastore_null
-
-       mov     offarraysize(%eax),%edx     /* load size                          */
-       mov     20(%esp),%ecx               /* index  (12 + 4 + 4)                 */
-       cmp     %edx,%ecx                   /* do bound check                     */
-       jae     nb_aastore_bound            /* if out of bounds throw exception   */
-
-       shl     $2,%ecx                     /* index * 4                          */
-       add     %eax,%ecx                   /* add index * 4 to arrayref          */
-          
-       mov     %ecx,8(%esp)                /* save store position                */
-          
-       mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
-       mov     %eax,(%esp)
-          
-       mov     24(%esp),%eax               /* object is second argument (12+4+4+4) */
-       mov     %eax,4(%esp)
-       
-       call    builtin_canstore            /* builtin_canstore(arrayref,object)  */
-
-       test    %eax,%eax                   /* if (false) throw exception         */
-       je      nb_aastore_store
-
-       mov     24(%esp),%eax
-       mov     8(%esp),%ecx
-       mov     %eax,offobjarrdata(%ecx)    /* store objectptr in array           */
-       
-       add     $12,%esp
-       ret
-
-nb_aastore_null:
-        add $12,%esp
-        mov string_java_lang_NullPointerException,%eax
-        pop %ecx
-        sub $2,%ecx
-        jmp asm_throw_and_handle_exception
-
-#if 0
-       push    string_java_lang_NullPointerException
-       call    new_exception
-       add     $(1*4),%esp
-       
-       add     $12,%esp
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp             asm_handle_exception
-#endif
-nb_aastore_bound:
-       add     $12,%esp
-       mov         %ecx,%eax                    /* itmp2 contains array index         */
-       pushl   $0  /*directly below return adress*/
-       pushl   $0  /*internal (invisible) method*/
-       call    asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
-
-       push    %eax
-       call    new_arrayindexoutofboundsexception
-       add     $(1*4),%esp
-
-       call    asm_remove_native_stackinfo /*return adress is the first on stack again*/
-
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-               
-nb_aastore_store:
-       add     $12,%esp
-
-        mov string_java_lang_ArrayStoreException,%eax
-        pop %ecx
-        sub $2,%ecx
-        jmp asm_throw_and_handle_exception
-
-#if 0
-       push    string_java_lang_ArrayStoreException
-       call    new_exception
-       add     $(1*4),%esp
-       
-       add     $12,%esp
-       pop     %ecx                        /* delete return address              */
-       sub     $2,%ecx                     /* faulting address is return adress - 2 */
-       jmp     asm_handle_exception
-#endif
-
-
 /******************* function asm_initialize_thread_stack **********************
 *                                                                              *
 * initialized a thread stack                                                   *
@@ -1085,112 +850,6 @@ asm_switchstackandcall:
        ret
 
                
-asm_throw_and_handle_exception:
-       push %ecx
-       pushl $0 /* the pushed XPC is directly below the java frame*/
-       pushl $0
-       call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
-       
-       push %eax
-        call new_exception
-       add $4,%esp   /*remove parameter*/
-
-       call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
-
-       pop %ecx
-       jmp asm_handle_exception
-       ret /*should never be reached */
-
-asm_throw_and_handle_hardware_arithmetic_exception:
-       
-       push %ecx
-       pushl $0 /* the pushed XPC is directly below the java frame*/
-       pushl $0
-       call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
-       
-       mov string_java_lang_ArithmeticException_message,%eax
-       push %eax
-       mov string_java_lang_ArithmeticException,%eax
-       push %eax
-
-       call new_exception_message
-       add $8,%esp /*remove parameters */
-
-       call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
-
-       pop %ecx
-       jmp asm_handle_exception
-       ret /*should never be reached */
-
-asm_builtin_new2:
-/*optimize a littlebit */
-               mov %esp,%eax
-/*DEBUG*/
-/*             push %eax
-               call i386_native_stub_debug
-               pop %eax */
-               
-               movl 4(%esp),%eax
-               mov     offclassinit(%eax),%ecx     /* get initialized flag           */
-               test    %ecx,%ecx
-               jnz             L_builtin_new_noinit
-
-               mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
-
-               /* 2 *4 bytes, the return adress is used directy */
-               pushl $0  /* the structure is placed directly below the java stackframe*/
-               pushl $0  /* builtin (invisible) method */
-               call  asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
-#if 0
-                sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
-
-                mov             20(%esp),%eax
-                mov             %eax,(%esp)
-
-               call    builtin_asm_get_stackframeinfo
-               movl    $0,12(%esp)
-               mov     %eax,8(%esp)
-               mov     (%eax),%ebx
-               mov     %ebx,4(%esp)
-               mov     %esp,%ecx
-               add     $4,%ecx
-               mov     %ecx,(%eax)
-#endif
-               push    %eax
-                call    builtin_new
-               add     $4,%esp
-
-               call    asm_remove_native_stackinfo /*first element on stack is return adress again*/
-#if 0          
-               call    
-               mov     4(%esp),%ebx
-               mov     8(%esp),%ecx
-               mov     %ebx,(%ecx)
-
-                add             $16,%esp
-#endif
-               jmp L_builtin_new_patch
-
-
-L_builtin_new_noinit:
-               mov 4(%esp),%eax
-               push %eax
-               call builtin_new
-               add $4,%esp
-               /*jmp L_builtin_new_patch*/
-
-L_builtin_new_patch:
-/*add patching code here */
-               lea builtin_new,%edx
-               mov (%esp),%ecx
-               mov %edx,-6(%ecx)       /*patch calling instruction, t directly call builtin_new the next time*/
-               ret
-
-
-
-
-
-
 asm_getclassvalues_atomic:
 _crit_restart2:
        mov     4(%esp),%ecx        /* super */
@@ -1222,106 +881,6 @@ asm_criticalsections:
        .long 0
 
 
-
-/************************ function asm_prepare_native_stackinfo ****************************
-*                                                                                          *
-*    creates a stackfame for the begin of a native function (either builtin or not )       *
-*    expected stack at begin of function                                                   *
-*                                        ....                                              *
-*                   address of the jit call which invokes the native                       *
-*                   begin address of stack frame of the java method                        *
-*                   method pointer or 0 (for built ins)                                    *
-*                   return address                                                         *
-*                                                                                          *
-*    at end of function:                                                                   *
-*                                          ...                                             *
-*                   address of the jit call which invokes the native                       *
-*                   begin address of stack frame of the java method                        *
-*                   method pointer or 0 (for built ins)                                    *
-*                   address of thread specific top of native list                          *
-*                   old value of thread specific head                                      *
-*                   return address                                                         *
-*                                                                                          *
-*                                        ....                                              *
-* This thing is less efficient than the original #define (callerside)                      *
-* destroyes REG_ITMP2, keeps REG_ITMP1                                                     *
-********************************************************************************************/
-
-
-asm_prepare_native_stackinfo:
-        sub $8,%esp
-        mov 8(%esp),%ecx
-        mov %ecx,(%esp)
-        push %eax
-        lea     builtin_asm_get_stackframeinfo,%ecx
-        call    *%ecx
-        mov %eax, 12(%esp)
-        mov (%eax),%ecx
-        mov %ecx,8(%esp)
-        mov %esp,%ecx
-        add $8,%ecx
-        mov %ecx,(%eax)
-        pop %eax
-        ret
-#if 0
-#define PREPARE_NATIVE_STACKINFO \
-    i386_push_reg(cd, REG_ITMP1);       /*save itmp1, needed by some stubs */ \
-    i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
-    i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
-    i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/ \
-    i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
-    i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/ \
-    i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/ \
-    i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4);     /* store value on stack */ \
-    i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
-    i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
-    i386_mov_imm_membase(cd, 0,REG_SP, 2*4);    /* builtin */
-#endif
-
-
-/************************ function asm_remove _native_stackinfo *******************************************
-*                                                                                                         *
-*    creates a stackfame for the begin of a native function (either builtin or not)                       *
-*    expected stack at begin of function                                                                  *
-*                   address of the jit call which invokes the native                                      *
-*                   begin address of stack frame of the java method                                       *
-*                   method pointer or 0 (for built ins)                                                   *
-*                   address thread specific top of native list                                            *
-*                   old value of thread specific head                                                     *
-*                   return address                                                                        *
-*                                                                                                         *
-*    at end of function:                                                                                  *
-*                             ....                                                                        *
-*                   return adresss of the jit call which invokes the native                               *
-*                   return address                                                                        *
-*                                                                                                         *
-*                   REG_ITMP2_XPC = address of the jit call which invokes the native                      *
-*                                                                                                         *
-*                                                                                                         *
-* This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1  *
-***********************************************************************************************************/
-
-asm_remove_native_stackinfo:
-        mov 4(%esp),%ecx
-        mov 8(%esp),%edx
-        mov %ecx,(%edx)
-        pop %edx
-        add $16,%esp
-        push %edx
-       ret
-
-#if 0
-#define REMOVE_NATIVE_STACKINFO \
-    i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
-    i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
-    i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
-#endif
-
-
-
-
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index 1b9b2a5a0a2064caf07edb2358e28806150e32fe..2fb770c513ff174dbf51133abd2c84a4f0d039a7 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Joseph Wenninger
            Christian Ullrich
 
-   $Id: codegen.c 2860 2005-06-28 18:37:28Z twisti $
+   $Id: codegen.c 2971 2005-07-10 15:33:54Z twisti $
 
 */
 
@@ -92,7 +92,7 @@ void codegen_stubcalled() {
 
 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 {
-       s4     len, s1, s2, s3, d;
+       s4     len, s1, s2, s3, d, off;
        ptrint a;
        stackptr      src;
        varinfo      *var;
@@ -1509,7 +1509,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
                case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
                        /* REG_RES Register usage: see icmd_uses_reg_res.inc */
-                       /* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: EAX*/ /* Really uses EDX? */
+                       /* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: EAX */
 
                        d = reg_of_var(rd, iptr->dst, REG_NULL);
                        var_to_reg_int(s1, src, REG_ITMP2);
@@ -1520,8 +1520,10 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        } else {
                                M_INTMOVE(src->prev->regoff, EAX);
                        }
-                       
-                       i386_alu_imm_reg(cd, ALU_CMP, 0x80000000, EAX);    /* check as described in jvm spec */
+
+                       /* check as described in jvm spec */
+
+                       i386_alu_imm_reg(cd, ALU_CMP, 0x80000000, EAX);
                        i386_jcc(cd, I386_CC_NE, 3 + 6);
                        i386_alu_imm_reg(cd, ALU_CMP, -1, s1);
                        i386_jcc(cd, I386_CC_E, 1 + 2);
@@ -1539,7 +1541,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
                case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
                        /* REG_RES Register usage: see icmd_uses_reg_res.inc */
-                       /* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: EDX*/ 
+                       /* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: EDX */
 
 
                        d = reg_of_var(rd, iptr->dst, REG_NULL);
@@ -1551,8 +1553,10 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        } else {
                                M_INTMOVE(src->prev->regoff, EAX);
                        }
-                       
-                       i386_alu_imm_reg(cd, ALU_CMP, 0x80000000, EAX);    /* check as described in jvm spec */
+
+                       /* check as described in jvm spec */
+
+                       i386_alu_imm_reg(cd, ALU_CMP, 0x80000000, EAX);
                        i386_jcc(cd, I386_CC_NE, 2 + 3 + 6);
                        i386_alu_reg_reg(cd, ALU_XOR, EDX, EDX);
                        i386_alu_imm_reg(cd, ALU_CMP, -1, s1);
@@ -1572,7 +1576,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
                                      /* val.i = constant                             */
                        /* REG_RES Register usage: see icmd_uses_reg_res.inc */
-                       /* EAX: YES ECX: NO EDX: NO OUTPUT: REG_NULL*/ 
+                       /* EAX: YES ECX: NO EDX: NO OUTPUT: REG_NULL */
 
                        /* TODO: optimize for `/ 2' */
                        var_to_reg_int(s1, src, REG_ITMP1);
@@ -1589,37 +1593,10 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        store_reg_to_var_int(iptr->dst, d);
                        break;
 
-               case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
-                                     /* val.i = constant                             */
-                       /* REG_RES Register usage: see icmd_uses_reg_res.inc */
-                       /* EAX: YES ECX: YES EDX: NO OUTPUT: REG_NULL*/ 
-
-                       d = reg_of_var(rd, iptr->dst, REG_NULL);
-                       if (iptr->dst->flags & INMEMORY) {
-                               if (src->flags & INMEMORY) {
-                                       a = 2;
-                                       CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
-                                       a += 3;
-                                       i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
-                                       i386_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP2);
-
-                                       i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
-                                       i386_jcc(cd, I386_CC_NS, a);
-                                       i386_alu_imm_reg(cd, ALU_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
-                                       i386_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
-                                       i386_shrd_imm_reg_reg(cd, iptr->val.i, REG_ITMP2, REG_ITMP1);
-                                       i386_shift_imm_reg(cd, I386_SAR, iptr->val.i, REG_ITMP2);
-
-                                       i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
-                                       i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 4 + 4);
-                               }
-                       }
-                       break;
-
                case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
                                      /* val.i = constant                             */
                        /* REG_RES Register usage: see icmd_uses_reg_res.inc */
-                       /* EAX: YES ECX: YES EDX: NO OUTPUT: REG_NULL*/ 
+                       /* EAX: YES ECX: YES EDX: NO OUTPUT: REG_NULL */
 
                        var_to_reg_int(s1, src, REG_ITMP1);
                        d = reg_of_var(rd, iptr->dst, REG_ITMP2);
@@ -1661,10 +1638,67 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        store_reg_to_var_int(iptr->dst, d);
                        break;
 
+               case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
+               case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
+
+                       d = reg_of_var(rd, iptr->dst, REG_NULL);
+                       M_ILD(REG_ITMP2, REG_SP, src->regoff * 4);
+                       M_OR_MEMBASE(REG_SP, src->regoff * 4 + 4, REG_ITMP2);
+                       M_TEST(REG_ITMP2);
+                       M_BEQ(0);
+                       codegen_addxdivrefs(cd, cd->mcodeptr);
+
+                       bte = iptr->val.a;
+                       md = bte->md;
+
+                       M_ILD(REG_ITMP1, REG_SP, src->prev->regoff * 4);
+                       M_ILD(REG_ITMP2, REG_SP, src->prev->regoff * 4 + 4);
+                       M_IST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_IST(REG_ITMP2, REG_SP, 0 * 4 + 4);
+
+                       M_ILD(REG_ITMP1, REG_SP, src->regoff * 4);
+                       M_ILD(REG_ITMP2, REG_SP, src->regoff * 4 + 4);
+                       M_IST(REG_ITMP1, REG_SP, 2 * 4);
+                       M_IST(REG_ITMP2, REG_SP, 2 * 4 + 4);
+
+                       M_MOV_IMM((ptrint) bte->fp, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+
+                       M_IST(REG_RESULT, REG_SP, iptr->dst->regoff * 4);
+                       M_IST(REG_RESULT2, REG_SP, iptr->dst->regoff * 4 + 4);
+                       break;
+
+               case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
+                                     /* val.i = constant                             */
+                       /* REG_RES Register usage: see icmd_uses_reg_res.inc */
+                       /* EAX: YES ECX: YES EDX: NO OUTPUT: REG_NULL */
+
+                       d = reg_of_var(rd, iptr->dst, REG_NULL);
+                       if (iptr->dst->flags & INMEMORY) {
+                               if (src->flags & INMEMORY) {
+                                       a = 2;
+                                       CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
+                                       a += 3;
+                                       i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
+                                       i386_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP2);
+
+                                       i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
+                                       i386_jcc(cd, I386_CC_NS, a);
+                                       i386_alu_imm_reg(cd, ALU_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
+                                       i386_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
+                                       i386_shrd_imm_reg_reg(cd, iptr->val.i, REG_ITMP2, REG_ITMP1);
+                                       i386_shift_imm_reg(cd, I386_SAR, iptr->val.i, REG_ITMP2);
+
+                                       i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
+                                       i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 4 + 4);
+                               }
+                       }
+                       break;
+
                case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
                                      /* val.l = constant                             */
                        /* REG_RES Register usage: see icmd_uses_reg_res.inc */
-                       /* EAX: YES ECX: YES EDX: NO OUTPUT: REG_NULL*/ 
+                       /* EAX: YES ECX: YES EDX: NO OUTPUT: REG_NULL */
 
                        d = reg_of_var(rd, iptr->dst, REG_NULL);
                        if (iptr->dst->flags & INMEMORY) {
@@ -2828,23 +2862,9 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        break;
 
 
-               case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
-                       /* REG_RES Register usage: see icmd_uses_reg_res.inc */
-                       /* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: REG_NULL*/ 
-
-                       var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
-                       var_to_reg_int(s2, src->prev, REG_ITMP2);
-                       if (iptr->op1 == 0) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
-                       var_to_reg_int(s3, src, REG_ITMP3);
-                       i386_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
-                       break;
-
                case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
                        /* REG_RES Register usage: see icmd_uses_reg_res.inc */
-                       /* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: REG_NULL*/ 
+                       /* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: REG_NULL */
 
                        var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
                        var_to_reg_int(s2, src->prev, REG_ITMP2);
@@ -2951,6 +2971,34 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        i386_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
                        break;
 
+               case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
+                       /* REG_RES Register usage: see icmd_uses_reg_res.inc */
+                       /* EAX: S|YES ECX: S|YES EDX: S|YES OUTPUT: REG_NULL */
+
+                       var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
+                       var_to_reg_int(s2, src->prev, REG_ITMP2);
+/*                     if (iptr->op1 == 0) { */
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+/*                     } */
+                       var_to_reg_int(s3, src, REG_ITMP3);
+
+                       bte = iptr->val.a;
+
+                       M_AST(s1, REG_SP, 0 * 4);
+                       M_AST(s3, REG_SP, 1 * 4);
+                       M_MOV_IMM((ptrint) bte->fp, REG_ITMP1);
+                       M_CALL(REG_ITMP1);
+                       M_TEST(REG_RESULT);
+                       M_BEQ(0);
+                       codegen_addxstorerefs(cd, cd->mcodeptr);
+
+                       var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
+                       var_to_reg_int(s2, src->prev, REG_ITMP2);
+                       var_to_reg_int(s3, src, REG_ITMP3);
+                       i386_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
+                       break;
+
                case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
                        /* REG_RES Register usage: see icmd_uses_reg_res.inc */
                        /* EAX: S|YES ECX: S|YES EDX: NO OUTPUT: REG_NULL*/ 
@@ -3042,7 +3090,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                                                        PATCHER_get_putstatic,
                                                                        (unresolved_field *) iptr->target);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -3055,7 +3103,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                        codegen_addpatchref(cd, cd->mcodeptr,
                                                                                PATCHER_clinit, fi->class);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
                                }
@@ -3110,7 +3158,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                                                        PATCHER_get_putstatic,
                                                                        (unresolved_field *) iptr->target);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -3123,7 +3171,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                        codegen_addpatchref(cd, cd->mcodeptr,
                                                                                PATCHER_clinit, fi->class);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
                                }
@@ -3178,7 +3226,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                                                        PATCHER_get_putstatic,
                                                                        (unresolved_field *) iptr[1].target);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -3191,7 +3239,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                        codegen_addpatchref(cd, cd->mcodeptr,
                                                                                PATCHER_clinit, fi->class);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
                                }
@@ -3227,7 +3275,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                                                        PATCHER_getfield,
                                                                        (unresolved_field *) iptr->target);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -3284,7 +3332,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                                                        PATCHER_putfield,
                                                                        (unresolved_field *) iptr->target);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -3336,7 +3384,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                                                        PATCHER_putfieldconst,
                                                                        (unresolved_field *) iptr[1].target);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -4303,7 +4351,7 @@ gen_method:
                                if (iptr->target) {
                                        codegen_addpatchref(cd, cd->mcodeptr, bte->fp, iptr->target);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
 
@@ -4333,7 +4381,7 @@ gen_method:
                                        codegen_addpatchref(cd, cd->mcodeptr,
                                                                                PATCHER_invokestatic_special, um);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
 
@@ -4359,7 +4407,7 @@ gen_method:
                                        codegen_addpatchref(cd, cd->mcodeptr,
                                                                                PATCHER_invokevirtual, um);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
 
@@ -4389,7 +4437,7 @@ gen_method:
                                        codegen_addpatchref(cd, cd->mcodeptr,
                                                                                PATCHER_invokeinterface, um);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
 
@@ -4502,7 +4550,7 @@ gen_method:
                                   2 /* test */ + 6 /* jcc */);
 
                        if (!super)
-                               s2 += (showdisassemble ? 5 : 0);
+                               s2 += (opt_showdisassemble ? 5 : 0);
 
                        /* calculate class checkcast code size */
 
@@ -4532,19 +4580,19 @@ gen_method:
                        s3 += 2 /* cmp */ + 6 /* jcc */;
 
                        if (!super)
-                               s3 += (showdisassemble ? 5 : 0);
+                               s3 += (opt_showdisassemble ? 5 : 0);
 
                        /* if class is not resolved, check which code to call */
 
                        if (!super) {
                                i386_test_reg_reg(cd, s1, s1);
-                               i386_jcc(cd, I386_CC_Z, 5 + (showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
+                               i386_jcc(cd, I386_CC_Z, 5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
 
                                codegen_addpatchref(cd, cd->mcodeptr,
                                                                        PATCHER_checkcast_instanceof_flags,
                                                                        (constant_classref *) iptr->target);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -4570,7 +4618,7 @@ gen_method:
                                                                                PATCHER_checkcast_instanceof_interface,
                                                                                (constant_classref *) iptr->target);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
                                }
@@ -4611,7 +4659,7 @@ gen_method:
                                                                                PATCHER_checkcast_class,
                                                                                (constant_classref *) iptr->target);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
                                }
@@ -4656,6 +4704,40 @@ gen_method:
                        }
                        break;
 
+               case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref        */
+                                         /* op1: 1... resolved, 0... not resolved    */
+
+                       var_to_reg_int(s1, src, REG_ITMP1);
+                       M_AST(s1, REG_SP, 0 * 4);
+
+                       bte = iptr->val.a;
+
+                       if (!iptr->op1) {
+                               codegen_addpatchref(cd, cd->mcodeptr, bte->fp, iptr->target);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               a = 0;
+
+                       } else {
+                               a = (ptrint) bte->fp;
+                       }
+
+                       M_AST_IMM((ptrint) iptr->target, REG_SP, 1 * 4);
+                       M_MOV_IMM((ptrint) a, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+                       M_TEST(REG_RESULT);
+                       M_BEQ(0);
+                       codegen_addxcastrefs(cd, cd->mcodeptr);
+
+                       var_to_reg_int(s1, src, REG_ITMP1);
+                       d = reg_of_var(rd, iptr->dst, s1);
+                       M_INTMOVE(s1, d);
+                       store_reg_to_var_int(iptr->dst, d);
+                       break;
+
                case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
 
                                      /* op1:   0 == array, 1 == class                */
@@ -4714,7 +4796,7 @@ gen_method:
                                   2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
 
                        if (!super)
-                               s2 += (showdisassemble ? 5 : 0);
+                               s2 += (opt_showdisassemble ? 5 : 0);
 
                        /* calculate class instanceof code size */
 
@@ -4732,7 +4814,7 @@ gen_method:
                                   2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
 
                        if (!super)
-                               s3 += (showdisassemble ? 5 : 0);
+                               s3 += (opt_showdisassemble ? 5 : 0);
 
                        i386_alu_reg_reg(cd, ALU_XOR, d, d);
 
@@ -4740,13 +4822,13 @@ gen_method:
 
                        if (!super) {
                                i386_test_reg_reg(cd, s1, s1);
-                               i386_jcc(cd, I386_CC_Z, 5 + (showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
+                               i386_jcc(cd, I386_CC_Z, 5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
 
                                codegen_addpatchref(cd, cd->mcodeptr,
                                                                        PATCHER_checkcast_instanceof_flags,
                                                                        (constant_classref *) iptr->target);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -4772,7 +4854,7 @@ gen_method:
                                                                                PATCHER_checkcast_instanceof_interface,
                                                                                (constant_classref *) iptr->target);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
                                }
@@ -4818,7 +4900,7 @@ gen_method:
                                                                                PATCHER_instanceof_class,
                                                                                (constant_classref *) iptr->target);
 
-                                       if (showdisassemble) {
+                                       if (opt_showdisassemble) {
                                                M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                        }
                                }
@@ -4918,7 +5000,7 @@ gen_method:
                                                                        (functionptr) (ptrint) iptr->target,
                                                                        iptr->val.a);
 
-                               if (showdisassemble) {
+                               if (opt_showdisassemble) {
                                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                                }
 
@@ -5010,7 +5092,7 @@ gen_method:
 
        {
 
-       /* generate bound check stubs */
+       /* generate ArrayIndexOutOfBoundsException stubs */
 
        u1 *xcodeptr = NULL;
        branchref *bref;
@@ -5023,53 +5105,71 @@ gen_method:
                MCODECHECK(100);
 
                /* move index register into REG_ITMP1 */
-               i386_mov_reg_reg(cd, bref->reg, REG_ITMP1);                /* 2 bytes */
 
-               i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
+               M_INTMOVE(bref->reg, REG_ITMP1);                           /* 2 bytes */
+
+               M_MOV_IMM(0, REG_ITMP2_XPC);                               /* 5 bytes */
                dseg_adddata(cd, cd->mcodeptr);
-               i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP3);      /* 5 bytes */
-               i386_alu_reg_reg(cd, ALU_ADD, REG_ITMP3, REG_ITMP2_XPC);  /* 2 bytes */
+               M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);          /* 6 bytes */
 
                if (xcodeptr != NULL) {
-                       i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
+                       M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
 
                } else {
                        xcodeptr = cd->mcodeptr;
 
-                       i386_push_reg(cd, REG_ITMP2_XPC);
-
-                       /*PREPARE_NATIVE_STACKINFO;*/
-                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
-                       i386_push_imm(cd,0);
-                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
-
-                       i386_alu_imm_reg(cd, ALU_SUB, 1 * 4, REG_SP);
-                       i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0 * 4);
-                       i386_mov_imm_reg(cd, (u4) new_arrayindexoutofboundsexception, REG_ITMP1);
-                       i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
-                       i386_alu_imm_reg(cd, ALU_ADD, 1 * 4, REG_SP);
+                       M_ASUB_IMM(6 * 4 + sizeof(stackframeinfo), REG_SP);
+                       M_IST(REG_ITMP1, REG_SP, 4 * 4);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 5 * 4);
 
-                       /*REMOVE_NATIVE_STACKINFO;*/
-                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* create dynamic stack info */
 
-                       i386_pop_reg(cd, REG_ITMP2_XPC);
-
-                       i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
-                       i386_jmp_reg(cd, REG_ITMP3);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(6 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_IST_IMM(0, REG_SP, 1 * 4);
+                       dseg_adddata(cd, cd->mcodeptr);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(6 * 4 + sizeof(stackframeinfo), REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 2 * 4);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4); /* don't use ITMP2 till here */
+                       M_MOV_IMM((ptrint) stacktrace_create_inline_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+
+                       /* create exception */
+
+                       M_ALD(REG_ITMP1, REG_SP, 4 * 4);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) new_arrayindexoutofboundsexception, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+                       M_AST(REG_RESULT, REG_SP, 1 * 4);
+
+                       /* remove native stackframe info */
+
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(6 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) stacktrace_remove_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+
+                       M_ALD(REG_ITMP1_XPTR, REG_SP, 1 * 4);
+                       M_ALD(REG_ITMP2_XPC, REG_SP, 5 * 4);
+                       M_AADD_IMM(6 * 4 + sizeof(stackframeinfo), REG_SP);
+
+                       M_MOV_IMM((ptrint) asm_handle_exception, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
                }
        }
 
-       /* generate negative array size check stubs */
+       /* generate ArrayStoreException stubs */
 
        xcodeptr = NULL;
        
-       for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
+       for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
                if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
                        gen_resolvebranch(cd->mcodebase + bref->branchpos, 
                                                          bref->branchpos,
-                                                         xcodeptr - cd->mcodebase - (5 + 5 + 2));
+                                                         xcodeptr - cd->mcodebase - (5 + 6));
                        continue;
                }
 
@@ -5079,53 +5179,65 @@ gen_method:
 
                MCODECHECK(100);
 
-               i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
+               M_MOV_IMM(0, REG_ITMP2_XPC);                               /* 5 bytes */
                dseg_adddata(cd, cd->mcodeptr);
-               i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
-               i386_alu_reg_reg(cd, ALU_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
+               M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);          /* 6 bytes */
 
                if (xcodeptr != NULL) {
-                       i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
+                       M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
 
                } else {
                        xcodeptr = cd->mcodeptr;
 
-                       i386_push_reg(cd, REG_ITMP2_XPC);
-
-                       /*PREPARE_NATIVE_STACKINFO;*/
-                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
-                       i386_push_imm(cd,0);
-                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       M_ASUB_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 4 * 4);
 
+                       /* create dynamic stack info */
 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_IST_IMM(0, REG_SP, 1 * 4);
+                       dseg_adddata(cd, cd->mcodeptr);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 2 * 4);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4); /* don't use ITMP2 till here */
+                       M_MOV_IMM((ptrint) stacktrace_create_inline_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
-                       i386_mov_imm_reg(cd, (u4) new_negativearraysizeexception, REG_ITMP1);
-                       i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
-                       /*i386_alu_imm_reg(cd, ALU_ADD, 1 * 4, REG_SP);*/
+                       /* create exception */
 
+                       M_MOV_IMM((ptrint) new_arraystoreexception, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+                       M_AST(REG_RESULT, REG_SP, 1 * 4);
 
-                       /*REMOVE_NATIVE_STACKINFO;*/
-                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* remove native stackframe info */
 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) stacktrace_remove_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
-                       i386_pop_reg(cd, REG_ITMP2_XPC);
+                       M_ALD(REG_ITMP1_XPTR, REG_SP, 1 * 4);
+                       M_ALD(REG_ITMP2_XPC, REG_SP, 4 * 4);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
 
-                       i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
-                       i386_jmp_reg(cd, REG_ITMP3);
+                       M_MOV_IMM((ptrint) asm_handle_exception, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
                }
        }
 
-       /* generate cast check stubs */
+       /* generate NegativeArraySizeException stubs */
 
        xcodeptr = NULL;
        
-       for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
+       for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
                if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
                        gen_resolvebranch(cd->mcodebase + bref->branchpos, 
                                                          bref->branchpos,
-                                                         xcodeptr - cd->mcodebase - (5 + 5 + 2));
+                                                         xcodeptr - cd->mcodebase - (5 + 6));
                        continue;
                }
 
@@ -5135,52 +5247,65 @@ gen_method:
 
                MCODECHECK(100);
 
-               i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
+               M_MOV_IMM(0, REG_ITMP2_XPC);                               /* 5 bytes */
                dseg_adddata(cd, cd->mcodeptr);
-               i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
-               i386_alu_reg_reg(cd, ALU_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
+               M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);          /* 6 bytes */
 
                if (xcodeptr != NULL) {
-                       i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
-               
+                       M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
+
                } else {
                        xcodeptr = cd->mcodeptr;
 
-                       i386_push_reg(cd, REG_ITMP2_XPC);
+                       M_ASUB_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 4 * 4);
 
-                       /*PREPARE_NATIVE_STACKINFO;*/
-                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
-                       i386_push_imm(cd,0);
-                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* create dynamic stack info */
 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_IST_IMM(0, REG_SP, 1 * 4);
+                       dseg_adddata(cd, cd->mcodeptr);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 2 * 4);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4); /* don't use ITMP2 till here */
+                       M_MOV_IMM((ptrint) stacktrace_create_inline_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
-                       i386_mov_imm_reg(cd, (u4) new_classcastexception, REG_ITMP1);
-                       i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
-                       /*i386_alu_imm_reg(cd, ALU_ADD, 1 * 4, REG_SP);*/
+                       /* create exception */
 
+                       M_MOV_IMM((ptrint) new_negativearraysizeexception, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+                       M_AST(REG_RESULT, REG_SP, 1 * 4);
 
-                       /*REMOVE_NATIVE_STACKINFO;*/
-                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* remove native stackframe info */
 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) stacktrace_remove_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
-                       i386_pop_reg(cd, REG_ITMP2_XPC);
+                       M_ALD(REG_ITMP1_XPTR, REG_SP, 1 * 4);
+                       M_ALD(REG_ITMP2_XPC, REG_SP, 4 * 4);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
 
-                       i386_mov_imm_reg(cd, (u4) asm_handle_exception, REG_ITMP3);
-                       i386_jmp_reg(cd, REG_ITMP3);
+                       M_MOV_IMM((ptrint) asm_handle_exception, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
                }
        }
 
-       /* generate divide by zero check stubs */
+       /* generate ClassCastException stubs */
 
        xcodeptr = NULL;
        
-       for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
+       for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
                if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
                        gen_resolvebranch(cd->mcodebase + bref->branchpos, 
                                                          bref->branchpos,
-                                                         xcodeptr - cd->mcodebase - (5 + 5 + 2));
+                                                         xcodeptr - cd->mcodebase - (5 + 6));
                        continue;
                }
 
@@ -5190,51 +5315,65 @@ gen_method:
 
                MCODECHECK(100);
 
-               i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
+               M_MOV_IMM(0, REG_ITMP2_XPC);                               /* 5 bytes */
                dseg_adddata(cd, cd->mcodeptr);
-               i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
-               i386_alu_reg_reg(cd, ALU_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
+               M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);          /* 6 bytes */
 
                if (xcodeptr != NULL) {
-                       i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
+                       M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
                
                } else {
                        xcodeptr = cd->mcodeptr;
 
-                       i386_push_reg(cd, REG_ITMP2_XPC);
+                       M_ASUB_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 4 * 4);
 
-                       /*PREPARE_NATIVE_STACKINFO;*/
-                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
-                       i386_push_imm(cd,0);
-                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* create dynamic stack info */
 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_IST_IMM(0, REG_SP, 1 * 4);
+                       dseg_adddata(cd, cd->mcodeptr);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 2 * 4);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4); /* don't use ITMP2 till here */
+                       M_MOV_IMM((ptrint) stacktrace_create_inline_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
+                       /* create exception */
 
-                       i386_mov_imm_reg(cd, (u4) new_arithmeticexception, REG_ITMP1);
-                       i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
+                       M_MOV_IMM((ptrint) new_classcastexception, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+                       M_AST(REG_RESULT, REG_SP, 1 * 4);
 
-                       /*REMOVE_NATIVE_STACKINFO;*/
-                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* remove native stackframe info */
 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) stacktrace_remove_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
-                       i386_pop_reg(cd, REG_ITMP2_XPC);
+                       M_ALD(REG_ITMP1_XPTR, REG_SP, 1 * 4);
+                       M_ALD(REG_ITMP2_XPC, REG_SP, 4 * 4);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
 
-                       i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
-                       i386_jmp_reg(cd, REG_ITMP3);
+                       M_MOV_IMM((ptrint) asm_handle_exception, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
                }
        }
 
-       /* generate exception check stubs */
+       /* generate ArithmeticException stubs */
 
        xcodeptr = NULL;
        
-       for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
+       for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
                if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
-                       gen_resolvebranch(cd->mcodebase + bref->branchpos,
+                       gen_resolvebranch(cd->mcodebase + bref->branchpos, 
                                                          bref->branchpos,
-                                                         xcodeptr - cd->mcodebase - (5 + 5 + 2));
+                                                         xcodeptr - cd->mcodebase - (5 + 6));
                        continue;
                }
 
@@ -5242,83 +5381,59 @@ gen_method:
                                  bref->branchpos,
                                                  cd->mcodeptr - cd->mcodebase);
 
-               MCODECHECK(200);
+               MCODECHECK(100);
 
-               i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
+               M_MOV_IMM(0, REG_ITMP2_XPC);                               /* 5 bytes */
                dseg_adddata(cd, cd->mcodeptr);
-               i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
-               i386_alu_reg_reg(cd, ALU_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
+               M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);          /* 6 bytes */
 
                if (xcodeptr != NULL) {
-                       i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
+                       M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
                
                } else {
                        xcodeptr = cd->mcodeptr;
 
-                       i386_push_reg(cd, REG_ITMP2_XPC);
+                       M_ASUB_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 4 * 4);
 
-                       /*PREPARE_NATIVE_STACKINFO;*/
-                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
-                       i386_push_imm(cd,0);
-                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* create dynamic stack info */
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-                       i386_mov_imm_reg(cd, (s4) &builtin_get_exceptionptrptr, REG_ITMP1);
-                       i386_call_reg(cd, REG_ITMP1);
-                       i386_mov_membase_reg(cd, REG_RESULT, 0, REG_ITMP3);
-                       i386_mov_imm_membase(cd, 0, REG_RESULT, 0);
-                       i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1_XPTR);
-#else
-                       i386_mov_imm_reg(cd, (s4) &_exceptionptr, REG_ITMP3);
-                       i386_mov_membase_reg(cd, REG_ITMP3, 0, REG_ITMP1_XPTR);
-                       i386_mov_imm_membase(cd, 0, REG_ITMP3, 0);
-#endif
-                       i386_push_imm(cd, 0);
-                       i386_push_reg(cd, REG_ITMP1_XPTR);
-
-/*get the fillInStackTrace Method ID. I simulate a native call here, because I do not want to mess around with the
-java stack at this point*/
-                       i386_mov_membase_reg(cd, REG_ITMP1_XPTR, OFFSET(java_objectheader, vftbl), REG_ITMP3);
-                       i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, class), REG_ITMP1);
-                       i386_push_imm(cd, (u4) utf_void__java_lang_Throwable);
-                       i386_push_imm(cd, (u4) utf_fillInStackTrace);
-                       i386_push_reg(cd, REG_ITMP1);
-                       i386_mov_imm_reg(cd, (s4) class_resolvemethod, REG_ITMP3);
-                       i386_call_reg(cd, REG_ITMP3);
-/*cleanup parameters of class_resolvemethod*/
-                       i386_alu_imm_reg(cd, ALU_ADD,3*4 /*class reference + 2x string reference*/,REG_SP);
-/*prepare call to asm_calljavafunction2 */                     
-                       i386_push_imm(cd, 0);
-                       i386_push_imm(cd, TYPE_ADR); /* --> call block (TYPE,Exceptionptr), each 8 byte  (make this dynamic) (JOWENN)*/
-                       i386_push_reg(cd, REG_SP);
-                       i386_push_imm(cd, sizeof(jni_callblock));
-                       i386_push_imm(cd, 1);
-                       i386_push_reg(cd, REG_RESULT);
-                       
-                       i386_mov_imm_reg(cd, (s4) asm_calljavafunction2, REG_ITMP3);
-                       i386_call_reg(cd, REG_ITMP3);
-
-                       /* check exceptionptr + fail (JOWENN)*/                 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_IST_IMM(0, REG_SP, 1 * 4);
+                       dseg_adddata(cd, cd->mcodeptr);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 2 * 4);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4); /* don't use ITMP2 till here */
+                       M_MOV_IMM((ptrint) stacktrace_create_inline_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
-                       i386_alu_imm_reg(cd, ALU_ADD,6*4,REG_SP);
+                       /* create exception */
 
-                       i386_pop_reg(cd, REG_ITMP1_XPTR);
-                       i386_pop_reg(cd, REG_ITMP3); /* just remove the no longer needed 0 from the stack*/
+                       M_MOV_IMM((ptrint) new_arithmeticexception, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+                       M_AST(REG_RESULT, REG_SP, 1 * 4);
 
-                       /*REMOVE_NATIVE_STACKINFO;*/
-                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* remove native stackframe info */
 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) stacktrace_remove_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
-                       i386_pop_reg(cd, REG_ITMP2_XPC);
+                       M_ALD(REG_ITMP1_XPTR, REG_SP, 1 * 4);
+                       M_ALD(REG_ITMP2_XPC, REG_SP, 4 * 4);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
 
-                       i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
-                       i386_jmp_reg(cd, REG_ITMP3);
+                       M_MOV_IMM((ptrint) asm_handle_exception, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
                }
        }
 
-       /* generate null pointer check stubs */
+       /* generate NullPointerException stubs */
 
        xcodeptr = NULL;
        
@@ -5326,7 +5441,7 @@ java stack at this point*/
                if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
                        gen_resolvebranch(cd->mcodebase + bref->branchpos, 
                                                          bref->branchpos,
-                                                         xcodeptr - cd->mcodebase - (5 + 5 + 2));
+                                                         xcodeptr - cd->mcodebase - (5 + 6));
                        continue;
                }
 
@@ -5336,64 +5451,135 @@ java stack at this point*/
                
                MCODECHECK(100);
 
-               i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
+               M_MOV_IMM(0, REG_ITMP2_XPC);                               /* 5 bytes */
                dseg_adddata(cd, cd->mcodeptr);
-               i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
-               i386_alu_reg_reg(cd, ALU_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
+               M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);          /* 6 bytes */
                
                if (xcodeptr != NULL) {
-                       i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
+                       M_JMP_IMM((xcodeptr - cd->mcodeptr) - 5);
                        
                } else {
                        xcodeptr = cd->mcodeptr;
                        
-                       i386_push_reg(cd, REG_ITMP2_XPC);
+                       M_ASUB_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 4 * 4);
 
-                       /*PREPARE_NATIVE_STACKINFO;*/
-                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
-                       i386_push_imm(cd,0);
-                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+                       /* create dynamic stack info */
 
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_IST_IMM(0, REG_SP, 1 * 4);
+                       dseg_adddata(cd, cd->mcodeptr);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 2 * 4);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4); /* don't use ITMP2 till here */
+                       M_MOV_IMM((ptrint) stacktrace_create_inline_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
+                       /* create exception */
 
-#if 0
-                       /* create native call block*/
-                       i386_alu_imm_reg(cd, ALU_SUB, 3*4, REG_SP); /* build stack frame (4 * 4 bytes) */
+                       M_MOV_IMM((ptrint) new_nullpointerexception, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+                       M_AST(REG_RESULT, REG_SP, 1 * 4);
 
+                       /* remove stackframe info */
 
-                       i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1);
-                       i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) stacktrace_remove_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
 
-                       i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1);
-                       i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/
-                       i386_mov_imm_membase(cd, 0,REG_SP, 2*4);        /* builtin */
-                       i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/
-                       i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */
-                       i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */
-                       i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */
-#endif                         
+                       M_ALD(REG_ITMP1_XPTR, REG_SP, 1 * 4);
+                       M_ALD(REG_ITMP2_XPC, REG_SP, 4 * 4);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
 
-                       i386_mov_imm_reg(cd, (u4) new_nullpointerexception, REG_ITMP1);
-                       i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
+                       M_MOV_IMM((ptrint) asm_handle_exception, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
+               }
+       }
 
-                       /*REMOVE_NATIVE_STACKINFO;*/
-                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
-                       i386_call_reg(cd,REG_ITMP3);
+       /* generate exception check stubs */
 
+       xcodeptr = NULL;
+       
+       for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
+               if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
+                       gen_resolvebranch(cd->mcodebase + bref->branchpos,
+                                                         bref->branchpos,
+                                                         xcodeptr - cd->mcodebase - (5 + 6));
+                       continue;
+               }
 
-#if 0
-                       /* restore native call stack */
-                       i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2);
-                       i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3);
-                       i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0);
-                       i386_alu_imm_reg(cd, ALU_ADD,3*4,REG_SP);
+               gen_resolvebranch(cd->mcodebase + bref->branchpos, 
+                                 bref->branchpos,
+                                                 cd->mcodeptr - cd->mcodebase);
+
+               MCODECHECK(200);
+
+               M_MOV_IMM(0, REG_ITMP2_XPC);                               /* 5 bytes */
+               dseg_adddata(cd, cd->mcodeptr);
+               M_AADD_IMM32(bref->branchpos - 6, REG_ITMP2_XPC);          /* 6 bytes */
+
+               if (xcodeptr != NULL) {
+                       i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
+               
+               } else {
+                       xcodeptr = cd->mcodeptr;
+
+                       M_ASUB_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 4 * 4);
+
+                       /* create dynamic stack info */
+
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_IST_IMM(0, REG_SP, 1 * 4);
+                       dseg_adddata(cd, cd->mcodeptr);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 2 * 4);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4); /* don't use ITMP2 till here */
+                       M_MOV_IMM((ptrint) stacktrace_create_inline_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+                       M_MOV_IMM((ptrint) &builtin_get_exceptionptrptr, REG_ITMP1);
+                       M_CALL(REG_ITMP1);
+                       M_ALD(REG_ITMP3, REG_RESULT, 0);
+                       M_AST_IMM(0, REG_RESULT, 0);
+                       M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
+#else
+                       M_MOV_IMM((ptrint) &_exceptionptr, REG_ITMP3);
+                       M_ALD(REG_ITMP1_XPTR, REG_ITMP3, 0);
+                       M_AST_IMM(0, REG_ITMP3, 0);
 #endif
 
-                       i386_pop_reg(cd, REG_ITMP2_XPC);
+                       M_AST(REG_ITMP1_XPTR, REG_SP, 1 * 4);
+
+                       /* call fillInStackTrace */
+
+                       M_AST(REG_ITMP1_XPTR, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) stacktrace_call_fillInStackTrace, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+
+                       /* remove stackframe info */
 
-                       i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
-                       i386_jmp_reg(cd, REG_ITMP3);
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(5 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                       M_MOV_IMM((ptrint) stacktrace_remove_stackframeinfo, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+
+                       M_ALD(REG_ITMP1_XPTR, REG_SP, 1 * 4);
+                       M_ALD(REG_ITMP2_XPC, REG_SP, 4 * 4);
+                       M_AADD_IMM(5 * 4 + sizeof(stackframeinfo), REG_SP);
+
+                       M_MOV_IMM((ptrint) asm_handle_exception, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
                }
        }
 
@@ -5417,15 +5603,6 @@ java stack at this point*/
                        xcodeptr = cd->mcodebase + pref->branchpos;
                        mcode = *((u8 *) xcodeptr);
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-                       /* create a virtual java_objectheader */
-
-                       *((ptrint *) (cd->mcodeptr + 0)) = 0;                    /* vftbl */
-                       *((ptrint *) (cd->mcodeptr + 4)) = (ptrint) get_dummyLR(); /* monitorPtr */
-
-                       cd->mcodeptr += 2 * 4;
-#endif
-
                        /* patch in `call rel32' to call the following code               */
 
                        tmpcd->mcodeptr = xcodeptr;     /* set dummy mcode pointer        */
@@ -5434,22 +5611,26 @@ java stack at this point*/
                        /* move pointer to java_objectheader onto stack */
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-                       i386_call_imm(cd, 0);
-                       i386_alu_imm_membase(cd, ALU_SUB, 5 + 2 * 4, REG_SP, 0);
+                       (void) dseg_addaddress(cd, get_dummyLR());          /* monitorPtr */
+                       off = dseg_addaddress(cd, NULL);                    /* vftbl      */
+
+                       M_MOV_IMM(0, REG_ITMP3);
+                       dseg_adddata(cd, cd->mcodeptr);
+                       M_AADD_IMM(off, REG_ITMP3);
+                       M_PUSH(REG_ITMP3);
 #else
-                       i386_push_imm(cd, 0);
+                       M_PUSH_IMM(0);
 #endif
 
                        /* move machine code bytes and classinfo pointer into registers */
 
-                       i386_push_imm(cd, (ptrint) (mcode >> 32));
-                       i386_push_imm(cd, (ptrint) mcode);
-                       i386_push_imm(cd, (ptrint) pref->ref);
+                       M_PUSH_IMM((ptrint) (mcode >> 32));
+                       M_PUSH_IMM((ptrint) mcode);
+                       M_PUSH_IMM((ptrint) pref->ref);
+                       M_PUSH_IMM((ptrint) pref->patcher);
 
-                       i386_push_imm(cd, (ptrint) pref->patcher);
-
-                       i386_mov_imm_reg(cd, (ptrint) asm_wrapper_patcher, REG_ITMP3);
-                       i386_jmp_reg(cd, REG_ITMP3);
+                       M_MOV_IMM((ptrint) asm_wrapper_patcher, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
                }
        }
        }
@@ -5521,7 +5702,6 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
        s4          t;
        s4          s1, s2, off;
        s4          stackframesize;
-       s4          stackframeoffset;
 
        /* set some variables */
 
@@ -5532,14 +5712,16 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
        /* previous pointer + method info + 4 offset native                       */
        /* already handled by nmd->memuse */
 
-       stackframesize = /* 4 + */ 16;
-       stackframeoffset = 4;
+       stackframesize =
+               sizeof(stackframeinfo) / SIZEOF_VOID_P +
+               4 * 4 +                         /* 4 arguments (create stackframe)    */
+               nmd->memuse;
 
 
        /* create method header */
 
        (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
-       (void) dseg_adds4(cd, 0 * 8);                           /* FrameSize      */
+       (void) dseg_adds4(cd, stackframesize * 4);              /* FrameSize      */
        (void) dseg_adds4(cd, 0);                               /* IsSync         */
        (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
        (void) dseg_adds4(cd, 0);                               /* IntSave        */
@@ -5554,21 +5736,18 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
        cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
 
 
-       /* if function is static, check for initialized */
+       /* calculate stackframe size for native function */
 
-       if (m->flags & ACC_STATIC) {
-               /* already handled by nmd->memuse */
-/*             stackframesize += 4; */
-               stackframeoffset += 4;
+       M_ASUB_IMM(stackframesize * 4, REG_SP);
 
-               /* if class isn't yet initialized, do it */
 
-               if (!m->class->initialized) {
-                       codegen_addpatchref(cd, cd->mcodeptr, PATCHER_clinit, m->class);
+       /* if function is static, check for initialized */
 
-                       if (showdisassemble) {
-                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
-                       }
+       if ((m->flags & ACC_STATIC) && !m->class->initialized) {
+               codegen_addpatchref(cd, cd->mcodeptr, PATCHER_clinit, m->class);
+
+               if (opt_showdisassemble) {
+                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                }
        }
 
@@ -5637,6 +5816,7 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
 
        /* Mark the whole fpu stack as free for native functions (only for saved  */
        /* register count == 0).                                                  */
+
        i386_ffree_reg(cd, 0);
        i386_ffree_reg(cd, 1);
        i386_ffree_reg(cd, 2);
@@ -5646,28 +5826,22 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
        i386_ffree_reg(cd, 6);
        i386_ffree_reg(cd, 7);
 
-       /* calculate stackframe size for native function */
-
-       stackframesize += nmd->memuse * 4;
 
-       i386_alu_imm_reg(cd, ALU_SUB, stackframesize, REG_SP);
+       /* create dynamic stack info */
 
-       /* CREATE DYNAMIC STACK INFO -- BEGIN*/
+       M_MOV(REG_SP, REG_ITMP1);
+       M_AADD_IMM(stackframesize * 4 - sizeof(stackframeinfo), REG_ITMP1);
+       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+       M_IST_IMM(0, REG_SP, 1 * 4);
+       dseg_adddata(cd, cd->mcodeptr);
+       M_MOV(REG_SP, REG_ITMP2);
+       M_AADD_IMM(stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
+       M_AST(REG_ITMP2, REG_SP, 2 * 4);
+       M_ALD(REG_ITMP3, REG_SP, stackframesize * 4);
+       M_AST(REG_ITMP3, REG_SP, 3 * 4);
+       M_MOV_IMM((ptrint) stacktrace_create_native_stackframeinfo, REG_ITMP1);
+       M_CALL(REG_ITMP1);
 
-       i386_mov_imm_membase(cd,0,REG_SP,stackframesize-4);
-       i386_mov_imm_membase(cd, (ptrint) m, REG_SP,stackframesize-8);
-       i386_mov_imm_reg(cd, (ptrint) builtin_asm_get_stackframeinfo, REG_ITMP1);
-       i386_call_reg(cd, REG_ITMP1);
-                                                /*save thread specific pointer*/
-       i386_mov_reg_membase(cd, REG_RESULT,REG_SP,stackframesize-12); 
-       i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); 
-  /*save previous value of memory adress pointed to by thread specific pointer*/
-       i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,stackframesize-16);
-       i386_mov_reg_reg(cd, REG_SP,REG_ITMP2);
-       i386_alu_imm_reg(cd, ALU_ADD,stackframesize-16,REG_ITMP2);
-       i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT,0);
-
-       /* CREATE DYNAMIC STACK INFO -- END*/
 
        /* copy arguments into new stackframe */
 
@@ -5677,14 +5851,14 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
                if (!md->params[i].inmemory) {
                        /* no integer argument registers */
                } else {       /* float/double in memory can be copied like int/longs */
-                       s1 = md->params[i].regoff * 4 + stackframesize + (1 * 4);
+                       s1 = (md->params[i].regoff + stackframesize + 1) * 4;
                        s2 = nmd->params[j].regoff * 4;
 
-                       i386_mov_membase_reg(cd, REG_SP, s1, REG_ITMP1);
-                       i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, s2);
+                       M_ILD(REG_ITMP1, REG_SP, s1);
+                       M_IST(REG_ITMP1, REG_SP, s2);
                        if (IS_2_WORD_TYPE(t)) {
-                               i386_mov_membase_reg(cd, REG_SP, s1 + 4, REG_ITMP1);
-                               i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, s2 + 4);
+                               M_ILD(REG_ITMP1, REG_SP, s1 + 4);
+                               M_IST(REG_ITMP1, REG_SP, s2 + 4);
                        }
                }
        }
@@ -5692,11 +5866,11 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
        /* if function is static, put class into second argument */
 
        if (m->flags & ACC_STATIC)
-               i386_mov_imm_membase(cd, (ptrint) m->class, REG_SP, 4);
+               i386_mov_imm_membase(cd, (ptrint) m->class, REG_SP, 1 * 4);
 
        /* put env into first argument */
 
-       i386_mov_imm_membase(cd, (ptrint) &env, REG_SP, 0);
+       i386_mov_imm_membase(cd, (ptrint) &env, REG_SP, 0 * 4);
 
        /* call the native function */
 
@@ -5704,7 +5878,7 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
        if (f == NULL)
                codegen_addpatchref(cd, cd->mcodeptr, PATCHER_resolve_native, m);
 
-               if (showdisassemble) {
+               if (opt_showdisassemble) {
                        M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
                }
 #endif
@@ -5713,15 +5887,31 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
        i386_call_reg(cd, REG_ITMP1);
 
 
-       /* REMOVE DYNAMIC STACK INFO -BEGIN */
-    i386_push_reg(cd, REG_RESULT2);
-    i386_mov_membase_reg(cd, REG_SP,stackframesize-12,REG_ITMP2); /*old value*/
-    i386_mov_membase_reg(cd, REG_SP,stackframesize-8,REG_RESULT2); /*pointer*/
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT2,0);
-    i386_pop_reg(cd, REG_RESULT2);
-       /* REMOVE DYNAMIC STACK INFO -END */
+       /* remove native stackframe info */
+
+       if (IS_INT_LNG_TYPE(md->returntype.type)) {
+               if (IS_2_WORD_TYPE(md->returntype.type))
+                       M_IST(REG_RESULT2, REG_SP, 2 * 4);
+               M_IST(REG_RESULT, REG_SP, 1 * 4);
+       
+       } else {
+               /* XXX save float? */
+       }
+
+       M_MOV(REG_SP, REG_ITMP1);
+       M_AADD_IMM(stackframesize * 4 - sizeof(stackframeinfo), REG_ITMP1);
+       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+       M_MOV_IMM((ptrint) stacktrace_remove_stackframeinfo, REG_ITMP1);
+       M_CALL(REG_ITMP1);
 
-    i386_alu_imm_reg(cd, ALU_ADD, stackframesize, REG_SP);
+       if (IS_INT_LNG_TYPE(md->returntype.type)) {
+               if (IS_2_WORD_TYPE(md->returntype.type))
+                       M_ILD(REG_RESULT2, REG_SP, 2 * 4);
+               M_ILD(REG_RESULT, REG_SP, 1 * 4);
+       
+       } else {
+               /* XXX save float? */
+       }
 
 
     if (runverbose) {
@@ -5745,6 +5935,9 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
     }
 
 
+       M_AADD_IMM(stackframesize * 4, REG_SP);
+
+
        /* check for exception */
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
@@ -5818,7 +6011,7 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
                        (void) dseg_addaddress(cd, get_dummyLR());          /* monitorPtr */
                        off = dseg_addaddress(cd, NULL);                    /* vftbl      */
 
-                       i386_mov_imm_reg(cd, 0, REG_ITMP3);
+                       M_MOV_IMM(0, REG_ITMP3);
                        dseg_adddata(cd, cd->mcodeptr);
                        M_AADD_IMM(off, REG_ITMP3);
                        M_PUSH(REG_ITMP3);
@@ -5828,14 +6021,13 @@ functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
 
                        /* move machine code bytes and classinfo pointer onto stack */
 
-                       i386_push_imm(cd, (ptrint) (mcode >> 32));
-                       i386_push_imm(cd, (ptrint) mcode);
-                       i386_push_imm(cd, (ptrint) pref->ref);
-
-                       i386_push_imm(cd, (ptrint) pref->patcher);
+                       M_PUSH_IMM((ptrint) (mcode >> 32));
+                       M_PUSH_IMM((ptrint) mcode);
+                       M_PUSH_IMM((ptrint) pref->ref);
+                       M_PUSH_IMM((ptrint) pref->patcher);
 
-                       i386_mov_imm_reg(cd, (ptrint) asm_wrapper_patcher, REG_ITMP3);
-                       i386_jmp_reg(cd, REG_ITMP3);
+                       M_MOV_IMM((ptrint) asm_wrapper_patcher, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
                }
        }
 
index 9432feaf9bcf36353d27fc712333411527e0ce2e..4fe675798cf2bd4b9e039f3c0380eb30b29e44a8 100644 (file)
@@ -29,7 +29,7 @@
 
    Changes:
 
-   $Id: codegen.h 2836 2005-06-26 23:51:36Z twisti $
+   $Id: codegen.h 2971 2005-07-10 15:33:54Z twisti $
 
 */
 
@@ -461,16 +461,36 @@ typedef enum {
 #define M_ALD(a,b,disp)         M_ILD(a,b,disp)
 
 #define M_IST(a,b,disp)         i386_mov_reg_membase(cd, (a), (b), (disp))
+#define M_IST_IMM(a,b,disp)     i386_mov_imm_membase(cd, (a), (b), (disp))
 #define M_AST(a,b,disp)         M_IST(a,b,disp)
+#define M_AST_IMM(a,b,disp)     M_IST_IMM(a,b,disp)
 
 #define M_IADD_IMM(a,b)         i386_alu_imm_reg(cd, ALU_ADD, (a), (b))
+#define M_IADD_IMM32(a,b)       i386_alu_imm32_reg(cd, ALU_ADD, (a), (b))
 #define M_ISUB_IMM(a,b)         i386_alu_imm_reg(cd, ALU_SUB, (a), (b))
 
 #define M_AADD_IMM(a,b)         M_IADD_IMM(a,b)
+#define M_AADD_IMM32(a,b)       M_IADD_IMM32(a,b)
 #define M_ASUB_IMM(a,b)         M_ISUB_IMM(a,b)
 
-#define M_PUSH(a)               i386_push_reg(cd, a)
-#define M_PUSH_IMM(a)           i386_push_imm(cd, a)
+#define M_OR_MEMBASE(a,b,c)     i386_alu_membase_reg(cd, ALU_OR, (a), (b), (c))
+
+#define M_PUSH(a)               i386_push_reg(cd, (a))
+#define M_PUSH_IMM(a)           i386_push_imm(cd, (a))
+#define M_POP(a)                i386_pop_reg(cd, (a))
+
+#define M_MOV(a,b)              i386_mov_reg_reg(cd, (a), (b))
+#define M_MOV_IMM(a,b)          i386_mov_imm_reg(cd, (a), (b))
+
+#define M_TEST(a)               i386_test_reg_reg(cd, (a), (a))
+
+#define M_CALL(a)               i386_call_reg(cd, (a))
+#define M_RET                   i386_ret(cd)
+
+#define M_BEQ(a)                i386_jcc(cd, I386_CC_E, (a))
+
+#define M_JMP(a)                i386_jmp_reg(cd, (a))
+#define M_JMP_IMM(a)            i386_jmp_imm(cd, (a))
 
 #define M_NOP                   i386_nop(cd)
 
index ae3a06bbec17f8052471fdbee165f7f1d656382a..99aee964f2bbe014cdb90070dd9b4228117efa65 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: md-os.c 2916 2005-07-05 13:59:43Z twisti $
+   $Id: md-os.c 2971 2005-07-10 15:33:54Z twisti $
 
 */
 
 
 #include <ucontext.h>
 
+#include "vm/exceptions.h"
 #include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/jit/asmpart.h"
+#include "vm/jit/stacktrace.h"
 
 
 /* signal_handler_sigsegv ******************************************************
 
 void signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 {
-       ucontext_t *_uc;
-       mcontext_t *_mc;
+       ucontext_t     *_uc;
+       mcontext_t     *_mc;
+       stackframeinfo *sfi;
+       u1             *sp;
+       functionptr     ra;
 
        _uc = (ucontext_t *) _p;
        _mc = &_uc->uc_mcontext;
 
-       _mc->gregs[REG_ECX] = _mc->gregs[REG_EIP];           /* REG_ITMP2_XPC     */
-       _mc->gregs[REG_EAX] = (ptrint) string_java_lang_NullPointerException;
-       _mc->gregs[REG_EIP] = (ptrint) asm_throw_and_handle_exception;
+       /* allocate stackframeinfo on heap */
+
+       sfi = NEW(stackframeinfo);
+
+       /* create exception */
+
+       sp = (u1 *) _mc->gregs[REG_ESP];
+       ra = (functionptr) _mc->gregs[REG_EIP];
+
+       stacktrace_create_inline_stackframeinfo(sfi, NULL, sp, ra);
+
+       _mc->gregs[REG_EAX] = (ptrint) new_nullpointerexception();
+
+       stacktrace_remove_stackframeinfo(sfi);
+
+       FREE(sfi, stackframeinfo);
+
+       _mc->gregs[REG_ECX] = _mc->gregs[REG_EIP];               /* REG_ITMP2_XPC */
+       _mc->gregs[REG_EIP] = (ptrint) asm_handle_exception;
 }
 
 
@@ -70,15 +91,34 @@ void signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
 void signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
 {
-       ucontext_t *_uc;
-       mcontext_t *_mc;
+       ucontext_t     *_uc;
+       mcontext_t     *_mc;
+       stackframeinfo *sfi;
+       u1             *sp;
+       functionptr     ra;
 
        _uc = (ucontext_t *) _p;
        _mc = &_uc->uc_mcontext;
 
-       _mc->gregs[REG_ECX] = _mc->gregs[REG_EIP];           /* REG_ITMP2_XPC     */
-       _mc->gregs[REG_EIP] =
-               (ptrint) asm_throw_and_handle_hardware_arithmetic_exception;
+       /* allocate stackframeinfo on heap */
+
+       sfi = NEW(stackframeinfo);
+
+       /* create exception */
+
+       sp = (u1 *) _mc->gregs[REG_ESP];
+       ra = (functionptr) _mc->gregs[REG_EIP];
+
+       stacktrace_create_inline_stackframeinfo(sfi, NULL, sp, ra);
+
+       _mc->gregs[REG_EAX] = (ptrint) new_arithmeticexception();
+
+       stacktrace_remove_stackframeinfo(sfi);
+
+       FREE(sfi, stackframeinfo);
+
+       _mc->gregs[REG_ECX] = _mc->gregs[REG_EIP];               /* REG_ITMP2_XPC */
+       _mc->gregs[REG_EIP] = (ptrint) asm_handle_exception;
 }
 
 
index df764b6e252042c09f777539ef97f7d5c9a2f457..e10c10cdc8c7ccb96cbe4d6216ec47a68bfa4e92 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: patcher.c 2773 2005-06-22 09:26:04Z twisti $
+   $Id: patcher.c 2971 2005-07-10 15:33:54Z twisti $
 
 */
 
@@ -101,7 +101,7 @@ bool patcher_get_putstatic(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch the field value's address */
@@ -160,7 +160,7 @@ bool patcher_getfield(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch the field's offset */
@@ -224,7 +224,7 @@ bool patcher_putfield(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch the field's offset */
@@ -297,7 +297,7 @@ bool patcher_putfieldconst(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch the field's offset */
@@ -374,7 +374,7 @@ bool patcher_builtin_new(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch new function address */
@@ -439,7 +439,7 @@ bool patcher_builtin_newarray(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch new function address */
@@ -504,7 +504,7 @@ bool patcher_builtin_multianewarray(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch the class' vftbl pointer */
@@ -525,10 +525,10 @@ bool patcher_builtin_multianewarray(u1 *sp)
 
    Machine code:
 
-   c7 44 24 08 00 00 00 00    movl   $0x00000000,0x8(%esp)
    <patched call position>
-   b8 00 00 00 00             mov    $0x00000000,%eax
-   ff d0                      call   *%eax
+   c7 44 24 04 00 00 00 00    movl   $0x00000000,0x4(%esp)
+   ba 00 00 00 00             mov    $0x00000000,%edx
+   ff d2                      call   *%edx
 
 *******************************************************************************/
 
@@ -549,7 +549,7 @@ bool patcher_builtin_arraycheckcast(u1 *sp)
 
        /* calculate and set the new return address */
 
-       ra = ra - (8 + 5);
+       ra = ra - 5;
        *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
 
        PATCHER_MONITORENTER;
@@ -564,18 +564,18 @@ bool patcher_builtin_arraycheckcast(u1 *sp)
 
        /* patch back original code */
 
-       *((u4 *) (ra + 8 + 0)) = (u4) mcode;
-       *((u1 *) (ra + 8 + 4)) = (u1) (mcode >> 32);
-
-       /* patch the class' vftbl pointer */
-
-       *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
+       *((u4 *) (ra + 0)) = (u4) mcode;
+       *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
+       /* patch the class' vftbl pointer */
+
+       *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
+
        /* patch new function address */
 
        *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arraycheckcast;
@@ -638,7 +638,7 @@ bool patcher_builtin_arrayinstanceof(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch new function address */
@@ -698,7 +698,7 @@ bool patcher_invokestatic_special(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch stubroutine */
@@ -759,7 +759,7 @@ bool patcher_invokevirtual(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch vftbl index */
@@ -822,7 +822,7 @@ bool patcher_invokeinterface(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch interfacetable index */
@@ -887,7 +887,7 @@ bool patcher_checkcast_instanceof_flags(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch class flags */
@@ -950,7 +950,7 @@ bool patcher_checkcast_instanceof_interface(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch super class index */
@@ -1017,7 +1017,7 @@ bool patcher_checkcast_class(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch super class' vftbl */
@@ -1080,7 +1080,7 @@ bool patcher_instanceof_class(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch super class' vftbl */
@@ -1157,6 +1157,7 @@ bool patcher_clinit(u1 *sp)
 
 *******************************************************************************/
 
+#if !defined(ENABLE_STATICVM)
 bool patcher_resolve_native(u1 *sp)
 {
        u1                *ra;
@@ -1194,7 +1195,7 @@ bool patcher_resolve_native(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (showdisassemble)
+       if (opt_showdisassemble)
                ra = ra + 5;
 
        /* patch native function pointer */
@@ -1205,6 +1206,7 @@ bool patcher_resolve_native(u1 *sp)
 
        return true;
 }
+#endif /* !defined(ENABLE_STATICVM) */
 
 
 /*