X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fs390%2Fcodegen.h;h=28ceb970a57084a1d28714a3ca681c376a393345;hb=e9865924b9bb241082f2b3878f893be3fc8b57c2;hp=3fa484793b1fc31f8871f145319954c2ce8823fc;hpb=63a738ae11823cb0d1d101690012fccbe5356a69;p=cacao.git diff --git a/src/vm/jit/s390/codegen.h b/src/vm/jit/s390/codegen.h index 3fa484793..28ceb970a 100644 --- a/src/vm/jit/s390/codegen.h +++ b/src/vm/jit/s390/codegen.h @@ -1,9 +1,7 @@ -/* 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, - 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 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -22,13 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Contact: cacao@cacaojvm.org - - Authors: Andreas Krall - Christian Thalinger - - $Id: codegen.h 7680 2007-04-10 05:02:20Z pm $ - */ @@ -41,42 +32,7 @@ #include "vm/types.h" -#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; - - -#define gen_nullptr_check_intern(objreg) \ - do { \ - M_TEST(objreg); \ - M_BEQ(0); \ - codegen_add_nullpointerexception_ref(cd); \ - } while (0); - -#define gen_nullptr_check(objreg) \ - if (checknull) { \ - gen_nullptr_check_intern(objreg); \ - } - - -#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); \ - } +#include "vm/jit/jit.hpp" /* MCODECHECK(icnt) */ @@ -87,34 +43,34 @@ codegen_increase(cd); \ } while (0) - #define ALIGNCODENOP \ - if ((s4) (((ptrint) cd->mcodeptr) & 7)) { \ - M_NOP; \ - } - - - -/* branch defines *************************************************************/ - -#define BRANCH_NOPS \ do { \ - M_NOP; \ + while (((ptrint) cd->mcodeptr) & 2) { \ + M_NOP2; \ + } \ + while (((ptrint) cd->mcodeptr) & 4) { \ + M_NOP; \ + } \ } while (0) - /* some patcher defines *******************************************************/ -#define PATCHER_CALL_SIZE 4 /* size in bytes of a patcher call */ +#define PATCHER_CALL_SIZE 2 /* size in bytes of a patcher call */ +#define PATCHER_NOPS M_NOP3 -#define PATCHER_NOPS \ - do { \ - M_NOP; \ - M_NOP; \ - M_NOP; \ - } while (0) +/* branch defines ************************************************************/ + +#define BRANCH_NOPS \ + 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_NOPS_SKIP 12 /* *** BIG TODO *** * Make all this inline functions !!!!!!!!!! @@ -142,14 +98,13 @@ * In debug mode, the instructions assert that %r0 was not given as argument. */ -#if 1 +#if !defined(NDEBUG) + # include + /* 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)) || @@ -160,7 +115,7 @@ } 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) @@ -174,7 +129,9 @@ } 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); @@ -182,7 +139,9 @@ } 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))) || @@ -193,7 +152,9 @@ } 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) @@ -250,6 +211,18 @@ #define SZ_RR 2 +static inline uint8_t N_RR_GET_OPC(uint8_t *instrp) { + return instrp[0]; +} + +static inline uint8_t N_RR_GET_REG1(uint8_t *instrp) { + return (instrp[1] >> 4) & 0xF; +} + +static inline uint8_t N_RR_GET_REG2(uint8_t *instrp) { + return (instrp[1] & 0xF); +} + #define N_RR2(op, i) \ _CODE2( (_OP(op) << 8) | _I8(i) ) @@ -258,8 +231,43 @@ #define SZ_RX 4 +static inline uint8_t N_RX_GET_OPC(uint8_t *instrp) { + return instrp[0]; +} + +static inline uint8_t N_RX_GET_REG(uint8_t *instrp) { + return (instrp[1] >> 4) & 0xF; +} + +static inline uint8_t N_RX_GET_INDEX(uint8_t *instrp) { + return (instrp[1] & 0xF); +} + +static inline uint8_t N_RX_GET_BASE(uint8_t *instrp) { + return (instrp[2] >> 4) & 0xF; +} + +static inline uint16_t N_RX_GET_DISP(uint8_t *instrp) { + return *(uint16_t *)(instrp + 2) & 0xFFF; +} + +static inline void N_RX_SET_DISP(uint8_t *instrp, uint16_t disp) { + *(uint16_t *)(instrp + 2) |= (disp & 0xFFF); +} + #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) ) + +static inline int16_t N_RI_GET_IMM(uint8_t *instrp) { + return *(int16_t *)(instrp + 2); +} + +static inline void N_RI_SET_IMM(uint8_t *instrp, int16_t imm) { + *(int16_t *)(instrp + 2) = imm; +} + +#define N_RI2(op1, op2, r1, i2) \ + _CODE4( (_OP(op1) << 24) | (_R(r1) << 20) | (_OP4(op2) << 16) | (u2)_UI16(i2) ) #define SZ_RI 4 @@ -328,11 +336,18 @@ #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_BRANCH_MIN -32768 -#define N_BRANCH_MAX 32767 +#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 * 2) +#define N_BRANCH_MAX (32767 * 2) #define N_VALID_BRANCH(x) ((N_BRANCH_MIN <= (x)) && ((x) <= N_BRANCH_MAX)) #define ASSERT_VALID_BRANCH(x) assert(N_VALID_BRANCH(x)) +#define N_IS_EVEN_ODD(x) \ + (((GET_HIGH_REG(x) % 2) == 0) && (GET_LOW_REG(x) == (GET_HIGH_REG(x) + 1))) + /* Condition codes */ #define DD_O 1 @@ -351,9 +366,37 @@ #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 OPC_ILL 0x02 +# define SZ_ILL 2 + +static inline uint8_t N_ILL_GET_REG(uint8_t *instrp) { + return (instrp[1] >> 4) & 0xF; +} + +static inline uint8_t N_ILL_GET_TYPE(uint8_t *instrp) { + return (instrp[1] & 0xF); +} + +#define N_LONG(l) _CODE4(l) +#define SZ_LONG 4 /* Chapter 7. General instructions */ @@ -368,10 +411,11 @@ # 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)) @@ -390,6 +434,10 @@ # 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) @@ -404,8 +452,9 @@ #define N_CHI(r1, i2) N_RI(0xA7, 0xE, r1, i2) #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 OPC_CL 0x55 #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) @@ -417,11 +466,12 @@ #define N_CUTFU(r1, r2) N_RRE(0xB2A7, r1, r2) #define N_CPYA(r1, r2) N_RRE(0xB240, r1, r2) #define N_DR(r1, r2) N_RR(0x1D, r1, r2) +# define OPC_DR 0x1D #define N_D(r1, d2, x2, b2) N_RX(0x5D, r1, d2, x2, 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) @@ -430,6 +480,7 @@ #define N_LR(r1, r2) N_RR(0x18, r1, r2) #define N_L(r1, d2, x2, b2) N_RX(0x58, r1, d2, x2, b2) # define SZ_L SZ_RX +# define OPC_L 0x58 #define N_LAM(r1, r3, d2, b2) N_RS(0x9A, r1, r3, d2, b2) #define N_LA(r1, d2, x2, b2) N_RX(0x41, r1, d2, x2, b2) #define N_LAE(r1, d2, x2, b2) N_RX(0x51, r1, d2, x2, b2) @@ -444,15 +495,15 @@ #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) @@ -462,8 +513,8 @@ #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) @@ -477,6 +528,7 @@ #define N_SRA(r1, d2, b2) N_RS(0x8A, r1, 0x00, d2, b2) #define N_SRL(r1, d2, b2) N_RS(0x88, r1, 0x00, d2, b2) #define N_ST(r1, d2, x2, b2) N_RX(0x50, r1, d2, x2, b2) +# define OPC_ST 0x50 #define N_STAM(r1, r3, d2, b2) N_RS(0x9B, r1, r3, d2, b2) #define N_STC(r1, d2, x2, b2) N_RX(0x42, r1, d2, x2, b2) #define N_STCM(r1, m3, d2, b2) N_RS(0xBE, r1, m3, d2, b2) @@ -492,12 +544,12 @@ #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 */ @@ -546,6 +598,7 @@ #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) @@ -553,6 +606,10 @@ #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) @@ -568,45 +625,67 @@ /* 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) \ do { \ if (N_VALID_DISP(d)) { \ N_L(r, d, RN, b); \ - } else if (r == R0) { \ + } 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 { \ + } 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, \ @@ -615,11 +694,13 @@ N_L(GET_LOW_REG(r), 4, GET_LOW_REG(r), 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_MOV(a, b) N_LR(b, a) #define M_FMOV(a, b) N_LDR(b, a) +#define M_DMOV(a, b) M_FMOV((a), (b)) #define M_DST(r, b, d) _IFNEG(d, assert(0), N_STD(r, d, RN, b)) #define M_FST(r, b, d) _IFNEG(d, assert(0), N_STE(r, d, RN, b)) #define M_IST(r, b, d) _IFNEG( \ @@ -654,10 +735,13 @@ #define M_BR(disp) N_BRC(DD_ANY, disp) #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_ACMP(a, b) N_CR(a, b) #define M_CVTIF(src, dst) N_CEFBR(dst, src) #define M_CVTID(src, dst) N_CDFBR(dst, src) #define M_FMUL(a, dest) N_MEEBR(dest, a) @@ -671,7 +755,9 @@ #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) @@ -719,7 +805,7 @@ N_LHI(reg, i); \ } else { \ disp = dseg_add_s4(cd, (i)); \ - M_ILD(reg, REG_PV, disp); \ + M_ILD_DSEG(reg, disp); \ } \ } while (0) @@ -729,204 +815,20 @@ 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. -*/ - -#define M_INTMOVE(reg,dreg) \ - do { \ - if ((reg) != (dreg)) { \ - M_MOV(reg, dreg); \ - } \ - } while (0) - -#define M_LNGMOVE(a, b) \ - do { \ - if (GET_HIGH_REG(a) == GET_LOW_REG(b)) { \ - assert((GET_LOW_REG(a) != GET_HIGH_REG(b))); \ - 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) - -/* 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(reg,dreg) \ - do { \ - if ((reg) != (dreg)) { \ - M_FMOV(reg, dreg); \ - } \ - } 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_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_LNEG(a) _DEPR( M_LNEG(a) ) - -#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 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_ISRA_IMM(a,b) _DEPR( M_ISRA_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_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) ) - - -/* 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 -#define __PROFILE_CYCLE_START _DEPR( __PROFILE_CYCLE_START ) - -#define 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)); +#define M_ASUB_IMM32(imm, tmpreg, reg) M_ISUB_IMM32(imm, tmpreg, reg) #endif /* _CODEGEN_H */ - -s4 codegen_reg_of_dst_notzero(jitdata *jd, instruction *iptr, s4 tempregnum); - /* * 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