* Removed all Id tags.
[cacao.git] / src / vm / jit / s390 / codegen.h
index caf820ef3e94062c15f6cfe4bda6515ea161c26e..7ef8c41eab21529fcc69bc0b18f2a466a67a88c2 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/jit/x86_64/codegen.h - code generation macros for x86_64
+/* src/vm/jit/s390/codegen.h - code generation macros for s390
 
-   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
-            Christian Thalinger
-
-   $Id: codegen.h 7323 2007-02-11 17:52:12Z pm $
-
 */
 
 
 #include "vm/jit/jit.h"
 
 
-/* additional functions and macros to generate code ***************************/
-
-#define CALCOFFSETBYTES(var, reg, val) \
-    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
-    else if ((s4) (val) != 0) (var) += 1; \
-    else if ((reg) == RBP || (reg) == RSP || (reg) == R12 || (reg) == R13) (var) += 1;
-
-
-#define CALCIMMEDIATEBYTES(var, val) \
-    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
-    else (var) += 1;
-
-
-/* gen_nullptr_check(objreg) */
-
-#define gen_nullptr_check(objreg) \
-       if (checknull) { \
-        M_TEST(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_ICMP(REG_ITMP3, s2); \
-        M_BAE(0); \
-        codegen_add_arrayindexoutofboundsexception_ref(cd, s2); \
-    }
-
-
 /* MCODECHECK(icnt) */
 
 #define MCODECHECK(icnt) \
             codegen_increase(cd); \
     } while (0)
 
+/* some patcher defines *******************************************************/
 
-#define ALIGNCODENOP \
-    if ((s4) (((ptrint) cd->mcodeptr) & 7)) { \
-        M_NOP; \
-    }
-
-
+#define PATCHER_CALL_SIZE    2          /* size in bytes of a patcher call    */
+#define PATCHER_NOPS M_NOP3
+#define PATCHER_NOPS_SKIP   2
 
-#define LCONST(r,c) \
-    do { \
-        if ((c) == 0) \
-            M_CLR((d)); \
-        else \
-            M_MOV_IMM((c), (d)); \
-    } while (0)
-
-/* branch defines *************************************************************/
+/* branch defines ************************************************************/
 
 #define BRANCH_NOPS \
-    do { \
-        M_NOP; \
-    } while (0)
-
-
-/* some patcher defines *******************************************************/
+       do { \
+               if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) { \
+                       M_NOP2; M_NOP2; /* brc */ \
+                       M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; /* ild */ \
+                       M_NOP2; /* ar, bcr */ \
+               } else { \
+                       M_NOP; /* brc */ \
+               } \
+       } while (0) 
 
-#define PATCHER_CALL_SIZE    4          /* size in bytes of a patcher call    */
+/* stub defines **************************************************************/
 
-#define PATCHER_NOPS \
-    do { \
-        M_NOP; \
-    } while (0)
+#define COMPILERSTUB_CODESIZE    (SZ_AHI + SZ_L + SZ_L + SZ_BCR)
 
 /* *** BIG TODO ***
  * Make all this inline functions !!!!!!!!!!
  * In debug mode, the instructions assert that %r0 was not given as argument.
  */
 
-#if 1
+#if !defined(NDEBUG)
+
 #      include <stdlib.h>
+
        /* register none */
 #      define RN 16
-       /* Optional register.
-        * Check that value given is %r1 - %r15 or RN
-        */
-#      define _WITH_LINE(f, ...) f(__FILE__, __LINE__, __VA_ARGS__)
+
        static inline int _OR_IMPL(const char *file, int line, int r) {
                if(!(
                        ((0 < r) && (r < 16)) ||
                }
                return ((r == RN) ? 0 : r);
        }
-#      define _OR(r) _WITH_LINE(_OR_IMPL, r)
+#      define _OR(r) _OR_IMPL(__FILE__, __LINE__, r)
 
 #      define _SMIN(b) (-(1 << (bits - 1)))
 #      define _SMAX(b) ((1 << (b - 1)) - 1)
                }
                return i;
        }
-#      define _UBITS(i, bits) _WITH_LINE(_UBITS_IMPL, i, bits)
+
+#      define _UBITS(i, bits) _UBITS_IMPL(__FILE__, __LINE__, i, bits)
+
        static inline int _SBITS_IMPL(const char *file, int line, int i, int bits) {
                if(!((_SMIN(bits) <= i) && (i <= _SMAX(bits)))) {
                        fprintf(stdout, "%d (0x%X) is not an signed %d bit integer at %s:%d.\n", i, i, bits, file, line);
                }
                return i;
        }
