* src/vm/jit/mips/md-atomic.hpp: New file.
[cacao.git] / src / vm / jit / powerpc64 / codegen.h
index 2f7ea399ddab1a3a1ac900c1fe6c33d76f03ffc5..1ffe1bfd91a3c5d5aa975f92ea1ebf90e4d08795 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 5329 2006-09-05 18:26:32Z 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)
+
+
+/* stub defines ***************************************************************/
+
+#define COMPILERSTUB_CODESIZE    1 * 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_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_IMM(a,b,c)               M_OP2_IMM(14, c, a, b)
+#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_ADDIC(a,b,c)                  M_OP2_IMM(12, c, a, b)
 #define M_ADDICTST(a,b,c)               M_OP2_IMM(13, c, a, b)
 #define M_ADDE(a,b,c)                   M_OP3(31, 138, 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_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_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_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_STWX(a,b,c)                   M_OP3(31, 151, 0, 0, a, b, c)
 #define M_STHX(a,b,c)                   M_OP3(31, 407, 0, 0, a, b, c)
 #define M_STBX(a,b,c)                   M_OP3(31, 215, 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_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 */