Fixes icedtea/PR 513.
[cacao.git] / src / vm / jit / arm / codegen.h
index 5cca08322e78a37d9986d371280aeeeadc8913f6..c18e324a9f6af1ea14d77d7470eb7a3dce93097a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/codegen.h - code generation macros and definitions for ARM
 
-   Copyright (C) 1996-2005, 2006 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, 2010
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Michael Starzinger
-            Christian Thalinger
-
-   $Id: codegen.h 6591 2007-01-02 19:14:25Z twisti $
-
 */
 
 
 #include "config.h"
 
 
-/* helper macros for generating code ******************************************/
-
-/* load_var_to_reg_xxx:
-   this function generates code to fetch data from a pseudo-register
-   into a real register. 
-   If the pseudo-register has actually been assigned to a real 
-   register, no code will be emitted, since following operations
-   can use this register directly.
-   v:      pseudoregister to be fetched from
-   tempnr: temporary register to be used if v is actually spilled to ram
-   regnr:  the register number, where the operand can be found after 
-           fetching (this wil be either tempregnum or the register
-           number allready given to v)
-*/
+/******************************************************************************/
+/* register splitting stuff (ugly) ********************************************/
+/******************************************************************************/
 
 #if defined(__ARMEL__)
-#define load_var_to_reg_lng(regnr,v,tempnr) { \
-       if ((v)->flags & INMEMORY) { \
-               COUNT_SPILLS; \
-               M_STACK_LOAD_LNG(tempnr, (v)->regoff); \
-               regnr = tempnr; \
-       } else if (GET_HIGH_REG((v)->regoff)==REG_SPLIT) { \
-               M_LDR_INTERN(GET_HIGH_REG(tempnr), REG_SP, 0); /* TODO: where to load? */ \
-               regnr = PACK_REGS(GET_LOW_REG((v)->regoff), GET_HIGH_REG(tempnr)); \
-       } else regnr = (v)->regoff; \
-}
-#else /* defined(__ARMEB__) */
-#define load_var_to_reg_lng(regnr,v,tempnr) { \
-        if ((v)->flags & INMEMORY) { \
-                COUNT_SPILLS; \
-                M_STACK_LOAD_LNG(tempnr, (v)->regoff); \
-                regnr = tempnr; \
-        } else if (GET_LOW_REG((v)->regoff)==REG_SPLIT) { \
-                M_LDR_INTERN(GET_LOW_REG(tempnr), REG_SP, 0); /* TODO: where to load? */ \
-                regnr = PACK_REGS(GET_LOW_REG(tempnr), GET_HIGH_REG((v)->regoff)); \
-        } else regnr = (v)->regoff; \
-}
-#endif
 
-
-/* store_reg_to_var_xxx:
-   This function generates the code to store the result of an operation
-   back into a spilled pseudo-variable.
-   If the pseudo-variable has not been spilled in the first place, this 
-   function will generate nothing.
-   v:      Pseudovariable
-   tempnr: Number of the temporary registers as returned by
-           reg_of_var.
-*/
-
-#if defined(__ARMEL__)
-#define store_reg_to_var_lng(v,tempnr) { \
-       if ((v)->flags & INMEMORY) { \
-               COUNT_SPILLS; \
-               M_STACK_STORE_LNG(tempnr, (v)->regoff); \
-       } else if (GET_HIGH_REG((v)->regoff)==REG_SPLIT) { \
-               M_STR_INTERN(GET_HIGH_REG(tempnr), REG_SP, 0); /* TODO: where to store? */ \
-       } \
-}
-#else /* defined(__ARMEB__) */
-#define store_reg_to_var_lng(v,tempnr) { \
-        if ((v)->flags & INMEMORY) { \
-                COUNT_SPILLS; \
-                M_STACK_STORE_LNG(tempnr, (v)->regoff); \
-        } else if (GET_LOW_REG((v)->regoff)==REG_SPLIT) { \
-                M_STR_INTERN(GET_LOW_REG(tempnr), REG_SP, 0); /* TODO: where to store? */ \
-        } \
-}
-#endif
-
-#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
 
 
+/******************************************************************************/
+/* checking macros ************************************************************/
+/******************************************************************************/
+
 #define MCODECHECK(icnt) \
     do { \
         if ((cd->mcodeptr + (icnt) * 4) > cd->mcodeend) \
             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 *************************************************************/
@@ -206,7 +124,9 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #endif
 
 
+/******************************************************************************/
 /* macros to create code ******************************************************/
+/******************************************************************************/
 
 /* the condition field */
 #define COND_EQ 0x0  /* Equal        Z set   */
@@ -259,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
@@ -339,6 +262,15 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
     } while (0)
 
 
+/* undefined instruction used for hardware exceptions */
+
+#define M_UNDEFINED(cond,imm,n) \
+       do { \
+               *((u4 *) cd->mcodeptr) = ((cond) << 28) | (0x7f << 20) | (((imm) & 0x0fff) << 8) | (0x0f << 4) | (n); \
+               cd->mcodeptr += 4; \
+       } while (0)
+
+
 #if !defined(ENABLE_SOFTFLOAT)
 
 /* M_CPDO **********************************************************************
@@ -368,6 +300,13 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
     } while (0)
 
 
+#define M_CPDP(cond,p,q,r,s,cp_num,D,N,M,Fd,Fn,Fm) \
+       do { \
+               *((u4 *) cd->mcodeptr) = (((cond) << 28) | (0x0e << 24) | ((p) << 23) | ((q) << 21) | ((r) << 20) | ((s) << 6) | ((cp_num) << 8) | ((D) << 22) | ((N) << 7) | ((M) << 5) | ((Fd) << 12) | ((Fn) << 16) | ((Fm) & 0x0f)); \
+               cd->mcodeptr += 4; \
+       } while (0)
+
+
 /* M_CPDT **********************************************************************
 
    Floating-Point Coprocessor Data Transfer
@@ -385,6 +324,12 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
         cd->mcodeptr += 4; \
     } while (0)
 
+#define M_CPLS(cond,L,P,U,W,cp_num,D,Fd,n,off) \
+       do { \
+               *((u4 *) cd->mcodeptr) = (((cond) << 28) | (0x0c << 24) | ((P) << 24) | ((U) << 23) | ((W) << 21) | ((L) << 20) | ((cp_num) << 8) | ((D) << 22) | ((Fd) << 12) | ((n) << 16) | ((off) & 0xff)); \
+               cd->mcodeptr += 4; \
+       } while (0)
+
 
 /* M_CPRT **********************************************************************
 
@@ -394,6 +339,12 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 
 *******************************************************************************/
 
+#define M_CPRT(cond,op,L,cp_num,N,Fn,n) \
+       do { \
+               *((u4 *) cd->mcodeptr) = (((cond) << 28) | (0x0e << 24) | (1 << 4) | ((op) << 21) | ((L) << 20) | ((cp_num) << 8) | ((N) << 7) | ((Fn) << 16) | ((n) << 12)); \
+               cd->mcodeptr += 4; \
+       } while (0)
+
 #define M_CPRTS(cond,L,d,Fn,Fm) \
     do { \
         *((u4 *) cd->mcodeptr) = (((cond) << 28) | (0x0e << 24) | (1 << 8) | (1 << 4) | ((L) << 20) | ((d) << 12) | ((Fn) << 16) | (Fm)); \
@@ -447,21 +398,25 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #define IMM_ROTR(imm, rot) ( ((imm) & 0xff) | (((rot) & 0x0f) << 8) )
 #define IMM_ROTL(imm, rot) IMM_ROTR(imm, 16-(rot))
 
-/* macros for all arm instructions ********************************************/
+
+/******************************************************************************/
+/* macros for all basic arm instructions **************************************/
+/******************************************************************************/
 
 #define M_ADD(d,a,b)       M_DAT(UNCOND,0x04,d,a,0,0,b)         /* d = a +  b */
 #define M_ADC(d,a,b)       M_DAT(UNCOND,0x05,d,a,0,0,b)         /* d = a +  b (with Carry) */
 #define M_SUB(d,a,b)       M_DAT(UNCOND,0x02,d,a,0,0,b)         /* d = a -  b */
 #define M_SBC(d,a,b)       M_DAT(UNCOND,0x06,d,a,0,0,b)         /* d = a -  b (with Carry) */
-#define M_AND(d,a,b)       M_DAT(UNCOND,0x00,d,a,0,0,b)         /* d = a &  b */
-#define M_ORR(d,a,b)       M_DAT(UNCOND,0x0c,d,a,0,0,b)         /* d = a |  b */
-#define M_EOR(d,a,b)       M_DAT(UNCOND,0x01,d,a,0,0,b)         /* d = a ^  b */
+#define M_AND(a,b,d)       M_DAT(UNCOND,0x00,d,a,0,0,b)         /* d = a &  b */
+#define M_ORR(a,b,d)       M_DAT(UNCOND,0x0c,d,a,0,0,b)         /* d = a |  b */
+#define M_EOR(a,b,d)       M_DAT(UNCOND,0x01,d,a,0,0,b)         /* d = a ^  b */
 #define M_TST(a,b)         M_DAT(UNCOND,0x08,0,a,1,0,b)         /* TST a &  b */
 #define M_TEQ(a,b)         M_DAT(UNCOND,0x09,0,a,1,0,b)         /* TST a ^  b */
 #define M_CMP(a,b)         M_DAT(UNCOND,0x0a,0,a,1,0,b)         /* TST a -  b */
 #define M_MOV(d,b)         M_DAT(UNCOND,0x0d,d,0,0,0,b)         /* d =      b */
 #define M_ADD_S(d,a,b)     M_DAT(UNCOND,0x04,d,a,1,0,b)         /* d = a +  b (update Flags) */
 #define M_SUB_S(d,a,b)     M_DAT(UNCOND,0x02,d,a,1,0,b)         /* d = a -  b (update Flags) */
+#define M_ORR_S(a,b,d)     M_DAT(UNCOND,0x0c,d,a,1,0,b)         /* d = a |  b (update flags) */
 #define M_MOV_S(d,b)       M_DAT(UNCOND,0x0d,d,0,1,0,b)         /* d =      b (update Flags) */
 
 #define M_ADD_IMM(d,a,i)   M_DAT(UNCOND,0x04,d,a,0,1,i)         /* d = a +  i */
@@ -470,7 +425,7 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #define M_SBC_IMM(d,a,i)   M_DAT(UNCOND,0x06,d,a,0,1,i)         /* d = a -  i (with Carry) */
 #define M_RSB_IMM(d,a,i)   M_DAT(UNCOND,0x03,d,a,0,1,i)         /* d = -a + i */
 #define M_RSC_IMM(d,a,i)   M_DAT(UNCOND,0x07,d,a,0,1,i)         /* d = -a + i (with Carry) */
-#define M_AND_IMM(d,a,i)   M_DAT(UNCOND,0x00,d,a,0,1,i)         /* d = a &  i */
+#define M_AND_IMM(a,i,d)   M_DAT(UNCOND,0x00,d,a,0,1,i)         /* d = a &  i */
 #define M_TST_IMM(a,i)     M_DAT(UNCOND,0x08,0,a,1,1,i)         /* TST a &  i */
 #define M_TEQ_IMM(a,i)     M_DAT(UNCOND,0x09,0,a,1,1,i)         /* TST a ^  i */
 #define M_CMP_IMM(a,i)     M_DAT(UNCOND,0x0a,0,a,1,1,i)         /* TST a -  i */
@@ -481,23 +436,56 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #define M_RSB_IMMS(d,a,i)  M_DAT(UNCOND,0x03,d,a,1,1,i)         /* d = -a + i (update Flags) */
 
 #define M_ADDSUB_IMM(d,a,i) if((i)>=0) M_ADD_IMM(d,a,i); else M_SUB_IMM(d,a,-(i))
-#define M_MOVEQ(d,b)       M_DAT(COND_EQ,0x0d,d,0,0,0,b)
-#define M_MOVVS_IMM(d,i)   M_DAT(COND_VS,0x0d,d,0,0,1,i)
-#define M_MOVNE_IMM(d,i)   M_DAT(COND_NE,0x0d,d,0,0,1,i)
-#define M_MOVLS_IMM(d,i)   M_DAT(COND_LS,0x0d,d,0,0,1,i)
+#define M_MOVEQ(a,d)       M_DAT(COND_EQ,0x0d,d,0,0,0,a)
+#define M_EORLE(d,a,b)     M_DAT(COND_LE,0x01,d,a,0,0,b)
+
+#define M_MOVVS_IMM(i,d)   M_DAT(COND_VS,0x0d,d,0,0,1,i)
+#define M_MOVEQ_IMM(i,d)   M_DAT(COND_EQ,0x0d,d,0,0,1,i)
+#define M_MOVNE_IMM(i,d)   M_DAT(COND_NE,0x0d,d,0,0,1,i)
+#define M_MOVLT_IMM(i,d)   M_DAT(COND_LT,0x0d,d,0,0,1,i)
+#define M_MOVGT_IMM(i,d)   M_DAT(COND_GT,0x0d,d,0,0,1,i)
+#define M_MOVLS_IMM(i,d)   M_DAT(COND_LS,0x0d,d,0,0,1,i)
+
+#define M_ADDHI_IMM(d,a,i) M_DAT(COND_HI,0x04,d,a,0,1,i)
 #define M_ADDLT_IMM(d,a,i) M_DAT(COND_LT,0x04,d,a,0,1,i)
 #define M_ADDGT_IMM(d,a,i) M_DAT(COND_GT,0x04,d,a,0,1,i)
+#define M_SUBLO_IMM(d,a,i) M_DAT(COND_CC,0x02,d,a,0,1,i)
 #define M_SUBLT_IMM(d,a,i) M_DAT(COND_LT,0x02,d,a,0,1,i)
 #define M_SUBGT_IMM(d,a,i) M_DAT(COND_GT,0x02,d,a,0,1,i)
 #define M_RSBMI_IMM(d,a,i) M_DAT(COND_MI,0x03,d,a,0,1,i)
 #define M_ADCMI_IMM(d,a,i) M_DAT(COND_MI,0x05,d,a,0,1,i)
 
+#define M_CMPEQ(a,b)       M_DAT(COND_EQ,0x0a,0,a,1,0,b)        /* TST a -  b */
+#define M_CMPLE(a,b)       M_DAT(COND_LE,0x0a,0,a,1,0,b)        /* TST a -  b */
+
+#define M_CMPEQ_IMM(a,i)   M_DAT(COND_EQ,0x0a,0,a,1,1,i)
+
 #define M_MUL(d,a,b)       M_MULT(UNCOND,d,a,b,0,0,0x0)         /* d = a *  b */
 
+#define M_B(off)           M_BRA(UNCOND,0,off)    /* unconditional branch */
+#define M_BL(off)          M_BRA(UNCOND,1,off)    /* branch and link      */
+#define M_BEQ(off)         M_BRA(COND_EQ,0,off)   /* conditional branches */
+#define M_BNE(off)         M_BRA(COND_NE,0,off)
+#define M_BGE(off)         M_BRA(COND_GE,0,off)
+#define M_BGT(off)         M_BRA(COND_GT,0,off)
+#define M_BLT(off)         M_BRA(COND_LT,0,off)
+#define M_BLE(off)         M_BRA(COND_LE,0,off)
+#define M_BHI(off)         M_BRA(COND_HI,0,off)   /* unsigned conditional */
+#define M_BHS(off)         M_BRA(COND_CS,0,off)
+#define M_BLO(off)         M_BRA(COND_CC,0,off)
+#define M_BLS(off)         M_BRA(COND_LS,0,off)
+
+
+/******************************************************************************/
+/* macros for load and store instructions *************************************/
+/******************************************************************************/
 
 #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); \
@@ -558,97 +546,14 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
         M_MEM(UNCOND,0,1,d,base,off,0,1,1,0); \
     } while (0)
 
-                                                                                                     
-#if !defined(ENABLE_SOFTFLOAT)
 
-#define M_LDFS_INTERN(d,base,off) \
-    do { \
-        CHECK_OFFSET(off, 0x03ff); \
-        M_CPDT(UNCOND,1,0,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),0); \
-    } while (0)
-
-#define M_LDFD_INTERN(d,base,off) \
-    do { \
-        CHECK_OFFSET(off, 0x03ff); \
-        M_CPDT(UNCOND,1,0,1,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),0); \
-    } while (0)
-
-#define M_STFS_INTERN(d,base,off) \
-    do { \
-        CHECK_OFFSET(off, 0x03ff); \
-        M_CPDT(UNCOND,0,0,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),0); \
-    } while (0)
-
-#define M_STFD_INTERN(d,base,off) \
-    do { \
-        CHECK_OFFSET(off, 0x03ff); \
-        M_CPDT(UNCOND,0,0,1,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),0); \
-    } while (0)
-
-#define M_LDFS_UPDATE(d,base,off) \
-    do { \
-        CHECK_OFFSET(off, 0x03ff); \
-        M_CPDT(UNCOND,1,0,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),0,(((off) < 0) ? 0 : 1),1); \
-    } while (0)
-
-#define M_LDFD_UPDATE(d,base,off) \
-    do { \
-        CHECK_OFFSET(off, 0x03ff); \
-        M_CPDT(UNCOND,1,0,1,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),0,(((off) < 0) ? 0 : 1),1); \
-    } while (0)
-
-#define M_STFS_UPDATE(d,base,off) \
-    do { \
-        CHECK_OFFSET(off, 0x03ff); \
-        M_CPDT(UNCOND,0,0,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),1); \
-    } while (0)
-
-#define M_STFD_UPDATE(d,base,off) \
-    do { \
-        CHECK_OFFSET(off, 0x03ff); \
-        M_CPDT(UNCOND,0,0,1,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),1); \
-    } while (0)
-
-#define M_ADFS(d,a,b)      M_CPDOS(UNCOND,0x00,0,d,a,b)         /* d = a +  b */
-#define M_SUFS(d,a,b)      M_CPDOS(UNCOND,0x02,0,d,a,b)         /* d = a -  b */
-#define M_RSFS(d,a,b)      M_CPDOS(UNCOND,0x03,0,d,a,b)         /* d = b -  a */
-#define M_MUFS(d,a,b)      M_CPDOS(UNCOND,0x01,0,d,a,b)         /* d = a *  b */
-#define M_DVFS(d,a,b)      M_CPDOS(UNCOND,0x04,0,d,a,b)         /* d = a /  b */
-#define M_RMFS(d,a,b)      M_CPDOS(UNCOND,0x08,0,d,a,b)         /* d = a %  b */
-#define M_ADFD(d,a,b)      M_CPDOD(UNCOND,0x00,0,d,a,b)         /* d = a +  b */
-#define M_SUFD(d,a,b)      M_CPDOD(UNCOND,0x02,0,d,a,b)         /* d = a -  b */
-#define M_RSFD(d,a,b)      M_CPDOD(UNCOND,0x03,0,d,a,b)         /* d = b -  a */
-#define M_MUFD(d,a,b)      M_CPDOD(UNCOND,0x01,0,d,a,b)         /* d = a *  b */
-#define M_DVFD(d,a,b)      M_CPDOD(UNCOND,0x04,0,d,a,b)         /* d = a /  b */
-#define M_RMFD(d,a,b)      M_CPDOD(UNCOND,0x08,0,d,a,b)         /* d = a %  b */
-#define M_MVFS(d,a)        M_CPDOS(UNCOND,0x00,1,d,0,a)         /* d =      a */
-#define M_MVFD(d,a)        M_CPDOD(UNCOND,0x00,1,d,0,a)         /* d =      a */
-#define M_MNFS(d,a)        M_CPDOS(UNCOND,0x01,1,d,0,a)         /* d =    - a */
-#define M_MNFD(d,a)        M_CPDOD(UNCOND,0x01,1,d,0,a)         /* d =    - a */
-#define M_CMF(a,b)         M_CPRTX(UNCOND,1,0x0f,a,b)           /* COMPARE a;  b */
-#define M_FLTS(d,a)        M_CPRTS(UNCOND,0,a,d,0)              /* d = (float) a */
-#define M_FLTD(d,a)        M_CPRTD(UNCOND,0,a,d,0)              /* d = (float) a */
-#define M_FIX(d,a)         M_CPRTI(UNCOND,1,d,0,a)              /* d = (int)   a */
-
-#endif /* !defined(ENABLE_SOFTFLOAT) */
-
-
-#define M_B(off)           M_BRA(UNCOND,0,off)    /* unconditional branch */
-#define M_BL(off)          M_BRA(UNCOND,1,off)    /* branch and link      */
-#define M_BEQ(off)         M_BRA(COND_EQ,0,off)   /* conditional branches */
-#define M_BNE(off)         M_BRA(COND_NE,0,off)
-#define M_BGE(off)         M_BRA(COND_GE,0,off)
-#define M_BGT(off)         M_BRA(COND_GT,0,off)
-#define M_BLT(off)         M_BRA(COND_LT,0,off)
-#define M_BLE(off)         M_BRA(COND_LE,0,off)
-#define M_BHI(off)         M_BRA(COND_HI,0,off)   /* unsigned conditional */
-#define M_BHS(off)         M_BRA(COND_CS,0,off)
-#define M_BLO(off)         M_BRA(COND_CC,0,off)
-#define M_BLS(off)         M_BRA(COND_LS,0,off)
-
-
-#define M_FMOV(a,b)        M_MVFS(b,a)
-#define M_DMOV(a,b)        M_MVFD(b,a)
+#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 we do not have double-word load/store command, we can fake them */
@@ -732,6 +637,227 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #endif /* defined(__ARMEB__) */
 
 
+/******************************************************************************/
+/* macros for all floating point instructions *********************************/
+/******************************************************************************/
+
+#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_FDIV(a,b,d)      M_CPDP(UNCOND,1,0,0,0,10,0,0,0,d,a,b)/* d = a /  b */
+#define M_DADD(a,b,d)      M_CPDP(UNCOND,0,1,1,0,11,0,0,0,d,a,b)/* d = a +  b */
+#define M_DSUB(a,b,d)      M_CPDP(UNCOND,0,1,1,1,11,0,0,0,d,a,b)/* d = a -  b */
+#define M_DMUL(a,b,d)      M_CPDP(UNCOND,0,1,0,0,11,0,0,0,d,a,b)/* d = a *  b */
+#define M_DDIV(a,b,d)      M_CPDP(UNCOND,1,0,0,0,11,0,0,0,d,a,b)/* d = a /  b */
+
+#define M_FMOV(a,d)        M_CPDP(UNCOND,1,1,1,1,10,0,0,0,d,0x0,a)
+#define M_DMOV(a,d)        M_CPDP(UNCOND,1,1,1,1,11,0,0,0,d,0x0,a)
+#define M_FNEG(a,d)        M_CPDP(UNCOND,1,1,1,1,10,0,0,0,d,0x1,a)
+#define M_DNEG(a,d)        M_CPDP(UNCOND,1,1,1,1,11,0,0,0,d,0x1,a)
+
+#define M_FCMP(a,b)        M_CPDP(UNCOND,1,1,1,1,10,0,0,0,a,0x4,b)
+#define M_DCMP(a,b)        M_CPDP(UNCOND,1,1,1,1,11,0,0,0,a,0x4,b)
+
+#define M_CVTDF(a,d)       M_CPDP(UNCOND,1,1,1,1,11,0,1,0,d,0x7,a)
+#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,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_FMSR(a,Fb)       M_CPRT(UNCOND,0x00,0,10,0,Fb,a)
+#define M_FMRS(Fa,b)       M_CPRT(UNCOND,0x00,1,10,0,Fa,b)
+#define M_FMDLR(a,Fb)      M_CPRT(UNCOND,0x00,0,11,0,Fb,a)
+#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_FDIV(a,b,d)      M_CPDOS(UNCOND,0x04,0,d,a,b)         /* d = a /  b */
+#define M_RMFS(d,a,b)      M_CPDOS(UNCOND,0x08,0,d,a,b)         /* d = a %  b */
+#define M_DADD(a,b,d)      M_CPDOD(UNCOND,0x00,0,d,a,b)         /* d = a +  b */
+#define M_DSUB(a,b,d)      M_CPDOD(UNCOND,0x02,0,d,a,b)         /* d = a -  b */
+#define M_DMUL(a,b,d)      M_CPDOD(UNCOND,0x01,0,d,a,b)         /* d = a *  b */
+#define M_DDIV(a,b,d)      M_CPDOD(UNCOND,0x04,0,d,a,b)         /* d = a /  b */
+#define M_RMFD(d,a,b)      M_CPDOD(UNCOND,0x08,0,d,a,b)         /* d = a %  b */
+
+#define M_FMOV(a,d)        M_CPDOS(UNCOND,0x00,1,d,0,a)         /* d =      a */
+#define M_DMOV(a,d)        M_CPDOD(UNCOND,0x00,1,d,0,a)         /* d =      a */
+#define M_FNEG(a,d)        M_CPDOS(UNCOND,0x01,1,d,0,a)         /* d =    - a */
+#define M_DNEG(a,d)        M_CPDOD(UNCOND,0x01,1,d,0,a)         /* d =    - a */
+
+#define M_FCMP(a,b)        M_CPRTX(UNCOND,1,0x0f,a,b)           /* COMPARE a;  b */
+#define M_DCMP(a,b)        M_CPRTX(UNCOND,1,0x0f,a,b)           /* COMPARE a;  b */
+
+#define M_CVTDF(a,b)       M_FMOV(a,b)
+#define M_CVTFD(a,b)       M_DMOV(a,b)
+#define M_CVTIF(a,d)       M_CPRTS(UNCOND,0,a,d,0)              /* d = (float) a */
+#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_CAST_x2x:
+   loads the value of the integer-register a (argument or result) into
+   float-register Fb. (and vice versa)
+*/
+
+#if defined(__VFP_FP__)
+
+#define M_CAST_I2F(a,Fb) M_FMSR(a,Fb)
+
+#define M_CAST_F2I(Fa,b) M_FMRS(Fa,b)
+
+#define M_CAST_L2D(a,Fb) \
+       do { \
+               M_FMDLR(GET_LOW_REG(a), Fb); \
+               M_FMDHR(GET_HIGH_REG(a), Fb); \
+       } while (0)
+
+#define M_CAST_D2L(Fa,b) \
+       do { \
+               M_FMRDL(Fa, GET_LOW_REG(b)); \
+               M_FMRDH(Fa, GET_HIGH_REG(b)); \
+       } while (0)
+
+#else
+
+#define M_CAST_I2F(a,Fb) \
+       do { \
+               CHECK_FLT_REG(Fb); \
+               CHECK_INT_REG(a); \
+               M_STR_UPDATE(a, REG_SP, -4); \
+               M_FLD_UPDATE(Fb, REG_SP, 4); \
+       } while (0)
+
+#define M_CAST_L2D(a,Fb) \
+       do { \
+               CHECK_FLT_REG(Fb); \
+               CHECK_INT_REG(GET_LOW_REG(a)); \
+               CHECK_INT_REG(GET_HIGH_REG(a)); \
+               M_STRD_UPDATE(a, REG_SP, -8); \
+               M_DLD_UPDATE(Fb, REG_SP, 8); \
+       } while (0)
+
+#define M_CAST_F2I(Fa,b) \
+       do { \
+               CHECK_FLT_REG(Fa); \
+               CHECK_INT_REG(b); \
+               M_FST_UPDATE(Fa, REG_SP, -4); \
+               M_LDR_UPDATE(b, REG_SP, 4); \
+       } while (0)
+
+#define M_CAST_D2L(Fa,b) \
+       do { \
+               CHECK_INT_REG(GET_LOW_REG(b)); \
+               CHECK_INT_REG(GET_HIGH_REG(b)); \
+               M_DST_UPDATE(Fa, REG_SP, -8); \
+               M_LDRD_UPDATE(b, REG_SP, 8); \
+       } while (0)
+
+#endif
+
+/* M_xLD_xx & M_xST_xx:
+   XXX document me!
+*/
+
+#if defined(__VFP_FP__)
+
+#define M_FLD_INTERN(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPLS(UNCOND,1,1,(((off) < 0) ? 0 : 1),0,10,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2)); \
+    } while (0)
+
+#define M_DLD_INTERN(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+               M_CPLS(UNCOND,1,1,(((off) < 0) ? 0 : 1),0,11,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2)); \
+    } while (0)
+
+#define M_FST_INTERN(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+               M_CPLS(UNCOND,0,1,(((off) < 0) ? 0 : 1),0,10,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2)); \
+    } while (0)
+
+#define M_DST_INTERN(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+               M_CPLS(UNCOND,0,1,(((off) < 0) ? 0 : 1),0,11,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2)); \
+    } while (0)
+
+#else
+
+#define M_FLD_INTERN(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPDT(UNCOND,1,0,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),0); \
+    } while (0)
+
+#define M_DLD_INTERN(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPDT(UNCOND,1,0,1,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),0); \
+    } while (0)
+
+#define M_FST_INTERN(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPDT(UNCOND,0,0,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),0); \
+    } while (0)
+
+#define M_DST_INTERN(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPDT(UNCOND,0,0,1,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),0); \
+    } while (0)
+
+#define M_FLD_UPDATE(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPDT(UNCOND,1,0,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),0,(((off) < 0) ? 0 : 1),1); \
+    } while (0)
+
+#define M_DLD_UPDATE(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPDT(UNCOND,1,0,1,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),0,(((off) < 0) ? 0 : 1),1); \
+    } while (0)
+
+#define M_FST_UPDATE(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPDT(UNCOND,0,0,0,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),1); \
+    } while (0)
+
+#define M_DST_UPDATE(d,base,off) \
+    do { \
+        CHECK_OFFSET(off, 0x03ff); \
+        M_CPDT(UNCOND,0,0,1,d,base,(((off) < 0) ? -(off) >> 2 : (off) >> 2),1,(((off) < 0) ? 0 : 1),1); \
+    } while (0)
+
+#endif
+
+#endif /* !defined(ENABLE_SOFTFLOAT) */
+
+
+/******************************************************************************/
+/* wrapper macros for load and store instructions *****************************/
+/******************************************************************************/
+
 /* M_LDR/M_STR:
    these are replacements for the original LDR/STR instructions, which can
    handle longer offsets (up to 20bits). the original functions are now
@@ -798,18 +924,19 @@ do { \
 } while (0)
 
 #if !defined(ENABLE_SOFTFLOAT)
+
 #define M_LDFS(d, base, offset) \
 do { \
        CHECK_OFFSET(offset, 0x03ffff); \
        if (IS_OFFSET(offset, 0x03ff)) { \
-               M_LDFS_INTERN(d, base, offset); \
+               M_FLD_INTERN(d, base, offset); \
        } else { \
                if ((offset) > 0) { \
                        M_ADD_IMM(REG_ITMP3, base, IMM_ROTL((offset) >> 10, 5)); \
-                       M_LDFS_INTERN(d, REG_ITMP3, (offset) & 0x03ff); \
+                       M_FLD_INTERN(d, REG_ITMP3, (offset) & 0x03ff); \
                } else { \
                        M_SUB_IMM(REG_ITMP3, base, IMM_ROTL((-(offset)) >> 10, 5)); \
-                       M_LDFS_INTERN(d, REG_ITMP3, -(-(offset) & 0x03ff)); \
+                       M_FLD_INTERN(d, REG_ITMP3, -(-(offset) & 0x03ff)); \
                } \
        } \
 } while (0)
@@ -818,14 +945,14 @@ do { \
 do { \
        CHECK_OFFSET(offset, 0x03ffff); \
        if (IS_OFFSET(offset, 0x03ff)) { \
-               M_LDFD_INTERN(d, base, offset); \
+               M_DLD_INTERN(d, base, offset); \
        } else { \
                if ((offset) > 0) { \
                        M_ADD_IMM(REG_ITMP3, base, IMM_ROTL((offset) >> 10, 5)); \
-                       M_LDFD_INTERN(d, REG_ITMP3, (offset) & 0x03ff); \
+                       M_DLD_INTERN(d, REG_ITMP3, (offset) & 0x03ff); \
                } else { \
                        M_SUB_IMM(REG_ITMP3, base, IMM_ROTL((-(offset)) >> 10, 5)); \
-                       M_LDFD_INTERN(d, REG_ITMP3, -(-(offset) & 0x03ff)); \
+                       M_DLD_INTERN(d, REG_ITMP3, -(-(offset) & 0x03ff)); \
                } \
        } \
 } while (0)
@@ -834,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); \
@@ -851,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); \
@@ -860,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); \
@@ -876,14 +1003,14 @@ do { \
 do { \
        CHECK_OFFSET(offset, 0x03ffff); \
        if (IS_OFFSET(offset, 0x03ff)) { \
-               M_STFS_INTERN(d, base, offset); \
+               M_FST_INTERN(d, base, offset); \
        } else { \
                if ((offset) > 0) { \
                        M_ADD_IMM(REG_ITMP3, base, IMM_ROTL((offset) >> 10, 5)); \
-                       M_STFS_INTERN(d, REG_ITMP3, (offset) & 0x03ff); \
+                       M_FST_INTERN(d, REG_ITMP3, (offset) & 0x03ff); \
                } else { \
                        M_SUB_IMM(REG_ITMP3, base, IMM_ROTL((-(offset)) >> 10, 5)); \
-                       M_STFS_INTERN(d, REG_ITMP3, -(-(offset) & 0x03ff)); \
+                       M_FST_INTERN(d, REG_ITMP3, -(-(offset) & 0x03ff)); \
                } \
        } \
 } while (0)
@@ -892,36 +1019,47 @@ do { \
 do { \
        CHECK_OFFSET(offset, 0x03ffff); \
        if (IS_OFFSET(offset, 0x03ff)) { \
-               M_STFD_INTERN(d, base, offset); \
+               M_DST_INTERN(d, base, offset); \
        } else { \
                if ((offset) > 0) { \
                        M_ADD_IMM(REG_ITMP3, base, IMM_ROTL((offset) >> 10, 5)); \
-                       M_STFD_INTERN(d, REG_ITMP3, (offset) & 0x03ff); \
+                       M_DST_INTERN(d, REG_ITMP3, (offset) & 0x03ff); \
                } else { \
                        M_SUB_IMM(REG_ITMP3, base, IMM_ROTL((-(offset)) >> 10, 5)); \
-                       M_STFD_INTERN(d, REG_ITMP3, -(-(offset) & 0x03ff)); \
+                       M_DST_INTERN(d, REG_ITMP3, -(-(offset) & 0x03ff)); \
                } \
        } \
 } while (0)
 
 #endif /* !defined(ENABLE_SOFTFLOAT) */
 
