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