X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Falpha%2Fmd.c;h=125ff089211127a14b9eeb2db0d541ecc0e209fd;hb=3a349bb476c3a52fa3271f8582488efb2c9aec20;hp=dc0e6d5081c11c79d0c9fbe69f40025d09829877;hpb=04814e29ad09d4e2ffa70fcf2b1d9dd588054e7a;p=cacao.git diff --git a/src/vm/jit/alpha/md.c b/src/vm/jit/alpha/md.c index dc0e6d508..125ff0892 100644 --- a/src/vm/jit/alpha/md.c +++ b/src/vm/jit/alpha/md.c @@ -1,9 +1,9 @@ /* src/vm/jit/alpha/md.c - machine dependent Alpha functions - Copyright (C) 1996-2005 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 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 This file is part of CACAO. @@ -19,35 +19,37 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. - - Contact: cacao@complang.tuwien.ac.at - - Authors: Andreas Krall - Reinhard Grafl - - Changes: Joseph Wenninger - Christian Thalinger - - $Id: md.c 2992 2005-07-11 21:52:07Z twisti $ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ +#include "config.h" + #include +#include #include -#include "config.h" +#if defined(__LINUX__) +# include -#include "vm/jit/alpha/asmoffsets.h" -#include "vm/jit/alpha/md-abi.h" -#include "vm/jit/alpha/types.h" +extern unsigned long ieee_get_fp_control(); +extern void ieee_set_fp_control(unsigned long fp_control); +#endif + +#include "vm/jit/alpha/codegen.h" +#include "vm/jit/alpha/md.h" #include "vm/exceptions.h" -#include "vm/stringlocal.h" + #include "vm/jit/asmpart.h" -#include "vm/jit/stacktrace.h" +#include "vm/jit/jit.h" + + +/* global variables ***********************************************************/ + +bool has_ext_instr_set = false; /* has instruction set extensions */ /* md_init ********************************************************************* @@ -58,153 +60,169 @@ void md_init(void) { -#if 0 - /* XXX TWISTI: do we really need this? fptest's seem to work fine */ - #if defined(__LINUX__) -/* Linux on Digital Alpha needs an initialisation of the ieee floating point - control for IEEE compliant arithmetic (option -mieee of GCC). Under - Digital Unix this is done automatically. -*/ + unsigned long int fpcw; +#endif -#include + /* check for extended instruction set */ -extern unsigned long ieee_get_fp_control(); -extern void ieee_set_fp_control(unsigned long fp_control); + has_ext_instr_set = !asm_md_init(); - /* initialize floating point control */ +#if defined(__LINUX__) + /* Linux on Digital Alpha needs an initialisation of the ieee + floating point control for IEEE compliant arithmetic (option + -mieee of GCC). Under Digital Unix this is done + automatically. */ - ieee_set_fp_control(ieee_get_fp_control() - & ~IEEE_TRAP_ENABLE_INV - & ~IEEE_TRAP_ENABLE_DZE -/* & ~IEEE_TRAP_ENABLE_UNF we dont want underflow */ - & ~IEEE_TRAP_ENABLE_OVF); -#endif -#endif + /* initialize floating point control */ - /* nothing to do */ -} + fpcw = ieee_get_fp_control(); + fpcw = fpcw + & ~IEEE_TRAP_ENABLE_INV + & ~IEEE_TRAP_ENABLE_DZE + /* We dont want underflow. */ +/* & ~IEEE_TRAP_ENABLE_UNF */ + & ~IEEE_TRAP_ENABLE_OVF; -/* signal_handler_sigsegv ****************************************************** +/* fpcw = fpcw */ +/* | IEEE_TRAP_ENABLE_INV */ +/* | IEEE_TRAP_ENABLE_DZE */ +/* | IEEE_TRAP_ENABLE_OVF */ +/* | IEEE_TRAP_ENABLE_UNF */ +/* | IEEE_TRAP_ENABLE_INE */ +/* | IEEE_TRAP_ENABLE_DNO; */ - NullPointerException signal handler for hardware null pointer check. + ieee_set_fp_control(fpcw); +#endif +} -*******************************************************************************/ -void signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) -{ - ucontext_t *_uc; - mcontext_t *_mc; - u4 instr; - ptrint addr; - u1 *pv; - u1 *sp; - functionptr ra; - functionptr xpc; - - _uc = (ucontext_t *) _p; - _mc = &_uc->uc_mcontext; - - instr = *((s4 *) (_mc->sc_pc)); - addr = _mc->sc_regs[(instr >> 16) & 0x1f]; - - if (addr == 0) { - pv = (u1 *) _mc->sc_regs[REG_PV]; - sp = (u1 *) _mc->sc_regs[REG_SP]; - ra = (functionptr) _mc->sc_regs[REG_RA]; /* this is correct for leafs*/ - xpc = (functionptr) _mc->sc_pc; - - _mc->sc_regs[REG_ITMP1_XPTR] = - (ptrint) stacktrace_hardware_nullpointerexception(pv, sp, ra, xpc); - - _mc->sc_regs[REG_ITMP2_XPC] = (ptrint) xpc; - _mc->sc_pc = (ptrint) asm_handle_exception; - - } else { - addr += (long) ((instr << 16) >> 16); - - throw_cacao_exception_exit(string_java_lang_InternalError, - "Segmentation fault: 0x%016lx at 0x%016lx\n", - addr, _mc->sc_pc); - } -} +/* 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 + to the right base address (PV or REG_METHODPTR). -#if defined(USE_THREADS) && defined(NATIVE_THREADS) -void thread_restartcriticalsection(ucontext_t *uc) -{ - void *critical; + INVOKESTATIC/SPECIAL: - critical = thread_checkcritical((void *) uc->uc_mcontext.sc_pc); + a77bffb8 ldq pv,-72(pv) + 6b5b4000 jsr (pv) - if (critical) - uc->uc_mcontext.sc_pc = (ptrint) critical; -} -#endif + INVOKEVIRTUAL: + a7900000 ldq at,0(a0) + a77c0000 ldq pv,0(at) + 6b5b4000 jsr (pv) -/* md_stacktrace_get_returnaddress ********************************************* + INVOKEINTERFACE: - Returns the return address of the current stackframe, specified by - the passed stack pointer and the stack frame size. + a7900000 ldq at,0(a0) + a79cff98 ldq at,-104(at) + a77c0018 ldq pv,24(at) + 6b5b4000 jsr (pv) *******************************************************************************/ -functionptr md_stacktrace_get_returnaddress(u1 *sp, u4 framesize) +void *md_jit_method_patch_address(void *pv, void *ra, void *mptr) { - functionptr ra; + uint32_t *pc; + uint32_t mcode; + int opcode; + int base; + int32_t disp; + void *pa; /* patch address */ - /* on Alpha the return address is located on the top of the stackframe */ + /* Go back to the load instruction (2 instructions). */ - ra = (functionptr) *((u1 **) (sp + framesize - SIZEOF_VOID_P)); + pc = ((uint32_t *) ra) - 2; - return ra; -} + /* Get first instruction word. */ + mcode = pc[0]; -/* codegen_findmethod ********************************************************** + /* Get opcode, base register and displacement. */ - Machine code: + opcode = M_MEM_GET_Opcode(mcode); + base = M_MEM_GET_Rb(mcode); + disp = M_MEM_GET_Memory_disp(mcode); - 6b5b4000 jsr (pv) - 237affe8 lda pv,-24(ra) + /* Check for short or long load (2 instructions). */ -*******************************************************************************/ + switch (opcode) { + case 0x29: /* LDQ: TODO use define */ + switch (base) { + case REG_PV: + /* Calculate the data segment address. */ -functionptr codegen_findmethod(functionptr pc) -{ - u1 *ra; - u1 *pv; - u4 mcode; - s2 offset; + pa = ((uint8_t *) pv) + disp; + break; + + case REG_METHODPTR: + /* Return NULL if no mptr was specified (used for + replacement). */ + + if (mptr == NULL) + return NULL; + + /* Calculate the address in the vftbl. */ - ra = (u1 *) pc; - pv = ra; + pa = ((uint8_t *) mptr) + disp; + break; - /* get offset of first instruction (lda) */ + default: + vm_abort_disassemble(pc, 2, "md_jit_method_patch_address: unknown instruction %x", mcode); + return NULL; + } + break; - mcode = *((u4 *) ra); + case 0x09: /* LDAH: TODO use define */ + /* XXX write a regression for this */ - if ((mcode >> 16) != 0x237a) { - log_text("No `lda pv,x(ra)' instruction found on return address!"); - assert(0); + vm_abort("md_jit_method_patch_address: IMPLEMENT ME!"); + + pa = NULL; + break; + + default: + vm_abort_disassemble(pc, 2, "md_jit_method_patch_address: unknown instruction %x", mcode); + return NULL; } - offset = (s2) (mcode & 0x0000ffff); - pv += offset; + return pa; +} + + +/* md_patch_replacement_point ************************************************** - /* check for second instruction (ldah) */ + Patch the given replacement point. - mcode = *((u4 *) (ra + 1 * 4)); +*******************************************************************************/ - if ((mcode >> 16) == 0x177b) { - offset = (s2) (mcode << 16); - pv += offset; +#if defined(ENABLE_REPLACEMENT) +void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert) +{ + u4 mcode; + + if (revert) { + /* restore the patched-over instruction */ + *(u4*)(pc) = *(u4*)(savedmcode); } + else { + /* save the current machine code */ + *(u4*)(savedmcode) = *(u4*)(pc); + + /* build the machine code for the patch */ + mcode = (0xa41f0000 | (EXCEPTION_HARDWARE_PATCHER)); - return (functionptr) pv; + /* write the new machine code */ + *(u4*)(pc) = mcode; + } + + /* flush instruction cache */ + md_icacheflush(pc,4); } +#endif /* defined(ENABLE_REPLACEMENT) */ /* @@ -218,4 +236,5 @@ functionptr codegen_findmethod(functionptr pc) * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */