* types.h: Include path fixes.
[cacao.git] / src / vm / jit / mips / codegen.h
index ea4545aba0f5b9103a134b626ff819a184ff5e42..1290137c6dfad40f36722314a08835cad672dfc9 100644 (file)
@@ -1,4 +1,4 @@
-/* vm/jit/mips/codegen.h - code generation macros and definitions for mips
+/* src/vm/jit/mips/codegen.h - code generation macros and definitions for MIPS
 
    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
@@ -26,7 +26,7 @@
 
    Authors: Andreas Krall
 
-   $Id: codegen.h 2222 2005-04-05 17:38:04Z christian $
+   $Id: codegen.h 3323 2005-10-04 18:33:30Z twisti $
 
 */
 
 #ifndef _CODEGEN_H
 #define _CODEGEN_H
 
-#include "vm/jit/mips/types.h"
-
-/* Macro for stack.c to set Argument Stackslots */
-
-#define SET_ARG_STACKSLOTS {                                                                                   \
-               s4 stacksize;     /* Stackoffset for spilled arg */                             \
-               stacksize = (i < rd->intreg_argnum)? 0 : (i - rd->intreg_argnum); \
-               copy = curstack;                                                                                                \
-                                                                                                                                               \
-               if (rd->ifmemuse < stacksize)                                                                   \
-                       rd->ifmemuse = stacksize;                                                                       \
-                                                                                                                                               \
-               while (--i >= 0) {                                                                                              \
-                       if (!(copy->flags & SAVEDVAR)) {                                                        \
-                               copy->varnum = i;                                                                               \
-                               copy->varkind = ARGVAR;                                                                 \
-                               if (IS_FLT_DBL_TYPE(copy->type)) {                                              \
-                                       if (i < rd->fltreg_argnum) {                                            \
-                                               copy->flags = 0;                                                                \
-                                               copy->regoff = rd->argfltregs[i];                               \
-                                       } else {                                                                                        \
-                                               copy->flags = INMEMORY;                                                 \
-                                               copy->regoff = --stacksize;                                             \
-                                       }                                                                                                       \
-                               } else { /* int arg */                                                                  \
-                                       if (i < rd->intreg_argnum) {                                            \
-                                               copy->flags = 0;                                                                \
-                                               copy->regoff = rd->argintregs[i];                               \
-                                       } else {                                                                                        \
-                                               copy->flags = INMEMORY;                                                 \
-                                               copy->regoff = --stacksize;                                             \
-                                       }                                                                                                       \
-                               }                                                                                                               \
-                       }                                                                                                                       \
-                       copy = copy->prev;                                                                                      \
-               }                                                                                                                               \
-       }                                                                                                                                       \
+#include "config.h"
+#include "vm/types.h"
 
-/* additional functions and macros to generate code ***************************/
-
-/* #define BlockPtrOfPC(pc)        block+block_index[pc] */
-#define BlockPtrOfPC(pc)  ((basicblock *) iptr->target)
 
+/* additional functions and macros to generate code ***************************/
 
 #ifdef STATISTICS
 #define COUNT_SPILLS count_spills++
         M_NOP; \
     }
 
+#define gen_div_check(r) \
+    M_BEQZ((r), 0); \
+    codegen_addxdivrefs(cd, mcodeptr); \
+    M_NOP;
+
 
 /* MCODECHECK(icnt) */
 
 #define M_FLTMOVE(a,b) if (a != b) { M_DMOV(a, b); }
 
 #define M_TFLTMOVE(t,a,b) \
-       {if(a!=b) \
-               if ((t)==TYPE_DBL) \
-                   {M_DMOV(a,b);} \
-               else {M_FMOV(a,b);} \
-       }
+    do { \
+        if ((a) != (b)) \
+            if ((t) == TYPE_DBL) { \
+                M_DMOV(a,b); \
+            } else { \
+                M_FMOV(a,b); \
+            } \
+    } while (0)
 
 #define M_TFLD(t,a,b,disp) \
