* Removed all Id tags.
[cacao.git] / src / vm / jit / arm / emit.c
index e16bc2ccc2781b09cc2faa33b9f4e2c54501eb37..456d27cb9a86201a225db9972fbbe122965ee6a8 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: emit.c 4398 2006-01-31 23:43:08Z twisti $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 
 #include "vm/types.h"
 
@@ -49,6 +48,7 @@
 #include "vm/jit/asmpart.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 
 #include "toolbox/logging.h" /* XXX for debugging only */
@@ -73,7 +73,7 @@ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
        if (src->flags & INMEMORY) {
                COUNT_SPILLS;
 
-               disp = src->vv.regoff * 4;
+               disp = src->vv.regoff;
 
 #if defined(ENABLE_SOFTFLOAT)
                switch (src->type) {
@@ -139,7 +139,7 @@ s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
        if (src->flags & INMEMORY) {
                COUNT_SPILLS;
 
-               disp = src->vv.regoff * 4;
+               disp = src->vv.regoff;
 
 #if defined(__ARMEL__)
                M_ILD(tempreg, REG_SP, disp);
@@ -177,7 +177,7 @@ s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
        if (src->flags & INMEMORY) {
                COUNT_SPILLS;
 
-               disp = src->vv.regoff * 4;
+               disp = src->vv.regoff;
 
 #if defined(__ARMEL__)
                M_ILD(tempreg, REG_SP, disp + 4);
@@ -212,7 +212,7 @@ void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
        if (dst->flags & INMEMORY) {
                COUNT_SPILLS;
 
-               disp = dst->vv.regoff * 4;
+               disp = dst->vv.regoff;
 
 #if defined(ENABLE_SOFTFLOAT)
                switch (dst->type) {
@@ -246,13 +246,6 @@ void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
                default:
                        vm_abort("emit_store: unknown type %d", dst->type);
                }
-#endif
-       }
-       else if (IS_LNG_TYPE(dst->type)) {
-#if defined(__ARMEL__)
-               assert(GET_HIGH_REG(dst->vv.regoff) != REG_SPLIT);
-#else
-               assert(GET_LOW_REG(dst->vv.regoff) != REG_SPLIT);
 #endif
        }
 }
@@ -517,7 +510,7 @@ void emit_nullpointer_check_force(codegendata *cd, instruction *iptr, s4 reg)
 void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
 {
        if (INSTRUCTION_MUST_CHECK(iptr)) {
-               M_ILD_INTERN(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+               M_ILD_INTERN(REG_ITMP3, s1, OFFSET(java_array_t, size));
                M_CMP(s2, REG_ITMP3);
                M_TRAPHS(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
        }
@@ -567,154 +560,25 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 }
 
 
-/* emit_patcher_stubs **********************************************************
+/* emit_trap *******************************************************************
 
-   Generates the code for the patcher stubs.
+   Emit a trap instruction and return the original machine code.
 
 *******************************************************************************/
 
-void emit_patcher_stubs(jitdata *jd)
+uint32_t emit_trap(codegendata *cd)
 {
-       codegendata *cd;
-       patchref    *pref;
-       u4           mcode;
-       u1          *savedmcodeptr;
-       u1          *tmpmcodeptr;
-       s4           targetdisp;
-       s4           disp;
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-
-       /* generate patcher stub call code */
-
-       targetdisp = 0;
-
-       for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
-               /* check code segment size */
-
-               MCODECHECK(100);
-
-               /* Get machine code which is patched back in later. The
-                  call is 1 instruction word long. */
-
-               tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
-
-               mcode = *((u4 *) tmpmcodeptr);
-
-               /* Patch in the call to call the following code (done at
-                  compile time). */
-
-               savedmcodeptr = cd->mcodeptr;   /* save current mcodeptr              */
-               cd->mcodeptr  = tmpmcodeptr;    /* set mcodeptr to patch position     */
-
-               disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 2);
-               M_B(disp);
-
-               cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr       */
-
-               /* create stack frame (align stack to 8-byte) */
-
-               M_SUB_IMM(REG_SP, REG_SP, 8 * 4);
-
-               /* save itmp3 onto stack */
-
-               M_STR_INTERN(REG_ITMP3, REG_SP, 6 * 4);
-
-               /* calculate return address and move it onto stack */
-               /* ATTENTION: we can not use BL to branch to patcher stub,        */
-               /* ATTENTION: because we need to preserve LR for leaf methods     */
-
-               disp = (s4) (((u4 *) cd->mcodeptr) - (((u4 *) tmpmcodeptr) + 1) + 2);
-
-               M_SUB_IMM_EXT_MUL4(REG_ITMP3, REG_PC, disp);
-               M_STR_INTERN(REG_ITMP3, REG_SP, 4 * 4);
-
-               /* move pointer to java_objectheader onto stack */
-
-#if defined(ENABLE_THREADS)
-               /* order reversed because of data segment layout */
+       uint32_t mcode;
 
-               (void) dseg_add_unique_address(cd, NULL);           /* flcword    */
-               (void) dseg_add_unique_address(cd, lock_get_initial_lock_word());
-               disp = dseg_add_unique_address(cd, NULL);           /* vftbl      */
+       /* Get machine code which is patched back in later. The
+          trap is 1 instruction word long. */
 
-               M_SUB_IMM_EXT_MUL4(REG_ITMP3, REG_PV, -disp / 4);
-               M_STR_INTERN(REG_ITMP3, REG_SP, 3 * 4);
-#else
-               M_EOR(REG_ITMP3, REG_ITMP3, REG_ITMP3);
-               M_STR_INTERN(REG_ITMP3, REG_SP, 3 * 4);
-#endif
-
-               /* move machine code onto stack */
-
-               disp = dseg_add_unique_s4(cd, mcode);
-               M_DSEG_LOAD(REG_ITMP3, disp);
-               M_STR_INTERN(REG_ITMP3, REG_SP, 2 * 4);
-
-               /* move class/method/field reference onto stack */
-
-               disp = dseg_add_unique_address(cd, pref->ref);
-               M_DSEG_LOAD(REG_ITMP3, disp);
-               M_STR_INTERN(REG_ITMP3, REG_SP, 1 * 4);
-
-               /* move data segment displacement onto stack */
-
-               disp = dseg_add_unique_s4(cd, pref->disp);
-               M_DSEG_LOAD(REG_ITMP3, disp);
-               M_STR_INTERN(REG_ITMP3, REG_SP, 5 * 4);
-
-               /* move patcher function pointer onto stack */
-
-               disp = dseg_add_functionptr(cd, pref->patcher);
-               M_DSEG_LOAD(REG_ITMP3, disp);
-               M_STR_INTERN(REG_ITMP3, REG_SP, 0 * 4);
-
-               /* finally call the patcher via asm_patcher_wrapper */
-               /* ATTENTION: don't use REG_PV here, because some patchers need it */
-
-               if (targetdisp == 0) {
-                       targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase);
-
-                       disp = dseg_add_functionptr(cd, asm_patcher_wrapper);
-                       /*M_DSEG_BRANCH_NOLINK(REG_PC, REG_PV, a);*/
-                       /* TODO: this is only a hack */
-                       M_DSEG_LOAD(REG_ITMP3, disp);
-                       M_MOV(REG_PC, REG_ITMP3);
-               }
-               else {
-                       disp = (((u4 *) cd->mcodebase) + targetdisp) -
-                               (((u4 *) cd->mcodeptr) + 2);
+       mcode = *((u4 *) cd->mcodeptr);
 
-                       M_B(disp);
-               }
-       }
-}
-
-
-/* emit_replacement_stubs ******************************************************
-
-   Generates the code for the replacement stubs.
-
-*******************************************************************************/
+       M_TRAP(0, EXCEPTION_HARDWARE_PATCHER);
 
-#if defined(ENABLE_REPLACEMENT)
-void emit_replacement_stubs(jitdata *jd)
-{
-       codegendata *cd;
-       codeinfo    *code;
-       rplpoint    *rplp;
-       u1          *savedmcodeptr;
-       s4           disp;
-       s4           i;
-
-       /* get required compiler data */
-
-       cd   = jd->cd;
-       code = jd->code;
+       return mcode;
 }
-#endif /* defined(ENABLE_REPLACEMENT) */
 
 
 /* emit_verbosecall_enter ******************************************************
@@ -756,7 +620,7 @@ void emit_verbosecall_enter(jitdata *jd)
        M_STMFD(BITMASK_ARGS | (1<<REG_LR) | (1<<REG_PV), REG_SP);
        M_SUB_IMM(REG_SP, REG_SP, (2 + 2 + 1 + 1) * 4); /* space for a3, a4 and m */
 
-       stackframesize += 6 + 2 + 2 + 1 + 1;
+       stackframesize += (6 + 2 + 2 + 1 + 1) * 4;
 
        /* prepare args for tracer */
 
@@ -777,19 +641,15 @@ void emit_verbosecall_enter(jitdata *jd)
                                M_MOV_IMM(REG_ITMP1, 0);
                                s1 = PACK_REGS(s1, REG_ITMP1);
                        }
-                       else {
-                               SPLIT_OPEN(t, s1, REG_ITMP1);
-                               SPLIT_LOAD(t, s1, stackframesize);
-                       }
                }
                else {
                        s1 = REG_ITMP12_PACKED;
                        s2 = md->params[i].regoff + stackframesize;
 
                        if (IS_2_WORD_TYPE(t))
-                               M_LLD(s1, REG_SP, s2 * 4);
+                               M_LLD(s1, REG_SP, s2);
                        else {
-                               M_ILD(GET_LOW_REG(s1), REG_SP, s2 * 4);
+                               M_ILD(GET_LOW_REG(s1), REG_SP, s2);
                                M_MOV_IMM(GET_HIGH_REG(s1), 0);
                        }
                }