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