X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Farm%2Femit.c;h=26393f68ab8f16ba55431f5d6a83978229f13a29;hb=219e4a46e3d127d3c0883ee2e8635b4fe3c94d60;hp=ccd5e740245ab0a965269a2793a04eb384121263;hpb=58bac0a56dab7d6983a3cfbee7a9b7ffec5a4284;p=cacao.git diff --git a/src/vm/jit/arm/emit.c b/src/vm/jit/arm/emit.c index ccd5e7402..26393f68a 100644 --- a/src/vm/jit/arm/emit.c +++ b/src/vm/jit/arm/emit.c @@ -1,9 +1,7 @@ /* src/vm/jit/arm/emit.c - Arm code emitter functions - 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. @@ -22,8 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: emit.c 4398 2006-01-31 23:43:08Z twisti $ - */ @@ -42,16 +38,16 @@ #include "threads/lock-common.h" -#include "vm/builtin.h" -#include "vm/exceptions.h" #include "vm/global.h" #include "vm/jit/abi.h" #include "vm/jit/asmpart.h" -#include "vm/jit/emit-common.h" -#include "vm/jit/jit.h" -#include "vm/jit/patcher-common.h" -#include "vm/jit/replace.h" +#include "vm/jit/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/patcher-common.hpp" +#include "vm/jit/replace.hpp" +#include "vm/jit/trace.hpp" +#include "vm/jit/trap.h" #include "toolbox/logging.h" /* XXX for debugging only */ @@ -477,7 +473,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg) if (INSTRUCTION_MUST_CHECK(iptr)) { CHECK_INT_REG(reg); M_TEQ_IMM(reg, 0); - M_TRAPEQ(0, EXCEPTION_HARDWARE_ARITHMETIC); + M_TRAPEQ(0, TRAP_ArithmeticException); } } @@ -492,14 +488,14 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg) { if (INSTRUCTION_MUST_CHECK(iptr)) { M_TST(reg, reg); - M_TRAPEQ(0, EXCEPTION_HARDWARE_NULLPOINTER); + M_TRAPEQ(0, TRAP_NullPointerException); } } void emit_nullpointer_check_force(codegendata *cd, instruction *iptr, s4 reg) { M_TST(reg, reg); - M_TRAPEQ(0, EXCEPTION_HARDWARE_NULLPOINTER); + M_TRAPEQ(0, TRAP_NullPointerException); } @@ -512,9 +508,24 @@ void emit_nullpointer_check_force(codegendata *cd, instruction *iptr, s4 reg) void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2) { if (INSTRUCTION_MUST_CHECK(iptr)) { - M_ILD_INTERN(REG_ITMP3, s1, OFFSET(java_arrayheader, size)); + M_ILD_INTERN(REG_ITMP3, s1, OFFSET(java_array_t, size)); M_CMP(s2, REG_ITMP3); - M_TRAPHS(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS); + M_TRAPHS(s2, TRAP_ArrayIndexOutOfBoundsException); + } +} + + +/* emit_arraystore_check ******************************************************* + + Emit an ArrayStoreException check. + +*******************************************************************************/ + +void emit_arraystore_check(codegendata *cd, instruction *iptr) +{ + if (INSTRUCTION_MUST_CHECK(iptr)) { + M_TST(REG_RESULT, REG_RESULT); + M_TRAPEQ(0, TRAP_ArrayStoreException); } } @@ -530,15 +541,15 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r if (INSTRUCTION_MUST_CHECK(iptr)) { switch (condition) { case BRANCH_EQ: - M_TRAPEQ(s1, EXCEPTION_HARDWARE_CLASSCAST); + M_TRAPEQ(s1, TRAP_ClassCastException); break; case BRANCH_LE: - M_TRAPLE(s1, EXCEPTION_HARDWARE_CLASSCAST); + M_TRAPLE(s1, TRAP_ClassCastException); break; case BRANCH_UGT: - M_TRAPHI(s1, EXCEPTION_HARDWARE_CLASSCAST); + M_TRAPHI(s1, TRAP_ClassCastException); break; default: @@ -557,7 +568,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr) { if (INSTRUCTION_MUST_CHECK(iptr)) { M_TST(REG_RESULT, REG_RESULT); - M_TRAPEQ(0, EXCEPTION_HARDWARE_EXCEPTION); + M_TRAPEQ(0, TRAP_CHECK_EXCEPTION); } } @@ -575,9 +586,9 @@ uint32_t emit_trap(codegendata *cd) /* Get machine code which is patched back in later. The trap is 1 instruction word long. */ - mcode = *((u4 *) cd->mcodeptr); + mcode = *((uint32_t *) cd->mcodeptr); - M_TRAP(0, EXCEPTION_HARDWARE_PATCHER); + M_TRAP(0, TRAP_PATCHER); return mcode; } @@ -596,9 +607,8 @@ void emit_verbosecall_enter(jitdata *jd) codegendata *cd; registerdata *rd; methoddesc *md; - s4 stackframesize; s4 disp; - s4 i, t, s1, s2; + s4 i, s; /* get required compiler data */ @@ -608,87 +618,101 @@ void emit_verbosecall_enter(jitdata *jd) md = m->parseddesc; - /* stackframesize is changed below */ - - stackframesize = cd->stackframesize; - /* mark trace code */ M_NOP; - /* Save argument registers to stack (including LR and PV). Keep - stack 8-byte aligned. */ - - M_STMFD(BITMASK_ARGS | (1<paramcount - 1; - - if (i > 3) - i = 3; + /* Keep stack 8-byte aligned. */ - for (; i >= 0; i--) { - t = md->paramtypes[i].type; + M_STMFD((1<paramcount * 8); - /* load argument into register (s1) and make it of TYPE_LNG */ + /* save argument registers */ + for (i = 0; i < md->paramcount; i++) { if (!md->params[i].inmemory) { - s1 = md->params[i].regoff; + s = md->params[i].regoff; - if (!IS_2_WORD_TYPE(t)) { - M_MOV_IMM(REG_ITMP1, 0); - s1 = PACK_REGS(s1, REG_ITMP1); +#if defined(ENABLE_SOFTFLOAT) + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_FLT: + case TYPE_ADR: + M_IST(s, REG_SP, i * 8); + break; + case TYPE_LNG: + case TYPE_DBL: + M_LST(s, REG_SP, i * 8); + break; } - } - else { - s1 = REG_ITMP12_PACKED; - s2 = md->params[i].regoff + stackframesize; - - if (IS_2_WORD_TYPE(t)) - M_LLD(s1, REG_SP, s2); - else { - M_ILD(GET_LOW_REG(s1), REG_SP, s2); - M_MOV_IMM(GET_HIGH_REG(s1), 0); +#else + switch (md->paramtypes[i].type) { + case TYPE_ADR: + case TYPE_INT: + M_IST(s, REG_SP, i * 8); + break; + case TYPE_LNG: + M_LST(s, REG_SP, i * 8); + break; + case TYPE_FLT: + M_FST(s, REG_SP, i * 8); + break; + case TYPE_DBL: + M_DST(s, REG_SP, i * 8); + break; } - } - - /* place argument for tracer */ - - if (i < 2) { -#if defined(__ARMEL__) - s2 = PACK_REGS(abi_registers_integer_argument[i * 2], - abi_registers_integer_argument[i * 2 + 1]); -#else /* defined(__ARMEB__) */ - s2 = PACK_REGS(abi_registers_integer_argument[i * 2 + 1], - abi_registers_integer_argument[i * 2]); -#endif - M_LNGMOVE(s1, s2); - } - else { - s2 = (i - 2) * 2; - M_LST(s1, REG_SP, s2 * 4); +#endif } } - /* prepare methodinfo pointer for tracer */ - disp = dseg_add_address(cd, m); - M_DSEG_LOAD(REG_ITMP1, disp); - M_STR_INTERN(REG_ITMP1, REG_SP, 16); + M_DSEG_LOAD(REG_A0, disp); + M_MOV(REG_A1, REG_SP); + M_ADD_IMM(REG_A2, REG_SP, md->paramcount * 8 + 2 * 4 + cd->stackframesize); + M_LONGBRANCH(trace_java_call_enter); - /* call tracer here (we use a long branch) */ + /* restore argument registers */ - M_LONGBRANCH(builtin_verbosecall_enter); + for (i = 0; i < md->paramcount; i++) { + if (!md->params[i].inmemory) { + s = md->params[i].regoff; - /* Restore argument registers from stack. Keep stack 8-byte - aligned. */ +#if defined(ENABLE_SOFTFLOAT) + switch (md->paramtypes[i].type) { + case TYPE_INT: + case TYPE_FLT: + case TYPE_ADR: + M_ILD(s, REG_SP, i * 8); + break; + case TYPE_LNG: + case TYPE_DBL: + M_LLD(s, REG_SP, i * 8); + break; + } +#else + switch (md->paramtypes[i].type) { + case TYPE_ADR: + case TYPE_INT: + M_ILD(s, REG_SP, i * 8); + break; + case TYPE_LNG: + M_LLD(s, REG_SP, i * 8); + break; + case TYPE_FLT: + M_FLD(s, REG_SP, i * 8); + break; + case TYPE_DBL: + M_DLD(s, REG_SP, i * 8); + break; + } +#endif + } + } + + /* Keep stack 8-byte aligned. */ - M_ADD_IMM(REG_SP, REG_SP, (2 + 2 + 1 + 1) * 4); /* free argument stack */ - M_LDMFD(BITMASK_ARGS | (1<paramcount * 8); + M_LDMFD((1<returntype.type) { case TYPE_ADR: case TYPE_INT: - M_INTMOVE(REG_RESULT, GET_LOW_REG(REG_A0_A1_PACKED)); - M_MOV_IMM(GET_HIGH_REG(REG_A0_A1_PACKED), 0); + case TYPE_FLT: + M_IST(REG_RESULT, REG_SP, 0 * 8); break; - case TYPE_LNG: - M_LNGMOVE(REG_RESULT_PACKED, REG_A0_A1_PACKED); + case TYPE_DBL: + M_LST(REG_RESULT_PACKED, REG_SP, 0 * 8); break; + } + + disp = dseg_add_address(cd, m); + M_DSEG_LOAD(REG_A0, disp); + M_MOV(REG_A1, REG_SP); + M_LONGBRANCH(trace_java_call_exit); + /* restore return value */ + + switch (md->returntype.type) { + case TYPE_ADR: + case TYPE_INT: case TYPE_FLT: - M_IST(REG_RESULT, REG_SP, 0 * 4); + M_ILD(REG_RESULT, REG_SP, 0 * 8); break; - + case TYPE_LNG: case TYPE_DBL: - M_LNGMOVE(REG_RESULT_PACKED, REG_A2_A3_PACKED); + M_LLD(REG_RESULT_PACKED, REG_SP, 0 * 8); break; } - disp = dseg_add_address(cd, m); - M_DSEG_LOAD(REG_ITMP1, disp); - M_AST(REG_ITMP1, REG_SP, 1 * 4); - M_LONGBRANCH(builtin_verbosecall_exit); - /* Keep stack 8-byte aligned. */ - M_ADD_IMM(REG_SP, REG_SP, (1 + 1) * 4); /* free argument stack */ - M_LDMFD(BITMASK_RESULT | (1<