-#      define _SBITS(i, bits) _WITH_LINE(_SBITS_IMPL, i, bits)
+
+#      define _SBITS(i, bits) _SBITS_IMPL(__FILE__, __LINE__, i, bits)
+
        static inline int _BITS_IMPL(const char *file, int line, int i, int bits) {
                if (!(
                        ((_UMIN(bits) <= i) && (i <= _UMAX(bits))) ||
                }
                return i;
        }
-#      define _BITS(i, bits) _WITH_LINE(_BITS_IMPL, i, bits)
+
+#      define _BITS(i, bits) _BITS_IMPL(__FILE__, __LINE__, i, bits)
+
 #else
 #      define RN 0
 #      define _OR(x) (x)
 #define _CODE2(code) _CODE(u2, code)
 #define _CODE4(code) _CODE(u4, code)
 
-#define _IFNEG(val, neg, pos) \
-       do { if ((val) < 0) { neg ; } else { pos ; } } while (0)
+#define _IF(cond, t, f) \
+       do { if (cond) { t ; } else { f ; } } while (0)
+
+#define _IFNEG(val, neg, pos) _IF((val) < 0, neg, pos)
 
 #define N_RR(op, r1, r2) \
        _CODE2( (_OP(op) << 8) | (_R(r1) << 4) | _R(r2) )
 #define SZ_RX 4
 
 #define N_RI(op1, op2, r1, i2) \
-       _CODE4( (_OP(op1) << 24) | (_R(r1) << 20) | (_OP4(op2) << 16) | (u2)_I16(i2) )
+       _CODE4( (_OP(op1) << 24) | (_R(r1) << 20) | (_OP4(op2) << 16) | (u2)_SI16(i2) )
+
+#define N_RI2(op1, op2, r1, i2) \
+       _CODE4( (_OP(op1) << 24) | (_R(r1) << 20) | (_OP4(op2) << 16) | (u2)_UI16(i2) )
 
 #define SZ_RI 4
 
 
 #define S_RRF 4
 
+#define N_IMM_MIN -32768
+#define N_IMM_MAX 32767
+#define N_VALID_IMM(x) ((N_IMM_MIN <= (x)) && ((x) <= N_IMM_MAX))
+#define ASSERT_VALID_IMM(x) assert(N_VALID_IMM(x))
+
+#define N_DISP_MIN 0
+#define N_DISP_MAX 0xFFF
+#define N_VALID_DISP(x) ((N_DISP_MIN <= (x)) && ((x) <= N_DISP_MAX))
+#define ASSERT_VALID_DISP(x) assert(N_VALID_DISP(x))
+
+#define N_PV_OFFSET (-0xFFC)
+#define N_DSEG_DISP(x) ((x) - N_PV_OFFSET)
+#define N_VALID_DSEG_DISP(x) N_VALID_DISP(N_DSEG_DISP(x))
+
+#define N_BRANCH_MIN -32768
+#define N_BRANCH_MAX 32767
+#define N_VALID_BRANCH(x) ((N_BRANCH_MIN <= (x)) && ((x) <= N_BRANCH_MAX))
+#define ASSERT_VALID_BRANCH(x) assert(N_VALID_BRANCH(x))
+
 /* Condition codes */
 
 #define DD_O 1
 #define DD_NO 14
 #define DD_ANY 15
 
+#define DD_0 8
+#define DD_1 4
+#define DD_2 2
+#define DD_3 1
+
 /* Misc */
 
-#define N_LONG_0() _CODE4(0)
+/* Trap instruction.
+ * If most significant bits of first opcode byte are 00, then
+ * format is RR (1 byte opcode) or E (2 bytes opcode). 
+ * There seems to be no opcode 0x02 or 0x02**, so we'll define
+ * our trap instruction as:
+ * +--------+--------+
+ * |  0x02  |  data  |
+ * +--------+--------+
+ * 0                 15
+ */
+#define N_ILL(data) _CODE2(0x0200 | _UBITS(data, 8))
+#define SZ_ILL 2
+
+#define N_LONG(l) _CODE4(l)
+#define SZ_LONG 4
 
 /* Chapter 7. General instructions */
 
 #      define SZ_AHI SZ_RI
 #define N_ALR(r1, r2) N_RR(0x1E, r1, r2)
 #define N_AL(r1, d2, x2, b2) N_RX(0x5E, r1, d2, x2, b2)
-#define N_NR(r1, r2) N_RR(r1, r2)
+#define N_NR(r1, r2) N_RR(0x14, r1, r2)
+#      define SZ_NR SZ_RR
 #define N_N(r1, d2, x2, b2) N_RX(0x54, r1, d2, x2, b2)
 #define N_NI(d1, b1, i2) N_SI(0x94, d1, b1, i2)
-#define N_NC(d1, l, b1, d2, b2) N_NC(0xD4, l, b1, d1, b2, d2)
+#define N_NC(d1, l, b1, d2, b2) N_SS(0xD4, (l - 1), b1, d1, b2, d2)
 #define N_BALR(r1, r2) N_RR(0x05, r1, _OR(r2))
 #define N_BAL(r1, d2, x2, b2) N_RX(0x45, r1, d2, x2, b2)
 #define N_BASR(r1, r2) N_RR(0x0D, r1, _OR(r2))
+#      define SZ_BASR SZ_RR
 #define N_BAS(r1, d2, x2, b2) N_RX(0x4D, r1, d2, x2, b2)
 #define N_BASSM(r1, r2) N_RR(0x0C, r1, _OR(r2))
 #define N_BSM(r1, r2) N_RR(0x0B, r1, _OR(r2))
 #      define N_J(i2) N_BRC(DD_ANY, i2)
 #      define SZ_BRC SZ_RI
 #      define SZ_J SZ_RI
+#      define N_BRC_BACK_PATCH(brc_pos) \
+               do { \
+                       *(u4 *)(brc_pos) |= (u4)(cd->mcodeptr - (brc_pos)) / 2; \
+               } while (0)
 #define N_BRCT(r1, i2) N_RI(0xA7, 0x6, r1, (i2) / 2)
 #define N_BRXH(r1, r3, i2) N_RSI(0x84, r1, r3, (i2) / 2)
 #define N_BRXLE(r1, r3, i2) N_RSI(0x85, r1, r2, (i2) / 2)
 #define N_CLR(r1, r2) N_RR(0x15, r1, r2)
 #define N_CL(r1, d2, x2, b2) N_RX(0x55, r1, d2, x2, b2)
 #define N_CLI(d1, b1, i2) N_SI(0x95, d1, b1, i2)
-#define N_CLC(d1, l, b1, d2, b2) N_SS(0xD5, d1, l, b1, d2, b2)
+#define N_CLC(d1, l, b1, d2, b2) N_SS(0xD5, d1, (l - 1), b1, d2, b2)
 #define N_CLM(r1, m3, d2, b2) N_RS(0xBD, r1, m3, d2, b2)
 #define N_CLCL(r1, r2) N_RR(0x0F, r1, r2)
 #define N_CLCLE(r1, r3, d2, b2) N_RS(0xA9, r1, r3, d2, b2)
 #define N_XR(r1, r2) N_RR(0x17, r1, r2)
 #define N_X(r1, d2, x2, b2) N_RX(0x57, r1, d2, x2, b2)
 #define N_XI(d1, b1, i2) N_SI(0x97, d1, b1, i2)
-#define N_XC(d1, l, b1, d2, b2) N_SS(0xD7, d1, l, b1, d2, b2)
+#define N_XC(d1, l, b1, d2, b2) N_SS(0xD7, d1, (l - 1), b1, d2, b2)
 #define N_EX(r1, d2, x2, b2) N_RX(0x44, r1, d2, x2, b2)
 #define N_EAR(r1, r2) N_RRE(0xB24F, r1, r2)
 #define N_IC(r1, d2, x2, b2) N_RX(0x43, r1, d2, x2, b2)
 #define N_LAE(r1, d2, x2, b2) N_RX(0x51, r1, d2, x2, b2)
 #define N_LTR(r1, r2) N_RR(0x12, r1, r2)
 #define N_LCR(r1, r2) N_RR(0x13, r1, r2)
+#      define SZ_LCR SZ_RR
 #define N_LH(r1, d2, x2, b2) N_RX(0x48, r1, d2, x2, b2)
 #define N_LHI(r1, i2) N_RI(0xA7, 0x8, r1, i2)
 #      define SZ_LHI SZ_RI
 #define N_LPR(r1, r2) N_RR(0x10, r1, r2)
 #define N_MC(d1, b1, i2) N_SI(0xAF, d1, b1, i2)
 #define N_MVI(d1, b1, i2) N_SI(0x92, d1, b1, i2)
-#define N_MVC(d1, l, b1, d2, b2) N_SS(0xD2, d1, l, b1, d2, b2)
-#define N_MVCIN(d1, l, b1, d2, b2) N_SS(0xEB, d1, l, b1, d2, b2)
+#define N_MVC(d1, l, b1, d2, b2) N_SS(0xD2, d1, (l - 1), b1, d2, b2)
+#define N_MVCIN(d1, l, b1, d2, b2) N_SS(0xEB, d1, (l - 1), b1, d2, b2)
 #define N_MVCL(r1, r2) N_RR(0x0E, r1, r2)
 #define N_MVCLE(r1, r3, d2, b2)  N_RS(0xAB, r1, r3, d2, b2)
-#define N_MVN(d1, l, b1, d2, b2) N_SS(0xD1, d1, l, b1, d2, b2)
+#define N_MVN(d1, l, b1, d2, b2) N_SS(0xD1, d1, (l - 1), b1, d2, b2)
 #define N_MVPG(r1, r2) N_RRE(0xB254, r1, r2)
 #define N_MVST(r1, r2) N_RRE(0xB255, r1, r2)
-#define N_MVO(d1, l1, b1, d2, l2, b2) N_SS2(0xF1, d1, l1, b1, d2, l2, b2)
-#define N_MVZ(d1, l, b1, d2, b2) N_SS(0xD3, d1, l, b1, d2, b2)
+#define N_MVO(d1, l1, b1, d2, l2, b2) N_SS2(0xF1, d1, (l1 - 1), b1, d2, (l2 - 1), b2)
+#define N_MVZ(d1, l, b1, d2, b2) N_SS(0xD3, d1, (l - 1), b1, d2, b2)
 #define N_MR(r1, r2) N_RR(0x1C, r1, r2)
 #define N_M(r1, d2, x2, b2) N_RX(0x5C, r1, d2, x2, b2)
 #define N_MH(r1, d2, x2, b2) N_RX(0x4C, r1, d2, x2, b2)
 #define N_OR(r1, r2) N_RR(0x16, r1, r2)
 #define N_O(r1, d2, x2, b2) N_RX(0x56, r1, d2, x2, b2)
 #define N_OI(d1, b1, i2) N_SI(0x96, d1, b1, i2)
-#define N_OC(d1, l, b1, d2, b2) N_SS(0xD6, d1, l, b1, d2, b2)
-#define N_PACK(d1, l1, b1, d2, l2, b2) N_SS2(0xF2, d1, l1, b1, d2, l2, b2)
+#define N_OC(d1, l, b1, d2, b2) N_SS(0xD6, d1, (l - 1), b1, d2, b2)
+#define N_PACK(d1, l1, b1, d2, l2, b2) N_SS2(0xF2, d1, (l1 - 1), b1, d2, (l2 - 1), b2)
 #define N_PLO(r1, d2, b2, r3, d4, b4) N_SS2(0xEE, d2, r1, b2, d4, r3, b4)
 #define N_SRST(r1, r2) N_RRE(0xB25E, r1, r2)
 #define N_SAR(r1, r2) N_RRE(0xB24E, r1, r2)
 #define N_SVC(i) N_RR2(0x0A, i)
 #define N_TS(d2, b2) N_S2(0x93, d2, b2)
 #define N_TM(d1, b1, i2) N_SI(0x91, d1, b1, i2)
-#define N_TMH(r1, i2) N_RI(0xA7, 0x00, r1, i2)
-#define N_TML(r1, i2) N_RI(0xA7, 0x01, r1, i2)
-#define N_TR(d1, l, b1, d2, b2) N_SS(0xDC, d1, l, b1, d2, b2)
-#define N_TRT(d1, l, b1, d2, b2) N_SS(0xDD, d1, l, b1, d2, b2)
+#define N_TMH(r1, i2) N_RI2(0xA7, 0x00, r1, i2)
+#define N_TML(r1, i2) N_RI2(0xA7, 0x01, r1, i2)
+#define N_TR(d1, l, b1, d2, b2) N_SS(0xDC, d1, (l - 1), b1, d2, b2)
+#define N_TRT(d1, l, b1, d2, b2) N_SS(0xDD, d1, (l - 1), b1, d2, b2)
 #define N_TRE(r1, r2) N_RRE(0xB2A5, r1, r2)
-#define N_UNPK(d1, l1, b1, d2, l2, b2) N_SS2(0xF3, d1, l1, b1, d2, l2, b2)
+#define N_UNPK(d1, l1, b1, d2, l2, b2) N_SS2(0xF3, d1, (l1 - 1), b1, d2, (l2 - 2), b2)
 #define N_UPT() N_E(0x0102)
 
 /* Chapter 9. Floating point instructions */
 
 /* chapter 19. Binary floating point instructions */
 
+#define N_AEBR(r1, r2) N_RRE(0xB30A, r1, r2)
+#define N_ADBR(r1, r2) N_RRE(0xB31A, r1, r2)
+#define N_AXBR(r1, r2) N_RRE(0xB34A, r1, r2)
+#define N_AEB(r1, d2, x2, b2) N_RXE(0xED0A, r1, d2, x2, b2)
+#define N_ADB(r1, d2, x2, b2) N_RXE(0xED1A, r1, d2, x2, b2)
+
 #define N_CEBR(r1, r2) N_RRE(0xB309, r1, r2)
 #define N_CDBR(r1, r2) N_RRE(0xB319, r1, r2)
 #define N_CXBR(r1, r2) N_RRE(0xB349, r1, r2)
 #define N_CFDBR(r1, m3, r2) N_RRF(0xB399, r1, m3, r2)
 #define N_CFXBR(r1, m3, r2) N_RRF(0xB39A, r1, m3, r2)
 
+#define N_DEBR(r1, r2) N_RRE(0xB30D, r1, r2)
+#define N_DDBR(r1, r2) N_RRE(0xB31D, r1, r2)
+#define N_DXBR(r1, r2) N_RRE(0xB34D, r1, r2)
+#define N_DEB(r1, d2, x2, b2) N_RXE(0xED0D, r1, d2, x2, b2)
+#define N_DDB(r1, d2, x2, b2) N_RXE(0xED1D, r1, d2, x2, b2)
+
+#define N_LCEBR(r1, r2) N_RRE(0xB303, r1, r2)
+#define N_LCDBR(r1, r2) N_RRE(0xB313, r1, r2)
+#define N_LCXBR(r1, r2) N_RRE(0xB343, r1, r2)
+
+#define N_LDEBR(r1, r2) N_RRE(0xB304, r1, r2)
+#      define SZ_LDEBR SZ_RRE
+#define N_LXDBR(r1, r2) N_RRE(0xB305, r1, r2)
+#define N_LXEBR(r1, r2) N_RRE(0xB306, r1, r2)
+
+#define N_LEDBR(r1, r2) N_RRE(0xB344, r1, r2)
+#define N_LDXBR(r1, r2) N_RRE(0xB345, r1, r2)
+#define N_LEXBR(r1, r2) N_RRE(0xB346, r1, r2)
+
+#define N_LTEBR(r1, r2) N_RRE(0xB302, r1, r2)
+#define N_LTDBR(r1, r2) N_RRE(0xB312, r1, r2)
+#define N_LTXBR(r1, r2) N_RRE(0xB342, r1, r2)
+
 #define N_MEEBR(r1, r2) N_RRE(0xB317, r1, r2)
 #define N_MDBR(r1, r2) N_RRE(0xB31C, r1, r2)
 #define N_MXBR(r1, r2) N_RRE(0xB34C, r1, r2)
 #define N_MDEBR(r1, r2) N_RRE(0xB30C, r1, r2)
 #define N_MXDBR(r1, r2) N_RRE(0xB307, r1, r2)
 
+#define N_SEBR(r1, r2) N_RRE(0xB30B, r1, r2)
+#define N_SDBR(r1, r2) N_RRE(0xB31B, r1, r2)
+#define N_SXBR(r1, r2) N_RRE(0xB34B, r1, r2)
+#define N_SEB(r1, d2, x2, b2) N_RXE(0xED0B, r1, d2, x2, b2)
+#define N_SDB(r1, d2, x2, b2) N_RXE(0xED1B, r1, d2, x2, b2)
+
 /* Alpha like instructions */
 
 #define M_CALL(r2) N_BASR(R14, r2)
+#define M_ILL(data) N_ILL(data)
+#define M_ILL2(data1, data2) N_ILL((_UBITS(data1, 4) << 4) | _UBITS(data2, 4))
+#define M_LONG(l) N_LONG(l)
 
-#define M_ILD(r, b, d) _IFNEG( \
-       d, \
-       N_LHI(r, d); N_L(r, 0, r, b), \
-       N_L(r, d, RN, b) \
-)
+#define M_ILD(r, b, d) \
+       do { \
+               if (N_VALID_DISP(d)) { \
+                       N_L(r, d, RN, b); \
+               } else if ((r == R0) && N_VALID_IMM(d)) { \
+                       N_LR(R0, R1); \
+                       N_LHI(R1, d); \
+                       N_L(R1, 0, R1, b); \
+                       N_XR(R1, R0); \
+                       N_XR(R0, R1); \
+                       N_XR(R1, R0); \
+               } else if ((r != R0) && N_VALID_IMM(d)) { \
+                       N_LHI(r, d); N_L(r, 0, r, b); \
+               } else { \
+                       N_BRAS(r, SZ_BRAS + SZ_LONG); \
+                       N_LONG(d); \
+                       N_L(r, 0, RN, r); \
+                       N_L(r, 0, r, b); \
+               } \
+       } while (0)
+
+#define M_ILD_DSEG(r, d) M_ILD(r, REG_PV, N_DSEG_DISP(d))
 
 #define M_ALD(r, b, d) M_ILD(r, b, d)
