/* src/vm/jit/mips/codegen.c - machine code generator for MIPS
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: codegen.c 7713 2007-04-15 21:49:48Z twisti $
-
*/
#include "mm/memory.h"
+#include "native/localref.h"
#include "native/native.h"
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "threads/lock-common.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
#include "vm/jit/abi.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
-#include "vm/jit/patcher.h"
+#include "vm/jit/linenumbertable.h"
+#include "vm/jit/patcher-common.h"
#include "vm/jit/reg.h"
#include "vm/jit/replace.h"
+#include "vm/jit/trap.h"
#if defined(ENABLE_LSRA)
# include "vm/jit/allocator/lsra.h"
varinfo *var;
basicblock *bptr;
instruction *iptr;
- exception_entry *ex;
u2 currentline;
constant_classref *cr;
unresolved_class *uc;
s4 i, p, t, l;
s4 savedregs_num;
- savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
+ savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
/* space to save used callee saved registers */
#if defined(ENABLE_THREADS)
/* space to save argument of monitor_enter */
- if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ if (checksync && code_is_synchronized(code)) {
# if SIZEOF_VOID_P == 8
cd->stackframesize++;
# else
(void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
(void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
-#if defined(ENABLE_THREADS)
- /* IsSync contains the offset relative to the stack pointer for the
- argument of monitor_exit used in the exception handler. Since the
- offset could be zero and give a wrong meaning of the flag it is
- offset by one.
- */
-
- if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
+ code->synchronizedoffset = rd->memuse * 8;
+
+ /* REMOVEME: We still need it for exception handling in assembler. */
+
+ if (code_is_leafmethod(code))
+ (void) dseg_add_unique_s4(cd, 1);
else
-#endif
- (void) dseg_add_unique_s4(cd, 0); /* IsSync */
-
- (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
+ (void) dseg_add_unique_s4(cd, 0);
+
(void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
(void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
- dseg_addlinenumbertablesize(cd);
- (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
- /* create exception table */
-
- for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
- dseg_add_target(cd, ex->start);
- dseg_add_target(cd, ex->end);
- dseg_add_target(cd, ex->handler);
- (void) dseg_add_unique_address(cd, ex->catchtype.any);
- }
-
/* create stack frame (if necessary) */
if (cd->stackframesize)
/* save return address and used callee saved registers */
p = cd->stackframesize;
- if (!jd->isleafmethod) {
+ if (!code_is_leafmethod(code)) {
p--; M_AST(REG_RA, REG_SP, p * 8);
}
for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
if (!(var->flags & INMEMORY))
M_INTMOVE(s1, var->vv.regoff);
else
- M_LST(s1, REG_SP, var->vv.regoff * 8);
+ M_LST(s1, REG_SP, var->vv.regoff);
#else
- if (IS_2_WORD_TYPE(t)) {
- if (!(var->flags & INMEMORY))
+ if (!(var->flags & INMEMORY)) {
+ if (IS_2_WORD_TYPE(t))
M_LNGMOVE(s1, var->vv.regoff);
else
- M_LST(s1, REG_SP, var->vv.regoff * 8);
+ M_INTMOVE(s1, var->vv.regoff);
}
else {
- if (!(var->flags & INMEMORY))
- M_INTMOVE(s1, var->vv.regoff);
+ if (IS_2_WORD_TYPE(t))
+ M_LST(s1, REG_SP, var->vv.regoff);
else
- M_IST(s1, REG_SP, var->vv.regoff * 8);
+ M_IST(s1, REG_SP, var->vv.regoff);
}
#endif
}
else { /* stack arguments */
if (!(var->flags & INMEMORY)) {
#if SIZEOF_VOID_P == 8
- M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
#else
if (IS_2_WORD_TYPE(t))
- M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
else
- M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
#endif
}
else
- var->vv.regoff = cd->stackframesize + s1;
+ var->vv.regoff = cd->stackframesize * 8 + s1;
}
}
else { /* floating args */
if (!md->params[p].inmemory) {
-#if SIZEOF_VOID_P == 8
if (!(var->flags & INMEMORY)) {
if (IS_2_WORD_TYPE(t))
- M_DMOV(s1, var->vv.regoff);
+ M_DBLMOVE(s1, var->vv.regoff);
else
- M_FMOV(s1, var->vv.regoff);
+ M_FLTMOVE(s1, var->vv.regoff);
}
else {
if (IS_2_WORD_TYPE(t))
- M_DST(s1, REG_SP, var->vv.regoff * 8);
+ M_DST(s1, REG_SP, var->vv.regoff);
else
- M_FST(s1, REG_SP, var->vv.regoff * 8);
+ M_FST(s1, REG_SP, var->vv.regoff);
}
-#else
- if ((p == 0) ||
- ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
- if (!(var->flags & INMEMORY)) {
- if (IS_2_WORD_TYPE(t))
- M_DBLMOVE(s1, var->vv.regoff);
- else
- M_FLTMOVE(s1, var->vv.regoff);
- }
- else {
- if (IS_2_WORD_TYPE(t))
- M_DST(s1, REG_SP, var->vv.regoff * 8);
- else
- M_FST(s1, REG_SP, var->vv.regoff * 8);
- }
- }
- else {
- if (IS_2_WORD_TYPE(t)) {
- if (!(var->flags & INMEMORY)) {
- M_MTC1(GET_LOW_REG(s1), var->vv.regoff);
- M_MTC1(GET_HIGH_REG(s1), var->vv.regoff + 1);
- M_NOP;
- }
- else
- M_LST(s1, REG_SP, var->vv.regoff * 8);
- }
- else {
- if (!(var->flags & INMEMORY)) {
- M_MTC1(s1, var->vv.regoff);
- M_NOP;
- }
- else
- M_IST(s1, REG_SP, var->vv.regoff * 8);
- }
- }
-#endif
}
else {
if (!(var->flags & INMEMORY)) {
if (IS_2_WORD_TYPE(t))
- M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
else
- M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
}
else
- var->vv.regoff = cd->stackframesize + s1;
+ var->vv.regoff = cd->stackframesize * 8 + s1;
}
}
}
/* call monitorenter function */
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ if (checksync && code_is_synchronized(code)) {
/* stack offset for monitor argument */
s1 = rd->memuse;
/* get correct lock object */
if (m->flags & ACC_STATIC) {
- disp = dseg_add_address(cd, &m->class->object.header);
+ disp = dseg_add_address(cd, &m->clazz->object.header);
M_ALD(REG_A0, REG_PV, disp);
disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
M_ALD(REG_ITMP3, REG_PV, disp);
M_BNEZ(REG_A0, 2);
disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
- M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+ M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
}
M_JSR(REG_RA, REG_ITMP3);
for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
if (iptr->line != currentline) {
- dseg_addlinenumber(cd, iptr->line);
+ linenumbertable_list_entry_add(cd, iptr->line);
currentline = iptr->line;
}
case ICMD_INLINE_BODY:
REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
- dseg_addlinenumber_inline_start(cd, iptr);
- dseg_addlinenumber(cd, iptr->line);
+ linenumbertable_list_entry_add_inline_start(cd, iptr);
+ linenumbertable_list_entry_add(cd, iptr->line);
break;
case ICMD_INLINE_END:
- dseg_addlinenumber_inline_end(cd, iptr);
- dseg_addlinenumber(cd, iptr->line);
+ linenumbertable_list_entry_add_inline_end(cd, iptr);
+ linenumbertable_list_entry_add(cd, iptr->line);
break;
case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
cr = iptr->sx.val.c.ref;
disp = dseg_add_unique_address(cd, cr);
- codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
+ cr, disp);
M_ALD(d, REG_PV, disp);
}
/* load/store/copy/move operations ************************************/
case ICMD_ILOAD: /* ... ==> ..., content of local variable */
- case ICMD_LLOAD: /* ... ==> ..., content of local variable */
- case ICMD_ALOAD: /* ... ==> ..., content of local variable */
- case ICMD_FLOAD: /* ... ==> ..., content of local variable */
- case ICMD_DLOAD: /* ... ==> ..., content of local variable */
+ case ICMD_LLOAD:
+ case ICMD_ALOAD:
+ case ICMD_FLOAD:
+ case ICMD_DLOAD:
case ICMD_ISTORE: /* ..., value ==> ... */
- case ICMD_LSTORE: /* ..., value ==> ... */
- case ICMD_FSTORE: /* ..., value ==> ... */
- case ICMD_DSTORE: /* ..., value ==> ... */
+ case ICMD_LSTORE:
+ case ICMD_FSTORE:
+ case ICMD_DSTORE:
case ICMD_COPY:
case ICMD_MOVE:
- emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
+ emit_copy(jd, iptr);
break;
case ICMD_ASTORE:
if (!(iptr->flags.bits & INS_FLAG_RETADDR))
- emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
+ emit_copy(jd, iptr);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
/* implicit null-pointer check */
- M_ILD(d, s1, OFFSET(java_arrayheader, size));
+ M_ILD(d, s1, OFFSET(java_array_t, size));
emit_store_dst(jd, iptr, d);
break;
emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP3);
/* implicit null-pointer check */
- M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
+ M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
emit_store_dst(jd, iptr, d);
break;
M_AADD(s2, s1, REG_ITMP3);
M_AADD(s2, REG_ITMP3, REG_ITMP3);
/* implicit null-pointer check */
- M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
+ M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
emit_store_dst(jd, iptr, d);
break;
M_AADD(s2, s1, REG_ITMP3);
M_AADD(s2, REG_ITMP3, REG_ITMP3);
/* implicit null-pointer check */
- M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
+ M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
emit_store_dst(jd, iptr, d);
break;
M_ASLL_IMM(s2, 2, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
/* implicit null-pointer check */
- M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
+ M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
emit_store_dst(jd, iptr, d);
break;
M_ASLL_IMM(s2, 3, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
/* implicit null-pointer check */
- M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
+ M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
emit_store_dst(jd, iptr, d);
break;
M_ASLL_IMM(s2, 2, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
/* implicit null-pointer check */
- M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
+ M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
emit_store_dst(jd, iptr, d);
break;
M_ASLL_IMM(s2, 3, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
/* implicit null-pointer check */
- M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
+ M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
emit_store_dst(jd, iptr, d);
break;
M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
/* implicit null-pointer check */
- M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
+ M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
emit_store_dst(jd, iptr, d);
break;
M_AADD(s2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
/* implicit null-pointer check */
- M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
+ M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
break;
case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
M_AADD(s2, REG_ITMP1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
/* implicit null-pointer check */
- M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
+ M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
break;
case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
/* implicit null-pointer check */
- M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
+ M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
break;
case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
#endif
/* implicit null-pointer check */
- M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
+ M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
break;
case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_FTMP1);
/* implicit null-pointer check */
- M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
+ M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
break;
case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_FTMP1);
/* implicit null-pointer check */
- M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
+ M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
break;
M_INTMOVE(s1, REG_A0);
M_INTMOVE(s3, REG_A1);
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
M_JSR(REG_RA, REG_ITMP3);
M_NOP;
- emit_exception_check(cd, iptr);
+ emit_arraystore_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
/* implicit null-pointer check */
- M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+ M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
break;
emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP1);
/* implicit null-pointer check */
- M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
+ M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
break;
case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
M_AADD(s2, s1, REG_ITMP1);
M_AADD(s2, REG_ITMP1, REG_ITMP1);
/* implicit null-pointer check */
- M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
+ M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
break;
case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
M_ASLL_IMM(s2, 2, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
/* implicit null-pointer check */
- M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
+ M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
break;
case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
M_AADD(REG_ITMP2, s1, REG_ITMP1);
/* implicit null-pointer check */
#if SIZEOF_VOID_P == 8
- M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
+ M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
#else
- M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
+ M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
#endif
break;
M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
/* implicit null-pointer check */
- M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+ M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
break;
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = dseg_add_unique_address(cd, uf);
- codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
+ patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
- disp = dseg_add_address(cd, &(fi->value));
+ disp = dseg_add_address(cd, fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
- codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+ patcher_add_patch_ref(jd, PATCHER_initialize_class,
+ fi->clazz, disp);
}
M_ALD(REG_ITMP1, REG_PV, disp);
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = dseg_add_unique_address(cd, uf);
- codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
+ patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
- disp = dseg_add_address(cd, &(fi->value));
+ disp = dseg_add_address(cd, fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
- codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+ patcher_add_patch_ref(jd, PATCHER_initialize_class,
+ fi->clazz, disp);
}
M_ALD(REG_ITMP1, REG_PV, disp);
break;
case ICMD_PUTSTATICCONST: /* ... ==> ... */
- /* val = value (in current instruction) */
- /* following NOP) */
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = dseg_add_unique_address(cd, uf);
- codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
+ patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
- disp = dseg_add_address(cd, &(fi->value));
+ disp = dseg_add_address(cd, fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
- codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+ patcher_add_patch_ref(jd, PATCHER_initialize_class,
+ fi->clazz, disp);
}
M_ALD(REG_ITMP1, REG_PV, disp);
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = 0;
- codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
+ patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
#endif
if (INSTRUCTION_IS_UNRESOLVED(iptr))
- codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
+ patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
switch (fieldtype) {
case TYPE_INT:
emit_nullpointer_check(cd, iptr, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+ uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = 0;
- codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
+ patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
}
else {
- fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
+ fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
disp = fi->offset;
}
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uc = iptr->sx.s23.s2.uc;
- codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
+ patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
}
#endif /* ENABLE_VERIFIER */
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uc = iptr->sx.s23.s2.uc;
- codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
+ patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
}
#endif /* ENABLE_VERIFIER */
goto nowperformreturn;
#endif
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ if (checksync && code_is_synchronized(code)) {
disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
M_ALD(REG_ITMP3, REG_PV, disp);
/* restore return address */
- if (!jd->isleafmethod) {
+ if (!code_is_leafmethod(code)) {
p--; M_ALD(REG_RA, REG_SP, p * 8);
}
}
else {
s1 = emit_load(jd, iptr, var, REG_ITMP1);
- M_LST(s1, REG_SP, d * 8);
+ M_LST(s1, REG_SP, d);
}
#else
if (!md->params[s3].inmemory) {
else {
if (IS_2_WORD_TYPE(var->type)) {
s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
- M_LST(s1, REG_SP, d * 8);
+ M_LST(s1, REG_SP, d);
}
else {
s1 = emit_load(jd, iptr, var, REG_ITMP1);
- M_IST(s1, REG_SP, d * 8);
+ M_IST(s1, REG_SP, d);
}
}
#endif
}
else {
if (!md->params[s3].inmemory) {
-#if SIZEOF_VOID_P == 8
s1 = emit_load(jd, iptr, var, d);
if (IS_2_WORD_TYPE(var->type))
- M_DMOV(s1, d);
+ M_DBLMOVE(s1, d);
else
- M_FMOV(s1, d);
-#else
- if ((s3 == 0) ||
- ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
- s1 = emit_load(jd, iptr, var, d);
- if (IS_2_WORD_TYPE(var->type))
- M_DBLMOVE(s1, d);
- else
- M_FLTMOVE(s1, d);
- }
- else {
- if (IS_2_WORD_TYPE(var->type)) {
- s1 = emit_load(jd, iptr, var, REG_FTMP1);
- M_MFC1(GET_LOW_REG(d), s1);
- M_MFC1(GET_HIGH_REG(d), s1 + 1);
- M_NOP;
- }
- else {
- s1 = emit_load(jd, iptr, var, d);
- M_MFC1(d, s1);
- M_NOP;
- }
- }
-#endif
+ M_FLTMOVE(s1, d);
}
else {
s1 = emit_load(jd, iptr, var, REG_FTMP1);
if (IS_2_WORD_TYPE(var->type))
- M_DST(s1, REG_SP, d * 8);
+ M_DST(s1, REG_SP, d);
else
- M_FST(s1, REG_SP, d * 8);
+ M_FST(s1, REG_SP, d);
}
}
}
switch (iptr->opc) {
case ICMD_BUILTIN:
- disp = dseg_add_functionptr(cd, bte->fp);
+ if (bte->stub == NULL) {
+ disp = dseg_add_functionptr(cd, bte->fp);
+ M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
- M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
+ /* generate the actual call */
- /* generate the actual call */
+ /* TWISTI: i actually don't know the reason for using
+ REG_ITMP3 here instead of REG_PV. */
+
+ M_JSR(REG_RA, REG_ITMP3);
+ M_NOP;
+ }
+ else {
+ disp = dseg_add_functionptr(cd, bte->stub);
+ M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
- /* TWISTI: i actually don't know the reason for using
- REG_ITMP3 here instead of REG_PV. */
+ /* generate the actual call */
+
+ M_JSR(REG_RA, REG_PV);
+ M_NOP;
+ }
- M_JSR(REG_RA, REG_ITMP3);
- M_NOP;
REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
disp = (s4) (cd->mcodeptr - cd->mcodebase);
M_LDA(REG_PV, REG_RA, -disp);
-
- emit_exception_check(cd, iptr);
break;
case ICMD_INVOKESPECIAL:
if (lm == NULL) {
disp = dseg_add_unique_address(cd, um);
- codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
+ patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
disp);
}
else
emit_nullpointer_check(cd, iptr, REG_A0);
if (lm == NULL) {
- codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
+ patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
s1 = 0;
}
sizeof(methodptr) * lm->vftblindex;
/* implicit null-pointer check */
- M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
M_ALD(REG_PV, REG_METHODPTR, s1);
/* generate the actual call */
emit_nullpointer_check(cd, iptr, REG_A0);
if (lm == NULL) {
- codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
+ patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
s1 = 0;
s2 = 0;
}
else {
s1 = OFFSET(vftbl_t, interfacetable[0]) -
- sizeof(methodptr*) * lm->class->index;
+ sizeof(methodptr*) * lm->clazz->index;
- s2 = sizeof(methodptr) * (lm - lm->class->methods);
+ s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
}
/* implicit null-pointer check */
- M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
M_ALD(REG_PV, REG_METHODPTR, s2);
case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
- /* val.a: (classinfo*) superclass */
-
- /* superclass is an interface:
- *
- * OK if ((sub == NULL) ||
- * (sub->vftbl->interfacetablelength > super->index) &&
- * (sub->vftbl->interfacetable[-super->index] != NULL));
- *
- * superclass is a class:
- *
- * OK if ((sub == NULL) || (0
- * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
- * super->vftbl->diffvall));
- */
if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
classinfo *super;
superindex = 0;
}
else {
- super = iptr->sx.s23.s3.c.cls;
+ super = iptr->sx.s23.s3.c.cls;
superindex = super->index;
}
-#if defined(ENABLE_THREADS)
- codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
-
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
/* if class is not resolved, check which code to call */
cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_s4(cd, 0); /* super->flags */
- codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
cr, disp);
M_ILD(REG_ITMP2, REG_PV, disp);
if (super == NULL) {
cr = iptr->sx.s23.s3.c.ref;
- codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
+ patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
cr, 0);
}
else {
emit_label_beqz(cd, BRANCH_LABEL_3, s1);
}
- M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
M_ILD(REG_ITMP3, REG_ITMP2,
OFFSET(vftbl_t, interfacetablelength));
M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_address(cd, NULL);
- codegen_add_patch_ref(cd,
- PATCHER_checkcast_instanceof_class,
+ patcher_add_patch_ref(jd,
+ PATCHER_resolve_classref_to_vftbl,
cr, disp);
}
else {
emit_label_beqz(cd, BRANCH_LABEL_5, s1);
}
- M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
M_ALD(REG_ITMP3, REG_PV, disp);
-#if defined(ENABLE_THREADS)
- codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
/* if (s1 != REG_ITMP1) { */
/* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
M_ALD(REG_ITMP3, REG_PV, disp);
M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
-#if defined(ENABLE_THREADS)
- codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
/* } */
M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_address(cd, NULL);
- codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
+ patcher_add_patch_ref(jd,
+ PATCHER_resolve_classref_to_classinfo,
cr, disp);
}
- else
+ else {
disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
+ }
M_ALD(REG_A1, REG_PV, disp);
disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
break;
case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
- /* val.a: (classinfo*) superclass */
-
- /* superclass is an interface:
- *
- * return (sub != NULL) &&
- * (sub->vftbl->interfacetablelength > super->index) &&
- * (sub->vftbl->interfacetable[-super->index] != NULL);
- *
- * superclass is a class:
- *
- * return ((sub != NULL) && (0
- * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
- * super->vftbl->diffvall));
- */
{
classinfo *super;
superindex = super->index;
}
-#if defined(ENABLE_THREADS)
- codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
-
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_s4(cd, 0); /* super->flags */
- codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
cr, disp);
M_ILD(REG_ITMP3, REG_PV, disp);
if (super == NULL) {
cr = iptr->sx.s23.s3.c.ref;
- codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
+ patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
cr, 0);
}
else {
emit_label_beqz(cd, BRANCH_LABEL_3, s1);
}
- M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
M_ILD(REG_ITMP3, REG_ITMP1,
OFFSET(vftbl_t, interfacetablelength));
M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_address(cd, NULL);
- codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
cr, disp);
}
else {
emit_label_beqz(cd, BRANCH_LABEL_5, s1);
}
- M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
M_ALD(REG_ITMP2, REG_PV, disp);
-#if defined(ENABLE_THREADS)
- codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
-#if defined(ENABLE_THREADS)
- codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
M_CMPULT(REG_ITMP2, REG_ITMP1, d);
M_XOR_IMM(d, 1, d);
cr = iptr->sx.s23.s3.c.ref;
disp = dseg_add_unique_address(cd, NULL);
- codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
cr, disp);
}
- else
+ else {
disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
+ }
/* a1 = arraydescriptor */
} /* if (bptr -> flags >= BBREACHED) */
} /* for basic block */
- dseg_createlinenumbertable(cd);
+ /* generate traps */
- /* generate stubs */
-
- emit_patcher_stubs(jd);
- REPLACEMENT_EMIT_STUBS(jd);
+ emit_patcher_traps(jd);
/* everything's ok */
}
-/* codegen_emit_stub_compiler **************************************************
-
- Emits a stub routine which calls the compiler.
-
-*******************************************************************************/
-
-void codegen_emit_stub_compiler(jitdata *jd)
-{
- methodinfo *m;
- codegendata *cd;
-
- /* get required compiler data */
-
- m = jd->m;
- cd = jd->cd;
-
- /* code for the stub */
-
- M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
- M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
- M_JMP(REG_PV);
- M_NOP;
-}
-
-
/* codegen_emit_stub_native ****************************************************
Emits a stub routine which calls a native method.
*******************************************************************************/
-void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
+void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
{
methodinfo *m;
codeinfo *code;
codegendata *cd;
methoddesc *md;
- s4 nativeparams;
s4 i, j;
s4 t;
- s4 s1, s2, disp;
- s4 funcdisp; /* displacement of the function */
+ int s1, s2;
+ int disp;
/* get required compiler data */
/* initialize variables */
md = m->parseddesc;
- nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
/* calculate stack frame size */
cd->stackframesize =
1 + /* return address */
- sizeof(stackframeinfo) / SIZEOF_VOID_P +
+ sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
sizeof(localref_table) / SIZEOF_VOID_P +
md->paramcount + /* for saving arguments over calls */
#if SIZEOF_VOID_P == 4
(void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
(void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
- (void) dseg_add_unique_s4(cd, 0); /* IsSync */
(void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
(void) dseg_add_unique_s4(cd, 0); /* IntSave */
(void) dseg_add_unique_s4(cd, 0); /* FltSave */
- (void) dseg_addlinenumbertablesize(cd);
- (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
/* generate stub code */
emit_verbosecall_enter(jd);
#endif
- /* get function address (this must happen before the stackframeinfo) */
-
- funcdisp = dseg_add_functionptr(cd, f);
-
-#if !defined(WITH_STATIC_CLASSPATH)
- if (f == NULL)
- codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
-#endif
-
/* save integer and float argument registers */
#if SIZEOF_VOID_P == 8
/* prepare data structures for native function call */
- M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
+ M_MOV(REG_SP, REG_A0);
M_MOV(REG_PV, REG_A1);
- M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
- M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
disp = dseg_add_functionptr(cd, codegen_start_native_call);
M_ALD(REG_ITMP3, REG_PV, disp);
M_JSR(REG_RA, REG_ITMP3);
M_NOP; /* XXX fill me! */
+ /* remember class argument */
+
+ if (m->flags & ACC_STATIC)
+ M_MOV(REG_RESULT, REG_ITMP3);
+
/* restore integer and float argument registers */
#if SIZEOF_VOID_P == 8
/* copy or spill arguments to new locations */
- for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
+ for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
t = md->params[i].type;
if (IS_INT_LNG_TYPE(t)) {
}
else {
#if SIZEOF_VOID_P == 8
- M_LST(s1, REG_SP, s2 * 8);
+ M_LST(s1, REG_SP, s2);
#else
if (IS_2_WORD_TYPE(t))
- M_LST(s1, REG_SP, s2 * 4);
+ M_LST(s1, REG_SP, s2);
else
- M_IST(s1, REG_SP, s2 * 4);
+ M_IST(s1, REG_SP, s2);
#endif
}
}
else {
- s1 = md->params[i].regoff + cd->stackframesize;
+ s1 = md->params[i].regoff + cd->stackframesize * 8;
s2 = nmd->params[j].regoff;
#if SIZEOF_VOID_P == 8
- M_LLD(REG_ITMP1, REG_SP, s1 * 8);
- M_LST(REG_ITMP1, REG_SP, s2 * 8);
+ M_LLD(REG_ITMP1, REG_SP, s1);
+ M_LST(REG_ITMP1, REG_SP, s2);
#else
if (IS_2_WORD_TYPE(t)) {
- M_LLD(REG_ITMP12_PACKED, REG_SP, s1 * 8);
- M_LST(REG_ITMP12_PACKED, REG_SP, s2 * 4);
+ M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
+ M_LST(REG_ITMP12_PACKED, REG_SP, s2);
}
else {
- M_ILD(REG_ITMP1, REG_SP, s1 * 8);
- M_IST(REG_ITMP1, REG_SP, s2 * 4);
+ M_ILD(REG_ITMP1, REG_SP, s1);
+ M_IST(REG_ITMP1, REG_SP, s2);
}
#endif
}
/* On MIPS32 float arguments for native functions
can never be in float argument registers, since
the first argument is _always_ an integer
- argument (JNIenv) */
+ argument (JNIEnv) */
if (IS_2_WORD_TYPE(t)) {
/* double high/low order is endian
else {
#if SIZEOF_VOID_P == 8
if (IS_2_WORD_TYPE(t))
- M_DST(s1, REG_SP, s2 * 8);
+ M_DST(s1, REG_SP, s2);
else
- M_FST(s1, REG_SP, s2 * 8);
+ M_FST(s1, REG_SP, s2);
#else
/* s1 may have been originally in 2 int registers,
but was moved out by the native function
argument(s), just get low register */
if (IS_2_WORD_TYPE(t))
- M_DST(GET_LOW_REG(s1), REG_SP, s2 * 4);
+ M_DST(GET_LOW_REG(s1), REG_SP, s2);
else
- M_FST(GET_LOW_REG(s1), REG_SP, s2 * 4);
+ M_FST(GET_LOW_REG(s1), REG_SP, s2);
#endif
}
}
else {
- s1 = md->params[i].regoff + cd->stackframesize;
+ s1 = md->params[i].regoff + cd->stackframesize * 8;
s2 = nmd->params[j].regoff;
+#if SIZEOF_VOID_P == 8
+ if (IS_2_WORD_TYPE(t)) {
+ M_DLD(REG_FTMP1, REG_SP, s1);
+ M_DST(REG_FTMP1, REG_SP, s2);
+ }
+ else {
+ M_FLD(REG_FTMP1, REG_SP, s1);
+ M_FST(REG_FTMP1, REG_SP, s2);
+ }
+#else
if (IS_2_WORD_TYPE(t)) {
- M_DLD(REG_FTMP1, REG_SP, s1 * 8);
- M_DST(REG_FTMP1, REG_SP, s2 * 8);
+ M_DLD(REG_FTMP1, REG_SP, s1);
+ M_DST(REG_FTMP1, REG_SP, s2);
}
else {
- M_FLD(REG_FTMP1, REG_SP, s1 * 8);
- M_FST(REG_FTMP1, REG_SP, s2 * 8);
+ M_FLD(REG_FTMP1, REG_SP, s1);
+ M_FST(REG_FTMP1, REG_SP, s2);
}
+#endif
}
}
}
- /* put class into second argument register */
+ /* Handle native Java methods. */
- if (m->flags & ACC_STATIC) {
- disp = dseg_add_address(cd, m->class);
- M_ALD(REG_A1, REG_PV, disp);
- }
+ if (m->flags & ACC_NATIVE) {
+ /* put class into second argument register */
- /* put env into first argument register */
+ if (m->flags & ACC_STATIC)
+ M_MOV(REG_ITMP3, REG_A1);
- disp = dseg_add_address(cd, _Jv_env);
- M_ALD(REG_A0, REG_PV, disp);
+ /* put env into first argument register */
- /* do the native function call */
+ disp = dseg_add_address(cd, _Jv_env);
+ M_ALD(REG_A0, REG_PV, disp);
+ }
+
+ /* Call the native function. */
- M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
+ disp = dseg_add_functionptr(cd, f);
+ M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
M_JSR(REG_RA, REG_ITMP3); /* call native method */
M_NOP; /* delay slot */
#else
case TYPE_INT:
case TYPE_ADR:
- M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
+ M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
break;
case TYPE_LNG:
- M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
+ M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
break;
case TYPE_FLT:
case TYPE_DBL:
- M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
+ M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
break;
#endif
case TYPE_VOID:
/* remove native stackframe info */
- M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
+ M_MOV(REG_SP, REG_A0);
+ M_MOV(REG_PV, REG_A1);
disp = dseg_add_functionptr(cd, codegen_finish_native_call);
M_ALD(REG_ITMP3, REG_PV, disp);
M_JSR(REG_RA, REG_ITMP3);
#else
case TYPE_INT:
case TYPE_ADR:
- M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
+ M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
break;
case TYPE_LNG:
- M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
+ M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
break;
case TYPE_FLT:
case TYPE_DBL:
- M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
+ M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
break;
#endif
case TYPE_VOID:
M_JMP(REG_ITMP3); /* jump to asm exception handler */
M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
- /* generate patcher stubs */
+ /* Generate patcher traps. */
- emit_patcher_stubs(jd);
+ emit_patcher_traps(jd);
}