* Removed all Id tags.
[cacao.git] / src / vm / jit / alpha / codegen.h
index efbc9abc90148e7e585acf77ccff850e92b4ec0e..9598e1b24f88fa317cf026a977500be8573a645c 100644 (file)
@@ -1,9 +1,9 @@
 /* vm/jit/alpha/codegen.h - code generation macros and definitions for Alpha
 
-   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
+   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
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
-
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-
-   Changes: Christian Thalinger
-
-   $Id: codegen.h 3120 2005-07-27 22:20:13Z twisti $
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
 */
 
 #define _CODEGEN_H
 
 #include "config.h"
+#include "vm/types.h"
 
-#include <ucontext.h>
+#include "vm/jit/jit.h"
 
 
 /* additional functions and macros to generate code ***************************/
 
-#ifdef STATISTICS
-#define COUNT_SPILLS count_spills++
-#else
-#define COUNT_SPILLS
-#endif
-
-
-/* gen_nullptr_check(objreg) */
-
-#define gen_nullptr_check(objreg) \
-    if (checknull) { \
-        M_BEQZ((objreg), 0); \
-        codegen_addxnullrefs(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_addxboundrefs(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); }
-
+#define M_FLTMOVE(a,b) \
+    do { \
+        if ((a) != (b)) \
+            M_FMOV(a, b); \
+    } while (0)
 
-/* 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
+#define ICONST(d,c)        emit_iconst(cd, (d), (c))
+#define LCONST(d,c)        emit_lconst(cd, (d), (c))
 
-   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)
 
-*******************************************************************************/
+/* branch defines *************************************************************/
 
-#define var_to_reg_int(regnr,v,tempnr) \
+#define BRANCH_NOPS \
     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) \
-    do { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            M_DLD(tempnr, REG_SP, (v)->regoff * 8); \
-            regnr = tempnr; \
-        } else { \
-            regnr = (v)->regoff; \
-        } \
+        M_NOP; \
     } while (0)
 
 
-/* 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
-   tempregnum ... Number of the temporary registers as returned by
-                  reg_of_var.
+/* patcher defines ************************************************************/
 
-*******************************************************************************/
+#define PATCHER_CALL_SIZE    1 * 4     /* an instruction is 4-bytes long      */
 
-#define store_reg_to_var_int(sptr, tempregnum) \
+#define PATCHER_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)
 
+/* stub 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 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 COMPILERSTUB_CODESIZE    3 * 4
 
 
 /* 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
-
-
-/* function prototypes ********************************************************/
-
-void thread_restartcriticalsection(ucontext_t*);
-
 #endif /* _CODEGEN_H */