* Merged in twisti-branch.
[cacao.git] / src / vm / jit / powerpc64 / codegen.h
index 24881f3d9a3a702b6e3efcd3769ac857c887d8e8..4d3d4aef4acce1845424805b83b792f9e6bb3789 100644 (file)
@@ -1,5 +1,5 @@
 /* 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,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
 
    Authors: Andreas Krall
             Stefan Ring
-
-   Changes: Christian Thalinger
+            Christian Thalinger
             Christian Ullrich
 
-   $Id: codegen.h 5389 2006-09-06 23:18:27Z twisti $
+   $Id: codegen.h 6199 2006-12-15 14:27:37Z tbfg $
 
 */
 
 
 /* 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_CMPU(s2, REG_ITMP3);\
-        M_BGE(0);\
-        codegen_add_arrayindexoutofboundsexception_ref(cd, s2); \
-    }
-
-
 /* MCODECHECK(icnt) */
 
 #define MCODECHECK(icnt) \
     } while (0)
 
 
-#define M_COPY(s,d)                     emit_copy(jd, iptr, (s), (d))
 #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)
+
+
 /* 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_EXTSW(a,b)                   M_OP3(31, 986, 0, 0, a, b, 0)
+
+
 /* instruction macros *********************************************************/
 
-#define M_IADD(a,b,c)                   M_OP3(31, 266, 0, 0, c, a, b)
-#define M_LADD(a,b,c)                   M_OP3(31, 266, 0, 0, c, a, b) /* XXX */
+#define M_IADD(a,b,c)                  M_LADD(a,b,c)
+#define M_LADD(a,b,c)                   M_OP3(31, 266, 0, 0, c, a, b) 
 #define M_IADD_IMM(a,b,c)               M_OP2_IMM(14, c, a, b) /* XXX */
 #define M_LADD_IMM(a,b,c)               M_OP2_IMM(14, c, a, b)
 #define M_ADDC(a,b,c)                   M_OP3(31, 10, 0, 0, c, a, b)
 #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_ISUB(a,b,c)                   M_OP3(31, 40, 0, 0, c, b, a)
-#define M_LSUB(a,b,c)                   M_OP3(31, 40, 0, 0, c, b, a) /* XXX */
+#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_SLL(a,b,c)                    M_OP3(31, 27, 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)
 
-#define M_IMUL(a,b,c)                   M_OP3(31, 235, 0, 0, c, a, b)
-#define M_IMUL_IMM(a,b,c)               M_OP2_IMM(7, c, a, b)
-#define M_IDIV(a,b,c)                   M_OP3(31, 491, 0, 0, c, a, b)
+#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, 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_RLWINM(a,b,0,31-(b),c)
+#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);    /* RLDICR is said to be turing complete, this seems right */
 #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_LBZX(a,b,c)                   M_OP3(31, 87, 0, 0, a, b, c)
 #define M_LFSX(a,b,c)                   M_OP3(31, 535, 0, 0, a, b, c)
 #define M_LFDX(a,b,c)                   M_OP3(31, 599, 0, 0, a, b, c)
 #define M_BLDU(a,b,c)                   M_OP2_IMM(34, a, b, c) /* LBZ */
 #define M_SLDU(a,b,c)                   M_OP2_IMM(40, a, b, c) /* LHZ */
 
+#if 0
 #define M_ILD_INTERN(a,b,disp)          M_OP2_IMM(32,a,b,disp) /* LWZ */
+#endif
+
+#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_ALD_INTERN(a,b,disp)          M_LLD_INTERN(a,b,disp)
 #define M_ALD(a,b,disp)                 M_LLD(a,b,disp)
+#define M_ALDX(a,b,c)                  M_OP3(31, 21, 0, 0, a, b, c)    /* LDX */
 
 #define M_BST(a,b,c)                    M_OP2_IMM(38, a, b, c) /* STB */
 #define M_SST(a,b,c)                    M_OP2_IMM(44, a, b, c) /* LMW */
 
 #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_CMP(a,b)                      M_OP3(31, 0, 0, 0, 0, a, b)
-#define M_CMPU(a,b)                     M_OP3(31, 32, 0, 0, 0, a, b)
-#define M_CMPI(a,b)                     M_OP2_IMM(11, 0, a, b)
-#define M_CMPUI(a,b)                    M_OP2_IMM(10, 0, a, b)
+#define M_CMP(a,b)                      M_OP3(31, 0, 0, 0, 1, a, b)
+#define M_CMPU(a,b)                     M_OP3(31, 32, 0, 0, 1, a, b)
+#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_CLR(a)                        M_LADD_IMM(0, 0, a)
 #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 */