* src/vm/jit/codegen-common.c (toolbox/list.h): Added.
authortwisti <none@none>
Mon, 6 Nov 2006 17:13:40 +0000 (17:13 +0000)
committertwisti <none@none>
Mon, 6 Nov 2006 17:13:40 +0000 (17:13 +0000)
(codegen_addreference): Renamed to codegen_add_branch_ref, use
md_codegen_patch_branch instead of gen_resolvebranch.
(codegen_resolve_branchrefs): New function.
(codegen_addpatchref): Renamed to codegen_add_patch_ref.
* src/vm/jit/codegen-common.h (codegen_addreference): Renamed to
codegen_add_branch_ref.
(codegen_resolve_branchrefs): New function.
(codegen_addpatchref): Renamed to codegen_add_patch_ref.

* src/vm/jit/dseg.h (toolbox/list.h): Added.

* src/vm/jit/mips/emit.c (vm/options.h): Added.
(emit_arithmetic_check): New function.
(emit_arrayindexoutofbounds_check): Likewise.
(emit_arraystore_check): Likewise.
(emit_classcast_check): Likewise.
(emit_nullpointer_check): Likewise.
(emit_exception_check): Likewise.
(emit_exception_stubs): Use md_codegen_patch_branch instead of
gen_resolvebranch.

* src/vm/jit/mips/md.c (vm/vm.h): Added.
(md_codegen_patch_branch): New function.

* src/vm/jit/mips/codegen.c (codegen): Use new emit_* functions, use
opt_shownops instead of opt_showdissasemble.
(createnativestub): Likewise.

* src/vm/jit/mips/codegen.h (gen_nullptr_check): Removed.
(gen_bound_check): Likewise.
(gen_div_check): Likewise.
(gen_resolvebranch): Likewise.

* src/vm/jit/mips/patcher.c: Use opt_shownops instead of
opt_showdissasemble.
(patcher_checkcast_instanceof_interface): Split into two functions:
patcher_checkcast_interface and patcher_instanceof_interface.

* src/vm/jit/patcher.h (patcher_checkcast_interface): Added.
(patcher_instanceof_interface): Added.

* src/vm/jit/emit-common.h (emit_arithmetic_check): Added.
(emit_arrayindexoutofbounds_check): Likewise.
(emit_arraystore_check): Likewise.
(emit_classcast_check): Likewise.
(emit_nullpointer_check): Likewise.
(emit_exception_check): Likewise.

src/vm/jit/codegen-common.c
src/vm/jit/codegen-common.h
src/vm/jit/dseg.h
src/vm/jit/emit-common.h
src/vm/jit/mips/codegen.c
src/vm/jit/mips/codegen.h
src/vm/jit/mips/emit.c
src/vm/jit/mips/md.c
src/vm/jit/mips/patcher.c
src/vm/jit/patcher.h

index 903b0dc42cf4d11f9213a4c5e2b076ce57b4365b..9428d740bdecc5c1aadd4c5a35a4d3c6c8421590 100644 (file)
@@ -48,7 +48,7 @@
    memory. All functions writing values into the data area return the offset
    relative the begin of the code area (start of procedure).   
 
-   $Id: codegen-common.c 5925 2006-11-05 23:11:27Z edwin $
+   $Id: codegen-common.c 5929 2006-11-06 17:13:40Z twisti $
 
 */
 
@@ -61,7 +61,7 @@
 #include "vm/types.h"
 
 #if defined(ENABLE_JIT)
-/* this is required for gen_resolvebranch and PATCHER_CALL_SIZE */
+/* this is required PATCHER_CALL_SIZE */
 # include "codegen.h"
 #endif
 
@@ -72,6 +72,7 @@
 
 #include "mm/memory.h"
 #include "toolbox/avl.h"
+#include "toolbox/list.h"
 #include "toolbox/logging.h"
 #include "native/jni.h"
 #include "native/native.h"
@@ -190,6 +191,7 @@ void codegen_setup(jitdata *jd)
 #endif
 
        cd->exceptionrefs  = NULL;
+/*     cd->patchrefs      = list_create_dump(OFFSET(patchref, linkage)); */
        cd->patchrefs      = NULL;
 
        cd->linenumberreferences = NULL;
@@ -286,35 +288,41 @@ u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
 #endif
 
 
-void codegen_addreference(codegendata *cd, basicblock *target)
+/* codegen_add_branch_ref ******************************************************
+
+   Prepends an branch to the list.
+
+*******************************************************************************/
+
+void codegen_add_branch_ref(codegendata *cd, basicblock *target)
 {
-       s4 branchpos;
+       s4 branchmpc;
 
-       branchpos = (u1 *) cd->mcodeptr - cd->mcodebase;
+       /* calculate the mpc of the branch instruction */
+
+       branchmpc = cd->mcodeptr - cd->mcodebase;
 
 #if defined(ENABLE_JIT)
        /* Check if the target basicblock has already a start pc, so the
           jump is backward and we can resolve it immediately. */
 
-       /* The interpreter uses absolute branches, so we do branch
-          resolving after the code and data segment move. */
-
-       if (target->mpc >= 0
+       if ((target->mpc >= 0)
 # if defined(ENABLE_INTRP)
+               /* The interpreter uses absolute branches, so we do branch
+                  resolving after the code and data segment move. */
+
                && !opt_intrp
 # endif
                )
        {
-               gen_resolvebranch((u1 *) cd->mcodebase + branchpos,
-                                                 branchpos,
-                                                 target->mpc);
-
-       } else
+               md_codegen_patch_branch(cd, branchmpc, target->mpc);
+       }
+       else
 #endif
        {
                branchref *br = DNEW(branchref);
 
-               br->branchpos = branchpos;
+               br->branchpos = branchmpc;
                br->next      = target->branchrefs;
 
                target->branchrefs = br;
@@ -322,28 +330,53 @@ void codegen_addreference(codegendata *cd, basicblock *target)
 }
 
 
+/* codegen_resolve_branchrefs **************************************************
+
+   Resolves and patches the branch references of a given basic block.
+
+*******************************************************************************/
+
+void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
+{
+       branchref *br;
+       s4         branchmpc;
+       s4         targetmpc;
+
+       /* set target */
+
+       targetmpc = bptr->mpc;
+
+       for (br = bptr->branchrefs; br != NULL; br = br->next) {
+               branchmpc = br->branchpos;
+
+               md_codegen_patch_branch(cd, branchmpc, targetmpc);
+       }
+}
+
+
 /* codegen_add_exception_ref ***************************************************
 
-   Adds an exception branch to the list.
+   Prepends an exception branch to the list.
 
 *******************************************************************************/
 
 static void codegen_add_exception_ref(codegendata *cd, s4 reg,
                                                                          functionptr function)
 {
-       s4            branchpos;
-       exceptionref *eref;
+       s4            branchmpc;
+       exceptionref *er;
 
-       branchpos = (u1 *) cd->mcodeptr - cd->mcodebase;
+       branchmpc = cd->mcodeptr - cd->mcodebase;
 
-       eref = DNEW(exceptionref);
+       er = DNEW(exceptionref);
 
-       eref->branchpos = branchpos;
-       eref->reg       = reg;
-       eref->function  = function;
-       eref->next      = cd->exceptionrefs;
+       er->branchpos = branchmpc;
+       er->reg       = reg;
+       er->function  = function;
 
-       cd->exceptionrefs = eref;
+       er->next      = cd->exceptionrefs;
+
+       cd->exceptionrefs = er;
 }
 
 
@@ -420,27 +453,28 @@ void codegen_add_fillinstacktrace_ref(codegendata *cd)
 }
 
 
