Merged revisions 7501-7598 via svnmerge from
[cacao.git] / src / vm / jit / alpha / md.c
index 96519b0fd0857fed793261e57caf222955ba8169..1aef1bad18a3691f664747805fd5a63ce3906d91 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 $
 
 */
 
@@ -53,9 +45,15 @@ extern void ieee_set_fp_control(unsigned long fp_control);
 
 #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 ***********************************************************/
 
@@ -110,25 +108,33 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
 }
 
 
-/* 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;
@@ -174,6 +180,11 @@ u1 *md_assembler_get_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
                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 {
@@ -191,7 +202,7 @@ u1 *md_assembler_get_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 }
 
 
-/* md_codegen_findmethod *******************************************************
+/* md_codegen_get_pv_from_pc ***************************************************
 
    Machine code:
 
@@ -201,7 +212,7 @@ u1 *md_assembler_get_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 
 *******************************************************************************/
 
-u1 *md_codegen_findmethod(u1 *ra)
+u1 *md_codegen_get_pv_from_pc(u1 *ra)
 {
        u1 *pv;
        u4  mcode;
@@ -229,8 +240,8 @@ u1 *md_codegen_findmethod(u1 *ra)
 
                offset = (s2) (mcode & 0x0000ffff);
                pv += offset;
-
-       else {
+       }
+       else {
                /* get displacement of first instruction (lda) */
 
                assert((mcode >> 16) == 0x237a);
@@ -268,6 +279,52 @@ void md_icacheflush(u1 *addr, s4 nbytes)
 }
 
 
+/* 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
@@ -279,4 +336,5 @@ void md_icacheflush(u1 *addr, s4 nbytes)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */