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