-/* codegen_addpatchref *********************************************************
+/* codegen_add_patch_ref *******************************************************
 
-   Adds a new patcher reference to the list of patching positions.
+   Appends a new patcher reference to the list of patching positions.
 
 *******************************************************************************/
 
-void codegen_addpatchref(codegendata *cd, functionptr patcher, voidptr ref,
-                                                s4 disp)
+void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref,
+                                                  s4 disp)
 {
        patchref *pr;
-       s4        branchpos;
+       s4        branchmpc;
 
-       branchpos = cd->mcodeptr - cd->mcodebase;
+       branchmpc = cd->mcodeptr - cd->mcodebase;
 
        pr = DNEW(patchref);
 
-       pr->branchpos = branchpos;
+       pr->branchpos = branchmpc;
+       pr->disp      = disp;
        pr->patcher   = patcher;
        pr->ref       = ref;
-       pr->disp      = disp;
 
+/*     list_add_first(cd->patchrefs, pr); */
        pr->next      = cd->patchrefs;
        cd->patchrefs = pr;
 
index 3ad9b3a7a27847d4b54a4113c780001407d299df..0c551c18e0b1635380419461295383805f09b33d 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen-common.h 5925 2006-11-05 23:11:27Z edwin $
+   $Id: codegen-common.h 5929 2006-11-06 17:13:40Z twisti $
 
 */
 
@@ -114,6 +114,7 @@ struct codegendata {
 #endif
 
        exceptionref   *exceptionrefs;  /* list of exception branches             */
+/*     list           *patchrefs; */
        patchref       *patchrefs;
 
        linenumberref  *linenumberreferences; /* list of line numbers and the     */
@@ -157,7 +158,9 @@ void codegen_increase(codegendata *cd);
 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr);
 #endif
 
-void codegen_addreference(codegendata *cd, basicblock *target);
+void codegen_add_branch_ref(codegendata *cd, basicblock *target);
+/* XXX REMOVE ME: don't-break-trunk macro */
+#define codegen_addreference codegen_add_branch_ref
 
 void codegen_add_arithmeticexception_ref(codegendata *cd);
 void codegen_add_arrayindexoutofboundsexception_ref(codegendata *cd, s4 reg);
@@ -167,8 +170,10 @@ void codegen_add_nullpointerexception_ref(codegendata *cd);
 void codegen_add_fillinstacktrace_ref(codegendata *cd);
 
 
-void codegen_addpatchref(codegendata *cd, functionptr patcher, voidptr ref,
-                                                s4 disp);
+void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref,
+                                                  s4 disp);
+/* XXX REMOVE ME: don't-break-trunk macro */
+#define codegen_addpatchref codegen_add_patch_ref
 
 void codegen_insertmethod(u1 *startpc, u1 *endpc);
 u1 *codegen_get_pv_from_pc(u1 *pc);
@@ -205,7 +210,8 @@ void codegen_threadcritstop(codegendata *cd, int offset);
 #endif
 
 /* machine dependent functions */
-u1 *md_codegen_get_pv_from_pc(u1 *ra);
+void md_codegen_patch_branch(codegendata *cd, s4 branchmpc, s4 targetmpc);
+u1  *md_codegen_get_pv_from_pc(u1 *ra);
 
 bool codegen(jitdata *jd);
 
index cf7faedcb79fd7d4549dd32637ac9b808dc686bc..b56b68a861e317666043d4f7709e49ebf9e8f6ca 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Christian Thalinger
             Joseph Wenninger
 
-   $Id: dseg.h 5892 2006-11-02 10:21:37Z twisti $
+   $Id: dseg.h 5929 2006-11-06 17:13:40Z twisti $
 
 */
 
@@ -53,6 +53,7 @@ typedef struct dseg_exception_entry dseg_exception_entry;
 
 #include "vm/types.h"
 
+#include "toolbox/list.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/codegen-common.h"
 
@@ -121,6 +122,7 @@ struct patchref {
        s4           disp;          /* displacement of ref in the data segment    */
        functionptr  patcher;       /* patcher function to call                   */
        voidptr      ref;           /* reference passed                           */
+/*     listnode     linkage; */
        patchref    *next;
 };
 
index b8c1919ac92cbd931093c5014a882b2446f820a6..43f0431326baf455aab74654939094323d8242cf 100644 (file)
@@ -91,6 +91,13 @@ void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst);
 void emit_iconst(codegendata *cd, s4 d, s4 value);
 void emit_lconst(codegendata *cd, s4 d, s8 value);
 
+void emit_arithmetic_check(codegendata *cd, s4 reg);
+void emit_arrayindexoutofbounds_check(codegendata *cd, s4 s1, s4 s2);
+void emit_arraystore_check(codegendata *cd, s4 reg);
+void emit_classcast_check(codegendata *cd, s4 condition, s4 reg, s4 s1);
+void emit_nullpointer_check(codegendata *cd, s4 reg);
+void emit_exception_check(codegendata *cd);
+
 void emit_exception_stubs(jitdata *jd);
 void emit_patcher_stubs(jitdata *jd);
 void emit_replacement_stubs(jitdata *jd);
index f536beac2a42c15b5fb75c401d2a07459a0054d9..73854d5475d22a98541535693cd037e0a5f93a9a 100644 (file)
@@ -26,8 +26,7 @@
 
    Authors: Andreas Krall
             Reinhard Grafl
-
-   Changes: Christian Thalinger
+            Christian Thalinger
             Christian Ullrich
             Edwin Steiner
 
@@ -35,7 +34,7 @@
    This module generates MIPS machine code for a sequence of
    intermediate code commands (ICMDs).
 
-   $Id: codegen.c 5891 2006-11-01 20:19:44Z twisti $
+   $Id: codegen.c 5929 2006-11-06 17:13:40Z twisti $
 
 */
 
@@ -96,6 +95,8 @@ bool codegen(jitdata *jd)
        instruction        *iptr;
        exception_entry    *ex;
        u2                  currentline;
+       constant_classref  *cr;
+       unresolved_class   *uc;
        methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
        unresolved_method  *um;
        builtintable_entry *bte;
@@ -289,10 +290,8 @@ bool codegen(jitdata *jd)
                        disp = dseg_add_address(cd, &m->class->object.header);
                        M_ALD(REG_A0, REG_PV, disp);
                }
-               else {
-                       M_BEQZ(REG_A0, 0);
-                       codegen_add_nullpointerexception_ref(cd);
-               }
+               else
+                       emit_nullpointer_check(cd, REG_A0);
 
                disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
                M_ALD(REG_ITMP3, REG_PV, disp);
@@ -352,16 +351,9 @@ bool codegen(jitdata *jd)
                bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
 
                if (bptr->flags >= BBREACHED) {
-
                        /* branch resolving */
-                       {
-                               branchref *bref;
-                               for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
-                                       gen_resolvebranch(cd->mcodebase + bref->branchpos, 
-                                                                         bref->branchpos,
-                                                                         bptr->mpc);
-                               }
-                       }
+
+                       codegen_resolve_branchrefs(cd, bptr);
 
                /* copy interface registers to their destination */
 
@@ -420,9 +412,7 @@ bool codegen(jitdata *jd)
                case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       M_BEQZ(s1, 0);
-                       codegen_add_nullpointerexception_ref(cd);
-                       M_NOP;
+                       emit_nullpointer_check(cd, s1);
                        break;
 
                /* constant operations ************************************************/
@@ -462,13 +452,12 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               constant_classref *cr = iptr->sx.val.c.ref;
-
+                               cr   = iptr->sx.val.c.ref;
                                disp = dseg_add_unique_address(cd, cr);
 
-                               codegen_addpatchref(cd, PATCHER_aconst, cr, disp);
+                               codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
 
@@ -723,7 +712,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       gen_div_check(s2);
+                       emit_arithmetic_check(cd, s2);
                        M_IDIV(s1, s2);
                        M_MFLO(d);
                        M_NOP;
@@ -736,7 +725,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       gen_div_check(s2);
+                       emit_arithmetic_check(cd, s2);
                        M_LDIV(s1, s2);
                        M_MFLO(d);
                        M_NOP;
@@ -749,7 +738,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       gen_div_check(s2);
+                       emit_arithmetic_check(cd, s2);
                        M_IDIV(s1, s2);
                        M_MFHI(d);
                        M_NOP;
@@ -762,7 +751,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       gen_div_check(s2);
+                       emit_arithmetic_check(cd, s2);
                        M_LDIV(s1, s2);
                        M_MFHI(d);
                        M_NOP;
@@ -1340,7 +1329,7 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       gen_nullptr_check(s1);
+                       emit_nullpointer_check(cd, s1);
                        M_ILD(d, s1, OFFSET(java_arrayheader, size));
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1351,8 +1340,8 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_AADD(s2, s1, REG_ITMP3);
                        M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
@@ -1365,8 +1354,8 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_AADD(s2, s1, REG_ITMP3);
                        M_AADD(s2, REG_ITMP3, REG_ITMP3);
@@ -1380,8 +1369,8 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_AADD(s2, s1, REG_ITMP3);
                        M_AADD(s2, REG_ITMP3, REG_ITMP3);
@@ -1395,8 +1384,8 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 2, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
@@ -1410,8 +1399,8 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
@@ -1425,8 +1414,8 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 2, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
@@ -1440,8 +1429,8 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
@@ -1455,8 +1444,8 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
@@ -1470,8 +1459,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_AADD(s2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
@@ -1484,8 +1473,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_AADD(s2, s1, REG_ITMP1);
                        M_AADD(s2, REG_ITMP1, REG_ITMP1);
@@ -1498,8 +1487,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
@@ -1512,8 +1501,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
@@ -1526,8 +1515,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
@@ -1540,8 +1529,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
@@ -1555,8 +1544,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
 
@@ -1567,9 +1556,10 @@ bool codegen(jitdata *jd)
                        M_JSR(REG_RA, REG_ITMP3);
                        M_NOP;
 
-                       M_BEQZ(REG_RESULT, 0);
-                       codegen_add_arraystoreexception_ref(cd);
-                       M_NOP;
+/*                     M_BEQZ(REG_RESULT, 0); */
+/*                     codegen_add_arraystoreexception_ref(cd); */
+/*                     M_NOP; */
+                       emit_arraystore_check(cd, REG_RESULT);
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -1585,8 +1575,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_AADD(s2, s1, REG_ITMP1);
                        M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
@@ -1598,8 +1588,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_AADD(s2, s1, REG_ITMP1);
                        M_AADD(s2, REG_ITMP1, REG_ITMP1);
@@ -1611,8 +1601,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
@@ -1624,8 +1614,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
@@ -1637,8 +1627,8 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
+                               emit_nullpointer_check(cd, s1);
+                               emit_arrayindexoutofbounds_check(cd, s1, s2);
                        }
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
@@ -1653,9 +1643,9 @@ bool codegen(jitdata *jd)
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp      = dseg_add_unique_address(cd, uf);
 
-                               codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+                               codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
                        }
@@ -1665,9 +1655,9 @@ bool codegen(jitdata *jd)
                                disp      = dseg_add_address(cd, &(fi->value));
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
-                                       codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
                                }
@@ -1707,9 +1697,9 @@ bool codegen(jitdata *jd)
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp      = dseg_add_unique_address(cd, uf);
 
-                               codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+                               codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
                        }
@@ -1719,9 +1709,9 @@ bool codegen(jitdata *jd)
                                disp      = dseg_add_address(cd, &(fi->value));
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
-                                       codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
                                }
@@ -1762,9 +1752,9 @@ bool codegen(jitdata *jd)
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp      = dseg_add_unique_address(cd, uf);
 
-                               codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
+                               codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
                        }
@@ -1774,9 +1764,9 @@ bool codegen(jitdata *jd)
                                disp      = dseg_add_address(cd, &(fi->value));
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
-                                       codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
                                }
@@ -1807,16 +1797,16 @@ bool codegen(jitdata *jd)
                case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       gen_nullptr_check(s1);
+                       emit_nullpointer_check(cd, s1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp      = 0;
 
-                               codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+                               codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
                        }
@@ -1854,7 +1844,7 @@ bool codegen(jitdata *jd)
                case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       gen_nullptr_check(s1);
+                       emit_nullpointer_check(cd, s1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                uf        = iptr->sx.s23.s3.uf;
@@ -1873,9 +1863,9 @@ bool codegen(jitdata *jd)
                                s2 = emit_load_s2(jd, iptr, REG_FTMP1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+                               codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
                        }
@@ -1902,16 +1892,16 @@ bool codegen(jitdata *jd)
                case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       gen_nullptr_check(s1);
+                       emit_nullpointer_check(cd, s1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                unresolved_field *uf = iptr->sx.s23.s3.uf;
 
                                fieldtype = uf->fieldref->parseddesc.fd->type;
 
-                               codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+                               codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
 
@@ -1952,10 +1942,11 @@ bool codegen(jitdata *jd)
                        
 #ifdef ENABLE_VERIFIER
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               codegen_addpatchref(cd, PATCHER_athrow_areturn,
-                                                                       iptr->sx.s23.s2.uc, 0);
+                               uc = iptr->sx.s23.s2.uc;
+
+                               codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
                        }
@@ -1974,7 +1965,7 @@ bool codegen(jitdata *jd)
                case ICMD_RET:          /* ... ==> ...                                */
 
                        M_BR(0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        ALIGNCODENOP;
                        break;
@@ -1982,7 +1973,7 @@ bool codegen(jitdata *jd)
                case ICMD_JSR:          /* ... ==> ...                                */
 
                        M_BR(0);
-                       codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
+                       codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
                        M_NOP;
                        ALIGNCODENOP;
                        break;
@@ -1991,7 +1982,7 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        M_BEQZ(s1, 0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -1999,7 +1990,7 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        M_BNEZ(s1, 0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2012,7 +2003,7 @@ bool codegen(jitdata *jd)
                                ICONST(REG_ITMP2, iptr->sx.val.i);
                                M_BEQ(s1, REG_ITMP2, 0);
                        }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2030,7 +2021,7 @@ bool codegen(jitdata *jd)
                                }
                                M_BNEZ(REG_ITMP1, 0);
                        }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2051,7 +2042,7 @@ bool codegen(jitdata *jd)
                                        M_BEQZ(REG_ITMP1, 0);
                                        }
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2065,7 +2056,7 @@ bool codegen(jitdata *jd)
                                ICONST(REG_ITMP2, iptr->sx.val.i);
                                M_BNE(s1, REG_ITMP2, 0);
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2086,7 +2077,7 @@ bool codegen(jitdata *jd)
                                        M_BNEZ(REG_ITMP1, 0);
                                        }
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2106,7 +2097,7 @@ bool codegen(jitdata *jd)
                                        }
                                M_BEQZ(REG_ITMP1, 0);
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2120,7 +2111,7 @@ bool codegen(jitdata *jd)
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_BEQ(s1, REG_ITMP2, 0);
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2140,7 +2131,7 @@ bool codegen(jitdata *jd)
                                        }
                                M_BNEZ(REG_ITMP1, 0);
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2161,7 +2152,7 @@ bool codegen(jitdata *jd)
                                        M_BEQZ(REG_ITMP1, 0);
                                        }
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2175,7 +2166,7 @@ bool codegen(jitdata *jd)
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_BNE(s1, REG_ITMP2, 0);
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2196,7 +2187,7 @@ bool codegen(jitdata *jd)
                                        M_BNEZ(REG_ITMP1, 0);
                                        }
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2216,7 +2207,7 @@ bool codegen(jitdata *jd)
                                        }
                                M_BEQZ(REG_ITMP1, 0);
                                }
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2227,7 +2218,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_BEQ(s1, s2, 0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2238,7 +2229,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_BNE(s1, s2, 0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2249,7 +2240,7 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMPLT(s1, s2, REG_ITMP1);
                        M_BNEZ(REG_ITMP1, 0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2260,7 +2251,7 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMPGT(s1, s2, REG_ITMP1);
                        M_BNEZ(REG_ITMP1, 0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2271,7 +2262,7 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMPGT(s1, s2, REG_ITMP1);
                        M_BEQZ(REG_ITMP1, 0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2282,7 +2273,7 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMPLT(s1, s2, REG_ITMP1);
                        M_BEQZ(REG_ITMP1, 0);
-                       codegen_addreference(cd, iptr->dst.block);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
@@ -2301,10 +2292,11 @@ bool codegen(jitdata *jd)
 
 #ifdef ENABLE_VERIFIER
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               codegen_addpatchref(cd, PATCHER_athrow_areturn,
-                                                                       iptr->sx.s23.s2.uc, 0);
+                               uc = iptr->sx.s23.s2.uc;
 
-                               if (opt_showdisassemble) {
+                               codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
+
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
                        }
@@ -2451,7 +2443,7 @@ nowperformreturn:
 
                        M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
                        M_BEQZ(REG_ITMP2, 0);
-                       codegen_addreference(cd, table[0].block); /* default target */
+                       codegen_add_branch_ref(cd, table[0].block); /* default target */
                        M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
 
                        /* build jump table top down and use address of lowest entry */
@@ -2489,13 +2481,13 @@ nowperformreturn:
                        while (--i >= 0) {
                                ICONST(REG_ITMP2, lookup->value);
                                M_BEQ(s1, REG_ITMP2, 0);
-                               codegen_addreference(cd, lookup->target.block); 
+                               codegen_add_branch_ref(cd, lookup->target.block); 
                                M_NOP;
                                ++lookup;
                        }
 
                        M_BR(0);
-                       codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
+                       codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
                        M_NOP;
                        ALIGNCODENOP;
                        break;
@@ -2580,19 +2572,27 @@ gen_method:
                                break;
 
                        case ICMD_INVOKESPECIAL:
-                               M_BEQZ(REG_A0, 0);
+/*                             emit_nullpointer_check(cd, REG_A0); */
+                               M_BNEZ(REG_A0, 6);
+                               M_NOP;
+
+                               M_LUI(REG_ITMP3, 0);
+                               M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
                                codegen_add_nullpointerexception_ref(cd);
+                               M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+                               M_JMP(REG_ITMP3);
                                M_NOP;
+
                                /* fall through */
 
                        case ICMD_INVOKESTATIC:
                                if (lm == NULL) {
                                        disp = dseg_add_unique_address(cd, um);
 
-                                       codegen_addpatchref(cd, PATCHER_invokestatic_special, um,
-                                                                               disp);
+                                       codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
+                                                                                 disp);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
                                }
@@ -2604,12 +2604,12 @@ gen_method:
                                break;
 
                        case ICMD_INVOKEVIRTUAL:
-                               gen_nullptr_check(REG_A0);
+                               emit_nullpointer_check(cd, REG_A0);
 
                                if (lm == NULL) {
-                                       codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
+                                       codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
 
@@ -2619,19 +2619,18 @@ gen_method:
                                        s1 = OFFSET(vftbl_t, table[0]) +
                                                sizeof(methodptr) * lm->vftblindex;
 
-                               M_ALD(REG_METHODPTR, REG_A0,
-                                         OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
                                M_ALD(REG_PV, REG_METHODPTR, s1);
                                s1 = REG_PV;
                                break;
 
                        case ICMD_INVOKEINTERFACE:
-                               gen_nullptr_check(REG_A0);
+                               emit_nullpointer_check(cd, REG_A0);
 
                                if (lm == NULL) {
-                                       codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
+                                       codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
 
@@ -2645,8 +2644,7 @@ gen_method:
                                        s2 = sizeof(methodptr) * (lm - lm->class->methods);
                                }
 
-                               M_ALD(REG_METHODPTR, REG_A0,
-                                         OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
                                M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
                                M_ALD(REG_PV, REG_METHODPTR, s2);
                                s1 = REG_PV;
@@ -2663,9 +2661,7 @@ gen_method:
                        /* actually only used for ICMD_BUILTIN */
 
                        if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               M_BEQZ(REG_RESULT, 0);
-                               codegen_add_fillinstacktrace_ref(cd);
-                               M_NOP;
+                               emit_exception_check(cd);
                        }
 
                        /* store return value */
@@ -2726,29 +2722,31 @@ gen_method:
 
                                /* calculate interface checkcast code size */
 
-                               s2 = 8;
+/*                             s2 = 3 + 2 + 1 + 2; */
+                               s2 = 3 + 7 + 1 + 7;
                                if (super == NULL)
-                                       s2 += (opt_showdisassemble ? 2 : 0);
+                                       s2 += (opt_shownops ? 2 : 0);
 
                                /* calculate class checkcast code size */
 
-                               s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
+/*                             s3 = 2 + 1 + 4 + 1 + 2 /\* 10 + (s1 == REG_ITMP1) *\/; */
+                               s3 = 2 + 1 + 4 + 1 + 7;
                                if (super == NULL)
-                                       s3 += (opt_showdisassemble ? 2 : 0);
+                                       s3 += (opt_shownops ? 2 : 0);
 
                                /* if class is not resolved, check which code to call */
 
                                if (super == NULL) {
-                                       M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
+                                       M_BEQZ(s1, 5 + (opt_shownops ? 2 : 0) + s2 + 2 + s3);
                                        M_NOP;
 
+                                       cr   = iptr->sx.s23.s3.c.ref;
                                        disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
 
-                                       codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
-                                                                               iptr->sx.s23.s3.c.ref,
-                                                                               disp);
+                                       codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
+                                                                                 cr, disp);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
 
@@ -2763,12 +2761,12 @@ gen_method:
 
                                if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
                                        if (super == NULL) {
-                                               codegen_addpatchref(cd,
-                                                                                       PATCHER_checkcast_instanceof_interface,
-                                                                                       iptr->sx.s23.s3.c.ref,
-                                                                                       0);
+                                               cr = iptr->sx.s23.s3.c.ref;
+
+                                               codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
+                                                                                         cr, 0);
 
-                                               if (opt_showdisassemble) {
+                                               if (opt_shownops) {
                                                        M_NOP; M_NOP;
                                                }
                                        }
@@ -2778,17 +2776,15 @@ gen_method:
                                        }
 
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
-                                       M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
+                                       M_ILD(REG_ITMP3, REG_ITMP2,
+                                                 OFFSET(vftbl_t, interfacetablelength));
                                        M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
-                                       M_BLEZ(REG_ITMP3, 0);
-                                       codegen_add_classcastexception_ref(cd, s1);
-                                       M_NOP;
+                                       emit_classcast_check(cd, ICMD_IFLE, REG_ITMP3, s1);
+
                                        M_ALD(REG_ITMP3, REG_ITMP2,
                                                  OFFSET(vftbl_t, interfacetable[0]) -
                                                  superindex * sizeof(methodptr*));
-                                       M_BEQZ(REG_ITMP3, 0);
-                                       codegen_add_classcastexception_ref(cd, s1);
-                                       M_NOP;
+                                       emit_classcast_check(cd, ICMD_IFEQ, REG_ITMP3, s1);
 
                                        if (super == NULL) {
                                                M_BR(1 + s3);
@@ -2800,14 +2796,14 @@ gen_method:
 
                                if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
                                        if (super == NULL) {
+                                               cr   = iptr->sx.s23.s3.c.ref;
                                                disp = dseg_add_unique_address(cd, NULL);
 
-                                               codegen_addpatchref(cd,
-                                                                                       PATCHER_checkcast_instanceof_class,
-                                                                                       iptr->sx.s23.s3.c.ref,
-                                                                                       disp);
+                                               codegen_add_patch_ref(cd,
+                                                                                         PATCHER_checkcast_instanceof_class,
+                                                                                         cr, disp);
 
-                                               if (opt_showdisassemble) {
+                                               if (opt_shownops) {
                                                        M_NOP; M_NOP;
                                                }
                                        }
@@ -2841,9 +2837,7 @@ gen_method:
 #endif
                                        /*                              } */
                                        M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
-                                       M_BNEZ(REG_ITMP3, 0);
-                                       codegen_add_classcastexception_ref(cd, s1);
-                                       M_NOP;
+                                       emit_classcast_check(cd, ICMD_IFNE, REG_ITMP3, s1);
                                }
 
                                d = codegen_reg_of_dst(jd, iptr, s1);
@@ -2853,13 +2847,13 @@ gen_method:
                                M_INTMOVE(s1, REG_A0);
 
                                if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                                       cr   = iptr->sx.s23.s3.c.ref;
                                        disp = dseg_add_unique_address(cd, NULL);
 
-                                       codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
-                                                                               iptr->sx.s23.s3.c.ref,
-                                                                               disp);
+                                       codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
+                                                                                 cr, disp);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
                                }
@@ -2873,9 +2867,7 @@ gen_method:
                                M_NOP;
 
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                               M_BEQZ(REG_RESULT, 0);
-                               codegen_add_classcastexception_ref(cd, s1);
-                               M_NOP;
+                               emit_classcast_check(cd, ICMD_IFEQ, REG_RESULT, s1);
 
                                d = codegen_reg_of_dst(jd, iptr, s1);
                        }
@@ -2930,28 +2922,29 @@ gen_method:
 
                        s2 = 7;
                        if (super == NULL)
-                               s2 += (opt_showdisassemble ? 2 : 0);
+                               s2 += (opt_shownops ? 2 : 0);
 
                        /* calculate class instanceof code size */
 
                        s3 = 8;
                        if (super == NULL)
-                               s3 += (opt_showdisassemble ? 2 : 0);
+                               s3 += (opt_shownops ? 2 : 0);
 
                        M_CLR(d);
 
                        /* if class is not resolved, check which code to call */
 
                        if (super == NULL) {
-                               M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
+                               M_BEQZ(s1, 5 + (opt_shownops ? 2 : 0) + s2 + 2 + s3);
                                M_NOP;
 
+                               cr   = iptr->sx.s23.s3.c.ref;
                                disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
 
-                               codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
-                                                                       iptr->sx.s23.s3.c.ref, disp);
+                               codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
+                                                                         cr, disp);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
 
