* src/vm/jit/i386/darwin/md-asm.h: Repaired --enable-cycles-stats.
[cacao.git] / src / vm / jit / arm / md.c
index e97ca5df4a968b6266a75c98561c8e68f8913bea..b6450a27858e90ca53d6140ccbdc0734746d9968 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: md.c 8185 2007-07-05 21:34:47Z michi $
-
 */
 
 
 #include "config.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"
-
-#include "vm/jit/codegen-common.h" /* REMOVE ME: for codegendata */
-
 
 /* md_init *********************************************************************
 
@@ -56,28 +46,7 @@ void md_init(void)
 }
 
 
-/* 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_assembler_get_patch_address **********************************************
+/* md_jit_method_patch_address *************************************************
 
    Gets the patch address of the currently compiled method. The offset
    is extracted from the load instruction(s) before the jump and added
@@ -105,21 +74,29 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
 
 *******************************************************************************/
 
-u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
+void *md_jit_method_patch_address(void *pv, void *ra, void *mptr)
 {
-       u4  mcode;
-       s4  offset;
-       u1 *pa;                             /* patch address                      */
+       uint32_t *pc;
+       uint32_t  mcode;
+       int32_t   offset;
+       void     *pa;                       /* patch address                      */
+
+       /* Go back to the actual load instruction. */
+
+       pc = ((uint32_t *) ra) - 3;
+
+       /* Get first instruction word on current PC. */
+
+       mcode = pc[0];
 
        /* sanity check: are we inside jit code? */
 
-       assert(*((u4 *) (ra - 2*4)) == 0xe1a0e00f /*MOV LR,PC*/);
-       assert(*((u4 *) (ra - 1*4)) == 0xe1a0f00c /*MOV PC,IP*/);
+       assert(pc[1] == 0xe1a0e00f /*MOV LR,PC*/);
+       assert(pc[2] == 0xe1a0f00c /*MOV PC,IP*/);
 
        /* get the load instruction and offset */
 
-       mcode  = *((u4 *) (ra - 12));
-       offset = (s4) (mcode & 0x0fff);
+       offset = (int32_t) (mcode & 0x0fff);
 
        assert ((mcode & 0xff70f000) == 0xe510c000);
 
@@ -135,7 +112,7 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 
                /* we loaded from REG_METHODPTR */
 
-               pa = mptr + offset;
+               pa = ((uint8_t *) mptr) + offset;
        }
        else {
                /* sanity check: we loaded from REG_IP; offset was negative or zero */
@@ -145,99 +122,25 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 
                /* we loaded from data segment; offset can be larger */
 
-               mcode = *((u4 *) (ra - 4*4));
+               mcode = pc[-1];
 
                /* check for "SUB IP, IP, #??, ROTL 12" */
 
                if ((mcode & 0xffffff00) == 0xe24cca00)
-                       offset += (s4) ((mcode & 0x00ff) << 12);
+                       offset += (int32_t) ((mcode & 0x00ff) << 12);
 
                /* and get the final data segment address */
 
-               pa = sfi->pv - offset;        
+               pa = ((uint8_t *) pv) - offset;        
        }
 
        return pa;
 }
 
 
-/* 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-4) == (s4)true || *((s4*)pv-4) == (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)
 {
-       asm_cacheflush(addr, nbytes);
+       return md_codegen_get_pv_from_pc(ra);
 }