+
+/******************************************************************************/
+/* additional helper macros ***************************************************/
+/******************************************************************************/
+
 /* M_???_IMM_EXT_MUL4:
    extended immediate operations, to handle immediates lager than 8bit.
    ATTENTION: the immediate is rotatet left by 2 (multiplied by 4)!!!
 */
+
 #define M_ADD_IMM_EXT_MUL4(d,n,imm) \
-       assert(d!=REG_PC); \
-       assert((imm) >= 0 && (imm) <= 0x00ffffff); \
-       M_ADD_IMM(d, n, IMM_ROTL(imm, 1)); \
-       if ((imm) > 0x000000ff) M_ADD_IMM(d, d, IMM_ROTL((imm) >>  8, 5)); \
-       if ((imm) > 0x0000ffff) M_ADD_IMM(d, d, IMM_ROTL((imm) >> 16, 9));
+    do { \
+        assert(d != REG_PC); \
+        assert((imm) >= 0 && (imm) <= 0x00ffffff); \
+        M_ADD_IMM(d, n, IMM_ROTL(imm, 1)); \
+        if ((imm) > 0x000000ff) M_ADD_IMM(d, d, IMM_ROTL((imm) >>  8, 5)); \
+        if ((imm) > 0x0000ffff) M_ADD_IMM(d, d, IMM_ROTL((imm) >> 16, 9)); \
+    } while (0)
+
 #define M_SUB_IMM_EXT_MUL4(d,n,imm) \
