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
55ST_IN HReg hregMIPS_GPR16 ( Bool mode64 ) { return GPR(mode64, 16,  0,  0); }
56ST_IN HReg hregMIPS_GPR17 ( Bool mode64 ) { return GPR(mode64, 17,  1,  1); }
57ST_IN HReg hregMIPS_GPR18 ( Bool mode64 ) { return GPR(mode64, 18,  2,  2); }
58ST_IN HReg hregMIPS_GPR19 ( Bool mode64 ) { return GPR(mode64, 19,  3,  3); }
59ST_IN HReg hregMIPS_GPR20 ( Bool mode64 ) { return GPR(mode64, 20,  4,  4); }
60ST_IN HReg hregMIPS_GPR21 ( Bool mode64 ) { return GPR(mode64, 21,  5,  5); }
61ST_IN HReg hregMIPS_GPR22 ( Bool mode64 ) { return GPR(mode64, 22,  6,  6); }
62
63ST_IN HReg hregMIPS_GPR12 ( Bool mode64 ) { return GPR(mode64, 12,  7,  7); }
64ST_IN HReg hregMIPS_GPR13 ( Bool mode64 ) { return GPR(mode64, 13,  8,  8); }
65ST_IN HReg hregMIPS_GPR14 ( Bool mode64 ) { return GPR(mode64, 14,  9,  9); }
66ST_IN HReg hregMIPS_GPR15 ( Bool mode64 ) { return GPR(mode64, 15, 10, 10); }
67ST_IN HReg hregMIPS_GPR24 ( Bool mode64 ) { return GPR(mode64, 24, 11, 11); }
68
69ST_IN HReg hregMIPS_F16   ( Bool mode64 ) { return FR (mode64, 16, 12, 12); }
70ST_IN HReg hregMIPS_F18   ( Bool mode64 ) { return FR (mode64, 18, 13, 13); }
71ST_IN HReg hregMIPS_F20   ( Bool mode64 ) { return FR (mode64, 20, 14, 14); }
72ST_IN HReg hregMIPS_F22   ( Bool mode64 ) { return FR (mode64, 22, 15, 15); }
73ST_IN HReg hregMIPS_F24   ( Bool mode64 ) { return FR (mode64, 24, 16, 16); }
74ST_IN HReg hregMIPS_F26   ( Bool mode64 ) { return FR (mode64, 26, 17, 17); }
75ST_IN HReg hregMIPS_F28   ( Bool mode64 ) { return FR (mode64, 28, 18, 18); }
76ST_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.
80ST_IN HReg hregMIPS_D0    ( Bool mode64 ) { vassert(!mode64);
81                                            return DR (mode64,  0,  0, 20); }
82ST_IN HReg hregMIPS_D1    ( Bool mode64 ) { vassert(!mode64);
83                                            return DR (mode64,  2,  0, 21); }
84ST_IN HReg hregMIPS_D2    ( Bool mode64 ) { vassert(!mode64);
85                                            return DR (mode64,  4,  0, 22); }
86ST_IN HReg hregMIPS_D3    ( Bool mode64 ) { vassert(!mode64);
87                                            return DR (mode64,  6,  0, 23); }
88ST_IN HReg hregMIPS_D4    ( Bool mode64 ) { vassert(!mode64);
89                                            return DR (mode64,  8,  0, 24); }
90ST_IN HReg hregMIPS_D5    ( Bool mode64 ) { vassert(!mode64);
91                                            return DR (mode64, 10,  0, 25); }
92ST_IN HReg hregMIPS_D6    ( Bool mode64 ) { vassert(!mode64);
93                                            return DR (mode64, 12,  0, 26); }
94ST_IN HReg hregMIPS_D7    ( Bool mode64 ) { vassert(!mode64);
95                                            return DR (mode64, 14,  0, 27); }
96
97ST_IN HReg hregMIPS_HI    ( Bool mode64 ) { return FR (mode64, 33, 20, 28); }
98ST_IN HReg hregMIPS_LO    ( Bool mode64 ) { return FR (mode64, 34, 21, 29); }
99
100ST_IN HReg hregMIPS_GPR0  ( Bool mode64 ) { return GPR(mode64,  0, 22, 30); }
101ST_IN HReg hregMIPS_GPR1  ( Bool mode64 ) { return GPR(mode64,  1, 23, 31); }
102ST_IN HReg hregMIPS_GPR2  ( Bool mode64 ) { return GPR(mode64,  2, 24, 32); }
103ST_IN HReg hregMIPS_GPR3  ( Bool mode64 ) { return GPR(mode64,  3, 25, 33); }
104ST_IN HReg hregMIPS_GPR4  ( Bool mode64 ) { return GPR(mode64,  4, 26, 34); }
105ST_IN HReg hregMIPS_GPR5  ( Bool mode64 ) { return GPR(mode64,  5, 27, 35); }
106ST_IN HReg hregMIPS_GPR6  ( Bool mode64 ) { return GPR(mode64,  6, 28, 36); }
107ST_IN HReg hregMIPS_GPR7  ( Bool mode64 ) { return GPR(mode64,  7, 29, 37); }
108ST_IN HReg hregMIPS_GPR8  ( Bool mode64 ) { return GPR(mode64,  8, 30, 38); }
109ST_IN HReg hregMIPS_GPR9  ( Bool mode64 ) { return GPR(mode64,  9, 31, 39); }
110ST_IN HReg hregMIPS_GPR10 ( Bool mode64 ) { return GPR(mode64, 10, 32, 40); }
111ST_IN HReg hregMIPS_GPR11 ( Bool mode64 ) { return GPR(mode64, 11, 33, 41); }
112ST_IN HReg hregMIPS_GPR23 ( Bool mode64 ) { return GPR(mode64, 23, 34, 42); }
113ST_IN HReg hregMIPS_GPR25 ( Bool mode64 ) { return GPR(mode64, 25, 35, 43); }
114ST_IN HReg hregMIPS_GPR29 ( Bool mode64 ) { return GPR(mode64, 29, 36, 44); }
115ST_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
138extern void ppHRegMIPS ( HReg, Bool );
139
140
141/* --------- Condition codes, Intel encoding. --------- */
142typedef 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
168extern const HChar *showMIPSCondCode(MIPSCondCode);
169
170/* --------- Memory address expressions (amodes). --------- */
171typedef enum {
172   Mam_IR,        /* Immediate (signed 16-bit) + Reg */
173   Mam_RR         /* Reg1 + Reg2 */
174} MIPSAModeTag;
175
176typedef 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
190extern MIPSAMode *MIPSAMode_IR(Int, HReg);
191extern MIPSAMode *MIPSAMode_RR(HReg, HReg);
192
193extern MIPSAMode *dopyMIPSAMode(MIPSAMode *);
194extern MIPSAMode *nextMIPSAModeFloat(MIPSAMode *);
195extern MIPSAMode *nextMIPSAModeInt(MIPSAMode *);
196
197extern void ppMIPSAMode(MIPSAMode *, Bool);
198
199/* --------- Operand, which can be a reg or a u16/s16. --------- */
200/* ("RH" == "Register or Halfword immediate") */
201typedef enum {
202   Mrh_Imm,
203   Mrh_Reg
204} MIPSRHTag;
205
206typedef 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
219extern void ppMIPSRH(MIPSRH *, Bool);
220
221extern MIPSRH *MIPSRH_Imm(Bool, UShort);
222extern MIPSRH *MIPSRH_Reg(HReg);
223
224/* --------- Instructions. --------- */
225
226/*Tags for operations*/
227
228/* --------- */
229typedef enum {
230   Mun_CLO,
231   Mun_CLZ,
232   Mun_DCLO,
233   Mun_DCLZ,
234   Mun_NOP,
235} MIPSUnaryOp;
236
237extern const HChar *showMIPSUnaryOp(MIPSUnaryOp);
238/* --------- */
239
240/* --------- */
241
242typedef 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
250extern const HChar *showMIPSAluOp(MIPSAluOp,
251                            Bool /* is the 2nd operand an immediate? */ );
252
253/* --------- */
254typedef enum {
255   Mshft_INVALID,
256   Mshft_SLL, Mshft_SRL,
257   Mshft_SRA
258} MIPSShftOp;
259
260extern const HChar *showMIPSShftOp(MIPSShftOp,
261                             Bool /* is the 2nd operand an immediate? */ ,
262                             Bool /* is this a 32bit or 64bit op? */ );
263
264/* --------- */
265typedef enum {
266   Macc_ADD,
267   Macc_SUB
268} MIPSMaccOp;
269
270extern const HChar *showMIPSMaccOp(MIPSMaccOp, Bool);
271/* --------- */
272
273/* ----- Instruction tags ----- */
274typedef 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/* --------- */
326typedef 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
353extern const HChar *showMIPSFpOp(MIPSFpOp);
354
355/* Move from/to fpr to/from gpr */
356typedef 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
363extern const HChar *showMIPSFpGpMoveOp ( MIPSFpGpMoveOp );
364
365/* Move Conditional */
366typedef 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
372extern const HChar *showMIPSMoveCondOp ( MIPSMoveCondOp );
373
374/*--------- Structure for instructions ----------*/
375/* Destinations are on the LEFT (first operand) */
376
377typedef 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
614extern MIPSInstr *MIPSInstr_LI(HReg, ULong);
615extern MIPSInstr *MIPSInstr_Alu(MIPSAluOp, HReg, HReg, MIPSRH *);
616extern MIPSInstr *MIPSInstr_Shft(MIPSShftOp, Bool sz32, HReg, HReg, MIPSRH *);
617extern MIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src);
618extern MIPSInstr *MIPSInstr_Cmp(Bool, Bool, HReg, HReg, HReg, MIPSCondCode);
619
620extern MIPSInstr *MIPSInstr_Mul(Bool syned, Bool hi32, Bool sz32, HReg,
621                                HReg, HReg);
622extern MIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg, HReg);
623extern MIPSInstr *MIPSInstr_Madd(Bool, HReg, HReg);
624extern MIPSInstr *MIPSInstr_Msub(Bool, HReg, HReg);
625
626extern MIPSInstr *MIPSInstr_Load(UChar sz, HReg dst, MIPSAMode * src,
627                                 Bool mode64);
628extern MIPSInstr *MIPSInstr_Store(UChar sz, MIPSAMode * dst, HReg src,
629                                  Bool mode64);
630
631extern MIPSInstr *MIPSInstr_LoadL(UChar sz, HReg dst, MIPSAMode * src,
632                                  Bool mode64);
633extern MIPSInstr *MIPSInstr_StoreC(UChar sz, MIPSAMode * dst, HReg src,
634                                   Bool mode64);
635extern MIPSInstr *MIPSInstr_Cas(UChar sz, HReg old, HReg addr,
636                                HReg expd, HReg data, Bool mode64);
637
638extern MIPSInstr *MIPSInstr_Call ( MIPSCondCode, Addr64, UInt, HReg, RetLoc );
639extern MIPSInstr *MIPSInstr_CallAlways ( MIPSCondCode, Addr64, UInt, RetLoc );
640
641extern MIPSInstr *MIPSInstr_XDirect ( Addr64 dstGA, MIPSAMode* amPC,
642                                      MIPSCondCode cond, Bool toFastEP );
643extern MIPSInstr *MIPSInstr_XIndir(HReg dstGA, MIPSAMode* amPC,
644                                     MIPSCondCode cond);
645extern MIPSInstr *MIPSInstr_XAssisted(HReg dstGA, MIPSAMode* amPC,
646                                      MIPSCondCode cond, IRJumpKind jk);
647
648extern MIPSInstr *MIPSInstr_FpUnary(MIPSFpOp op, HReg dst, HReg src);
649extern MIPSInstr *MIPSInstr_FpBinary(MIPSFpOp op, HReg dst, HReg srcL,
650                                     HReg srcR);
651extern MIPSInstr *MIPSInstr_FpTernary ( MIPSFpOp op, HReg dst, HReg src1,
652                                        HReg src2, HReg src3 );
653extern MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src);
654extern MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL,
655                                      HReg srcR);
656extern MIPSInstr *MIPSInstr_FpMulAcc(MIPSFpOp op, HReg dst, HReg srcML,
657                                     HReg srcMR, HReg srcAcc);
658extern MIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg, MIPSAMode *);
659extern MIPSInstr *MIPSInstr_FpSTFIW(HReg addr, HReg data);
660extern MIPSInstr *MIPSInstr_FpRSP(HReg dst, HReg src);
661extern MIPSInstr *MIPSInstr_FpCftI(Bool fromI, Bool int32, HReg dst, HReg src);
662extern MIPSInstr *MIPSInstr_FpCMov(MIPSCondCode, HReg dst, HReg src);
663extern MIPSInstr *MIPSInstr_MtFCSR(HReg src);
664extern MIPSInstr *MIPSInstr_MfFCSR(HReg dst);
665extern MIPSInstr *MIPSInstr_FpCmp(HReg dst, HReg srcL, HReg srcR);
666
667extern MIPSInstr *MIPSInstr_Mfhi(HReg dst);
668extern MIPSInstr *MIPSInstr_Mflo(HReg dst);
669extern MIPSInstr *MIPSInstr_Mthi(HReg src);
670extern MIPSInstr *MIPSInstr_Mtlo(HReg src);
671
672extern MIPSInstr *MIPSInstr_RdWrLR(Bool wrLR, HReg gpr);
673
674extern MIPSInstr *MIPSInstr_MoveCond ( MIPSMoveCondOp op, HReg dst,
675                                       HReg src, HReg cond );
676
677extern MIPSInstr *MIPSInstr_FpGpMove ( MIPSFpGpMoveOp op, HReg dst, HReg src );
678
679extern MIPSInstr *MIPSInstr_EvCheck(MIPSAMode* amCounter,
680                                    MIPSAMode* amFailAddr );
681extern MIPSInstr *MIPSInstr_ProfInc( void );
682
683extern void ppMIPSInstr(const MIPSInstr *, Bool mode64);
684
685/* Some functions that insulate the register allocator from details
686   of the underlying instruction set. */
687extern void getRegUsage_MIPSInstr (HRegUsage *, const MIPSInstr *, Bool);
688extern void mapRegs_MIPSInstr     (HRegRemap *, MIPSInstr *, Bool mode64);
689extern Bool isMove_MIPSInstr      (const MIPSInstr *, HReg *, HReg *);
690extern 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
699extern void genSpill_MIPS ( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
700                            HReg rreg, Int offset, Bool);
701extern void genReload_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
702                            HReg rreg, Int offset, Bool);
703
704extern const RRegUniverse* getRRegUniverse_MIPS ( Bool mode64 );
705
706extern 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. */
721extern Int evCheckSzB_MIPS (void);
722
723/* Perform a chaining and unchaining of an XDirect jump. */
724extern 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
730extern 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. */
737extern 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