* src/vm/jit/i386/codegen.h (vm/jit/i386/emit.h): Added.
[cacao.git] / src / vm / jit / alpha / md.c
index fcf70eb0502f254073be075636f19b79e297c796..e6e94bccc7d6f012d174f0092a3c2ac1efdf289e 100644 (file)
 
    Authors: Andreas Krall
             Reinhard Grafl
-
-   Changes: Joseph Wenninger
+            Joseph Wenninger
             Christian Thalinger
+            Edwin Steiner
 
-   $Id: md.c 4498 2006-02-12 23:43:09Z twisti $
+   $Id: md.c 5948 2006-11-11 16:56:48Z twisti $
 
 */
 
@@ -56,6 +56,11 @@ extern void ieee_set_fp_control(unsigned long fp_control);
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.h"
 
+#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
+#include "vm/options.h" /* XXX debug */
+#include "vm/jit/disass.h" /* XXX debug */
+#endif
+
 
 /* global variables ***********************************************************/
 
@@ -91,6 +96,42 @@ void md_init(void)
 }
 
 
+/* md_codegen_patch_branch *****************************************************
+
+   Back-patches a branch instruction.
+
+*******************************************************************************/
+
+void md_codegen_patch_branch(codegendata *cd, s4 branchmpc, s4 targetmpc)
+{
+       s4 *mcodeptr;
+       s4  mcode;
+       s4  disp;                           /* branch displacement                */
+
+       /* calculate the patch position */
+
+       mcodeptr = (s4 *) (cd->mcodebase + branchmpc);
+
+       /* get the instruction before the exception point */
+
+       mcode = mcodeptr[-1];
+
+       /* Calculate the branch displacement.  For branches we need a
+          displacement relative and shifted to the branch PC. */
+
+       disp = (targetmpc - branchmpc) >> 2;
+
+       /* check branch displacement */
+
+       if ((disp < (s4) 0xffe00000) || (disp > (s4) 0x001fffff))
+               vm_abort("branch displacement is out of range: %d > +/-%d", disp, 0x001fffff);
+
+       /* patch the branch instruction before the mcodeptr */
+
+       mcodeptr[-1] |= (disp & 0x001fffff);
+}
+
+
 /* md_stacktrace_get_returnaddress *********************************************
 
    Returns the return address of the current stackframe, specified by
@@ -110,25 +151,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;
@@ -191,7 +240,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 +250,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 +278,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);
@@ -243,6 +292,62 @@ u1 *md_codegen_findmethod(u1 *ra)
 }
 
 
+/* 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_patch_replacement_point **************************************************
+
+   Patch the given replacement point.
+
+*******************************************************************************/
+
+void md_patch_replacement_point(rplpoint *rp)
+{
+    u8 mcode;
+
+       /* save the current machine code */
+       mcode = *(u4*)rp->pc;
+
+       /* write the new machine code */
+    *(u4*)(rp->pc) = (u4) rp->mcode;
+
+       /* store saved mcode */
+       rp->mcode = mcode;
+       
+#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
+       {
+               u1* u1ptr = rp->pc;
+               DISASSINSTR(u1ptr);
+               fflush(stdout);
+       }
+#endif
+                       
+       /* flush instruction cache */
+    md_icacheflush(rp->pc,4);
+}
+
 /*
  * 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
@@ -254,4 +359,5 @@ u1 *md_codegen_findmethod(u1 *ra)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */