X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fvm%2Fjit%2Fm68k%2Femit.c;h=f0e3e5fbe7537981ad48419175ff565d6e923e6c;hb=23a3859cc1442012273e1a77e44ca2ac985aac5e;hp=f835e3f10c1f5cb56a1e1b334bc67cdfa1df46fc;hpb=9fff6661011f3d45d707b2e3283aa938816c7e2f;p=cacao.git diff --git a/src/vm/jit/m68k/emit.c b/src/vm/jit/m68k/emit.c index f835e3f10..f0e3e5fbe 100644 --- a/src/vm/jit/m68k/emit.c +++ b/src/vm/jit/m68k/emit.c @@ -1,9 +1,7 @@ /* src/vm/jit/m68k/emit.c - 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: arch.h 5330 2006-09-05 18:43:12Z edwin $ - */ @@ -31,22 +27,24 @@ #include -#include "emit.h" -#include "vm/jit/emit-common.h" -#include "vm/exceptions.h" -#include "vm/jit/asmpart.h" -#include "vm/builtin.h" +#include "vm/jit/m68k/codegen.h" +#include "vm/jit/m68k/emit.h" -#include "mm/memory.h" +#include "mm/memory.hpp" -#include "threads/lock-common.h" +#include "vm/jit/builtin.hpp" -#include "codegen.h" -#include "md-os.h" +#include "vm/jit/asmpart.h" +#include "vm/jit/emit-common.hpp" +#include "vm/jit/trace.hpp" +#include "vm/jit/trap.hpp" -/* - * Loads an immededat operand into data register - */ + +/* emit_mov_imm_reg ************************************************************************** + * + * Loads an immededat operand into an integer data register + * + ********************************************************************************************/ void emit_mov_imm_reg (codegendata *cd, s4 imm, s4 dreg) { /* FIXME: -1 can be used as byte form 0xff, but this ifs cascade is plain wrong it seems */ @@ -69,7 +67,6 @@ void emit_mov_imm_reg (codegendata *cd, s4 imm, s4 dreg) } } - /* emit_copy ******************************************************************* Generates a register/memory to register/memory copy. @@ -149,7 +146,7 @@ void emit_copy(jitdata *jd, instruction *iptr) *******************************************************************************/ -inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d) +void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d) { codegendata *cd; @@ -165,23 +162,23 @@ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d) case TYPE_DBL: #endif case TYPE_LNG: - M_LST(d, REG_SP, dst->vv.regoff * 4); + M_LST(d, REG_SP, dst->vv.regoff); break; #if defined(ENABLE_SOFTFLOAT) case TYPE_FLT: #endif case TYPE_INT: - M_IST(d, REG_SP, dst->vv.regoff * 4); + M_IST(d, REG_SP, dst->vv.regoff); break; case TYPE_ADR: - M_AST(d, REG_SP, dst->vv.regoff * 4); + M_AST(d, REG_SP, dst->vv.regoff); break; #if !defined(ENABLE_SOFTFLOAT) case TYPE_DBL: - M_DST(d, REG_SP, dst->vv.regoff * 4); + M_DST(d, REG_SP, dst->vv.regoff); break; case TYPE_FLT: - M_FST(d, REG_SP, dst->vv.regoff * 4); + M_FST(d, REG_SP, dst->vv.regoff); break; #endif default: @@ -210,7 +207,7 @@ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) if (IS_INMEMORY(src->flags)) { COUNT_SPILLS; - disp = src->vv.regoff * 4; + disp = src->vv.regoff; switch (src->type) { #if defined(ENABLE_SOFTFLOAT) @@ -263,79 +260,6 @@ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) return reg; } - -/* emit_patcher_stubs ********************************************************** - - Generates the code for the patcher stubs. - -*******************************************************************************/ -void emit_patcher_stubs(jitdata *jd) -{ - codegendata *cd; - patchref *pref; - u8 mcode; - u1 *savedmcodeptr; - u1 *tmpmcodeptr; - s4 targetdisp; - s4 disp; - - /* get required compiler data */ - - cd = jd->cd; - - /* generate code patching stub call code */ - - targetdisp = 0; - - for (pref = cd->patchrefs; pref != NULL; pref = pref->next) { - /* check code segment size */ - - MCODECHECK(512); - - /* Get machine code which is patched back in later. A - `bsr.l' is 6 bytes long. */ - - savedmcodeptr = cd->mcodebase + pref->branchpos; - mcode = *((u8 *) savedmcodeptr); - - /* patch in `bsr.l' to call the following code */ - - tmpmcodeptr = cd->mcodeptr; /* save current mcodeptr */ - cd->mcodeptr = savedmcodeptr; /* set mcodeptr to patch position */ - - M_BSR_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE) + 4); - - cd->mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */ - - /* save REG_ITMP3 */ - M_IPUSH(REG_ITMP3); /* FIXME why, and restore where ? */ - - /* move pointer to java_objectheader onto stack */ - -#if defined(ENABLE_THREADS) - (void) dseg_add_unique_address(cd, NULL); /* flcword */ - (void) dseg_add_unique_address(cd, lock_get_initial_lock_word()); - disp = dseg_add_unique_address(cd, NULL); /* vftbl */ - - assert(0); /* The next lines are wrong */ - M_MOV_IMM(0, REG_ITMP3); - dseg_adddata(cd); - M_AADD_IMM(REG_ITMP3, disp); - M_IPUSH(REG_ITMP3); -#else - M_IPUSH_IMM(0); -#endif - - /* push move machine code bytes and classinfo pointer */ - - M_IPUSH_IMM(mcode >> 32); - M_IPUSH_IMM(mcode); - M_IPUSH_IMM(pref->ref); - M_IPUSH_IMM(pref->patcher); - - M_JMP_IMM(asm_patcher_wrapper); - } -} s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) { codegendata *cd; @@ -354,7 +278,7 @@ s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) if (IS_INMEMORY(src->flags)) { COUNT_SPILLS; - disp = src->vv.regoff * 4; + disp = src->vv.regoff; M_ILD(tempreg, REG_SP, disp + 4); reg = tempreg; } else { @@ -378,7 +302,7 @@ s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) if (IS_INMEMORY(src->flags)) { COUNT_SPILLS; - disp = src->vv.regoff * 4; + disp = src->vv.regoff; M_ILD(tempreg, REG_SP, disp); reg = tempreg; } else { @@ -493,8 +417,6 @@ void emit_verbosecall_enter(jitdata* jd) codegendata *cd; registerdata *rd; methoddesc *md; - s4 disp,i,t; - if (!JITDATA_HAS_FLAG_VERBOSECALL(jd)) return; @@ -508,55 +430,38 @@ void emit_verbosecall_enter(jitdata* jd) /* mark trace code */ M_NOP; - M_LINK(REG_FP, -16*4); - M_PUSHALL; + M_IPUSH(REG_D0); + M_IPUSH(REG_D1); + M_APUSH(REG_A0); + M_APUSH(REG_A1); + M_AMOV(REG_SP, REG_A0); /* simpyfy stack offset calculation */ - /* builtin_verbosecall_enter takes all args as s8 type */ - /* TRACE_ARGS_NUM is the number of args the builtin_verbosecall_enter expects */ - M_IPUSH_IMM(m); +#if !defined(ENABLE_SOFTFLOAT) + M_AADD_IMM(-8*2, REG_SP); + M_FSTORE(REG_F0, REG_SP, 8); + M_FSTORE(REG_F1, REG_SP, 0); +#endif + + M_AADD_IMM(4*4 + 4, REG_A0); + M_APUSH(REG_A0); /* third arg is original argument stack */ + M_IPUSH_IMM(0); /* second arg is number of argument registers (=0) */ + M_IPUSH_IMM(m); /* first arg is methodpointer */ - disp = 16*4 + 4 + 4; /* points to old argument stack initially */ + M_JSR_IMM(trace_java_call_enter); + /* pop arguments off stack */ + M_AADD_IMM(3*4, REG_SP); - /* travel up stack to the first argument of the function which needs to be copied */ - for (i=0; (i < md->paramcount) && (i < TRACE_ARGS_NUM); i++) { - disp += 4; - if (IS_2_WORD_TYPE(md->paramtypes[i].type)) { - disp += 4; - } - } +#if !defined(ENABLE_SOFTFLOAT) + M_FSTORE(REG_F1, REG_SP, 0); + M_FSTORE(REG_F0, REG_SP, 8); + M_AADD_IMM(8*2, REG_SP); +#endif - /* disp now points to the first arg which gets copied to the trace stack, relative to REG_SP! */ - for (i=TRACE_ARGS_NUM-1; i>=0; --i) { - if (i < md->paramcount) { - /* traced function has such an argument */ - t = md->paramtypes[i].type; - - if (IS_2_WORD_TYPE(t)) { - /* copy from original argument stack */ - M_ILD(REG_ITMP1, REG_SP, disp); - M_IPUSH(REG_ITMP1); - M_ILD(REG_ITMP1, REG_SP, disp); - M_IPUSH(REG_ITMP1); - } else { - /* displacment is increased as 4 byte on original stack but 8 byte on trace stack */ - M_ILD(REG_ITMP1, REG_SP, disp); - M_IPUSH(REG_ITMP1); - M_IPUSH_IMM(0); - disp += 4; - } - } else { - /* function has no arg here, push nothing and adapt displacement */ - M_IPUSH_IMM(0); - M_IPUSH_IMM(0); - disp += 8; - } - } - M_JSR_IMM(builtin_verbosecall_enter); - /* pop arguments off stack */ - M_AADD_IMM(TRACE_ARGS_NUM*8+4, REG_SP); + M_APOP(REG_A1); + M_APOP(REG_A0); + M_IPOP(REG_D1); + M_IPOP(REG_D0); - M_POPALL; - M_UNLK(REG_FP); M_NOP; } void emit_verbosecall_exit(jitdata* jd) @@ -577,39 +482,78 @@ void emit_verbosecall_exit(jitdata* jd) /* void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m); */ + /* void trace_java_call_exit(methodinfo *m, uint64_t *return_regs) */ /* mark trace code */ M_NOP; - M_LINK(REG_FP, 0); - M_IPUSH_IMM(m); /* push methodinfo */ + /* to store result on stack */ + M_AADD_IMM(-8, REG_SP); /* create space for array */ + + switch (md->returntype.type) { + case TYPE_ADR: + case TYPE_INT: + #if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: + #endif + M_IST(REG_D0, REG_SP, 0); + break; - M_IPUSH_IMM(0); /* TODO push float result */ + case TYPE_LNG: + #if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: + #endif + M_LST(REG_D1, REG_SP, 0); + break; - M_IPUSH_IMM(0); /* TODO push double result */ - M_IPUSH_IMM(0); /* TODO push double result */ + #if !defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: /* FIXME */ + case TYPE_DBL: /* FIXME */ + #endif - M_IPUSH(GET_HIGH_REG(REG_RESULT_PACKED)) - M_IPUSH(GET_LOW_REG(REG_RESULT_PACKED)) /* push long result */ + case TYPE_VOID: /* nothing */ + break; + default: + assert(0); + } - M_JSR_IMM(builtin_verbosecall_exit); + M_APUSH(REG_SP); /* push address of array */ + M_IPUSH_IMM(m); /* push methodinfo */ + M_JSR_IMM(trace_java_call_exit); + M_AADD_IMM(8, REG_SP); /* remove args */ /* poping result registers from stack */ - M_IPOP(GET_LOW_REG(REG_RESULT_PACKED)) - M_IPOP(GET_HIGH_REG(REG_RESULT_PACKED)) + switch (md->returntype.type) { + case TYPE_ADR: + case TYPE_INT: + #if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: + #endif + M_ILD(REG_D0, REG_SP, 0); + break; -#if 0 - /* that is wrong of course, overwrites registers and stuff */ - M_IPOP(0); /* TODO: pop double result */ - M_IPOP(0); /* TODO: pop double result */ + case TYPE_LNG: + #if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: + #endif + M_LLD(REG_D1, REG_SP, 0); + break; + + #if !defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: /* FIXME */ + case TYPE_DBL: /* FIXME */ + #endif + + case TYPE_VOID: /* nothing */ + break; + + default: + assert(0); + } + + M_AADD_IMM(8, REG_SP); /* remove space for array */ - M_IPOP(0); /* TODO: pop float result */ -#else - M_AADD_IMM(3*4, REG_SP); -#endif - M_AADD_IMM(4, REG_SP); /* remove rest of stack */ - M_UNLK(REG_FP); M_NOP; } #endif @@ -640,7 +584,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r vm_abort("emit_classcast_check: unknown condition %d", condition); } M_TRAP_SETREGISTER(s1); - M_TRAP(EXCEPTION_HARDWARE_CLASSCAST); + M_TRAP(TRAP_ClassCastException); } } @@ -652,26 +596,45 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r 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_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size)); M_ICMP(s2, REG_ITMP3); M_BHI(4); M_TRAP_SETREGISTER(s2); - M_TRAP(EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS); + M_TRAP(TRAP_ArrayIndexOutOfBoundsException); } } + +/* emit_arraystore_check ******************************************************* + + Emit an ArrayStoreException check. + +*******************************************************************************/ + +void emit_arraystore_check(codegendata *cd, instruction *iptr) +{ + if (INSTRUCTION_MUST_CHECK(iptr)) { + M_ITST(REG_RESULT); + M_BNE(2); + M_TRAP(TRAP_ArrayStoreException); + } +} + + /* emit_nullpointer_check ****************************************************** Emit a NullPointerException check. *******************************************************************************/ + void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg) { if (INSTRUCTION_MUST_CHECK(iptr)) { - /* did like to assert on TYPE_ADR, but not possible in here */ + /* XXX: this check is copied to call monitor_enter + * invocation at the beginning of codegen.c */ M_ATST(reg); M_BNE(2); - M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER); + M_TRAP(TRAP_NullPointerException); } } @@ -686,43 +649,59 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg) if (INSTRUCTION_MUST_CHECK(iptr)) { M_ITST(reg); M_BNE(2); - M_TRAP(EXCEPTION_HARDWARE_ARITHMETIC); + M_TRAP(TRAP_ArithmeticException); } } -#if 0 -/* emit_exception_check_areg ************************************************** - * - Emit an Exception check, tested register is address REG_RESULT +/* emit_exception_check_ireg ************************************************** + + Emit an Exception check. Teste register is integer REG_RESULT *******************************************************************************/ -void emit_exception_check_areg(codegendata *cd, instruction *iptr) +void emit_exception_check(codegendata *cd, instruction *iptr) { if (INSTRUCTION_MUST_CHECK(iptr)) { - M_ATST(REG_RESULT); + M_ITST(REG_RESULT); M_BNE(2); - /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);*/ - M_ILLEGAL; /*FIXME*/ + M_TRAP(TRAP_CHECK_EXCEPTION); } } -#endif -/* emit_exception_check_ireg ************************************************** +/* emit_trap_compiler ********************************************************** - Emit an Exception check. Teste register is integer REG_RESULT + Emit a trap instruction which calls the JIT compiler. *******************************************************************************/ -void emit_exception_check(codegendata *cd, instruction *iptr) + +void emit_trap_compiler(codegendata *cd) { - if (INSTRUCTION_MUST_CHECK(iptr)) { - M_ITST(REG_RESULT); - M_BNE(2); - /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);*/ - M_TRAP(EXCEPTION_HARDWARE_EXCEPTION); - } + M_TRAP_SETREGISTER(REG_METHODPTR); + M_TRAP(TRAP_COMPILER); +} + + +/* emit_trap ******************************************************************* + + Emit a trap instruction and return the original machine code. + +*******************************************************************************/ + +uint32_t emit_trap(codegendata *cd) +{ + uint32_t mcode; + + /* Get machine code which is patched back in later. The + trap is 2 bytes long. */ + + mcode = *((uint32_t *) cd->mcodeptr); + + M_TRAP(TRAP_PATCHER); + + return mcode; } + /* * 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