+#define M_ALD_DSEG(r, d) M_ALD(r, REG_PV, N_DSEG_DISP(d))
 
-#define M_LDA(r, b, d) _IFNEG( \
-       d, \
-       N_LHI(r, d); N_LA(r, 0, r, b), \
-       N_LA(r, d, RN, b) \
-)
+#define M_LDA(r, b, d) \
+       do { \
+               if (N_VALID_DISP(d)) { \
+                       N_LA(r, d, RN, b); \
+               } else if (N_VALID_IMM(d)) { \
+                       N_LHI(r, d); \
+                       N_LA(r, 0, r, b); \
+               } else { \
+                       N_BRAS(r, SZ_BRAS + SZ_LONG); \
+                       N_LONG(d); \
+                       N_L(r, 0, RN, r); \
+                       N_LA(r, 0, r, b); \
+               } \
+       } while (0)
+#define M_LDA_DSEG(r, d) M_LDA(r, REG_PV, N_DSEG_DISP(d))
 
 #define M_FLD(r, b, d) N_LE(r, d, RN, b)
-
 #define M_FLDN(r, b, d, t) _IFNEG( \
        d, \
        N_LHI(t, d); N_LE(r, 0, t, b), \
        N_LE(r, d, RN, b) \
 )
-               
+#define M_FLD_DSEG(r, d, t) M_FLDN(r, REG_PV, N_DSEG_DISP(d), t)
+
 #define M_DLD(r, b, d) N_LD(r, d, RN, b)
 #define M_DLDN(r, b, d, t) _IFNEG( \
        d, \
        N_LHI(t, d); N_LD(r, 0, t, b), \
        N_LD(r, d, RN, b) \
 )