@@ -2966,11 +2959,12 @@ gen_method:
 
                        if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
                                if (super == NULL) {
-                                       codegen_addpatchref(cd,
-                                                                               PATCHER_checkcast_instanceof_interface,
-                                                                               iptr->sx.s23.s3.c.ref, 0);
+                                       cr = iptr->sx.s23.s3.c.ref;
+
+                                       codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
+                                                                                 cr, 0);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
                                }
@@ -2980,7 +2974,8 @@ gen_method:
                                }
 
                                M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
-                               M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
+                               M_ILD(REG_ITMP3, REG_ITMP1,
+                                         OFFSET(vftbl_t, interfacetablelength));
                                M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
                                M_BLEZ(REG_ITMP3, 3);
                                M_NOP;
@@ -2999,13 +2994,13 @@ gen_method:
 
                        if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
                                if (super == NULL) {
+                                       cr   = iptr->sx.s23.s3.c.ref;
                                        disp = dseg_add_unique_address(cd, NULL);
 
-                                       codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
-                                                                               iptr->sx.s23.s3.c.ref,
-                                                                               disp);
+                                       codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
+                                                                                 cr, disp);
 
-                                       if (opt_showdisassemble) {
+                                       if (opt_shownops) {
                                                M_NOP; M_NOP;
                                        }
                                }
@@ -3060,12 +3055,13 @@ gen_method:
                        /* is patcher function set? */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               cr   = iptr->sx.s23.s3.c.ref;
                                disp = dseg_add_unique_address(cd, NULL);
 
-                               codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
-                                                                       iptr->sx.s23.s3.c.ref, disp);
+                               codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
+                                                                         cr, disp);
 
-                               if (opt_showdisassemble) {
+                               if (opt_shownops) {
                                        M_NOP; M_NOP;
                                }
                        }
@@ -3087,9 +3083,7 @@ gen_method:
 
                        /* check for exception before result assignment */
 
-                       M_BEQZ(REG_RESULT, 0);
-                       codegen_add_fillinstacktrace_ref(cd);
-                       M_NOP;
+                       emit_exception_check(cd);
 
                        d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
                        M_INTMOVE(REG_RESULT, d);
@@ -3268,9 +3262,9 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
 #if !defined(WITH_STATIC_CLASSPATH)
        if (f == NULL) {
-               codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
+               codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
 
-               if (opt_showdisassemble) {
+               if (opt_shownops) {
                        M_NOP; M_NOP;
                }
        }
index 951474c7522a7f4cd7a0a4c57ad1727ae8fe47f7..cd0c997ad75a95377e09d98ef125cb93d35b5ab9 100644 (file)
@@ -25,8 +25,9 @@
    Contact: cacao@cacaojvm.org
 
    Authors: Andreas Krall
+            Christian Thalinger
 
-   $Id: codegen.h 5891 2006-11-01 20:19:44Z twisti $
+   $Id: codegen.h 5929 2006-11-06 17:13:40Z twisti $
 
 */
 
 
 /* additional functions and macros to generate code ***************************/
 
-#define gen_nullptr_check(objreg) \
-    if (checknull) { \
-        M_BEQZ(objreg, 0); \
-        codegen_add_nullpointerexception_ref(cd); \
-        M_NOP; \
-    }
-
-#define gen_bound_check \
-    if (checkbounds) { \
-        M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size)); \
-        M_CMPULT(s2, REG_ITMP3, REG_ITMP3); \
-        M_BEQZ(REG_ITMP3, 0); \
-        codegen_add_arrayindexoutofboundsexception_ref(cd, s2); \
-        M_NOP; \
-    }
-
-#define gen_div_check(r) \
-    do { \
-        M_BEQZ((r), 0); \
-        codegen_add_arithmeticexception_ref(cd); \
-        M_NOP; \
-    } while (0)
-
-
 /* MCODECHECK(icnt) */
 
 #define MCODECHECK(icnt) \
 
 #endif /* SIZEOF_VOID_P == 8 */
 
-
-/* function gen_resolvebranch **************************************************
-
-       backpatches a branch instruction; MIPS branch instructions are very
-       regular, so it is only necessary to overwrite some fixed bits in the
-       instruction.
-
-       parameters: ip ... pointer to instruction after branch (void*)
-                   so ... offset of instruction after branch  (s4)
-                   to ... offset of branch target             (s4)
-
-*******************************************************************************/
-
-#define gen_resolvebranch(ip,so,to) \
-    do { \
-        s4 offset; \
-        \
-        offset = ((s4) (to) - (so)) >> 2; \
-        \
-        /* On the MIPS we can only branch signed 16-bit instruction words */ \
-        /* (signed 18-bit = 32KB = +/- 16KB). Check this!                 */ \
-        \
-        if ((offset < (s4) 0xffff8000) || (offset > (s4) 0x00007fff)) { \
-            throw_cacao_exception_exit(string_java_lang_InternalError, \
-                                       "Jump offset is out of range: %d > +/-%d", \
-                                       offset, 0x00007fff); \
-        } \
-        \
-        ((s4 *) (ip))[-1] |= (offset & 0x0000ffff); \
-    } while (0)
-
-
-/* function prototypes ********************************************************/
-
-void docacheflush(u1 *p, long bytelen);
-
 #endif /* _CODEGEN_H */
 
 
index 6dd24332f8c64bb5146a08d42e2e2979277c6d76..f3cb0ca9370e314a9da6bdfc43de4f1061eda169 100644 (file)
@@ -46,6 +46,7 @@
 #endif
 
 #include "vm/exceptions.h"
+#include "vm/options.h"
 #include "vm/stringlocal.h" /* XXX for gen_resolvebranch */
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
@@ -215,6 +216,185 @@ void emit_lconst(codegendata *cd, s4 d, s8 value)
 }
 
 
+/* emit_arithmetic_check *******************************************************
+
+   Emit an ArithmeticException check.
+
+*******************************************************************************/
+
+void emit_arithmetic_check(codegendata *cd, s4 reg)
+{
+#if 0
+       M_BEQZ(reg, 0);
+       codegen_add_arithmeticexception_ref(cd);
+       M_NOP;
+#else
+       M_BNEZ(reg, 6);
+       M_NOP;
+
+       M_LUI(REG_ITMP3, 0);
+       M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+       codegen_add_arithmeticexception_ref(cd);
+       M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+       M_JMP(REG_ITMP3);
+       M_NOP;
+#endif
+}
+
+
+/* emit_arrayindexoutofbounds_check ********************************************
+
+   Emit an ArrayIndexOutOfBoundsException check.
+
+*******************************************************************************/
+
+void emit_arrayindexoutofbounds_check(codegendata *cd, s4 s1, s4 s2)
+{
+       if (checkbounds) {
+               M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+               M_CMPULT(s2, REG_ITMP3, REG_ITMP3);
+
+#if 0
+               M_BEQZ(REG_ITMP3, 0);
+               codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+               M_NOP;
+#else
+               M_BNEZ(REG_ITMP3, 6);
+               M_NOP;
+
+               M_LUI(REG_ITMP3, 0);
+               M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+               codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+               M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+               M_JMP(REG_ITMP3);
+               M_NOP;
+#endif
+       }
+}
+
+
+/* emit_arraystore_check *******************************************************
+
+   Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, s4 reg)
+{
+#if 0
+       M_BEQZ(reg, 0);
+       codegen_add_arraystoreexception_ref(cd);
+       M_NOP;
+#else
+       M_BNEZ(reg, 6);
+       M_NOP;
+
+       M_LUI(REG_ITMP3, 0);
+       M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+       codegen_add_arraystoreexception_ref(cd);
+       M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+       M_JMP(REG_ITMP3);
+       M_NOP;
+#endif
+}
+
+
+/* emit_classcast_check ********************************************************
+
+   Emit a ClassCastException check.
+
+*******************************************************************************/
+
+void emit_classcast_check(codegendata *cd, s4 condition, s4 reg, s4 s1)
+{
+#if 0
+       M_BNEZ(reg, 0);
+       codegen_add_classcastexception_ref(cd, s1);
+       M_NOP;
+#else
+       switch (condition) {
+       case ICMD_IFEQ:
+               M_BNEZ(reg, 6);
+               break;
+
+       case ICMD_IFNE:
+               M_BEQZ(reg, 6);
+               break;
+
+       case ICMD_IFLE:
+               M_BGTZ(reg, 6);
+               break;
+
+       default:
+               vm_abort("emit_classcast_check: condition %d not found", condition);
+       }
+
+       M_NOP;
+
+       M_LUI(REG_ITMP3, 0);
+       M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+       codegen_add_classcastexception_ref(cd, s1);
+       M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+       M_JMP(REG_ITMP3);
+       M_NOP;
+#endif
+}
+
+
+/* emit_nullpointer_check ******************************************************
+
+   Emit a NullPointerException check.
+
+*******************************************************************************/
+
+void emit_nullpointer_check(codegendata *cd, s4 reg)
+{
+       if (checknull) {
+#if 0
+               M_BEQZ(reg, 0);
+               codegen_add_nullpointerexception_ref(cd);
+               M_NOP;
+#else
+               M_BNEZ(reg, 6);
+               M_NOP;
+
+               M_LUI(REG_ITMP3, 0);
+               M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+               codegen_add_nullpointerexception_ref(cd);
+               M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+               M_JMP(REG_ITMP3);
+               M_NOP;
+#endif
+       }
+}
+
+
+/* emit_exception_check ********************************************************
+
+   Emit an Exception check.
+
+*******************************************************************************/
+
+void emit_exception_check(codegendata *cd)
+{
+#if 0
+       M_BEQZ(REG_RESULT, 0);
+       codegen_add_fillinstacktrace_ref(cd);
+       M_NOP;
+#else
+       M_BNEZ(REG_RESULT, 6);
+       M_NOP;
+
+       M_LUI(REG_ITMP3, 0);
+       M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
+       codegen_add_fillinstacktrace_ref(cd);
+       M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
+       M_JMP(REG_ITMP3);
+       M_NOP;
+#endif
+}
+
+
 /* emit_exception_stubs ********************************************************
 
    Generates the code for the exception stubs.
@@ -225,7 +405,9 @@ void emit_exception_stubs(jitdata *jd)
 {
        codegendata  *cd;
        registerdata *rd;
-       exceptionref *eref;
+       exceptionref *er;
+       s4            branchmpc;
+       s4            targetmpc;
        s4            targetdisp;
        s4            disp;
 
@@ -238,9 +420,13 @@ void emit_exception_stubs(jitdata *jd)
 
        targetdisp = 0;
 
-       for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
-               gen_resolvebranch(cd->mcodebase + eref->branchpos, 
-                                                 eref->branchpos, cd->mcodeptr - cd->mcodebase);
+       for (er = cd->exceptionrefs; er != NULL; er = er->next) {
+               /* back-patch the branch to this exception code */
+
+               branchmpc = er->branchpos;
+               targetmpc = cd->mcodeptr - cd->mcodebase;
+
+               md_codegen_patch_branch(cd, branchmpc, targetmpc);
 
                MCODECHECK(100);
 
@@ -248,31 +434,31 @@ void emit_exception_stubs(jitdata *jd)
                   ArrayIndexOutOfBoundsException.  If so, move index register
                   into REG_ITMP1. */
 
-               if (eref->reg != -1)
-                       M_MOV(eref->reg, REG_ITMP1);
+               if (er->reg != -1)
+                       M_MOV(er->reg, REG_ITMP1);
 
                /* calcuate exception address */
 
-               M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
+               M_LDA(REG_ITMP2_XPC, REG_PV, er->branchpos - 4);
 
                /* move function to call into REG_ITMP3 */
 
-               disp = dseg_add_functionptr(cd, eref->function);
+               disp = dseg_add_functionptr(cd, er->function);
                M_ALD(REG_ITMP3, REG_PV, disp);
 
                if (targetdisp == 0) {
                        targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase);
 
-                       M_MOV(REG_PV, rd->argintregs[0]);
-                       M_MOV(REG_SP, rd->argintregs[1]);
+                       M_MOV(REG_PV, REG_A0);
+                       M_MOV(REG_SP, REG_A1);
 
                        if (jd->isleafmethod)
-                               M_MOV(REG_RA, rd->argintregs[2]);
+                               M_MOV(REG_RA, REG_A2);
                        else
-                               M_ALD(rd->argintregs[2], REG_SP, (cd->stackframesize - 1) * 8);
+                               M_ALD(REG_A2, REG_SP, (cd->stackframesize - 1) * 8);
 
-                       M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
-                       M_MOV(REG_ITMP1, rd->argintregs[4]);
+                       M_MOV(REG_ITMP2_XPC, REG_A3);
+                       M_MOV(REG_ITMP1, REG_A4);
 
                        M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
                        M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
@@ -315,7 +501,7 @@ void emit_exception_stubs(jitdata *jd)
 void emit_patcher_stubs(jitdata *jd)
 {
        codegendata *cd;
-       patchref    *pref;
+       patchref    *pr;
        u4           mcode[2];
        u1          *savedmcodeptr;
        u1          *tmpmcodeptr;
@@ -330,7 +516,9 @@ void emit_patcher_stubs(jitdata *jd)
 
        targetdisp = 0;
 
-       for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
+/*     for (pr = list_first_unsynced(cd->patchrefs); pr != NULL; */
+/*              pr = list_next_unsynced(cd->patchrefs, pr)) { */
+       for (pr = cd->patchrefs; pr != NULL; pr = pr->next) {
                /* check code segment size */
 
                MCODECHECK(100);
@@ -338,7 +526,7 @@ void emit_patcher_stubs(jitdata *jd)
                /* Get machine code which is patched back in later. The
                   call is 2 instruction words long. */
 
-               tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
+               tmpmcodeptr = (u1 *) (cd->mcodebase + pr->branchpos);
 
                /* We use 2 loads here as an unaligned 8-byte read on 64-bit
                   MIPS causes a SIGSEGV and using the same code for both
@@ -373,7 +561,7 @@ void emit_patcher_stubs(jitdata *jd)
 
                /* calculate return address and move it onto the stack */
 
-               M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
+               M_LDA(REG_ITMP3, REG_PV, pr->branchpos);
                M_AST(REG_ITMP3, REG_SP, 5 * 8);
 
                /* move pointer to java_objectheader onto stack */
@@ -403,19 +591,19 @@ void emit_patcher_stubs(jitdata *jd)
 
                /* move class/method/field reference onto stack */
 
-               disp = dseg_add_address(cd, pref->ref);
+               disp = dseg_add_address(cd, pr->ref);
                M_ALD(REG_ITMP3, REG_PV, disp);
                M_AST(REG_ITMP3, REG_SP, 2 * 8);
 
                /* move data segment displacement onto stack */
 
-               disp = dseg_add_s4(cd, pref->disp);
+               disp = dseg_add_s4(cd, pr->disp);
                M_ILD(REG_ITMP3, REG_PV, disp);
                M_IST(REG_ITMP3, REG_SP, 1 * 8);
 
                /* move patcher function pointer onto stack */
 
-               disp = dseg_add_address(cd, pref->patcher);
+               disp = dseg_add_address(cd, pr->patcher);
                M_ALD(REG_ITMP3, REG_PV, disp);
                M_AST(REG_ITMP3, REG_SP, 0 * 8);
 
index 647c5bcb0c3f8ddc315db69248d42435a46e43b8..1af596c33e6346c1967fccaf69bd1abc770fbeed 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: md.c 5233 2006-08-14 10:59:39Z twisti $
+   $Id: md.c 5929 2006-11-06 17:13:40Z twisti $
 
 */
 
@@ -43,6 +43,7 @@
 
 #include "toolbox/logging.h"
 #include "vm/global.h"
+#include "vm/vm.h"
 #include "vm/jit/stacktrace.h"
 
 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
 #endif
 
 
+/* md_codegen_patch_branch *****************************************************
+
+   Back-patches a branch instruction.
+
+*******************************************************************************/
+
+void md_codegen_patch_branch(codegendata *cd, s4 branchmpc, s4 targetmpc)
+{
+       s4 *mcodeptr;
+       s4  mcode;
+       s4  disp;                           /* branch displacement                */
+       s4  lo;
+       s4  hi;
+
+       /* calculate the patch position */
+
+       mcodeptr = (s4 *) (cd->mcodebase + branchmpc);
+
+       /* get the instruction before the exception point */
+
+       mcode = mcodeptr[-1];
+
+       /* check for: ori t9,t9,0 */
+
+       if ((mcode >> 16) == 0x3739) {
+               /* Calculate the branch displacement.  For jumps we need a
+                  displacement relative to PV. */
+
+               disp = targetmpc;
+
+        lo = (short) disp;
+        hi = (short) ((disp - lo) >> 16);
+
+               /* patch the two instructions before the mcodeptr */
+
+               mcodeptr[-2] |= (hi & 0x0000ffff);
+               mcodeptr[-1] |= (lo & 0x0000ffff);
+       }
+       else {
+               /* Calculate the branch displacement.  For branches we need a
+                  displacement relative and shifted to the branch PC. */
+
+               disp = (targetmpc - branchmpc) >> 2;
+
+               /* On the MIPS we can only branch signed 16-bit instruction words
+                  (signed 18-bit = 32KB = +/- 16KB). Check this! */
+
+               if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff))
+                       vm_abort("jump displacement is out of range: %d > +/-%d", disp, 0x00007fff);
+
+               /* patch the branch instruction before the mcodeptr */
+
+               mcodeptr[-1] |= (disp & 0x0000ffff);
+       }
+}
+
+
 /* md_stacktrace_get_returnaddress *********************************************
 
    Returns the return address of the current stackframe, specified by
@@ -132,8 +190,8 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
                assert((mcode >> 16) != 0x6739);
 
                offset += (s2) (mcode & 0x0000ffff);
-
-       else {
+       }
+       else {
                /* get first instruction (ld) */
 
                mcode = *((u4 *) ra);
@@ -152,8 +210,8 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
                        /* in this case we use the passed method pointer */
 
                        pa = mptr + offset;
-
-               else {
+               }
+               else {
                        /* in the normal case we check for a `ld s8,x(s8)' instruction */
 
 #if SIZEOF_VOID_P == 8
index 4d3634504c7837115f386fce70192839635b8c17..2754be0b00900f150af0fb055da6b058c811a7d7 100644 (file)
@@ -26,9 +26,7 @@
 
    Authors: Christian Thalinger
 
-   Changes:
-
-   $Id: patcher.c 5319 2006-09-05 12:54:10Z twisti $
+   $Id: patcher.c 5929 2006-11-06 17:13:40Z twisti $
 
 */
 
@@ -218,7 +216,7 @@ bool patcher_get_putfield(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (opt_showdisassemble)
+       if (opt_shownops)
                ra = ra + 2 * 4;
 
        /* patch the field's offset */
@@ -240,7 +238,7 @@ bool patcher_get_putfield(u1 *sp)
 
        /* synchronize instruction cache */
 
-       if (opt_showdisassemble) {
+       if (opt_shownops) {
 #if SIZEOF_VOID_P == 4
                if (fi->type == TYPE_LNG)
                        md_icacheflush(ra - 2 * 4, 4 * 4);
@@ -515,7 +513,7 @@ bool patcher_invokevirtual(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (opt_showdisassemble)
+       if (opt_shownops)
                ra = ra + 2 * 4;
 
        /* patch vftbl index */
@@ -525,7 +523,7 @@ bool patcher_invokevirtual(u1 *sp)
 
        /* synchronize instruction cache */
 
-       if (opt_showdisassemble)
+       if (opt_shownops)
                md_icacheflush(ra - 2 * 4, 4 * 4);
        else
                md_icacheflush(ra, 2 * 4);
@@ -573,7 +571,7 @@ bool patcher_invokeinterface(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (opt_showdisassemble)
+       if (opt_shownops)
                ra = ra + 2 * 4;
 
        /* patch interfacetable index */
@@ -588,7 +586,7 @@ bool patcher_invokeinterface(u1 *sp)
 
        /* synchronize instruction cache */
 
-       if (opt_showdisassemble)
+       if (opt_shownops)
                md_icacheflush(ra - 2 * 4, 5 * 4);
        else
                md_icacheflush(ra, 3 * 4);
@@ -667,7 +665,7 @@ bool patcher_checkcast_instanceof_flags(u1 *sp)
 
 *******************************************************************************/
 
-bool patcher_checkcast_instanceof_interface(u1 *sp)
+bool patcher_checkcast_interface(u1 *sp)
 {
        u1                *ra;
        u4                 mcode[2];
@@ -693,19 +691,80 @@ bool patcher_checkcast_instanceof_interface(u1 *sp)
 
        /* if we show disassembly, we have to skip the nop's */
 
-       if (opt_showdisassemble)
+       if (opt_shownops)
                ra = ra + 2 * 4;
 
        /* patch super class index */
 
        *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
+/*     *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - */
+/*                                                                      c->index * sizeof(methodptr*)) & 0x0000ffff); */
+       *((s4 *) (ra + 10 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
+                                                                         c->index * sizeof(methodptr*)) & 0x0000ffff);
+
+       /* synchronize instruction cache */
+
+       if (opt_shownops)
+               md_icacheflush(ra - 2 * 4, 8 * 4);
+       else
+               md_icacheflush(ra, 6 * 4);
+
+       return true;
+}
+
+
+/* patcher_instanceof_interface ************************************************
+
+   Machine code:
+
+   <patched call position>
+   dd030000    ld       v1,0(a4)
+   8c79001c    lw       t9,28(v1)
+   27390000    addiu    t9,t9,0
+   1b200082    blez     t9,zero,0x000000001051843c
+   00000000    nop
+   dc790000    ld       t9,0(v1)
+
+*******************************************************************************/
+
+bool patcher_instanceof_interface(u1 *sp)
+{
+       u1                *ra;
+       u4                 mcode[2];
+       constant_classref *cr;
+       classinfo         *c;
+
+       /* get stuff from the stack */
+
+       ra       = (u1 *)                *((ptrint *) (sp + 5 * 8));
+       mcode[0] =                       *((u4 *)     (sp + 3 * 8));
+       mcode[1] =                       *((u4 *)     (sp + 3 * 8 + 4));
+       cr       = (constant_classref *) *((ptrint *) (sp + 2 * 8));
 
+       /* get the fieldinfo */
+
+       if (!(c = resolve_classref_eager(cr)))
+               return false;
+
+       /* patch back original code */
+
+       *((u4 *) (ra + 0 * 4)) = mcode[0];
+       *((u4 *) (ra + 1 * 4)) = mcode[1];
+
+       /* if we show disassembly, we have to skip the nop's */
+
+       if (opt_shownops)
+               ra = ra + 2 * 4;
+
+       /* patch super class index */
+
+       *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
        *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
                                                                         c->index * sizeof(methodptr*)) & 0x0000ffff);
 
        /* synchronize instruction cache */
 
-       if (opt_showdisassemble)
+       if (opt_shownops)
                md_icacheflush(ra - 2 * 4, 8 * 4);
        else
                md_icacheflush(ra, 6 * 4);
index 3a95ccd8c4a8e6efeb39607406cbe65ca99e4443..9b2c5916c99c9267ceed107dd48fb65e357bda82 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: patcher.h 5281 2006-08-28 15:18:54Z twisti $
+   $Id: patcher.h 5929 2006-11-06 17:13:40Z twisti $
 
 */
 
@@ -175,6 +175,12 @@ bool patcher_checkcast_instanceof_flags(u1 *sp);
 bool patcher_checkcast_instanceof_interface(u1 *sp);
 #define PATCHER_checkcast_instanceof_interface (functionptr) patcher_checkcast_instanceof_interface
 
+bool patcher_checkcast_interface(u1 *sp);
+#define PATCHER_checkcast_interface (functionptr) patcher_checkcast_interface
+
+bool patcher_instanceof_interface(u1 *sp);
+#define PATCHER_instanceof_interface (functionptr) patcher_instanceof_interface
+
 #if defined(__I386__) || defined(__X86_64__) || defined(__POWERPC__) || defined(__POWERPC64__)
 
 bool patcher_checkcast_class(u1 *sp);