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@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
52extern void ppHRegMIPS(HReg, Bool);
53
54extern HReg hregMIPS_GPR0(Bool mode64);  /* scratch reg / zero reg */
55extern HReg hregMIPS_GPR1(Bool mode64);
56extern HReg hregMIPS_GPR2(Bool mode64);
57extern HReg hregMIPS_GPR3(Bool mode64);
58extern HReg hregMIPS_GPR4(Bool mode64);
59extern HReg hregMIPS_GPR5(Bool mode64);
60extern HReg hregMIPS_GPR6(Bool mode64);
61extern HReg hregMIPS_GPR7(Bool mode64);
62extern HReg hregMIPS_GPR8(Bool mode64);
63extern HReg hregMIPS_GPR9(Bool mode64);
64extern HReg hregMIPS_GPR10(Bool mode64);
65extern HReg hregMIPS_GPR11(Bool mode64);
66extern HReg hregMIPS_GPR12(Bool mode64);
67extern HReg hregMIPS_GPR13(Bool mode64);
68extern HReg hregMIPS_GPR14(Bool mode64);
69extern HReg hregMIPS_GPR15(Bool mode64);
70extern HReg hregMIPS_GPR16(Bool mode64);
71extern HReg hregMIPS_GPR17(Bool mode64);
72extern HReg hregMIPS_GPR18(Bool mode64);
73extern HReg hregMIPS_GPR19(Bool mode64);
74extern HReg hregMIPS_GPR20(Bool mode64);
75extern HReg hregMIPS_GPR21(Bool mode64);
76extern HReg hregMIPS_GPR22(Bool mode64);
77extern HReg hregMIPS_GPR23(Bool mode64);  /* GuestStatePtr */
78extern HReg hregMIPS_GPR24(Bool mode64);
79extern HReg hregMIPS_GPR25(Bool mode64);
80extern HReg hregMIPS_GPR26(Bool mode64);
81extern HReg hregMIPS_GPR27(Bool mode64);
82extern HReg hregMIPS_GPR28(Bool mode64);
83extern HReg hregMIPS_GPR29(Bool mode64);
84extern HReg hregMIPS_GPR30(Bool mode64);
85extern HReg hregMIPS_GPR31(Bool mode64);
86extern HReg hregMIPS_PC(Bool mode64);
87
88extern HReg hregMIPS_HI(Bool mode64);
89extern HReg hregMIPS_LO(Bool mode64);
90
91extern HReg hregMIPS_F0(Bool mode64);
92extern HReg hregMIPS_F1(Bool mode64);
93extern HReg hregMIPS_F2(Bool mode64);
94extern HReg hregMIPS_F3(Bool mode64);
95extern HReg hregMIPS_F4(Bool mode64);
96extern HReg hregMIPS_F5(Bool mode64);
97extern HReg hregMIPS_F6(Bool mode64);
98extern HReg hregMIPS_F7(Bool mode64);
99extern HReg hregMIPS_F8(Bool mode64);
100extern HReg hregMIPS_F9(Bool mode64);
101extern HReg hregMIPS_F10(Bool mode64);
102extern HReg hregMIPS_F11(Bool mode64);
103extern HReg hregMIPS_F12(Bool mode64);
104extern HReg hregMIPS_F13(Bool mode64);
105extern HReg hregMIPS_F14(Bool mode64);
106extern HReg hregMIPS_F15(Bool mode64);
107extern HReg hregMIPS_F16(Bool mode64);
108extern HReg hregMIPS_F17(Bool mode64);
109extern HReg hregMIPS_F18(Bool mode64);
110extern HReg hregMIPS_F19(Bool mode64);
111extern HReg hregMIPS_F20(Bool mode64);
112extern HReg hregMIPS_F21(Bool mode64);
113extern HReg hregMIPS_F22(Bool mode64);
114extern HReg hregMIPS_F23(Bool mode64);
115extern HReg hregMIPS_F24(Bool mode64);
116extern HReg hregMIPS_F25(Bool mode64);
117extern HReg hregMIPS_F26(Bool mode64);
118extern HReg hregMIPS_F27(Bool mode64);
119extern HReg hregMIPS_F28(Bool mode64);
120extern HReg hregMIPS_F29(Bool mode64);
121extern HReg hregMIPS_F30(Bool mode64);
122extern HReg hregMIPS_F31(Bool mode64);
123extern HReg hregMIPS_FIR(void);
124extern HReg hregMIPS_FCCR(void);
125extern HReg hregMIPS_FEXR(void);
126extern HReg hregMIPS_FENR(void);
127extern HReg hregMIPS_FCSR(void);
128extern HReg hregMIPS_COND(void);
129
130extern HReg hregMIPS_D0(void);
131extern HReg hregMIPS_D1(void);
132extern HReg hregMIPS_D2(void);
133extern HReg hregMIPS_D3(void);
134extern HReg hregMIPS_D4(void);
135extern HReg hregMIPS_D5(void);
136extern HReg hregMIPS_D6(void);
137extern HReg hregMIPS_D7(void);
138extern HReg hregMIPS_D8(void);
139extern HReg hregMIPS_D9(void);
140extern HReg hregMIPS_D10(void);
141extern HReg hregMIPS_D11(void);
142extern HReg hregMIPS_D12(void);
143extern HReg hregMIPS_D13(void);
144extern HReg hregMIPS_D14(void);
145extern 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. --------- */
167typedef 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
193extern const HChar *showMIPSCondCode(MIPSCondCode);
194
195/* --------- Memory address expressions (amodes). --------- */
196typedef enum {
197   Mam_IR,        /* Immediate (signed 16-bit) + Reg */
198   Mam_RR         /* Reg1 + Reg2 */
199} MIPSAModeTag;
200
201typedef 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
215extern MIPSAMode *MIPSAMode_IR(Int, HReg);
216extern MIPSAMode *MIPSAMode_RR(HReg, HReg);
217
218extern MIPSAMode *dopyMIPSAMode(MIPSAMode *);
219extern MIPSAMode *nextMIPSAModeFloat(MIPSAMode *);
220extern MIPSAMode *nextMIPSAModeInt(MIPSAMode *);
221
222extern void ppMIPSAMode(MIPSAMode *, Bool);
223
224/* --------- Operand, which can be a reg or a u16/s16. --------- */
225/* ("RH" == "Register or Halfword immediate") */
226typedef enum {
227   Mrh_Imm,
228   Mrh_Reg
229} MIPSRHTag;
230
231typedef 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
244extern void ppMIPSRH(MIPSRH *, Bool);
245
246extern MIPSRH *MIPSRH_Imm(Bool, UShort);
247extern MIPSRH *MIPSRH_Reg(HReg);
248
249/* --------- Instructions. --------- */
250
251/*Tags for operations*/
252
253/* --------- */
254typedef enum {
255   Mun_CLO,
256   Mun_CLZ,
257   Mun_DCLO,
258   Mun_DCLZ,
259   Mun_NOP,
260} MIPSUnaryOp;
261
262extern const HChar *showMIPSUnaryOp(MIPSUnaryOp);
263/* --------- */
264
265/* --------- */
266
267typedef 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
275extern const HChar *showMIPSAluOp(MIPSAluOp,
276                            Bool /* is the 2nd operand an immediate? */ );
277
278/* --------- */
279typedef enum {
280   Mshft_INVALID,
281   Mshft_SLL, Mshft_SRL,
282   Mshft_SRA
283} MIPSShftOp;
284
285extern const HChar *showMIPSShftOp(MIPSShftOp,
286                             Bool /* is the 2nd operand an immediate? */ ,
287                             Bool /* is this a 32bit or 64bit op? */ );
288
289/* --------- */
290typedef enum {
291   Macc_ADD,
292   Macc_SUB
293} MIPSMaccOp;
294
295extern const HChar *showMIPSMaccOp(MIPSMaccOp, Bool);
296/* --------- */
297
298/* ----- Instruction tags ----- */
299typedef 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/* --------- */
350typedef 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
377extern const HChar *showMIPSFpOp(MIPSFpOp);
378
379/* Move from/to fpr to/from gpr */
380typedef 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
387extern const HChar *showMIPSFpGpMoveOp ( MIPSFpGpMoveOp );
388
389/* Move Conditional */
390typedef 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
396extern const HChar *showMIPSMoveCondOp ( MIPSMoveCondOp );
397
398/*--------- Structure for instructions ----------*/
399/* Destinations are on the LEFT (first operand) */
400
401typedef 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
631extern MIPSInstr *MIPSInstr_LI(HReg, ULong);
632extern MIPSInstr *MIPSInstr_Alu(MIPSAluOp, HReg, HReg, MIPSRH *);
633extern MIPSInstr *MIPSInstr_Shft(MIPSShftOp, Bool sz32, HReg, HReg, MIPSRH *);
634extern MIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src);
635extern MIPSInstr *MIPSInstr_Cmp(Bool, Bool, HReg, HReg, HReg, MIPSCondCode);
636
637extern MIPSInstr *MIPSInstr_Mul(Bool syned, Bool hi32, Bool sz32, HReg,
638                                HReg, HReg);
639extern MIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg, HReg);
640extern MIPSInstr *MIPSInstr_Madd(Bool, HReg, HReg);
641extern MIPSInstr *MIPSInstr_Msub(Bool, HReg, HReg);
642
643extern MIPSInstr *MIPSInstr_Load(UChar sz, HReg dst, MIPSAMode * src,
644                                 Bool mode64);
645extern MIPSInstr *MIPSInstr_Store(UChar sz, MIPSAMode * dst, HReg src,
646                                  Bool mode64);
647
648extern MIPSInstr *MIPSInstr_LoadL(UChar sz, HReg dst, MIPSAMode * src,
649                                  Bool mode64);
650extern MIPSInstr *MIPSInstr_StoreC(UChar sz, MIPSAMode * dst, HReg src,
651                                   Bool mode64);
652
653extern MIPSInstr *MIPSInstr_Call ( MIPSCondCode, Addr64, UInt, HReg, RetLoc );
654extern MIPSInstr *MIPSInstr_CallAlways ( MIPSCondCode, Addr64, UInt, RetLoc );
655
656extern MIPSInstr *MIPSInstr_XDirect ( Addr64 dstGA, MIPSAMode* amPC,
657                                      MIPSCondCode cond, Bool toFastEP );
658extern MIPSInstr *MIPSInstr_XIndir(HReg dstGA, MIPSAMode* amPC,
659                                     MIPSCondCode cond);
660extern MIPSInstr *MIPSInstr_XAssisted(HReg dstGA, MIPSAMode* amPC,
661                                      MIPSCondCode cond, IRJumpKind jk);
662
663extern MIPSInstr *MIPSInstr_FpUnary(MIPSFpOp op, HReg dst, HReg src);
664extern MIPSInstr *MIPSInstr_FpBinary(MIPSFpOp op, HReg dst, HReg srcL,
665                                     HReg srcR);
666extern MIPSInstr *MIPSInstr_FpTernary ( MIPSFpOp op, HReg dst, HReg src1,
667                                        HReg src2, HReg src3 );
668extern MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src);
669extern MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL,
670                                      HReg srcR);
671extern MIPSInstr *MIPSInstr_FpMulAcc(MIPSFpOp op, HReg dst, HReg srcML,
672                                     HReg srcMR, HReg srcAcc);
673extern MIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg, MIPSAMode *);
674extern MIPSInstr *MIPSInstr_FpSTFIW(HReg addr, HReg data);
675extern MIPSInstr *MIPSInstr_FpRSP(HReg dst, HReg src);
676extern MIPSInstr *MIPSInstr_FpCftI(Bool fromI, Bool int32, HReg dst, HReg src);
677extern MIPSInstr *MIPSInstr_FpCMov(MIPSCondCode, HReg dst, HReg src);
678extern MIPSInstr *MIPSInstr_MtFCSR(HReg src);
679extern MIPSInstr *MIPSInstr_MfFCSR(HReg dst);
680extern MIPSInstr *MIPSInstr_FpCmp(HReg dst, HReg srcL, HReg srcR);
681
682extern MIPSInstr *MIPSInstr_Mfhi(HReg dst);
683extern MIPSInstr *MIPSInstr_Mflo(HReg dst);
684extern MIPSInstr *MIPSInstr_Mthi(HReg src);
685extern MIPSInstr *MIPSInstr_Mtlo(HReg src);
686
687extern MIPSInstr *MIPSInstr_RdWrLR(Bool wrLR, HReg gpr);
688
689extern MIPSInstr *MIPSInstr_MoveCond ( MIPSMoveCondOp op, HReg dst,
690                                       HReg src, HReg cond );
691
692extern MIPSInstr *MIPSInstr_FpGpMove ( MIPSFpGpMoveOp op, HReg dst, HReg src );
693
694extern MIPSInstr *MIPSInstr_EvCheck(MIPSAMode* amCounter,
695                                    MIPSAMode* amFailAddr );
696extern MIPSInstr *MIPSInstr_ProfInc( void );
697
698extern void ppMIPSInstr(MIPSInstr *, Bool mode64);
699
700/* Some functions that insulate the register allocator from details
701   of the underlying instruction set. */
702extern void       getRegUsage_MIPSInstr (HRegUsage *, MIPSInstr *, Bool);
703extern void       mapRegs_MIPSInstr     (HRegRemap *, MIPSInstr *, Bool mode64);
704extern Bool       isMove_MIPSInstr      (MIPSInstr *, HReg *, HReg *);
705extern 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
713extern void genSpill_MIPS ( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
714                            HReg rreg, Int offset, Bool);
715extern void genReload_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
716                            HReg rreg, Int offset, Bool);
717
718extern void        getAllocableRegs_MIPS (Int *, HReg **, Bool mode64);
719extern 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. */
734extern Int evCheckSzB_MIPS ( void );
735
736/* Perform a chaining and unchaining of an XDirect jump. */
737extern VexInvalRange chainXDirect_MIPS ( void* place_to_chain,
738                                         void* disp_cp_chain_me_EXPECTED,
739                                         void* place_to_jump_to,
740                                         Bool  mode64 );
741
742extern 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. */
748extern 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