Fixes icedtea/PR 513.
[cacao.git] / src / vm / jit / arm / codegen.h
index 448f99476b570afe6c8b40703c75e190f6161e56..c18e324a9f6af1ea14d77d7470eb7a3dce93097a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/arm/codegen.h - code generation macros and definitions for ARM
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2005, 2006, 2007, 2008, 2010
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
             codegen_increase(cd); \
     } while (0)
 
+#define ALIGNCODENOP /* empty */
 
 /* TODO: correct this! */
 #define IS_IMM(val) ( ((val) >= 0) && ((val) <= 255) )
 #define IS_OFFSET(off,max) ((s4)(off) <= (max) && (s4)(off) >= -(max))
 
-#if !defined(NDEBUG)
-# define CHECK_INT_REG(r) if ((r)<0 || (r)>15) printf("CHECK_INT_REG: this is not an integer register: %d\n", r); assert((r)>=0 && (r)<=15)
-# define CHECK_FLT_REG(r) if ((r)<0 || (r)>7) printf("CHECK_FLT_REG: this is not an float register: %d\n", r); assert((r)>=0 && (r)<=7)
-# define CHECK_OFFSET(off,max) \
-       if (!IS_OFFSET(off,max)) printf("CHECK_OFFSET: offset out of range: %x (>%x) SEVERE ERROR!!!\n", ((off)<0)?-(off):off, max); \
-       assert(IS_OFFSET(off,max))
-#else
-# define CHECK_INT_REG(r)
-# define CHECK_FLT_REG(r)
-# define CHECK_OFFSET(off,max)
-#endif
+#define CHECK_INT_REG(r)              assert((r)>=0 && (r)<=15)
+#define CHECK_FLT_REG(r)              assert((r)>=0 && (r)<=7)
+#define CHECK_OFFSET(off,max)         assert(IS_OFFSET(off,max))
 
 
 /* branch defines *************************************************************/
@@ -186,6 +179,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
@@ -487,6 +483,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); \
@@ -550,6 +549,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);
@@ -643,6 +644,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 */
@@ -664,8 +666,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)
 
@@ -675,7 +677,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 */
@@ -701,6 +705,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
 
 
@@ -956,11 +961,11 @@ do { \
 
 #define M_STR(d, base, offset) \
 do { \
-       assert((d) != REG_ITMP3); \
        CHECK_OFFSET(offset, 0x0fffff); \
        if (IS_OFFSET(offset, 0x000fff)) { \
                M_STR_INTERN(d, base, offset); \
        } else { \
+               assert((d) != REG_ITMP3); \
                if ((offset) > 0) { \
                        M_ADD_IMM(REG_ITMP3, base, IMM_ROTL((offset) >> 12, 6)); \
                        M_STR_INTERN(d, REG_ITMP3, (offset) & 0x000fff); \
@@ -973,8 +978,6 @@ do { \
 
 #define M_STRD(d, base, offset) \
 do { \
-       assert(GET_LOW_REG(d) != REG_ITMP3); \
-       assert(GET_HIGH_REG(d) != REG_ITMP3); \
        CHECK_OFFSET(offset, 0x0fffff - 4); \
        if (IS_OFFSET(offset, 0x000fff - 4)) { \
                M_STRD_INTERN(d,base,offset); \
@@ -982,6 +985,8 @@ do { \
                dolog("M_STRD: this offset seems to be complicated (%d)", offset); \
                assert(0); \
        } else { \
+               assert(GET_LOW_REG(d) != REG_ITMP3); \
+               assert(GET_HIGH_REG(d) != REG_ITMP3); \
                if ((offset) > 0) { \
                        M_ADD_IMM(REG_ITMP3, base, IMM_ROTL((offset) >> 12, 6)); \
                        M_STRD_INTERN(d, REG_ITMP3, (offset) & 0x000fff); \
@@ -1093,65 +1098,6 @@ do { \
 #endif /* !defined(ENABLE_SOFTFLOAT) */
 
 
-/* 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: 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); \
-       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.
-   if a and b are the same int-register, no code will be generated.
-*/
-
-#define M_INTMOVE(a,b) \
-    do { \
-        if ((a) != (b)) \
-            M_MOV(b, a); \
-    } while (0)
-
-#define M_LNGMOVE(a,b) \
-    do { \
-        if (GET_HIGH_REG(a) == GET_LOW_REG(b)) { \
-            assert((GET_LOW_REG(a) != GET_HIGH_REG(b))); \
-            M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
-            M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
-        } else { \
-            M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
-            M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
-        } \
-    } while (0)
-
-
-/* M_COMPARE:
-   generates the compare part of an if-sequece
-   uses M_CMP or M_CMP_IMM to do the compare
-   ATTENTION: uses REG_ITMP3 as intermediate register
-*/
-#define M_COMPARE(reg, val) \
-       if (IS_IMM(val)) { \
-               M_CMP_IMM(reg, (val)); \
-       } else if(IS_IMM(-(val))) { \
-               M_CMN_IMM(reg, -(val)); \
-       } else { \
-               ICONST(REG_ITMP3, (val)); \
-               M_CMP(reg, REG_ITMP3); \
-       }
-
 /* M_LONGBRANCH:
    performs a long branch to an absolute address with return address in LR
    takes up 3 bytes of code space; address is hard-coded into code
@@ -1190,6 +1136,7 @@ do { \
 
 #define M_ALD(a,b,c)                    M_ILD(a,b,c)
 #define M_ALD_INTERN(a,b,c)             M_ILD_INTERN(a,b,c)
+#define M_ALD_DSEG(a,c)                 M_DSEG_LOAD(a,c)
 
 
 #define M_IST(a,b,c)                    M_STR(a,b,c)
@@ -1202,6 +1149,13 @@ do { \
 #define M_AST_INTERN(a,b,c)             M_IST_INTERN(a,b,c)
 
 
+#define M_ACMP(a,b)                     M_CMP(a,b)
+#define M_ICMP(a,b)                     M_CMP(a,b)
+
+
+#define M_TEST(a)                       M_TEQ_IMM(a, 0);
+
+
 #if !defined(ENABLE_SOFTFLOAT)
 
 #define M_FLD(a,b,c)                    M_LDFS(a,b,c)
@@ -1210,6 +1164,15 @@ do { \
 #define M_FST(a,b,c)                    M_STFS(a,b,c)
 #define M_DST(a,b,c)                    M_STFD(a,b,c)
 
+#else /* !defined(ENABLE_SOFTFLOAT) */
+
+#define M_FMOV(s,d)                     M_MOV((d), (s))
+#define M_DMOV(s,d) \
+       { \
+               M_MOV(GET_LOW_REG(d), GET_LOW_REG(s)); \
+               M_MOV(GET_HIGH_REG(d), GET_HIGH_REG(s)); \
+       }
+
 #endif /* !defined(ENABLE_SOFTFLOAT) */