-/* jit/mips/codegen.h - code generation macros and definitions for mips
+/* src/vm/jit/mips/codegen.h - code generation macros and definitions for MIPS
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Institut f. Computersprachen, TU Wien
- R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
- M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
- P. Tomsich, J. Wenninger
+ 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
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-
- Contact: cacao@complang.tuwien.ac.at
-
- Authors: Andreas Krall
-
- $Id: codegen.h 1291 2004-07-09 13:20:56Z twisti $
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
*/
#ifndef _CODEGEN_H
#define _CODEGEN_H
-#include "jit/jit.h"
-
-
-/* see also file calling.doc for explanation of calling conventions */
-
-/* preallocated registers *****************************************************/
-
-/* integer registers */
-
-#define REG_ZERO 0 /* allways zero */
-
-#define REG_RESULT 2 /* to deliver method results */
-
-#define REG_ITMP1 1 /* temporary register */
-#define REG_ITMP2 3 /* temporary register and method pointer */
-#define REG_ITMP3 25 /* temporary register */
-
-#define REG_ARG_0 4 /* argument register */
-#define REG_ARG_1 5 /* argument register */
-#define REG_ARG_2 6 /* argument register */
-#define REG_ARG_3 7 /* argument register */
-#define REG_ARG_4 8 /* argument register */
-#define REG_ARG_5 9 /* argument register */
-
-#define REG_RA 31 /* return address */
-#define REG_SP 29 /* stack pointer */
-#define REG_GP 28 /* global pointer */
-
-#define REG_PV 30 /* procedure vector, must be provided by caller */
-#define REG_METHODPTR 25 /* pointer to the place from where the procedure */
- /* vector has been fetched */
-#define REG_ITMP1_XPTR 1 /* exception pointer = temporary register 1 */
-#define REG_ITMP2_XPC 3 /* exception pc = temporary register 2 */
-
-/* floating point registers */
-
-#define REG_FRESULT 0 /* to deliver floating point method results */
-#define REG_FTMP1 1 /* temporary floating point register */
-#define REG_FTMP2 2 /* temporary floating point register */
-#define REG_FTMP3 3 /* temporary floating point register */
+#include "config.h"
+#include "vm/types.h"
-#define REG_IFTMP 1 /* temporary integer and floating point register */
-
-
-#define INT_SAV_CNT 8 /* number of int callee saved registers */
-#define INT_ARG_CNT 8 /* number of int argument registers */
-
-#define FLT_SAV_CNT 4 /* number of flt callee saved registers */
-#define FLT_ARG_CNT 8 /* number of flt argument registers */
+#include "vm/jit/jit.h"
/* additional functions and macros to generate code ***************************/
-/* #define BlockPtrOfPC(pc) block+block_index[pc] */
-#define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
-
-
-#ifdef STATISTICS
-#define COUNT_SPILLS count_spills++
-#else
-#define COUNT_SPILLS
-#endif
+/* MCODECHECK(icnt) */
+#define MCODECHECK(icnt) \
+ do { \
+ if ((cd->mcodeptr + (icnt) * 4) > cd->mcodeend) \
+ codegen_increase(cd); \
+ } while (0)
-/* gen_nullptr_check(objreg) */
-#define gen_nullptr_check(objreg) \
- if (checknull) { \
- M_BEQZ((objreg), 0); \
- codegen_addxnullrefs(mcodeptr); \
+#define ALIGNCODENOP \
+ if ((s4) ((ptrint) cd->mcodeptr & 7)) { \
M_NOP; \
}
+#define M_INTMOVE(a,b) \
+ do { \
+ if ((a) != (b)) \
+ M_MOV(a, b); \
+ } while (0)
+
+#if SIZEOF_VOID_P == 8
+
+#define M_LNGMOVE(a,b) M_INTMOVE(a,b)
+
+#else /* SIZEOF_VOID_P == 8 */
+
+#define M_LNGMOVE(a,b) \
+ do { \
+ if (GET_LOW_REG(b) == GET_HIGH_REG(a)) { \
+ assert(GET_HIGH_REG(b) == GET_LOW_REG(a)); \
+ M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+ M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+ } else { \
+ M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+ M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+ } \
+ } while (0)
+
+#endif /* SIZEOF_VOID_P == 8 */
+
+#define M_FLTMOVE(a,b) \
+ do { \
+ if ((a) != (b)) \
+ M_FMOV(a, b); \
+ } while (0)
+
+#define M_DBLMOVE(a,b) \
+ do { \
+ if ((a) != (b)) \
+ M_DMOV(a, b); \
+ } while (0)
+
+#define ICONST(r,c) emit_iconst(cd, (r), (c))
+#define LCONST(r,c) emit_lconst(cd, (r), (c))
+
+
+/* branch defines *************************************************************/
+
+#define BRANCH_NOPS \
+ do { \
+ if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) { \
+ M_NOP; \
+ M_NOP; \
+ M_NOP; \
+ M_NOP; \
+ M_NOP; \
+ M_NOP; \
+ } \
+ else { \
+ M_NOP; \
+ M_NOP; \
+ } \
+ } while (0)
+
+
+/* patcher defines ************************************************************/
+
+#define PATCHER_CALL_INSTRUCTIONS 1 /* number of instructions */
+#define PATCHER_CALL_SIZE 1 * 4 /* size in bytes of a patcher call */
+
+#define PATCHER_NOPS \
+ do { \
+ M_NOP; \
+ } while (0)
-/* MCODECHECK(icnt) */
-#define MCODECHECK(icnt) \
- if ((mcodeptr + (icnt)) > mcodeend) mcodeptr = codegen_increase((u1 *) mcodeptr)
-
-/* 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.
-*/
-
-#define M_INTMOVE(a,b) if (a != b) { M_MOV(a, b); }
-
-
-/* M_FLTMOVE:
- generates a floating-point-move from register a to b.
- if a and b are the same float-register, no code will be generated
-*/
-
-#define M_FLTMOVE(a,b) if (a != b) { M_DMOV(a, b); }
-
-#define M_TFLTMOVE(t,a,b) \
- {if(a!=b) \
- if ((t)==TYPE_DBL) \
- {M_DMOV(a,b);} \
- else {M_FMOV(a,b);} \
- }
-
-#define M_TFLD(t,a,b,disp) \
- if ((t)==TYPE_DBL) \
- {M_DLD(a,b,disp);} \
- else \
- {M_FLD(a,b,disp);}
-
-#define M_TFST(t,a,b,disp) \
- if ((t)==TYPE_DBL) \
- {M_DST(a,b,disp);} \
- else \
- {M_FST(a,b,disp);}
-
-#define M_CCFLTMOVE(t1,t2,a,b) \
- if ((t1)==(t2)) \
- {M_TFLTMOVE(t1,a,b);} \
- else \
- if ((t1)==TYPE_DBL) \
- {M_CVTDF(a,b);} \
- else \
- {M_CVTFD(a,b);}
-
-#define M_CCFLD(t1,t2,a,b,disp) \
- if ((t1)==(t2)) \
- {M_DLD(a,b,disp);} \
- else { \
- M_DLD(REG_FTMP1,b,disp); \
- if ((t1)==TYPE_DBL) \
- {M_CVTDF(REG_FTMP1,a);} \
- else \
- {M_CVTFD(REG_FTMP1,a);} \
- }
-
-#define M_CCFST(t1,t2,a,b,disp) \
- if ((t1)==(t2)) \
- {M_DST(a,b,disp);} \
- else { \
- if ((t1)==TYPE_DBL) \
- {M_CVTDF(a,REG_FTMP1);} \
- else \
- {M_CVTFD(a,REG_FTMP1);} \
- M_DST(REG_FTMP1,b,disp); \
- }
-
-
-/* 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)
-*/
+/* stub defines ***************************************************************/
-#define var_to_reg_int(regnr,v,tempnr) { \
- if ((v)->flags & INMEMORY) \
- {COUNT_SPILLS;M_LLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
- else regnr=(v)->regoff; \
-}
-
-
-#define var_to_reg_flt(regnr,v,tempnr) { \
- if ((v)->flags & INMEMORY) \
- {COUNT_SPILLS;M_DLD(tempnr,REG_SP,8*(v)->regoff);regnr=tempnr;} \
- else regnr=(v)->regoff; \
-}
-
-
-/* store_reg_to_var_xxx:
- This function generates the code to store the result of an operation
- back into a spilled pseudo-variable.
- If the pseudo-variable has not been spilled in the first place, this
- function will generate nothing.
-
- v ............ Pseudovariable
- tempregnum ... Number of the temporary registers as returned by
- reg_of_var.
-*/
-
-#define store_reg_to_var_int(sptr, tempregnum) { \
- if ((sptr)->flags & INMEMORY) { \
- COUNT_SPILLS; \
- M_LST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
- } \
- }
-
-#define store_reg_to_var_flt(sptr, tempregnum) { \
- if ((sptr)->flags & INMEMORY) { \
- COUNT_SPILLS; \
- M_DST(tempregnum, REG_SP, 8 * (sptr)->regoff); \
- } \
- }
+#define COMPILERSTUB_CODESIZE 4 * 4
/* macros to create code ******************************************************/
*/
-#define M_ITYPE(op, rs, rt, imm)\
- *(mcodeptr++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((imm)&0xffff))
+#define M_ITYPE(op,rs,rt,imm) \
+ do { \
+ *((u4 *) cd->mcodeptr) = (((op) << 26) | ((rs) << 21) | ((rt) << 16) | ((imm) & 0xffff)); \
+ cd->mcodeptr += 4; \
+ } while (0)
+
+#define M_ITYPE_GET_RS(x) (((x) >> 21) & 0x1f )
+#define M_ITYPE_GET_RT(x) (((x) >> 16) & 0x1f )
+#define M_ITYPE_GET_IMM(x) ( (x) & 0xffff)
+
-#define M_JTYPE(op, imm)\
- *(mcodeptr++) = (((op)<<26)|((off)&0x3ffffff))
+#define M_JTYPE(op,imm) \
+ do { \
+ *((u4 *) cd->mcodeptr) = (((op) << 26) | ((off) & 0x3ffffff)); \
+ cd->mcodeptr += 4; \
+ } while (0)
-#define M_RTYPE(op, rs, rt, rd, sa, fu)\
- *(mcodeptr++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((rd)<<11)|((sa)<<6)|(fu))
+#define M_RTYPE(op,rs,rt,rd,sa,fu) \
+ do { \
+ *((u4 *) cd->mcodeptr) = (((op) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((sa) << 6) | (fu)); \
+ cd->mcodeptr += 4; \
+ } while (0)
#define M_FP2(fu, fmt, fs, fd) M_RTYPE(0x11, fmt, 0, fs, fd, fu)
#define M_FP3(fu, fmt, fs, ft, fd) M_RTYPE(0x11, fmt, ft, fs, fd, fu)
#define FMT_I 20
#define FMT_L 21
-/* macros for all used commands (see a MIPS-manual for description) ***********/
+
+/* macros for all used commands (see a MIPS-manual for description) ***********/
/* load/store macros use the form OPERATION(source/dest, base, offset) */
+#define M_LDA(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_AADD_IMM(b,lo,a); \
+ } else { \
+ M_LUI(REG_ITMP3, hi); \
+ M_AADD_IMM(REG_ITMP3, lo, REG_ITMP3); \
+ M_AADD(b, REG_ITMP3, a); \
+ } \
+ } while (0)
+
#define M_BLDS(a,b,disp) M_ITYPE(0x20,b,a,disp) /* 8 load */
#define M_BLDU(a,b,disp) M_ITYPE(0x24,b,a,disp) /* 8 load */
#define M_SLDS(a,b,disp) M_ITYPE(0x21,b,a,disp) /* 16 load */
#define M_SLDU(a,b,disp) M_ITYPE(0x25,b,a,disp) /* 16 load */
-#define M_ILD(a,b,disp) M_ITYPE(0x23,b,a,disp) /* 32 load */
-#define M_LLD(a,b,disp) M_ITYPE(0x37,b,a,disp) /* 64 load */
+
+#define M_ILD_INTERN(a,b,disp) M_ITYPE(0x23,b,a,disp) /* 32 load */
+
+#define M_ILD(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_ILD_INTERN(a,b,lo); \
+ } else { \
+ M_LUI(a,hi); \
+ M_AADD(b,a,a); \
+ M_ILD_INTERN(a,a,lo); \
+ } \
+ } while (0)
+
+#if SIZEOF_VOID_P == 8
+
+#define M_LLD_INTERN(a,b,disp) M_ITYPE(0x37,b,a,disp) /* 64 load */
+
+#else /* SIZEOF_VOID_P == 8 */
+
+# if WORDS_BIGENDIAN == 1
+
+/* ATTENTION: b may be equal to GET_LOW_REG(a) (displacement overflow case ) */
+
+#define M_LLD_INTERN(a,b,disp) \
+ do { \
+ M_ILD_INTERN(GET_HIGH_REG(a), b, disp); \
+ M_ILD_INTERN(GET_LOW_REG(a), b, disp + 4); \
+ } while (0)
+
+/* this macro is specially for ICMD_GETFIELD since the base (source)
+ register may be one of the destination registers */
+
+#define M_LLD_GETFIELD(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ if (GET_HIGH_REG(a) == (b)) { \
+ M_ILD_INTERN(GET_LOW_REG(a), b, disp + 4); \
+ M_ILD_INTERN(GET_HIGH_REG(a), b, disp); \
+ } else { \
+ M_ILD_INTERN(GET_HIGH_REG(a), b, disp); \
+ M_ILD_INTERN(GET_LOW_REG(a), b, disp + 4); \
+ } \
+ } else { \
+ M_LUI(GET_LOW_REG(a), hi); \
+ M_AADD(b, GET_LOW_REG(a), GET_LOW_REG(a)); \
+ M_LLD_INTERN(a, GET_LOW_REG(a), lo); \
+ } \
+ } while (0)
+
+# else /* if WORDS_BIGENDIAN == 1 */
+
+/* ATTENTION: b may be equal to GET_LOW_REG(a) (displacement overflow case ) */
+
+#define M_LLD_INTERN(a,b,disp) \
+ do { \
+ M_ILD_INTERN(GET_HIGH_REG(a), b, disp + 4); \
+ M_ILD_INTERN(GET_LOW_REG(a), b, disp); \
+ } while (0)
+
+/* this macro is specially for ICMD_GETFIELD since the base (source)
+ register may be one of the destination registers */
+
+#define M_LLD_GETFIELD(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ if (GET_HIGH_REG(a) == (b)) { \
+ M_ILD_INTERN(GET_LOW_REG(a), b, disp); \
+ M_ILD_INTERN(GET_HIGH_REG(a), b, disp + 4); \
+ } else { \
+ M_ILD_INTERN(GET_HIGH_REG(a), b, disp + 4); \
+ M_ILD_INTERN(GET_LOW_REG(a), b, disp); \
+ } \
+ } else { \
+ M_LUI(GET_LOW_REG(a), hi); \
+ M_AADD(b, GET_LOW_REG(a), GET_LOW_REG(a)); \
+ M_LLD_INTERN(a, GET_LOW_REG(a), lo); \
+ } \
+ } while (0)
+
+# endif /* if WORDS_BIGENDIAN == 1 */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
+#define M_LLD(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_LLD_INTERN(a, b, lo); \
+ } else { \
+ M_LUI(GET_LOW_REG(a), hi); \
+ M_AADD(b, GET_LOW_REG(a), GET_LOW_REG(a)); \
+ M_LLD_INTERN(a, GET_LOW_REG(a), lo); \
+ } \
+ } while (0)
+
#define M_BST(a,b,disp) M_ITYPE(0x28,b,a,disp) /* 8 store */
#define M_SST(a,b,disp) M_ITYPE(0x29,b,a,disp) /* 16 store */
-#define M_IST(a,b,disp) M_ITYPE(0x2b,b,a,disp) /* 32 store */
-#define M_LST(a,b,disp) M_ITYPE(0x3f,b,a,disp) /* 64 store */
-#define M_FLD(a,b,disp) M_ITYPE(0x31,b,a,disp) /* load flt */
-#define M_DLD(a,b,disp) M_ITYPE(0x35,b,a,disp) /* load dbl */
-#define M_FST(a,b,disp) M_ITYPE(0x39,b,a,disp) /* store flt */
-#define M_DST(a,b,disp) M_ITYPE(0x3d,b,a,disp) /* store dbl */
+#define M_IST_INTERN(a,b,disp) M_ITYPE(0x2b,b,a,disp) /* 32 store */
+
+#define M_IST(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_IST_INTERN(a,b,lo); \
+ } else { \
+ M_LUI(REG_ITMP3, hi); \
+ M_AADD(b, REG_ITMP3, REG_ITMP3); \
+ M_IST_INTERN(a, REG_ITMP3, lo); \
+ } \
+ } while (0)
+
+#if SIZEOF_VOID_P == 8
+
+#define M_LST_INTERN(a,b,disp) M_ITYPE(0x3f,b,a,disp) /* 64 store */
+
+#else /* SIZEOF_VOID_P == 8 */
+
+#if WORDS_BIGENDIAN == 1
+
+#define M_LST_INTERN(a,b,disp) \
+ do { \
+ M_IST_INTERN(GET_HIGH_REG(a), b, disp); \
+ M_IST_INTERN(GET_LOW_REG(a), b, disp + 4); \
+ } while (0)
+
+#else /* if WORDS_BIGENDIAN == 1 */
+
+#define M_LST_INTERN(a,b,disp) \
+ do { \
+ M_IST_INTERN(GET_HIGH_REG(a), b, disp + 4); \
+ M_IST_INTERN(GET_LOW_REG(a), b, disp); \
+ } while (0)
+
+#endif /* if WORDS_BIGENDIAN == 1 */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
+#define M_LST(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_LST_INTERN(a,b,lo); \
+ } else { \
+ M_LUI(REG_ITMP3, hi); \
+ M_AADD(b, REG_ITMP3, REG_ITMP3); \
+ M_LST_INTERN(a, REG_ITMP3, lo); \
+ } \
+ } while (0)
+
+#define M_FLD_INTERN(a,b,disp) M_ITYPE(0x31,b,a,disp) /* load flt */
+#define M_DLD_INTERN(a,b,disp) M_ITYPE(0x35,b,a,disp) /* load dbl */
+
+#define M_FLD(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_FLD_INTERN(a,b,lo); \
+ } else { \
+ M_LUI(REG_ITMP3, hi); \
+ M_AADD(b, REG_ITMP3, REG_ITMP3); \
+ M_FLD_INTERN(a, REG_ITMP3, lo); \
+ } \
+ } while (0)
+
+#define M_DLD(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_DLD_INTERN(a,b,lo); \
+ } else { \
+ M_LUI(REG_ITMP3, hi); \
+ M_AADD(b, REG_ITMP3, REG_ITMP3); \
+ M_DLD_INTERN(a, REG_ITMP3, lo); \
+ } \
+ } while (0)
+
+#define M_FST_INTERN(a,b,disp) M_ITYPE(0x39,b,a,disp) /* store flt */
+#define M_DST_INTERN(a,b,disp) M_ITYPE(0x3d,b,a,disp) /* store dbl */
+
+#define M_FST(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_FST_INTERN(a,b,lo); \
+ } else { \
+ M_LUI(REG_ITMP3, hi); \
+ M_AADD(b, REG_ITMP3, REG_ITMP3); \
+ M_FST_INTERN(a, REG_ITMP3, lo); \
+ } \
+ } while (0)
+
+#define M_DST(a,b,disp) \
+ do { \
+ s4 lo = (short) (disp); \
+ s4 hi = (short) (((disp) - lo) >> 16); \
+ if (hi == 0) { \
+ M_DST_INTERN(a,b,lo); \
+ } else { \
+ M_LUI(REG_ITMP3, hi); \
+ M_AADD(b, REG_ITMP3, REG_ITMP3); \
+ M_DST_INTERN(a, REG_ITMP3, lo); \
+ } \
+ } while (0)
#define M_BEQ(a,b,disp) M_ITYPE(0x04,a,b,disp) /* br a == b */
#define M_BNE(a,b,disp) M_ITYPE(0x05,a,b,disp) /* br a != b */
#define M_BGEZ(a,disp) M_ITYPE(0x01,a,1,disp) /* br a >= 0 */
#define M_BGTZ(a,disp) M_ITYPE(0x07,a,0,disp) /* br a > 0 */
+#if 0
#define M_BEQL(a,b,disp) M_ITYPE(0x14,a,b,disp) /* br a == b */
#define M_BNEL(a,b,disp) M_ITYPE(0x15,a,b,disp) /* br a != b */
#define M_BEQZL(a,disp) M_ITYPE(0x14,a,0,disp) /* br a == 0 */
#define M_BNEZL(a,disp) M_ITYPE(0x15,a,0,disp) /* br a != 0 */
#define M_BGEZL(a,disp) M_ITYPE(0x01,a,3,disp) /* br a >= 0 */
#define M_BGTZL(a,disp) M_ITYPE(0x17,a,0,disp) /* br a > 0 */
+#endif
#define M_BR(disp) M_ITYPE(0x04,0,0,disp) /* branch */
#define M_BRS(disp) M_ITYPE(0x01,0,17,disp) /* branch sbr */
#define M_ISUB(a,b,c) M_RTYPE(0,a,b,c,0,0x23) /* 32 sub */
#define M_LSUB(a,b,c) M_RTYPE(0,a,b,c,0,0x2f) /* 64 sub */
#define M_IMUL(a,b) M_ITYPE(0,a,b,0x18) /* 32 mul */
+#define M_IMULU(a,b) M_ITYPE(0,a,b,0x19) /* 32 mul */
#define M_LMUL(a,b) M_ITYPE(0,a,b,0x1c) /* 64 mul */
#define M_IDIV(a,b) M_ITYPE(0,a,b,0x1a) /* 32 div */
#define M_LDIV(a,b) M_ITYPE(0,a,b,0x1e) /* 64 div */
#define M_IADD_IMM(a,b,c) M_ITYPE(0x09,a,c,b) /* 32 add */
#define M_LADD_IMM(a,b,c) M_ITYPE(0x19,a,c,b) /* 64 add */
-#define M_ISUB_IMM(a,b,c) M_ITYPE(0x09,a,c,-(b)) /* 32 sub */
-#define M_LSUB_IMM(a,b,c) M_ITYPE(0x19,a,c,-(b)) /* 64 sub */
+#define M_ISUB_IMM(a,b,c) M_IADD_IMM(a,-(b),c) /* 32 sub */
+#define M_LSUB_IMM(a,b,c) M_LADD_IMM(a,-(b),c) /* 64 sub */
#define M_LUI(a,imm) M_ITYPE(0x0f,0,a,imm) /* a = imm<<16*/
#define M_OR_IMM( a,b,c) M_ITYPE(0x0d,a,c,b) /* c = a | b */
#define M_XOR_IMM(a,b,c) M_ITYPE(0x0e,a,c,b) /* c = a ^ b */
-#define M_CZEXT(a,c) M_AND_IMM(a,0xffff,c) /* c = zext(a)*/
-
#define M_ISLL(a,b,c) M_RTYPE(0,b,a,c,0,0x04) /* c = a << b */
#define M_ISRL(a,b,c) M_RTYPE(0,b,a,c,0,0x06) /* c = a >>>b */
#define M_ISRA(a,b,c) M_RTYPE(0,b,a,c,0,0x07) /* c = a >> b */
#define M_MOVID(i,d) M_FP3(0,4,d,i,0) /* d = i */
#define M_MOVLD(l,d) M_FP3(0,5,d,l,0) /* d = l */
+#define M_MFC1(l,f) M_FP3(0,0,f,l,0)
+#define M_MTC1(l,f) M_FP3(0,4,f,l,0)
+
#define M_DMFC1(l,f) M_FP3(0,1,f,l,0)
#define M_DMTC1(l,f) M_FP3(0,5,f,l,0)
#define M_CMOVF(a,b) M_RTYPE(0x00,a,0,b,0,1)
#define M_CMOVT(a,b) M_RTYPE(0x00,a,1,b,0,1)
+
/*
* Load Address pseudo instruction:
* -n32 addressing mode -> 32 bit addrs, -64 addressing mode -> 64 bit addrs
*/
-#if POINTERSIZE==8
+#if SIZEOF_VOID_P == 8
+
#define POINTERSHIFT 3
+
+#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_AST_INTERN(a,b,disp) M_LST_INTERN(a,b,disp)
#define M_AST(a,b,disp) M_LST(a,b,disp)
#define M_AADD(a,b,c) M_LADD(a,b,c)
+#define M_AADD_IMM(a,b,c) M_LADD_IMM(a,b,c)
+#define M_ASUB_IMM(a,b,c) M_LSUB_IMM(a,b,c)
#define M_ASLL_IMM(a,b,c) M_LSLL_IMM(a,b,c)
-#define M_LDA(a,b,disp) M_LADD_IMM(b,disp,a) /* a = b+disp */
-#else
+
+#else /* SIZEOF_VOID_P == 8 */
+
#define POINTERSHIFT 2
+
+#define M_ALD_INTERN(a,b,disp) M_ILD_INTERN(a,b,disp)
#define M_ALD(a,b,disp) M_ILD(a,b,disp)
+#define M_AST_INTERN(a,b,disp) M_IST_INTERN(a,b,disp)
#define M_AST(a,b,disp) M_IST(a,b,disp)
#define M_AADD(a,b,c) M_IADD(a,b,c)
+#define M_AADD_IMM(a,b,c) M_IADD_IMM(a,b,c)
+#define M_ASUB_IMM(a,b,c) M_ISUB_IMM(a,b,c)
#define M_ASLL_IMM(a,b,c) M_ISLL_IMM(a,b,c)
-#define M_LDA(a,b,disp) M_IADD_IMM(b,disp,a) /* a = b+disp */
-#endif
-
-/* macros for special commands (see an Alpha-manual for description) **********/
-
-#if 0
-#define M_CMOVEQ(a,b,c) M_OP3 (0x11,0x24, a,b,c,0) /* a==0 ? c=b */
-#define M_CMOVNE(a,b,c) M_OP3 (0x11,0x26, a,b,c,0) /* a!=0 ? c=b */
-#define M_CMOVLT(a,b,c) M_OP3 (0x11,0x44, a,b,c,0) /* a< 0 ? c=b */
-#define M_CMOVGE(a,b,c) M_OP3 (0x11,0x46, a,b,c,0) /* a>=0 ? c=b */
-#define M_CMOVLE(a,b,c) M_OP3 (0x11,0x64, a,b,c,0) /* a<=0 ? c=b */
-#define M_CMOVGT(a,b,c) M_OP3 (0x11,0x66, a,b,c,0) /* a> 0 ? c=b */
-
-#define M_CMOVEQ_IMM(a,b,c) M_OP3 (0x11,0x24, a,b,c,1) /* a==0 ? c=b */
-#define M_CMOVNE_IMM(a,b,c) M_OP3 (0x11,0x26, a,b,c,1) /* a!=0 ? c=b */
-#define M_CMOVLT_IMM(a,b,c) M_OP3 (0x11,0x44, a,b,c,1) /* a< 0 ? c=b */
-#define M_CMOVGE_IMM(a,b,c) M_OP3 (0x11,0x46, a,b,c,1) /* a>=0 ? c=b */
-#define M_CMOVLE_IMM(a,b,c) M_OP3 (0x11,0x64, a,b,c,1) /* a<=0 ? c=b */
-#define M_CMOVGT_IMM(a,b,c) M_OP3 (0x11,0x66, a,b,c,1) /* a> 0 ? c=b */
-#endif
-
-/* function gen_resolvebranch **************************************************
-
- backpatches a branch instruction; MIPS branch instructions are very
- regular, so it is only necessary to overwrite some fixed bits in the
- instruction.
-
- 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&0xffff
-
-
-/* function prototypes */
-
-void codegen_init();
-void init_exceptions();
-void codegen(methodinfo *m);
-void codegen_close();
-void dseg_display(s4 *s4ptr);
-void docacheflush(u1 *p, long bytelen);
+#endif /* SIZEOF_VOID_P == 8 */
#endif /* _CODEGEN_H */