/* src/vm/jit/alpha/md.c - 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: Andreas Krall
- Reinhard Grafl
-
- Changes: Joseph Wenninger
- Christian Thalinger
-
- $Id: md.c 4634 2006-03-16 15:16:16Z twisti $
+ $Id: md.c 7596 2007-03-28 21:05:53Z twisti $
*/
#include "vm/exceptions.h"
#include "vm/stringlocal.h"
+
#include "vm/jit/asmpart.h"
#include "vm/jit/stacktrace.h"
+#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
+#include "vmcore/options.h" /* XXX debug */
+#include "vm/jit/disass.h" /* XXX debug */
+#endif
+
/* global variables ***********************************************************/
}
-/* md_assembler_get_patch_address **********************************************
+/* md_get_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).
- Machine code:
+ INVOKESTATIC/SPECIAL:
a77bffb8 ldq pv,-72(pv)
6b5b4000 jsr (pv)
- or
+ INVOKEVIRTUAL:
+ a7900000 ldq at,0(a0)
a77c0000 ldq pv,0(at)
6b5b4000 jsr (pv)
+ INVOKEINTERFACE:
+
+ a7900000 ldq at,0(a0)
+ a79cff98 ldq at,-104(at)
+ a77c0018 ldq pv,24(at)
+ 6b5b4000 jsr (pv)
+
*******************************************************************************/
-u1 *md_assembler_get_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
+u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
{
u4 mcode;
s4 offset;
if ((mcode >> 16) == 0xa77c) {
/* in this case we use the passed method pointer */
+ /* return NULL if no mptr was specified (used for replacement) */
+
+ if (mptr == NULL)
+ return NULL;
+
pa = mptr + offset;
} else {
}
-/* md_codegen_findmethod *******************************************************
+/* md_codegen_get_pv_from_pc ***************************************************
Machine code:
*******************************************************************************/
-u1 *md_codegen_findmethod(u1 *ra)
+u1 *md_codegen_get_pv_from_pc(u1 *ra)
{
u1 *pv;
u4 mcode;
offset = (s2) (mcode & 0x0000ffff);
pv += offset;
-
- } else {
+ }
+ else {
/* get displacement of first instruction (lda) */
assert((mcode >> 16) == 0x237a);
}
+/* md_patch_replacement_point **************************************************
+
+ Patch the given replacement point.
+
+*******************************************************************************/
+
+#if defined(ENABLE_REPLACEMENT)
+void md_patch_replacement_point(codeinfo *code, s4 index, rplpoint *rp, u1 *savedmcode)
+{
+ s4 disp;
+ u4 mcode;
+
+ if (index < 0) {
+ /* restore the patched-over instruction */
+ *(u4*)(rp->pc) = *(u4*)(savedmcode);
+ }
+ else {
+ /* save the current machine code */
+ *(u4*)(savedmcode) = *(u4*)(rp->pc);
+
+ /* build the machine code for the patch */
+ disp = ((u4*)code->replacementstubs - (u4*)rp->pc)
+ + index * REPLACEMENT_STUB_SIZE
+ - 1;
+
+ /* BR */
+ mcode = (((s4) (0x30)) << 26) | ((REG_ZERO) << 21) | ((disp) & 0x1fffff);
+
+ /* write the new machine code */
+ *(u4*)(rp->pc) = mcode;
+ }
+
+#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) && 0
+ {
+ u1* u1ptr = rp->pc;
+ DISASSINSTR(u1ptr);
+ fflush(stdout);
+ }
+#endif
+
+ /* flush instruction cache */
+ md_icacheflush(rp->pc,4);
+}
+#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
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/