+#define M_DLD_DSEG(r, d, t) M_DLDN(r, REG_PV, N_DSEG_DISP(d), t)
 
 #define M_LLD(r, b, d) _IFNEG( \
        d, \
        N_LHI(GET_LOW_REG(r), d); \
                N_L(GET_HIGH_REG(r), 0, GET_LOW_REG(r), b); \
                N_L(GET_LOW_REG(r), 4, GET_LOW_REG(r), b), \
-       N_L(GET_HIGH_REG(r), 0, RN, b); N_L(GET_LOW_REG(r), 4, RN, b) \
+       N_L(GET_HIGH_REG(r), (d) + 0, RN, b); N_L(GET_LOW_REG(r), (d) + 4, RN, b) \
 )
+#define M_LLD_DSEG(r, d) M_LLD(r, REG_PV, N_DSEG_DISP(d)
 
 /* MOV(a, b) -> mov from A to B */
 
 #define M_LST(r, b, d) _IFNEG( \
        d, \
        assert(0), \
-       N_ST(GET_HIGH_REG(r), 0, RN, b); N_ST(GET_LOW_REG(r), 4, RN, b) \
+       N_ST(GET_HIGH_REG(r), (d) + 0, RN, b); N_ST(GET_LOW_REG(r), (d) + 4, RN, b) \
 )
 #define M_TEST(r) N_LTR(r, r)
 #define M_BEQ(off) N_BRC(DD_E, off)
 #define M_BGT(off) N_BRC(DD_H, off)
 #define M_BLT(off) N_BRC(DD_L, off)
 #define M_BGE(off) N_BRC(DD_HE, off)
