GNU header update.
[cacao.git] / src / vm / jit / alpha / codegen.c
index da7cd586d3fd76cee5c541199854a407b6ef878d..ccec552f6e5746ae8746091d001e75e8bbac8bb1 100644 (file)
@@ -1,10 +1,9 @@
-/* jit/alpha/codegen.c - machine code generator for alpha
+/* vm/jit/alpha/codegen.c - machine code generator for alpha
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Institut f. Computersprachen, TU Wien
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
-   S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
-   J. Wenninger
+   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
    Authors: Andreas Krall
             Reinhard Grafl
 
-   $Id: codegen.c 1507 2004-11-14 17:02:15Z jowenn $
+   Changes: Joseph Wenninger
+
+   $Id: codegen.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
 
-#include "global.h"
 #include <stdio.h>
 #include <signal.h>
-#include "types.h"
-#include "main.h"
-#include "jit/alpha/codegen.h"
-#include "jit/jit.h"
-#include "jit/parse.h"
-#include "jit/reg.h"
-#include "builtin.h"
-#include "asmpart.h"
-#include "jni.h"
-#include "loader.h"
-#include "tables.h"
-#include "native.h"
-#include "main.h"
+
+#include "vm/jit/alpha/arch.h"
+#include "native/native.h"
+#include "vm/builtin.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/tables.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+#ifdef LSRA
+#include "vm/jit/lsra.h"
+#endif
+#include "vm/jit/parse.h"
+#include "vm/jit/reg.h"
+#include "vm/jit/alpha/codegen.h"
+#include "vm/jit/alpha/types.h"
+#include "vm/jit/alpha/asmoffsets.h"
 
 
 /* *****************************************************************************
@@ -104,13 +108,15 @@ int nregdescfloat[] = {
        REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES,
        REG_END };
 
-/* for use of reserved registers, see comment above */
 
-/* include independent code generation stuff -- include after register        */
-/* descriptions to avoid extern definitions                                   */
+/* Include independent code generation stuff -- include after register        */
+/* descriptions to avoid extern definitions.                                  */
 
-#include "jit/codegen.inc"
-#include "jit/reg.inc"
+#include "vm/jit/codegen.inc"
+#include "vm/jit/reg.inc"
+#ifdef LSRA
+#include "vm/jit/lsra.inc"
+#endif
 
 
 /* NullPointerException handlers and exception handling initialisation        */
@@ -163,16 +169,19 @@ void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
        faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
 
        if (faultaddr == 0) {
-               signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
+               /* reinstall handler */
+               signal(sig, (functionptr) catch_NullPointerException);
                sigemptyset(&nsig);
                sigaddset(&nsig, sig);
                sigprocmask(SIG_UNBLOCK, &nsig, NULL);           /* unblock signal    */
 
-               xptr = new_exception(string_java_lang_NullPointerException);
+               /*xptr = new_nullpointerexception();
+               sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;*/
 
-               sigctx->sc_regs[REG_ITMP1_XPTR] = (u8) xptr;
+               sigctx->sc_regs[REG_ITMP1_XPTR]=string_java_lang_NullPointerException;
                sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
-               sigctx->sc_pc = (u8) asm_handle_exception;
+               /*sigctx->sc_pc = (u8) asm_handle_exception;*/
+               sigctx->sc_pc = (u8) asm_throw_and_handle_exception;
                return;
 
        } else {
@@ -215,11 +224,11 @@ ieee_set_fp_control(ieee_get_fp_control()
 
        if (!checknull) {
 #if defined(SIGSEGV)
-               signal(SIGSEGV, (void*) catch_NullPointerException);
+               signal(SIGSEGV, (functionptr) catch_NullPointerException);
 #endif
 
 #if defined(SIGBUS)
-               signal(SIGBUS, (void*) catch_NullPointerException);
+               signal(SIGBUS, (functionptr) catch_NullPointerException);
 #endif
        }
 }
@@ -242,7 +251,7 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
        basicblock     *bptr;
        instruction    *iptr;
        exceptiontable *ex;
-
+       u2 currentline=0;
        {
        s4 i, p, pa, t, l;
        s4 savedregs_num;
@@ -499,9 +508,26 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                src = bptr->instack;
                len = bptr->indepth;
                MCODECHECK(64+len);
+#ifdef LSRA
+               if (opt_lsra) {
                while (src != NULL) {
                        len--;
                        if ((len == 0) && (bptr->type != BBTYPE_STD)) {
+                                       /*                              d = reg_of_var(m, src, REG_ITMP1); */
+                                       if (!(src->flags & INMEMORY))
+                                               d= src->regoff;
+                                       else
+                                               d=REG_ITMP1;
+                                       M_INTMOVE(REG_ITMP1, d);
+                                       store_reg_to_var_int(src, d);
+                               }
+                               src = src->prev;
+                       }
+               } else {
+#endif
+                       while (src != NULL) {
+                               len--;
+                               if ((len == 0) && (bptr->type != BBTYPE_STD)) {
                                d = reg_of_var(rd, src, REG_ITMP1);
                                M_INTMOVE(REG_ITMP1, d);
                                store_reg_to_var_int(src, d);
@@ -534,6 +560,9 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                                }
                        src = src->prev;
                        }
+#ifdef LSRA
+               }
+#endif
 
                /* walk through all instructions */
                
@@ -543,6 +572,11 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                    len > 0;
                    src = iptr->dst, len--, iptr++) {
 
+               if (iptr->line!=currentline) {
+                       dseg_addlinenumber(cd,iptr->line,mcodeptr);
+                       currentline=iptr->line;
+               }
+
        MCODECHECK(64);           /* an instruction usually needs < 64 words      */
        switch (iptr->opc) {
 
@@ -2099,26 +2133,16 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
                                      /* op1 = type, val.a = field address            */
 
-                       /* if class isn't yet initialized, do it */
+                       /* If the static fields' class is not yet initialized, we do it   */
+                       /* now. The call code is generated later.                         */
                        if (!((fieldinfo *) iptr->val.a)->class->initialized) {
-                               /* call helper function which patches this code */
-                               a = dseg_addaddress(cd, ((fieldinfo *) iptr->val.a)->class);
-                               M_ALD(REG_ITMP1, REG_PV, a);
-                               a = dseg_addaddress(cd, asm_check_clinit);
-                               M_ALD(REG_PV, REG_PV, a);
-                               M_JSR(REG_RA, REG_PV);
+                               codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
 
-                               /* recompute pv */
-                               s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
-                               if (s1 <= 32768) {
-                                       M_LDA(REG_PV, REG_RA, -s1);
+                               /* This is just for debugging purposes. Is very difficult to  */
+                               /* read patched code. Here we patch the following 2 nop's     */
+                               /* so that the real code keeps untouched.                     */
+                               if (showdisassemble) {
                                        M_NOP;
-
-                               } else {
-                                       s4 ml = -s1, mh = 0;
-                                       while (ml < -32768) { ml += 65536; mh--; }
-                                       M_LDA(REG_PV, REG_RA, ml);
-                                       M_LDAH(REG_PV, REG_PV, mh);
                                }
                        }
                        
@@ -2154,24 +2178,13 @@ void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
                        /* if class isn't yet initialized, do it */
                        if (!((fieldinfo *) iptr->val.a)->class->initialized) {
-                               /* call helper function which patches this code */
-                               a = dseg_addaddress(cd, ((fieldinfo *) iptr->val.a)->class);
-                               M_ALD(REG_ITMP1, REG_PV, a);
-                               a = dseg_addaddress(cd, asm_check_clinit);
-                               M_ALD(REG_PV, REG_PV, a);
-                               M_JSR(REG_RA, REG_PV);
+                               codegen_addclinitref(cd, mcodeptr, ((fieldinfo *) iptr->val.a)->class);
 
-                               /* recompute pv */
-                               s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
-                               if (s1 <= 32768) {
-                                       M_LDA(REG_PV, REG_RA, -s1);
+                               /* This is just for debugging purposes. Is very difficult to  */
+                               /* read patched code. Here we patch the following 2 nop's     */
+                               /* so that the real code keeps untouched.                     */
+                               if (showdisassemble) {
                                        M_NOP;
-
-                               } else {
-                                       s4 ml = -s1, mh = 0;
-                                       while (ml < -32768) { ml += 65536; mh--; }
-                                       M_LDA(REG_PV, REG_RA, ml);
-                                       M_LDAH(REG_PV, REG_PV, mh);
                                }
                        }
                        
@@ -3478,6 +3491,9 @@ gen_method: {
        src = bptr->outstack;
        len = bptr->outdepth;
        MCODECHECK(64+len);
+#ifdef LSRA
+       if (!opt_lsra) 
+#endif
        while (src) {
                len--;
                if ((src->varkind != STACKVAR)) {
@@ -3506,6 +3522,8 @@ gen_method: {
        } /* if (bptr -> flags >= BBREACHED) */
        } /* for basic block */
 
+       codegen_createlinenumbertable(cd);
+
        {
        /* generate bound check stubs */
 
@@ -3529,36 +3547,20 @@ gen_method: {
                } else {
                        xcodeptr = mcodeptr;
 
-                       M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
-                       M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
-
-                       a = dseg_addaddress(cd, string_java_lang_ArrayIndexOutOfBoundsException);
-                       M_ALD(rd->argintregs[0], REG_PV, a);
-                       M_MOV(REG_ITMP1, rd->argintregs[1]);
+                        a = dseg_addaddress(cd, asm_throw_and_handle_arrayindexoutofbounds_exception);
+                        M_ALD(REG_PV, REG_PV, a);
 
-                       a = dseg_addaddress(cd, new_exception_int);
-                       M_ALD(REG_PV, REG_PV, a);
-                       M_JSR(REG_RA, REG_PV);
+                        M_JSR(REG_RA, REG_PV);
 
-                       /* recompute pv */
-                       s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
-                       if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
-                       else {
-                               s4 ml = -s1, mh = 0;
-                               while (ml < -32768) { ml += 65536; mh--; }
-                               M_LDA(REG_PV, REG_RA, ml);
-                               M_LDAH(REG_PV, REG_PV, mh);
-                       }
-
-                       M_MOV(REG_RESULT, REG_ITMP1_XPTR);
-
-                       M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
-                       M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
-
-                       a = dseg_addaddress(cd, asm_handle_exception);
-                       M_ALD(REG_ITMP3, REG_PV, a);
-
-                       M_JMP(REG_ZERO, REG_ITMP3);
+                        /* recompute pv */
+                        s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
+                        if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
+                        else {
+                                s4 ml = -s1, mh = 0;
+                                while (ml < -32768) { ml += 65536; mh--; }
+                                M_LDA(REG_PV, REG_RA, ml);
+                                M_LDAH(REG_PV, REG_PV, mh);
+                        }
                }
        }
 
@@ -3588,16 +3590,15 @@ gen_method: {
                } else {
                        xcodeptr = mcodeptr;
 
-                       M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
-                       M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
-
+                       
                        a = dseg_addaddress(cd, string_java_lang_NegativeArraySizeException);
-                       M_ALD(rd->argintregs[0], REG_PV, a);
+                       M_ALD(REG_ITMP1_XPTR,REG_PV,a);
 
-                       a = dseg_addaddress(cd, new_exception);
+                       a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
                        M_ALD(REG_PV, REG_PV, a);
-                       M_JSR(REG_RA, REG_PV);
 
+                       M_JSR(REG_RA, REG_PV);
+               
                        /* recompute pv */
                        s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
                        if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
@@ -3608,15 +3609,7 @@ gen_method: {
                                M_LDAH(REG_PV, REG_PV, mh);
                        }
 
-                       M_MOV(REG_RESULT, REG_ITMP1_XPTR);
-
-                       M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
-                       M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
-
-                       a = dseg_addaddress(cd, asm_handle_exception);
-                       M_ALD(REG_ITMP3, REG_PV, a);
 
-                       M_JMP(REG_ZERO, REG_ITMP3);
                }
        }
 
@@ -3646,35 +3639,24 @@ gen_method: {
                } else {
                        xcodeptr = mcodeptr;
 
-                       M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
-                       M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
-
                        a = dseg_addaddress(cd, string_java_lang_ClassCastException);
-                       M_ALD(rd->argintregs[0], REG_PV, a);
+                        M_ALD(REG_ITMP1_XPTR,REG_PV,a);
 
-                       a = dseg_addaddress(cd, new_exception);
-                       M_ALD(REG_PV, REG_PV, a);
-                       M_JSR(REG_RA, REG_PV);
+                        a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
+                        M_ALD(REG_PV, REG_PV, a);
 
-                       /* recompute pv */
-                       s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
-                       if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
-                       else {
-                               s4 ml = -s1, mh = 0;
-                               while (ml < -32768) { ml += 65536; mh--; }
-                               M_LDA(REG_PV, REG_RA, ml);
-                               M_LDAH(REG_PV, REG_PV, mh);
-                       }
+                        M_JSR(REG_RA, REG_PV);
 
-                       M_MOV(REG_RESULT, REG_ITMP1_XPTR);
+                        /* recompute pv */
+                        s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
+                        if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
+                        else {
+                                s4 ml = -s1, mh = 0;
+                                while (ml < -32768) { ml += 65536; mh--; }
+                                M_LDA(REG_PV, REG_RA, ml);
+                                M_LDAH(REG_PV, REG_PV, mh);
+                        }
 
-                       M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
-                       M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
-
-                       a = dseg_addaddress(cd, asm_handle_exception);
-                       M_ALD(REG_ITMP3, REG_PV, a);
-
-                       M_JMP(REG_ZERO, REG_ITMP3);
                }
        }
 
@@ -3734,10 +3716,21 @@ gen_method: {
                        M_AST(REG_ZERO, REG_ITMP3, 0);
 #endif
 
-                       a = dseg_addaddress(cd, asm_handle_exception);
-                       M_ALD(REG_ITMP3, REG_PV, a);
+                       a = dseg_addaddress(cd, asm_refillin_and_handle_exception);
+                       M_ALD(REG_PV, REG_PV, a);
+
+                       M_JMP(REG_RA, REG_PV);
+               
+                       /* recompute pv */
+                       s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
+                       if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
+                       else {
+                               s4 ml = -s1, mh = 0;
+                               while (ml < -32768) { ml += 65536; mh--; }
+                               M_LDA(REG_PV, REG_RA, ml);
+                               M_LDAH(REG_PV, REG_PV, mh);
+                       }
 
-                       M_JMP(REG_ZERO, REG_ITMP3);
                }
        }
 
@@ -3767,35 +3760,65 @@ gen_method: {
                } else {
                        xcodeptr = mcodeptr;
 
-                       M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
-                       M_LST(REG_ITMP2_XPC, REG_SP, 0 * 8);
-
                        a = dseg_addaddress(cd, string_java_lang_NullPointerException);
-                       M_ALD(rd->argintregs[0], REG_PV, a);
+                        M_ALD(REG_ITMP1_XPTR,REG_PV,a);
 
-                       a = dseg_addaddress(cd, new_exception);
-                       M_ALD(REG_PV, REG_PV, a);
-                       M_JSR(REG_RA, REG_PV);
+                        a = dseg_addaddress(cd, asm_throw_and_handle_nat_exception);
+                        M_ALD(REG_PV, REG_PV, a);
 
-                       /* recompute pv */
-                       s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
-                       if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
-                       else {
-                               s4 ml = -s1, mh = 0;
-                               while (ml < -32768) { ml += 65536; mh--; }
-                               M_LDA(REG_PV, REG_RA, ml);
-                               M_LDAH(REG_PV, REG_PV, mh);
-                       }
+                        M_JSR(REG_RA, REG_PV);
 
-                       M_MOV(REG_RESULT, REG_ITMP1_XPTR);
+                        /* recompute pv */
+                        s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
+                        if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
+                        else {
+                                s4 ml = -s1, mh = 0;
+                                while (ml < -32768) { ml += 65536; mh--; }
+                                M_LDA(REG_PV, REG_RA, ml);
+                                M_LDAH(REG_PV, REG_PV, mh);
+                        }
 
-                       M_LLD(REG_ITMP2_XPC, REG_SP, 0 * 8);
-                       M_LADD_IMM(REG_SP, 1 * 8, REG_SP);
+               }
+       }
 
-                       a = dseg_addaddress(cd, asm_handle_exception);
-                       M_ALD(REG_ITMP3, REG_PV, a);
+       /* generate put/getstatic stub call code */
+
+       {
+               clinitref   *cref;
+               u4           mcode;
+               s4          *tmpmcodeptr;
+
+               for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
+                       /* Get machine code which is patched back in later. The call is   */
+                       /* 1 instruction word long.                                       */
+                       xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
+                       mcode = *xcodeptr;
+
+                       /* patch in the call to call the following code (done at compile  */
+                       /* time)                                                          */
+
+                       tmpmcodeptr = mcodeptr;         /* save current mcodeptr          */
+                       mcodeptr = xcodeptr;            /* set mcodeptr to patch position */
+
+                       M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
+
+                       mcodeptr = tmpmcodeptr;         /* restore the current mcodeptr   */
+
+                       MCODECHECK(6);
 
-                       M_JMP(REG_ZERO, REG_ITMP3);
+                       /* move class pointer into REG_ITMP2                              */
+                       a = dseg_addaddress(cd, cref->class);
+                       M_ALD(REG_ITMP1, REG_PV, a);
+
+                       /* move machine code onto stack                                   */
+                       a = dseg_adds4(cd, mcode);
+                       M_ILD(REG_ITMP3, REG_PV, a);
+                       M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
+                       M_IST(REG_ITMP3, REG_SP, 0);
+
+                       a = dseg_addaddress(cd, asm_check_clinit);
+                       M_ALD(REG_ITMP2, REG_PV, a);
+                       M_JMP(REG_ZERO, REG_ITMP2);
                }
        }
        }
@@ -3851,18 +3874,36 @@ void removecompilerstub(u1 *stub)
 
 *******************************************************************************/
 
+
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-#define NATIVESTUBSTACK          2
-#define NATIVESTUBTHREADEXTRA    6
+#define NATIVESTUB_STACK          8/*ra,native result, oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
+#define NATIVESTUB_THREAD_EXTRA    (6 + 20) /*20 for additional frame creation*/
+#define NATIVESTUB_STACKTRACE_OFFSET   1
 #else
-#define NATIVESTUBSTACK          1
-#define NATIVESTUBTHREADEXTRA    1
+#define NATIVESTUB_STACK          7/*ra,oldThreadspecificHeadValue, addressOfThreadspecificHead, method, 0,0,ra*/
+#define NATIVESTUB_THREAD_EXTRA    (1 + 20) /*20 for additional frame creation*/
+#define NATIVESTUB_STACKTRACE_OFFSET   0
 #endif
 
-#define NATIVESTUBSIZE           (44 + NATIVESTUBTHREADEXTRA - 1)
-#define NATIVESTATICSIZE         5
-#define NATIVEVERBOSESIZE        (39 + 13)
-#define NATIVESTUBOFFSET         9
+#define NATIVESTUB_SIZE           (44 + NATIVESTUB_THREAD_EXTRA - 1)
+#define NATIVESTUB_STATIC_SIZE         5
+#define NATIVESTUB_VERBOSE_SIZE        (39 + 13)
+#define NATIVESTUB_OFFSET         11
+
+#if 0
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#define NATIVESTUB_STACK           2
+#define NATIVESTUB_THREAD_EXTRA    6
+#else
+#define NATIVESTUB_STACK           1
+#define NATIVESTUB_THREAD_EXTRA    1
+#endif
+
+#define NATIVESTUB_SIZE            (44 + NATIVESTUB_THREAD_EXTRA - 1)
+#define NATIVESTUB_STATIC_SIZE     4
+#define NATIVESTUB_VERBOSE_SIZE    (39 + 13)
+#define NATIVESTUB_OFFSET          10
+#endif
 
 u1 *createnativestub(functionptr f, methodinfo *m)
 {
@@ -3872,16 +3913,18 @@ u1 *createnativestub(functionptr f, methodinfo *m)
        s4 stackframesize = 0;              /* size of stackframe if needed       */
        s4 disp;
        s4 stubsize;
-       s4 dumpsize;
+       codegendata  *cd;
        registerdata *rd;
        t_inlining_globals *id;
+       s4 dumpsize;
 
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
 
        /* setup registers before using it */
-       
+
+       cd = DNEW(codegendata);
        rd = DNEW(registerdata);
        id = DNEW(t_inlining_globals);
 
@@ -3890,51 +3933,54 @@ u1 *createnativestub(functionptr f, methodinfo *m)
 
        descriptor2types(m);                /* set paramcount and paramtypes      */
 
-       stubsize = NATIVESTUBSIZE;          /* calculate nativestub size          */
+       stubsize = NATIVESTUB_SIZE;         /* calculate nativestub size          */
+
        if ((m->flags & ACC_STATIC) && !m->class->initialized)
-               stubsize += NATIVESTATICSIZE;
+               stubsize += NATIVESTUB_STATIC_SIZE;
 
        if (runverbose)
-               stubsize += NATIVEVERBOSESIZE;
+               stubsize += NATIVESTUB_VERBOSE_SIZE;
 
        s = CNEW(u8, stubsize);             /* memory to hold the stub            */
-       cs = s + NATIVESTUBOFFSET;
-       mcodeptr = (s4 *) (cs);             /* code generation pointer            */
+       cs = s + NATIVESTUB_OFFSET;
+       mcodeptr = (s4 *) cs;               /* code generation pointer            */
+
+       /* set some required varibles which are normally set by codegen_setup     */
+       cd->mcodebase = (u1 *) mcodeptr;
+       cd->clinitrefs = NULL;
 
-       *(cs-1) = (u8) f;                   /* address of native method           */
+       *(cs-1)  = (u8) f;                  /* address of native method           */
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       *(cs-2) = (u8) &builtin_get_exceptionptrptr;
+       *(cs-2)  = (u8) &builtin_get_exceptionptrptr;
 #else
-       *(cs-2) = (u8) (&_exceptionptr);    /* address of exceptionptr            */
+       *(cs-2)  = (u8) (&_exceptionptr);   /* address of exceptionptr            */
 #endif
-       *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
-       *(cs-4) = (u8) (&env);              /* addr of jni_environement           */
-       *(cs-5) = (u8) builtin_trace_args;
-       *(cs-6) = (u8) m;
-       *(cs-7) = (u8) builtin_displaymethodstop;
-       *(cs-8) = (u8) m->class;
-       *(cs-9) = (u8) asm_check_clinit;
-
-       M_LDA(REG_SP, REG_SP, -NATIVESTUBSTACK * 8);      /* build up stackframe  */
+       *(cs-3)  = (u8) asm_handle_nat_exception; /* addr of asm exception handler*/
+       *(cs-4)  = (u8) (&env);             /* addr of jni_environement           */
+       *(cs-5)  = (u8) builtin_trace_args;
+       *(cs-6)  = (u8) m;
+       *(cs-7)  = (u8) builtin_displaymethodstop;
+       *(cs-8)  = (u8) m->class;
+       *(cs-9)  = (u8) asm_check_clinit;
+       *(cs-10) = (u8) &builtin_asm_get_stackframeinfo;
+       *(cs-11) = (u8) NULL;               /* filled with machine code           */
+
+       M_LDA(REG_SP, REG_SP, -NATIVESTUB_STACK * 8);     /* build up stackframe  */
        M_AST(REG_RA, REG_SP, 0 * 8);       /* store return address               */
 
+       M_AST(REG_RA, REG_SP, (6+NATIVESTUB_STACKTRACE_OFFSET) * 8);       /* store return address  in stackinfo helper*/
+
        /* if function is static, check for initialized */
 
        if (m->flags & ACC_STATIC) {
        /* if class isn't yet initialized, do it */
                if (!m->class->initialized) {
-                       /* call helper function which patches this code */
-                       M_ALD(REG_ITMP1, REG_PV, -8 * 8);     /* class                    */
-                       M_ALD(REG_PV, REG_PV, -9 * 8);        /* asm_check_clinit         */
-                       M_JSR(REG_RA, REG_PV);
-                       disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
-                       M_LDA(REG_PV, REG_RA, disp);
-                       M_NOP;                  /* this is essential for code patching    */
+                       codegen_addclinitref(cd, mcodeptr, m->class);
                }
        }
 
-       /* max. 39 instructions */
-       if (runverbose) {
+       /* max. 39 +9 instructions */
+       {
                s4 p;
                s4 t;
                M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
@@ -3964,12 +4010,38 @@ u1 *createnativestub(functionptr f, methodinfo *m)
                        }
                }
 
-               M_ALD(REG_ITMP1, REG_PV, -6 * 8);
-               M_AST(REG_ITMP1, REG_SP, 0 * 8);
-               M_ALD(REG_PV, REG_PV, -5 * 8);
-               M_JSR(REG_RA, REG_PV);
-               disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
-               M_LDA(REG_PV, REG_RA, disp);
+               if (runverbose) {
+                       M_ALD(REG_ITMP1, REG_PV, -6 * 8);
+                       M_AST(REG_ITMP1, REG_SP, 0 * 8);
+                       M_ALD(REG_PV, REG_PV, -5 * 8);
+                       M_JSR(REG_RA, REG_PV);
+                       disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
+                       M_LDA(REG_PV, REG_RA, disp);
+               }
+
+
+/*stack info */
+                M_ALD(REG_PV, REG_PV, -10 * 8);      /* builtin_asm_get_stackframeinfo        */
+                M_JSR(REG_RA, REG_PV);
+                disp = -(s4) (mcodeptr - (s4 *) cs) * 4;
+                M_LDA(REG_PV, REG_RA, disp);
+
+#if 0
+                M_MOV(REG_RESULT,REG_ITMP3);
+                M_LST(REG_RESULT,REG_ITMP3,0);
+#endif
+                M_LST(REG_RESULT,REG_SP, ((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)+(2+NATIVESTUB_STACKTRACE_OFFSET)*8);/*save adress of pointer*/
+                M_LLD(REG_ITMP3,REG_RESULT,0); /* get pointer*/
+                M_LST(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*save old value*/
+                M_LDA(REG_ITMP3,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8)); /*calculate new value*/
+                M_LLD(REG_ITMP2,REG_ITMP3,8);
+                M_LST(REG_ITMP3,REG_ITMP2,0); /*store new value*/
+                M_LLD(REG_ITMP2,REG_PV,-6*8);
+                M_LST(REG_ITMP2,REG_SP,(3+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
+                M_LST(REG_ZERO,REG_SP,(4+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
+                M_LST(REG_ZERO,REG_SP,(5+NATIVESTUB_STACKTRACE_OFFSET)*8+((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
+/*stack info -end */
+
 
                for (p = 0; p < m->paramcount && p < INT_ARG_CNT; p++) {
                        M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
@@ -4090,6 +4162,10 @@ u1 *createnativestub(functionptr f, methodinfo *m)
                M_LDA(REG_SP, REG_SP, 2 * 8);
        }
 
+        M_LLD(REG_ITMP3,REG_SP,(2+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get address of stacktrace helper pointer*/
+        M_LLD(REG_ITMP1,REG_SP,(1+NATIVESTUB_STACKTRACE_OFFSET)*8); /*get old value*/
+        M_LST(REG_ITMP1,REG_ITMP3,0); /*set old value*/
+
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
        if (IS_FLT_DBL_TYPE(m->returntype))
                M_DST(REG_FRESULT, REG_SP, 1 * 8);
@@ -4111,31 +4187,70 @@ u1 *createnativestub(functionptr f, methodinfo *m)
        M_BNEZ(REG_ITMP1, 3);               /* if no exception then return        */
 
        M_ALD(REG_RA, REG_SP, 0 * 8);       /* load return address                */
-       M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe          */
+       M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe         */
        M_RET(REG_ZERO, REG_RA);            /* return to caller                   */
 
        M_AST(REG_ZERO, REG_ITMP3, 0);      /* store NULL into exceptionptr       */
 
        M_ALD(REG_RA, REG_SP, 0 * 8);       /* load return address                */
-       M_LDA(REG_SP, REG_SP, NATIVESTUBSTACK * 8); /* remove stackframe          */
+       M_LDA(REG_SP, REG_SP, NATIVESTUB_STACK * 8); /* remove stackframe         */
        M_LDA(REG_ITMP2, REG_RA, -4);       /* move fault address into reg. itmp2 */
        M_ALD(REG_ITMP3, REG_PV, -3 * 8);   /* load asm exception handler address */
        M_JMP(REG_ZERO, REG_ITMP3);         /* jump to asm exception handler      */
        
+       /* generate put/getstatic stub call code */
+
+       {
+               s4          *xcodeptr;
+               clinitref   *cref;
+               s4          *tmpmcodeptr;
+
+               /* there can only be one clinit ref entry                             */
+               cref = cd->clinitrefs;
+
+               if (cref) {
+                       /* Get machine code which is patched back in later. The call is   */
+                       /* 1 instruction word long.                                       */
+                       xcodeptr = (s4 *) (cd->mcodebase + cref->branchpos);
+                       *(cs-11) = (u4) *xcodeptr;
+
+                       /* patch in the call to call the following code (done at compile  */
+                       /* time)                                                          */
+
+                       tmpmcodeptr = mcodeptr;         /* save current mcodeptr          */
+                       mcodeptr = xcodeptr;            /* set mcodeptr to patch position */
+
+                       M_BSR(REG_RA, tmpmcodeptr - (xcodeptr + 1));
+
+                       mcodeptr = tmpmcodeptr;         /* restore the current mcodeptr   */
+
+                       /* move class pointer into REG_ITMP2                              */
+                       M_ALD(REG_ITMP1, REG_PV, -8 * 8);     /* class                    */
+
+                       /* move machine code into REG_ITMP3                               */
+                       M_ILD(REG_ITMP3, REG_PV, -11 * 8);    /* machine code             */
+                       M_LSUB_IMM(REG_SP, 1 * 8, REG_SP);
+                       M_IST(REG_ITMP3, REG_SP, 0);
+
+                       M_ALD(REG_ITMP2, REG_PV, -9 * 8);     /* asm_check_clinit         */
+                       M_JMP(REG_ZERO, REG_ITMP2);
+               }
+       }
+
 #if 0
        dolog_plain("stubsize: %d (for %d params)\n", (int) (mcodeptr - (s4*) s), m->paramcount);
 #endif
 
 #if defined(STATISTICS)
        if (opt_stat)
-               count_nstub_len += NATIVESTUBSIZE * 8;
+               count_nstub_len += NATIVESTUB_SIZE * 8;
 #endif
 
        /* release dump area */
 
        dump_release(dumpsize);
 
-       return (u1 *) (s + NATIVESTUBOFFSET);
+       return (u1 *) (s + NATIVESTUB_OFFSET);
 }