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