Home | History | Annotate | Download | only in priv
      1 
      2 /*---------------------------------------------------------------*/
      3 /*--- begin                                  host_mips_defs.h ---*/
      4 /*---------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2010-2015 RT-RK
     11       mips-valgrind (at) rt-rk.com
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 #ifndef __VEX_HOST_MIPS_DEFS_H
     32 #define __VEX_HOST_MIPS_DEFS_H
     33 
     34 #include "libvex_basictypes.h"
     35 #include "libvex.h"             /* VexArch */
     36 #include "host_generic_regs.h"  /* HReg */
     37 
     38 
     39 /* --------- Registers. --------- */
     40 
     41 #define ST_IN static inline
     42 
     43 #define GPR(_mode64, _enc, _ix64, _ix32) \
     44   mkHReg(False,  (_mode64) ? HRcInt64 : HRcInt32, \
     45          (_enc), (_mode64) ? (_ix64) : (_ix32))
     46 
     47 #define FR(_mode64, _enc, _ix64, _ix32) \
     48   mkHReg(False,  (_mode64) ? HRcFlt64 : HRcFlt32, \
     49          (_enc), (_mode64) ? (_ix64) : (_ix32))
     50 
     51 #define DR(_mode64, _enc, _ix64, _ix32) \
     52   mkHReg(False,  HRcFlt64, \
     53          (_enc), (_mode64) ? (_ix64) : (_ix32))
     54 
     55 ST_IN HReg hregMIPS_GPR16 ( Bool mode64 ) { return GPR(mode64, 16,  0,  0); }
     56 ST_IN HReg hregMIPS_GPR17 ( Bool mode64 ) { return GPR(mode64, 17,  1,  1); }
     57 ST_IN HReg hregMIPS_GPR18 ( Bool mode64 ) { return GPR(mode64, 18,  2,  2); }
     58 ST_IN HReg hregMIPS_GPR19 ( Bool mode64 ) { return GPR(mode64, 19,  3,  3); }
     59 ST_IN HReg hregMIPS_GPR20 ( Bool mode64 ) { return GPR(mode64, 20,  4,  4); }
     60 ST_IN HReg hregMIPS_GPR21 ( Bool mode64 ) { return GPR(mode64, 21,  5,  5); }
     61 ST_IN HReg hregMIPS_GPR22 ( Bool mode64 ) { return GPR(mode64, 22,  6,  6); }
     62 
     63 ST_IN HReg hregMIPS_GPR12 ( Bool mode64 ) { return GPR(mode64, 12,  7,  7); }
     64 ST_IN HReg hregMIPS_GPR13 ( Bool mode64 ) { return GPR(mode64, 13,  8,  8); }
     65 ST_IN HReg hregMIPS_GPR14 ( Bool mode64 ) { return GPR(mode64, 14,  9,  9); }
     66 ST_IN HReg hregMIPS_GPR15 ( Bool mode64 ) { return GPR(mode64, 15, 10, 10); }
     67 ST_IN HReg hregMIPS_GPR24 ( Bool mode64 ) { return GPR(mode64, 24, 11, 11); }
     68 
     69 ST_IN HReg hregMIPS_F16   ( Bool mode64 ) { return FR (mode64, 16, 12, 12); }
     70 ST_IN HReg hregMIPS_F18   ( Bool mode64 ) { return FR (mode64, 18, 13, 13); }
     71 ST_IN HReg hregMIPS_F20   ( Bool mode64 ) { return FR (mode64, 20, 14, 14); }
     72 ST_IN HReg hregMIPS_F22   ( Bool mode64 ) { return FR (mode64, 22, 15, 15); }
     73 ST_IN HReg hregMIPS_F24   ( Bool mode64 ) { return FR (mode64, 24, 16, 16); }
     74 ST_IN HReg hregMIPS_F26   ( Bool mode64 ) { return FR (mode64, 26, 17, 17); }
     75 ST_IN HReg hregMIPS_F28   ( Bool mode64 ) { return FR (mode64, 28, 18, 18); }
     76 ST_IN HReg hregMIPS_F30   ( Bool mode64 ) { return FR (mode64, 30, 19, 19); }
     77 
     78 // DRs are only allocatable in 32-bit mode, so the 64-bit index numbering
     79 // doesn't advance here.
     80 ST_IN HReg hregMIPS_D0    ( Bool mode64 ) { vassert(!mode64);
     81                                             return DR (mode64,  0,  0, 20); }
     82 ST_IN HReg hregMIPS_D1    ( Bool mode64 ) { vassert(!mode64);
     83                                             return DR (mode64,  2,  0, 21); }
     84 ST_IN HReg hregMIPS_D2    ( Bool mode64 ) { vassert(!mode64);
     85                                             return DR (mode64,  4,  0, 22); }
     86 ST_IN HReg hregMIPS_D3    ( Bool mode64 ) { vassert(!mode64);
     87                                             return DR (mode64,  6,  0, 23); }
     88 ST_IN HReg hregMIPS_D4    ( Bool mode64 ) { vassert(!mode64);
     89                                             return DR (mode64,  8,  0, 24); }
     90 ST_IN HReg hregMIPS_D5    ( Bool mode64 ) { vassert(!mode64);
     91                                             return DR (mode64, 10,  0, 25); }
     92 ST_IN HReg hregMIPS_D6    ( Bool mode64 ) { vassert(!mode64);
     93                                             return DR (mode64, 12,  0, 26); }
     94 ST_IN HReg hregMIPS_D7    ( Bool mode64 ) { vassert(!mode64);
     95                                             return DR (mode64, 14,  0, 27); }
     96 
     97 ST_IN HReg hregMIPS_HI    ( Bool mode64 ) { return FR (mode64, 33, 20, 28); }
     98 ST_IN HReg hregMIPS_LO    ( Bool mode64 ) { return FR (mode64, 34, 21, 29); }
     99 
    100 ST_IN HReg hregMIPS_GPR0  ( Bool mode64 ) { return GPR(mode64,  0, 22, 30); }
    101 ST_IN HReg hregMIPS_GPR1  ( Bool mode64 ) { return GPR(mode64,  1, 23, 31); }
    102 ST_IN HReg hregMIPS_GPR2  ( Bool mode64 ) { return GPR(mode64,  2, 24, 32); }
    103 ST_IN HReg hregMIPS_GPR3  ( Bool mode64 ) { return GPR(mode64,  3, 25, 33); }
    104 ST_IN HReg hregMIPS_GPR4  ( Bool mode64 ) { return GPR(mode64,  4, 26, 34); }
    105 ST_IN HReg hregMIPS_GPR5  ( Bool mode64 ) { return GPR(mode64,  5, 27, 35); }
    106 ST_IN HReg hregMIPS_GPR6  ( Bool mode64 ) { return GPR(mode64,  6, 28, 36); }
    107 ST_IN HReg hregMIPS_GPR7  ( Bool mode64 ) { return GPR(mode64,  7, 29, 37); }
    108 ST_IN HReg hregMIPS_GPR8  ( Bool mode64 ) { return GPR(mode64,  8, 30, 38); }
    109 ST_IN HReg hregMIPS_GPR9  ( Bool mode64 ) { return GPR(mode64,  9, 31, 39); }
    110 ST_IN HReg hregMIPS_GPR10 ( Bool mode64 ) { return GPR(mode64, 10, 32, 40); }
    111 ST_IN HReg hregMIPS_GPR11 ( Bool mode64 ) { return GPR(mode64, 11, 33, 41); }
    112 ST_IN HReg hregMIPS_GPR23 ( Bool mode64 ) { return GPR(mode64, 23, 34, 42); }
    113 ST_IN HReg hregMIPS_GPR25 ( Bool mode64 ) { return GPR(mode64, 25, 35, 43); }
    114 ST_IN HReg hregMIPS_GPR29 ( Bool mode64 ) { return GPR(mode64, 29, 36, 44); }
    115 ST_IN HReg hregMIPS_GPR31 ( Bool mode64 ) { return GPR(mode64, 31, 37, 45); }
    116 
    117 #undef ST_IN
    118 #undef GPR
    119 #undef FR
    120 #undef DR
    121 
    122 #define GuestStatePointer(_mode64)     hregMIPS_GPR23(_mode64)
    123 #define StackFramePointer(_mode64)     hregMIPS_GPR30(_mode64)
    124 #define StackPointer(_mode64)          hregMIPS_GPR29(_mode64)
    125 
    126 /* Num registers used for function calls */
    127 #if defined(VGP_mips32_linux)
    128   /* a0, a1, a2, a3 */
    129 # define MIPS_N_REGPARMS 4
    130 #else
    131   /* a0, a1, a2, a3, a4, a5, a6, a7 */
    132 # define MIPS_N_REGPARMS 8
    133 #endif
    134 
    135 extern void ppHRegMIPS ( HReg, Bool );
    136 
    137 
    138 /* --------- Condition codes, Intel encoding. --------- */
    139 typedef enum {
    140    MIPScc_EQ = 0,   /* equal */
    141    MIPScc_NE = 1,   /* not equal */
    142 
    143    MIPScc_HS = 2,   /* >=u (higher or same) */
    144    MIPScc_LO = 3,   /* <u  (lower) */
    145 
    146    MIPScc_MI = 4,   /* minus (negative) */
    147    MIPScc_PL = 5,   /* plus (zero or +ve) */
    148 
    149    MIPScc_VS = 6,   /* overflow */
    150    MIPScc_VC = 7,   /* no overflow */
    151 
    152    MIPScc_HI = 8,   /* >u   (higher) */
    153    MIPScc_LS = 9,   /* <=u  (lower or same) */
    154 
    155    MIPScc_GE = 10,  /* >=s (signed greater or equal) */
    156    MIPScc_LT = 11,  /* <s  (signed less than) */
    157 
    158    MIPScc_GT = 12,  /* >s  (signed greater) */
    159    MIPScc_LE = 13,  /* <=s (signed less or equal) */
    160 
    161    MIPScc_AL = 14,  /* always (unconditional) */
    162    MIPScc_NV = 15   /* never (unconditional): */
    163 } MIPSCondCode;
    164 
    165 extern const HChar *showMIPSCondCode(MIPSCondCode);
    166 
    167 /* --------- Memory address expressions (amodes). --------- */
    168 typedef enum {
    169    Mam_IR,        /* Immediate (signed 16-bit) + Reg */
    170    Mam_RR         /* Reg1 + Reg2 */
    171 } MIPSAModeTag;
    172 
    173 typedef struct {
    174    MIPSAModeTag tag;
    175    union {
    176       struct {
    177          HReg base;
    178          Int index;
    179       } IR;
    180       struct {
    181          HReg base;
    182          HReg index;
    183       } RR;
    184    } Mam;
    185 } MIPSAMode;
    186 
    187 extern MIPSAMode *MIPSAMode_IR(Int, HReg);
    188 extern MIPSAMode *MIPSAMode_RR(HReg, HReg);
    189 
    190 extern MIPSAMode *dopyMIPSAMode(MIPSAMode *);
    191 extern MIPSAMode *nextMIPSAModeFloat(MIPSAMode *);
    192 extern MIPSAMode *nextMIPSAModeInt(MIPSAMode *);
    193 
    194 extern void ppMIPSAMode(MIPSAMode *, Bool);
    195 
    196 /* --------- Operand, which can be a reg or a u16/s16. --------- */
    197 /* ("RH" == "Register or Halfword immediate") */
    198 typedef enum {
    199    Mrh_Imm,
    200    Mrh_Reg
    201 } MIPSRHTag;
    202 
    203 typedef struct {
    204    MIPSRHTag tag;
    205    union {
    206       struct {
    207          Bool syned;
    208          UShort imm16;
    209       } Imm;
    210       struct {
    211          HReg reg;
    212       } Reg;
    213    } Mrh;
    214 } MIPSRH;
    215 
    216 extern void ppMIPSRH(MIPSRH *, Bool);
    217 
    218 extern MIPSRH *MIPSRH_Imm(Bool, UShort);
    219 extern MIPSRH *MIPSRH_Reg(HReg);
    220 
    221 /* --------- Instructions. --------- */
    222 
    223 /*Tags for operations*/
    224 
    225 /* --------- */
    226 typedef enum {
    227    Mun_CLO,
    228    Mun_CLZ,
    229    Mun_DCLO,
    230    Mun_DCLZ,
    231    Mun_NOP,
    232 } MIPSUnaryOp;
    233 
    234 extern const HChar *showMIPSUnaryOp(MIPSUnaryOp);
    235 /* --------- */
    236 
    237 /* --------- */
    238 
    239 typedef enum {
    240    Malu_INVALID,
    241    Malu_ADD, Malu_SUB,
    242    Malu_AND, Malu_OR, Malu_NOR, Malu_XOR,
    243    Malu_DADD, Malu_DSUB,
    244    Malu_SLT
    245 } MIPSAluOp;
    246 
    247 extern const HChar *showMIPSAluOp(MIPSAluOp,
    248                             Bool /* is the 2nd operand an immediate? */ );
    249 
    250 /* --------- */
    251 typedef enum {
    252    Mshft_INVALID,
    253    Mshft_SLL, Mshft_SRL,
    254    Mshft_SRA
    255 } MIPSShftOp;
    256 
    257 extern const HChar *showMIPSShftOp(MIPSShftOp,
    258                              Bool /* is the 2nd operand an immediate? */ ,
    259                              Bool /* is this a 32bit or 64bit op? */ );
    260 
    261 /* --------- */
    262 typedef enum {
    263    Macc_ADD,
    264    Macc_SUB
    265 } MIPSMaccOp;
    266 
    267 extern const HChar *showMIPSMaccOp(MIPSMaccOp, Bool);
    268 /* --------- */
    269 
    270 /* ----- Instruction tags ----- */
    271 typedef enum {
    272    Min_LI,         /* load word (32/64-bit) immediate (fake insn) */
    273    Min_Alu,        /* word add/sub/and/or/xor/nor/others? */
    274    Min_Shft,       /* word sll/srl/sra */
    275    Min_Unary,      /* clo, clz, nop, neg */
    276 
    277    Min_Cmp,        /* word compare (fake insn) */
    278 
    279    Min_Mul,        /* widening/non-widening multiply */
    280    Min_Div,        /* div */
    281 
    282    Min_Call,       /* call to address in register */
    283 
    284    /* The following 5 insns are mandated by translation chaining */
    285    Min_XDirect,    /* direct transfer to GA */
    286    Min_XIndir,     /* indirect transfer to GA */
    287    Min_XAssisted,  /* assisted transfer to GA */
    288    Min_EvCheck,    /* Event check */
    289    Min_ProfInc,    /* 64-bit profile counter increment */
    290 
    291    Min_RdWrLR,     /* Read/Write Link Register */
    292    Min_Mthi,       /* Move to HI from GP register */
    293    Min_Mtlo,       /* Move to LO from GP register */
    294    Min_Mfhi,       /* Move from HI to GP register */
    295    Min_Mflo,       /* Move from LO to GP register */
    296    Min_Macc,       /* Multiply and accumulate */
    297 
    298    Min_Load,       /* zero-extending load a 8|16|32 bit value from mem */
    299    Min_Store,      /* store a 8|16|32 bit value to mem */
    300    Min_Cas,        /* compare and swap */
    301    Min_LoadL,      /* mips Load Linked Word - LL */
    302    Min_StoreC,     /* mips Store Conditional Word - SC */
    303 
    304    Min_FpUnary,    /* FP unary op */
    305    Min_FpBinary,   /* FP binary op */
    306    Min_FpTernary,  /* FP ternary op */
    307    Min_FpConvert,  /* FP conversion op */
    308    Min_FpMulAcc,   /* FP multipy-accumulate style op */
    309    Min_FpLdSt,     /* FP load/store */
    310    Min_FpSTFIW,    /* stfiwx */
    311    Min_FpRSP,      /* FP round IEEE754 double to IEEE754 single */
    312    Min_FpCftI,     /* fcfid/fctid/fctiw */
    313    Min_FpCMov,     /* FP floating point conditional move */
    314    Min_MtFCSR,     /* set FCSR register */
    315    Min_MfFCSR,     /* get FCSR register */
    316    Min_FpCompare,  /* FP compare, generating value into int reg */
    317 
    318    Min_FpGpMove,   /* Move from/to fpr to/from gpr */
    319    Min_MoveCond    /* Move Conditional */
    320 } MIPSInstrTag;
    321 
    322 /* --------- */
    323 typedef enum {
    324    Mfp_INVALID,
    325 
    326    /* Ternary */
    327    Mfp_MADDD, Mfp_MSUBD,
    328    Mfp_MADDS, Mfp_MSUBS,
    329 
    330    /* Binary */
    331    Mfp_ADDD, Mfp_SUBD, Mfp_MULD, Mfp_DIVD,
    332    Mfp_ADDS, Mfp_SUBS, Mfp_MULS, Mfp_DIVS,
    333 
    334    /* Unary */
    335    Mfp_SQRTS, Mfp_SQRTD,
    336    Mfp_ABSS, Mfp_ABSD, Mfp_NEGS, Mfp_NEGD, Mfp_MOVS, Mfp_MOVD,
    337 
    338    /* FP convert */
    339    Mfp_CVTSD, Mfp_CVTSW, Mfp_CVTWD,
    340    Mfp_CVTWS, Mfp_CVTDL, Mfp_CVTSL, Mfp_CVTLS, Mfp_CVTLD, Mfp_TRULS, Mfp_TRULD,
    341    Mfp_TRUWS, Mfp_TRUWD, Mfp_FLOORWS, Mfp_FLOORWD, Mfp_ROUNDWS, Mfp_ROUNDWD,
    342    Mfp_CVTDW, Mfp_CEILWS, Mfp_CEILWD, Mfp_CEILLS, Mfp_CEILLD, Mfp_CVTDS,
    343    Mfp_ROUNDLD, Mfp_FLOORLD,
    344 
    345    /* FP compare */
    346    Mfp_CMP_UN, Mfp_CMP_EQ, Mfp_CMP_LT, Mfp_CMP_NGT
    347 
    348 } MIPSFpOp;
    349 
    350 extern const HChar *showMIPSFpOp(MIPSFpOp);
    351 
    352 /* Move from/to fpr to/from gpr */
    353 typedef enum {
    354    MFpGpMove_mfc1,   /* Move Word From Floating Point - MIPS32 */
    355    MFpGpMove_dmfc1,  /* Doubleword Move from Floating Point - MIPS64 */
    356    MFpGpMove_mtc1,   /* Move Word to Floating Point - MIPS32 */
    357    MFpGpMove_dmtc1   /* Doubleword Move to Floating Point - MIPS64 */
    358 } MIPSFpGpMoveOp;
    359 
    360 extern const HChar *showMIPSFpGpMoveOp ( MIPSFpGpMoveOp );
    361 
    362 /* Move Conditional */
    363 typedef enum {
    364    MFpMoveCond_movns,  /* FP Move Conditional on Not Zero - MIPS32 */
    365    MFpMoveCond_movnd,
    366    MMoveCond_movn      /* Move Conditional on Not Zero */
    367 } MIPSMoveCondOp;
    368 
    369 extern const HChar *showMIPSMoveCondOp ( MIPSMoveCondOp );
    370 
    371 /*--------- Structure for instructions ----------*/
    372 /* Destinations are on the LEFT (first operand) */
    373 
    374 typedef struct {
    375    MIPSInstrTag tag;
    376    union {
    377       /* Get a 32/64-bit literal into a register.
    378          May turn into a number of real insns. */
    379       struct {
    380          HReg dst;
    381          ULong imm;
    382       } LI;
    383       /* Integer add/sub/and/or/xor.  Limitations:
    384          - For add, the immediate, if it exists, is a signed 16.
    385          - For sub, the immediate, if it exists, is a signed 16
    386          which may not be -32768, since no such instruction
    387          exists, and so we have to emit addi with +32768, but
    388          that is not possible.
    389          - For and/or/xor,  the immediate, if it exists,
    390          is an unsigned 16.
    391        */
    392       struct {
    393          MIPSAluOp op;
    394          HReg dst;
    395          HReg srcL;
    396          MIPSRH *srcR;
    397       } Alu;
    398       /* Integer shl/shr/sar.
    399          Limitations: the immediate, if it exists,
    400          is a signed 5-bit value between 1 and 31 inclusive.
    401        */
    402       struct {
    403          MIPSShftOp op;
    404          Bool sz32;  /* mode64 has both 32 and 64bit shft */
    405          HReg dst;
    406          HReg srcL;
    407          MIPSRH *srcR;
    408       } Shft;
    409       /* Clz, Clo, nop */
    410       struct {
    411          MIPSUnaryOp op;
    412          HReg dst;
    413          HReg src;
    414       } Unary;
    415       /* Word compare. Fake instruction, used for basic block ending */
    416       struct {
    417          Bool syned;
    418          Bool sz32;
    419          HReg dst;
    420          HReg srcL;
    421          HReg srcR;
    422 
    423          MIPSCondCode cond;
    424       } Cmp;
    425       struct {
    426          Bool widening;  /* True => widening, False => non-widening */
    427          Bool syned;     /* signed/unsigned - meaningless if widenind = False */
    428          Bool sz32;
    429          HReg dst;
    430          HReg srcL;
    431          HReg srcR;
    432       } Mul;
    433       struct {
    434          Bool syned;  /* signed/unsigned - meaningless if widenind = False */
    435          Bool sz32;
    436          HReg srcL;
    437          HReg srcR;
    438       } Div;
    439       /* Pseudo-insn.  Call target (an absolute address), on given
    440          condition (which could be Mcc_ALWAYS).  argiregs indicates
    441          which of $4 .. $7 (mips32) or $4 .. $11 (mips64)
    442          carries argument values for this call,
    443          using a bit mask (1<<N is set if $N holds an arg, for N in
    444          $4 .. $7 or $4 .. $11 inclusive).
    445          If cond is != Mcc_ALWAYS, src is checked.
    446          Otherwise, unconditional call */
    447       struct {
    448          MIPSCondCode cond;
    449          Addr64 target;
    450          UInt argiregs;
    451          HReg src;
    452          RetLoc rloc;     /* where the return value will be */
    453       } Call;
    454       /* Update the guest EIP value, then exit requesting to chain
    455          to it.  May be conditional.  Urr, use of Addr32 implicitly
    456          assumes that wordsize(guest) == wordsize(host). */
    457       struct {
    458          Addr64       dstGA;     /* next guest address */
    459          MIPSAMode*   amPC;      /* amode in guest state for PC */
    460          MIPSCondCode cond;      /* can be MIPScc_AL */
    461          Bool         toFastEP;  /* chain to the slow or fast point? */
    462       } XDirect;
    463       /* Boring transfer to a guest address not known at JIT time.
    464          Not chainable.  May be conditional. */
    465       struct {
    466          HReg        dstGA;
    467          MIPSAMode*   amPC;
    468          MIPSCondCode cond; /* can be MIPScc_AL */
    469       } XIndir;
    470       /* Assisted transfer to a guest address, most general case.
    471          Not chainable.  May be conditional. */
    472       struct {
    473          HReg        dstGA;
    474          MIPSAMode*   amPC;
    475          MIPSCondCode cond; /* can be MIPScc_AL */
    476          IRJumpKind  jk;
    477       } XAssisted;
    478       /* Zero extending loads.  Dst size is host word size */
    479       struct {
    480          UChar sz;   /* 1|2|4|8 */
    481          HReg dst;
    482          MIPSAMode *src;
    483       } Load;
    484       /* 64/32/16/8 bit stores */
    485       struct {
    486          UChar sz;   /* 1|2|4|8 */
    487          MIPSAMode *dst;
    488          HReg src;
    489       } Store;
    490       struct {
    491          UChar sz;   /* 4|8 */
    492          HReg dst;
    493          MIPSAMode *src;
    494       } LoadL;
    495       struct {
    496          UChar sz;   /* 4|8 */
    497          HReg  old;
    498          HReg  addr;
    499          HReg  expd;
    500          HReg  data;
    501       } Cas;
    502       struct {
    503          UChar sz;   /* 4|8 */
    504          MIPSAMode *dst;
    505          HReg src;
    506       } StoreC;
    507       /* Move from HI/LO register to GP register. */
    508       struct {
    509          HReg dst;
    510       } MfHL;
    511 
    512       /* Move to HI/LO register from GP register. */
    513       struct {
    514          HReg src;
    515       } MtHL;
    516 
    517       /* Read/Write Link Register */
    518       struct {
    519          Bool wrLR;
    520          HReg gpr;
    521       } RdWrLR;
    522 
    523       /* MIPS Multiply and accumulate instructions. */
    524       struct {
    525          MIPSMaccOp op;
    526          Bool syned;
    527 
    528          HReg srcL;
    529          HReg srcR;
    530       } Macc;
    531 
    532       /* MIPS Floating point */
    533       struct {
    534          MIPSFpOp op;
    535          HReg dst;
    536          HReg src;
    537       } FpUnary;
    538       struct {
    539          MIPSFpOp op;
    540          HReg dst;
    541          HReg srcL;
    542          HReg srcR;
    543       } FpBinary;
    544       struct {
    545          MIPSFpOp op;
    546          HReg dst;
    547          HReg src1;
    548          HReg src2;
    549          HReg src3;
    550       } FpTernary;
    551       struct {
    552          MIPSFpOp op;
    553          HReg dst;
    554          HReg srcML;
    555          HReg srcMR;
    556          HReg srcAcc;
    557       } FpMulAcc;
    558       struct {
    559          Bool isLoad;
    560          UChar sz;   /* only 4 (IEEE single) or 8 (IEEE double) */
    561          HReg reg;
    562          MIPSAMode *addr;
    563       } FpLdSt;
    564 
    565       struct {
    566          MIPSFpOp op;
    567          HReg dst;
    568          HReg src;
    569       } FpConvert;
    570       struct {
    571          MIPSFpOp op;
    572          HReg dst;
    573          HReg srcL;
    574          HReg srcR;
    575          UChar cond1;
    576       } FpCompare;
    577       /* Move from GP register to FCSR register. */
    578       struct {
    579          HReg src;
    580       } MtFCSR;
    581       /* Move from FCSR register to GP register. */
    582       struct {
    583          HReg dst;
    584       } MfFCSR;
    585       struct {
    586          MIPSAMode* amCounter;
    587          MIPSAMode* amFailAddr;
    588       } EvCheck;
    589       struct {
    590          /* No fields.  The address of the counter to inc is
    591             installed later, post-translation, by patching it in,
    592             as it is not known at translation time. */
    593       } ProfInc;
    594 
    595       /* Move from/to fpr to/from gpr */
    596       struct {
    597          MIPSFpGpMoveOp op;
    598          HReg dst;
    599          HReg src;
    600       } FpGpMove;
    601       struct {
    602          MIPSMoveCondOp op;
    603          HReg dst;
    604          HReg src;
    605          HReg cond;
    606       } MoveCond;
    607 
    608    } Min;
    609 } MIPSInstr;
    610 
    611 extern MIPSInstr *MIPSInstr_LI(HReg, ULong);
    612 extern MIPSInstr *MIPSInstr_Alu(MIPSAluOp, HReg, HReg, MIPSRH *);
    613 extern MIPSInstr *MIPSInstr_Shft(MIPSShftOp, Bool sz32, HReg, HReg, MIPSRH *);
    614 extern MIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src);
    615 extern MIPSInstr *MIPSInstr_Cmp(Bool, Bool, HReg, HReg, HReg, MIPSCondCode);
    616 
    617 extern MIPSInstr *MIPSInstr_Mul(Bool syned, Bool hi32, Bool sz32, HReg,
    618                                 HReg, HReg);
    619 extern MIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg, HReg);
    620 extern MIPSInstr *MIPSInstr_Madd(Bool, HReg, HReg);
    621 extern MIPSInstr *MIPSInstr_Msub(Bool, HReg, HReg);
    622 
    623 extern MIPSInstr *MIPSInstr_Load(UChar sz, HReg dst, MIPSAMode * src,
    624                                  Bool mode64);
    625 extern MIPSInstr *MIPSInstr_Store(UChar sz, MIPSAMode * dst, HReg src,
    626                                   Bool mode64);
    627 
    628 extern MIPSInstr *MIPSInstr_LoadL(UChar sz, HReg dst, MIPSAMode * src,
    629                                   Bool mode64);
    630 extern MIPSInstr *MIPSInstr_StoreC(UChar sz, MIPSAMode * dst, HReg src,
    631                                    Bool mode64);
    632 extern MIPSInstr *MIPSInstr_Cas(UChar sz, HReg old, HReg addr,
    633                                 HReg expd, HReg data, Bool mode64);
    634 
    635 extern MIPSInstr *MIPSInstr_Call ( MIPSCondCode, Addr64, UInt, HReg, RetLoc );
    636 extern MIPSInstr *MIPSInstr_CallAlways ( MIPSCondCode, Addr64, UInt, RetLoc );
    637 
    638 extern MIPSInstr *MIPSInstr_XDirect ( Addr64 dstGA, MIPSAMode* amPC,
    639                                       MIPSCondCode cond, Bool toFastEP );
    640 extern MIPSInstr *MIPSInstr_XIndir(HReg dstGA, MIPSAMode* amPC,
    641                                      MIPSCondCode cond);
    642 extern MIPSInstr *MIPSInstr_XAssisted(HReg dstGA, MIPSAMode* amPC,
    643                                       MIPSCondCode cond, IRJumpKind jk);
    644 
    645 extern MIPSInstr *MIPSInstr_FpUnary(MIPSFpOp op, HReg dst, HReg src);
    646 extern MIPSInstr *MIPSInstr_FpBinary(MIPSFpOp op, HReg dst, HReg srcL,
    647                                      HReg srcR);
    648 extern MIPSInstr *MIPSInstr_FpTernary ( MIPSFpOp op, HReg dst, HReg src1,
    649                                         HReg src2, HReg src3 );
    650 extern MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src);
    651 extern MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL,
    652                                       HReg srcR);
    653 extern MIPSInstr *MIPSInstr_FpMulAcc(MIPSFpOp op, HReg dst, HReg srcML,
    654                                      HReg srcMR, HReg srcAcc);
    655 extern MIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg, MIPSAMode *);
    656 extern MIPSInstr *MIPSInstr_FpSTFIW(HReg addr, HReg data);
    657 extern MIPSInstr *MIPSInstr_FpRSP(HReg dst, HReg src);
    658 extern MIPSInstr *MIPSInstr_FpCftI(Bool fromI, Bool int32, HReg dst, HReg src);
    659 extern MIPSInstr *MIPSInstr_FpCMov(MIPSCondCode, HReg dst, HReg src);
    660 extern MIPSInstr *MIPSInstr_MtFCSR(HReg src);
    661 extern MIPSInstr *MIPSInstr_MfFCSR(HReg dst);
    662 extern MIPSInstr *MIPSInstr_FpCmp(HReg dst, HReg srcL, HReg srcR);
    663 
    664 extern MIPSInstr *MIPSInstr_Mfhi(HReg dst);
    665 extern MIPSInstr *MIPSInstr_Mflo(HReg dst);
    666 extern MIPSInstr *MIPSInstr_Mthi(HReg src);
    667 extern MIPSInstr *MIPSInstr_Mtlo(HReg src);
    668 
    669 extern MIPSInstr *MIPSInstr_RdWrLR(Bool wrLR, HReg gpr);
    670 
    671 extern MIPSInstr *MIPSInstr_MoveCond ( MIPSMoveCondOp op, HReg dst,
    672                                        HReg src, HReg cond );
    673 
    674 extern MIPSInstr *MIPSInstr_FpGpMove ( MIPSFpGpMoveOp op, HReg dst, HReg src );
    675 
    676 extern MIPSInstr *MIPSInstr_EvCheck(MIPSAMode* amCounter,
    677                                     MIPSAMode* amFailAddr );
    678 extern MIPSInstr *MIPSInstr_ProfInc( void );
    679 
    680 extern void ppMIPSInstr(const MIPSInstr *, Bool mode64);
    681 
    682 /* Some functions that insulate the register allocator from details
    683    of the underlying instruction set. */
    684 extern void getRegUsage_MIPSInstr (HRegUsage *, const MIPSInstr *, Bool);
    685 extern void mapRegs_MIPSInstr     (HRegRemap *, MIPSInstr *, Bool mode64);
    686 extern Bool isMove_MIPSInstr      (const MIPSInstr *, HReg *, HReg *);
    687 extern Int        emit_MIPSInstr (/*MB_MOD*/Bool* is_profInc,
    688                                   UChar* buf, Int nbuf, const MIPSInstr* i,
    689                                   Bool mode64,
    690                                   VexEndness endness_host,
    691                                   const void* disp_cp_chain_me_to_slowEP,
    692                                   const void* disp_cp_chain_me_to_fastEP,
    693                                   const void* disp_cp_xindir,
    694                                   const void* disp_cp_xassisted );
    695 
    696 extern void genSpill_MIPS ( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
    697                             HReg rreg, Int offset, Bool);
    698 extern void genReload_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
    699                             HReg rreg, Int offset, Bool);
    700 
    701 extern const RRegUniverse* getRRegUniverse_MIPS ( Bool mode64 );
    702 
    703 extern HInstrArray *iselSB_MIPS          ( const IRSB*,
    704                                            VexArch,
    705                                            const VexArchInfo*,
    706                                            const VexAbiInfo*,
    707                                            Int offs_Host_EvC_Counter,
    708                                            Int offs_Host_EvC_FailAddr,
    709                                            Bool chainingAllowed,
    710                                            Bool addProfInc,
    711                                            Addr max_ga );
    712 
    713 /* How big is an event check?  This is kind of a kludge because it
    714    depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
    715    and so assumes that they are both <= 128, and so can use the short
    716    offset encoding.  This is all checked with assertions, so in the
    717    worst case we will merely assert at startup. */
    718 extern Int evCheckSzB_MIPS (void);
    719 
    720 /* Perform a chaining and unchaining of an XDirect jump. */
    721 extern VexInvalRange chainXDirect_MIPS ( VexEndness endness_host,
    722                                          void* place_to_chain,
    723                                          const void* disp_cp_chain_me_EXPECTED,
    724                                          const void* place_to_jump_to,
    725                                          Bool  mode64 );
    726 
    727 extern VexInvalRange unchainXDirect_MIPS ( VexEndness endness_host,
    728                                            void* place_to_unchain,
    729                                            const void* place_to_jump_to_EXPECTED,
    730                                            const void* disp_cp_chain_me,
    731                                            Bool  mode64 );
    732 
    733 /* Patch the counter location into an existing ProfInc point. */
    734 extern VexInvalRange patchProfInc_MIPS ( VexEndness endness_host,
    735                                          void*  place_to_patch,
    736                                          const ULong* location_of_counter,
    737                                          Bool  mode64 );
    738 
    739 #endif /* ndef __VEX_HOST_MIPS_DEFS_H */
    740 
    741 /*---------------------------------------------------------------*/
    742 /*--- end                                    host-mips_defs.h ---*/
    743 /*---------------------------------------------------------------*/
    744