-/* 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 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.
Authors: Andreas Krall
- $Id: codegen.h 1349 2004-07-22 12:08:29Z twisti $
+ $Id: codegen.h 2628 2005-06-09 20:39:37Z twisti $
*/
#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 */
-
-#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/mips/types.h"
/* additional functions and macros to generate code ***************************/
-/* #define BlockPtrOfPC(pc) block+block_index[pc] */
#define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
#define gen_nullptr_check(objreg) \
if (checknull) { \
M_BEQZ((objreg), 0); \
- codegen_addxnullrefs(m, mcodeptr); \
+ codegen_addxnullrefs(cd, mcodeptr); \
M_NOP; \
}
M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size)); \
M_CMPULT(s2, REG_ITMP3, REG_ITMP3); \
M_BEQZ(REG_ITMP3, 0); \
- codegen_addxboundrefs(m, mcodeptr, s2); \
+ codegen_addxboundrefs(cd, mcodeptr, s2); \
M_NOP; \
}
#define MCODECHECK(icnt) \
if ((mcodeptr + (icnt)) > cd->mcodeend) \
- mcodeptr = codegen_increase(m, (u1 *) mcodeptr)
+ mcodeptr = codegen_increase(cd, (u1 *) mcodeptr)
+
+
+#define ALIGNCODENOP \
+ if ((int) ((long) mcodeptr & 7)) { \
+ M_NOP; \
+ }
+
/* M_INTMOVE:
generates an integer-move from register a to b.
#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);} \
- }
+ do { \
+ if ((a) != (b)) \
+ if ((t) == TYPE_DBL) { \
+ M_DMOV(a,b); \
+ } else { \
+ M_FMOV(a,b); \
+ } \
+ } while (0)
#define M_TFLD(t,a,b,disp) \
- if ((t)==TYPE_DBL) \
- {M_DLD(a,b,disp);} \
- else \
- {M_FLD(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) \
*/
#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; \
+ 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; \
+ if ((v)->flags & INMEMORY) { \
+ COUNT_SPILLS; \
+ M_DLD(tempnr, REG_SP, 8 * (v)->regoff); \
+ regnr = tempnr; \
+ } else regnr = (v)->regoff; \
}
#define M_COPY(from,to) \
- d = reg_of_var(m, to, REG_IFTMP); \
+ d = reg_of_var(rd, to, REG_IFTMP); \
if ((from->regoff != to->regoff) || \
((from->flags ^ to->flags) & INMEMORY)) { \
if (IS_FLT_DBL_TYPE(from->type)) { \
} else if ((c) >= 0 && (c) <= 0xffff) { \
M_OR_IMM(REG_ZERO, (c), (r)); \
} else { \
- a = dseg_adds4(m, (c)); \
+ a = dseg_adds4(cd, (c)); \
M_ILD((r), REG_PV, a); \
}
} else if ((c) >= 0 && (c) <= 0xffff) { \
M_OR_IMM(REG_ZERO, (c), (r)); \
} else { \
- a = dseg_adds8(m, (c)); \
+ a = dseg_adds8(cd, (c)); \
M_LLD((r), REG_PV, a); \
}
*/
-#define M_ITYPE(op, rs, rt, imm)\
- *(mcodeptr++) = (((op)<<26)|((rs)<<21)|((rt)<<16)|((imm)&0xffff))
+#define M_ITYPE(op,rs,rt,imm) \
+ *(mcodeptr++) = (((op) << 26) | ((rs) << 21) | ((rt) << 16) | ((imm) & 0xffff))
-#define M_JTYPE(op, imm)\
- *(mcodeptr++) = (((op)<<26)|((off)&0x3ffffff))
+#define M_JTYPE(op,imm) \
+ *(mcodeptr++) = (((op) << 26) | ((off) & 0x3ffffff))
-#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) \
+ *(mcodeptr++) = (((op) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((sa) << 6) | (fu))
#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_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(a,b,disp) M_LLD(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_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
+
#define POINTERSHIFT 2
+
#define M_ALD(a,b,disp) M_ILD(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_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
*******************************************************************************/
-#define gen_resolvebranch(ip,so,to) ((s4*)(ip))[-1]|=((s4)(to)-(so))>>2&0xffff
-
-
-/* function prototypes */
+#define gen_resolvebranch(ip,so,to) \
+ do { \
+ s4 offset; \
+ \
+ offset = ((s4) (to) - (so)) >> 2; \
+ \
+ /* On the MIPS we can only branch signed 16-bit instruction words */ \
+ /* (signed 18-bit = 32KB = +/- 16KB). Check this! */ \
+ \
+ if ((offset < (s4) 0xffff8000) || (offset > (s4) 0x00007fff)) { \
+ throw_cacao_exception_exit(string_java_lang_InternalError, \
+ "Jump offset is out of range: %d > +/-%d", \
+ offset, 0x00007fff); \
+ } \
+ \
+ ((s4 *) (ip))[-1] |= (offset & 0x0000ffff); \
+ } while (0)
+
+
+/* function prototypes ********************************************************/
void docacheflush(u1 *p, long bytelen);