58017211ca9c5f5909fba32155dde52323abb771 cacao-0.94
f0bbc765d01fd58f0c42e25de02f059c2f9a9598 cacao-0.95
31f9c3186dded73dab4ed3f519c1cc28940c98dd cacao-0.96
+ae597ed07b16e08575c39f88b93004049f663b2b new_instruction_format_branch_point
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 5290 2006-09-04 17:12:48Z christian $
+ $Id: codegen.c 5323 2006-09-05 16:45:24Z edwin $
*/
M_ALD(REG_ITMP1, REG_PV, disp);
switch (iptr->op1) {
case TYPE_INT:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_IST(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_IST(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_LST(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_LST(s1, REG_ITMP1, 0);
break;
case TYPE_ADR:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_AST(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_AST(s1, REG_ITMP1, 0);
break;
case TYPE_FLT:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_FST(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_FST(s1, REG_ITMP1, 0);
break;
case TYPE_DBL:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_DST(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_DST(s1, REG_ITMP1, 0);
break;
}
break;
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 5275 2006-08-24 18:42:48Z twisti $
+ $Id: codegen.c 5323 2006-09-05 16:45:24Z edwin $
*/
}
#endif
- /* copy argument registers to stack and call trace function with pointer
- to arguments on stack.
- */
-
#if !defined(NDEBUG)
- if (opt_verbosecall) {
- stack_off = 0;
- s1 = INT_TMP_CNT * 4 + TRACE_ARGS_NUM * 8 + 4 + 4 + cd->stackframesize * 4;
-
- M_ISUB_IMM(INT_TMP_CNT * 4 + TRACE_ARGS_NUM * 8 + 4, REG_SP);
-
- /* save temporary registers for leaf methods */
-
- for (p = 0; p < INT_TMP_CNT; p++)
- M_IST(rd->tmpintregs[p], REG_SP, TRACE_ARGS_NUM * 8 + 4 + p * 4);
-
- for (p = 0, l = 0; p < md->paramcount && p < TRACE_ARGS_NUM; p++) {
- t = md->paramtypes[p].type;
-
- if (IS_INT_LNG_TYPE(t)) {
- if (IS_2_WORD_TYPE(t)) {
- emit_mov_membase_reg(cd, REG_SP, s1 + stack_off, REG_ITMP1);
- emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
- emit_mov_membase_reg(cd, REG_SP, s1 + stack_off + 4, REG_ITMP1);
- emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
-
- } else if (t == TYPE_ADR) {
-/* } else { */
- emit_mov_membase_reg(cd, REG_SP, s1 + stack_off, REG_ITMP1);
- emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
- emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP1, REG_ITMP1);
- emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
-
- } else {
- emit_mov_membase_reg(cd, REG_SP, s1 + stack_off, EAX);
- emit_cltd(cd);
- emit_mov_reg_membase(cd, EAX, REG_SP, p * 8);
- emit_mov_reg_membase(cd, EDX, REG_SP, p * 8 + 4);
- }
-
- } else {
- if (!IS_2_WORD_TYPE(t)) {
- emit_flds_membase(cd, REG_SP, s1 + stack_off);
- emit_fstps_membase(cd, REG_SP, p * 8);
- emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP1, REG_ITMP1);
- emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
-
- } else {
- emit_fldl_membase(cd, REG_SP, s1 + stack_off);
- emit_fstpl_membase(cd, REG_SP, p * 8);
- }
- }
- stack_off += (IS_2_WORD_TYPE(t)) ? 8 : 4;
- }
-
- /* fill up the remaining arguments */
- emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP1, REG_ITMP1);
- for (p = md->paramcount; p < TRACE_ARGS_NUM; p++) {
- emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
- emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
- }
-
- emit_mov_imm_membase(cd, (ptrint) m, REG_SP, TRACE_ARGS_NUM * 8);
- emit_mov_imm_reg(cd, (ptrint) builtin_trace_args, REG_ITMP1);
- emit_call_reg(cd, REG_ITMP1);
-
- /* restore temporary registers for leaf methods */
-
- for (p = 0; p < INT_TMP_CNT; p++)
- M_ILD(rd->tmpintregs[p], REG_SP, TRACE_ARGS_NUM * 8 + 4 + p * 4);
-
- M_IADD_IMM(INT_TMP_CNT * 4 + TRACE_ARGS_NUM * 8 + 4, REG_SP);
- }
-#endif /* !defined(NDEBUG) */
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+ emit_verbosecall_enter(jd);
+#endif
}
switch (iptr->op1) {
case TYPE_INT:
case TYPE_ADR:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_IST(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_IST(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP23_PACKED);
- M_LST(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP23_PACKED);
+ M_LST(s1, REG_ITMP1, 0);
break;
case TYPE_FLT:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP1);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
emit_fstps_membase(cd, REG_ITMP1, 0);
break;
case TYPE_DBL:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP1);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
emit_fstpl_membase(cd, REG_ITMP1, 0);
break;
}
p = cd->stackframesize;
#if !defined(NDEBUG)
- /* call trace function */
-
- if (opt_verbosecall) {
- M_ISUB_IMM(4 + 8 + 8 + 4, REG_SP);
-
- emit_mov_imm_membase(cd, (s4) m, REG_SP, 0);
-
- emit_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
- emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
-
- emit_fstl_membase(cd, REG_SP, 4 + 8);
- emit_fsts_membase(cd, REG_SP, 4 + 8 + 8);
-
- emit_mov_imm_reg(cd, (s4) builtin_displaymethodstop, REG_ITMP1);
- emit_call_reg(cd, REG_ITMP1);
-
- emit_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
- emit_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
-
- emit_alu_imm_reg(cd, ALU_ADD, 4 + 8 + 8 + 4, REG_SP);
- }
-#endif /* !defined(NDEBUG) */
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+ emit_verbosecall_exit(jd);
+#endif
#if defined(ENABLE_THREADS)
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
#if !defined(NDEBUG)
- if (opt_verbosecall) {
- s4 p, t;
-
- disp = cd->stackframesize * 4;
-
- M_ASUB_IMM(TRACE_ARGS_NUM * 8 + 4, REG_SP);
-
- for (p = 0; p < md->paramcount && p < TRACE_ARGS_NUM; p++) {
- t = md->paramtypes[p].type;
- if (IS_INT_LNG_TYPE(t)) {
- if (IS_2_WORD_TYPE(t)) {
- M_ILD(REG_ITMP1, REG_SP,
- 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
- M_ILD(REG_ITMP2, REG_SP,
- 4 + TRACE_ARGS_NUM * 8 + 4 + disp + 4);
- M_IST(REG_ITMP1, REG_SP, p * 8);
- M_IST(REG_ITMP2, REG_SP, p * 8 + 4);
-
- } else if (t == TYPE_ADR) {
- M_ALD(REG_ITMP1, REG_SP,
- 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
- M_CLR(REG_ITMP2);
- M_AST(REG_ITMP1, REG_SP, p * 8);
- M_AST(REG_ITMP2, REG_SP, p * 8 + 4);
-
- } else {
- M_ILD(EAX, REG_SP, 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
- emit_cltd(cd);
- M_IST(EAX, REG_SP, p * 8);
- M_IST(EDX, REG_SP, p * 8 + 4);
- }
-
- } else {
- if (!IS_2_WORD_TYPE(t)) {
- emit_flds_membase(cd, REG_SP,
- 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
- emit_fstps_membase(cd, REG_SP, p * 8);
- emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP2, REG_ITMP2);
- M_IST(REG_ITMP2, REG_SP, p * 8 + 4);
-
- } else {
- emit_fldl_membase(cd, REG_SP,
- 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
- emit_fstpl_membase(cd, REG_SP, p * 8);
- }
- }
- disp += (IS_2_WORD_TYPE(t)) ? 8 : 4;
- }
-
- M_CLR(REG_ITMP1);
- for (p = md->paramcount; p < TRACE_ARGS_NUM; p++) {
- M_IST(REG_ITMP1, REG_SP, p * 8);
- M_IST(REG_ITMP1, REG_SP, p * 8 + 4);
- }
-
- M_AST_IMM(m, REG_SP, TRACE_ARGS_NUM * 8);
-
- M_MOV_IMM(builtin_trace_args, REG_ITMP1);
- M_CALL(REG_ITMP1);
-
- M_AADD_IMM(TRACE_ARGS_NUM * 8 + 4, REG_SP);
- }
-#endif /* !defined(NDEBUG) */
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+ emit_verbosecall_enter(jd);
+#endif
/* get function address (this must happen before the stackframeinfo) */
}
#if !defined(NDEBUG)
- if (opt_verbosecall) {
- /* restore return value */
-
- if (IS_INT_LNG_TYPE(md->returntype.type)) {
- if (IS_2_WORD_TYPE(md->returntype.type))
- M_ILD(REG_RESULT2, REG_SP, 2 * 4);
- M_ILD(REG_RESULT, REG_SP, 1 * 4);
-
- } else {
- if (IS_2_WORD_TYPE(md->returntype.type))
- emit_fldl_membase(cd, REG_SP, 1 * 4);
- else
- emit_flds_membase(cd, REG_SP, 1 * 4);
- }
-
- M_ASUB_IMM(4 + 8 + 8 + 4, REG_SP);
-
- M_AST_IMM((ptrint) m, REG_SP, 0);
-
- M_IST(REG_RESULT, REG_SP, 4);
- M_IST(REG_RESULT2, REG_SP, 4 + 4);
-
- emit_fstl_membase(cd, REG_SP, 4 + 8);
- emit_fsts_membase(cd, REG_SP, 4 + 8 + 8);
-
- M_MOV_IMM(builtin_displaymethodstop, REG_ITMP1);
- M_CALL(REG_ITMP1);
-
- M_AADD_IMM(4 + 8 + 8 + 4, REG_SP);
- }
-#endif /* !defined(NDEBUG) */
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+ emit_verbosecall_exit(jd);
+#endif
/* remove native stackframe info */
Changes:
- $Id: codegen.h 5234 2006-08-14 17:50:12Z christian $
+ $Id: codegen.h 5320 2006-09-05 16:10:21Z twisti $
*/
#define M_FST(a,b,disp) emit_fstps_membase(cd, (b), (disp))
#define M_DST(a,b,disp) emit_fstpl_membase(cd, (b), (disp))
+#define M_FSTNP(a,b,disp) emit_fsts_membase(cd, (b), (disp))
+#define M_DSTNP(a,b,disp) emit_fstl_membase(cd, (b), (disp))
+
/* function gen_resolvebranch **************************************************
Changes:
- $Id: emit.c 5277 2006-08-25 07:29:05Z twisti $
+ $Id: emit.c 5320 2006-09-05 16:10:21Z twisti $
*/
# include "threads/native/lock.h"
#endif
+#include "vm/builtin.h"
#include "vm/statistics.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit.h"
#include "vm/jit/jit.h"
+#include "vm/jit/replace.h"
/* emit_load_s1 ****************************************************************
}
+/* emit_verbosecall_enter ******************************************************
+
+ Generates the code for the call trace.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void emit_verbosecall_enter(jitdata *jd)
+{
+ methodinfo *m;
+ codegendata *cd;
+ registerdata *rd;
+ methoddesc *md;
+ s4 disp;
+ s4 i, t;
+
+ /* get required compiler data */
+
+ m = jd->m;
+ cd = jd->cd;
+ rd = jd->rd;
+
+ md = m->parseddesc;
+
+ /* mark trace code */
+
+ M_NOP;
+
+ /* methodinfo* + arguments + return address */
+
+ disp = TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4 +
+ cd->stackframesize * 4 + 4;
+
+ M_ASUB_IMM(TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4, REG_SP);
+
+ /* save temporary registers for leaf methods */
+
+ for (i = 0; i < INT_TMP_CNT; i++)
+ M_IST(rd->tmpintregs[i], REG_SP, TRACE_ARGS_NUM * 8 + 4 + i * 4);
+
+ for (i = 0; i < md->paramcount && i < TRACE_ARGS_NUM; i++) {
+ t = md->paramtypes[i].type;
+
+ if (IS_INT_LNG_TYPE(t)) {
+ if (IS_2_WORD_TYPE(t)) {
+ M_LLD(REG_ITMP12_PACKED, REG_SP, disp);
+ M_LST(REG_ITMP12_PACKED, REG_SP, i * 8);
+ }
+ else if (IS_ADR_TYPE(t)) {
+ M_ALD(REG_ITMP1, REG_SP, disp);
+ M_AST(REG_ITMP1, REG_SP, i * 8);
+ M_IST_IMM(0, REG_SP, i * 8 + 4);
+ }
+ else {
+ M_ILD(EAX, REG_SP, disp);
+ emit_cltd(cd);
+ M_LST(EAX_EDX_PACKED, REG_SP, i * 8);
+ }
+ }
+ else {
+ if (IS_2_WORD_TYPE(t)) {
+ M_DLD(REG_NULL, REG_SP, disp);
+ M_DST(REG_NULL, REG_SP, i * 8);
+ }
+ else {
+ M_FLD(REG_NULL, REG_SP, disp);
+ M_FST(REG_NULL, REG_SP, i * 8);
+ M_IST_IMM(0, REG_SP, i * 8 + 4);
+ }
+ }
+
+ disp += (IS_2_WORD_TYPE(t)) ? 8 : 4;
+ }
+
+ M_AST_IMM(m, REG_SP, TRACE_ARGS_NUM * 8);
+
+ M_MOV_IMM(builtin_trace_args, REG_ITMP1);
+ M_CALL(REG_ITMP1);
+
+ /* restore temporary registers for leaf methods */
+
+ for (i = 0; i < INT_TMP_CNT; i++)
+ M_ILD(rd->tmpintregs[i], REG_SP, TRACE_ARGS_NUM * 8 + 4 + i * 4);
+
+ M_AADD_IMM(TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4, REG_SP);
+
+ /* mark trace code */
+
+ M_NOP;
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* emit_verbosecall_exit *******************************************************
+
+ Generates the code for the call trace.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void emit_verbosecall_exit(jitdata *jd)
+{
+ methodinfo *m;
+ codegendata *cd;
+ registerdata *rd;
+
+ /* get required compiler data */
+
+ m = jd->m;
+ cd = jd->cd;
+ rd = jd->rd;
+
+ /* mark trace code */
+
+ M_NOP;
+
+ M_ASUB_IMM(4 + 8 + 8 + 4 + 8, REG_SP); /* +8: keep stack 16-byte aligned */
+
+ M_AST_IMM(m, REG_SP, 0 * 4);
+
+ M_LST(REG_RESULT_PACKED, REG_SP, 1 * 4);
+
+ M_DSTNP(REG_NULL, REG_SP, 1 * 4 + 1 * 8);
+ M_FSTNP(REG_NULL, REG_SP, 1 * 4 + 2 * 8);
+
+ M_MOV_IMM(builtin_displaymethodstop, REG_ITMP1);
+ M_CALL(REG_ITMP1);
+
+ M_LLD(REG_RESULT_PACKED, REG_SP, 1 * 4);
+
+ M_AADD_IMM(4 + 8 + 8 + 4 + 8, REG_SP);
+
+ /* mark trace code */
+
+ M_NOP;
+}
+#endif /* !defined(NDEBUG) */
+
+
/* code generation functions **************************************************/
static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
This module generates MIPS machine code for a sequence of
intermediate code commands (ICMDs).
- $Id: codegen.c 5291 2006-09-04 17:45:32Z twisti $
+ $Id: codegen.c 5324 2006-09-05 17:11:32Z twisti $
*/
}
#endif
- /* copy argument registers to stack and call trace function */
-
- if (opt_verbosecall) {
- M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
- M_AST(REG_RA, REG_SP, 1 * 8);
-
- /* save integer argument registers */
-
- for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
- M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
-
- /* save and copy float arguments into integer registers */
-
- for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
- t = md->paramtypes[p].type;
-
- if (IS_FLT_DBL_TYPE(t)) {
- if (IS_2_WORD_TYPE(t)) {
- M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
- M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
-
- } else {
- M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
- M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
- }
-
- } else {
- M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
- }
- }
-
- /* save temporary registers for leaf methods */
-
- if (jd->isleafmethod) {
- for (p = 0; p < INT_TMP_CNT; p++)
- M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
-
- for (p = 0; p < FLT_TMP_CNT; p++)
- M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
- }
-
- p = dseg_addaddress(cd, m);
- M_ALD(REG_ITMP1, REG_PV, p);
- M_AST(REG_ITMP1, REG_SP, 0 * 8);
- disp = dseg_addaddress(cd, (void *) builtin_trace_args);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JSR(REG_RA, REG_ITMP3);
- M_NOP;
-
- M_ALD(REG_RA, REG_SP, 1 * 8);
-
- /* restore integer argument registers */
-
- for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
- M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
-
- /* restore float argument registers */
-
- for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
- t = md->paramtypes[p].type;
-
- if (IS_FLT_DBL_TYPE(t)) {
- if (IS_2_WORD_TYPE(t)) {
- M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
-
- } else {
- M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
- }
-
- } else {
- M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
- }
- }
-
- /* restore temporary registers for leaf methods */
-
- if (jd->isleafmethod) {
- for (p = 0; p < INT_TMP_CNT; p++)
- M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
-
- for (p = 0; p < FLT_TMP_CNT; p++)
- M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
- }
-
- M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
- }
+#if !defined(NDEBUG)
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+ emit_verbosecall_enter(jd);
+#endif
}
M_ALD(REG_ITMP1, REG_PV, disp);
switch (iptr->op1) {
case TYPE_INT:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_IST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_IST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_LST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_LST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_ADR:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_AST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_AST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_FLT:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_FST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_FST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_DBL:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_DST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_DST_INTERN(s1, REG_ITMP1, 0);
break;
}
break;
s4 i, p;
p = cd->stackframesize;
-
- /* call trace function */
-
- if (opt_verbosecall) {
- M_LDA(REG_SP, REG_SP, -3 * 8);
- M_LST(REG_RA, REG_SP, 0 * 8);
- M_LST(REG_RESULT, REG_SP, 1 * 8);
- M_DST(REG_FRESULT, REG_SP, 2 * 8);
-
- disp = dseg_addaddress(cd, m);
- M_ALD(rd->argintregs[0], REG_PV, disp);
- M_MOV(REG_RESULT, rd->argintregs[1]);
- M_DMOV(REG_FRESULT, rd->argfltregs[2]);
- M_FMOV(REG_FRESULT, rd->argfltregs[3]);
-
- disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JSR(REG_RA, REG_ITMP3);
- M_NOP;
- M_DLD(REG_FRESULT, REG_SP, 2 * 8);
- M_LLD(REG_RESULT, REG_SP, 1 * 8);
- M_LLD(REG_RA, REG_SP, 0 * 8);
- M_LDA(REG_SP, REG_SP, 3 * 8);
- }
+#if !defined(NDEBUG)
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+ emit_verbosecall_exit(jd);
+#endif
#if defined(ENABLE_THREADS)
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* store RA*/
#if !defined(NDEBUG)
- /* call trace function */
-
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
- M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
-
- /* save integer argument registers */
-
- for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
- if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
- M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
-
- /* save and copy float arguments into integer registers */
-
- for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
- t = md->paramtypes[i].type;
-
- if (IS_FLT_DBL_TYPE(t)) {
- if (IS_2_WORD_TYPE(t)) {
- M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
- M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
- } else {
- M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
- M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
- }
- }
- }
-
- disp = dseg_addaddress(cd, m);
- M_ALD(REG_ITMP1, REG_PV, disp);
- M_AST(REG_ITMP1, REG_SP, 0 * 8);
- disp = dseg_addaddress(cd, builtin_trace_args);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JSR(REG_RA, REG_ITMP3);
- M_NOP;
-
- for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
- if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
- M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
-
- for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
- t = md->paramtypes[i].type;
-
- if (IS_FLT_DBL_TYPE(t)) {
- if (IS_2_WORD_TYPE(t))
- M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
- else
- M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
- }
- }
-
- M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
- }
-#endif /* !defined(NDEBUG) */
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+ emit_verbosecall_enter(jd);
+#endif
/* get function address (this must happen before the stackframeinfo) */
}
#if !defined(NDEBUG)
- /* call finished trace function */
-
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
- if (md->returntype.type != TYPE_VOID) {
- if (IS_INT_LNG_TYPE(md->returntype.type))
- M_LLD(REG_RESULT, REG_SP, 0 * 8);
- else
- M_DLD(REG_FRESULT, REG_SP, 0 * 8);
- }
-
- disp = dseg_addaddress(cd, m);
- M_ALD(rd->argintregs[0], REG_PV, disp);
-
- M_MOV(REG_RESULT, rd->argintregs[1]);
- M_DMFC1(REG_ITMP1, REG_FRESULT);
- M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
- M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
-
- disp = dseg_addaddress(cd, builtin_displaymethodstop);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JSR(REG_RA, REG_ITMP3);
- M_NOP;
- }
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+ emit_verbosecall_exit(jd);
#endif
/* remove native stackframe info */
M_JMP(REG_ITMP3); /* jump to asm exception handler */
M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
- /* generate static stub call code */
-
- {
- patchref *pref;
- u8 mcode;
- u1 *savedmcodeptr;
- u1 *tmpmcodeptr;
-
- for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
- /* Get machine code which is patched back in later. The
- call is 2 instruction words long. */
-
- tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
-
- /* We need to split this, because an unaligned 8 byte read
- causes a SIGSEGV. */
-
- mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
- ((u4 *) tmpmcodeptr)[0];
+ /* generate patcher stubs */
- /* 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_BRS(disp);
- M_NOP; /* branch delay slot */
-
- cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
-
- /* create stack frame */
-
- M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
-
- /* move return address onto stack */
-
- M_AST(REG_RA, 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(REG_ITMP3, REG_SP, 4 * 8);
-#else
- M_AST(REG_ZERO, REG_SP, 4 * 8);
-#endif
-
- /* move machine code onto stack */
-
- disp = dseg_adds8(cd, mcode);
- M_LLD(REG_ITMP3, REG_PV, disp);
- M_LST(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(REG_ITMP3, REG_SP, 2 * 8);
-
- /* move data segment displacement onto stack */
-
- disp = dseg_adds4(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);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST(REG_ITMP3, REG_SP, 0 * 8);
-
- disp = dseg_addaddress(cd, asm_patcher_wrapper);
- M_ALD(REG_ITMP3, REG_PV, disp);
- M_JMP(REG_ITMP3);
- M_NOP;
- }
- }
+ emit_patcher_stubs(jd);
codegen_finish(jd);
#include "vm/exceptions.h"
#include "vm/stringlocal.h" /* XXX for gen_resolvebranch */
+#include "vm/jit/abi-asm.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit.h"
else {
disp = (((u4 *) cd->mcodebase) + targetdisp) -
(((u4 *) cd->mcodeptr) + 1);
+
M_BR(disp);
M_NOP;
}
{
codegendata *cd;
patchref *pref;
- u4 mcode;
+ u4 mcode[2];
u1 *savedmcodeptr;
u1 *tmpmcodeptr;
s4 targetdisp;
tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
- /* We need to split this, because an unaligned 8 byte read
- causes a SIGSEGV. */
+ /* We use 2 loads here as an unaligned 8-byte read on 64-bit
+ MIPS causes a SIGSEGV and using the same code for both
+ architectures is much better. */
- mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
- ((u4 *) tmpmcodeptr)[0];
+ mcode[0] = ((u4 *) tmpmcodeptr)[0];
+ mcode[1] = ((u4 *) tmpmcodeptr)[1];
/* Patch in the call to call the following code (done at
compile time). */
/* move machine code onto stack */
- disp = dseg_adds8(cd, mcode);
- M_LLD(REG_ITMP3, REG_PV, disp);
- M_LST(REG_ITMP3, REG_SP, 3 * 8);
+ disp = dseg_adds4(cd, mcode[0]);
+ M_ILD(REG_ITMP3, REG_PV, disp);
+ M_IST(REG_ITMP3, REG_SP, 3 * 8);
+
+ disp = dseg_adds4(cd, mcode[1]);
+ M_ILD(REG_ITMP3, REG_PV, disp);
+ M_IST(REG_ITMP3, REG_SP, 3 * 8 + 4);
/* move class/method/field reference onto stack */
else {
disp = (((u4 *) cd->mcodebase) + targetdisp) -
(((u4 *) cd->mcodeptr) + 1);
+
M_BR(disp);
M_NOP;
}
}
+/* emit_verbosecall_enter ******************************************************
+
+ Generates the code for the call trace.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void emit_verbosecall_enter(jitdata *jd)
+{
+ methodinfo *m;
+ codegendata *cd;
+ registerdata *rd;
+ methoddesc *md;
+ s4 disp;
+ s4 i, t;
+
+ /* get required compiler data */
+
+ m = jd->m;
+ cd = jd->cd;
+ rd = jd->rd;
+
+ md = m->parseddesc;
+
+ /* mark trace code */
+
+ M_NOP;
+
+ M_LDA(REG_SP, REG_SP, -(2 + ARG_CNT + TMP_CNT) * 8);
+ M_AST(REG_RA, REG_SP, 1 * 8);
+
+ /* save argument registers */
+
+ for (i = 0; i < INT_ARG_CNT; i++)
+ M_LST(rd->argintregs[i], REG_SP, (2 + i) * 8);
+
+ for (i = 0; i < FLT_ARG_CNT; i++)
+ M_DST(rd->argfltregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
+
+ /* save temporary registers for leaf methods */
+
+ if (jd->isleafmethod) {
+ for (i = 0; i < INT_TMP_CNT; i++)
+ M_LST(rd->tmpintregs[i], REG_SP, (2 + ARG_CNT + i) * 8);
+
+ for (i = 0; i < FLT_TMP_CNT; i++)
+ M_DST(rd->tmpfltregs[i], REG_SP, (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
+ }
+
+ /* load float arguments into integer registers */
+
+ for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
+ t = md->paramtypes[i].type;
+
+ if (IS_FLT_DBL_TYPE(t)) {
+ if (IS_2_WORD_TYPE(t)) {
+ M_DST(rd->argfltregs[i], REG_SP, 0 * 8);
+ M_LLD(rd->argintregs[i], REG_SP, 0 * 8);
+ }
+ else {
+ M_FST(rd->argfltregs[i], REG_SP, 0 * 8);
+ M_ILD(rd->argintregs[i], REG_SP, 0 * 8);
+ }
+ }
+ }
+
+ disp = dseg_addaddress(cd, m);
+ M_ALD(REG_ITMP1, REG_PV, disp);
+ M_AST(REG_ITMP1, REG_SP, 0 * 8);
+ disp = dseg_addaddress(cd, builtin_trace_args);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_JSR(REG_RA, REG_ITMP3);
+ M_NOP;
+
+ /* restore argument registers */
+
+ for (i = 0; i < INT_ARG_CNT; i++)
+ M_LLD(rd->argintregs[i], REG_SP, (2 + i) * 8);
+
+ for (i = 0; i < FLT_ARG_CNT; i++)
+ M_DLD(rd->argfltregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
+
+ /* restore temporary registers for leaf methods */
+
+ if (jd->isleafmethod) {
+ for (i = 0; i < INT_TMP_CNT; i++)
+ M_LLD(rd->tmpintregs[i], REG_SP, (2 + ARG_CNT + i) * 8);
+
+ for (i = 0; i < FLT_TMP_CNT; i++)
+ M_DLD(rd->tmpfltregs[i], REG_SP, (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
+ }
+
+ M_ALD(REG_RA, REG_SP, 1 * 8);
+ M_LDA(REG_SP, REG_SP, (2 + ARG_CNT + TMP_CNT) * 8);
+
+ /* mark trace code */
+
+ M_NOP;
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* emit_verbosecall_exit *******************************************************
+
+ Generates the code for the call trace.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void emit_verbosecall_exit(jitdata *jd)
+{
+ methodinfo *m;
+ codegendata *cd;
+ registerdata *rd;
+ s4 disp;
+
+ /* get required compiler data */
+
+ m = jd->m;
+ cd = jd->cd;
+ rd = jd->rd;
+
+ /* mark trace code */
+
+ M_NOP;
+
+ M_LDA(REG_SP, REG_SP, -4 * 8); /* keep stack 16-byte aligned */
+ M_LST(REG_RA, REG_SP, 0 * 8);
+
+ M_LST(REG_RESULT, REG_SP, 1 * 8);
+ M_DST(REG_FRESULT, REG_SP, 2 * 8);
+
+ disp = dseg_addaddress(cd, m);
+ M_ALD(rd->argintregs[0], REG_PV, disp);
+
+ M_MOV(REG_RESULT, rd->argintregs[1]);
+ M_DMOV(REG_FRESULT, rd->argfltregs[2]);
+ M_FMOV(REG_FRESULT, rd->argfltregs[3]);
+
+ disp = dseg_addaddress(cd, builtin_displaymethodstop);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_JSR(REG_RA, REG_ITMP3);
+ M_NOP;
+
+ M_DLD(REG_FRESULT, REG_SP, 2 * 8);
+ M_LLD(REG_RESULT, REG_SP, 1 * 8);
+
+ M_LLD(REG_RA, REG_SP, 0 * 8);
+ M_LDA(REG_SP, REG_SP, 4 * 8);
+
+ /* mark trace code */
+
+ M_NOP;
+}
+#endif /* !defined(NDEBUG) */
+
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where
Changes:
- $Id: patcher.c 5164 2006-07-19 15:54:01Z twisti $
+ $Id: patcher.c 5319 2006-09-05 12:54:10Z twisti $
*/
bool patcher_get_putstatic(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
unresolved_field *uf;
s4 disp;
u1 *pv;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_get_putfield(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
unresolved_field *uf;
fieldinfo *fi;
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
/* get the fieldinfo */
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* if we show disassembly, we have to skip the nop's */
bool patcher_aconst(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
constant_classref *cr;
s4 disp;
u1 *pv;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_builtin_multianewarray(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
constant_classref *cr;
s4 disp;
u1 *pv;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_builtin_arraycheckcast(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
constant_classref *cr;
s4 disp;
u1 *pv;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_invokestatic_special(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
unresolved_method *um;
s4 disp;
u1 *pv;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_invokevirtual(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
unresolved_method *um;
methodinfo *m;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
/* get the fieldinfo */
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* if we show disassembly, we have to skip the nop's */
bool patcher_invokeinterface(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
unresolved_method *um;
methodinfo *m;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
/* get the fieldinfo */
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* if we show disassembly, we have to skip the nop's */
bool patcher_checkcast_instanceof_flags(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
constant_classref *cr;
s4 disp;
u1 *pv;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_checkcast_instanceof_interface(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
constant_classref *cr;
classinfo *c;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
/* get the fieldinfo */
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* if we show disassembly, we have to skip the nop's */
bool patcher_checkcast_instanceof_class(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
constant_classref *cr;
s4 disp;
u1 *pv;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_clinit(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
classinfo *c;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
c = (classinfo *) *((ptrint *) (sp + 2 * 8));
/* check if the class is initialized */
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_athrow_areturn(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
unresolved_class *uc;
classinfo *c;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
/* resolve the class */
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
bool patcher_resolve_native(u1 *sp)
{
u1 *ra;
-#if SIZEOF_VOID_P == 8
- u8 mcode;
-#else
u4 mcode[2];
-#endif
methodinfo *m;
s4 disp;
u1 *pv;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
-#if SIZEOF_VOID_P == 8
- mcode = *((u8 *) (sp + 3 * 8));
-#else
mcode[0] = *((u4 *) (sp + 3 * 8));
mcode[1] = *((u4 *) (sp + 3 * 8 + 4));
-#endif
m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
- /* calculate and set the new return address */
-
- ra = ra - 2 * 4;
- *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
-
/* resolve native function */
if (!(f = native_resolve_function(m)))
/* patch back original code */
-#if SIZEOF_VOID_P == 8
- *((u4 *) (ra + 0 * 4)) = mcode;
- *((u4 *) (ra + 1 * 4)) = mcode >> 32;
-#else
*((u4 *) (ra + 0 * 4)) = mcode[0];
*((u4 *) (ra + 1 * 4)) = mcode[1];
-#endif
/* synchronize instruction cache */
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 5281 2006-08-28 15:18:54Z twisti $
+ $Id: codegen.c 5323 2006-09-05 16:45:24Z edwin $
*/
M_ALD(REG_ITMP1, REG_PV, disp);
switch (iptr->op1) {
case TYPE_INT:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_IST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_IST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP23_PACKED);
- M_LST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP23_PACKED);
+ M_LST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_ADR:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_AST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_AST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_FLT:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_FST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_FST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_DBL:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_DST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_DST_INTERN(s1, REG_ITMP1, 0);
break;
}
break;
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 5286 2006-09-04 12:38:21Z tbfg $
+ $Id: codegen.c 5323 2006-09-05 16:45:24Z edwin $
*/
#if defined(ENABLE_THREADS)
/* space to save argument of monitor_enter and Return Values to survive */
/* monitor_exit. The stack position for the argument can not be shared */
- /* with place to save the return register on PPC, since both values */
+ /* with place to save the return register on PPC64, since both values */
/* reside in R3 */
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
/* reserve 2 slots for long/double return values for monitorexit */
-
- if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
- stackframesize += 3;
- else
- stackframesize += 2;
+ stackframesize += 2;
}
#endif
*/
if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_adds4(cd, (rd->memuse + 1) * 4); /* IsSync */
+ (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
else
#endif
(void) dseg_adds4(cd, 0); /* IsSync */
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
p = dseg_addaddress(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 */
codegen_add_nullpointerexception_ref(cd);
}
- M_AST(rd->argintregs[0], REG_SP, rd->memuse * 4);
+ M_AST(rd->argintregs[0], REG_SP, rd->memuse * 8);
M_JSR;
}
#endif
disp = dseg_addaddress(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_ALD(REG_ITMP1, REG_PV, disp);
switch (iptr->op1) {
case TYPE_INT:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_IST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_IST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_LST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_LST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_ADR:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_AST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_AST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_FLT:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_FST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_FST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_DBL:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_DST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_DST_INTERN(s1, REG_ITMP1, 0);
break;
}
break;
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
disp = dseg_addaddress(cd, LOCK_monitor_exit);
M_ALD(REG_ITMP3, REG_PV, disp);
+ M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(REG_ITMP3);
/* we need to save the proper return value */
switch (iptr->opc) {
case ICMD_LRETURN:
- /*M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8); FIXME*/
- /* fall through */
case ICMD_IRETURN:
case ICMD_ARETURN:
- M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
+ /* fall through */
+ M_LST(REG_RESULT , REG_SP, rd->memuse * 4 + 8);
break;
case ICMD_FRETURN:
- M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
break;
case ICMD_DRETURN:
- M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
break;
}
- M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 4);
+ M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
M_JSR;
/* and now restore the proper return value */
switch (iptr->opc) {
case ICMD_LRETURN:
- /*M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8); FIXME*/
- /* fall through */
case ICMD_IRETURN:
case ICMD_ARETURN:
- M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
+ /* fall through */
+ M_LLD(REG_RESULT , REG_SP, rd->memuse * 4 + 8);
break;
case ICMD_FRETURN:
- M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
break;
case ICMD_DRETURN:
- M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
break;
}
}
stackframesize =
sizeof(stackframeinfo) / SIZEOF_VOID_P +
sizeof(localref_table) / SIZEOF_VOID_P +
- 4 + /* 4 stackframeinfo arguments (darwin)*/
+ 4 + /* 4 stackframeinfo arguments (darwin)*/
nmd->paramcount +
nmd->memuse;
/* create method header */
(void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, stackframesize * 4); /* FrameSize */
+ (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
(void) dseg_adds4(cd, 0); /* IsSync */
(void) dseg_adds4(cd, 0); /* IsLeaf */
(void) dseg_adds4(cd, 0); /* IntSave */
M_MTCTR(REG_ITMP1);
M_JSR;
+ M_NOP;
+ M_NOP;
+ M_NOP;
+
/* restore integer and float argument registers */
j = 0;
M_MTCTR(REG_ITMP3);
M_JSR;
+ M_NOP;
+ M_NOP;
+ M_NOP;
+
/* save return value */
if (md->returntype.type != TYPE_VOID) {
/* remove native stackframe info */
+ M_NOP;
+ M_NOP;
+ M_NOP;
+
M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]);
disp = dseg_addaddress(cd, codegen_finish_native_call);
M_ALD(REG_ITMP1, REG_PV, disp);
M_ALD(REG_ZERO, REG_SP, stack_size + LA_LR_OFFSET);
M_MTLR(REG_ZERO);
M_LDA(REG_SP, REG_SP, stack_size);
+
+ /* mark trace code */
+ M_NOP;
}
/* emit_verbosecall_exit ******************************************************
codegendata *cd = jd->cd;
s4 disp;
+ /* mark trace code */
+ M_NOP;
+
M_MFLR(REG_ZERO);
M_LDA(REG_SP, REG_SP, -(LA_SIZE+PA_SIZE+10*8));
M_DST(REG_FRESULT, REG_SP, LA_SIZE+PA_SIZE+0*8);
M_ALD(REG_ZERO, REG_SP, LA_SIZE+PA_SIZE+2*8);
M_LDA(REG_SP, REG_SP, LA_SIZE+PA_SIZE+10*8);
M_MTLR(REG_ZERO);
+
+ /* mark trace code */
+ M_NOP;
}
Changes:
- $Id: md-abi.c 5232 2006-08-11 13:11:44Z tbfg $
+ $Id: md-abi.c 5316 2006-09-05 12:24:48Z tbfg $
*/
iarg = 0;
farg = 0;
- stacksize = LA_SIZE_IN_POINTERS;
+ stacksize = LA_SIZE_IN_POINTERS + PA_SIZE_IN_POINTERS;
/* get params field of methoddesc */
for (i = 0; i < md->paramcount; i++, pd++) {
switch (md->paramtypes[i].type) {
+ case TYPE_LNG:
case TYPE_INT:
case TYPE_ADR:
if (iarg < INT_ARG_CNT) {
stacksize++;
}
break;
- case TYPE_LNG:
- if (iarg < INT_ARG_CNT - 1) {
- _ALIGN(iarg);
- pd->inmemory = false;
- /* rd->arg[int|flt]regs index !! */
- pd->regoff = PACK_REGS(iarg + 1, iarg);
- iarg += 2;
- } else {
- _ALIGN(stacksize);
- pd->inmemory = true;
- pd->regoff = stacksize;
- iarg = INT_ARG_CNT;
- stacksize += 2;
- }
- break;
case TYPE_FLT:
if (farg < FLT_ARG_CNT) {
pd->inmemory = false;
/* Since R3/R4, F1 (==A0/A1, A0) are used for passing return values, this */
/* argument register usage has to be regarded, too */
if (IS_INT_LNG_TYPE(md->returntype.type)) {
- if (iarg < (IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1))
- iarg = IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1;
- } else {
- if (IS_FLT_DBL_TYPE(md->returntype.type))
- if (farg < 1)
- farg = 1;
+ if (iarg < 1)
+ iarg = 1;
+ } else if (IS_FLT_DBL_TYPE(md->returntype.type)) {
+ if (farg < 1)
+ farg = 1;
}
/* fill register and stack usage */
stackslot->flags = 0;
if (IS_INT_LNG_TYPE(md->returntype.type)) {
- if (!IS_2_WORD_TYPE(md->returntype.type)) {
- if (rd->argintreguse < 1)
- rd->argintreguse = 1;
-
- stackslot->regoff = REG_RESULT;
-
- } else {
- if (rd->argintreguse < 2)
- rd->argintreguse = 2;
-
- /* stackslot->regoff = PACK_REGS(REG_RESULT2, REG_RESULT); // FIXME */
- }
+ if (rd->argintreguse < 1)
+ rd->argintreguse = 1;
+ stackslot->regoff = REG_RESULT;
} else { /* float/double */
if (rd->argfltreguse < 1)
rd->argfltreguse = 1;
M_ALD(REG_ITMP1, REG_PV, disp);
switch (iptr->op1) {
case TYPE_INT:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_IST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_IST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_STX_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_STX_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_ADR:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_AST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_AST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_FLT:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_FST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_FST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_DBL:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_DST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_DST_INTERN(s1, REG_ITMP1, 0);
break;
}
break;