X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fpowerpc%2Fmd.c;h=ee362634644c1892e6b39e200a1c569b3dc79b7d;hb=e72c835d82fb165a91cbd1d16d2b8c56cc67e389;hp=3e0ec2e7fee3efe60406bc3167cd52165bf2e04b;hpb=7be877e61760c8f9314abbfb152b62f05f270273;p=cacao.git diff --git a/src/vm/jit/powerpc/md.c b/src/vm/jit/powerpc/md.c index 3e0ec2e7f..ee3626346 100644 --- a/src/vm/jit/powerpc/md.c +++ b/src/vm/jit/powerpc/md.c @@ -1,9 +1,8 @@ /* src/vm/jit/powerpc/md.c - machine dependent PowerPC 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 + Copyright (C) 2009 Theobroma Systems Ltd. This file is part of CACAO. @@ -22,29 +21,25 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: md.c 7968 2007-05-25 15:05:04Z twisti $ - */ #include "config.h" #include +#include #include "vm/types.h" #include "md-abi.h" #include "vm/jit/powerpc/codegen.h" +#include "vm/jit/powerpc/md.h" #include "vm/global.h" +#include "vm/vm.hpp" -#include "vm/jit/asmpart.h" -#include "vm/jit/stacktrace.h" - -#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) -# include "vm/jit/disass.h" /* XXX debug */ -# include "vmcore/options.h" /* XXX debug */ -#endif +#include "vm/jit/jit.hpp" +#include "vm/jit/trap.hpp" /* md_init ********************************************************************* @@ -59,26 +54,7 @@ void md_init(void) } -/* md_stacktrace_get_returnaddress ********************************************* - - Returns the return address of the current stackframe, specified by - the passed stack pointer and the stack frame size. - -*******************************************************************************/ - -u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize) -{ - u1 *ra; - - /* on PowerPC the return address is located in the linkage area */ - - ra = *((u1 **) (sp + framesize + LA_LR_OFFSET)); - - return ra; -} - - -/* md_get_method_patch_address ************************************************* +/* md_jit_method_patch_address ************************************************* Gets the patch address of the currently compiled method. The offset is extracted from the load instruction(s) before the jump and added @@ -107,19 +83,20 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize) *******************************************************************************/ -u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr) +void *md_jit_method_patch_address(void *pv, void *ra, void *mptr) { - u4 mcode; - s4 offset; - u1 *pa; + uint32_t *pc; + uint32_t mcode; + int32_t offset; + void *pa; /* go back to the actual load instruction (3 instructions) */ - ra = ra - 3 * 4; + pc = ((uint32_t *) ra) - 3; /* get first instruction word (lwz) */ - mcode = *((u4 *) ra); + mcode = *pc; /* check if we have 2 instructions (addis, addi) */ @@ -130,27 +107,27 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr) /* get displacement of first instruction (addis) */ - offset = (s4) (mcode << 16); + offset = (int32_t) (mcode << 16); /* get displacement of second instruction (addi) */ - mcode = *((u4 *) (ra + 1 * 4)); + mcode = *(pc + 1); assert((mcode >> 16) != 0x6739); - offset += (s2) (mcode & 0x0000ffff); + offset += (int16_t) (mcode & 0x0000ffff); } else { /* get the offset from the instruction */ - offset = (s2) (mcode & 0x0000ffff); + offset = (int16_t) (mcode & 0x0000ffff); /* check for load from PV */ if ((mcode >> 16) == 0x81ad) { /* get the final data segment address */ - pa = sfi->pv + offset; + pa = ((uint8_t *) pv) + offset; } else if ((mcode >> 16) == 0x81ac) { /* in this case we use the passed method pointer */ @@ -160,12 +137,12 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr) if (mptr == NULL) return NULL; - pa = mptr + offset; + pa = ((uint8_t *) mptr) + offset; } else { /* catch any problems */ - vm_abort("md_get_method_patch_address: unknown instruction %x", + vm_abort("md_jit_method_patch_address: unknown instruction %x", mcode); /* keep compiler happy */ @@ -178,100 +155,69 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr) } -/* md_codegen_get_pv_from_pc *************************************************** - - Machine code: - - 7d6802a6 mflr r11 - 39abffe0 addi r13,r11,-32 - - or - - 7d6802a6 mflr r11 - 3dabffff addis r13,r11,-1 - 39ad68b0 addi r13,r13,26800 - -*******************************************************************************/ - -u1 *md_codegen_get_pv_from_pc(u1 *ra) +/** + * Decode the trap instruction at the given PC. + * + * @param trp information about trap to be filled + * @param sig signal number + * @param xpc exception PC + * @param es execution state of the machine + * @return true if trap was decoded successfully, false otherwise. + */ +bool md_trap_decode(trapinfo_t* trp, int sig, void* xpc, executionstate_t* es) { - u1 *pv; - u4 mcode; - s4 offset; - - /* get first instruction word after jump */ - - mcode = *((u4 *) (ra + 1 * 4)); - - /* check if we have 2 instructions (addis, addi) */ - - if ((mcode >> 16) == 0x3dab) { - /* get displacement of first instruction (addis) */ - - offset = (s4) (mcode << 16); - - /* get displacement of second instruction (addi) */ - - mcode = *((u4 *) (ra + 2 * 4)); - - /* check for addi instruction */ - - assert((mcode >> 16) == 0x39ad); - - offset += (s2) (mcode & 0x0000ffff); - - } else { - /* check for addi instruction */ - - assert((mcode >> 16) == 0x39ab); + // Get the exception-throwing instruction. + uint32_t mcode = *((uint32_t*) xpc); + + switch (sig) { + case TRAP_SIGILL: + // Check for valid trap instruction. + if (patcher_is_valid_trap_instruction_at(xpc)) { + trp->type = TRAP_PATCHER; + trp->value = 0; + return true; + } + return false; - /* get offset of first instruction (addi) */ + case TRAP_SIGTRAP: + { + int s1 = M_OP3_GET_A(mcode); - offset = (s2) (mcode & 0x0000ffff); + // For now we only handle ArrayIndexOutOfBoundsException. + trp->type = TRAP_ArrayIndexOutOfBoundsException; + trp->value = es->intregs[s1]; + return true; } - /* calculate PV via RA + offset */ - - pv = ra + offset; - - return pv; -} - - -/* md_cacheflush *************************************************************** - - Calls the system's function to flush the instruction and data - cache. - -*******************************************************************************/ - -void md_cacheflush(u1 *addr, s4 nbytes) -{ - asm_cacheflush(addr, nbytes); -} - - -/* md_icacheflush ************************************************************** - - Calls the system's function to flush the instruction cache. - -*******************************************************************************/ - -void md_icacheflush(u1 *addr, s4 nbytes) -{ - asm_cacheflush(addr, nbytes); -} - - -/* md_dcacheflush ************************************************************** + case TRAP_SIGSEGV: + { + int s1 = M_INSTR_OP2_IMM_A(mcode); + uintptr_t addr = es->intregs[s1]; + + // Check for special-load. + if (s1 == REG_ZERO) { + int16_t disp = M_INSTR_OP2_IMM_I(mcode); + int d = M_INSTR_OP2_IMM_D(mcode); + + // We use the exception type as load displacement. + trp->type = disp; + trp->value = es->intregs[d]; + return true; + } - Calls the system's function to flush the data cache. + // Check for implicit NullPointerException. + if (addr == 0) { + trp->type = TRAP_NullPointerException; + trp->value = 0; + return true; + } -*******************************************************************************/ + return false; + } -void md_dcacheflush(u1 *addr, s4 nbytes) -{ - asm_cacheflush(addr, nbytes); + default: + return false; + } } @@ -282,43 +228,32 @@ void md_dcacheflush(u1 *addr, s4 nbytes) *******************************************************************************/ #if defined(ENABLE_REPLACEMENT) -void md_patch_replacement_point(codeinfo *code, s4 index, rplpoint *rp, u1 *savedmcode) +void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert) { - s4 disp; u4 mcode; - if (index < 0) { + if (revert) { /* restore the patched-over instruction */ - *(u4*)(rp->pc) = *(u4*)(savedmcode); + *(u4*)(pc) = *(u4*)(savedmcode); } else { /* save the current machine code */ - *(u4*)(savedmcode) = *(u4*)(rp->pc); + *(u4*)(savedmcode) = *(u4*)(pc); - /* build the machine code for the patch */ - disp = ((u4*)code->replacementstubs - (u4*)rp->pc) - + index * REPLACEMENT_STUB_SIZE - - 1; - - mcode = (18 << 26) | ((((disp) * 4) + 4) & M_BMASK); + // Build the machine code for the patch. On PowerPC we use + // an illegal instruction which really is just 0, believe me! + mcode = 0; /* write the new machine code */ - *(u4*)(rp->pc) = (u4) mcode; + *(u4*)(pc) = (u4) mcode; } -#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) && 0 - { - u1* u1ptr = rp->pc; - DISASSINSTR(u1ptr); - fflush(stdout); - } -#endif - /* flush instruction cache */ - md_icacheflush(rp->pc,4); + md_icacheflush(pc,4); } #endif /* defined(ENABLE_REPLACEMENT) */ + /* * 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