/* src/vm/jit/sparc64/emit.c - Sparc code emitter functions
- 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
Authors: Christian Thalinger
Alexander Jordan
- Changes:
-
$Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
*/
-#include "vm/types.h"
-#include "md-abi.h"
+#include "config.h"
+#include "vm/types.h"
#include "vm/jit/sparc64/codegen.h"
+#include "vm/jit/sparc64/md-abi.h"
+
+#include "mm/memory.h"
#include "vm/exceptions.h"
+#include "vm/options.h"
#include "vm/stringlocal.h" /* XXX for gen_resolvebranch */
#include "vm/jit/abi-asm.h"
#include "vm/jit/asmpart.h"
+#include "vm/builtin.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
if (src->flags & INMEMORY) {
COUNT_SPILLS;
- disp = src->vv.regoff * 8;
+ disp = JITSTACK + src->vv.regoff * 8;
if (IS_FLT_DBL_TYPE(src->type))
M_DLD(tempreg, REG_SP, disp);
if (dst->flags & INMEMORY) {
COUNT_SPILLS;
- disp = dst->vv.regoff * 8;
+ disp = JITSTACK + dst->vv.regoff * 8;
if (IS_FLT_DBL_TYPE(dst->type))
M_DST(d, REG_SP, disp);
if (s1 != d) {
if (IS_FLT_DBL_TYPE(src->type))
- M_FMOV(s1, d);
+ M_DMOV(s1, d);
else
M_MOV(s1, d);
}
s4 disp;
if ((value >= -4096) && (value <= 4095)) {
- M_XOR(REG_ZERO, value, d);
+ M_XOR_IMM(REG_ZERO, value, d);
} else {
disp = dseg_add_s4(cd, value);
M_ILD(d, REG_PV_CALLEE, disp);
s4 disp;
if ((value >= -4096) && (value <= 4095)) {
- M_XOR(REG_ZERO, value, d);
+ M_XOR_IMM(REG_ZERO, value, d);
} else {
disp = dseg_add_s8(cd, value);
M_LDX(d, REG_PV_CALLEE, disp);
}
+/* emit_arithmetic_check *******************************************************
+
+ Emit an ArithmeticException check.
+
+*******************************************************************************/
+
+void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_BEQZ(reg, 0);
+ codegen_add_arithmeticexception_ref(cd);
+ M_NOP;
+ }
+}
+
+
+/* emit_arrayindexoutofbounds_check ********************************************
+
+ Emit an ArrayIndexOutOfBoundsException check.
+
+*******************************************************************************/
+
+void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+ M_CMP(s2, REG_ITMP3);
+ M_XBUGE(0);
+ codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+ M_NOP;
+ }
+}
+
+/* emit_nullpointer_check ******************************************************
+
+ Emit a NullPointerException check.
+
+*******************************************************************************/
+
+void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_BEQZ(reg, 0);
+ codegen_add_nullpointerexception_ref(cd);
+ M_NOP;
+ }
+}
+
/* emit_exception_stubs ********************************************************
Generates the code for the exception stubs.
disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) );
if ((disp < (s4) 0xfffc0000) || (disp > (s4) 0x003ffff)) {
- *exceptionptr =
- new_internalerror("Jump offset is out of range: %d > +/-%d",
- disp, 0x003ffff);
+ vm_abort("Jump offset is out of range: %d > +/-%d",
+ disp, 0x003ffff);
return;
}
M_BR(disp);
M_NOP;
- cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
+ cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
/* extend stack frame for wrapper data */
/* calculate return address and move it onto the stack */
M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
- M_AST(REG_ITMP3, REG_SP, USESTACK + 5 * 8);
+ M_AST(REG_ITMP3, REG_SP, JITSTACK + 5 * 8);
/* move pointer to java_objectheader onto stack */
disp = dseg_add_unique_address(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
- M_AST(REG_ITMP3, REG_SP, USESTACK + 4 * 8);
+ M_AST(REG_ITMP3, REG_SP, JITSTACK + 4 * 8);
#else
/* do nothing */
#endif
disp = dseg_add_s4(cd, mcode[0]);
M_ILD(REG_ITMP3, REG_PV, disp);
- M_IST(REG_ITMP3, REG_SP, USESTACK + 3 * 8);
+ M_IST(REG_ITMP3, REG_SP, JITSTACK + 3 * 8);
disp = dseg_add_s4(cd, mcode[1]);
M_ILD(REG_ITMP3, REG_PV, disp);
- M_IST(REG_ITMP3, REG_SP, USESTACK + 3 * 8 + 4);
+ M_IST(REG_ITMP3, REG_SP, JITSTACK + 3 * 8 + 4);
/* move class/method/field reference onto stack */
disp = dseg_add_address(cd, pref->ref);
M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST(REG_ITMP3, REG_SP, USESTACK + 2 * 8);
+ M_AST(REG_ITMP3, REG_SP, JITSTACK + 2 * 8);
/* move data segment displacement onto stack */
disp = dseg_add_s4(cd, pref->disp);
M_ILD(REG_ITMP3, REG_PV, disp);
- M_IST(REG_ITMP3, REG_SP, USESTACK + 1 * 8);
+ M_IST(REG_ITMP3, REG_SP, JITSTACK + 1 * 8);
/* move patcher function pointer onto stack */
disp = dseg_add_address(cd, pref->patcher);
M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST(REG_ITMP3, REG_SP, USESTACK + 0 * 8);
+ M_AST(REG_ITMP3, REG_SP, JITSTACK + 0 * 8);
if (targetdisp == 0) {
targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase);
*******************************************************************************/
+#if defined(ENABLE_REPLACEMENT)
void emit_replacement_stubs(jitdata *jd)
{
}
+#endif /* defined(ENABLE_REPLACEMENT) */
/* emit_verbosecall_enter ******************************************************
M_NOP;
- /* we're calling a c function allocate paramter array */
- M_LDA(REG_SP, REG_SP, -(1 + FLT_ARG_CNT + ABI_PARAMARRAY_SLOTS) * 8);
+ /* XXX jit-c-call */
+ M_LDA(REG_SP, REG_SP, -(1 + FLT_ARG_CNT) * 8);
/* save float argument registers */
for (i = 0; i < FLT_ARG_CNT; i++)
- M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS + (1 + i) * 8);
+ M_DST(rd->argfltregs[i], REG_SP, JITSTACK + (1 + i) * 8);
/* save temporary registers for leaf methods */
/* XXX no leaf optimization yet
}
else {
if (IS_2_WORD_TYPE(t)) {
- M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS);
- M_LDX(rd->argintregs[i], REG_SP, USESTACK_PARAMS);
+ M_DST(rd->argfltregs[i], REG_SP, JITSTACK);
+ M_LDX(rd->argintregs[i], REG_SP, JITSTACK);
}
else {
- M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS);
- M_LDX(rd->argintregs[i], REG_SP, USESTACK_PARAMS);
+ M_FST(rd->argfltregs[i], REG_SP, JITSTACK);
+ M_ILD(rd->argintregs[i], REG_SP, JITSTACK);
}
}
}
/* restore float argument registers */
for (i = 0; i < FLT_ARG_CNT; i++)
- M_DLD(rd->argfltregs[i], REG_SP, USESTACK_PARAMS + (1 + i) * 8);
+ M_DLD(rd->argfltregs[i], REG_SP, JITSTACK + (1 + i) * 8);
/* restore temporary registers for leaf methods */
/* XXX no leaf optimization yet
M_DLD(rd->tmpfltregs[i], REG_SP, (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
}
*/
- M_LDA(REG_SP, REG_SP, (1 + FLT_ARG_CNT + ABI_PARAMARRAY_SLOTS) * 8);
+ M_LDA(REG_SP, REG_SP, (1 + FLT_ARG_CNT) * 8);
/* mark trace code */
M_NOP;
- /* we're calling a c function allocate paramter array */
- M_LDA(REG_SP, REG_SP, -(1 + ABI_PARAMARRAY_SLOTS) * 8);
+ /* XXX jit-c-call */
+ M_LDA(REG_SP, REG_SP, -(1 * 8));
- M_DST(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+ M_DST(REG_FRESULT, REG_SP, JITSTACK);
disp = dseg_add_address(cd, m);
M_ALD(rd->argintregs[0], REG_PV_CALLEE, disp);
M_MOV(REG_RESULT_CALLEE, rd->argintregs[1]);
- M_DMOV(REG_FRESULT, rd->argfltregs[2]);
- M_FMOV(REG_FRESULT, rd->argfltregs[3]);
+ M_DMOV(REG_FRESULT, 2); /* applies for flt and dbl values */
disp = dseg_add_functionptr(cd, builtin_displaymethodstop);
M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
M_NOP;
- M_DLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+ M_DLD(REG_FRESULT, REG_SP, JITSTACK);
- M_LDA(REG_SP, REG_SP, (1 + ABI_PARAMARRAY_SLOTS) * 8);
+ M_LDA(REG_SP, REG_SP, 1 * 8);
/* mark trace code */