* Removed all Id tags.
[cacao.git] / src / vm / jit / sparc64 / codegen.h
index 77f80c8b96f3737f65528d09dde5aab596c22830..ade165128a665165191011b905ce4d3424039e77 100644 (file)
@@ -1,6 +1,7 @@
-/* vm/jit/sparc64/codegen.h - code generation macros and definitions for Sparc
+/* src/vm/jit/sparc64/codegen.h - code generation macros and definitions for
+                                  Sparc64
 
-   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
-            Reinhard Grafl
-            Alexander Jordan
-
-   Changes:
-
-   $Id: codegen.h 4722 2006-04-03 15:36:00Z twisti $
-
 */
 
 #ifndef _CODEGEN_H
 
 #include "vm/jit/jit.h"
 
+#include "md-abi.h" /* for INT_NATARG_CNT */
+
+#include <assert.h>
+
+/* debug defines **************************************************************/
+#ifndef NDEBUG
+# define PASS13BIT(imm) ((((s4)(imm)&0x1fff)<<19)>>19)
+#else
+# define PASS13BIT(imm) imm
+#endif
+
+
+/* from md-abi.c */
+s4 nat_argintregs[INT_NATARG_CNT];
+
 /* branch defines *************************************************************/
 
 #define BRANCH_NOPS \
@@ -56,6 +62,9 @@
 #define PATCHER_CALL_INSTRUCTIONS    2     /* number of instructions          */
 #define PATCHER_CALL_SIZE            2 * 4 /* size in bytes of a patcher call */
 
+#define EXCEPTION_CHECK_INSTRUCTIONS 3     /* number of instructions          */
+#define EXCEPTION_CHECK_SIZE         3 * 4 /* byte size of an exception check */
+
 #define PATCHER_NOPS \
     do { \
         M_NOP; \
     } while (0)
 
 
-/* additional functions and macros to generate code ***************************/
+/* stub defines ***************************************************************/
 
-#define gen_nullptr_check(objreg) \
-    if (checknull) { \
-        M_BEQZ(objreg, 0); \
-        codegen_add_nullpointerexception_ref(cd); \
-        M_NOP; \
-    }
+#define COMPILERSTUB_CODESIZE    4 * 4
 
-#define gen_bound_check \
-    if (checkbounds) { \
-        M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size)); \
-        M_CMP(s2, REG_ITMP3); \
-        M_XBUGE(0); \
-        codegen_add_arrayindexoutofboundsexception_ref(cd, s2); \
-        M_NOP; \
-    }
 
-#define gen_div_check(r) \
-    do { \
-        M_BEQZ((r), 0); \
-        codegen_add_arithmeticexception_ref(cd); \
-        M_NOP; \
-    } while (0)
+/* additional functions and macros to generate code ***************************/
+
 
 /* MCODECHECK(icnt) */
 
         M_NOP; \
     }
 
+#define ALIGN_STACK_SLOTS(slots) \
+       if (slots & 1) \
+               slots++;
+
 
 /* M_INTMOVE:
      generates an integer-move from register rs to rd.
 
 /********************** instruction formats ***********************************/
 
-#define REG    0
-#define IMM    1
+#define REG     0
+#define IMM     1
 
 /* 3-address-operations: M_OP3
  *       op  ..... opcode
  */
 #define M_OP3(op,op3,rd,rs1,rs2,imm) \
        do { \
+               assert(check_13bit_imm(rs2)); \
                *((u4 *) cd->mcodeptr) =  ((((s4) (op)) << 30) | ((rd) << 25) | ((op3) << 19) | ((rs1) << 14) | ((imm)<<13) | (imm?((rs2)&0x1fff):(rs2)) ); \
                cd->mcodeptr += 4; \
        } while (0)
 
 
+#define M_OP3_GET_RD(x)               (((x) >> 25) & 0x1f)
+#define M_OP3_GET_RS(x)               (((x) >> 14) & 0x1f)
+#define M_OP3_GET_IMM(x)              ( (x)        & 0x1fff)
+
 /* 3-address-operations: M_OP3C
  *       rcond ... condition opcode
  *       rs2 ..... register number or 10bit signed immediate
 /* shift Format 3
  *    op ..... opcode
  *    op3..... op3 code
- *    rs1 .... source 1
- *    rs2 .... source 2 or constant
+ *    rs1 .... source reg 1
+ *    rs2 .... source reg 2 or immediate shift count (5 or 6 bits long depending whether 32 or 64 bit shift)
  *    rd ..... dest reg
  *    imm .... switch for constant
  *    x ...... 0 => 32, 1 => 64 bit shift 
  */
 #define M_SHFT(op,op3,rs1,rs2,rd,imm,x) \
        do { \
-               *((u4 *) cd->mcodeptr) =  ( (((s4)(op)) << 30) | ((op3) << 19) | ((rd) << 25) | ((rs1) << 14) | ((rs2) << 0) | \
-                     ((imm) << 13) | ((x) << 12) ); \
+               *((u4 *) cd->mcodeptr) =  ( (((s4)(op)) << 30) | ((op3) << 19) | ((rd) << 25) | ((rs1) << 14) | ((imm) << 13) | \
+                       ((x) << 12) | (((imm) && (x))?((rs2) & 0x3f):((rs2) & 0x1f)) ); \
                cd->mcodeptr += 4; \
        } while (0)
 
  #define M_FMT4(op,op3,rd,rs2,cond,cc2,cc1,cc0,imm) \
        do { \
                *((u4 *) cd->mcodeptr) =  ( (((s4)(op)) << 30) | ((op3) << 19) | ((rd) << 25) | ((cc2) << 18) |  ((cond) << 14) | \
-                       ((imm) << 13) | ((cc1) << 12) | ((cc0) << 11) | ((rs2) << 0) ); \
+                       ((imm) << 13) | ((cc1) << 12) | ((cc0) << 11) | ((rs2) & 0x7ff) ); \
                cd->mcodeptr += 4; \
        } while (0)
 
 
+#define FR_X(r) (((r)<<1) + 1) /* transpose macro for floats which reside in upper half of double word */
+#define DR_X(r) ((((r)*2)|(((r)*2)>>5)) & 0x1f) /* transpose & pack double, see SPARC spec.            */
+
 /* 3-address-floating-point-operation
-     op .... opcode
-     op3,opf .... function-number
-     rd .... dest reg
-     rs2 ... source reg
-     
-     !!! 6-bit to 5-bit conversion done here !!!
-*/ 
+ *   op .... opcode
+ *   op3,opf .... function-number
+ *   rd .... dest reg
+ *   rs1 ... source reg (-1 signals unused)
+ *   rs2 ... source reg
+ *   
+ *
+ */ 
 #define M_FOP3(op,op3,opf,rd,rs1,rs2) \
        do { \
-               *((u4 *) cd->mcodeptr) =  ( (((s4)(op))<<30) | ((rd*2)<<25) | ((op3)<<19) | ((rs1*2) << 14) | ((opf)<<5) | (rs2*2) ); \
+               *((u4 *) cd->mcodeptr) =  ( (((s4)(op))<<30) | ((rd)<<25) | ((op3)<<19) | ((((rs1)==-1)?0:(rs1)) << 14) | \
+               ((opf)<<5) | (rs2) ); \
+               cd->mcodeptr += 4; \
+       } while (0)
+/* float addressing */
+#define M_FOP3_FX(op,op3,opf,rd,rs1,rs2) \
+       do { \
+               *((u4 *) cd->mcodeptr) =  ( (((s4)(op))<<30) | (FR_X(rd)<<25) | ((op3)<<19) | ((((rs1)==-1)?0:FR_X(rs1)) << 14) | \
+               ((opf)<<5) | FR_X(rs2) ); \
+               cd->mcodeptr += 4; \
+       } while (0)
+/* double addressing */
+#define M_FOP3_DX(op,op3,opf,rd,rs1,rs2) \
+       do { \
+               *((u4 *) cd->mcodeptr) =  ( (((s4)(op))<<30) | (DR_X(rd)<<25) | ((op3)<<19) | ((((rs1)==-1)?0:DR_X(rs1)) << 14) | \
+               ((opf)<<5) | DR_X(rs2) ); \
                cd->mcodeptr += 4; \
        } while (0)
 
+/* 3-address-floating-point-compare-operation
+ *   op .... opcode
+ *   op3,opf .... function-number
+ *   fcc ... floating point condition code (fcc0 - fcc3)
+ *   rs1 ... source reg
+ *   rs2 ... source reg
+ *   
+ *
+ */ 
+#define M_FCMP_DX(op,op3,opf,fcc,rs1,rs2) \
+       do { \
+               *((u4 *) cd->mcodeptr) =  ( (((s4)(op))<<30) | ((fcc)<<25) | ((op3)<<19) | (DR_X(rs1) << 14) | \
+               ((opf)<<5) | DR_X(rs2) ); \
+               cd->mcodeptr += 4; \
+       } while (0)
+       
+#define M_FCMP_FX(op,op3,opf,fcc,rs1,rs2) \
+       do { \
+               *((u4 *) cd->mcodeptr) =  ( (((s4)(op))<<30) | ((fcc)<<25) | ((op3)<<19) | (FR_X(rs1) << 14) | \
+               ((opf)<<5) | FR_X(rs2) ); \
+               cd->mcodeptr += 4; \
+       } while (0)
 
 /**** format 2 operations ********/
 
                cd->mcodeptr += 4; \
        } while (0)
 
-
-
 #define M_NOP M_SETHI(0,0)      /* nop */
 
 #define M_AND(rs1,rs2,rd)       M_OP3(0x02,0x01,rd,rs1,rs2,REG)     /* 64b c = a &  b */
 #define M_XOR_IMM(rs1,rs2,rd)   M_OP3(0x02,0x03,rd,rs1,rs2,IMM)
 
 #define M_MOV(rs,rd)            M_OR(REG_ZERO, rs, rd)              /* rd = rs            */
+#define M_CLR(rd)               M_OR(REG_ZERO,REG_ZERO,rd)          /* rd = 0             */
 
 
 
 #define M_SLLX(rs1,rs2,rd)             M_SHFT(0x02,0x25,rs1,rs2,rd,REG,1)      /* 64b rd = rs << rs2 */
 #define M_SLLX_IMM(rs1,rs2,rd) M_SHFT(0x02,0x25,rs1,rs2,rd,IMM,1)
+#define M_SLL(rs1,rs2,rd)              M_SHFT(0x02,0x25,rs1,rs2,rd,REG,0)      /* 32b rd = rs << rs2 */
+#define M_SLL_IMM(rs1,rs2,rd)  M_SHFT(0x02,0x25,rs1,rs2,rd,IMM,0)
 #define M_SRLX(rs1,rs2,rd)             M_SHFT(0x02,0x26,rs1,rs2,rd,REG,1)      /* 64b rd = rs >>>rs2 */
 #define M_SRLX_IMM(rs1,rs2,rd) M_SHFT(0x02,0x26,rs1,rs2,rd,IMM,1)
 #define M_SRL(rs1,rs2,rd)              M_SHFT(0x02,0x26,rs1,rs2,rd,REG,0)      /* 32b rd = rs >>>rs2 */
 #define M_SRL_IMM(rs1,rs2,rd)  M_SHFT(0x02,0x26,rs1,rs2,rd,IMM,0)
 #define M_SRAX(rs1,rs2,rd)             M_SHFT(0x02,0x27,rs1,rs2,rd,REG,1)      /* 64b rd = rs >> rs2 */
 #define M_SRAX_IMM(rs1,rs2,rd) M_SHFT(0x02,0x27,rs1,rs2,rd,IMM,1)
-#define M_SRA(rs1,rs2,rd)              M_SHFT(0x02,0x27,rs1,rs2,rd,REG,0)      /* 32b rd = rs >> rs2 */
+#define M_SRA(rs1,rs2,rd)       M_SHFT(0x02,0x27,rs1,rs2,rd,REG,0)  /* 32b rd = rs >> rs2 */
 #define M_SRA_IMM(rs1,rs2,rd)  M_SHFT(0x02,0x27,rs1,rs2,rd,IMM,0)
 
-#define M_ISEXT(rs,rd)                         M_SRA_IMM(rs,0,rd)                  /* sign extend 32 bits*/
+#define M_ISEXT(rs,rd)                         M_SRA(rs,REG_ZERO,rd)                 /* sign extend 32 bits*/
 
 
 #define M_ADD(rs1,rs2,rd)      M_OP3(0x02,0x00,rd,rs1,rs2,REG)         /* 64b rd = rs1 + rs2 */
 #define M_MULX_IMM(rs1,rs2,rd)  M_OP3(0x02,0x09,rd,rs1,rs2,IMM)
 #define M_DIVX(rs1,rs2,rd)      M_OP3(0x02,0x2d,rd,rs1,rs2,REG)        /* 64b rd = rs1 / rs2 */
 
+#define M_SUBcc(rs1,rs2,rd)     M_OP3(0x02,0x14,rd,rs1,rs2,REG)     /* sets xcc and icc   */
+#define M_SUBcc_IMM(rs1,rs2,rd) M_OP3(0x02,0x14,rd,rs1,rs2,IMM)     /* sets xcc and icc   */
+
 
 
 /**** compare and conditional ALU operations ***********/
 
-#define M_CMP(rs1,rs2)          M_SUB(rs1,rs2,REG_ZERO)             /* sets xcc and icc   */
-#define M_CMP_IMM(rs1,rs2)      M_SUB_IMM(rs1,rs2,REG_ZERO)
+#define M_CMP(rs1,rs2)          M_SUBcc(rs1,rs2,REG_ZERO)             
+#define M_CMP_IMM(rs1,rs2)      M_SUBcc_IMM(rs1,rs2,REG_ZERO)
+
 
 /* move integer register on (64-bit) condition */
 
 #define M_XCMOVGE(rs,rd)        M_FMT4(0x2,0x2c,rd,rs,0xb,1,1,0,REG)   /* a>=b ? rd=rs    */
 #define M_XCMOVLE(rs,rd)        M_FMT4(0x2,0x2c,rd,rs,0x2,1,1,0,REG)   /* a<=b ? rd=rs    */
 #define M_XCMOVGT(rs,rd)        M_FMT4(0x2,0x2c,rd,rs,0xa,1,1,0,REG)   /* a>b  ? rd=rs    */
