* src/vm/jit/arm/arch.h (USES_NEW_SUBTYPE): Added define.
[cacao.git] / src / vm / jit / arm / codegen.h
index 9432f05a5d1d07b72b6991cd7c7c4dde32fb98e0..0191858b85e41bd36c910966dd224d36d1cc6276 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/codegen.h - code generation macros and definitions for ARM
 
-   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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 /******************************************************************************/
 
 #if defined(__ARMEL__)
-#define SPLIT_OPEN(type, reg, tmpreg) \
+
+# define SPLIT_OPEN(type, reg, tmpreg) \
        if (IS_2_WORD_TYPE(type) && GET_HIGH_REG(reg)==REG_SPLIT) { \
                /*dolog("SPLIT_OPEN({R%d;SPL} > {R%d;R%d})", GET_LOW_REG(reg), GET_LOW_REG(reg), tmpreg);*/ \
                /*assert(GET_LOW_REG(reg) == 3);*/ \
                (reg) = PACK_REGS(GET_LOW_REG(reg), tmpreg); \
        }
-#define SPLIT_LOAD(type, reg, offset) \
-       if (IS_2_WORD_TYPE(type) && GET_LOW_REG(reg)==3) { \
-               /*dolog("SPLIT_LOAD({R%d;R%d} from [%x])", GET_LOW_REG(reg), GET_HIGH_REG(reg), offset);*/ \
-               M_LDR(GET_HIGH_REG(reg), REG_SP, 4 * (offset)); \
-       }
-#define SPLIT_STORE_AND_CLOSE(type, reg, offset) \
+
+# define SPLIT_STORE_AND_CLOSE(type, reg, offset) \
        if (IS_2_WORD_TYPE(type) && GET_LOW_REG(reg)==3) { \
                /*dolog("SPLIT_STORE({R%d;R%d} to [%x])", GET_LOW_REG(reg), GET_HIGH_REG(reg), offset);*/ \
                M_STR(GET_HIGH_REG(reg), REG_SP, 4 * (offset)); \
                (reg) = PACK_REGS(GET_LOW_REG(reg), REG_SPLIT); \
        }
+
 #else /* defined(__ARMEB__) */
-#define SPLIT_OPEN(type, reg, tmpreg) \
+
+# define SPLIT_OPEN(type, reg, tmpreg) \
        if (IS_2_WORD_TYPE(type) && GET_LOW_REG(reg)==REG_SPLIT) { \
                /*dolog("SPLIT_OPEN({SPL;R%d} > {R%d;R%d})", GET_HIGH_REG(reg), tmpreg, GET_HIGH_REG(reg));*/ \
                /*assert(GET_HIGH_REG(reg) == 3);*/ \
                (reg) = PACK_REGS(tmpreg, GET_HIGH_REG(reg)); \
        }
-#define SPLIT_LOAD(type, reg, offset) \
-       if (IS_2_WORD_TYPE(type) && GET_HIGH_REG(reg)==3) { \
-               /*dolog("SPLIT_LOAD({R%d;R%d} from [%x])", GET_LOW_REG(reg), GET_HIGH_REG(reg), offset);*/ \
-               M_LDR(GET_LOW_REG(reg), REG_SP, 4 * (offset)); \
-       }
-#define SPLIT_STORE_AND_CLOSE(type, reg, offset) \
+
+# define SPLIT_STORE_AND_CLOSE(type, reg, offset) \
        if (IS_2_WORD_TYPE(type) && GET_HIGH_REG(reg)==3) { \
                /*dolog("SPLIT_STORE({R%d;R%d} to [%x])", GET_LOW_REG(reg), GET_HIGH_REG(reg), offset);*/ \
                M_STR(GET_LOW_REG(reg), REG_SP, 4 * (offset)); \
                (reg) = PACK_REGS(REG_SPLIT, GET_HIGH_REG(reg)); \
        }
+
 #endif
 
 
     } while (0)
 
 
-/* stub defines ***************************************************************/
-
-#define COMPILERSTUB_CODESIZE    2 * 4
-
-
 /* lazy debugger **************************************************************/
 
 #if !defined(NDEBUG)
@@ -197,6 +186,9 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
         cd->mcodeptr += 4; \
     } while (0)
 
+#define M_MEM_GET_Rd(mcode)    (((mcode) >> 12) & 0x0f)
+#define M_MEM_GET_Rbase(mcode) (((mcode) >> 16) & 0x0f)
+
 
 /* load and store instruction: M_MEM2
    cond ... conditional execution
@@ -498,6 +490,9 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #define M_LDMFD(regs,base) M_MEM_MULTI(UNCOND,1,0,regs,base,0,1,1)
 #define M_STMFD(regs,base) M_MEM_MULTI(UNCOND,0,0,regs,base,1,0,1)
 
+#define M_LDR_REG(d,base,offreg) M_MEM(UNCOND,1,0,d,base,offreg,1,1,1,0)
+#define M_STR_REG(d,base,offreg) M_MEM(UNCOND,0,0,d,base,offreg,1,1,1,0)
+
 #define M_LDR_INTERN(d,base,off) \
     do { \
         CHECK_OFFSET(off, 0x0fff); \
@@ -561,6 +556,8 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 
 #define M_TRAP(a,i)        M_UNDEFINED(UNCOND,i,a);
 #define M_TRAPEQ(a,i)      M_UNDEFINED(COND_EQ,i,a);
+#define M_TRAPNE(a,i)      M_UNDEFINED(COND_NE,i,a);
+#define M_TRAPLT(a,i)      M_UNDEFINED(COND_LT,i,a);
 #define M_TRAPLE(a,i)      M_UNDEFINED(COND_LE,i,a);
 #define M_TRAPHI(a,i)      M_UNDEFINED(COND_HI,i,a);
 #define M_TRAPHS(a,i)      M_UNDEFINED(COND_CS,i,a);
@@ -654,6 +651,7 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #if !defined(ENABLE_SOFTFLOAT)
 
 #if defined(__VFP_FP__)
+
 #define M_FADD(a,b,d)      M_CPDP(UNCOND,0,1,1,0,10,0,0,0,d,a,b)/* d = a +  b */
 #define M_FSUB(a,b,d)      M_CPDP(UNCOND,0,1,1,1,10,0,0,0,d,a,b)/* d = a -  b */
 #define M_FMUL(a,b,d)      M_CPDP(UNCOND,0,1,0,0,10,0,0,0,d,a,b)/* d = a *  b */
