* src/vm/jit/powerpc/emit.c (emit_replacement_stubs): Prepared for
[cacao.git] / src / vm / jit / alpha / emit.c
index 365858a1256cd3b54b4f1237abb9ae62c6b0484e..019ed4f34ee3fc729b29e125968b6e7bdfbfa044 100644 (file)
@@ -26,8 +26,6 @@
 
    Authors: Christian Thalinger
 
-   Changes:
-
    $Id: emit.c 4398 2006-01-31 23:43:08Z twisti $
 
 */
 #endif
 
 #include "vm/builtin.h"
+#include "vm/options.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/dseg.h"
-#include "vm/jit/emit.h"
+#include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/replace.h"
 
 
-/* code generation functions **************************************************/
-
 /* emit_load *******************************************************************
 
    Emits a possible load of an operand.
 
 *******************************************************************************/
 
-s4 emit_load(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
 {
        codegendata  *cd;
        s4            reg;
@@ -70,78 +67,30 @@ s4 emit_load(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 
        cd = jd->cd;
 
-       if (src->flags & INMEMORY) {
+       if (IS_INMEMORY(src->flags)) {
                COUNT_SPILLS;
 
                if (IS_FLT_DBL_TYPE(src->type))
-                       M_DLD(tempreg, REG_SP, src->regoff * 8);
+                       M_DLD(tempreg, REG_SP, src->vv.regoff * 8);
                else
-                       M_LLD(tempreg, REG_SP, src->regoff * 8);
+                       M_LLD(tempreg, REG_SP, src->vv.regoff * 8);
 
                reg = tempreg;
        }
        else
-               reg = src->regoff;
+               reg = src->vv.regoff;
 
        return reg;
 }
 
 
-/* emit_load_s1 ****************************************************************
-
-   Emits a possible load of the first source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
-{
-       s4 r;
-       
-       r = emit_load(jd, iptr, iptr->s1.var, tempreg);
-
-       return r;
-}
-
-
-/* emit_load_s2 ****************************************************************
-
-   Emits a possible load of the second source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
-{
-       s4 r;
-
-       r = emit_load(jd, iptr, iptr->sx.s23.s2.var, tempreg);
-
-       return r;
-}
-
-
-/* emit_load_s3 ****************************************************************
-
-   Emits a possible load of the third source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
-{
-       s4 r;
-
-       r = emit_load(jd, iptr, iptr->sx.s23.s3.var, tempreg);
-
-       return r;
-}
-
-
 /* emit_store ******************************************************************
 
    Emit a possible store for the given variable.
 
 *******************************************************************************/
 
-void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
 
@@ -149,47 +98,33 @@ void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
        cd = jd->cd;
 
-       if (dst->flags & INMEMORY) {
+       if (IS_INMEMORY(dst->flags)) {
                COUNT_SPILLS;
 
                if (IS_FLT_DBL_TYPE(dst->type))
-                       M_DST(d, REG_SP, dst->regoff * 8);
+                       M_DST(d, REG_SP, dst->vv.regoff * 8);
                else
-                       M_LST(d, REG_SP, dst->regoff * 8);
+                       M_LST(d, REG_SP, dst->vv.regoff * 8);
        }
 }
 
 
-/* emit_store_dst **************************************************************
-
-   Emit a possible store for the destination operand.
-
-*******************************************************************************/
-
-void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
-{
-       emit_store(jd, iptr, iptr->dst.var, d);
-}
-
-
 /* emit_copy *******************************************************************
 
    Generates a register/memory to register/memory copy.
 
 *******************************************************************************/
 
-void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
+void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
 {
        codegendata  *cd;
-       registerdata *rd;
        s4            s1, d;
 
        /* get required compiler data */
 
        cd = jd->cd;
-       rd = jd->rd;
 
-       if ((src->regoff != dst->regoff) ||
+       if ((src->vv.regoff != dst->vv.regoff) ||
                ((src->flags ^ dst->flags) & INMEMORY)) {
 
                /* If one of the variables resides in memory, we can eliminate
@@ -197,12 +132,12 @@ void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
                   order of getting the destination register and the load. */
 
                if (IS_INMEMORY(src->flags)) {
-                       d = codegen_reg_of_var(rd, iptr->opc, dst, REG_IFTMP);
+                       d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
                        s1 = emit_load(jd, iptr, src, d);
                }
                else {
                        s1 = emit_load(jd, iptr, src, REG_IFTMP);
-                       d = codegen_reg_of_var(rd, iptr->opc, dst, s1);
+                       d = codegen_reg_of_var(iptr->opc, dst, s1);
                }
 
                if (s1 != d) {
@@ -230,7 +165,7 @@ void emit_iconst(codegendata *cd, s4 d, s4 value)
        if ((value >= -32768) && (value <= 32767))
                M_LDA_INTERN(d, REG_ZERO, value);
        else {
-               disp = dseg_adds4(cd, value);
+               disp = dseg_add_s4(cd, value);
                M_ILD(d, REG_PV, disp);
        }
 }
@@ -249,12 +184,70 @@ void emit_lconst(codegendata *cd, s4 d, s8 value)
        if ((value >= -32768) && (value <= 32767))
                M_LDA_INTERN(d, REG_ZERO, value);
        else {
-               disp = dseg_adds8(cd, value);
+               disp = dseg_add_s8(cd, value);
                M_LLD(d, REG_PV, disp);
        }
 }
 
 
+/* 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);
+               M_BEQZ(REG_ITMP3, 0);
+               codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+       }
+}
+
+
+/* emit_arraystore_check *******************************************************
+
+   Emit an ArrayStoreException check.
+
+*******************************************************************************/
+
+void emit_arraystore_check(codegendata *cd, s4 reg)
+{
+       M_BEQZ(reg, 0);
+       codegen_add_arraystoreexception_ref(cd);
+}
+
+
+/* emit_classcast_check ********************************************************
+
+   Emit a ClassCastException check.
+
+*******************************************************************************/
+
+void emit_classcast_check(codegendata *cd, s4 condition, s4 reg, s4 s1)
+{
+       M_BNEZ(reg, 0);
+       codegen_add_classcastexception_ref(cd, s1);
+}
+
+
+/* emit_nullpointer_check ******************************************************
+
+   Emit a NullPointerException check.
+
+*******************************************************************************/
+
+void emit_nullpointer_check(codegendata *cd, s4 reg)
+{
+       if (checknull) {
+               M_BEQZ(reg, 0);
+               codegen_add_nullpointerexception_ref(cd);
+       }
+}
+
+
 /* emit_exception_stubs ********************************************************
 
    Generates the code for the exception stubs.
@@ -265,7 +258,9 @@ void emit_exception_stubs(jitdata *jd)
 {
        codegendata  *cd;
        registerdata *rd;
-       exceptionref *eref;
+       exceptionref *er;
+       s4            branchmpc;
+       s4            targetmpc;
        s4            targetdisp;
        s4            disp;
 
@@ -278,9 +273,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);
 
@@ -290,16 +289,16 @@ void emit_exception_stubs(jitdata *jd)
                   ArrayIndexOutOfBoundsException.  If so, move index register
                   into a4. */
 
-               if (eref->reg != -1)
-                       M_MOV(eref->reg, rd->argintregs[4]);
+               if (er->reg != -1)
+                       M_MOV(er->reg, rd->argintregs[4]);
 
                /* calcuate exception address */
 
-               M_LDA(rd->argintregs[3], REG_PV, eref->branchpos - 4);
+               M_LDA(rd->argintregs[3], 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) {
@@ -469,9 +468,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 */
 
@@ -480,24 +481,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 *) (ptrint) (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);
+               /* 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 - 16-byte aligned */
 
@@ -514,6 +514,8 @@ void emit_replacement_stubs(jitdata *jd)
                disp = dseg_add_functionptr(cd, asm_replacement_out);
                M_ALD(REG_ITMP3, REG_PV, disp);
                M_JMP(REG_ZERO, REG_ITMP3);
+
+               assert((cd->mcodeptr - savedmcodeptr) == 4*REPLACEMENT_STUB_SIZE);
        }
 }