* Removed all Id tags.
[cacao.git] / src / vm / jit / powerpc64 / codegen.h
index b89c80012ab517332b2d960eff3ee3e646156b41..2b82467bc6a4622a438a9f4785f3d6dd42db9dde 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/jit/powerpc64/codegen.h - code generation macros and definitions for
-                                  32-bit PowerPC
+                                 64-bit PowerPC
 
-   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
 
    Authors: Andreas Krall
             Stefan Ring
-
-   Changes: Christian Thalinger
+            Christian Thalinger
             Christian Ullrich
 
-   $Id: codegen.h 5632 2006-10-02 13:43:15Z edwin $
 
 */
 
 
 /* additional functions and macros to generate code ***************************/
 
-/* gen_nullptr_check(objreg) */
-
-#define gen_nullptr_check(objreg) \
-    if (checknull) { \
-        M_TST((objreg)); \
-        M_BEQ(0); \
-        codegen_add_nullpointerexception_ref(cd); \
-    }
-
-#define gen_bound_check \
-    if (checkbounds) { \
-        M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
-        M_CMP(s2, REG_ITMP3);\
-        M_BGE(0);\
-        codegen_add_arrayindexoutofboundsexception_ref(cd, s2); \
-    }
-
-
 /* MCODECHECK(icnt) */
 
 #define MCODECHECK(icnt) \
 
 
 #define ICONST(d,c)                     emit_iconst(cd, (d), (c))
-#define LCONST(reg,c)                  ICONST(reg,c)
+#define LCONST(reg,c)                  emit_lconst(cd, (reg), (c))
 
 
 #define ALIGNCODENOP \
     }
 
 
+/* branch defines *************************************************************/
+/* and additional branch is needed when generating long branches */
+#define BRANCH_NOPS \
+    do { \
+       if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {\
+               M_NOP; \
+       } \
+        M_NOP; \
+    } while (0)
+
+
+/* patcher defines ************************************************************/
+
+#define PATCHER_CALL_SIZE    1 * 4      /* an instruction is 4-bytes long     */
+
+#define PATCHER_NOPS \
+    do { \
+        M_NOP; \
+    } while (0)
+
+
+/* stub defines ***************************************************************/
+
+#define COMPILERSTUB_CODESIZE    4 * 4
+
+
 /* macros to create code ******************************************************/
 
 #define M_OP3(opcode,y,oe,rc,d,a,b) \
         cd->mcodeptr += 4; \
     } while (0)
 
-#define M_BRMASK     0x0000fffc                     /* (((1 << 16) - 1) & ~3) */
-#define M_BRAMASK    0x03fffffc                     /* (((1 << 26) - 1) & ~3) */
+/* for instruction decodeing */
+#define M_INSTR_OP2_IMM_D(x)            (((x) >> 21) & 0x1f  )
+#define M_INSTR_OP2_IMM_A(x)            (((x) >> 16) & 0x1f  )
+#define M_INSTR_OP2_IMM_I(x)            ( (x)        & 0xffff)
+
+#define M_BCMASK     0x0000fffc                     /* (((1 << 16) - 1) & ~3) */
+#define M_BMASK    0x03fffffc                     /* (((1 << 26) - 1) & ~3) */
 
-#define M_BRA(x,i,a,l) \
+#define M_B(x,i,a,l) \
     do { \
-        *((u4 *) cd->mcodeptr) = (((x) << 26) | ((((i) * 4) + 4) & M_BRAMASK) | ((a) << 1) | (l)); \
+        *((u4 *) cd->mcodeptr) = (((x) << 26) | ((((i) * 4) + 4) & M_BMASK) | ((a) << 1) | (l)); \
         cd->mcodeptr += 4; \
     } while (0)
 
-#define M_BRAC(x,bo,bi,i,a,l) \
+#define M_BC(x,bo,bi,i,a,l) \
     do { \
-        *((u4 *) cd->mcodeptr) = (((x) << 26) | ((bo) << 21) | ((bi) << 16) | (((i) * 4 + 4) & M_BRMASK) | ((a) << 1) | (l)); \
+        *((u4 *) cd->mcodeptr) = (((x) << 26) | ((bo) << 21) | ((bi) << 16) | (((i) * 4 + 4) & M_BCMASK) | ((a) << 1) | (l)); \
         cd->mcodeptr += 4; \
     } while (0)
 
 #define M_ADDZE(a,b)                    M_OP3(31, 202, 0, 0, b, a, 0)
 #define M_ADDME(a,b)                    M_OP3(31, 234, 0, 0, b, a, 0)
 
