/* 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 *************************************************************/
#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);
#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); \
#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); \
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); \
#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
#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)
#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)
#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) */