@@ -675,8 +673,8 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #define M_CVTFD(a,d)       M_CPDP(UNCOND,1,1,1,1,10,0,1,0,d,0x7,a)
 #define M_CVTIF(a,d)       M_CPDP(UNCOND,1,1,1,1,10,0,1,0,d,0x8,a)
 #define M_CVTID(a,d)       M_CPDP(UNCOND,1,1,1,1,11,0,1,0,d,0x8,a)
-#define M_CVTFI(a,d)       M_CPDP(UNCOND,1,1,1,1,10,0,1,0,d,0xc,a)
-#define M_CVTDI(a,d)       M_CPDP(UNCOND,1,1,1,1,11,0,1,0,d,0xc,a)
+#define M_CVTFI(a,d)       M_CPDP(UNCOND,1,1,1,1,10,0,1,0,d,0xd,a) // ftosis
+#define M_CVTDI(a,d)       M_CPDP(UNCOND,1,1,1,1,11,0,1,0,d,0xd,a) // ftosid
 
 #define M_FMSTAT           M_CPRT(UNCOND,0x07,1,10,0,0x1,0xf)
 
@@ -686,7 +684,9 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #define M_FMRDL(Fa,b)      M_CPRT(UNCOND,0x00,1,11,0,Fa,b)
 #define M_FMDHR(a,Fb)      M_CPRT(UNCOND,0x01,0,11,0,Fb,a)
 #define M_FMRDH(Fa,b)      M_CPRT(UNCOND,0x01,1,11,0,Fa,b)
+
 #else
+
 #define M_FADD(a,b,d)      M_CPDOS(UNCOND,0x00,0,d,a,b)         /* d = a +  b */
 #define M_FSUB(a,b,d)      M_CPDOS(UNCOND,0x02,0,d,a,b)         /* d = a -  b */
 #define M_FMUL(a,b,d)      M_CPDOS(UNCOND,0x01,0,d,a,b)         /* d = a *  b */
@@ -712,6 +712,7 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #define M_CVTID(a,d)       M_CPRTD(UNCOND,0,a,d,0)              /* d = (float) a */
 #define M_CVTFI(a,d)       M_CPRTI(UNCOND,1,d,0,a)              /* d = (int)   a */
 #define M_CVTDI(a,d)       M_CPRTI(UNCOND,1,d,0,a)              /* d = (int)   a */
+
 #endif
 
 
@@ -1107,15 +1108,22 @@ do { \
 /* M_RECOMPUTE_PV:
    used to recompute our PV (we use the IP for this) out of the current PC
    ATTENTION: if you change this, you have to look at other functions as well!
-   Following things depend on it: asm_call_jit_compiler(); codegen_findmethod();
+   Following things depend on it: md_codegen_get_pv_from_pc();
 */
 #define M_RECOMPUTE_PV(disp) \
        disp += 8; /* we use PC relative addr.  */ \
        assert((disp & 0x03) == 0); \
        assert(disp >= 0 && disp <= 0x03ffffff); \
-       M_SUB_IMM(REG_PV, REG_PC, IMM_ROTL(disp >> 2, 1)); \
-       if (disp > 0x000003ff) M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 10, 5)); \
-       if (disp > 0x0003ffff) M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 18, 9)); \
+       if (disp > 0x0003ffff) { \
+               M_SUB_IMM(REG_PV, REG_PC, IMM_ROTL(disp >> 18, 9)); \
+               M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 10, 5)); \
+               M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 2, 1)); \
+       } else if (disp > 0x000003ff) { \
+               M_SUB_IMM(REG_PV, REG_PC, IMM_ROTL(disp >> 10, 5)); \
+               M_SUB_IMM(REG_PV, REG_PV, IMM_ROTL(disp >> 2, 1)); \
+       } else { \
+               M_SUB_IMM(REG_PV, REG_PC, IMM_ROTL(disp >> 2, 1)); \
+       }
 
 /* M_INTMOVE:
    generates an integer-move from register a to b.
@@ -1152,6 +1160,7 @@ do { \
        } else if(IS_IMM(-(val))) { \
                M_CMN_IMM(reg, -(val)); \
        } else { \
+               assert((reg) != REG_ITMP3); \
                ICONST(REG_ITMP3, (val)); \
                M_CMP(reg, REG_ITMP3); \
        }