+#define M_BO(off) N_BRC(DD_O, off)
 
 #define M_CMP(r1, r2) N_CR(r1, r2)
+#define M_CMPU(r1, r2) N_CLR(r1, r2)
 #define M_CLR(r) N_LHI(r, 0)
-#define M_AADD_IMM(val, reg) N_LA(reg, val, RN, reg)
+#define M_AADD_IMM(val, reg) N_AHI(reg, val)
 #define M_IADD_IMM(val, reg) N_AHI(reg, val)
 #define M_ISUB_IMM(val, reg) N_AHI(reg, -(val))
 #define M_ASUB_IMM(val, reg) N_AHI(reg, -(val))
 #define M_RET N_BCR(DD_ANY, R14)
 #define M_BSR(ret_reg, disp) N_BRAS(ret_reg, disp)
 #define M_BR(disp) N_BRC(DD_ANY, disp)
-#define M_JMP(rd, rs) N_BCR(DD_ANY, rs)
+#define M_JMP(rs, rd) _IF(rs == RN, N_BCR(DD_ANY, rd), N_BASR(rs, rd))
 #define M_NOP N_BC(0, 0, RN, RN)
+#define M_NOP2 N_BCR(0, RN)
+#define M_NOP3 N_BCR(0, 1)
 #define M_JSR(reg_ret, reg_addr) N_BASR(reg_ret, reg_addr)
 #define M_ICMP(a, b) N_CR(a, b)
+#define M_ICMPU(a, b) N_CLR(a, b)
+#define M_ICMP_IMM(a, b) N_CHI(a, b)
 #define M_CVTIF(src, dst) N_CEFBR(dst, src)
-#define M_CVTID(src, dst) N_CEDBR(dst, src)
+#define M_CVTID(src, dst) N_CDFBR(dst, src)
 #define M_FMUL(a, dest) N_MEEBR(dest, a)
+#define M_FSUB(a, dest) N_SEBR(dest, a)
+#define M_FADD(a, dest) N_AEBR(dest, a)
+#define M_FDIV(a, dest) N_DEBR(dest, a)
+#define M_DMUL(a, dest) N_MDBR(dest, a)
+#define M_DSUB(a, dest) N_SDBR(dest, a)
+#define M_DADD(a, dest) N_ADBR(dest, a)
+#define M_DDIV(a, dest) N_DDBR(dest, a)
 #define M_CVTFI(src, dst) N_CFEBR(dst, 5, src)
+#define M_CVTDI(src, dst) N_CFDBR(dst, 5, src)
 #define M_IADD(a, dest) N_AR(dest, a)
+#define M_AADD(a, dest) N_AR(dest, a)
 #define M_ISUB(a, dest) N_SR(dest, a)
+#define M_ASUB(a, dest) N_SR(dest, a)
+#define M_IAND(a, dest) N_NR(dest, a)
+#define M_IOR(a, dest) N_OR(dest, a)
+#define M_IXOR(a, dest) N_XR(dest, a)
+#define M_CVTFD(src,dst) N_LDEBR(dst, src)
+#define M_CVTDF(src,dst) N_LEDBR(dst, src)
+
+#define M_SLL_IMM(imm, reg) N_SLL(reg, imm, RN) 
+#define M_SLA_IMM(imm, reg) N_SLA(reg, imm, RN) 
+
+#define M_SLDL_IMM(imm, reg) N_SLDL(reg, imm, RN) 
+#define M_SLDA_IMM(imm, reg) N_SLDA(reg, imm, RN) 
+
+#define M_SRL_IMM(imm, reg) N_SRL(reg, imm, RN)
+#define M_SRA_IMM(imm, reg) N_SRA(reg, imm, RN)
+
+#define M_SRDL_IMM(imm, reg) N_SRDL(reg, imm, RN)
+#define M_SRDA_IMM(imm, reg) N_SRDA(reg, imm, RN)
+
+#define M_SLL(op, dst) N_SLL(dst, 0, op)
+#define M_SLA(op, dst) N_SLA(dst, 0, op)
+
+#define M_SLDL(op, dst) N_SLDL(dst, 0, op)
+#define M_SLDA(op, dst) N_SLDA(dst, 0, op)
+
+#define M_SRL(op, dst) N_SRL(dst, 0, op)
+#define M_SRA(op, dst) N_SRA(dst, 0, op)
+
+#define M_SRDL(op, dst) N_SRDL(dst, 0, op)
+#define M_SRDA(op, dst) N_SRDA(dst, 0, op)
+
+#define M_IMUL_IMM(val, reg) N_MHI(reg, val)
+#define M_IMUL(a, dest) N_MSR(dest, a)
+
+#define M_INEG(a, dest) N_LCR(dest, a)
+
+#define M_FCMP(a, b) N_CEBR(a, b)
+#define M_DCMP(a, b) N_CDBR(a, b)
+
+#define M_FMOVN(r, dst) N_LCEBR(dst, r)
+#define M_DMOVN(r, dst) N_LCDBR(dst, r)
 
 #define ICONST(reg, i) \
        do { \
-               if ((i) >= -32768 && (i) <= 32767) { \
+               if (N_VALID_IMM(i)) { \
                        N_LHI(reg, i); \
                } else { \
                        disp = dseg_add_s4(cd, (i)); \
-                       N_ILD(reg, REG_PV, disp); \
+                       M_ILD_DSEG(reg, disp); \
                } \
        } while (0) 
 
+#define LCONST(reg,c) \
+       do { \
+           ICONST(GET_HIGH_REG((reg)), (s4) ((s8) (c) >> 32)); \
+           ICONST(GET_LOW_REG((reg)), (s4) ((s8) (c))); \
+       } while (0)
+
 /* M_INTMOVE:
     generates an integer-move from register a to b.
     if a and b are the same int-register, no code will be generated.
         } \
     } while (0)
 
-
-
-/* ----------------------------------------------- */
-
-#define _DEPR(x) \
+#define M_ISUB_IMM32(imm, tmpreg, reg) \
        do { \
-               fprintf(stdout, \
-                       "Using old x86_64 instruction %s at %s (%s:%d), fix this.\n", \
-                       #x, __FUNCTION__, __FILE__, __LINE__); \
+               if (N_VALID_IMM(imm)) { \
+                       M_ISUB_IMM(imm, reg); \
+               } else { \
+                       ICONST(tmpreg, imm); \
+                       M_ISUB(tmpreg, reg); \
+               } \
        } while (0)
 
-#define M_MOV_IMM(a,b) _DEPR( M_MOV_IMM(a,b) )
-
-#define M_IMOV(a,b) _DEPR( M_IMOV(a,b) )
-#define M_IMOV_IMM(a,b) _DEPR( M_IMOV_IMM(a,b) )
-
-
-#define M_ILD32(a,b,disp) _DEPR( M_ILD32(a,b,disp) )
-#define M_LLD32(a,b,disp) _DEPR( M_LLD32(a,b,disp) )
-
-
-#define M_IST_IMM(a,b,disp) _DEPR( M_IST_IMM(a,b,disp) )
-#define M_LST_IMM32(a,b,disp) _DEPR( M_LST_IMM32(a,b,disp) )
-
-#define M_IST32(a,b,disp) _DEPR( M_IST32(a,b,disp) )
-#define M_LST32(a,b,disp) _DEPR( M_LST32(a,b,disp) )
-
-#define M_IST32_IMM(a,b,disp) _DEPR( M_IST32_IMM(a,b,disp) )
-#define M_LST32_IMM32(a,b,disp) _DEPR( M_LST32_IMM32(a,b,disp) )
-
-#define M_IMUL(a,b) _DEPR( M_IMUL(a,b) )
-
-#define M_IMUL_IMM(a,b,c) _DEPR( M_IMUL_IMM(a,b,c) )
-
-#define M_LADD(a,b) _DEPR( M_LADD(a,b) )
-#define M_LSUB(a,b) _DEPR( M_LSUB(a,b) )
-#define M_LMUL(a,b) _DEPR( M_LMUL(a,b) )
-
-#define M_LADD_IMM(a,b) _DEPR( M_LADD_IMM(a,b) )
-#define M_LSUB_IMM(a,b) _DEPR( M_LSUB_IMM(a,b) )
-#define M_LMUL_IMM(a,b,c) _DEPR( M_LMUL_IMM(a,b,c) )
-
-#define M_IINC(a) _DEPR( M_IINC(a) )
-#define M_IDEC(a) _DEPR( M_IDEC(a) )
-
-#define M_ALD32(a,b,disp) _DEPR( M_ALD32(a,b,disp) )
-
-#define M_AST_IMM32(a,b,c) _DEPR( M_AST_IMM32(a,b,c) )
-
-#define M_AADD(a,b) _DEPR( M_AADD(a,b) )
-
-#define M_LADD_IMM32(a,b) _DEPR( M_LADD_IMM32(a,b) )
-#define M_AADD_IMM32(a,b) _DEPR( M_AADD_IMM32(a,b) )
-#define M_LSUB_IMM32(a,b) _DEPR( M_LSUB_IMM32(a,b) )
-
-#define M_ILEA(a,b,c) _DEPR( M_ILEA(a,b,c) )
-#define M_LLEA(a,b,c) _DEPR( M_LLEA(a,b,c) )
-#define M_ALEA(a,b,c) _DEPR( M_ALEA(a,b,c) )
-
-#define M_INEG(a) _DEPR( M_INEG(a) )
-#define M_LNEG(a) _DEPR( M_LNEG(a) )
+#define M_ASUB_IMM32(imm, tmpreg, reg) M_ISUB_IMM32(imm, tmpreg, reg)
 
-#define M_IAND(a,b) _DEPR( M_IAND(a,b) )
-#define M_IOR(a,b) _DEPR( M_IOR(a,b) )
-#define M_IXOR(a,b) _DEPR( M_IXOR(a,b) )
+#define PROFILE_CYCLE_START 
 
-#define M_IAND_IMM(a,b) _DEPR( M_IAND_IMM(a,b) )
-#define M_IOR_IMM(a,b) _DEPR( M_IOR_IMM(a,b) )
-#define M_IXOR_IMM(a,b) _DEPR( M_IXOR_IMM(a,b) )
+#define PROFILE_CYCLE_STOP 
 
-#define M_LAND(a,b) _DEPR( M_LAND(a,b) )
-#define M_LOR(a,b) _DEPR( M_LOR(a,b) )
-#define M_LXOR(a,b) _DEPR( M_LXOR(a,b) )
-
-#define M_LAND_IMM(a,b) _DEPR( M_LAND_IMM(a,b) )
-#define M_LOR_IMM(a,b) _DEPR( M_LOR_IMM(a,b) )
-#define M_LXOR_IMM(a,b) _DEPR( M_LXOR_IMM(a,b) )
-
-#define M_SSEXT(a,b) _DEPR( M_SSEXT(a,b) )
-#define M_ISEXT(a,b) _DEPR( M_ISEXT(a,b) )
-
-#define M_CZEXT(a,b) _DEPR( M_CZEXT(a,b) )
-
-#define M_ISLL_IMM(a,b) _DEPR( M_ISLL_IMM(a,b) )
-#define M_ISRA_IMM(a,b) _DEPR( M_ISRA_IMM(a,b) )
-#define M_ISRL_IMM(a,b) _DEPR( M_ISRL_IMM(a,b) )
-
-#define M_LSLL_IMM(a,b) _DEPR( M_LSLL_IMM(a,b) )
-#define M_LSRA_IMM(a,b) _DEPR( M_LSRA_IMM(a,b) )
-#define M_LSRL_IMM(a,b) _DEPR( M_LSRL_IMM(a,b) )
-
-#define M_LCMP(a,b) _DEPR( M_LCMP(a,b) )
-#define M_LCMP_IMM(a,b) _DEPR( M_LCMP_IMM(a,b) )
-#define M_LCMP_IMM_MEMBASE(a,b,c) _DEPR( M_LCMP_IMM_MEMBASE(a,b,c) )
-#define M_LCMP_MEMBASE(a,b,c) _DEPR( M_LCMP_MEMBASE(a,b,c) )
-
-#define M_ICMP_IMM(a,b) _DEPR( M_ICMP_IMM(a,b) )
-#define M_ICMP_IMM_MEMBASE(a,b,c) _DEPR( M_ICMP_IMM_MEMBASE(a,b,c) )
-#define M_ICMP_MEMBASE(a,b,c) _DEPR( M_ICMP_MEMBASE(a,b,c) )
-
-#define M_BAE(disp) _DEPR( M_BAE(disp) )
-#define M_BA(disp) _DEPR( M_BA(disp) )
-
-#define M_CMOVEQ(a,b) _DEPR( M_CMOVEQ(a,b) )
-#define M_CMOVNE(a,b) _DEPR( M_CMOVNE(a,b) )
-#define M_CMOVLT(a,b) _DEPR( M_CMOVLT(a,b) )
-#define M_CMOVLE(a,b) _DEPR( M_CMOVLE(a,b) )
-#define M_CMOVGE(a,b) _DEPR( M_CMOVGE(a,b) )
-#define M_CMOVGT(a,b) _DEPR( M_CMOVGT(a,b) )
-
-#define M_CMOVEQ_MEMBASE(a,b,c) _DEPR( M_CMOVEQ_MEMBASE(a,b,c) )
-#define M_CMOVNE_MEMBASE(a,b,c) _DEPR( M_CMOVNE_MEMBASE(a,b,c) )
-#define M_CMOVLT_MEMBASE(a,b,c) _DEPR( M_CMOVLT_MEMBASE(a,b,c) )
-#define M_CMOVLE_MEMBASE(a,b,c) _DEPR( M_CMOVLE_MEMBASE(a,b,c) )
-#define M_CMOVGE_MEMBASE(a,b,c) _DEPR( M_CMOVGE_MEMBASE(a,b,c) )
-#define M_CMOVGT_MEMBASE(a,b,c) _DEPR( M_CMOVGT_MEMBASE(a,b,c) )
-
-#define M_CMOVB(a,b) _DEPR( M_CMOVB(a,b) )
-#define M_CMOVA(a,b) _DEPR( M_CMOVA(a,b) )
-#define M_CMOVP(a,b) _DEPR( M_CMOVP(a,b) )
-
-#define M_PUSH(a) _DEPR( M_PUSH(a) )
-#define M_PUSH_IMM(a) _DEPR( M_PUSH_IMM(a) )
-#define M_POP(a) _DEPR( M_POP(a) )
-
-#define M_JMP_IMM(a) _DEPR( M_JMP_IMM(a) )
-#define M_CALL_IMM(a) _DEPR( M_CALL_IMM(a) )
-
-
-
-
-#define M_FLD32(a,b,disp) _DEPR( M_FLD32(a,b,disp) )
-#define M_DLD32(a,b,disp) _DEPR( M_DLD32(a,b,disp) )
-
-
-#define M_FST32(a,b,disp) _DEPR( M_FST32(a,b,disp) )
-#define M_DST32(a,b,disp) _DEPR( M_DST32(a,b,disp) )
-
-#define M_FADD(a,b) _DEPR( M_FADD(a,b) )
-#define M_DADD(a,b) _DEPR( M_DADD(a,b) )
-#define M_FSUB(a,b) _DEPR( M_FSUB(a,b) )
-#define M_DSUB(a,b) _DEPR( M_DSUB(a,b) )
-#define M_DMUL(a,b) _DEPR( M_DMUL(a,b) )
-#define M_FDIV(a,b) _DEPR( M_FDIV(a,b) )
-#define M_DDIV(a,b) _DEPR( M_DDIV(a,b) )
-
-#define M_CVTLF(a,b) _DEPR( M_CVTLF(a,b) )
-#define M_CVTLD(a,b) _DEPR( M_CVTLD(a,b) )
-#define M_CVTDI(a,b) _DEPR( M_CVTDI(a,b) )
-#define M_CVTFL(a,b) _DEPR( M_CVTFL(a,b) )
-#define M_CVTDL(a,b) _DEPR( M_CVTDL(a,b) )
-
-#define M_CVTFD(a,b) _DEPR( M_CVTFD(a,b) )
-#define M_CVTDF(a,b) _DEPR( M_CVTDF(a,b) )
-
-
-/* system instructions ********************************************************/
-
-#define M_RDTSC _DEPR( M_RDTSC )
-
-#define M_IINC_MEMBASE(a,b) _DEPR( M_IINC_MEMBASE(a,b) )
-
-#define M_IADD_MEMBASE(a,b,c) _DEPR( M_IADD_MEMBASE(a,b,c) )
-#define M_IADC_MEMBASE(a,b,c) _DEPR( M_IADC_MEMBASE(a,b,c) )
-#define M_ISUB_MEMBASE(a,b,c) _DEPR( M_ISUB_MEMBASE(a,b,c) )
-#define M_ISBB_MEMBASE(a,b,c) _DEPR( M_ISBB_MEMBASE(a,b,c) )
-
-#define PROFILE_CYCLE_START _DEPR( PROFILE_CYCLE_START )
-#define __PROFILE_CYCLE_START _DEPR( __PROFILE_CYCLE_START )
-
-#define PROFILE_CYCLE_STOP _DEPR( PROFILE_CYCLE_STOP )
-#define __PROFILE_CYCLE_STOP _DEPR( __PROFILE_CYCLE_STOP )
-
-
-/* function gen_resolvebranch **************************************************
-
-    backpatches a branch instruction
-
-    parameters: ip ... pointer to instruction after branch (void*)
-                so ... offset of instruction after branch  (s8)
-                to ... offset of branch target             (s8)
-
-*******************************************************************************/
-
-#define gen_resolvebranch(ip,so,to) \
-    *((s4*) ((ip) - 4)) = (s4) ((to) - (so));
+s4 codegen_reg_of_dst_notzero(jitdata *jd, instruction *iptr, s4 tempregnum);
 
 #endif /* _CODEGEN_H */
 
-
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where