-/* src/vm/jit/powerpc64/codegen.c - machine code generator for 32-bit PowerPC
+/* src/vm/jit/powerpc64/codegen.c - machine code generator for 64-bit PowerPC
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ 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
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Andreas Krall
- Stefan Ring
-
- Changes: Christian Thalinger
- Christian Ullrich
- Edwin Steiner
- Roland Lezuo
-
- $Id: codegen.c 5928 2006-11-06 16:38:31Z tbfg $
+ $Id: codegen.c 7582 2007-03-26 09:27:10Z tbfg $
*/
#include "vm/types.h"
#include "md-abi.h"
-#include "vm/jit/abi-asm.h"
#include "vm/jit/powerpc64/arch.h"
#include "vm/jit/powerpc64/codegen.h"
#include "mm/memory.h"
+
#include "native/native.h"
+
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
#include "vm/stringlocal.h"
#include "vm/vm.h"
+
+#include "vm/jit/abi-asm.h"
+#include "vm/jit/md.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/patcher.h"
#include "vm/jit/reg.h"
#include "vm/jit/replace.h"
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
#if defined(ENABLE_LSRA)
# include "vm/jit/allocator/lsra.h"
#endif
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
-/* codegen *********************************************************************
+
+/* codegen_emit ****************************************************************
Generates machine code.
*******************************************************************************/
-bool codegen(jitdata *jd)
+bool codegen_emit(jitdata *jd)
{
methodinfo *m;
codeinfo *code;
exception_entry *ex;
u2 currentline;
methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
+ unresolved_method *um;
builtintable_entry *bte;
methoddesc *md;
- rplpoint *replacementpoint;
s4 fieldtype;
s4 varindex;
unresolved_field *uf;
/* else if (m->isleafmethod && (stackframesize == LA_WORD_SIZE)) */
/* stackframesize = 0; */
- (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
+ (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
*/
if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
+ (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
else
#endif
- (void) dseg_adds4(cd, 0); /* IsSync */
+ (void) dseg_add_unique_s4(cd, 0); /* IsSync */
- (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
- (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
- (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
+ (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
+ (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_adds4(cd, jd->exceptiontablelength); /* ExTableSize */
+ (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
/* create exception table */
for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
- dseg_addtarget(cd, ex->start);
- dseg_addtarget(cd, ex->end);
- dseg_addtarget(cd, ex->handler);
- (void) dseg_addaddress(cd, ex->catchtype.any);
+ 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) */
} else { /* stack arguments */
if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
- M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ if (IS_2_WORD_TYPE(t)) {
+ M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ } else {
+ M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ }
} else { /* stack-arg -> spilled */
var->vv.regoff = cd->stackframesize + s1;
}
s1 += (LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS + ARG_CNT);
}
#endif
- p = dseg_addaddress(cd, LOCK_monitor_enter);
+ p = dseg_add_functionptr(cd, LOCK_monitor_enter);
M_ALD(REG_ITMP3, REG_PV, p);
M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(REG_ITMP3);
/* get or test the lock object */
if (m->flags & ACC_STATIC) {
- p = dseg_addaddress(cd, &m->class->object.header);
+ p = dseg_add_address(cd, &m->class->object.header);
M_ALD(rd->argintregs[0], REG_PV, p);
}
else {
M_TST(rd->argintregs[0]);
- M_BEQ(0);
- codegen_add_nullpointerexception_ref(cd);
+ M_BNE(1);
+ M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
}
M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* rd->memuse * 8 */
/* end of header generation */
- replacementpoint = jd->code->rplpoints;
+ /* create replacement points */
+
+ REPLACEMENT_POINTS_INIT(cd, jd);
/* walk through all basic blocks */
+
for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
if (bptr->flags >= BBREACHED) {
/* branch resolving */
-
- {
- branchref *brefs;
- for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
- gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
- brefs->branchpos,
- bptr->mpc);
- }
- }
+ codegen_resolve_branchrefs(cd, bptr);
/* handle replacement points */
-#if 0
- if (bptr->bitflags & BBFLAG_REPLACEMENT) {
- replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
-
- replacementpoint++;
- }
-#endif
+ REPLACEMENT_POINT_BLOCK_START(cd, bptr);
/* copy interface registers to their destination */
MCODECHECK(64); /* an instruction usually needs < 64 words */
- switch (iptr->opc) {
- case ICMD_NOP: /* ... ==> ... */
- case ICMD_INLINE_START:
- case ICMD_INLINE_END:
- break;
+ switch (iptr->opc) {
+ case ICMD_NOP: /* ... ==> ... */
+ case ICMD_POP: /* ..., value ==> ... */
+ case ICMD_POP2: /* ..., value, value ==> ... */
+ break;
+
+ case ICMD_INLINE_START:
+
+ REPLACEMENT_POINT_INLINE_START(cd, iptr);
+ break;
+
+ case ICMD_INLINE_BODY:
+
+ REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
+ dseg_addlinenumber_inline_start(cd, iptr);
+ dseg_addlinenumber(cd, iptr->line);
+ break;
+
+ case ICMD_INLINE_END:
+
+ dseg_addlinenumber_inline_end(cd, iptr);
+ dseg_addlinenumber(cd, iptr->line);
+ break;
case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_TST(s1);
M_BEQ(0);
- codegen_add_nullpointerexception_ref(cd);
+ emit_nullpointer_check(cd, iptr, s1);
break;
/* constant operations ************************************************/
case ICMD_FCONST: /* ... ==> ..., constant */
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- a = dseg_addfloat(cd, iptr->sx.val.f);
+ a = dseg_add_float(cd, iptr->sx.val.f);
M_FLD(d, REG_PV, a);
emit_store_dst(jd, iptr, d);
break;
case ICMD_DCONST: /* ... ==> ..., constant */
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- a = dseg_adddouble(cd, iptr->sx.val.d);
+ a = dseg_add_double(cd, iptr->sx.val.d);
M_DLD(d, REG_PV, a);
emit_store_dst(jd, iptr, d);
break;
case ICMD_ACONST: /* ... ==> ..., constant */
+
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+ disp = dseg_add_unique_address(cd, iptr->sx.val.c.ref);
codegen_addpatchref(cd, PATCHER_aconst,
iptr->sx.val.c.ref,
disp);
-
- if (opt_showdisassemble)
- M_NOP;
+ } else {
+ disp = dseg_add_address(cd, iptr->sx.val.anyptr);
}
-
M_ALD(d, REG_PV, disp);
emit_store_dst(jd, iptr, d);
break;
case ICMD_FLOAD: /* ... ==> ..., content of local variable */
case ICMD_DLOAD: /* ... ==> ..., content of local variable */
case ICMD_ISTORE: /* ..., value ==> ... */
- case ICMD_ASTORE: /* dst.localindex = local variable */
case ICMD_LSTORE:
case ICMD_FSTORE: /* ..., value ==> ... */
case ICMD_DSTORE: /* ..., value ==> ... */
emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
break;
-
- /* pop operations *****************************************************/
-
- /* attention: double and longs are only one entry in CACAO ICMDs */
-
- case ICMD_POP: /* ..., value ==> ... */
- case ICMD_POP2: /* ..., value, value ==> ... */
-
+ case ICMD_ASTORE:
+ if (!(iptr->flags.bits & INS_FLAG_RETADDR))
+ emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
- M_TST(s2);
- M_BEQ(0);
- codegen_add_arithmeticexception_ref(cd);
+ emit_arithmetic_check(cd, iptr, s2);
M_DIV(s1, s2, d);
/* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_TST(s2);
- M_BEQ(0);
- codegen_add_arithmeticexception_ref(cd);
+ emit_arithmetic_check(cd, iptr, s2);
M_DIV(s1, s2, REG_ITMP3);
/* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
/* XXX implement me!!! */
+ vm_abort("codegen: implement ICMD_LCMP!");
emit_store_dst(jd, iptr, d);
break;
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_CLR(d);
- disp = dseg_addfloat(cd, 0.0);
+ disp = dseg_add_float(cd, 0.0);
M_FLD(REG_FTMP2, REG_PV, disp);
M_FCMPU(s1, REG_FTMP2);
M_BNAN(4);
- disp = dseg_adds4(cd, 0);
+ disp = dseg_add_unique_s4(cd, 0);
M_CVTDL_C(s1, REG_FTMP1);
M_LDA(REG_ITMP1, REG_PV, disp);
M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
M_BNAN(1);
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_beq(cd, iptr->dst.block);
break;
case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
- M_BNAN(0);
- codegen_addreference(cd, iptr->dst.block);
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bnan(cd, iptr->dst.block);
+ emit_bne(cd, iptr->dst.block);
break;
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
- M_BNAN(0);
- codegen_addreference(cd, iptr->dst.block);
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bnan(cd, iptr->dst.block);
+ emit_blt(cd, iptr->dst.block);
break;
case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
M_BNAN(1);
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bgt(cd, iptr->dst.block);
break;
case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
- M_BNAN(0);
- codegen_addreference(cd, iptr->dst.block);
- M_BLE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bnan(cd, iptr->dst.block);
+ emit_ble(cd, iptr->dst.block);
break;
case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
M_BNAN(1);
- M_BGE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bge(cd, iptr->dst.block);
break;
case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
M_BNAN(1);
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_blt(cd, iptr->dst.block);
break;
case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
- M_BNAN(0);
- codegen_addreference(cd, iptr->dst.block);
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bnan(cd, iptr->dst.block);
+ emit_bgt(cd, iptr->dst.block);
break;
case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
M_BNAN(1);
- M_BLE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_ble(cd, iptr->dst.block);
break;
case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_FTMP1);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
M_FCMPU(s1, s2);
- M_BNAN(0);
- codegen_addreference(cd, iptr->dst.block);
- M_BGE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bnan(cd, iptr->dst.block);
+ emit_bge(cd, iptr->dst.block);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
M_ILD(d, s1, OFFSET(java_arrayheader, size));
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
- M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2);
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
+ M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_LBZX(d, s1, REG_ITMP2);
M_BSEXT(d, d);
emit_store_dst(jd, iptr, d);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_SLL_IMM(s2, 1, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
- M_LHAX(d, s1, REG_ITMP2);
+ /* implicit null-pointer check */
+ M_LHZX(d, s1, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_SLL_IMM(s2, 1, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_LHAX(d, s1, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_SLL_IMM(s2, 2, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
- M_LWZX(d, s1, REG_ITMP2);
+ /* implicit null-pointer check */
+ M_LWAX(d, s1, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, PACK_REGS(REG_ITMP2, REG_ITMP1));
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_SLL_IMM(s2, 3, REG_ITMP2);
M_IADD(s1, REG_ITMP2, REG_ITMP2);
+ /* implicit null-pointer check */
M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_SLL_IMM(s2, 2, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_LFSX(d, s1, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_SLL_IMM(s2, 3, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_LFDX(d, s1, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
M_SLL_IMM(s2, 3, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_ALDX(d, s1, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_STBX(s3, s1, REG_ITMP2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_SLL_IMM(s2, 1, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_STHX(s3, s1, REG_ITMP2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_SLL_IMM(s2, 1, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_SLL_IMM(s2, 2, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_STWX(s3, s1, REG_ITMP2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_SLL_IMM(s2, 3, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_LSTX(s3, s1, REG_ITMP2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_FTMP3);
M_SLL_IMM(s2, 2, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_STFSX(s3, s1, REG_ITMP2);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_FTMP3);
M_SLL_IMM(s2, 3, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_STFDX(s3, s1, REG_ITMP2);
break;
case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
- s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
+ s1 = emit_load_s1(jd, iptr, REG_A0);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
- s3 = emit_load_s3(jd, iptr, rd->argintregs[1]);
+ emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
+ s3 = emit_load_s3(jd, iptr, REG_A1);
- disp = dseg_addaddress(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(REG_ITMP3);
- M_INTMOVE(s1, rd->argintregs[0]);
- M_INTMOVE(s3, rd->argintregs[1]);
+ M_INTMOVE(s1, REG_A0);
+ M_INTMOVE(s3, REG_A1);
M_JSR;
- M_TST(REG_RESULT);
- M_BEQ(0);
- codegen_add_arraystoreexception_ref(cd);
+ emit_exception_check(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_SLL_IMM(s2, 3, REG_ITMP2);
M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
+ /* implicit null-pointer check */
M_ASTX(s3, s1, REG_ITMP2);
break;
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
- disp = dseg_addaddress(cd, NULL);
+ disp = dseg_add_unique_address(cd, NULL);
codegen_addpatchref(cd, PATCHER_get_putstatic,
iptr->sx.s23.s3.uf, disp);
- if (opt_showdisassemble)
- M_NOP;
-
} else {
fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
- disp = dseg_addaddress(cd, &(fi->value));
+ disp = dseg_add_address(cd, &(fi->value));
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
-
- if (opt_showdisassemble)
- M_NOP;
}
}
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
- disp = dseg_addaddress(cd, NULL);
+ disp = dseg_add_unique_address(cd, NULL);
codegen_addpatchref(cd, PATCHER_get_putstatic,
iptr->sx.s23.s3.uf, disp);
-
- if (opt_showdisassemble)
- M_NOP;
-
} else {
fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
- disp = dseg_addaddress(cd, &(fi->value));
+ disp = dseg_add_address(cd, &(fi->value));
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
-
- if (opt_showdisassemble)
- M_NOP;
}
}
case ICMD_GETFIELD: /* ... ==> ..., value */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
disp = 0;
codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
-
- if (opt_showdisassemble)
- M_NOP;
-
} else {
fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
disp = fi->offset;
}
+ /* implicit null-pointer check */
switch (fieldtype) {
case TYPE_INT:
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
case ICMD_PUTFIELD: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
-
- if (opt_showdisassemble)
- M_NOP;
}
+ /* implicit null-pointer check */
switch (fieldtype) {
case TYPE_INT:
M_IST(s2, s1, disp);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
codegen_addpatchref(cd, PATCHER_athrow_areturn,
iptr->sx.s23.s2.uc, 0);
-
- if (opt_showdisassemble)
- M_NOP;
}
#endif /* ENABLE_VERIFIER */
- disp = dseg_addaddress(cd, asm_handle_exception);
+ disp = dseg_add_functionptr(cd, asm_handle_exception);
M_ALD(REG_ITMP2, REG_PV, disp);
M_MTCTR(REG_ITMP2);
case ICMD_GOTO: /* ... ==> ... */
case ICMD_RET: /* ... ==> ... */
- M_BR(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_br(cd, iptr->dst.block);
ALIGNCODENOP;
break;
case ICMD_JSR: /* ... ==> ... */
- M_BR(0);
- codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
+ emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
ALIGNCODENOP;
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_TST(s1);
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_beq(cd, iptr->dst.block);
break;
case ICMD_IFNONNULL: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_TST(s1);
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bne(cd, iptr->dst.block);
break;
case ICMD_IFLT:
ICONST(REG_ITMP2, iptr->sx.val.i);
M_CMP(s1, REG_ITMP2);
}
- switch (iptr->opc) {
- case ICMD_IFLT:
- M_BLT(0);
- break;
- case ICMD_IFLE:
- M_BLE(0);
- break;
- case ICMD_IFNE:
- M_BNE(0);
- break;
- case ICMD_IFGT:
- M_BGT(0);
- break;
- case ICMD_IFGE:
- M_BGE(0);
- break;
- case ICMD_IFEQ:
- M_BEQ(0);
- break;
- }
- codegen_addreference(cd, iptr->dst.block);
+ emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
break;
case ICMD_IF_LEQ: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMP(s1, REG_ITMP2);
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_beq(cd, iptr->dst.block);
break;
case ICMD_IF_LLT: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMP(s1, REG_ITMP2);
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_blt(cd, iptr->dst.block);
break;
case ICMD_IF_LLE: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMP(s1, REG_ITMP2);
- M_BLE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_ble(cd, iptr->dst.block);
break;
case ICMD_IF_LNE: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMP(s1, REG_ITMP2);
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bne(cd, iptr->dst.block);
break;
case ICMD_IF_LGE: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMP(s1, REG_ITMP2);
- M_BGE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bge(cd, iptr->dst.block);
break;
case ICMD_IF_LGT: /* ..., value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMP(s1, REG_ITMP2);
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bgt(cd, iptr->dst.block);
break;
case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMP(s1, s2);
- M_BEQ(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_beq(cd, iptr->dst.block);
break;
case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMP(s1, s2);
- M_BNE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bne(cd, iptr->dst.block);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMP(s1, s2);
- M_BLT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_blt(cd, iptr->dst.block);
break;
case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMP(s1, s2);
- M_BGT(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bgt(cd, iptr->dst.block);
break;
case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMP(s1, s2);
- M_BLE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_ble(cd, iptr->dst.block);
break;
case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_CMP(s1, s2);
- M_BGE(0);
- codegen_addreference(cd, iptr->dst.block);
+ emit_bge(cd, iptr->dst.block);
break;
case ICMD_LRETURN: /* ..., retvalue ==> ... */
case ICMD_IRETURN: /* ..., retvalue ==> ... */
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_RESULT);
M_LNGMOVE(s1, REG_RESULT);
goto nowperformreturn;
case ICMD_ARETURN: /* ..., retvalue ==> ... */
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_RESULT);
M_LNGMOVE(s1, REG_RESULT);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
codegen_addpatchref(cd, PATCHER_athrow_areturn,
iptr->sx.s23.s2.uc, 0);
-
- if (opt_showdisassemble)
- M_NOP;
}
#endif /* ENABLE_VERIFIER */
case ICMD_FRETURN: /* ..., retvalue ==> ... */
case ICMD_DRETURN:
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_FRESULT);
M_FLTMOVE(s1, REG_FRESULT);
goto nowperformreturn;
case ICMD_RETURN: /* ... ==> ... */
+ REPLACEMENT_POINT_RETURN(cd, iptr);
+
nowperformreturn:
{
s4 i, p;
#if defined(ENABLE_THREADS)
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
- disp = dseg_addaddress(cd, LOCK_monitor_exit);
+ disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
M_ALD(REG_ITMP3, REG_PV, disp);
M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(REG_ITMP3);
/* range check */
M_CMPUI(REG_ITMP1, i - 1);
- M_BGT(0);
- codegen_addreference(cd, table[0].block);
+ emit_bgt(cd, table[0].block);
/* build jump table top down and use address of lowest entry */
table += i;
while (--i >= 0) {
- dseg_addtarget(cd, table->block);
+ dseg_add_target(cd, table->block);
--table;
- }
}
- /* length of dataseg after last dseg_addtarget is used by load */
+ /* length of dataseg after last dseg_add_unique_target is used by load */
M_SLL_IMM(REG_ITMP1, 3, REG_ITMP1);
M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
M_MTCTR(REG_ITMP2);
M_RTS;
ALIGNCODENOP;
+ }
break;
val = lookup->value;
if ((val >= -32768) && (val <= 32767)) {
M_CMPI(s1, val);
+
} else {
- a = dseg_adds4(cd, val);
+ a = dseg_add_s4(cd, val);
M_ILD(REG_ITMP2, REG_PV, a);
M_CMP(s1, REG_ITMP2);
}
- M_BEQ(0);
- codegen_addreference(cd, lookup->target.block);
+ emit_beq(cd, lookup->target.block);
++lookup;
}
- M_BR(0);
- codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
+ emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
ALIGNCODENOP;
break;
goto gen_method;
case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
-
case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
case ICMD_INVOKEINTERFACE:
+ REPLACEMENT_POINT_INVOKE(cd, iptr);
+
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
lm = NULL;
+ um = iptr->sx.s23.s3.um;
+ md = um->methodref->parseddesc.md;
}
else {
lm = iptr->sx.s23.s3.fmiref->p.method;
+ um = NULL;
md = lm->parseddesc;
}
M_FLTMOVE(d, s1);
} else {
d = emit_load(jd, iptr, var, REG_FTMP1);
- if (IS_2_WORD_TYPE(var->type))
- M_DST(d, REG_SP, md->params[s3].regoff * 8);
- else
- M_FST(d, REG_SP, md->params[s3].regoff * 8);
+ M_DST(d, REG_SP, md->params[s3].regoff * 8);
}
}
} /* end of for */
switch (iptr->opc) {
case ICMD_BUILTIN:
- disp = dseg_addaddress(cd, bte->fp);
- d = md->returntype.type;
+ disp = dseg_add_functionptr(cd, bte->fp);
+ M_ALD(REG_PV, REG_PV, disp);
+ M_ALD(REG_PV, REG_PV, 0); /* TOC */
- M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function descriptor */
- M_ALD(REG_ITMP1, REG_PV, 0); /* function entry point address, what about TOC */
- M_MTCTR(REG_ITMP1);
+ /* generate the actual call */
+ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
+ M_MTCTR(REG_PV);
M_JSR;
-
+ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
disp = (s4) (cd->mcodeptr - cd->mcodebase);
M_MFLR(REG_ITMP1);
M_LDA(REG_PV, REG_ITMP1, -disp);
-
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- M_CMPI(REG_RESULT, 0);
- M_BEQ(0);
- codegen_add_fillinstacktrace_ref(cd);
- }
+ emit_exception_check(cd, iptr);
break;
+
case ICMD_INVOKESPECIAL:
- gen_nullptr_check(rd->argintregs[0]);
- M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullptr */
+ emit_nullpointer_check(cd, iptr, REG_A0);
/* fall through */
case ICMD_INVOKESTATIC:
if (lm == NULL) {
- unresolved_method *um = iptr->sx.s23.s3.um;
-
- disp = dseg_addaddress(cd, NULL);
+ disp = dseg_add_unique_address(cd, um);
codegen_addpatchref(cd, PATCHER_invokestatic_special,
um, disp);
-
- if (opt_showdisassemble)
- M_NOP;
-
- d = md->returntype.type;
-
} else {
- disp = dseg_addaddress(cd, lm->stubroutine);
- d = md->returntype.type;
+ disp = dseg_add_address(cd, lm->stubroutine);
}
-
- M_NOP;
M_ALD(REG_PV, REG_PV, disp);
+
+ /* generate the actual call */
+
M_MTCTR(REG_PV);
M_JSR;
+ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
disp = (s4) (cd->mcodeptr - cd->mcodebase);
M_MFLR(REG_ITMP1);
M_LDA(REG_PV, REG_ITMP1, -disp);
- break;
+ break;
case ICMD_INVOKEVIRTUAL:
- gen_nullptr_check(rd->argintregs[0]);
-
if (lm == NULL) {
- unresolved_method *um = iptr->sx.s23.s3.um;
-
codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
-
- if (opt_showdisassemble)
- M_NOP;
-
s1 = 0;
- d = md->returntype.type;
-
} else {
s1 = OFFSET(vftbl_t, table[0]) +
sizeof(methodptr) * lm->vftblindex;
- d = md->returntype.type;
}
- M_ALD(REG_METHODPTR, rd->argintregs[0],
- OFFSET(java_objectheader, vftbl));
+ /* implicit null-pointer check */
+ M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
M_ALD(REG_PV, REG_METHODPTR, s1);
+
+ /* generate the actual call */
+
M_MTCTR(REG_PV);
M_JSR;
+ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
disp = (s4) (cd->mcodeptr - cd->mcodebase);
M_MFLR(REG_ITMP1);
M_LDA(REG_PV, REG_ITMP1, -disp);
break;
case ICMD_INVOKEINTERFACE:
- gen_nullptr_check(rd->argintregs[0]);
-
if (lm == NULL) {
- unresolved_method *um = iptr->sx.s23.s3.um;
-
codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
- if (opt_showdisassemble)
- M_NOP;
-
s1 = 0;
s2 = 0;
- d = md->returntype.type;
} else {
s1 = OFFSET(vftbl_t, interfacetable[0]) -
sizeof(methodptr*) * lm->class->index;
s2 = sizeof(methodptr) * (lm - lm->class->methods);
-
- d = md->returntype.type;
}
- M_ALD(REG_METHODPTR, rd->argintregs[0],
- OFFSET(java_objectheader, vftbl));
+ /* implicit null-pointer check */
+ M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
M_ALD(REG_PV, REG_METHODPTR, s2);
+
+ /* generate the actual call */
+
M_MTCTR(REG_PV);
M_JSR;
+ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
disp = (s4) (cd->mcodeptr - cd->mcodebase);
M_MFLR(REG_ITMP1);
M_LDA(REG_PV, REG_ITMP1, -disp);
+
break;
}
+ /* store return value */
- /* d contains return type */
+ d = md->returntype.type;
if (d != TYPE_VOID) {
if (IS_INT_LNG_TYPE(d)) {
s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
M_MOV(REG_RESULT, s1);
- } else {
+ }
+ else {
s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
M_FLTMOVE(REG_FRESULT, s1);
}
}
break;
-
case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
/* val.a: (classinfo*) superclass */
/* calculate interface checkcast code size */
- s2 = 7;
+ s2 = 9;
+#if defined(SOFTEX)
+ s2 += CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd) ? 2 : 0;
+#endif
if (super == NULL)
- s2 += (opt_showdisassemble ? 1 : 0);
+ s2 += (opt_shownops ? 1 : 0);
/* calculate class checkcast code size */
- s3 = 9 + (s1 == REG_ITMP1);
+ s3 = 10 + (s1 == REG_ITMP1);
+#if defined(SOFTEX)
+ s3 += CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd) ? 1 : 0;
+#endif
if (super == NULL)
- s3 += (opt_showdisassemble ? 1 : 0);
+ s3 += (opt_shownops ? 1 : 0);
/* if class is not resolved, check which code to call */
if (super == NULL) {
M_TST(s1);
- M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
+ M_BEQ(3 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
- disp = dseg_adds4(cd, 0); /* super->flags */
+ disp = dseg_add_unique_s4(cd, 0); /* super->flags */
codegen_addpatchref(cd,
PATCHER_checkcast_instanceof_flags,
iptr->sx.s23.s3.c.ref,
disp);
- if (opt_showdisassemble)
- M_NOP;
-
M_ILD(REG_ITMP2, REG_PV, disp);
M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
M_BEQ(s2 + 1);
if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
if (super == NULL) {
codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_interface,
+ PATCHER_checkcast_interface,
iptr->sx.s23.s3.c.ref,
0);
- if (opt_showdisassemble)
- M_NOP;
-
} else {
M_TST(s1);
M_BEQ(s2);
M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
- M_BLE(0);
- codegen_add_classcastexception_ref(cd, s1); /*XXX s1?? */
+ emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
M_ALD(REG_ITMP3, REG_ITMP2,
OFFSET(vftbl_t, interfacetable[0]) -
superindex * sizeof(methodptr*));
M_TST(REG_ITMP3);
- M_BEQ(0);
- codegen_add_classcastexception_ref(cd, s1); /*XXX s1??*/
+ emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
if (!super)
M_BR(s3);
codegen_addpatchref(cd, PATCHER_checkcast_class,
iptr->sx.s23.s3.c.ref,
disp);
- if (opt_showdisassemble)
- M_NOP;
} else {
- disp = dseg_addaddress(cd, super->vftbl);
+ disp = dseg_add_address(cd, super->vftbl);
M_TST(s1);
M_BEQ(s3);
}
#endif
}
M_CMPU(REG_ITMP3, REG_ITMP2);
- M_BGT(0);
- codegen_add_classcastexception_ref(cd, s1); /* XXX s1? */
+ emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1);
}
d = codegen_reg_of_dst(jd, iptr, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- disp = dseg_addaddress(cd, NULL);
+ disp = dseg_add_unique_address(cd, NULL);
codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
iptr->sx.s23.s3.c.ref,
disp);
-
- if (opt_showdisassemble)
- M_NOP;
} else {
- disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
+ disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
}
M_ALD(rd->argintregs[1], REG_PV, disp);
- disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
+ disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
M_ALD(REG_ITMP2, REG_PV, disp);
M_ALD(REG_ITMP2, REG_ITMP2, 0); /* TOC */
M_MTCTR(REG_ITMP2);
M_JSR;
M_TST(REG_RESULT);
- M_BEQ(0);
- codegen_add_classcastexception_ref(cd, s1); /* XXX s1? */
+ emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, s1);
emit_store_dst(jd, iptr, d);
break;
+
case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
/* val.a: (classinfo*) superclass */
s2 = 8;
if (!super)
- s2 += (opt_showdisassemble ? 1 : 0);
+ s2 += (opt_shownops ? 1 : 0);
/* calculate class instanceof code size */
- s3 = 10;
- if (!super)
- s3 += (opt_showdisassemble ? 1 : 0);
+ s3 = 11;
+ if (super == NULL)
+ s3 += (opt_shownops ? 1 : 0);
M_CLR(d);
/* if class is not resolved, check which code to call */
- if (!super) {
+ if (super == NULL) {
M_TST(s1);
- M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
+ M_BEQ(3 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
- disp = dseg_adds4(cd, 0); /* super->flags */
+ disp = dseg_add_unique_s4(cd, 0); /* super->flags */
codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
iptr->sx.s23.s3.c.ref, disp);
- if (opt_showdisassemble)
- M_NOP;
-
M_ILD(REG_ITMP3, REG_PV, disp);
M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
M_BEQ(s2 + 1);
} else {
codegen_addpatchref(cd,
- PATCHER_checkcast_instanceof_interface,
+ PATCHER_instanceof_interface,
iptr->sx.s23.s3.c.ref, 0);
-
- if (opt_showdisassemble)
- M_NOP;
}
M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
M_BEQ(1);
M_IADD_IMM(REG_ZERO, 1, d);
- if (!super)
+ if (super == NULL)
M_BR(s3);
}
/* class instanceof code */
- if (!super || !(super->flags & ACC_INTERFACE)) {
- disp = dseg_addaddress(cd, supervftbl);
+ if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
if (super) {
+ disp = dseg_add_address(cd, supervftbl);
M_TST(s1);
M_BEQ(s3);
} else {
+ disp = dseg_add_unique_address(cd, NULL);
codegen_addpatchref(cd, PATCHER_instanceof_class,
iptr->sx.s23.s3.c.ref,
disp);
-
- if (opt_showdisassemble) {
- M_NOP;
- }
}
M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
#endif
M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
+ M_EXTSW(REG_ITMP1, REG_ITMP1);
M_CMPU(REG_ITMP1, REG_ITMP2);
M_CLR(d);
M_BGT(1);
codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
iptr->sx.s23.s3.c.ref, disp);
-
- if (opt_showdisassemble)
- M_NOP;
-
} else {
- disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
+ disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
}
/* a1 = arraydescriptor */
M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 8);
#endif
- disp = dseg_addaddress(cd, BUILTIN_multianewarray);
+ disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
M_ALD(REG_ITMP3, REG_PV, disp);
M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(REG_ITMP3);
M_JSR;
/* check for exception before result assignment */
-
- M_CMPI(REG_RESULT, 0);
- M_BEQ(0);
- codegen_add_fillinstacktrace_ref(cd);
+ emit_exception_check(cd, iptr);
d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
M_INTMOVE(REG_RESULT, d);
break;
default:
- *exceptionptr =
- new_internalerror("Unknown ICMD %d during code generation",
- iptr->opc);
+ exceptions_throw_internalerror("Unknown ICMD %d during code generation",
+ iptr->opc);
return false;
} /* switch */
dseg_createlinenumbertable(cd);
+ /* generate stubs */
- /* generate exception and patcher stubs */
-
- {
- exceptionref *eref;
- patchref *pref;
- u4 mcode;
- u1 *savedmcodeptr;
- u1 *tmpmcodeptr;
-
- savedmcodeptr = NULL;
-
- /* generate exception stubs */
-
- for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
- gen_resolvebranch(cd->mcodebase + eref->branchpos,
- eref->branchpos, cd->mcodeptr - cd->mcodebase);
-
- MCODECHECK(100);
-
- /* Check if the exception is an
- ArrayIndexOutOfBoundsException. If so, move index register
- into REG_ITMP1. */
-
- if (eref->reg != -1)
- M_MOV(eref->reg, REG_ITMP1);
-
- /* calcuate exception address */
-
- M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
-
- /* move function to call into REG_ITMP3 */
-
- disp = dseg_addaddress(cd, eref->function);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
-
- if (savedmcodeptr != NULL) {
- disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1);
- M_BR(disp);
-
- } else {
- savedmcodeptr = cd->mcodeptr;
-
- if (jd->isleafmethod) {
- M_MFLR(REG_ZERO);
- M_AST(REG_ZERO, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
- }
-
- M_MOV(REG_PV, rd->argintregs[0]);
- M_MOV(REG_SP, rd->argintregs[1]);
-
- if (jd->isleafmethod)
- M_MOV(REG_ZERO, rd->argintregs[2]);
- else
- M_ALD(rd->argintregs[2],
- REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
-
- M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
- M_MOV(REG_ITMP1, rd->argintregs[4]);
-
- M_STDU(REG_SP, REG_SP, -(LA_SIZE + 6 * 8));
- M_AST(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 8);
-
- M_MTCTR(REG_ITMP3);
- M_JSR;
- M_MOV(REG_RESULT, REG_ITMP1_XPTR);
-
- M_ALD(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 8);
- M_LADD_IMM(REG_SP, LA_SIZE + 6 * 8, REG_SP);
-
- if (jd->isleafmethod) {
- /* XXX FIXME: REG_ZERO can cause problems here! */
- assert(cd->stackframesize * 8 <= 32767);
-
- M_ALD(REG_ZERO, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
- M_MTLR(REG_ZERO);
- }
-
- disp = dseg_addaddress(cd, asm_handle_exception);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_MTCTR(REG_ITMP3);
- M_RTS;
- }
- }
-
-
- /* generate code patching stub call code */
-
- for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
- /* check code segment size */
-
- MCODECHECK(16);
-
- /* 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) + 1);
- M_BR(disp);
-
- cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
-
- /* create stack frame - keep stack 16-byte aligned */
-
- M_AADD_IMM(REG_SP, -8 * 8, REG_SP);
-
- /* calculate return address and move it onto the stack */
-
- M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
- M_AST_INTERN(REG_ITMP3, REG_SP, 5 * 8);
-
- /* move pointer to java_objectheader onto stack */
-
-#if defined(ENABLE_THREADS)
- /* order reversed because of data segment layout */
-
- (void) dseg_addaddress(cd, NULL); /* flcword */
- (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
- disp = dseg_addaddress(cd, NULL); /* vftbl */
-
- M_LDA(REG_ITMP3, REG_PV, disp);
- M_AST_INTERN(REG_ITMP3, REG_SP, 4 * 8);
-#else
- /* do nothing */
-#endif
-
- /* move machine code onto stack */
-
- disp = dseg_adds4(cd, mcode);
- M_ILD(REG_ITMP3, REG_PV, disp);
- M_IST_INTERN(REG_ITMP3, REG_SP, 3 * 8);
-
- /* move class/method/field reference onto stack */
-
- disp = dseg_addaddress(cd, pref->ref);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST_INTERN(REG_ITMP3, REG_SP, 2 * 8);
-
- /* move data segment displacement onto stack */
-
- disp = dseg_addaddress(cd, pref->disp);
- M_LLD(REG_ITMP3, REG_PV, disp);
- M_IST_INTERN(REG_ITMP3, REG_SP, 1 * 8);
-
- /* move patcher function pointer onto stack */
-
- disp = dseg_addaddress(cd, pref->patcher);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 8);
-
- disp = dseg_addaddress(cd, asm_patcher_wrapper);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_MTCTR(REG_ITMP3);
- M_RTS;
- }
-
- /* generate replacement-out stubs */
-
-#if 0
- {
- int i;
-
- replacementpoint = jd->code->rplpoints;
-
- for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
- /* check code segment size */
-
- MCODECHECK(100);
-
- /* note start of stub code */
-
- replacementpoint->outcode = (u1 *) (cd->mcodeptr - cd->mcodebase);
-
- /* make machine code for patching */
-
- tmpmcodeptr = cd->mcodeptr;
- cd->mcodeptr = (u1 *) &(replacementpoint->mcode) + 1 /* big-endian */;
-
- disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
- M_BR(disp);
-
- cd->mcodeptr = tmpmcodeptr;
-
- /* create stack frame - keep 16-byte aligned */
-
- M_AADD_IMM(REG_SP, -4 * 4, REG_SP);
-
- /* push address of `rplpoint` struct */
-
- disp = dseg_addaddress(cd, replacementpoint);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 4);
-
- /* jump to replacement function */
-
- disp = dseg_addaddress(cd, asm_replacement_out);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_MTCTR(REG_ITMP3);
- M_RTS;
- }
- }
-#endif
- }
-
- codegen_finish(jd);
+ emit_patcher_stubs(jd);
+ REPLACEMENT_EMIT_STUBS(jd);
/* everything's ok */
{
u1 *s; /* memory to hold the stub */
ptrint *d;
- codeinfo *code;
codegendata *cd;
s4 dumpsize;
/* Store the codeinfo pointer in the same place as in the
methodheader for compiled methods. */
- code = code_codeinfo_new(m);
-
d[0] = (ptrint) asm_call_jit_compiler;
d[1] = (ptrint) m;
- d[2] = (ptrint) code;
+ d[2] = (ptrint) &d[1]; /* fake code->m */
M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);
M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);
nmd->paramcount +
nmd->memuse;
- cd->stackframesize = (cd->stackframesize + 3) & ~3; /* keep stack 16-byte aligned */
+/* cd->stackframesize = (cd->stackframesize + 3) & ~3;*/ /* keep stack 16-byte aligned */
/* create method header */
- (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
- (void) dseg_adds4(cd, 0); /* IsSync */
- (void) dseg_adds4(cd, 0); /* IsLeaf */
- (void) dseg_adds4(cd, 0); /* IntSave */
- (void) dseg_adds4(cd, 0); /* FltSave */
+ (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_adds4(cd, 0); /* ExTableSize */
+ (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
/* generate code */
#endif
/* get function address (this must happen before the stackframeinfo) */
- funcdisp = dseg_addaddress(cd, f);
+ funcdisp = dseg_add_functionptr(cd, f);
#if !defined(WITH_STATIC_CLASSPATH)
if (f == NULL) {
codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
-
- if (opt_showdisassemble)
- M_NOP;
}
#endif
if (IS_INT_LNG_TYPE(t)) {
if (!md->params[i].inmemory) {
s1 = md->params[i].regoff;
- M_LST(rd->argintregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
+ M_LST(rd->argintregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4*8 + j * 8);
j++;
}
}
if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
if (!md->params[i].inmemory) {
s1 = md->params[i].regoff;
- M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
+ M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4*8 + j * 8);
j++;
}
}
M_MOV(REG_PV, rd->argintregs[1]);
M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[2]);
M_ALD(rd->argintregs[3], REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
- disp = dseg_addaddress(cd, codegen_start_native_call);
+ disp = dseg_add_functionptr(cd, codegen_start_native_call);
M_ALD(REG_ITMP1, REG_PV, disp);
M_ALD(REG_ITMP1, REG_ITMP1, 0); /* TOC */
s1 = md->params[i].regoff + cd->stackframesize;
s2 = nmd->params[j].regoff;
- 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 * 8);
+ if (IS_2_WORD_TYPE(t)) {
+ M_DST(REG_FTMP1, REG_SP, s2 * 8);
} else {
- M_FLD(REG_FTMP1, REG_SP, s1 * 8);
- M_FST(REG_FTMP1, REG_SP, s2 * 8);
+ M_FST(REG_FTMP1, REG_SP, s2 * 8 + 4);
}
}
}
/* put class into second argument register */
if (m->flags & ACC_STATIC) {
- disp = dseg_addaddress(cd, m->class);
+ disp = dseg_add_unique_address(cd, m->class);
M_ALD(rd->argintregs[1], REG_PV, disp);
}
/* put env into first argument register */
- disp = dseg_addaddress(cd, _Jv_env);
+ disp = dseg_add_unique_address(cd, _Jv_env);
M_ALD(rd->argintregs[0], REG_PV, disp);
/* generate the actual native call */
M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
}
else {
- if (IS_2_WORD_TYPE(md->returntype.type))
- M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
- else
- M_FST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); /* FIXME, needed ?*/
+ M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
}
}
/* remove native stackframe info */
M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[0]);
- disp = dseg_addaddress(cd, codegen_finish_native_call);
+ disp = dseg_add_functionptr(cd, codegen_finish_native_call);
M_ALD(REG_ITMP1, REG_PV, disp);
M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */
M_MTCTR(REG_ITMP1);
M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
}
else {
- if (IS_2_WORD_TYPE(md->returntype.type))
+/* if (IS_2_WORD_TYPE(md->returntype.type)) */
M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
- else
- M_FLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
+/* else
+ M_FLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); F XXX
+ */
}
}
M_LADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
- disp = dseg_addaddress(cd, asm_handle_nat_exception);
+ disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
M_ALD(REG_ITMP3, REG_PV, disp);
M_MTCTR(REG_ITMP3);
M_RTS;
#if defined(ENABLE_THREADS)
/* order reversed because of data segment layout */
- (void) dseg_addaddress(cd, NULL); /* flcword */
- (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
- disp = dseg_addaddress(cd, NULL); /* vftbl */
+ (void) dseg_add_unique_address(cd, NULL); /* flcword */
+ (void) dseg_add_unique_address(cd, lock_get_initial_lock_word()); /* monitorPtr */
+ disp = dseg_add_unique_address(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
M_AST(REG_ITMP3, REG_SP, 4 * 8);
/* move machine code onto stack */
- disp = dseg_adds4(cd, mcode);
+ disp = dseg_add_unique_s4(cd, mcode);
M_ILD(REG_ITMP3, REG_PV, disp);
M_IST(REG_ITMP3, REG_SP, 3 * 8);
/* move class/method/field reference onto stack */
- disp = dseg_addaddress(cd, pref->ref);
+ disp = dseg_add_unique_address(cd, pref->ref);
M_ALD(REG_ITMP3, REG_PV, disp);
M_AST(REG_ITMP3, REG_SP, 2 * 8);
/* move data segment displacement onto stack */
- disp = dseg_adds4(cd, pref->disp);
+ disp = dseg_add_unique_s4(cd, pref->disp);
M_ILD(REG_ITMP3, REG_PV, disp);
M_IST(REG_ITMP3, REG_SP, 1 * 8);
/* move patcher function pointer onto stack */
- disp = dseg_addaddress(cd, pref->patcher);
+ disp = dseg_add_functionptr(cd, pref->patcher);
M_ALD(REG_ITMP3, REG_PV, disp);
M_AST(REG_ITMP3, REG_SP, 0 * 8);
- disp = dseg_addaddress(cd, asm_patcher_wrapper);
+ disp = dseg_add_functionptr(cd, asm_patcher_wrapper);
M_ALD(REG_ITMP3, REG_PV, disp);
M_MTCTR(REG_ITMP3);
M_RTS;