/* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
- 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/sparc64/arch.h" */
#include "vm/jit/sparc64/codegen.h"
+#include "vm/jit/sparc64/emit.h"
#include "mm/memory.h"
-#include "native/jni.h"
#include "native/localref.h"
#include "native/native.h"
+
#include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
#include "vm/jit/abi.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/sparc64/emit.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/linenumbertable.h"
#include "vm/jit/parse.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"
+#include "vm/jit/stacktrace.hpp"
#include "vm/jit/sparc64/solaris/macro_rename.h"
varinfo *var;
basicblock *bptr;
instruction *iptr;
- exception_entry *ex;
u2 currentline;
constant_classref *cr;
methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
s4 framesize_disp;
#if 0 /* no leaf optimization yet */
- savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
+ savedregs_num = (code_is_leafmethod(code)) ? 0 : 1; /* space to save the RA */
#endif
savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
cd->stackframesize = rd->memuse + savedregs_num;
#if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
- if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ if (checksync && code_is_synchronized(code))
cd->stackframesize++;
#endif
(void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
framesize_disp = 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.
- */
+ code->synchronizedoffset = JITSTACK + rd->memuse * 8;
+
+ /* REMOVEME: We still need it for exception handling in assembler. */
- if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_add_unique_s4(cd, JITSTACK + (rd->memuse + 1) * 8); /* IsSync */
+ 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);
- }
/* save register window and create stack frame (if necessary) */
/* 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_OUT0, REG_PV, disp);
disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
M_ALD(REG_ITMP3, REG_PV, disp);
M_BNEZ(REG_OUT0, 3);
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_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
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;
}
M_MOV(s1, REG_OUT0);
M_MOV(s3, REG_OUT1);
- disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+ disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
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);
fieldtype = fi->type;
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))
+ codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
}
M_ALD(REG_ITMP1, REG_PV, disp);
fieldtype = fi->type;
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))
+ codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
}
M_ALD(REG_ITMP1, REG_PV, disp);
fieldtype = fi->type;
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))
+ codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
}
M_ALD(REG_ITMP1, REG_PV, disp);
#endif
#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ if (checksync && code_is_synchronized(code)) {
/* XXX jit-c-call */
disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
M_ALD(REG_ITMP3, REG_PV, disp);
/* REG_RA holds the value of the jmp instruction, therefore +8 */
M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
- emit_exception_check(cd, iptr);
if (md->returntype.type == TYPE_FLT) {
/* special handling for float return value in %f0 */
M_FMOV_INTERN(0,1);
}
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));
M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
M_SUB(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_CMP(REG_ITMP3, REG_ITMP2);
emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
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);
if (s1 == d) {
M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
M_ALD(REG_ITMP2, REG_PV, disp);
- CODEGEN_CRITICAL_SECTION_START;
-
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));
- CODEGEN_CRITICAL_SECTION_END;
-
M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
M_CMP(REG_ITMP1, REG_ITMP2);
M_XCMOVULE_IMM(1, d);
} /* if (bptr -> flags >= BBREACHED) */
} /* for basic block */
- dseg_createlinenumbertable(cd);
-
/* generate stubs */
emit_patcher_stubs(jd);
WINSAVE_CNT +
ABIPARAMS_CNT +
FLT_ARG_CNT +
- sizeof(stackframeinfo) / SIZEOF_VOID_P +
+ sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
4; /* 4 arguments or return value */
/* create method header */
(void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
(void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* 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 */
- M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
+ M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
#if defined(ENABLE_GC_CACAO)
/* Save callee saved integer registers in stackframeinfo (GC may
need to recover them during a collection). */
- disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
- OFFSET(stackframeinfo, intregs) + BIAS;
+ disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
+ OFFSET(stackframeinfo_t, intregs) + BIAS;
for (i = 0; i < INT_SAV_CNT; i++)
M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
/* Restore callee saved integer registers from stackframeinfo (GC
might have modified them during a collection). */
- disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
- OFFSET(stackframeinfo, intregs) + BIAS;
+ disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
+ OFFSET(stackframeinfo_t, intregs) + BIAS;
for (i = 0; i < INT_SAV_CNT; i++)
M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
(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 */
funcdisp = dseg_add_functionptr(cd, f);
-#if !defined(WITH_STATIC_CLASSPATH)
- if (f == NULL) {
+ if (f == NULL)
codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
- }
-#endif
/* save float argument registers */
M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
M_NOP; /* XXX fill me! */
+ /* remember class argument */
+
+ if (m->flags & ACC_STATIC)
+ M_MOV(REG_RESULT_CALLER, REG_ITMP3);
+
/* keep float arguments on stack */
#if 0
for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
/* put class into second argument register */
- if (m->flags & ACC_STATIC) {
- disp = dseg_add_address(cd, m->class);
- M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
- }
+ if (m->flags & ACC_STATIC)
+ M_MOV(REG_ITMP3, REG_OUT1);
/* put env into first argument register */
- disp = dseg_add_address(cd, _Jv_env);
+ disp = dseg_add_address(cd, VM_get_jnienv());
M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
/* do the native function call */