/* 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)
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
#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); \
#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);
#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 */
#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)
#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 */
#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
/* 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.
} else if(IS_IMM(-(val))) { \
M_CMN_IMM(reg, -(val)); \
} else { \
+ assert((reg) != REG_ITMP3); \
ICONST(REG_ITMP3, (val)); \
M_CMP(reg, REG_ITMP3); \
}