/* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
- 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.
#include "vm/jit/alpha/arch.h"
#include "vm/jit/alpha/codegen.h"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
-#include "native/jni.h"
-#include "native/localref.h"
-#include "native/native.h"
+#include "native/localref.hpp"
+#include "native/native.hpp"
-#include "threads/lock-common.h"
+#include "threads/lock.hpp"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
#include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/loader.hpp"
+#include "vm/options.h"
+#include "vm/vm.hpp"
#include "vm/jit/abi.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
+#include "vm/jit/codegen-common.hpp"
#include "vm/jit/dseg.h"
-#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/linenumbertable.h"
-#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/emit-common.hpp"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/linenumbertable.hpp"
+#include "vm/jit/parse.hpp"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
-
-#if defined(ENABLE_LSRA)
+#include "vm/jit/replace.hpp"
+#include "vm/jit/stacktrace.hpp"
+#include "vm/jit/trap.h"
+
+#if defined(ENABLE_SSA)
+# include "vm/jit/optimizing/lsra.h"
+# include "vm/jit/optimizing/ssa.h"
+#elif defined(ENABLE_LSRA)
# include "vm/jit/allocator/lsra.h"
#endif
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
/* codegen_emit ****************************************************************
/* decide which monitor enter function to call */
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);
}
else {
M_BNEZ(REG_A0, 1);
- M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+ M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
}
M_AST(REG_A0, REG_SP, s1 * 8);
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_FADD(s1, s2, d);
+ if (d == s1 || d == s2) {
+ M_FADDS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FMOV(REG_FTMP3, d);
} else {
- if (d == s1 || d == s2) {
- M_FADDS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FMOV(REG_FTMP3, d);
- } else {
- M_FADDS(s1, s2, d);
- M_TRAPB;
- }
+ M_FADDS(s1, s2, d);
+ M_TRAPB;
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_DADD(s1, s2, d);
+ if (d == s1 || d == s2) {
+ M_DADDS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FMOV(REG_FTMP3, d);
} else {
- if (d == s1 || d == s2) {
- M_DADDS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FMOV(REG_FTMP3, d);
- } else {
- M_DADDS(s1, s2, d);
- M_TRAPB;
- }
+ M_DADDS(s1, s2, d);
+ M_TRAPB;
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_FSUB(s1, s2, d);
+ if (d == s1 || d == s2) {
+ M_FSUBS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FMOV(REG_FTMP3, d);
} else {
- if (d == s1 || d == s2) {
- M_FSUBS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FMOV(REG_FTMP3, d);
- } else {
- M_FSUBS(s1, s2, d);
- M_TRAPB;
- }
+ M_FSUBS(s1, s2, d);
+ M_TRAPB;
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_DSUB(s1, s2, d);
+ if (d == s1 || d == s2) {
+ M_DSUBS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FMOV(REG_FTMP3, d);
} else {
- if (d == s1 || d == s2) {
- M_DSUBS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FMOV(REG_FTMP3, d);
- } else {
- M_DSUBS(s1, s2, d);
- M_TRAPB;
- }
+ M_DSUBS(s1, s2, d);
+ M_TRAPB;
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_FMUL(s1, s2, d);
+ if (d == s1 || d == s2) {
+ M_FMULS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FMOV(REG_FTMP3, d);
} else {
- if (d == s1 || d == s2) {
- M_FMULS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FMOV(REG_FTMP3, d);
- } else {
- M_FMULS(s1, s2, d);
- M_TRAPB;
- }
+ M_FMULS(s1, s2, d);
+ M_TRAPB;
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_DMUL(s1, s2, d);
+ if (d == s1 || d == s2) {
+ M_DMULS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FMOV(REG_FTMP3, d);
} else {
- if (d == s1 || d == s2) {
- M_DMULS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FMOV(REG_FTMP3, d);
- } else {
- M_DMULS(s1, s2, d);
- M_TRAPB;
- }
+ M_DMULS(s1, s2, d);
+ M_TRAPB;
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_FDIV(s1, s2, d);
+ if (d == s1 || d == s2) {
+ M_FDIVS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FMOV(REG_FTMP3, d);
} else {
- if (d == s1 || d == s2) {
- M_FDIVS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FMOV(REG_FTMP3, d);
- } else {
- M_FDIVS(s1, s2, d);
- M_TRAPB;
- }
+ M_FDIVS(s1, s2, d);
+ M_TRAPB;
}
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_DDIV(s1, s2, d);
+ if (d == s1 || d == s2) {
+ M_DDIVS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FMOV(REG_FTMP3, d);
} else {
- if (d == s1 || d == s2) {
- M_DDIVS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FMOV(REG_FTMP3, d);
- } else {
- M_DDIVS(s1, s2, d);
- M_TRAPB;
- }
+ M_DDIVS(s1, s2, d);
+ M_TRAPB;
}
emit_store_dst(jd, iptr, d);
break;
case ICMD_L2F:
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- disp = dseg_add_unique_double(cd, 0.0);
+ disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
M_LST(s1, REG_PV, disp);
M_DLD(d, REG_PV, disp);
M_CVTLF(d, d);
case ICMD_L2D:
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- disp = dseg_add_unique_double(cd, 0.0);
+ disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
M_LST(s1, REG_PV, disp);
M_DLD(d, REG_PV, disp);
M_CVTLD(d, d);
case ICMD_D2I:
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
- disp = dseg_add_unique_double(cd, 0.0);
+ disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
M_CVTDL_C(s1, REG_FTMP2);
M_CVTLI(REG_FTMP2, REG_FTMP3);
M_DST(REG_FTMP3, REG_PV, disp);
case ICMD_D2L:
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
- disp = dseg_add_unique_double(cd, 0.0);
+ disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
M_CVTDL_C(s1, REG_FTMP2);
M_DST(REG_FTMP2, REG_PV, disp);
M_LLD(d, REG_PV, disp);
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
- if (opt_noieee) {
- M_CVTDF(s1, d);
- } else {
- M_CVTDFS(s1, d);
- M_TRAPB;
- }
+ M_CVTDFS(s1, d);
+ M_TRAPB;
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
- if (opt_noieee) {
- M_LSUB_IMM(REG_ZERO, 1, d);
- M_FCMPEQ(s1, s2, REG_FTMP3);
- M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
- M_CLR (d);
- M_FCMPLT(s2, s1, REG_FTMP3);
- M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
- M_LADD_IMM(REG_ZERO, 1, d);
- } else {
- M_LSUB_IMM(REG_ZERO, 1, d);
- M_FCMPEQS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
- M_CLR (d);
- M_FCMPLTS(s2, s1, REG_FTMP3);
- M_TRAPB;
- M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
- M_LADD_IMM(REG_ZERO, 1, d);
- }
+ M_LSUB_IMM(REG_ZERO, 1, d);
+ M_FCMPEQS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
+ M_CLR (d);
+ M_FCMPLTS(s2, s1, REG_FTMP3);
+ M_TRAPB;
+ M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
+ M_LADD_IMM(REG_ZERO, 1, d);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
- if (opt_noieee) {
- M_LADD_IMM(REG_ZERO, 1, d);
- M_FCMPEQ(s1, s2, REG_FTMP3);
- M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
- M_CLR (d);
- M_FCMPLT(s1, s2, REG_FTMP3);
- M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
- M_LSUB_IMM(REG_ZERO, 1, d);
- } else {
- M_LADD_IMM(REG_ZERO, 1, d);
- M_FCMPEQS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
- M_CLR (d);
- M_FCMPLTS(s1, s2, REG_FTMP3);
- M_TRAPB;
- M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
- M_LSUB_IMM(REG_ZERO, 1, d);
- }
+ M_LADD_IMM(REG_ZERO, 1, d);
+ M_FCMPEQS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
+ M_CLR (d);
+ M_FCMPLTS(s1, s2, REG_FTMP3);
+ M_TRAPB;
+ M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
+ M_LSUB_IMM(REG_ZERO, 1, d);
emit_store_dst(jd, iptr, d);
break;
fieldtype = fi->type;
disp = dseg_add_address(cd, fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
- patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+ patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
0);
}
fieldtype = fi->type;
disp = dseg_add_address(cd, fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
- patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+ patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
0);
}
fieldtype = fi->type;
disp = dseg_add_address(cd, fi->value);
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
- patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+ patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
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 */
superindex = super->index;
}
- if ((super == NULL) || !(super->flags & ACC_INTERFACE))
- CODEGEN_CRITICAL_SECTION_NEW;
-
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
/* if class is not resolved, check which code to call */
M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
M_ALD(REG_ITMP3, REG_PV, disp);
- CODEGEN_CRITICAL_SECTION_START;
-
- 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_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
- /* #if defined(ENABLE_THREADS) */
- /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
- /* #endif */
- /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
-
- /* } else { */
- M_ILD(REG_ITMP3, 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));
-
- CODEGEN_CRITICAL_SECTION_END;
-
- /* } */
- M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
- emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
+ if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
+ M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
+ M_ALD(REG_ITMP1, REG_ITMP1, 0);
+ M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
+ emit_label_bnez(cd, BRANCH_LABEL_6, REG_ITMP1); /* good */
+
+ if (super == NULL) {
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
+ M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
+ emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* throw */
+ }
+
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
+ M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
+ M_CMPLE(REG_ITMP1, REG_ITMP3, REG_ITMP3);
+ emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* throw */
+ /* reload */
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
+ M_S8ADDQ(REG_ITMP1, REG_ITMP2, REG_ITMP2);
+ M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
+ M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
+ emit_label_bnez(cd, BRANCH_LABEL_7, REG_ITMP1); /* good */
+
+ emit_label(cd, BRANCH_LABEL_9);
+ if (super == NULL)
+ emit_label(cd, BRANCH_LABEL_10);
+
+ /* reload s1, might have been destroyed */
+ emit_load_s1(jd, iptr, REG_ITMP1);
+ M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
+
+ emit_label(cd, BRANCH_LABEL_7);
+ emit_label(cd, BRANCH_LABEL_6);
+ /* reload s1, might have been destroyed */
+ emit_load_s1(jd, iptr, REG_ITMP1);
+ }
+ else {
+ M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
+ M_CMPEQ(REG_ITMP2, REG_ITMP3, REG_ITMP2);
+ emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP2, s1);
+ }
if (super != NULL)
emit_label(cd, BRANCH_LABEL_5);
supervftbl = super->vftbl;
}
- if ((super == NULL) || !(super->flags & ACC_INTERFACE))
- CODEGEN_CRITICAL_SECTION_NEW;
-
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
emit_label_beqz(cd, BRANCH_LABEL_5, s1);
}
- M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
- M_ALD(REG_ITMP2, REG_PV, disp);
+ M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
+ M_ALD(REG_ITMP3, REG_PV, disp);
+
+ if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
+ M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
+ M_ALD(REG_ITMP1, REG_ITMP1, 0);
+ M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
+ emit_label_beqz(cd, BRANCH_LABEL_8, REG_ITMP1);
+ ICONST(d, 1);
+ emit_label_br(cd, BRANCH_LABEL_6); /* true */
+ emit_label(cd, BRANCH_LABEL_8);
+
+ if (super == NULL) {
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
+ M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
+ emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* false */
+ }
- CODEGEN_CRITICAL_SECTION_START;
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
- 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));
+ M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
+ M_CMPLE(REG_ITMP1, REG_ITMP3, REG_ITMP3);
+ emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* false */
+ /* reload */
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
+ M_S8ADDQ(REG_ITMP1, REG_ITMP2, REG_ITMP2);
+ M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
+ M_CMPEQ(REG_ITMP1, REG_ITMP3, d);
- CODEGEN_CRITICAL_SECTION_END;
+ if (d == REG_ITMP2)
+ emit_label_br(cd, BRANCH_LABEL_7);
+ emit_label(cd, BRANCH_LABEL_9);
+ if (super == NULL)
+ emit_label(cd, BRANCH_LABEL_10);
+ if (d == REG_ITMP2) {
+ M_CLR(d);
- M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
- M_CMPULE(REG_ITMP1, REG_ITMP2, d);
+ emit_label(cd, BRANCH_LABEL_7);
+ }
+ emit_label(cd, BRANCH_LABEL_6);
+ }
+ else {
+ M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
+ M_CMPEQ(REG_ITMP2, REG_ITMP3, d);
+ }
if (super != NULL)
emit_label(cd, BRANCH_LABEL_5);
/* put env into first argument register */
- disp = dseg_add_address(cd, _Jv_env);
+ disp = dseg_add_address(cd, VM_get_jnienv());
M_ALD(REG_A0, REG_PV, disp);
}