-#define M_SUB(a,b,c)                   M_OP3(31, 40, 0, 0, c, b, a)
+#define M_SUB(a,b,c)                    M_OP3(31, 40, 0, 0, c, b, a)
 #define M_ISUBTST(a,b,c)                M_OP3(31, 40, 0, 1, c, b, a)
 #define M_SUBC(a,b,c)                   M_OP3(31, 8, 0, 0, c, b, a)
 #define M_SUBIC(a,b,c)                  M_OP2_IMM(8, c, b, a)
 #define M_XOR_IMM(a,b,c)                M_OP2_IMM(26, a, c, b)
 #define M_XORIS(a,b,c)                  M_OP2_IMM(27, a, c, b)
 
-#define M_SLL(a,b,c)                    M_OP3(31, 24, 0, 0, a, c, b)
-#define M_SRL(a,b,c)                    M_OP3(31, 536, 0, 0, a, c, b)
-#define M_SRA(a,b,c)                    M_OP3(31, 792, 0, 0, a, c, b)
-#define M_SRA_IMM(a,b,c)                M_OP3(31, 824, 0, 0, a, c, b)
+/* RLDICR is said to be turing complete, this seems right */
+#define M_SLL(a,b,c)                    M_OP3(31, 27, 0, 0, a, c, b)
+#define M_SLL_IMM(a,b,c)                M_OP3(30, ((b)&0x20 ? 1:0), 0, ((((63-(b))&0x1f)<<6) | (((63-(b))&0x20 ? 1:0)<<5) | 0x04), a, c, (b)&0x1f);
+#define M_SRL(a,b,c)                    M_OP3(31, 539, 0, 0, a, c, b)
+#define M_SRL_IMM(a,b,c)                M_OP3(30, ((64-(b))&0x20 ? 1:0), 0, (((((b))&0x1f)<<6) | ((((b))&0x20 ? 1:0)<<5) | 0x00), a, c, (64-(b))&0x1f);
+#define M_SRA(a,b,c)                    M_OP3(31, 794, 0, 0, a, c, b)
+#define M_SRA_IMM(a,b,c)                M_OP3(31, (826 | ((b)&0x20?1:0)), 0, 0, a, c, ((b)&0x1f))
 
 #define M_MUL(a,b,c)                   M_OP3(31, 233, 0, 0, c, a, b)
 #define M_MUL_IMM(a,b,c)               M_OP2_IMM(7, c, a, b)
-#define M_DIV(a,b,c)                   M_OP3(31, 489, 0, 0, c, a, b)
+#define M_DIV(a,b,c)                   M_OP3(31, 489, 1, 0, c, a, b)
 
 #define M_NEG(a,b)                      M_OP3(31, 104, 0, 0, b, a, 0)
 #define M_NOT(a,b)                      M_OP3(31, 124, 0, 0, a, b, a)
 #define M_SUBFZE(a,b)                   M_OP3(31, 200, 0, 0, b, a, 0)
 #define M_RLWINM(a,b,c,d,e)             M_OP4(21, d, 0, a, e, b, c)
 #define M_ADDZE(a,b)                    M_OP3(31, 202, 0, 0, b, a, 0)
-#define M_SLL_IMM(a,b,c)                M_OP3(30, 0, 0, 0, a, c, b)    /* RLDICL/ROTLDI FIXME: b is a split field */
-#define M_SRL_IMM(a,b,c)                M_RLWINM(a,32-(b),b,31,c)
 #define M_ADDIS(a,b,c)                  M_OP2_IMM(15, c, a, b)
 #define M_STFIWX(a,b,c)                 M_OP3(31, 983, 0, 0, a, b, c)
 
-#define M_LWZX(a,b,c)                   M_OP3(31, 23, 0, 0, a, b, c)
+#define M_LWAX(a,b,c)                   M_OP3(31, 341, 0, 0, a, b, c)
 #define M_LHZX(a,b,c)                   M_OP3(31, 279, 0, 0, a, b, c)
 #define M_LHAX(a,b,c)                   M_OP3(31, 343, 0, 0, a, b, c)
 #define M_LHAX(a,b,c)                   M_OP3(31, 343, 0, 0, a, b, c)
 #define M_ILD_INTERN(a,b,disp)          M_OP2_IMM(32,a,b,disp) /* LWZ */
 #endif
 
-#define M_ILD_INTERN(a,b,disp)         M_OP2_IMM(58, a, b, (((disp) & 0xfffe) | 0x0002))
+#define M_LWZ(a,b,disp)                        M_OP2_IMM(32,a,b,disp)  /* needed for hardware exceptions */
+
+#define M_ILD_INTERN(a,b,disp)         M_OP2_IMM(58, a, b, (((disp) & 0xfffe) | 0x0002))       /* this is LWA actually */
 
 #define M_ILD(a,b,disp) \
     do { \
 #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_ASTX(a,b,c)                  M_OP3(31, 149, 0, 0, a, b, c)
+#define M_LSTX(a,b,c)                  M_ASTX(a,b,c)
+
 
 #define M_BSEXT(a,b)                    M_OP3(31, 954, 0, 0, a, b, 0)
 #define M_CZEXT(a,b)                    M_RLWINM(a,0,16,31,b)
 #define M_SSEXT(a,b)                    M_OP3(31, 922, 0, 0, a, b, 0)
 #define M_ISEXT(a,b)                   M_OP3(31, 986, 0, 0, a, b, 0)
 
-#define M_BR(a)                         M_BRA(18, a, 0, 0)
-#define M_BL(a)                         M_BRA(18, a, 0, 1)
+#define M_BR(a)                         M_B(18, a, 0, 0)
+#define M_BL(a)                         M_B(18, a, 0, 1)
 #define M_RET                           M_OP3(19, 16, 0, 0, 20, 0, 0)
 #define M_JSR                           M_OP3(19, 528, 0, 1, 20, 0, 0)
 #define M_RTS                           M_OP3(19, 528, 0, 0, 20, 0, 0)
 #define M_CMPI(a,b)                     M_OP2_IMM(11, 1, a, b) 
 #define M_CMPUI(a,b)                    M_OP2_IMM(10, 1, a, b)  
 
-#define M_BLT(a)                        M_BRAC(16, 12, 0, a, 0, 0)
-#define M_BLE(a)                        M_BRAC(16, 4, 1, a, 0, 0)
-#define M_BGT(a)                        M_BRAC(16, 12, 1, a, 0, 0)
-#define M_BGE(a)                        M_BRAC(16, 4, 0, a, 0, 0)
-#define M_BEQ(a)                        M_BRAC(16, 12, 2, a, 0, 0)
-#define M_BNE(a)                        M_BRAC(16, 4, 2, a, 0, 0)
-#define M_BNAN(a)                       M_BRAC(16, 12, 3, a, 0, 0)
+#define M_BLT(a)                        M_BC(16, 12, 0, a, 0, 0)
+#define M_BLE(a)                        M_BC(16, 4, 1, a, 0, 0)
+#define M_BGT(a)                        M_BC(16, 12, 1, a, 0, 0)
+#define M_BGE(a)                        M_BC(16, 4, 0, a, 0, 0)
+#define M_BEQ(a)                        M_BC(16, 12, 2, a, 0, 0)
+#define M_BNE(a)                        M_BC(16, 4, 2, a, 0, 0)
+#define M_BNAN(a)                       M_BC(16, 12, 3, a, 0, 0)
 
 #define M_FLD_INTERN(a,b,disp)          M_OP2_IMM(48,a,b,disp)
 #define M_DLD_INTERN(a,b,disp)          M_OP2_IMM(50,a,b,disp)
 
 #define M_LDATST(a,b,c)                 M_ADDICTST(b, c, a)
 #define M_CLR(a)                        M_LADD_IMM(0, 0, a)
+#define M_CLR_HIGH(a)                  M_OP3(30, 0, 0, 0x20, (a), (a), 0);
 #define M_AADD_IMM(a,b,c)               M_LADD_IMM(a, b, c)
 
-
-/* function gen_resolvebranch **************************************************
-
-       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*)(ip)-1) & ~M_BRMASK) | (((s4)((to)-(so))+4)&((((*((s4*)(ip)-1)>>26)&63)==18)?M_BRAMASK:M_BRMASK))
-
 #endif /* _CODEGEN_H */