#include "mm/memory.h"
-#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"
+#include "vm/jit/replace.hpp"
+#include "vm/jit/stacktrace.hpp"
#include "vm/jit/trap.h"
#if defined(ENABLE_SSA)
# include "vm/jit/allocator/lsra.h"
#endif
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
/* codegen_emit ****************************************************************
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;
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;
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);
}