/*---------------------------------------------------------------*/ /*--- begin host_tilegx_defs.h ---*/ /*---------------------------------------------------------------*/ /* This file is part of Valgrind, a dynamic binary instrumentation framework. Copyright (C) 2010-2015 Tilera Corp. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 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. The GNU General Public License is contained in the file COPYING. */ /* Contributed by Zhi-Gang Liu */ #ifndef __VEX_HOST_TILEGX_DEFS_H #define __VEX_HOST_TILEGX_DEFS_H #include "tilegx_disasm.h" /* Num registers used for function calls */ #define TILEGX_N_REGPARMS 10 /* --------- Registers. --------- */ /* The usual HReg abstraction. There are 56 general purpose regs. */ #define ST_IN static inline ST_IN HReg hregTILEGX_R30 ( void ) { return mkHReg(False, HRcInt64, 30, 0); } ST_IN HReg hregTILEGX_R31 ( void ) { return mkHReg(False, HRcInt64, 31, 1); } ST_IN HReg hregTILEGX_R32 ( void ) { return mkHReg(False, HRcInt64, 32, 2); } ST_IN HReg hregTILEGX_R33 ( void ) { return mkHReg(False, HRcInt64, 33, 3); } ST_IN HReg hregTILEGX_R34 ( void ) { return mkHReg(False, HRcInt64, 34, 4); } ST_IN HReg hregTILEGX_R35 ( void ) { return mkHReg(False, HRcInt64, 35, 5); } ST_IN HReg hregTILEGX_R36 ( void ) { return mkHReg(False, HRcInt64, 36, 6); } ST_IN HReg hregTILEGX_R37 ( void ) { return mkHReg(False, HRcInt64, 37, 7); } ST_IN HReg hregTILEGX_R38 ( void ) { return mkHReg(False, HRcInt64, 38, 8); } ST_IN HReg hregTILEGX_R39 ( void ) { return mkHReg(False, HRcInt64, 39, 9); } ST_IN HReg hregTILEGX_R40 ( void ) { return mkHReg(False, HRcInt64, 40, 10); } ST_IN HReg hregTILEGX_R41 ( void ) { return mkHReg(False, HRcInt64, 41, 11); } ST_IN HReg hregTILEGX_R42 ( void ) { return mkHReg(False, HRcInt64, 42, 12); } ST_IN HReg hregTILEGX_R43 ( void ) { return mkHReg(False, HRcInt64, 43, 13); } ST_IN HReg hregTILEGX_R44 ( void ) { return mkHReg(False, HRcInt64, 44, 14); } ST_IN HReg hregTILEGX_R45 ( void ) { return mkHReg(False, HRcInt64, 45, 15); } ST_IN HReg hregTILEGX_R46 ( void ) { return mkHReg(False, HRcInt64, 46, 16); } ST_IN HReg hregTILEGX_R47 ( void ) { return mkHReg(False, HRcInt64, 47, 17); } ST_IN HReg hregTILEGX_R48 ( void ) { return mkHReg(False, HRcInt64, 48, 18); } ST_IN HReg hregTILEGX_R49 ( void ) { return mkHReg(False, HRcInt64, 49, 19); } ST_IN HReg hregTILEGX_R10 ( void ) { return mkHReg(False, HRcInt64, 10, 20); } ST_IN HReg hregTILEGX_R13 ( void ) { return mkHReg(False, HRcInt64, 13, 21); } ST_IN HReg hregTILEGX_R14 ( void ) { return mkHReg(False, HRcInt64, 14, 22); } ST_IN HReg hregTILEGX_R15 ( void ) { return mkHReg(False, HRcInt64, 15, 23); } ST_IN HReg hregTILEGX_R16 ( void ) { return mkHReg(False, HRcInt64, 16, 24); } ST_IN HReg hregTILEGX_R17 ( void ) { return mkHReg(False, HRcInt64, 17, 25); } ST_IN HReg hregTILEGX_R18 ( void ) { return mkHReg(False, HRcInt64, 18, 26); } ST_IN HReg hregTILEGX_R19 ( void ) { return mkHReg(False, HRcInt64, 19, 27); } ST_IN HReg hregTILEGX_R20 ( void ) { return mkHReg(False, HRcInt64, 20, 28); } ST_IN HReg hregTILEGX_R21 ( void ) { return mkHReg(False, HRcInt64, 21, 29); } ST_IN HReg hregTILEGX_R22 ( void ) { return mkHReg(False, HRcInt64, 22, 30); } ST_IN HReg hregTILEGX_R23 ( void ) { return mkHReg(False, HRcInt64, 23, 31); } ST_IN HReg hregTILEGX_R24 ( void ) { return mkHReg(False, HRcInt64, 24, 32); } ST_IN HReg hregTILEGX_R25 ( void ) { return mkHReg(False, HRcInt64, 25, 33); } ST_IN HReg hregTILEGX_R26 ( void ) { return mkHReg(False, HRcInt64, 26, 34); } ST_IN HReg hregTILEGX_R27 ( void ) { return mkHReg(False, HRcInt64, 27, 35); } ST_IN HReg hregTILEGX_R28 ( void ) { return mkHReg(False, HRcInt64, 28, 36); } ST_IN HReg hregTILEGX_R29 ( void ) { return mkHReg(False, HRcInt64, 29, 37); } ST_IN HReg hregTILEGX_R0 ( void ) { return mkHReg(False, HRcInt64, 0, 38); } ST_IN HReg hregTILEGX_R1 ( void ) { return mkHReg(False, HRcInt64, 1, 39); } ST_IN HReg hregTILEGX_R2 ( void ) { return mkHReg(False, HRcInt64, 2, 40); } ST_IN HReg hregTILEGX_R3 ( void ) { return mkHReg(False, HRcInt64, 3, 41); } ST_IN HReg hregTILEGX_R4 ( void ) { return mkHReg(False, HRcInt64, 4, 42); } ST_IN HReg hregTILEGX_R5 ( void ) { return mkHReg(False, HRcInt64, 5, 43); } ST_IN HReg hregTILEGX_R6 ( void ) { return mkHReg(False, HRcInt64, 6, 44); } ST_IN HReg hregTILEGX_R7 ( void ) { return mkHReg(False, HRcInt64, 7, 45); } ST_IN HReg hregTILEGX_R8 ( void ) { return mkHReg(False, HRcInt64, 8, 46); } ST_IN HReg hregTILEGX_R9 ( void ) { return mkHReg(False, HRcInt64, 9, 47); } ST_IN HReg hregTILEGX_R11 ( void ) { return mkHReg(False, HRcInt64, 11, 48); } ST_IN HReg hregTILEGX_R12 ( void ) { return mkHReg(False, HRcInt64, 12, 49); } ST_IN HReg hregTILEGX_R50 ( void ) { return mkHReg(False, HRcInt64, 50, 50); } ST_IN HReg hregTILEGX_R51 ( void ) { return mkHReg(False, HRcInt64, 51, 51); } ST_IN HReg hregTILEGX_R52 ( void ) { return mkHReg(False, HRcInt64, 52, 52); } ST_IN HReg hregTILEGX_R53 ( void ) { return mkHReg(False, HRcInt64, 53, 53); } ST_IN HReg hregTILEGX_R54 ( void ) { return mkHReg(False, HRcInt64, 54, 54); } ST_IN HReg hregTILEGX_R55 ( void ) { return mkHReg(False, HRcInt64, 55, 55); } ST_IN HReg hregTILEGX_R63 ( void ) { return mkHReg(False, HRcInt64, 63, 56); } extern void ppHRegTILEGX ( HReg ); #define TILEGXGuestStatePointer() hregTILEGX_R50() #define TILEGXStackFramePointer() hregTILEGX_R52() #define TILEGXLinkRegister() hregTILEGX_R55() #define TILEGXStackPointer() hregTILEGX_R54() /* r0, r1, r2, r3 ... r9 */ #define TILEGX_N_ARGREGS 10 /* --------- Condition codes, Tilegx encoding. --------- */ typedef enum { TILEGXcc_EQ = 0, /* equal */ TILEGXcc_NE = 1, /* not equal */ TILEGXcc_HS = 2, /* >=u (higher or same) */ TILEGXcc_LO = 3, /* u (higher) */ TILEGXcc_LS = 9, /* <=u (lower or same) */ TILEGXcc_GE = 10, /* >=s (signed greater or equal) */ TILEGXcc_LT = 11, /* s (signed greater) */ TILEGXcc_LE = 13, /* <=s (signed less or equal) */ TILEGXcc_AL = 14, /* always (unconditional) */ TILEGXcc_NV = 15, /* never (unconditional): */ TILEGXcc_EQ8x8 = 16,/* V1 equal */ TILEGXcc_NE8x8 = 17,/* V1 not equal */ TILEGXcc_EZ = 18, /* equal 0 */ TILEGXcc_NZ = 19, /* not equal */ } TILEGXCondCode; /* --------- Memory address expressions (amodes). --------- */ typedef enum { GXam_IR, /* Immediate (signed 16-bit) + Reg */ } TILEGXAModeTag; typedef struct { TILEGXAModeTag tag; union { struct { HReg base; Int index; } IR; struct { HReg base; HReg index; } RR; } GXam; } TILEGXAMode; extern TILEGXAMode *TILEGXAMode_IR ( Int, HReg ); extern TILEGXAMode *TILEGXAMode_RR ( HReg, HReg ); extern TILEGXAMode *dopyTILEGXAMode ( TILEGXAMode * ); extern TILEGXAMode *nextTILEGXAModeFloat ( TILEGXAMode * ); extern TILEGXAMode *nextTILEGXAModeInt ( TILEGXAMode * ); extern void ppTILEGXAMode ( const TILEGXAMode * ); /* --------- Operand, which can be a reg or a u16/s16. --------- */ /* ("RH" == "Register or Halfword immediate") */ typedef enum { GXrh_Imm, GXrh_Reg } TILEGXRHTag; typedef struct { TILEGXRHTag tag; union { struct { Bool syned; UShort imm16; } Imm; struct { HReg reg; } Reg; } GXrh; } TILEGXRH; extern void ppTILEGXRH ( const TILEGXRH * ); extern TILEGXRH *TILEGXRH_Imm ( Bool, UShort ); extern TILEGXRH *TILEGXRH_Reg ( HReg ); /* --------- Reg or imm5 operands --------- */ typedef enum { TILEGXri5_I5 = 7, /* imm5, 1 .. 31 only (no zero!) */ TILEGXri5_R /* reg */ } TILEGXRI5Tag; typedef struct { TILEGXRI5Tag tag; union { struct { UInt imm5; } I5; struct { HReg reg; } R; } TILEGXri5; } TILEGXRI5; extern TILEGXRI5 *TILEGXRI5_I5 ( UInt imm5 ); extern TILEGXRI5 *TILEGXRI5_R ( HReg ); extern void ppTILEGXRI5 ( const TILEGXRI5 * ); /* --------- Instructions. --------- */ /*Tags for operations*/ /* --------- */ typedef enum { GXun_CLZ, GXun_CTZ, GXun_NOP, } TILEGXUnaryOp; /* --------- */ typedef enum { GXalu_INVALID, GXalu_ADD, GXalu_SUB, GXalu_AND, GXalu_OR, GXalu_NOR, GXalu_XOR, } TILEGXAluOp; /* --------- */ typedef enum { GXshft_INVALID, GXshft_SLL, GXshft_SRL, GXshft_SRA, GXshft_SLL8x8, GXshft_SRL8x8, } TILEGXShftOp; /* --------- */ typedef enum { GXbf_EXTS, GXbf_EXTU, GXbf_INS } TILEGXBfOp; /* --------- */ /* --------- */ typedef enum { GXacas_CMPEXCH, GXacas_EXCH, GXacas_FetchAnd, GXacas_FetchAdd, GXacas_FetchAddgez, GXacas_FetchOr, } TILEGXAcasOp; /* --------- */ /* ----- Instruction tags ----- */ typedef enum { GXin_LI, /* load word (32/64-bit) immediate (fake insn) */ GXin_Alu, /* word add/sub/and/or/xor/nor/others? */ GXin_Shft, /* word sll/srl/sra */ GXin_Unary, /* clo, clz, nop, neg */ GXin_Cmp, /* word compare (fake insn) */ GXin_CmpI, GXin_Mul, /* widening/non-widening multiply */ GXin_Call, /* call to address in register */ GXin_XDirect, /* direct transfer to GA */ GXin_XIndir, /* indirect transfer to GA */ GXin_XAssisted, /* assisted transfer to GA */ GXin_EvCheck, /* Event check */ GXin_ProfInc, /* 64-bit profile counter increment */ GXin_RdWrLR, /* Read/Write Link Register */ GXin_Load, /* zero-extending load a 8|16|32|64 bit value from mem */ GXin_Store, /* store a 8|16|32|64 bit value to mem */ GXin_MovCond, GXin_Bf, /* Bitfield operations */ GXin_Acas, /* Atomic Campare and swap. */ } TILEGXInstrTag; /*--------- Structure for instructions ----------*/ /* Destinations are on the LEFT (first operand) */ typedef struct { TILEGXInstrTag tag; union { /* Get a 32/64-bit literal into a register. May turn into a number of real insns. */ struct { HReg dst; ULong imm; } LI; /* Integer add/sub/and/or/xor. Limitations: - For add, the immediate, if it exists, is a signed 16. - For sub, the immediate, if it exists, is a signed 16 which may not be -32768, since no such instruction exists, and so we have to emit addi with +32768, but that is not possible. - For and/or/xor, the immediate, if it exists, is an unsigned 16. */ struct { TILEGXAluOp op; HReg dst; HReg srcL; TILEGXRH *srcR; } Alu; struct { TILEGXBfOp op; HReg dst; HReg src; UInt Start; UInt End; } Bf; struct { TILEGXAcasOp op; HReg addr; HReg exp; HReg new; HReg old; UInt sz; } Acas; /* Integer shl/shr/sar. Limitations: the immediate, if it exists, is a signed 5-bit value between 1 and 31 inclusive. */ struct { TILEGXShftOp op; Bool sz32; HReg dst; HReg srcL; TILEGXRH *srcR; } Shft; /* Clz, Ctz, Clo, nop */ struct { TILEGXUnaryOp op; HReg dst; HReg src; } Unary; /* Word compare. Fake instruction, used for basic block ending */ struct { Bool syned; Bool sz32; HReg dst; HReg srcL; HReg srcR; TILEGXCondCode cond; } Cmp; struct { Bool syned; Bool sz32; HReg dst; HReg srcL; TILEGXRH *srcR; TILEGXCondCode cond; } CmpI; struct { Bool widening; //True => widening, False => non-widening Bool syned; //signed/unsigned - meaningless if widenind = False Bool sz32; HReg dst; HReg srcL; HReg srcR; } Mul; /* Pseudo-insn. Call target (an absolute address), on given condition (which could be Mcc_ALWAYS). argiregs indicates which of r0 .. r9 carries argument values for this call, using a bit mask (1<