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"
}
+/* 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.
{
codegendata *cd;
registerdata *rd;
- exceptionref *eref;
+ exceptionref *er;
+ s4 branchmpc;
+ s4 targetmpc;
s4 targetdisp;
s4 disp;
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) {
codegendata *cd;
codeinfo *code;
rplpoint *rplp;
- u1 *savedmcodeptr;
s4 disp;
s4 i;
+#if !defined(NDEBUG)
+ u1 *savedmcodeptr;
+#endif
/* get required compiler data */
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 */
M_ALD(REG_ITMP3, REG_PV, disp);
M_MTCTR(REG_ITMP3);
M_RTS;
+
+ assert((cd->mcodeptr - savedmcodeptr) == 4*REPLACEMENT_STUB_SIZE);
}
}
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);
}
}