• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
hregMIPS_GPR16(Bool mode64)55 ST_IN HReg hregMIPS_GPR16 ( Bool mode64 ) { return GPR(mode64, 16,  0,  0); }
hregMIPS_GPR17(Bool mode64)56 ST_IN HReg hregMIPS_GPR17 ( Bool mode64 ) { return GPR(mode64, 17,  1,  1); }
hregMIPS_GPR18(Bool mode64)57 ST_IN HReg hregMIPS_GPR18 ( Bool mode64 ) { return GPR(mode64, 18,  2,  2); }
hregMIPS_GPR19(Bool mode64)58 ST_IN HReg hregMIPS_GPR19 ( Bool mode64 ) { return GPR(mode64, 19,  3,  3); }
hregMIPS_GPR20(Bool mode64)59 ST_IN HReg hregMIPS_GPR20 ( Bool mode64 ) { return GPR(mode64, 20,  4,  4); }
hregMIPS_GPR21(Bool mode64)60 ST_IN HReg hregMIPS_GPR21 ( Bool mode64 ) { return GPR(mode64, 21,  5,  5); }
hregMIPS_GPR22(Bool mode64)61 ST_IN HReg hregMIPS_GPR22 ( Bool mode64 ) { return GPR(mode64, 22,  6,  6); }
62 
hregMIPS_GPR12(Bool mode64)63 ST_IN HReg hregMIPS_GPR12 ( Bool mode64 ) { return GPR(mode64, 12,  7,  7); }
hregMIPS_GPR13(Bool mode64)64 ST_IN HReg hregMIPS_GPR13 ( Bool mode64 ) { return GPR(mode64, 13,  8,  8); }
hregMIPS_GPR14(Bool mode64)65 ST_IN HReg hregMIPS_GPR14 ( Bool mode64 ) { return GPR(mode64, 14,  9,  9); }
hregMIPS_GPR15(Bool mode64)66 ST_IN HReg hregMIPS_GPR15 ( Bool mode64 ) { return GPR(mode64, 15, 10, 10); }
hregMIPS_GPR24(Bool mode64)67 ST_IN HReg hregMIPS_GPR24 ( Bool mode64 ) { return GPR(mode64, 24, 11, 11); }
68 
hregMIPS_F16(Bool mode64)69 ST_IN HReg hregMIPS_F16   ( Bool mode64 ) { return FR (mode64, 16, 12, 12); }
hregMIPS_F18(Bool mode64)70 ST_IN HReg hregMIPS_F18   ( Bool mode64 ) { return FR (mode64, 18, 13, 13); }
hregMIPS_F20(Bool mode64)71 ST_IN HReg hregMIPS_F20   ( Bool mode64 ) { return FR (mode64, 20, 14, 14); }
hregMIPS_F22(Bool mode64)72 ST_IN HReg hregMIPS_F22   ( Bool mode64 ) { return FR (mode64, 22, 15, 15); }
hregMIPS_F24(Bool mode64)73 ST_IN HReg hregMIPS_F24   ( Bool mode64 ) { return FR (mode64, 24, 16, 16); }
hregMIPS_F26(Bool mode64)74 ST_IN HReg hregMIPS_F26   ( Bool mode64 ) { return FR (mode64, 26, 17, 17); }
hregMIPS_F28(Bool mode64)75 ST_IN HReg hregMIPS_F28   ( Bool mode64 ) { return FR (mode64, 28, 18, 18); }
hregMIPS_F30(Bool mode64)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.
hregMIPS_D0(Bool mode64)80 ST_IN HReg hregMIPS_D0    ( Bool mode64 ) { vassert(!mode64);
81                                             return DR (mode64,  0,  0, 20); }
hregMIPS_D1(Bool mode64)82 ST_IN HReg hregMIPS_D1    ( Bool mode64 ) { vassert(!mode64);
83                                             return DR (mode64,  2,  0, 21); }
hregMIPS_D2(Bool mode64)84 ST_IN HReg hregMIPS_D2    ( Bool mode64 ) { vassert(!mode64);
85                                             return DR (mode64,  4,  0, 22); }
hregMIPS_D3(Bool mode64)86 ST_IN HReg hregMIPS_D3    ( Bool mode64 ) { vassert(!mode64);
87                                             return DR (mode64,  6,  0, 23); }
hregMIPS_D4(Bool mode64)88 ST_IN HReg hregMIPS_D4    ( Bool mode64 ) { vassert(!mode64);
89                                             return DR (mode64,  8,  0, 24); }
hregMIPS_D5(Bool mode64)90 ST_IN HReg hregMIPS_D5    ( Bool mode64 ) { vassert(!mode64);
91                                             return DR (mode64, 10,  0, 25); }
hregMIPS_D6(Bool mode64)92 ST_IN HReg hregMIPS_D6    ( Bool mode64 ) { vassert(!mode64);
93                                             return DR (mode64, 12,  0, 26); }
hregMIPS_D7(Bool mode64)94 ST_IN HReg hregMIPS_D7    ( Bool mode64 ) { vassert(!mode64);
95                                             return DR (mode64, 14,  0, 27); }
96 
hregMIPS_HI(Bool mode64)97 ST_IN HReg hregMIPS_HI    ( Bool mode64 ) { return FR (mode64, 33, 20, 28); }
hregMIPS_LO(Bool mode64)98 ST_IN HReg hregMIPS_LO    ( Bool mode64 ) { return FR (mode64, 34, 21, 29); }
99 
hregMIPS_GPR0(Bool mode64)100 ST_IN HReg hregMIPS_GPR0  ( Bool mode64 ) { return GPR(mode64,  0, 22, 30); }
hregMIPS_GPR1(Bool mode64)101 ST_IN HReg hregMIPS_GPR1  ( Bool mode64 ) { return GPR(mode64,  1, 23, 31); }
hregMIPS_GPR2(Bool mode64)102 ST_IN HReg hregMIPS_GPR2  ( Bool mode64 ) { return GPR(mode64,  2, 24, 32); }
hregMIPS_GPR3(Bool mode64)103 ST_IN HReg hregMIPS_GPR3  ( Bool mode64 ) { return GPR(mode64,  3, 25, 33); }
hregMIPS_GPR4(Bool mode64)104 ST_IN HReg hregMIPS_GPR4  ( Bool mode64 ) { return GPR(mode64,  4, 26, 34); }
hregMIPS_GPR5(Bool mode64)105 ST_IN HReg hregMIPS_GPR5  ( Bool mode64 ) { return GPR(mode64,  5, 27, 35); }
hregMIPS_GPR6(Bool mode64)106 ST_IN HReg hregMIPS_GPR6  ( Bool mode64 ) { return GPR(mode64,  6, 28, 36); }
hregMIPS_GPR7(Bool mode64)107 ST_IN HReg hregMIPS_GPR7  ( Bool mode64 ) { return GPR(mode64,  7, 29, 37); }
hregMIPS_GPR8(Bool mode64)108 ST_IN HReg hregMIPS_GPR8  ( Bool mode64 ) { return GPR(mode64,  8, 30, 38); }
hregMIPS_GPR9(Bool mode64)109 ST_IN HReg hregMIPS_GPR9  ( Bool mode64 ) { return GPR(mode64,  9, 31, 39); }
hregMIPS_GPR10(Bool mode64)110 ST_IN HReg hregMIPS_GPR10 ( Bool mode64 ) { return GPR(mode64, 10, 32, 40); }
hregMIPS_GPR11(Bool mode64)111 ST_IN HReg hregMIPS_GPR11 ( Bool mode64 ) { return GPR(mode64, 11, 33, 41); }
hregMIPS_GPR23(Bool mode64)112 ST_IN HReg hregMIPS_GPR23 ( Bool mode64 ) { return GPR(mode64, 23, 34, 42); }
hregMIPS_GPR25(Bool mode64)113 ST_IN HReg hregMIPS_GPR25 ( Bool mode64 ) { return GPR(mode64, 25, 35, 43); }
hregMIPS_GPR29(Bool mode64)114 ST_IN HReg hregMIPS_GPR29 ( Bool mode64 ) { return GPR(mode64, 29, 36, 44); }
hregMIPS_GPR31(Bool mode64)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