+#define M_XCMOVULE(rs,rd)       M_FMT4(0x2,0x2c,rd,rs,0x4,1,1,0,REG)   /* a<=b ? rd=rs (u)*/
 
 #define M_XCMOVEQ_IMM(rs,rd)    M_FMT4(0x2,0x2c,rd,rs,0x1,1,1,0,IMM)   /* a==b ? rd=rs    */
 #define M_XCMOVNE_IMM(rs,rd)    M_FMT4(0x2,0x2c,rd,rs,0x9,1,1,0,IMM)   /* a!=b ? rd=rs    */
 #define M_XCMOVGE_IMM(rs,rd)    M_FMT4(0x2,0x2c,rd,rs,0xb,1,1,0,IMM)   /* a>=b ? rd=rs    */
 #define M_XCMOVLE_IMM(rs,rd)    M_FMT4(0x2,0x2c,rd,rs,0x2,1,1,0,IMM)   /* a<=b ? rd=rs    */
 #define M_XCMOVGT_IMM(rs,rd)    M_FMT4(0x2,0x2c,rd,rs,0xa,1,1,0,IMM)   /* a>b  ? rd=rs    */
+#define M_XCMOVULE_IMM(rs,rd)   M_FMT4(0x2,0x2c,rd,rs,0x4,1,1,0,IMM)   /* a<=b ? rd=rs (u)*/
 
 /* move integer register on (fcc0) floating point condition */
 
 #define M_CMOVRGE_IMM(rs1,rs2,rd) M_OP3C(0x2,0x2f,0x7,rd,rs1,rs2,IMM)  /* rs1>=0 ? rd=rs2 */
 
 
-/**** load/store operations ********/
+/**** big constant helpers *********/
+
+/* #define FITS_13BIT_IMM(x)       ((x >= -4096) && (x <= 4095)) */
+
+bool fits_13(s4 disp);
+s4   get_lopart_disp(s4 disp);
+
+#define abs(x) ((x) < 0 ? (-(x)) : (x))
+
+#define sethi_part(x) ((x)>>10)
+#define setlo_part(x) ((x) & 0x3ff)
+
+#define DO_SETHI_REG(c,rd) \
+       do { \
+               if (c > 0) { \
+                       M_SETHI(sethi_part(c), rd); \
+                       if (setlo_part(c)) { \
+                               M_OR_IMM(rd, setlo_part(c), rd); \
+                       } \
+               } \
+               else { \
+                       M_SETHI(sethi_part(~c), rd); \
+                       M_XOR_IMM(rd, PASS13BIT(setlo_part(c) | 0xffffffffffff1c00), rd); \
+               } \
+       } while (0)
+       
+#define DO_SETHI_PART(c,rs,rd) \
+       do { \
+               if (c > 0) { \
+                       M_SETHI(sethi_part(c), rd); \
+                       M_ADD(rs,rd,rd); \
+               } \
+               else { \
+                       M_SETHI(sethi_part(-c), rd); \
+                       M_SUB(rs,rd,rd); \
+                       assert(sethi_part(c) != 0xf); \
+               } \
+       } while (0)
+       
+
+               
 
 #define M_LDA(rd,rs,disp) \
     do { \
-        s4 lo = (short) (disp); \
-        s4 hi = (short) (((disp) - lo) >> 13); \
-        if (hi == 0) { \
-            M_AADD_IMM(rs,lo,rd); \
-        } else { \
-            M_SETHI(hi&0x3ffff8,rd); \
-            M_AADD_IMM(rd,lo,rd); \
+        if (fits_13(disp)) { \
+            M_AADD_IMM(rs,disp,rd); \
+        } \
+        else { \
+            DO_SETHI_REG(disp,rd); \
             M_AADD(rd,rs,rd); \
         } \
     } while (0)
 
+/**** load/store operations ********/
+
 #define M_SLDU(rd,rs,disp)      M_OP3(0x03,0x02,rd,rs,disp,IMM)        /* 16-bit load, uns*/
 #define M_SLDS(rd,rs,disp)      M_OP3(0x03,0x0a,rd,rs,disp,IMM)        /* 16-bit load, sig*/
 #define M_BLDS(rd,rs,disp)      M_OP3(0x03,0x09,rd,rs,disp,IMM)        /* 8-bit load, sig */
 #define M_LDX_INTERN(rd,rs,disp) M_OP3(0x03,0x0b,rd,rs,disp,IMM)       /* 64-bit load, sig*/
 #define M_LDX(rd,rs,disp) \
        do { \
-        s4 lo = (short) (disp); \
-        s4 hi = (short) (((disp) - lo) >> 13); \
-        if (hi == 0) { \
-            M_LDX_INTERN(rd,rs,lo); \
-        } else { \
-            M_SETHI(hi&0x3ffff8,rd); \
-            M_AADD(rs,rd,rd); \
-            M_LDX_INTERN(rd,rd,lo); \
+        if (fits_13(disp)) { \
+            M_LDX_INTERN(rd,rs,disp); \
+        } \
+        else { \
+               DO_SETHI_PART(disp,rs,rd); \
+               M_LDX_INTERN(rd,rd,PASS13BIT(get_lopart_disp(disp))); \
         } \
     } while (0)
 
 #define M_ILD_INTERN(rd,rs,disp) M_OP3(0x03,0x08,rd,rs,disp,IMM)       /* 32-bit load, sig */
 #define M_ILD(rd,rs,disp) \
        do { \
-        s4 lo = (short) (disp); \
-        s4 hi = (short) (((disp) - lo) >> 13); \
-        if (hi == 0) { \
-            M_ILD_INTERN(rd,rs,lo); \
-        } else { \
-            M_SETHI(hi&0x3ffff8,rd); \
-            M_AADD(rs,rd,rd); \
-            M_ILD_INTERN(rd,rd,lo); \
+        if (fits_13(disp)) { \
+            M_ILD_INTERN(rd,rs,disp); \
+       } \
+        else { \
+            DO_SETHI_PART(disp,rs,rd); \
+            M_ILD_INTERN(rd,rd,PASS13BIT(get_lopart_disp(disp))); \
         } \
     } while (0)
 
 #define M_STX_INTERN(rd,rs,disp) M_OP3(0x03,0x0e,rd,rs,disp,IMM)       /* 64-bit store    */
 #define M_STX(rd,rs,disp) \
        do { \
-        s4 lo = (short) (disp); \
-        s4 hi = (short) (((disp) - lo) >> 13); \
-        if (hi == 0) { \
-            M_STX_INTERN(rd,rs,lo); \
-        } else { \
-            M_SETHI(hi&0x3ffff8,REG_ITMP3); /* sethi has a 22bit imm, only set upper 19 bits */ \
-            M_AADD(rs,REG_ITMP3,REG_ITMP3); \
-            M_STX_INTERN(rd,REG_ITMP3,lo); \
+        if (fits_13(disp)) { \
+            M_STX_INTERN(rd,rs,disp); \
+        } \
+        else { \
+            DO_SETHI_PART(disp,rs,REG_ITMP3); \
+            M_STX_INTERN(rd,REG_ITMP3,PASS13BIT(get_lopart_disp(disp))); \
         } \
     } while (0)
 
 #define M_IST_INTERN(rd,rs,disp) M_OP3(0x03,0x04,rd,rs,disp,IMM)       /* 32-bit store    */
 #define M_IST(rd,rs,disp) \
     do { \
-        s4 lo = (short) (disp); \
-        s4 hi = (short) (((disp) - lo) >> 13); \
-        if (hi == 0) { \
-            M_IST_INTERN(rd,rs,lo); \
-        } else { \
-            M_SETHI(hi&0x3ffff8,REG_ITMP3); /* sethi has a 22bit imm, only set upper 19 bits */ \
-            M_AADD(rs,REG_ITMP3,REG_ITMP3); \
-            M_IST_INTERN(rd,REG_ITMP3,lo); \
+        if (fits_13(disp)) { \
+            M_IST_INTERN(rd,rs,disp); \
+       } \
+        else { \
+            DO_SETHI_PART(disp,rs,REG_ITMP3); \
+            M_IST_INTERN(rd,REG_ITMP3,PASS13BIT(get_lopart_disp(disp))); \
         } \
     } while (0)
 
 #define M_XBGE(disp)            M_BRACC(0x00,0x1,0xb,disp,2,1,0)      /* branch a>=b */
 #define M_XBLE(disp)            M_BRACC(0x00,0x1,0x2,disp,2,1,0)      /* branch a<=b */
 #define M_XBUGE(disp)           M_BRACC(0x00,0x1,0xd,disp,2,1,0)      /* br uns a>=b */
+#define M_XBUGT(disp)           M_BRACC(0x00,0x1,0xc,disp,2,1,0)      /* br uns a>b  */
 #define M_XBULT(disp)           M_BRACC(0x00,0x1,0x5,disp,2,1,0)      /* br uns a<b  */
 
 /* branch on (32-bit) integer condition codes */
 #define M_BGE(disp)             M_BRACC(0x00,0x1,0xb,disp,0,1,0)      /* branch a>=b */
 #define M_BLE(disp)             M_BRACC(0x00,0x1,0x2,disp,0,1,0)      /* branch a<=b */
 #define M_BULE(disp)            M_BRACC(0x00,0x1,0x4,disp,0,1,0)      /* br uns a<=b */
+#define M_BUGT(disp)            M_BRACC(0x00,0x1,0xc,disp,0,1,0)      /* br uns a>b  */
 #define M_BULT(disp)            M_BRACC(0x00,0x1,0x5,disp,0,1,0)      /* br uns a<b  */
 
+/* branch on (fcc0) floating point condition codes */
+
+#define M_FBR(disp)             M_BRACC(0x00,0x5,0x8,disp,0,1,0)      /* branch      */
+#define M_FBU(disp)             M_BRACC(0x00,0x5,0x7,disp,0,1,0)      /* unordered   */
+#define M_FBG(disp)             M_BRACC(0x00,0x5,0x6,disp,0,1,0)      /* branch a>b  */
+#define M_FBL(disp)             M_BRACC(0x00,0x5,0x4,disp,0,1,0)      /* branch a<b  */
+#define M_FBO(disp)             M_BRACC(0x00,0x5,0xf,disp,0,1,0)      /* br ordered  */
+
 
 
 #define M_SAVE(rs1,rs2,rd)      M_OP3(0x02,0x3c,rd,rs1,rs2,IMM)
+#define M_SAVE_REG(rs1,rs2,rd)  M_OP3(0x02,0x3c,rd,rs1,rs2,REG)
 #define M_RESTORE(rs1,rs2,rd)   M_OP3(0x02,0x3d,rd,rs1,rs2,IMM)
 
 
 /**** floating point operations **/
 
 
-#define M_DMOV(rs,rd)           M_FOP3(0x02,0x34,0x02,rd,0,rs)      /* rd = rs */
-#define M_FMOV(rs,rd)           M_FOP3(0x02,0x34,0x01,rd,0,rs)  /* rd = rs */
+#define M_DMOV(rs,rd)           M_FOP3_DX(0x02,0x34,0x02,rd,-1,rs)      /* rd = rs */
+#define M_FMOV(rs,rd)           M_FOP3_FX(0x02,0x34,0x01,rd,-1,rs)      /* rd = rs */
 
-#define M_FNEG(rs,rd)                  M_FOP3(0x02,0x34,0x05,rd,0,rs)          /* rd = -rs     */
-#define M_DNEG(rs,rd)                  M_FOP3(0x02,0x34,0x06,rd,0,rs)          /* rd = -rs     */
+#define M_FMOV_INTERN(rs,rd)    M_FOP3(0x02,0x34,0x01,rd,-1,rs)         /* rd = rs */
 
-#define M_FADD(rs1,rs2,rd)      M_FOP3(0x02,0x34,0x41,rd,rs1,rs2)  /* float add    */
-#define M_DADD(rs1,rs2,rd)      M_FOP3(0x02,0x34,0x42,rd,rs1,rs2)  /* double add   */
-#define M_FSUB(rs1,rs2,rd)      M_FOP3(0x02,0x34,0x045,rd,rs1,rs2)     /* float sub    */
-#define M_DSUB(rs1,rs2,rd)      M_FOP3(0x02,0x34,0x046,rd,rs1,rs2) /* double sub   */
-#define M_FMUL(rs1,rs2,rd)      M_FOP3(0x02,0x34,0x049,rd,rs1,rs2) /* float mul    */
-#define M_DMUL(rs1,rs2,rd)      M_FOP3(0x02,0x34,0x04a,rd,rs1,rs2) /* double mul   */
-#define M_FDIV(rs1,rs2,rd)      M_FOP3(0x02,0x34,0x04d,rd,rs1,rs2) /* float div    */
-#define M_DDIV(rs1,rs2,rd)      M_FOP3(0x02,0x34,0x04e,rd,rs1,rs2) /* double div   */
+#define M_FNEG(rs,rd)                  M_FOP3_FX(0x02,0x34,0x05,rd,-1,rs)              /* rd = -rs     */
+#define M_DNEG(rs,rd)                  M_FOP3_DX(0x02,0x34,0x06,rd,-1,rs)      /* rd = -rs     */
+
+#define M_FADD(rs1,rs2,rd)      M_FOP3_FX(0x02,0x34,0x41,rd,rs1,rs2)  /* float add    */
+#define M_DADD(rs1,rs2,rd)      M_FOP3_DX(0x02,0x34,0x42,rd,rs1,rs2)  /* double add   */
+#define M_FSUB(rs1,rs2,rd)      M_FOP3_FX(0x02,0x34,0x045,rd,rs1,rs2)  /* float sub    */
+#define M_DSUB(rs1,rs2,rd)      M_FOP3_DX(0x02,0x34,0x046,rd,rs1,rs2) /* double sub   */
+#define M_FMUL(rs1,rs2,rd)      M_FOP3_FX(0x02,0x34,0x049,rd,rs1,rs2) /* float mul    */
+#define M_DMUL(rs1,rs2,rd)      M_FOP3_DX(0x02,0x34,0x04a,rd,rs1,rs2) /* double mul   */
+#define M_FDIV(rs1,rs2,rd)      M_FOP3_FX(0x02,0x34,0x04d,rd,rs1,rs2) /* float div    */
+#define M_DDIV(rs1,rs2,rd)      M_FOP3_DX(0x02,0x34,0x04e,rd,rs1,rs2) /* double div   */
 
 
 /**** compare and conditional FPU operations ***********/
 
 /* rd field 0 ==> fcc target unit is fcc0 */
-#define M_FCMP(rs1,rs2)                    M_FOP3(0x02,0x35,0x051,0,rs1,rs2) /* set fcc flt  */
-#define M_DCMP(rs1,rs2)                    M_FOP3(0x02,0x35,0x052,0,rs1,rs2)     /* set fcc dbl  */
+#define M_FCMP(rs1,rs2)                    M_FCMP_FX(0x02,0x35,0x051,0,rs1,rs2)     /* compare flt  */
+#define M_DCMP(rs1,rs2)                    M_FCMP_DX(0x02,0x35,0x052,0,rs1,rs2)     /* compare dbl  */
 
 /* conversion functions */
 
-#define M_CVTIF(rs,rd)          M_FOP3(0x02,0x34,0x0c4,rd,0,rs)/* int2flt      */
-#define M_CVTID(rs,rd)          M_FOP3(0x02,0x34,0x0c8,rd,0,rs)  /* int2dbl      */
-#define M_CVTLF(rs,rd)          M_FOP3(0x02,0x34,0x084,rd,0,rs)  /* long2flt     */
-#define M_CVTLD(rs,rd)          M_FOP3(0x02,0x34,0x088,rd,0,rs)    /* long2dbl     */
+#define M_CVTIF(rs,rd)          M_FOP3_FX(0x02,0x34,0x0c4,rd,-1,rs)/* int2flt      */
+#define M_CVTID(rs,rd)          M_FOP3(0x02,0x34,0x0c8,DR_X(rd),-1,FR_X(rs))  /* int2dbl      */
+#define M_CVTLF(rs,rd)          M_FOP3(0x02,0x34,0x084,FR_X(rd),-1,DR_X(rs))  /* long2flt     */
+#define M_CVTLD(rs,rd)          M_FOP3_DX(0x02,0x34,0x088,rd,-1,rs)    /* long2dbl     */
 
-#define M_CVTFI(rs,rd)          M_FOP3(0x02,0x34,0x0d1,rd,0,rs)   /* flt2int   */
-#define M_CVTDI(rs,rd)          M_FOP3(0x02,0x34,0x0d2,rd,0,rs)     /* dbl2int   */
-#define M_CVTFL(rs,rd)          M_FOP3(0x02,0x34,0x081,rd,0,rs)     /* flt2long  */
-#define M_CVTDL(rs,rd)          M_FOP3(0x02,0x34,0x082,rd,0,rs)       /* dbl2long  */
+#define M_CVTFI(rs,rd)          M_FOP3_FX(0x02,0x34,0x0d1,rd,-1,rs)   /* flt2int   */
+#define M_CVTDI(rs,rd)          M_FOP3(0x02,0x34,0x0d2,FR_X(rd),-1,DR_X(rs))     /* dbl2int   */
+#define M_CVTFL(rs,rd)          M_FOP3(0x02,0x34,0x081,DR_X(rd),-1,FR_X(rs))     /* flt2long  */
+#define M_CVTDL(rs,rd)          M_FOP3_DX(0x02,0x34,0x082,rd,-1,rs)       /* dbl2long  */
 
-#define M_CVTFD(rs,rd)          M_FOP3(0x02,0x34,0x0c9,rd,0,rs)     /* flt2dbl   */
-#define M_CVTDF(rs,rd)          M_FOP3(0x02,0x34,0x0c6,rd,0,rs)     /* dbl2float */
+#define M_CVTFD(rs,rd)          M_FOP3(0x02,0x34,0x0c9,DR_X(rd),-1,FR_X(rs))     /* flt2dbl   */
+#define M_CVTDF(rs,rd)          M_FOP3(0x02,0x34,0x0c6,FR_X(rd),-1,DR_X(rs))     /* dbl2float */
 
 
-/* a 6-bit double register index has to be converted into the 5-bit representation 
- * (%d1 -> %f2, %d2 -> %f4, ie. shift left once )
- * don't have to pack the MSB, since we are not using the upper 16 doubles
- * 
- * since single precision floats reside in the lower register of a double pair their
- * register numbers need to be handled in the same way
- */
 
-/* M_OP3 will not do the floar register number conversion */
-#define M_DLD_INTERN(rd,rs1,disp) M_OP3(0x03,0x23,rd*2,rs1,disp,IMM)    /* double (64-bit) load */
+#define M_DLD_INTERN(rd,rs1,disp) M_OP3(0x03,0x23,DR_X(rd),rs1,disp,IMM)    /* double (64-bit) load */
 #define M_DLD(rd,rs,disp) \
        do { \
         s4 lo = (short) (disp); \
         } else { \
             M_SETHI(hi&0x3ffff8,rd); \
             M_AADD(rs,rd,rd); \
-            M_DLD_INTERN(rd,rd,lo); \
+            M_DLD_INTERN(rd,rd,PASS13BIT(lo)); \
         } \
     } while (0)
 /* Note for SETHI: sethi has a 22bit imm, only set upper 19 bits */ 
 
-#define M_FLD_INTERN(rd,rs1,disp) M_OP3(0x03,0x20,rd*2,rs1,disp,IMM)    /* float (32-bit) load */
+#define M_FLD_INTERN(rd,rs1,disp) M_OP3(0x03,0x20,FR_X(rd),rs1,disp,IMM)    /* float (32-bit) load */
 #define M_FLD(rd,rs,disp) \
        do { \
         s4 lo = (short) (disp); \
         } else { \
             M_SETHI(hi&0x3ffff8,rd); \
             M_AADD(rs,rd,rd); \
-            M_FLD_INTERN(rd,rd,lo); \
+            M_FLD_INTERN(rd,rd,PASS13BIT(lo)); \
         } \
     } while (0)
 
 
-#define M_FST_INTERN(rd,rs,disp) M_OP3(0x03,0x24,rd*2,rs,disp,IMM)    /* float (32-bit) store  */
+#define M_FST_INTERN(rd,rs,disp) M_OP3(0x03,0x24,FR_X(rd),rs,disp,IMM)    /* float (32-bit) store  */
 #define M_FST(rd,rs,disp) \
     do { \
         s4 lo = (short) (disp); \
         } else { \
             M_SETHI(hi&0x3ffff8,REG_ITMP3); \
             M_AADD(rs,REG_ITMP3,REG_ITMP3); \
-            M_FST_INTERN(rd,REG_ITMP3,lo); \
+            M_FST_INTERN(rd,REG_ITMP3,PASS13BIT(lo)); \
         } \
     } while (0)
     
 
-#define M_DST_INTERN(rd,rs1,disp) M_OP3(0x03,0x27,rd*2,rs1,disp,IMM)    /* double (64-bit) store */
+#define M_DST_INTERN(rd,rs1,disp) M_OP3(0x03,0x27,DR_X(rd),rs1,disp,IMM)    /* double (64-bit) store */
 #define M_DST(rd,rs,disp) \
     do { \
         s4 lo = (short) (disp); \
         } else { \
             M_SETHI(hi&0x3ffff8,REG_ITMP3); \
             M_AADD(rs,REG_ITMP3,REG_ITMP3); \
-            M_DST_INTERN(rd,REG_ITMP3,lo); \
+            M_DST_INTERN(rd,REG_ITMP3,PASS13BIT(lo)); \
         } \
     } while (0)
     
 #define M_AADD_IMM(a,b,c)       M_ADD_IMM(a,b,c)
 #define M_ASUB_IMM(a,b,c)       M_SUB_IMM(a,b,c)
 #define M_ASLL_IMM(a,b,c)       M_SLLX_IMM(a,b,c)
-
-
-
-
-/* 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
-
-   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)
-
-*******************************************************************************/
-
-#define var_to_reg_int(regnr,v,tempnr) \
-    do { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            M_LDX(tempnr, REG_SP, (v)->regoff * 8); \
-            regnr = tempnr; \
-        } else { \
-            regnr = (v)->regoff; \
-        } \
-    } while (0)
-                                                                                                                                 
-
-/* gen_resolvebranch ***********************************************************
- *
- *    backpatches a branch instruction
- *    On Sparc all there is to do, is replace the 22bit disp at the end of the 
- *    instruction.
- *    THIS APPLIES TO THE (V8) BICC INSTRUCTION ONLY.
- *
- *    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
-
-
-
-                                                                                                                                 
        
+
 #endif /* _CODEGEN_H */