Merged revisions 7501-7598 via svnmerge from
[cacao.git] / src / vm / jit / alpha / codegen.h
index c33802301813d80049808ce9c3aa18224939ec7c..fb60d38f617914493e68f5c382ee6c5d4440579f 100644 (file)
@@ -1,6 +1,6 @@
 /* vm/jit/alpha/codegen.h - code generation macros and definitions for Alpha
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-
-   Changes: Christian Thalinger
-
-   $Id: codegen.h 4626 2006-03-16 12:03:47Z twisti $
+   $Id: codegen.h 7596 2007-03-28 21:05:53Z twisti $
 
 */
 
 
 /* additional functions and macros to generate code ***************************/
 
-/* gen_nullptr_check(objreg) */
-
-#define gen_nullptr_check(objreg) \
-    if (checknull) { \
-        M_BEQZ((objreg), 0); \
-        codegen_add_nullpointerexception_ref(cd, mcodeptr); \
-    }
-
 #define gen_bound_check \
     if (checkbounds) { \
         M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
         M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
         M_BEQZ(REG_ITMP3, 0);\
-        codegen_add_arrayindexoutofboundsexception_ref(cd, mcodeptr, s2); \
+        codegen_add_arrayindexoutofboundsexception_ref(cd, s2); \
     }
 
 
 /* MCODECHECK(icnt) */
 
 #define MCODECHECK(icnt) \
-       if ((mcodeptr + (icnt)) > cd->mcodeend) \
-        mcodeptr = codegen_increase(cd, (u1 *) mcodeptr)
+    do { \
+        if ((cd->mcodeptr + (icnt) * 4) > cd->mcodeend) \
+            codegen_increase(cd); \
+    } while (0)
 
 
 #define ALIGNCODENOP \
-    if ((s4) ((ptrint) mcodeptr & 7)) { \
+    if ((s4) ((ptrint) cd->mcodeptr & 7)) { \
         M_NOP; \
     }
 
      if a and b are the same int-register, no code will be generated.
 */ 
 
-#define M_INTMOVE(a,b) if (a != b) { M_MOV(a, b); }
+#define M_INTMOVE(a,b) \
+    do { \
+        if ((a) != (b)) \
+            M_MOV(a, b); \
+    } while (0)
 
 
 /* M_FLTMOVE:
     if a and b are the same float-register, no code will be generated
 */ 
 
-#define M_FLTMOVE(a,b) if (a != b) { M_FMOV(a, b); }
-
-
-/* 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
-   tempregnum: temporary register to be used if v is actually spilled to ram
-
-   return: the register number, where the operand can be found after 
-           fetching (this wil be either tempregnum or the register
-           number allready given to v)
-
-*******************************************************************************/
-
-#define var_to_reg_int(regnr,v,tempnr) \
-    do { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            M_LLD(tempnr, REG_SP, (v)->regoff * 8); \
-            regnr = tempnr; \
-        } else { \
-            regnr = (v)->regoff; \
-        } \
-    } while (0)
-
-
-#define var_to_reg_flt(regnr,v,tempnr) \
+#define M_FLTMOVE(a,b) \
     do { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            M_DLD(tempnr, REG_SP, (v)->regoff * 8); \
-            regnr = tempnr; \
-        } else { \
-            regnr = (v)->regoff; \
-        } \
+        if ((a) != (b)) \
+            M_FMOV(a, b); \
     } while (0)
 
 
-/* store_reg_to_var_xxx ********************************************************
+#define ICONST(d,c)        emit_iconst(cd, (d), (c))
+#define LCONST(d,c)        emit_lconst(cd, (d), (c))
 
-   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
-   tempregnum ... Number of the temporary registers as returned by
-                  reg_of_var.
 
-*******************************************************************************/
+/* branch defines *************************************************************/
 
-#define store_reg_to_var_int(sptr, tempregnum) \
+#define BRANCH_NOPS \
     do { \
-        if ((sptr)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            M_LST(tempregnum, REG_SP, (sptr)->regoff * 8); \
-        } \
+        M_NOP; \
     } while (0)
 
-#define store_reg_to_var_flt(sptr, tempregnum) \
-    do { \
-        if ((sptr)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            M_DST(tempregnum, REG_SP, (sptr)->regoff * 8); \
-        } \
-    } while (0)
 
+/* patcher defines ************************************************************/
 
-#define M_COPY(from,to) \
-       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)) { \
-                       var_to_reg_flt(s1, from, d); \
-                       M_FLTMOVE(s1,d); \
-                       store_reg_to_var_flt(to, d); \
-               } else { \
-                       var_to_reg_int(s1, from, d); \
-                       M_INTMOVE(s1,d); \
-                       store_reg_to_var_int(to, d); \
-               } \
-       }
-
-#define ICONST(r,c) \
-    if ((c) >= -32768 && (c) <= 32767) { \
-        M_LDA_INTERN((r), REG_ZERO, c); \
-    } else { \
-        disp = dseg_adds4(cd, (c)); \
-        M_ILD((r), REG_PV, disp); \
-    }
+#define PATCHER_CALL_SIZE    1 * 4     /* an instruction is 4-bytes long      */
 
-#define LCONST(r,c) \
-    if ((c) >= -32768 && (c) <= 32767) { \
-        M_LDA_INTERN((r), REG_ZERO, (c)); \
-    } else { \
-        disp = dseg_adds8(cd, (c)); \
-        M_LLD((r), REG_PV, disp); \
-    }
+#define PATCHER_NOPS \
+    do { \
+        M_NOP; \
+    } while (0)
 
 
 /* macros to create code ******************************************************/
 */      
 
 #define M_OP3(op,fu,a,b,c,const) \
-       *(mcodeptr++) = ((((s4) (op)) << 26) | ((a) << 21) | ((b) << (16 - 3 * (const))) | ((const) << 12) | ((fu) << 5) | ((c)))
+    do { \
+        *((u4 *) cd->mcodeptr) = ((((s4) (op)) << 26) | ((a) << 21) | ((b) << (16 - 3 * (const))) | ((const) << 12) | ((fu) << 5) | ((c))); \
+        cd->mcodeptr += 4; \
+    } while (0)
 
 
 /* 3-address-floating-point-operation: M_FOP3 
 */ 
 
 #define M_FOP3(op,fu,a,b,c) \
-       *(mcodeptr++) = ((((s4) (op)) << 26) | ((a) << 21) | ((b) << 16) | ((fu) << 5) | (c))
+    do { \
+        *((u4 *) cd->mcodeptr) = ((((s4) (op)) << 26) | ((a) << 21) | ((b) << 16) | ((fu) << 5) | (c)); \
+        cd->mcodeptr += 4; \
+    } while (0)
 
 
 /* branch instructions: M_BRA 
 */
 
 #define M_BRA(op,a,disp) \
-       *(mcodeptr++) = ((((s4) (op)) << 26) | ((a) << 21) | ((disp) & 0x1fffff))
+    do { \
+        *((u4 *) cd->mcodeptr) = ((((s4) (op)) << 26) | ((a) << 21) | ((disp) & 0x1fffff)); \
+        cd->mcodeptr += 4; \
+    } while (0)
 
 
 /* memory operations: M_MEM
 */ 
 
 #define M_MEM(op,a,b,disp) \
-       *(mcodeptr++) = ((((s4) (op)) << 26) | ((a) << 21) | ((b) << 16) | ((disp) & 0xffff))
+    do { \
+        *((u4 *) cd->mcodeptr) = ((((s4) (op)) << 26) | ((a) << 21) | ((b) << 16) | ((disp) & 0xffff)); \
+        cd->mcodeptr += 4; \
+    } while (0)
+
+#define M_MEM_GET_A(x)                  (((x) >> 21) & 0x1f  )
+#define M_MEM_GET_B(x)                  (((x) >> 16) & 0x1f  )
+#define M_MEM_GET_DISP(x)               ( (x)        & 0xffff)
 
 
 /* macros for all used commands (see an Alpha-manual for description) *********/
         } \
     } while (0)
 
+#define M_ALD_INTERN(a,b,disp)  M_LLD_INTERN(a,b,disp)
 #define M_ALD(a,b,disp)         M_LLD(a,b,disp)                 /* addr load  */
 
 #define M_BST(a,b,disp)         M_MEM(0x0e,a,b,disp)            /*  8 store   */
 #define M_LMUL_IMM(a,b,c)       M_OP3 (0x13,0x20, a,b,c,1)      /* 64 mul     */
 
 #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_CMPEQ(a,b,c)          M_OP3 (0x10,0x2d, a,b,c,0)      /* c = a == b */
 #define M_CMPLT(a,b,c)          M_OP3 (0x10,0x4d, a,b,c,0)      /* c = a <  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  */
 
-/* macros for unused commands (see an Alpha-manual for description) ***********/ 
+/* macros for unused commands (see an Alpha-manual for description) ***********/
 
 #define M_ANDNOT(a,b,c,const)   M_OP3 (0x11,0x08, a,b,c,const) /* c = a &~ b  */
 #define M_ORNOT(a,b,c,const)    M_OP3 (0x11,0x28, a,b,c,const) /* c = a |~ b  */
 
 #define M_JMP_CO(a,b)           M_MEM (0x1a,a,b,0xc000)        /* call cosub  */
 
-
-/* gen_resolvebranch ***********************************************************
-
-   backpatches a branch instruction; Alpha branch instructions are very
-   regular, so it is only necessary to overwrite some fixed bits in the
-   instruction.
-
-   parameters: 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) \
-    ((s4 *) (ip))[-1] |= ((s4) (to) - (so)) >> 2 & 0x1fffff
-
 #endif /* _CODEGEN_H */