-       assert(d!=REG_PC); \
-       assert((imm) >= 0 && (imm) <= 0x00ffffff); \
-       M_SUB_IMM(d, n, IMM_ROTL(imm, 1)); \
-       if ((imm) > 0x000000ff) M_SUB_IMM(d, d, IMM_ROTL((imm) >>  8, 5)); \
-       if ((imm) > 0x0000ffff) M_SUB_IMM(d, d, IMM_ROTL((imm) >> 16, 9));
+    do { \
+        assert(d != REG_PC); \
+        assert((imm) >= 0 && (imm) <= 0x00ffffff); \
+        M_SUB_IMM(d, n, IMM_ROTL(imm, 1)); \
+        if ((imm) > 0x000000ff) M_SUB_IMM(d, d, IMM_ROTL((imm) >>  8, 5)); \
+        if ((imm) > 0x0000ffff) M_SUB_IMM(d, d, IMM_ROTL((imm) >> 16, 9)); \
+    } while (0)
 
 
 /* ICONST/LCONST:
@@ -930,15 +1068,6 @@ do { \
 
 #define ICONST(d,c)                     emit_iconst(cd, (d), (c))
 
-#define ICONST_CONDITIONAL(cond,d,const) \
-       if (IS_IMM(const)) { \
-               /* M_MOV_IMM */ M_DAT(cond,0x0d,d,0,0,1,const); \
-       } else { \
-               disp = dseg_adds4(cd, const); \
-               /* TODO: implement this using M_DSEG_LOAD!!! */ \
-               /* M_LDR_INTERN */ CHECK_OFFSET(disp,0x0fff); M_MEM(cond,1,0,d,REG_IP,(disp<0)?-disp:disp,0,1,(disp<0)?0:1,0); \
-       }
-
 #define LCONST(d,c) \
        if (IS_IMM((c) >> 32)) { \
                M_MOV_IMM(GET_HIGH_REG(d), (s4) ((s8) (c) >> 32)); \
@@ -948,7 +1077,7 @@ do { \
                ICONST(GET_HIGH_REG(d), (s4) ((s8) (c) >> 32)); \
        } else { \
                disp = dseg_add_s8(cd, (c)); \
-               M_LDRD(d, REG_IP, disp); \
+               M_LDRD(d, REG_PV, disp); \
        }
 
 
@@ -957,127 +1086,18 @@ do { \
 #define FCONST(d,c) \
     do { \
         disp = dseg_add_float(cd, (c)); \
-        M_LDFS(d, REG_IP, disp); \
+        M_LDFS(d, REG_PV, disp); \
     } while (0)
 
 #define DCONST(d,c) \
     do { \
         disp = dseg_add_double(cd, (c)); \
-        M_LDFD(d, REG_IP, disp); \
+        M_LDFD(d, REG_PV, disp); \
     } while (0)
 
 #endif /* !defined(ENABLE_SOFTFLOAT) */
 
 
-/* M_RECOMPUTE_IP:
-   used to recompute our IP (something like PV) 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();
-*/
-#define M_RECOMPUTE_IP(disp) \
-       disp += 8; /* we use PC relative addr.  */ \
-       assert((disp & 0x03) == 0); \
-       assert(disp >= 0 && disp <= 0x03ffffff); \
-       M_SUB_IMM(REG_IP, REG_PC, IMM_ROTL(disp >> 2, 1)); \
-       if (disp > 0x000003ff) M_SUB_IMM(REG_IP, REG_IP, IMM_ROTL(disp >> 10, 5)); \
-       if (disp > 0x0003ffff) M_SUB_IMM(REG_IP, REG_IP, IMM_ROTL(disp >> 18, 9)); \
-
-/* 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)
-
-
-#if !defined(ENABLE_SOFTFLOAT)
-
-/* M_FLTMOVE:
-   generates a floating-point-move from register a to b.
-   if a and b are the same float-register, no code will be generated.
-*/
-
-#define M_FLTMOVE(a,b) \
-    do { \
-        if ((a) != (b)) \
-            M_FMOV(a, b); \
-    } while (0)
-
-#define M_DBLMOVE(a,b) \
-    do { \
-        if ((a) != (b)) \
-            M_DMOV(a, b); \
-    } while (0)
-
-#endif
-
-#if !defined(ENABLE_SOFTFLOAT)
-/* M_CAST_INT_TO_FLT_TYPED:
-   loads the value of the integer-register a (argument or result) into
-   float-register Fb. (and vice versa)
-*/
-#define M_CAST_INT_TO_FLT_TYPED(t,a,Fb) \
-       CHECK_FLT_REG(Fb); \
-       if ((t) == TYPE_FLT) { \
-               CHECK_INT_REG(a); \
-               M_STR_UPDATE(a, REG_SP, -4); \
-               M_LDFS_UPDATE(Fb, REG_SP, 4); \
-       } else { \
-               CHECK_INT_REG(GET_LOW_REG(a)); \
-               CHECK_INT_REG(GET_HIGH_REG(a)); \
-               M_STRD_UPDATE(a, REG_SP, -8); \
-               M_LDFD_UPDATE(Fb, REG_SP, 8); \
-       }
-#define M_CAST_FLT_TO_INT_TYPED(t,Fa,b) \
-       CHECK_FLT_REG(Fa); \
-       if ((t) == TYPE_FLT) { \
-               CHECK_INT_REG(b); \
-               M_STFS_UPDATE(Fa, REG_SP, -4); \
-               M_LDR_UPDATE(b, REG_SP, 4); \
-       } else { \
-               CHECK_INT_REG(GET_LOW_REG(b)); \
-               CHECK_INT_REG(GET_HIGH_REG(b)); \
-               M_STFD_UPDATE(Fa, REG_SP, -8); \
-               M_LDRD_UPDATE(b, REG_SP, 8); \
-       }
-#endif /* !defined(ENABLE_SOFTFLOAT) */
-
-
-/* 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
-*/
-/* TODO: improve this and add some comments! */
-#define M_COMPARE(reg, val, cond, overjump) \
-       if (IS_IMM(val)) { \
-               if (overjump) M_BNE(1); \
-               /* M_CMP_IMM */ M_DAT(cond,0x0a,0,(reg),1,1,(val)); \
-       } else if(IS_IMM(-(val))) { \
-               if (overjump) M_BNE(1); \
-               /* M_CMN_IMM */ M_DAT(cond,0x0b,0,(reg),1,1,-(val)); \
-       } else { \
-               ICONST(REG_ITMP3, (val)); \
-               if (overjump) M_BNE(1); \
-               /* M_CMP */ M_DAT(cond,0x0a,0,(reg),1,0,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
@@ -1093,31 +1113,20 @@ do { \
    ATTENTION: we use M_LDR, so the same restrictions apply to us!
 */
 #define M_DSEG_LOAD(reg, offset) \
-       M_LDR_NEGATIVE(reg, REG_IP, offset)
+       M_LDR_NEGATIVE(reg, REG_PV, offset)
 
 #define M_DSEG_BRANCH(offset) \
        if (IS_OFFSET(offset, 0x0fff)) { \
                M_MOV(REG_LR, REG_PC); \
-               M_LDR_INTERN(REG_PC, REG_IP, offset); \
+               M_LDR_INTERN(REG_PC, REG_PV, offset); \
        } else { \
                /*assert((offset) <= 0);*/ \
                CHECK_OFFSET(offset,0x0fffff); \
-               M_SUB_IMM(REG_ITMP3, REG_IP, ((-(offset) >>  12) & 0xff) | (((10) & 0x0f) << 8)); /*TODO: more to go*/ \
+               M_SUB_IMM(REG_ITMP3, REG_PV, ((-(offset) >>  12) & 0xff) | (((10) & 0x0f) << 8)); /*TODO: more to go*/ \
                M_MOV(REG_LR, REG_PC); \
                M_LDR_INTERN(REG_PC, REG_ITMP3, -(-(offset) & 0x0fff)); /*TODO: this looks ugly*/ \
        }
 
-/* M_STACK_LOAD/STORE:
-   loads or stores integer values from register to stack or from stack to register
-   ATTENTION: we use M_LDR and M_STR, so the same restrictions apply to us!
-*/
-
-#define M_STACK_LOAD_LNG(reg, offset) { \
-       CHECK_INT_REG(GET_LOW_REG(reg)); \
-       CHECK_INT_REG(GET_HIGH_REG(reg)); \
-       M_LDRD(reg, REG_SP, (offset) * 4); \
-}
-
 
 #define M_ILD(a,b,c)                    M_LDR(a,b,c)
 #define M_LLD(a,b,c)                    M_LDRD(a,b,c)
@@ -1127,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)
@@ -1139,92 +1149,32 @@ do { \
 #define M_AST_INTERN(a,b,c)             M_IST_INTERN(a,b,c)
 
 
-#if !defined(ENABLE_SOFTFLOAT)
+#define M_ACMP(a,b)                     M_CMP(a,b)
+#define M_ICMP(a,b)                     M_CMP(a,b)
 
-#define M_STACK_LOAD_FLT_TYPED(t, reg, offset) { \
-       CHECK_FLT_REG(reg); \
-       if (IS_2_WORD_TYPE(t)) { \
-               M_LDFD(reg, REG_SP, (offset) * 4); \
-       } else { \
-               M_LDFS(reg, REG_SP, (offset) * 4); \
-       } \
-}
 
-#define M_FLD(a,b,c)                    M_LDFS(a,b,c)
-#define M_DLD(a,b,c)                    M_LDFD(a,b,c)
+#define M_TEST(a)                       M_TEQ_IMM(a, 0);
 
-#define M_FLD_INTERN(a,b,c)             M_LDFS_INTERN(a,b,c)
-#define M_DLD_INTERN(a,b,c)             M_LDFD_INTERN(a,b,c)
 
+#if !defined(ENABLE_SOFTFLOAT)
 
-#define M_STACK_STORE_FLT_TYPED(t, reg, offset) { \
-       CHECK_FLT_REG(reg); \
-       if (IS_2_WORD_TYPE(t)) { \
-               M_STFD(reg, REG_SP, (offset) * 4); \
-       } else { \
-               M_STFS(reg, REG_SP, (offset) * 4); \
-       } \
-}
+#define M_FLD(a,b,c)                    M_LDFS(a,b,c)
+#define M_DLD(a,b,c)                    M_LDFD(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)
 
-#define M_FST_INTERN(a,b,c)             M_STFS_INTERN(a,b,c)
-#define M_DST_INTERN(a,b,c)             M_STFD_INTERN(a,b,c)
+#else /* !defined(ENABLE_SOFTFLOAT) */
 
-#endif /* !defined(ENABLE_SOFTFLOAT) */
-
-
-/* function gen_resolvebranch **************************************************
-   ip ... pointer to instruction after branch (void*)
-   so ... offset of instruction after branch  (s4)
-   to ... offset of branch target             (s4) */
-
-#define gen_resolvebranch(ip,so,to) \
-       assert((((s4*) (ip))[-1] & 0x0e000000) == 0x0a000000); \
-       ((s4*) (ip))[-1] |= ((s4) (to) - (so) - 1) >> 2 & 0x0ffffff
-
-
-/* function gen_nullptr_check *************************************************/
-
-#define gen_nullptr_check_intern(objreg) { \
-       M_TST((objreg), (objreg)); \
-       M_BEQ(0); \
-       codegen_add_nullpointerexception_ref(cd); \
-}
-
-#define gen_nullptr_check(objreg) \
-       if (checknull) \
-               gen_nullptr_check_intern(objreg)
-
-
-/* function gen_div_check *****************************************************/
-
-#define gen_div_check(type,reg) \
-    do { \
-       if (IS_2_WORD_TYPE(type)) { \
-               M_TEQ_IMM(GET_LOW_REG(reg), 0); \
-               /* M_TEQ_EQ_IMM(GET_HIGH_REG(reg), 0) */ M_DAT(COND_EQ,0x09,0,GET_HIGH_REG(reg),1,1,0); \
-               M_BEQ(0); \
-       } else { \
-               M_TEQ_IMM((reg), 0); \
-               M_BEQ(0); \
-       } \
-       codegen_add_arithmeticexception_ref(cd); \
-    } while (0)
-
-/* function gen_bound_check ***************************************************
-   ATTENTION: uses REG_ITMP3 as intermediate register */
-/* TODO: maybe use another reg instead of REG_ITMP3! */
-
-#define gen_bound_check(arrayref,index) \
-       if (checkbounds) { \
-               M_LDR_INTERN(REG_ITMP3, (arrayref), OFFSET(java_arrayheader, size)); \
-               M_CMP((index), REG_ITMP3); \
-               M_BHS(0); \
-               codegen_add_arrayindexoutofboundsexception_ref(cd, index); \
+#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) */
+
 
 #endif /* _CODEGEN_H */