* removed SET_ARG_STACKSLOTS
[cacao.git] / src / vm / jit / mips / codegen.h
index c4aa8521aea7e6b89bd5f59dee700e78e8d600f6..b6e06981e18e762e6d799739fa7cf9186f07032b 100644 (file)
@@ -1,10 +1,9 @@
-/* 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, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Institut f. Computersprachen, TU Wien
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
-   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
-   P. Tomsich, J. Wenninger
+   Copyright (C) 1996-2005 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
 
    This file is part of CACAO.
 
@@ -27,7 +26,7 @@
 
    Authors: Andreas Krall
 
-   $Id: codegen.h 1349 2004-07-22 12:08:29Z twisti $
+   $Id: codegen.h 2628 2005-06-09 20:39:37Z twisti $
 
 */
 
 #ifndef _CODEGEN_H
 #define _CODEGEN_H
 
-#include "jit/jit.h"
-
-
-/* see also file calling.doc for explanation of calling conventions           */
-
-/* preallocated registers *****************************************************/
-
-/* integer registers */
-  
-#define REG_ZERO        0    /* allways zero                                  */
-
-#define REG_RESULT      2    /* to deliver method results                     */ 
-
-#define REG_ITMP1       1    /* temporary register                            */
-#define REG_ITMP2       3    /* temporary register and method pointer         */
-#define REG_ITMP3       25   /* temporary register                            */
-
-#define REG_ARG_0       4    /* argument register                             */
-#define REG_ARG_1       5    /* argument register                             */
-#define REG_ARG_2       6    /* argument register                             */
-#define REG_ARG_3       7    /* argument register                             */
-#define REG_ARG_4       8    /* argument register                             */
-#define REG_ARG_5       9    /* argument register                             */
-
-#define REG_RA          31   /* return address                                */
-#define REG_SP          29   /* stack pointer                                 */
-#define REG_GP          28   /* global pointer                                */
-
-#define REG_PV          30   /* procedure vector, must be provided by caller  */
-#define REG_METHODPTR   25   /* pointer to the place from where the procedure */
-                             /* vector has been fetched                       */
-#define REG_ITMP1_XPTR  1    /* exception pointer = temporary register 1      */
-#define REG_ITMP2_XPC   3    /* exception pc = temporary register 2           */
-
-/* floating point registers */
-
-#define REG_FRESULT     0    /* to deliver floating point method results      */ 
-#define REG_FTMP1       1    /* temporary floating point register             */
-#define REG_FTMP2       2    /* temporary floating point register             */
-#define REG_FTMP3       3    /* temporary floating point register             */
-
-#define REG_IFTMP       1    /* temporary integer and floating point register */
-
-
-#define INT_SAV_CNT      8   /* number of int callee saved registers          */
-#define INT_ARG_CNT      8   /* number of int argument registers              */
-
-#define FLT_SAV_CNT      4   /* number of flt callee saved registers          */
-#define FLT_ARG_CNT      8   /* number of flt argument registers              */
-
+#include "vm/jit/mips/types.h"
 
 /* additional functions and macros to generate code ***************************/
 
-/* #define BlockPtrOfPC(pc)        block+block_index[pc] */
 #define BlockPtrOfPC(pc)  ((basicblock *) iptr->target)
 
 
 #define gen_nullptr_check(objreg) \
     if (checknull) { \
         M_BEQZ((objreg), 0); \
-        codegen_addxnullrefs(m, mcodeptr); \
+        codegen_addxnullrefs(cd, mcodeptr); \
         M_NOP; \
     }
 
         M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size)); \
         M_CMPULT(s2, REG_ITMP3, REG_ITMP3); \
         M_BEQZ(REG_ITMP3, 0); \
-        codegen_addxboundrefs(m, mcodeptr, s2); \
+        codegen_addxboundrefs(cd, mcodeptr, s2); \
         M_NOP; \
     }
 
 
 #define MCODECHECK(icnt) \
        if ((mcodeptr + (icnt)) > cd->mcodeend) \
-        mcodeptr = codegen_increase(m, (u1 *) mcodeptr)
+        mcodeptr = codegen_increase(cd, (u1 *) mcodeptr)
+
+
+#define ALIGNCODENOP \
+    if ((int) ((long) mcodeptr & 7)) { \
+        M_NOP; \
+    }
+
 
 /* M_INTMOVE:
      generates an integer-move from register a to b.
 #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) \
 */
 
 #define var_to_reg_int(regnr,v,tempnr) { \
-       if ((v)->flags & INMEMORY) \
-               {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
-       else regnr=(v)->regoff; \
+       if ((v)->flags & INMEMORY) { \
+               COUNT_SPILLS; \
+        M_LLD(tempnr, REG_SP, 8 * (v)->regoff); \
+        regnr = tempnr; \
+       } else regnr = (v)->regoff; \
 }
 
 
 #define var_to_reg_flt(regnr,v,tempnr) { \
-       if ((v)->flags & INMEMORY) \
-               {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
-       else regnr=(v)->regoff; \
+       if ((v)->flags & INMEMORY) { \
+               COUNT_SPILLS; \
+        M_DLD(tempnr, REG_SP, 8 * (v)->regoff); \
+        regnr = tempnr; \
+       } else regnr = (v)->regoff; \
 }
 
 
 
 
 #define M_COPY(from,to) \
-       d = reg_of_var(m, to, REG_IFTMP); \
+       d = reg_of_var(rd, to, REG_IFTMP); \
        if ((from->regoff != to->regoff) || \
            ((from->flags ^ to->flags) & INMEMORY)) { \
                if (IS_FLT_DBL_TYPE(from->type)) { \
     } else if ((c) >= 0 && (c) <= 0xffff) { \
         M_OR_IMM(REG_ZERO, (c), (r)); \
     } else { \
-        a = dseg_adds4(m, (c)); \
+        a = dseg_adds4(cd, (c)); \
         M_ILD((r), REG_PV, a); \
     }
 
     } else if ((c) >= 0 && (c) <= 0xffff) { \
         M_OR_IMM(REG_ZERO, (c), (r)); \
     } else { \
-        a = dseg_adds8(m, (c)); \
+        a = dseg_adds8(cd, (c)); \
         M_LLD((r), REG_PV, a); \
     }
 
 */
 
 
-#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_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(a,b,disp)         M_LLD(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_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
+
 #define POINTERSHIFT 2
+
 #define M_ALD(a,b,disp)         M_ILD(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_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) **********/ 
-
-#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 **************************************************
 
        backpatches a branch instruction; MIPS branch instructions are very
 
 *******************************************************************************/
 
-#define gen_resolvebranch(ip,so,to) ((s4*)(ip))[-1]|=((s4)(to)-(so))>>2&0xffff
-
-
-/* function prototypes */
+#define gen_resolvebranch(ip,so,to) \
+    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);