-    if ((t)==TYPE_DBL) \
-         {M_DLD(a,b,disp);} \
-    else \
-         {M_FLD(a,b,disp);}
+    if ((t) == TYPE_DBL) { \
+         M_DLD(a,b,disp); \
+    } else { \
+         M_FLD(a,b,disp); \
+    }
 
 #define M_TFST(t,a,b,disp) \
     if ((t)==TYPE_DBL) \
     } else if ((c) >= 0 && (c) <= 0xffff) { \
         M_OR_IMM(REG_ZERO, (c), (r)); \
     } else { \
-        a = dseg_adds4(cd, (c)); \
-        M_ILD((r), REG_PV, a); \
+        disp = dseg_adds4(cd, (c)); \
+        M_ILD((r), REG_PV, disp); \
     }
 
 #define LCONST(r,c) \
     } else if ((c) >= 0 && (c) <= 0xffff) { \
         M_OR_IMM(REG_ZERO, (c), (r)); \
     } else { \
-        a = dseg_adds8(cd, (c)); \
-        M_LLD((r), REG_PV, a); \
+        disp = dseg_adds8(cd, (c)); \
+        M_LLD((r), REG_PV, disp); \
     }
 
 
 */
 
 
-#define M_ITYPE(op, rs, rt, imm)\
-  *(mcodeptr++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((imm)&0xffff))
+#define M_ITYPE(op,rs,rt,imm) \
+    *(mcodeptr++) = (((op) << 26) | ((rs) << 21) | ((rt) << 16) | ((imm) & 0xffff))
 
-#define M_JTYPE(op, imm)\
-  *(mcodeptr++) = (((op)<<26)|((off)&0x3ffffff))
+#define M_JTYPE(op,imm) \
+    *(mcodeptr++) = (((op) << 26) | ((off) & 0x3ffffff))
 
-#define M_RTYPE(op, rs, rt, rd, sa, fu)\
-  *(mcodeptr++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|(fu))
+#define M_RTYPE(op,rs,rt,rd,sa,fu) \
+    *(mcodeptr++) = (((op) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((sa) << 6) | (fu))
 
 #define M_FP2(fu, fmt, fs, fd)       M_RTYPE(0x11, fmt,  0, fs, fd, fu)
 #define M_FP3(fu, fmt, fs, ft, fd)   M_RTYPE(0x11, fmt, ft, fs, fd, fu)
 #define FMT_I  20
 #define FMT_L  21
 
-/* macros for all used commands (see a MIPS-manual for description) ***********/ 
+
+/* macros for all used commands (see a MIPS-manual for description) ***********/
 
 /* load/store macros use the form OPERATION(source/dest, base, offset)        */
 
+#define M_LDA(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_AADD_IMM(b,lo,a); \
+        } else { \
+            M_LUI(REG_ITMP3,hi); \
+            M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3); \
+            M_AADD(REG_ITMP3,b,a); \
+        } \
+    } while (0)
+
 #define M_BLDS(a,b,disp)        M_ITYPE(0x20,b,a,disp)          /*  8 load    */
 #define M_BLDU(a,b,disp)        M_ITYPE(0x24,b,a,disp)          /*  8 load    */
 #define M_SLDS(a,b,disp)        M_ITYPE(0x21,b,a,disp)          /* 16 load    */
 #define M_SLDU(a,b,disp)        M_ITYPE(0x25,b,a,disp)          /* 16 load    */
-#define M_ILD(a,b,disp)         M_ITYPE(0x23,b,a,disp)          /* 32 load    */
-#define M_LLD(a,b,disp)         M_ITYPE(0x37,b,a,disp)          /* 64 load    */
+
+#define M_ILD_INTERN(a,b,disp)  M_ITYPE(0x23,b,a,disp)          /* 32 load    */
+#define M_LLD_INTERN(a,b,disp)  M_ITYPE(0x37,b,a,disp)          /* 64 load    */
+
+#define M_ILD(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_ILD_INTERN(a,b,lo); \
+        } else { \
+            M_LUI(a,hi); \
+            M_AADD(b,a,a); \
+            M_ILD_INTERN(a,a,lo); \
+        } \
+    } while (0)
+
+#define M_LLD(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_LLD_INTERN(a,b,lo); \
+        } else { \
+            M_LUI(a,hi); \
+            M_AADD(b,a,a); \
+            M_LLD_INTERN(a,a,lo); \
+        } \
+    } while (0)
+
 #define M_BST(a,b,disp)         M_ITYPE(0x28,b,a,disp)          /*  8 store   */
 #define M_SST(a,b,disp)         M_ITYPE(0x29,b,a,disp)          /* 16 store   */
-#define M_IST(a,b,disp)         M_ITYPE(0x2b,b,a,disp)          /* 32 store   */
-#define M_LST(a,b,disp)         M_ITYPE(0x3f,b,a,disp)          /* 64 store   */
 
-#define M_FLD(a,b,disp)         M_ITYPE(0x31,b,a,disp)          /* load flt   */
-#define M_DLD(a,b,disp)         M_ITYPE(0x35,b,a,disp)          /* load dbl   */
-#define M_FST(a,b,disp)         M_ITYPE(0x39,b,a,disp)          /* store flt  */
-#define M_DST(a,b,disp)         M_ITYPE(0x3d,b,a,disp)          /* store dbl  */
+#define M_IST_INTERN(a,b,disp)  M_ITYPE(0x2b,b,a,disp)          /* 32 store   */
+#define M_LST_INTERN(a,b,disp)  M_ITYPE(0x3f,b,a,disp)          /* 64 store   */
+
+#define M_IST(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_IST_INTERN(a,b,lo); \
+        } else { \
+            M_LUI(REG_ITMP3, hi); \
+            M_AADD(b, REG_ITMP3, REG_ITMP3); \
+            M_IST_INTERN(a,REG_ITMP3,lo); \
+        } \
+    } while (0)
+
+#define M_LST(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_LST_INTERN(a,b,lo); \
+        } else { \
+            M_LUI(REG_ITMP3, hi); \
+            M_AADD(b, REG_ITMP3, REG_ITMP3); \
+            M_LST_INTERN(a,REG_ITMP3,lo); \
+        } \
+    } while (0)
+
+#define M_FLD_INTERN(a,b,disp)  M_ITYPE(0x31,b,a,disp)          /* load flt   */
+#define M_DLD_INTERN(a,b,disp)  M_ITYPE(0x35,b,a,disp)          /* load dbl   */
+
+#define M_FLD(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_FLD_INTERN(a,b,lo); \
+        } else { \
+            M_LUI(REG_ITMP3,hi); \
+            M_AADD(b,REG_ITMP3,REG_ITMP3); \
+            M_FLD_INTERN(a,REG_ITMP3,lo); \
+        } \
+    } while (0)
+
+#define M_DLD(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_DLD_INTERN(a,b,lo); \
+        } else { \
+            M_LUI(REG_ITMP3,hi); \
+            M_AADD(b,REG_ITMP3,REG_ITMP3); \
+            M_DLD_INTERN(a,REG_ITMP3,lo); \
+        } \
+    } while (0)
+
+#define M_FST_INTERN(a,b,disp)  M_ITYPE(0x39,b,a,disp)          /* store flt  */
+#define M_DST_INTERN(a,b,disp)  M_ITYPE(0x3d,b,a,disp)          /* store dbl  */
+
+#define M_FST(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_FST_INTERN(a,b,lo); \
+        } else { \
+            M_LUI(REG_ITMP3, hi); \
+            M_AADD(b, REG_ITMP3, REG_ITMP3); \
+            M_FST_INTERN(a,REG_ITMP3,lo); \
+        } \
+    } while (0)
+
+#define M_DST(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_DST_INTERN(a,b,lo); \
+        } else { \
+            M_LUI(REG_ITMP3, hi); \
+            M_AADD(b, REG_ITMP3, REG_ITMP3); \
+            M_DST_INTERN(a,REG_ITMP3,lo); \
+        } \
+    } while (0)
 
 #define M_BEQ(a,b,disp)         M_ITYPE(0x04,a,b,disp)          /* br a == b  */
 #define M_BNE(a,b,disp)         M_ITYPE(0x05,a,b,disp)          /* br a != b  */
 #define M_CMOVF(a,b)                   M_RTYPE(0x00,a,0,b,0,1)
 #define M_CMOVT(a,b)                   M_RTYPE(0x00,a,1,b,0,1)
 
+
 /*
  * Load Address pseudo instruction:
  * -n32 addressing mode -> 32 bit addrs, -64 addressing mode -> 64 bit addrs
  */
-#if POINTERSIZE==8
+#if SIZEOF_VOID_P == 8
+
 #define POINTERSHIFT 3
+
+#define M_ALD_INTERN(a,b,disp)  M_LLD_INTERN(a,b,disp)
 #define M_ALD(a,b,disp)         M_LLD(a,b,disp)
+#define M_AST_INTERN(a,b,disp)  M_LST_INTERN(a,b,disp)
 #define M_AST(a,b,disp)         M_LST(a,b,disp)
 #define M_AADD(a,b,c)           M_LADD(a,b,c)
+#define M_AADD_IMM(a,b,c)       M_LADD_IMM(a,b,c)
+#define M_ASUB_IMM(a,b,c)       M_LSUB_IMM(a,b,c)
 #define M_ASLL_IMM(a,b,c)       M_LSLL_IMM(a,b,c)
-#define M_LDA(a,b,disp)         M_LADD_IMM(b,disp,a)            /* a = b+disp */
-#else
+
+#else /* SIZEOF_VOID_P == 8 */
+
 #define POINTERSHIFT 2
+
+#define M_ALD_INTERN(a,b,disp)  M_ILD_INTERN(a,b,disp)
 #define M_ALD(a,b,disp)         M_ILD(a,b,disp)
+#define M_AST_INTERN(a,b,disp)  M_IST_INTERN(a,b,disp)
 #define M_AST(a,b,disp)         M_IST(a,b,disp)
 #define M_AADD(a,b,c)           M_IADD(a,b,c)
+#define M_AADD_IMM(a,b,c)       M_IADD_IMM(a,b,c)
+#define M_ASUB_IMM(a,b,c)       M_ISUB_IMM(a,b,c)
 #define M_ASLL_IMM(a,b,c)       M_ISLL_IMM(a,b,c)
-#define M_LDA(a,b,disp)         M_IADD_IMM(b,disp,a)            /* a = b+disp */
-#endif
 
-/* macros for special commands (see an Alpha-manual for description) **********/ 
+#endif /* SIZEOF_VOID_P == 8 */
 
-#if 0
-#define M_CMOVEQ(a,b,c)         M_OP3 (0x11,0x24, a,b,c,0)     /* a==0 ? c=b  */
-#define M_CMOVNE(a,b,c)         M_OP3 (0x11,0x26, a,b,c,0)     /* a!=0 ? c=b  */
-#define M_CMOVLT(a,b,c)         M_OP3 (0x11,0x44, a,b,c,0)     /* a< 0 ? c=b  */
-#define M_CMOVGE(a,b,c)         M_OP3 (0x11,0x46, a,b,c,0)     /* a>=0 ? c=b  */
-#define M_CMOVLE(a,b,c)         M_OP3 (0x11,0x64, a,b,c,0)     /* a<=0 ? c=b  */
-#define M_CMOVGT(a,b,c)         M_OP3 (0x11,0x66, a,b,c,0)     /* a> 0 ? c=b  */
-
-#define M_CMOVEQ_IMM(a,b,c)     M_OP3 (0x11,0x24, a,b,c,1)     /* a==0 ? c=b  */
-#define M_CMOVNE_IMM(a,b,c)     M_OP3 (0x11,0x26, a,b,c,1)     /* a!=0 ? c=b  */
-#define M_CMOVLT_IMM(a,b,c)     M_OP3 (0x11,0x44, a,b,c,1)     /* a< 0 ? c=b  */
-#define M_CMOVGE_IMM(a,b,c)     M_OP3 (0x11,0x46, a,b,c,1)     /* a>=0 ? c=b  */
-#define M_CMOVLE_IMM(a,b,c)     M_OP3 (0x11,0x64, a,b,c,1)     /* a<=0 ? c=b  */
-#define M_CMOVGT_IMM(a,b,c)     M_OP3 (0x11,0x66, a,b,c,1)     /* a> 0 ? c=b  */
-#endif
 
 /* function gen_resolvebranch **************************************************
 
 *******************************************************************************/
 
 #define gen_resolvebranch(ip,so,to) \
-    ((s4 *) (ip))[-1] |= ((s4) (to) - (so)) >> 2 & 0xffff
-
-
-/* function prototypes */
+    do { \
+        s4 offset; \
+        \
+        offset = ((s4) (to) - (so)) >> 2; \
+        \
+        /* On the MIPS we can only branch signed 16-bit instruction words */ \
+        /* (signed 18-bit = 32KB = +/- 16KB). Check this!                 */ \
+        \
+        if ((offset < (s4) 0xffff8000) || (offset > (s4) 0x00007fff)) { \
+            throw_cacao_exception_exit(string_java_lang_InternalError, \
+                                       "Jump offset is out of range: %d > +/-%d", \
+                                       offset, 0x00007fff); \
+        } \
+        \
+        ((s4 *) (ip))[-1] |= (offset & 0x0000ffff); \
+    } while (0)
+
+
+/* function prototypes ********************************************************/
 
 void docacheflush(u1 *p, long bytelen);