* src/vm/jit/Makefile.am (noinst_HEADERS): Removed md.h.
* src/vm/jit/asmpart.h (md_asm_codegen_get_pv_from_pc): Added
temporarily.
* src/vm/jit/codegen-common.c (md.h): Added.
(vm/jit/md.h): Removed.
(md_asm_codegen_get_pv_from_pc): Added temporarily.
* src/vm/jit/codegen-common.h (md_codegen_get_pv_from_pc): Removed.
* src/vm/jit/jit.c (stdint.h): Added.
(md.h): Likewise.
* src/vm/jit/patcher-common.c (md.h): Added.
(vm/jit/md.h): Removed.
* src/vm/jit/replace.c: Likewise.
* src/vm/jit/stacktrace.c (md.h): Added.
* src/vm/jit/stacktrace.h (md_stacktrace_get_returnaddress): Removed.
* src/vm/jit/alpha/asmpart.S,
src/vm/jit/alpha/linux/md-os.c,
src/vm/jit/alpha/md.c,
src/vm/jit/alpha/md.h,
src/vm/jit/alpha/patcher.c,
src/vm/jit/arm/asmpart.S,
src/vm/jit/arm/codegen.c,
src/vm/jit/arm/md.c,
src/vm/jit/arm/md.h,
src/vm/jit/arm/patcher.c,
src/vm/jit/i386/linux/md-os.c,
src/vm/jit/i386/md.c,
src/vm/jit/i386/md.h,
src/vm/jit/m68k/asmpart.S,
src/vm/jit/m68k/codegen.c,
src/vm/jit/m68k/md.c,
src/vm/jit/m68k/md.h,
src/vm/jit/m68k/patcher.c,
src/vm/jit/mips/asmpart.S,
src/vm/jit/mips/codegen.c,
src/vm/jit/mips/linux/md-os.c,
src/vm/jit/mips/md.c,
src/vm/jit/mips/md.h,
src/vm/jit/mips/patcher.c,
src/vm/jit/powerpc/asmpart.S,
src/vm/jit/powerpc/codegen.c,
src/vm/jit/powerpc/darwin/md-asm.h,
src/vm/jit/powerpc/linux/md-os.c,
src/vm/jit/powerpc/md.c,
src/vm/jit/powerpc/md.h,
src/vm/jit/powerpc/patcher.c,
src/vm/jit/powerpc64/asmpart.S,
src/vm/jit/powerpc64/codegen.c,
src/vm/jit/powerpc64/linux/md-os.c,
src/vm/jit/powerpc64/md.c,
src/vm/jit/powerpc64/md.h,
src/vm/jit/powerpc64/patcher.c,
src/vm/jit/s390/md.c,
src/vm/jit/s390/md.h,
src/vm/jit/sparc64/md.c,
src/vm/jit/sparc64/md.h,
src/vm/jit/sparc64/patcher.c,
src/vm/jit/x86_64/linux/md-os.c,
src/vm/jit/x86_64/md.c,
src/vm/jit/x86_64/md.h
(md_stacktrace_get_returnaddress): Made inline function.
(md_codegen_get_pv_from_pc): Likewise.
(md_cacheflush): Likewise.
(md_icacheflush): Likewise.
(md_dcacheflush): Likewise.
abi.h \
abi-asm.h \
asmpart.h \
- md.h \
methodheader.h
noinst_LTLIBRARIES = \
L_asm_handle_exception_load_gp:
ldgp gp,0(ra) /* load gp */
- jsr ra,md_codegen_get_pv_from_pc/* get PV from RA */
+ jsr ra,md_asm_codegen_get_pv_from_pc /* get PV from RA */
stq v0,2*8(sp) /* save PV */
ldq a0,0*8(sp) /* pass xptr */
#include "vm/types.h"
#include "vm/jit/alpha/codegen.h"
+#include "vm/jit/alpha/md.h"
#include "vm/jit/alpha/md-abi.h"
#if defined(ENABLE_THREADS)
extern void ieee_set_fp_control(unsigned long fp_control);
#endif
-#include "vm/types.h"
-
#include "vm/jit/alpha/codegen.h"
-#include "vm/jit/alpha/md-abi.h"
+#include "vm/jit/alpha/md.h"
#include "vm/exceptions.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
/* global variables ***********************************************************/
}
-/* 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 Alpha the return address is located on the top of the stackframe */
-
- ra = *((u1 **) (sp + framesize - SIZEOF_VOID_P));
-
- return ra;
-}
-
-
/* md_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* md_codegen_get_pv_from_pc ***************************************************
-
- Machine code:
-
- 6b5b4000 jsr (pv)
- 277afffe ldah pv,-2(ra)
- 237ba61c lda pv,-23012(pv)
-
-*******************************************************************************/
-
-u1 *md_codegen_get_pv_from_pc(u1 *ra)
-{
- uint32_t *pc;
- uint32_t mcode;
- int opcode;
- int32_t disp;
- void *pv;
-
- pc = (uint32_t *) ra;
-
- /* Get first instruction word after jump. */
-
- mcode = pc[0];
-
- /* Get opcode and displacement. */
-
- opcode = M_MEM_GET_Opcode(mcode);
- disp = M_MEM_GET_Memory_disp(mcode);
-
- /* Check for short or long load (2 instructions). */
-
- switch (opcode) {
- case 0x08: /* LDA: TODO use define */
- assert((mcode >> 16) == 0x237a);
-
- pv = ((uint8_t *) pc) + disp;
- break;
-
- case 0x09: /* LDAH: TODO use define */
- pv = ((uint8_t *) pc) + (disp << 16);
-
- /* Get displacement of second instruction (LDA). */
-
- mcode = pc[1];
-
- assert((mcode >> 16) == 0x237b);
-
- disp = M_MEM_GET_Memory_disp(mcode);
-
- pv = ((uint8_t *) pv) + disp;
- break;
-
- default:
- vm_abort_disassemble(pc, 2, "md_codegen_get_pv_from_pc: unknown instruction %x", mcode);
- return NULL;
- }
-
- 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 **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
/* md_patch_replacement_point **************************************************
Patch the given replacement point.
/* src/vm/jit/alpha/md.h - machine dependent Alpha functions
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ 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
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
+*/
- Authors: Christian Thalinger
- Changes:
+#ifndef _VM_JIT_ALPHA_MD_H
+#define _VM_JIT_ALPHA_MD_H
-*/
+#include "config.h"
+#include <assert.h>
+#include <stdint.h>
-#ifndef _MD_H
-#define _MD_H
+#include "vm/jit/alpha/codegen.h"
-#include "config.h"
#include "vm/global.h"
+#include "vm/vm.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/codegen-common.h"
/* global variables ***********************************************************/
extern bool has_ext_instr_set;
-/* function prototypes ********************************************************/
-#endif /* _MD_H_ */
+/* inline functions ***********************************************************/
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* On Alpha the return address is located on the top of the
+ stackframe. */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize - SIZEOF_VOID_P));
+
+ return ra;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ Machine code:
+
+ 6b5b4000 jsr (pv)
+ 277afffe ldah pv,-2(ra)
+ 237ba61c lda pv,-23012(pv)
+
+*******************************************************************************/
+
+inline static void *md_codegen_get_pv_from_pc(void *ra)
+{
+ uint32_t *pc;
+ uint32_t mcode;
+ int opcode;
+ int32_t disp;
+ void *pv;
+
+ pc = (uint32_t *) ra;
+
+ /* Get first instruction word after jump. */
+
+ mcode = pc[0];
+
+ /* Get opcode and displacement. */
+
+ opcode = M_MEM_GET_Opcode(mcode);
+ disp = M_MEM_GET_Memory_disp(mcode);
+
+ /* Check for short or long load (2 instructions). */
+
+ switch (opcode) {
+ case 0x08: /* LDA: TODO use define */
+ assert((mcode >> 16) == 0x237a);
+
+ pv = ((uint8_t *) pc) + disp;
+ break;
+
+ case 0x09: /* LDAH: TODO use define */
+ pv = ((uint8_t *) pc) + (disp << 16);
+
+ /* Get displacement of second instruction (LDA). */
+
+ mcode = pc[1];
+
+ assert((mcode >> 16) == 0x237b);
+
+ disp = M_MEM_GET_Memory_disp(mcode);
+
+ pv = ((uint8_t *) pv) + disp;
+ break;
+
+ default:
+ vm_abort_disassemble(pc, 2, "md_codegen_get_pv_from_pc: unknown instruction %x", mcode);
+ return NULL;
+ }
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ /* do nothing */
+}
+
+#endif /* _VM_JIT_ALPHA_MD_H */
/*
#include "vm/types.h"
+#include "vm/jit/alpha/md.h"
+
#include "mm/memory.h"
#include "native/native.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/patcher-common.h"
-#include "vm/jit/md.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/stacktrace.h"
/*TODO:maybe make a macro out of it!!!*/
SAVE_ARGUMENT_REGISTERS
mov a0, lr
- bl md_codegen_get_pv_from_pc
+ bl md_asm_codegen_get_pv_from_pc
mov ip, res1
RESTORE_ARGUMENT_REGISTERS
/* fall through */
/*TODO:maybe make a macro out of it!!!*/
SAVE_ARGUMENT_REGISTERS
mov a0, lr
- bl md_codegen_get_pv_from_pc
+ bl md_asm_codegen_get_pv_from_pc
mov ip, res1
RESTORE_ARGUMENT_REGISTERS
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
#include "vm/jit/linenumbertable.h"
-#include "vm/jit/md.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
#include "vm/jit/patcher-common.h"
#include <assert.h>
#include <stdint.h>
-#include "vm/types.h"
-
+#include "vm/jit/arm/md.h"
#include "vm/jit/arm/md-abi.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-
-#include "vm/jit/asmpart.h"
-#include "vm/jit/md.h"
-
/* md_init *********************************************************************
}
-/* 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 ARM the return address is located on the top of the
- stackframe. */
- /* ATTENTION: This is only true for non-leaf methods!!! */
-
- ra = *((u1 **) (sp + framesize - SIZEOF_VOID_P));
-
- return ra;
-}
-
-
/* md_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* md_codegen_get_pv_from_pc ***************************************************
-
- TODO: document me
-
-*******************************************************************************/
-
-u1 *md_codegen_get_pv_from_pc(u1 *ra)
-{
- u1 *pv;
- u4 mcode1, mcode2, mcode3;
-
- pv = ra;
-
- /* this can either be a RECOMPUTE_IP in JIT code or a fake in asm_calljavafunction */
- mcode1 = *((u4*) ra);
- if ((mcode1 & 0xffffff00) == 0xe24fcf00 /*sub ip,pc,#__*/)
- pv -= (s4) ((mcode1 & 0x000000ff) << 2);
- else if ((mcode1 & 0xffffff00) == 0xe24fc000 /*sub ip,pc,#__*/)
- pv -= (s4) (mcode1 & 0x000000ff);
- else {
- /* if this happens, we got an unexpected instruction at (*ra) */
- vm_abort("Unable to find method: %p (instr=%x)", ra, mcode1);
- }
-
- /* if we have a RECOMPUTE_IP there can be more than one instruction */
- mcode2 = *((u4*) (ra + 4));
- mcode3 = *((u4*) (ra + 8));
- if ((mcode2 & 0xffffff00) == 0xe24ccb00 /*sub ip,ip,#__*/)
- pv -= (s4) ((mcode2 & 0x000000ff) << 10);
- if ((mcode3 & 0xffffff00) == 0xe24cc700 /*sub ip,ip,#__*/)
- pv -= (s4) ((mcode3 & 0x000000ff) << 18);
-
- /* we used PC-relative adressing; but now it is LR-relative */
- pv += 8;
-
- /* if we found our method the data segment has to be valid */
- /* we check this by looking up the IsLeaf field, which has to be boolean */
-/* assert( *((s4*)pv-8) == (s4)true || *((s4*)pv-8) == (s4)false ); */
-
- 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 **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
+void *md_asm_codegen_get_pv_from_pc(void *ra)
{
- /* do nothing */
+ return md_codegen_get_pv_from_pc(ra);
}
--- /dev/null
+/* src/vm/jit/arm/md.h - machine dependent Arm 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
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_ARM_MD_H
+#define _VM_JIT_ARM_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/codegen-common.h"
+
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* On ARM the return address is located on the top of the
+ stackframe. */
+ /* ATTENTION: This is only true for non-leaf methods!!! */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize - SIZEOF_VOID_P));
+
+ return ra;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ TODO: document me
+
+*******************************************************************************/
+
+inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
+{
+ u1 *pv;
+ u4 mcode1, mcode2, mcode3;
+
+ pv = ra;
+
+ /* this can either be a RECOMPUTE_IP in JIT code or a fake in asm_calljavafunction */
+ mcode1 = *((u4*) ra);
+ if ((mcode1 & 0xffffff00) == 0xe24fcf00 /*sub ip,pc,#__*/)
+ pv -= (s4) ((mcode1 & 0x000000ff) << 2);
+ else if ((mcode1 & 0xffffff00) == 0xe24fc000 /*sub ip,pc,#__*/)
+ pv -= (s4) (mcode1 & 0x000000ff);
+ else {
+ /* if this happens, we got an unexpected instruction at (*ra) */
+ vm_abort("Unable to find method: %p (instr=%x)", ra, mcode1);
+ }
+
+ /* if we have a RECOMPUTE_IP there can be more than one instruction */
+ mcode2 = *((u4*) (ra + 4));
+ mcode3 = *((u4*) (ra + 8));
+ if ((mcode2 & 0xffffff00) == 0xe24ccb00 /*sub ip,ip,#__*/)
+ pv -= (s4) ((mcode2 & 0x000000ff) << 10);
+ if ((mcode3 & 0xffffff00) == 0xe24cc700 /*sub ip,ip,#__*/)
+ pv -= (s4) ((mcode3 & 0x000000ff) << 18);
+
+ /* we used PC-relative adressing; but now it is LR-relative */
+ pv += 8;
+
+ /* if we found our method the data segment has to be valid */
+ /* we check this by looking up the IsLeaf field, which has to be boolean */
+/* assert( *((s4*)pv-8) == (s4)true || *((s4*)pv-8) == (s4)false ); */
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ /* do nothing */
+}
+
+#endif /* _VM_JIT_ARM_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "vm/types.h"
+#include "vm/jit/arm/md.h"
+
#include "mm/memory.h"
#include "native/native.h"
#include "vm/initialize.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/md.h"
#include "vm/jit/patcher-common.h"
#include "vmcore/field.h"
u8 asm_get_cycle_count(void);
+void *md_asm_codegen_get_pv_from_pc(void *ra);
+
#endif /* _ASMPART_H */
#include "vm/types.h"
#include "codegen.h"
+#include "md.h"
#include "md-abi.h"
#include "mm/memory.h"
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
#include "vm/jit/linenumbertable.h"
-#include "vm/jit/md.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#endif /* defined(ENABLE_SSA) */
+/* REMOVEME When we have exception handling in C. */
+
+void *md_asm_codegen_get_pv_from_pc(void *ra)
+{
+ return md_codegen_get_pv_from_pc(ra);
+}
+
/*
* These are local overrides for various environment variables in Emacs.
# define CODEGEN_CRITICAL_SECTION_END /* no-op */
#endif
-/* machine dependent functions */
-u1 *md_codegen_get_pv_from_pc(u1 *ra);
-
-
#if defined(ENABLE_SSA)
void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr);
#endif
#include "vm/types.h"
#include "vm/jit/i386/codegen.h"
+#include "vm/jit/i386/md.h"
#include "threads/threads-common.h"
#include "vm/vm.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
/* md_init *********************************************************************
}
-/* 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 i386 the return address is above the current stack frame */
-
- ra = *((u1 **) (sp + framesize));
-
- return ra;
-}
-
-
/* md_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* md_codegen_get_pv_from_pc ***************************************************
-
- On this architecture just a wrapper function to
- codegen_get_pv_from_pc.
-
-*******************************************************************************/
-
-u1 *md_codegen_get_pv_from_pc(u1 *ra)
-{
- u1 *pv;
-
- /* Get the start address of the function which contains this
- address from the method table. */
-
- pv = codegen_get_pv_from_pc(ra);
-
- return pv;
-}
-
-
-/* md_cacheflush ***************************************************************
-
- Calls the system's function to flush the instruction and data
- cache.
-
-*******************************************************************************/
-
-void md_cacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
-/* md_icacheflush **************************************************************
-
- Calls the system's function to flush the instruction cache.
-
-*******************************************************************************/
-
-void md_icacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
-/* md_dcacheflush **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
/* md_patch_replacement_point **************************************************
Patch the given replacement point.
--- /dev/null
+/* src/vm/jit/i386/md.h - machine dependent i386 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
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_I386_MD_H
+#define _VM_JIT_I386_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/jit/codegen-common.h"
+
+
+/* inline functions ***********************************************************/
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* On i386 the return address is above the current stack frame. */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize));
+
+ return ra;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ On this architecture just a wrapper function to
+ codegen_get_pv_from_pc.
+
+*******************************************************************************/
+
+inline static void *md_codegen_get_pv_from_pc(void *ra)
+{
+ void *pv;
+
+ /* Get the start address of the function which contains this
+ address from the method table. */
+
+ pv = codegen_get_pv_from_pc(ra);
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ /* do nothing */
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(void *addr, int nbytes)
+{
+ /* do nothing */
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ /* do nothing */
+}
+
+#endif /* _VM_JIT_I386_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "config.h"
#include <assert.h>
+#include <stdint.h>
#include "vm/types.h"
+#include "md.h"
+
#include "mm/memory.h"
#include "native/native.h"
/* we need the dseg, figure it out */
movel %a3, %sp@- /* push ra argument */
- jsr md_codegen_get_pv_from_pc /* pv in %d0 now */
+ jsr md_asm_codegen_get_pv_from_pc /* pv in %d0 now */
movel %d0, %d2 /* move to safe register */
lea %sp@(4), %sp /* pop args off stack */
#include "vm/jit/reg.h"
#include "vm/jit/replace.h"
#include "vm/jit/stacktrace.h"
-#include "vm/jit/md.h"
#include "vmcore/loader.h"
#include "vmcore/options.h"
#include <assert.h>
#include <stdint.h>
-#include "md-os.h"
-
#include "vm/types.h"
-#include "vm/jit/codegen-common.h"
-#include "vm/jit/md.h"
#include "vm/vm.h"
-#include "vmcore/class.h"
-#include "vmcore/linker.h"
-#include "vmcore/method.h"
-#include "mm/memory.h"
-#include "vm/jit/asmpart.h"
/*
{
}
-/* md_codegen_get_pv_from_pc ***************************************************
-
- On this architecture just a wrapper function to
- codegen_get_pv_from_pc.
-
-*******************************************************************************/
-u1* md_codegen_get_pv_from_pc(u1 *ra)
-{
- u1 *pv;
- pv = codegen_get_pv_from_pc(ra);
-
- return pv;
-}
/* md_jit_method_patch_address *************************************************
return pa;
}
-/* XXX i can't find a definition of cacheflush in any installed header files but i can find the symbol in libc */
-/* lets extract the signature from the assembler code*/
-/*
- 000e7158 <cacheflush>:
- e7158: 707b moveq #123,%d0
- e715a: 2f04 movel %d4,%sp@-
- e715c: 282f 0014 movel %sp@(20),%d4 arg
- e7160: 2243 moveal %d3,%a1
- e7162: 262f 0010 movel %sp@(16),%d3 arg
- e7166: 2042 moveal %d2,%a0
- e7168: 242f 000c movel %sp@(12),%d2 arg
- e716c: 222f 0008 movel %sp@(8),%d1 arg
- e7170: 4e40 trap #0 traps into system i guess
- e7172: 2408 movel %a0,%d2
- e7174: 2609 movel %a1,%d3
- e7176: 281f movel %sp@+,%d4
- e7178: 223c ffff f001 movel #-4095,%d1
- e717e: b081 cmpl %d1,%d0
- e7180: 6402 bccs e7184 <cacheflush+0x2c>
- e7182: 4e75 rts
- e7184: 4480 negl %d0
- e7186: 2f00 movel %d0,%sp@-
- e7188: 61ff fff3 82e2 bsrl 1f46c <D_MAX_EXP+0x1ec6d>
- e718e: 209f movel %sp@+,%a0@
- e7190: 70ff moveq #-1,%d0
- e7192: 2040 moveal %d0,%a0
- e7194: 4e75 rts
- e7196: 4e75 rts
- */
-
-/* seems to have 4 arguments */
-/* best guess: it is this syscall */
-/* asmlinkage int sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) */
-/* kernel 2.6.10 with freescale patches (the one I develop against) needs a patch of */
-/* arch/m68k/kernel/sys_m68k.c(sys_cacheflush) */
-/* evil hack: */
-/*
-void DcacheFlushInvalidateCacheBlock(void *start, unsigned long size);
-void IcacheInvalidateCacheBlock(void *start, unsigned long size);
-
-asmlinkage int
-sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
-{
- lock_kernel();
- DcacheFlushInvalidateCacheBlock(addr, len);
- IcacheInvalidateCacheBlock(addr, len);
- unlock_kernel();
- return 0;
-}
-*/
-extern int cacheflush(unsigned long addr, int scope, int cache, unsigned long len);
-
-#include "asm/cachectl.h" /* found more traces of the cacheflush function */
-#include "errno.h"
-
-void md_cacheflush(u1 *addr, s4 nbytes) { cacheflush((unsigned long)addr, FLUSH_SCOPE_PAGE, FLUSH_CACHE_BOTH, nbytes); }
-void md_dcacheflush(u1 *addr, s4 nbytes) { cacheflush((unsigned long)addr, FLUSH_SCOPE_PAGE, FLUSH_CACHE_DATA, nbytes); }
-void md_icacheflush(u1* addr, s4 nbytes) { cacheflush((unsigned long)addr, FLUSH_SCOPE_LINE, FLUSH_CACHE_INSN, nbytes); }
-
-/* 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)
-{
- /* return address is above stackpointer */
- u1 *ra = *((u1**)(sp + framesize));
-
- /* XXX: This helps for now, but it's a ugly hack
- * the problem _may_ be: the link instruction is used
- * by some gcc generated code, and we get an additional word
- * on the stack, the old framepointer. Its address is somewhere
- * near sp, but that all depends the code generated by the compiler.
- * I'm unsure about a clean solution.
- */
- #if 0
- if (!(ra > 0x40000000 && ra < 0x80000000)) {
- ra = *((u1**)(sp + framesize + 4));
- }
- #endif
- /* assert(ra > 0x40000000 && ra < 0x80000000);
- printf("XXXXXX=%x\n", ra);
- */
- return ra;
-}
-
/*
* These are local overrides for various environment variables in Emacs.
--- /dev/null
+/* src/vm/jit/m68k/md.h
+
+ 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.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_M68K_MD_H
+#define _VM_JIT_M68K_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/jit/codegen-common.h"
+
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* return address is above stackpointer */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize));
+
+ /* XXX: This helps for now, but it's a ugly hack
+ * the problem _may_ be: the link instruction is used
+ * by some gcc generated code, and we get an additional word
+ * on the stack, the old framepointer. Its address is somewhere
+ * near sp, but that all depends the code generated by the compiler.
+ * I'm unsure about a clean solution.
+ */
+#if 0
+ if (!(ra > 0x40000000 && ra < 0x80000000)) {
+ ra = *((u1**)(sp + framesize + 4));
+ }
+#endif
+
+ /* assert(ra > 0x40000000 && ra < 0x80000000);
+ printf("XXXXXX=%x\n", ra);
+ */
+
+ return ra;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ On this architecture just a wrapper function to
+ codegen_get_pv_from_pc.
+
+*******************************************************************************/
+
+inline static void *md_codegen_get_pv_from_pc(void *ra)
+{
+ void *pv;
+
+ pv = codegen_get_pv_from_pc(ra);
+
+ return pv;
+}
+
+
+/* XXX i can't find a definition of cacheflush in any installed header files but i can find the symbol in libc */
+/* lets extract the signature from the assembler code*/
+/*
+ 000e7158 <cacheflush>:
+ e7158: 707b moveq #123,%d0
+ e715a: 2f04 movel %d4,%sp@-
+ e715c: 282f 0014 movel %sp@(20),%d4 arg
+ e7160: 2243 moveal %d3,%a1
+ e7162: 262f 0010 movel %sp@(16),%d3 arg
+ e7166: 2042 moveal %d2,%a0
+ e7168: 242f 000c movel %sp@(12),%d2 arg
+ e716c: 222f 0008 movel %sp@(8),%d1 arg
+ e7170: 4e40 trap #0 traps into system i guess
+ e7172: 2408 movel %a0,%d2
+ e7174: 2609 movel %a1,%d3
+ e7176: 281f movel %sp@+,%d4
+ e7178: 223c ffff f001 movel #-4095,%d1
+ e717e: b081 cmpl %d1,%d0
+ e7180: 6402 bccs e7184 <cacheflush+0x2c>
+ e7182: 4e75 rts
+ e7184: 4480 negl %d0
+ e7186: 2f00 movel %d0,%sp@-
+ e7188: 61ff fff3 82e2 bsrl 1f46c <D_MAX_EXP+0x1ec6d>
+ e718e: 209f movel %sp@+,%a0@
+ e7190: 70ff moveq #-1,%d0
+ e7192: 2040 moveal %d0,%a0
+ e7194: 4e75 rts
+ e7196: 4e75 rts
+ */
+
+/* seems to have 4 arguments */
+/* best guess: it is this syscall */
+/* asmlinkage int sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) */
+/* kernel 2.6.10 with freescale patches (the one I develop against) needs a patch of */
+/* arch/m68k/kernel/sys_m68k.c(sys_cacheflush) */
+/* evil hack: */
+/*
+void DcacheFlushInvalidateCacheBlock(void *start, unsigned long size);
+void IcacheInvalidateCacheBlock(void *start, unsigned long size);
+
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+ lock_kernel();
+ DcacheFlushInvalidateCacheBlock(addr, len);
+ IcacheInvalidateCacheBlock(addr, len);
+ unlock_kernel();
+ return 0;
+}
+*/
+
+extern int cacheflush(unsigned long addr, int scope, int cache, unsigned long len);
+
+#include "asm/cachectl.h" /* found more traces of the cacheflush function */
+#include "errno.h"
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ cacheflush((unsigned long)addr, FLUSH_SCOPE_PAGE, FLUSH_CACHE_BOTH, nbytes);
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(void *addr, int nbytes)
+{
+ cacheflush((unsigned long)addr, FLUSH_SCOPE_LINE, FLUSH_CACHE_INSN, nbytes);
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ cacheflush((unsigned long)addr, FLUSH_SCOPE_PAGE, FLUSH_CACHE_DATA, nbytes);
+}
+
+#endif /* _VM_JIT_M68K_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "vm/types.h"
+#include "vm/jit/m68k/md.h"
+
#include "mm/memory.h"
#include "native/native.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/patcher-common.h"
-#include "vm/jit/md.h"
#include "vm/jit/stacktrace.h"
#include "vmcore/class.h"
+++ /dev/null
-/* src/vm/jit/md.h - machine dependent functions
-
- Copyright (C) 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#ifndef _MD_H
-#define _MD_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/jit/stacktrace.h"
-
-
-/* function prototypes ********************************************************/
-
-#if defined(ENABLE_JIT)
-void md_cacheflush(u1 *addr, s4 nbytes);
-void md_icacheflush(u1 *addr, s4 nbytes);
-void md_dcacheflush(u1 *addr, s4 nbytes);
-#endif
-
-#endif /* _MD_H */
-
-
-/*
- * 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
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
#endif
move a0,ra /* pass RA */
- jal md_codegen_get_pv_from_pc /* get PV from RA */
+ jal md_asm_codegen_get_pv_from_pc /* get PV from RA */
#if SIZEOF_VOID_P == 8
ast v0,2*8(sp) /* save PV */
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
#include "vm/jit/linenumbertable.h"
-#include "vm/jit/md.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/reg.h"
#include "vm/jit/replace.h"
#include "vm/types.h"
#include "vm/jit/mips/codegen.h"
+#include "vm/jit/mips/md.h"
#include "vm/jit/mips/md-abi.h"
#include "mm/gc-common.h"
#include <assert.h>
#include <stdint.h>
-#include <unistd.h>
-#include <sys/cachectl.h>
#include "vm/types.h"
-#include "toolbox/logging.h"
+#include "vm/jit/mips/md.h"
#include "vm/global.h"
#include "vm/vm.h"
-#include "vm/jit/codegen-common.h"
#include "vm/jit/jit.h"
-/* 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 MIPS the return address is located on the top of the stackframe */
-
- /* XXX change this if we ever want to use 4-byte stackslots */
- /* ra = *((u1 **) (sp + framesize - SIZEOF_VOID_P)); */
- ra = *((u1 **) (sp + framesize - 8));
-
- return ra;
-}
-
-
/* md_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* md_codegen_get_pv_from_pc ***************************************************
-
- Machine code:
-
- 03c0f809 jalr s8
- 00000000 nop
- 27feff9c addiu s8,ra,-100
-
-*******************************************************************************/
-
-u1 *md_codegen_get_pv_from_pc(u1 *ra)
-{
- u1 *pv;
- u4 mcode;
- s4 offset;
-
- /* get the offset of the instructions */
-
- /* get first instruction word after jump */
-
- mcode = *((u4 *) ra);
-
- /* check if we have 2 instructions (lui, daddiu) */
-
- if ((mcode >> 16) == 0x3c19) {
- /* get displacement of first instruction (lui) */
-
- offset = (s4) (mcode << 16);
-
- /* get displacement of second instruction (daddiu) */
-
- mcode = *((u4 *) (ra + 1 * 4));
-
-#if SIZEOF_VOID_P == 8
- assert((mcode >> 16) == 0x6739);
-#else
- assert((mcode >> 16) == 0x2739);
-#endif
-
- offset += (s2) (mcode & 0x0000ffff);
- }
- else {
- /* get offset of first instruction (daddiu) */
-
- mcode = *((u4 *) ra);
-
-#if SIZEOF_VOID_P == 8
- assert((mcode >> 16) == 0x67fe);
-#else
- assert((mcode >> 16) == 0x27fe);
-#endif
-
- offset = (s2) (mcode & 0x0000ffff);
- }
-
- /* 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)
-{
- cacheflush(addr, nbytes, BCACHE);
-}
-
-
-/* md_icacheflush **************************************************************
-
- Calls the system's function to flush the instruction cache.
-
-*******************************************************************************/
-
-void md_icacheflush(u1 *addr, s4 nbytes)
-{
- cacheflush(addr, nbytes, ICACHE);
-}
-
-
-/* md_dcacheflush **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
-{
- cacheflush(addr, nbytes, DCACHE);
-}
-
-
/* md_patch_replacement_point **************************************************
Patch the given replacement point.
}
#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
--- /dev/null
+/* src/vm/jit/mips/md.h - machine dependent MIPS 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
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_MIPS_MD_H
+#define _VM_JIT_MIPS_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/cachectl.h>
+
+#include "vm/types.h"
+
+#include "vm/vm.h"
+
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* On MIPS the return address is located on the top of the
+ stackframe. */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize - 8));
+
+ return ra;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ Machine code:
+
+ 03c0f809 jalr s8
+ 00000000 nop
+ 27feff9c addiu s8,ra,-100
+
+*******************************************************************************/
+
+inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
+{
+ u1 *pv;
+ u4 mcode;
+ s4 offset;
+
+ /* get the offset of the instructions */
+
+ /* get first instruction word after jump */
+
+ mcode = *((u4 *) ra);
+
+ /* check if we have 2 instructions (lui, daddiu) */
+
+ if ((mcode >> 16) == 0x3c19) {
+ /* get displacement of first instruction (lui) */
+
+ offset = (s4) (mcode << 16);
+
+ /* get displacement of second instruction (daddiu) */
+
+ mcode = *((u4 *) (ra + 1 * 4));
+
+#if SIZEOF_VOID_P == 8
+ assert((mcode >> 16) == 0x6739);
+#else
+ assert((mcode >> 16) == 0x2739);
+#endif
+
+ offset += (s2) (mcode & 0x0000ffff);
+ }
+ else {
+ /* get offset of first instruction (daddiu) */
+
+ mcode = *((u4 *) ra);
+
+#if SIZEOF_VOID_P == 8
+ assert((mcode >> 16) == 0x67fe);
+#else
+ assert((mcode >> 16) == 0x27fe);
+#endif
+
+ offset = (s2) (mcode & 0x0000ffff);
+ }
+
+ /* calculate PV via RA + offset */
+
+ pv = ra + offset;
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ cacheflush(addr, nbytes, BCACHE);
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(void *addr, int nbytes)
+{
+ cacheflush(addr, nbytes, ICACHE);
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ cacheflush(addr, nbytes, DCACHE);
+}
+
+#endif /* _VM_JIT_MIPS_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "vm/types.h"
#include "vm/jit/mips/codegen.h"
+#include "vm/jit/mips/md.h"
#include "mm/memory.h"
#include "vm/initialize.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/md.h"
#include "vm/jit/patcher-common.h"
#include "vmcore/class.h"
#include <stdint.h>
#include "codegen.h" /* for PATCHER_NOPS */
+#include "md.h"
#include "mm/memory.h"
#include "vm/jit/code.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
#include "vm/jit/patcher-common.h"
#include "vmcore/options.h"
stw itmp3,LA_SIZE+(4+4)*4(sp) /* save maybe-leaf flag (cleared) */
mr a0,r0 /* pass return address */
- bl md_codegen_get_pv_from_pc /* get PV from RA */
+ bl md_asm_codegen_get_pv_from_pc /* get PV from RA */
stw v0,LA_SIZE+(4+2)*4(sp) /* save data segment pointer */
lwz a0,LA_SIZE+(4+0)*4(sp) /* pass xptr */
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.align 2
-L_md_codegen_get_pv_from_pc$stub:
- .indirect_symbol _md_codegen_get_pv_from_pc
+L_md_asm_codegen_get_pv_from_pc$stub:
+ .indirect_symbol _md_asm_codegen_get_pv_from_pc
mflr r0
- bcl 20,31,L00$_md_codegen_get_pv_from_pc
-L00$_md_codegen_get_pv_from_pc:
+ bcl 20,31,L00$_md_asm_codegen_get_pv_from_pc
+L00$_md_asm_codegen_get_pv_from_pc:
mflr r11
- addis r11,r11,ha16(L_md_codegen_get_pv_from_pc$lazy_ptr - L00$_md_codegen_get_pv_from_pc)
+ addis r11,r11,ha16(L_md_asm_codegen_get_pv_from_pc$lazy_ptr - L00$_md_asm_codegen_get_pv_from_pc)
mtlr r0
- lwzu r12,lo16(L_md_codegen_get_pv_from_pc$lazy_ptr - L00$_md_codegen_get_pv_from_pc)(r11)
+ lwzu r12,lo16(L_md_asm_codegen_get_pv_from_pc$lazy_ptr - L00$_md_asm_codegen_get_pv_from_pc)(r11)
mtctr r12
bctr
.data
.lazy_symbol_pointer
-L_md_codegen_get_pv_from_pc$lazy_ptr:
- .indirect_symbol _md_codegen_get_pv_from_pc
+L_md_asm_codegen_get_pv_from_pc$lazy_ptr:
+ .indirect_symbol _md_asm_codegen_get_pv_from_pc
.long dyld_stub_binding_helper
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
#include "vm/jit/linenumbertable.h"
-#include "vm/jit/md.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
#include "vm/jit/patcher-common.h"
#define builtin_throw_exception L_builtin_throw_exception$stub
-#define md_codegen_get_pv_from_pc L_md_codegen_get_pv_from_pc$stub
+#define md_asm_codegen_get_pv_from_pc L_md_asm_codegen_get_pv_from_pc$stub
#define exceptions_handle_exception L_exceptions_handle_exception$stub
#define exceptions_asm_new_abstractmethoderror \
#include "vm/types.h"
#include "vm/jit/powerpc/codegen.h"
+#include "vm/jit/powerpc/md.h"
#include "vm/jit/powerpc/linux/md-abi.h"
#if defined(ENABLE_THREADS)
#include "md-abi.h"
#include "vm/jit/powerpc/codegen.h"
+#include "vm/jit/powerpc/md.h"
#include "vm/global.h"
#include "vm/vm.h"
-#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
/* md_init *********************************************************************
}
-/* 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_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* 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)
-{
- 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 offset of first instruction (addi) */
-
- offset = (s2) (mcode & 0x0000ffff);
- }
-
- /* 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 **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
-{
- asm_cacheflush(addr, nbytes);
-}
-
-
/* md_patch_replacement_point **************************************************
Patch the given replacement point.
}
#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
--- /dev/null
+/* src/vm/jit/powerpc/md.h - 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
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_POWERPC_MD_H
+#define _VM_JIT_POWERPC_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/jit/powerpc/codegen.h"
+
+#include "vm/global.h"
+#include "vm/vm.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/codegen-common.h"
+
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* Pn PowerPC the return address is located in the linkage
+ area. */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize + LA_LR_OFFSET));
+
+ return ra;
+}
+
+
+/* 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
+
+*******************************************************************************/
+
+inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
+{
+ 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 offset of first instruction (addi) */
+
+ offset = (s2) (mcode & 0x0000ffff);
+ }
+
+ /* calculate PV via RA + offset */
+
+ pv = ra + offset;
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+#endif /* _VM_JIT_POWERPC_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "vm/types.h"
+#include "vm/jit/powerpc/md.h"
+
#include "mm/memory.h"
+
#include "native/native.h"
#include "vm/builtin.h"
#include "vm/initialize.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/md.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/stacktrace.h"
std itmp3,LA_SIZE+PA_SIZE+(4+4)*8(sp) /* save maybe-leaf flag (cleared) */
mr a0,r0 /* pass return address */
- bl md_codegen_get_pv_from_pc /* get PV from RA */
+ bl md_asm_codegen_get_pv_from_pc /* get PV from RA */
std v0,LA_SIZE+PA_SIZE+(4+2)*8(sp) /* save data segment pointer */
ld a0,LA_SIZE+PA_SIZE+(4+0)*8(sp) /* pass xptr */
#include "vm/jit/abi.h"
#include "vm/jit/abi-asm.h"
-#include "vm/jit/md.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/types.h"
#include "vm/jit/powerpc64/codegen.h"
+#include "vm/jit/powerpc64/md.h"
#include "vm/jit/powerpc64/linux/md-abi.h"
#if defined(ENABLE_THREADS)
#include "md-abi.h"
#include "vm/jit/powerpc64/codegen.h"
+#include "vm/jit/powerpc64/md.h"
#include "vm/exceptions.h"
#include "vm/global.h"
-#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
/* md_init *********************************************************************
}
-/* 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_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* md_codegen_get_pv_from_pc ***************************************************
-
- Machine code:
-
- 7d6802a6 mflr r11
- 39cbffe0 addi r14,r11,-32
-
- or
-
- 7d6802a6 mflr r11
- 3dcbffff addis r14,r11,-1
- 39ce68b0 addi r14,r13,26800
-
-*******************************************************************************/
-
-u1 *md_codegen_get_pv_from_pc(u1 *ra)
-{
- 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) == 0x3dcb) {
- /* 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) == 0x39ce);
-
- offset += (s2) (mcode & 0x0000ffff);
- }
- else if ((mcode >> 16) == 0x39cb) {
- /* get offset of first instruction (addi) */
-
- offset = (s2) (mcode & 0x0000ffff);
- }
- else {
- vm_abort("md_codegen_get_pv_from_pc: unknown instruction %x", mcode);
-
- /* keep compiler happy */
-
- offset = 0;
- }
-
- /* 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 **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
-{
- asm_cacheflush(addr, nbytes);
-}
-
-
/* md_patch_replacement_point **************************************************
Patch the given replacement point.
}
#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
--- /dev/null
+/* src/vm/jit/powerpc64/md.h - 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
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_POWERPC64_MD_H
+#define _VM_JIT_POWERPC64_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/jit/powerpc64/codegen.h"
+
+#include "vm/global.h"
+#include "vm/vm.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* On PowerPC64 the return address is located in the linkage
+ area. */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize + LA_LR_OFFSET));
+
+ return ra;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ Machine code:
+
+ 7d6802a6 mflr r11
+ 39cbffe0 addi r14,r11,-32
+
+ or
+
+ 7d6802a6 mflr r11
+ 3dcbffff addis r14,r11,-1
+ 39ce68b0 addi r14,r13,26800
+
+*******************************************************************************/
+
+inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
+{
+ 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) == 0x3dcb) {
+ /* 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) == 0x39ce);
+
+ offset += (s2) (mcode & 0x0000ffff);
+ }
+ else if ((mcode >> 16) == 0x39cb) {
+ /* get offset of first instruction (addi) */
+
+ offset = (s2) (mcode & 0x0000ffff);
+ }
+ else {
+ vm_abort("md_codegen_get_pv_from_pc: unknown instruction %x", mcode);
+
+ /* keep compiler happy */
+
+ offset = 0;
+ }
+
+ /* calculate PV via RA + offset */
+
+ pv = ra + offset;
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ asm_cacheflush(addr, nbytes);
+}
+
+#endif /* _VM_JIT_POWERPC64_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "vm/types.h"
+#include "vm/jit/powerpc64/md.h"
+
#include "mm/memory.h"
#include "native/native.h"
#include "vm/initialize.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/md.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/stacktrace.h"
#include <stdlib.h>
#include "arch.h"
+#include "md.h"
#if defined(ENABLE_GC_CACAO)
# include "mm/cacao-gc/gc.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/disass.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/replace.h"
#include "vm/jit/show.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/s390/codegen.h"
-#include <assert.h>
/* prototypes *****************************************************************/
#endif
-/* 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 S390 the return address is located on the top of the stackframe */
-
- ra = *((u1 **) (sp + framesize - 8));
-
- return ra;
-}
-
-
/* md_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* md_codegen_get_pv_from_pc ***************************************************
-
- On this architecture just a wrapper function to
- codegen_get_pv_from_pc.
-
-*******************************************************************************/
-
-u1 *md_codegen_get_pv_from_pc(u1 *ra)
-{
- u1 *pv;
-
- /* Get the start address of the function which contains this
- address from the method table. */
-
- pv = codegen_get_pv_from_pc(ra);
-
- return pv;
-}
-
-
-/* md_cacheflush ***************************************************************
-
- Calls the system's function to flush the instruction and data
- cache.
-
-*******************************************************************************/
-
-void md_cacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
-/* md_icacheflush **************************************************************
-
- Calls the system's function to flush the instruction cache.
-
-*******************************************************************************/
-
-void md_icacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
-/* md_dcacheflush **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
/* md_patch_replacement_point **************************************************
Patch the given replacement point.
--- /dev/null
+/* src/vm/jit/s390/md.h - machine dependent s390 Linux functions
+
+ Copyright (C) 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.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_S390_MD_H
+#define _VM_JIT_S390_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/jit/codegen-common.h"
+
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* On S390 the return address is located on the top of the
+ stackframe. */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize - 8));
+
+ return ra;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ On this architecture just a wrapper function to
+ codegen_get_pv_from_pc.
+
+*******************************************************************************/
+
+inline static void *md_codegen_get_pv_from_pc(void *ra)
+{
+ void *pv;
+
+ /* Get the start address of the function which contains this
+ address from the method table. */
+
+ pv = codegen_get_pv_from_pc(ra);
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ /* do nothing */
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(void *addr, int nbytes)
+{
+ /* do nothing */
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ /* do nothing */
+}
+
+#endif /* _VM_JIT_S390_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
-/* src/vm/jit/sparc64/md.c - machine dependent SPARC functions
+/* src/vm/jit/sparc64/md.c - machine dependent SPARC64 functions
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ 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
void asm_load_fp_state_reg(u8 *mem);
-
-/* shift away 13-bit immediate, mask rd and rs1 */
-#define SHIFT_AND_MASK(instr) \
- ((instr >> 13) & 0x60fc1)
-
/* NOP is defined as a SETHI instruction with rd and imm. set to zero */
/* therefore we check if the 22-bit immediate is zero */
#define IS_SETHI(instr) \
}
-/* 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;
- /* flush register windows to the stack */
- __asm__ ("flushw");
-
- /* the return address resides in register i7, the last register in the
- * 16-extended-word save area
- */
- ra = *((u1 **) (sp + 120 + BIAS));
-
- /* NOTE: on SPARC ra is the address of the call instruction */
-
- return ra;
-}
-
-u1 *md_get_framepointer(u1 *sp)
-{
- u1 *fp;
- /* flush register windows to the stack */
- __asm__ ("flushw");
-
- fp = *((u1 **) (sp + 112 + BIAS));
-
- return fp;
-}
-
-u1 *md_get_pv_from_stackframe(u1 *sp)
-{
- u1 *pv;
- /* flush register windows to the stack */
- __asm__ ("flushw");
-
- pv = *((u1 **) (sp + 104 + BIAS));
-
- return pv;
-}
-
-
-/* md_codegen_get_pv_from_pc ***************************************************
-
- This reconstructs and returns the PV of a method given a return address
- pointer. (basically, same was as the generated code following the jump does)
-
- Machine code:
-
- 6b5b4000 jmpl (pv)
- 10000000 nop
- 277afffe ldah pv,-2(ra)
- 237ba61c lda pv,-23012(pv)
-
-*******************************************************************************/
-
-u1 *md_codegen_get_pv_from_pc(u1 *ra)
-{
- u1 *pv;
- u8 mcode;
- s4 offset;
-
- pv = ra;
-
- /* get the instruction word after jump and nop */
- mcode = *((u4 *) (ra+8) );
-
- /* check if we have a sethi insruction */
- if (IS_SETHI(mcode)) {
- s4 xor_imm;
-
- /* get 22-bit immediate of sethi instruction */
- offset = (s4) (mcode & 0x3fffff);
- offset = offset << 10;
-
- /* now the xor */
- mcode = *((u4 *) (ra+12) );
- xor_imm = decode_13bit_imm(mcode);
-
- offset ^= xor_imm;
- }
- else {
- u4 mcode_masked;
-
- mcode_masked = SHIFT_AND_MASK(mcode);
-
- assert(mcode_masked == 0x40001);
-
- /* mask and extend the negative sign for the 13 bit immediate */
- offset = decode_13bit_imm(mcode);
- }
-
- pv += offset;
-
- return pv;
-}
-
-
/* md_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* md_cacheflush ***************************************************************
-
- Calls the system's function to flush the instruction and data
- cache.
-
-*******************************************************************************/
-
-void md_cacheflush(u1 *addr, s4 nbytes)
-{
- /* don't know yet */
-}
-
-
-/* md_dcacheflush **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
-{
- /* XXX don't know yet */
- /* printf("md_dcacheflush\n"); */
- __asm__ __volatile__ ( "membar 0x7F" : : : "memory" );
-}
-
-
/* md_patch_replacement_point **************************************************
Patch the given replacement point.
--- /dev/null
+/* src/vm/jit/sparc64/md.c - machine dependent SPARC64 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
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_SPARC64_MD_H
+#define _VM_JIT_SPARC64_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "vm/jit/codegen-common.h"
+
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* flush register windows to the stack */
+ __asm__ ("flushw");
+
+ /* the return address resides in register i7, the last register in the
+ * 16-extended-word save area
+ */
+ ra = *((void **) (((uintptr_t) sp) + 120 + BIAS));
+
+ /* NOTE: on SPARC ra is the address of the call instruction */
+
+ return ra;
+}
+
+inline static void *md_get_framepointer(void *sp)
+{
+ void *fp;
+
+ /* flush register windows to the stack */
+ __asm__ ("flushw");
+
+ fp = *((void **) (((uintptr_t) sp) + 112 + BIAS));
+
+ return fp;
+}
+
+inline static void *md_get_pv_from_stackframe(void *sp)
+{
+ void *pv;
+
+ /* flush register windows to the stack */
+ __asm__ ("flushw");
+
+ pv = *((void **) (((uintptr_t) sp) + 104 + BIAS));
+
+ return pv;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ This reconstructs and returns the PV of a method given a return address
+ pointer. (basically, same was as the generated code following the jump does)
+
+ Machine code:
+
+ 6b5b4000 jmpl (pv)
+ 10000000 nop
+ 277afffe ldah pv,-2(ra)
+ 237ba61c lda pv,-23012(pv)
+
+*******************************************************************************/
+
+/* TODO Move these macros into the code generator. */
+
+/* shift away 13-bit immediate, mask rd and rs1 */
+#define SHIFT_AND_MASK(instr) \
+ ((instr >> 13) & 0x60fc1)
+
+/* NOP is defined as a SETHI instruction with rd and imm. set to zero */
+/* therefore we check if the 22-bit immediate is zero */
+#define IS_SETHI(instr) \
+ (((instr & 0xc1c00000) == 0x01000000) \
+ && ((instr & 0x3fffff) != 0x0))
+
+inline s2 decode_13bit_imm(u4 instr) {
+ s2 imm;
+
+ /* mask everything else in the instruction */
+ imm = instr & 0x00001fff;
+
+ /* sign extend 13-bit to 16-bit */
+ imm <<= 3;
+ imm >>= 3;
+
+ return imm;
+}
+
+inline static void *md_codegen_get_pv_from_pc(void *ra)
+{
+ uint8_t *pv;
+ u8 mcode;
+ s4 offset;
+
+ pv = ra;
+
+ /* get the instruction word after jump and nop */
+ mcode = *((u4 *) (ra+8) );
+
+ /* check if we have a sethi insruction */
+ if (IS_SETHI(mcode)) {
+ s4 xor_imm;
+
+ /* get 22-bit immediate of sethi instruction */
+ offset = (s4) (mcode & 0x3fffff);
+ offset = offset << 10;
+
+ /* now the xor */
+ mcode = *((u4 *) (ra+12) );
+ xor_imm = decode_13bit_imm(mcode);
+
+ offset ^= xor_imm;
+ }
+ else {
+ u4 mcode_masked;
+
+ mcode_masked = SHIFT_AND_MASK(mcode);
+
+ assert(mcode_masked == 0x40001);
+
+ /* mask and extend the negative sign for the 13 bit immediate */
+ offset = decode_13bit_imm(mcode);
+ }
+
+ pv += offset;
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(void *addr, int nbytes)
+{
+ /* don't know yet */
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(void *addr, int nbytes)
+{
+ /* XXX don't know yet */
+ /* printf("md_dcacheflush\n"); */
+ __asm__ __volatile__ ( "membar 0x7F" : : : "memory" );
+}
+
+#endif /* _VM_JIT_SPARC64_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "mm/memory.h"
-#include "vm/jit/sparc64/md-abi.h"
#include "vm/jit/sparc64/codegen.h"
+#include "vm/jit/sparc64/md.h"
+#include "vm/jit/sparc64/md-abi.h"
#include "native/native.h"
#include "vm/builtin.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/patcher.h"
-#include "vm/jit/md.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/stacktrace.h"
#include "vm/jit/sparc64/solaris/macro_rename.h"
+
/* patcher_wrapper *************************************************************
Wrapper for all patchers. It also creates the stackframe info
#include "vm/types.h"
+#include "md.h"
+
#include "mm/gc-common.h"
#include "mm/memory.h"
/* machine dependent functions (code in ARCH_DIR/md.c) */
#if defined(ENABLE_JIT)
-u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize);
# if defined(__SPARC_64__)
u1 *md_get_framepointer(u1 *sp);
u1 *md_get_pv_from_stackframe(u1 *sp);
#include "vm/types.h"
#include "vm/jit/x86_64/codegen.h"
+#include "vm/jit/x86_64/md.h"
#if defined(ENABLE_THREADS)
# include "threads/native/threads.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
/* md_init *********************************************************************
}
-/* 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 x86_64 the return address is above the current stack frame */
-
- ra = *((u1 **) (sp + framesize));
-
- return ra;
-}
-
-
/* md_jit_method_patch_address *************************************************
Gets the patch address of the currently compiled method. The offset
}
-/* md_codegen_get_pv_from_pc ***************************************************
-
- On this architecture just a wrapper function to
- codegen_get_pv_from_pc.
-
-*******************************************************************************/
-
-u1 *md_codegen_get_pv_from_pc(u1 *ra)
-{
- u1 *pv;
-
- /* Get the start address of the function which contains this
- address from the method table. */
-
- pv = codegen_get_pv_from_pc(ra);
-
- return pv;
-}
-
-
-/* md_cacheflush ***************************************************************
-
- Calls the system's function to flush the instruction and data
- cache.
-
-*******************************************************************************/
-
-void md_cacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
-/* md_icacheflush **************************************************************
-
- Calls the system's function to flush the instruction cache.
-
-*******************************************************************************/
-
-void md_icacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
-/* md_dcacheflush **************************************************************
-
- Calls the system's function to flush the data cache.
-
-*******************************************************************************/
-
-void md_dcacheflush(u1 *addr, s4 nbytes)
-{
- /* do nothing */
-}
-
-
/* md_patch_replacement_point **************************************************
Patch the given replacement point.
}
#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
--- /dev/null
+/* src/vm/jit/x86_64/md.c - machine dependent x86_64 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
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _VM_JIT_X86_64_MD_H
+#define _VM_JIT_X86_64_MD_H
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/jit/codegen-common.h"
+
+
+/* inline functions ***********************************************************/
+
+/* md_stacktrace_get_returnaddress *********************************************
+
+ Returns the return address of the current stackframe, specified by
+ the passed stack pointer and the stack frame size.
+
+*******************************************************************************/
+
+inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+ void *ra;
+
+ /* On x86_64 the return address is above the current stack
+ frame. */
+
+ ra = *((void **) (((uintptr_t) sp) + stackframesize));
+
+ return ra;
+}
+
+
+/* md_codegen_get_pv_from_pc ***************************************************
+
+ On this architecture just a wrapper function to
+ codegen_get_pv_from_pc.
+
+*******************************************************************************/
+
+inline static void *md_codegen_get_pv_from_pc(void *ra)
+{
+ void *pv;
+
+ /* Get the start address of the function which contains this
+ address from the method table. */
+
+ pv = codegen_get_pv_from_pc(ra);
+
+ return pv;
+}
+
+
+/* md_cacheflush ***************************************************************
+
+ Calls the system's function to flush the instruction and data
+ cache.
+
+*******************************************************************************/
+
+inline static void md_cacheflush(u1 *addr, s4 nbytes)
+{
+ /* do nothing */
+}
+
+
+/* md_icacheflush **************************************************************
+
+ Calls the system's function to flush the instruction cache.
+
+*******************************************************************************/
+
+inline static void md_icacheflush(u1 *addr, s4 nbytes)
+{
+ /* do nothing */
+}
+
+
+/* md_dcacheflush **************************************************************
+
+ Calls the system's function to flush the data cache.
+
+*******************************************************************************/
+
+inline static void md_dcacheflush(u1 *addr, s4 nbytes)
+{
+ /* do nothing */
+}
+
+#endif /* _VM_JIT_X86_64_MD_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */