* src/vm/jit/powerpc/emit.c (emit_replacement_stubs): Prepared for
[cacao.git] / src / vm / jit / powerpc / emit.c
index c0c77f8b7dc4748ce434fa398ad97a6255ea1559..b6e060a5ac5e341065a57d293dfebf233d6e753e 100644 (file)
@@ -26,9 +26,7 @@
 
    Authors: Christian Thalinger
 
-   Changes:
-
-   $Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
+   $Id: emit.c 4398 2006-01-31 23:43:08Z twisti $
 
 */
 
 
 #include "vm/jit/powerpc/codegen.h"
 
+#include "mm/memory.h"
 #include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/options.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
@@ -271,6 +272,46 @@ void emit_iconst(codegendata *cd, s4 d, s4 value)
 }
 
 
+/* emit_nullpointer_check ******************************************************
+
+   Emit a NullPointerException check.
+
+*******************************************************************************/
+
+void emit_nullpointer_check(codegendata *cd, s4 reg)
+{
+       if (checknull) {
+               M_TST(reg);
+               M_BEQ(0);
+               codegen_add_nullpointerexception_ref(cd);
+       }
+}
+
+
+/* emit_arrayindexoutofbounds_check ********************************************
+
+   Emit a ArrayIndexOutOfBoundsException check.
+
+*******************************************************************************/
+
+void emit_arrayindexoutofbounds_check(codegendata *cd, s4 s1, s4 s2)
+{
+#if 0
+       if (checkbounds) {
+               M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+               M_CMPU(s2, REG_ITMP3);
+               M_BGE(0);
+               codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+       }
+#else
+       M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+       M_CMPU(s2, REG_ITMP3);
+       M_BLT(1);
+       M_ALD_INTERN(s2, REG_ZERO, EXCEPTION_LOAD_DISP_ARRAYINDEXOUTOFBOUNDS);
+#endif
+}
+
+
 /* emit_exception_stubs ********************************************************
 
    Generates the code for the exception stubs.
@@ -281,7 +322,9 @@ void emit_exception_stubs(jitdata *jd)
 {
        codegendata  *cd;
        registerdata *rd;
-       exceptionref *eref;
+       exceptionref *er;
+       s4            branchmpc;
+       s4            targetmpc;
        s4            targetdisp;
        s4            disp;
 
@@ -294,25 +337,29 @@ 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);
 
                /* Move the value register to a temporary register, if
                   there is the need for it. */
 
-               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) {
@@ -490,9 +537,11 @@ void emit_replacement_stubs(jitdata *jd)
        codegendata *cd;
        codeinfo    *code;
        rplpoint    *rplp;
-       u1          *savedmcodeptr;
        s4           disp;
        s4           i;
+#if !defined(NDEBUG)
+       u1          *savedmcodeptr;
+#endif
 
        /* get required compiler data */
 
@@ -501,24 +550,23 @@ void emit_replacement_stubs(jitdata *jd)
 
        rplp = code->rplpoints;
 
-       for (i = 0; i < code->rplpointcount; ++i, ++rplp) {
-               /* check code segment size */
-
-               MCODECHECK(100);
+       /* store beginning of replacement stubs */
 
-               /* note start of stub code */
+       code->replacementstubs = (u1*) (cd->mcodeptr - cd->mcodebase);
 
-               rplp->outcode = (u1 *) (cd->mcodeptr - cd->mcodebase);
+       for (i = 0; i < code->rplpointcount; ++i, ++rplp) {
+               /* do not generate stubs for non-trappable points */
 
-               /* make machine code for patching */
+               if (rplp->flags & RPLPOINT_FLAG_NOTRAP)
+                       continue;
 
-               savedmcodeptr = cd->mcodeptr;
-               cd->mcodeptr  = (u1 *) &(rplp->mcode) + 1;              /* big-endian */
+               /* check code segment size */
 
-               disp = (ptrint) ((s4 *) rplp->outcode - (s4 *) rplp->pc) - 1;
-               M_BR(disp);
+               MCODECHECK(100);
 
-               cd->mcodeptr = savedmcodeptr;
+#if !defined(NDEBUG)
+               savedmcodeptr = cd->mcodeptr;
+#endif
 
                /* create stack frame - keep 16-byte aligned */
 
@@ -536,6 +584,8 @@ void emit_replacement_stubs(jitdata *jd)
                M_ALD(REG_ITMP3, REG_PV, disp);
                M_MTCTR(REG_ITMP3);
                M_RTS;
+
+               assert((cd->mcodeptr - savedmcodeptr) == 4*REPLACEMENT_STUB_SIZE);
        }
 }
 
@@ -724,12 +774,12 @@ void emit_verbosecall_enter(jitdata *jd)
                if (IS_INT_LNG_TYPE(t)) {
                        if (!md->params[p].inmemory) {
                                if (IS_2_WORD_TYPE(t)) {
-                                       M_ILD(rd->argintregs[GET_HIGH_REG(md->params[p].vv.regoff)]
+                                       M_ILD(rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]
                                                  , REG_SP, stack_off);
-                                       M_ILD(rd->argintregs[GET_LOW_REG(md->params[p].vv.regoff)]
+                                       M_ILD(rd->argintregs[GET_LOW_REG(md->params[p].regoff)]
                                                  , REG_SP, stack_off + 4);
                                } else {
-                                       M_ILD(rd->argintregs[md->params[p].vv.regoff]
+                                       M_ILD(rd->argintregs[md->params[p].regoff]
                                                  , REG_SP, stack_off + 4);
                                }
                        }