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
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 /* 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
135 extern void ppHRegMIPS ( HReg, Bool );
136
137
138 /* --------- Condition codes, Intel encoding. --------- */
139 typedef 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
165 extern const HChar *showMIPSCondCode(MIPSCondCode);
166
167 /* --------- Memory address expressions (amodes). --------- */
168 typedef enum {
169 Mam_IR, /* Immediate (signed 16-bit) + Reg */
170 Mam_RR /* Reg1 + Reg2 */
171 } MIPSAModeTag;
172
173 typedef 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
187 extern MIPSAMode *MIPSAMode_IR(Int, HReg);
188 extern MIPSAMode *MIPSAMode_RR(HReg, HReg);
189
190 extern MIPSAMode *dopyMIPSAMode(MIPSAMode *);
191 extern MIPSAMode *nextMIPSAModeFloat(MIPSAMode *);
192 extern MIPSAMode *nextMIPSAModeInt(MIPSAMode *);
193
194 extern void ppMIPSAMode(MIPSAMode *, Bool);
195
196 /* --------- Operand, which can be a reg or a u16/s16. --------- */
197 /* ("RH" == "Register or Halfword immediate") */
198 typedef enum {
199 Mrh_Imm,
200 Mrh_Reg
201 } MIPSRHTag;
202
203 typedef 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
216 extern void ppMIPSRH(MIPSRH *, Bool);
217
218 extern MIPSRH *MIPSRH_Imm(Bool, UShort);
219 extern MIPSRH *MIPSRH_Reg(HReg);
220
221 /* --------- Instructions. --------- */
222
223 /*Tags for operations*/
224
225 /* --------- */
226 typedef enum {
227 Mun_CLO,
228 Mun_CLZ,
229 Mun_DCLO,
230 Mun_DCLZ,
231 Mun_NOP,
232 } MIPSUnaryOp;
233
234 extern const HChar *showMIPSUnaryOp(MIPSUnaryOp);
235 /* --------- */
236
237 /* --------- */
238
239 typedef 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
247 extern const HChar *showMIPSAluOp(MIPSAluOp,
248 Bool /* is the 2nd operand an immediate? */ );
249
250 /* --------- */
251 typedef enum {
252 Mshft_INVALID,
253 Mshft_SLL, Mshft_SRL,
254 Mshft_SRA
255 } MIPSShftOp;
256
257 extern const HChar *showMIPSShftOp(MIPSShftOp,
258 Bool /* is the 2nd operand an immediate? */ ,
259 Bool /* is this a 32bit or 64bit op? */ );
260
261 /* --------- */
262 typedef enum {
263 Macc_ADD,
264 Macc_SUB
265 } MIPSMaccOp;
266
267 extern const HChar *showMIPSMaccOp(MIPSMaccOp, Bool);
268 /* --------- */
269
270 /* ----- Instruction tags ----- */
271 typedef 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 /* --------- */
323 typedef 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
350 extern const HChar *showMIPSFpOp(MIPSFpOp);
351
352 /* Move from/to fpr to/from gpr */
353 typedef 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
360 extern const HChar *showMIPSFpGpMoveOp ( MIPSFpGpMoveOp );
361
362 /* Move Conditional */
363 typedef 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
369 extern const HChar *showMIPSMoveCondOp ( MIPSMoveCondOp );
370
371 /*--------- Structure for instructions ----------*/
372 /* Destinations are on the LEFT (first operand) */
373
374 typedef 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
611 extern MIPSInstr *MIPSInstr_LI(HReg, ULong);
612 extern MIPSInstr *MIPSInstr_Alu(MIPSAluOp, HReg, HReg, MIPSRH *);
613 extern MIPSInstr *MIPSInstr_Shft(MIPSShftOp, Bool sz32, HReg, HReg, MIPSRH *);
614 extern MIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src);
615 extern MIPSInstr *MIPSInstr_Cmp(Bool, Bool, HReg, HReg, HReg, MIPSCondCode);
616
617 extern MIPSInstr *MIPSInstr_Mul(Bool syned, Bool hi32, Bool sz32, HReg,
618 HReg, HReg);
619 extern MIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg, HReg);
620 extern MIPSInstr *MIPSInstr_Madd(Bool, HReg, HReg);
621 extern MIPSInstr *MIPSInstr_Msub(Bool, HReg, HReg);
622
623 extern MIPSInstr *MIPSInstr_Load(UChar sz, HReg dst, MIPSAMode * src,
624 Bool mode64);
625 extern MIPSInstr *MIPSInstr_Store(UChar sz, MIPSAMode * dst, HReg src,
626 Bool mode64);
627
628 extern MIPSInstr *MIPSInstr_LoadL(UChar sz, HReg dst, MIPSAMode * src,
629 Bool mode64);
630 extern MIPSInstr *MIPSInstr_StoreC(UChar sz, MIPSAMode * dst, HReg src,
631 Bool mode64);
632 extern MIPSInstr *MIPSInstr_Cas(UChar sz, HReg old, HReg addr,
633 HReg expd, HReg data, Bool mode64);
634
635 extern MIPSInstr *MIPSInstr_Call ( MIPSCondCode, Addr64, UInt, HReg, RetLoc );
636 extern MIPSInstr *MIPSInstr_CallAlways ( MIPSCondCode, Addr64, UInt, RetLoc );
637
638 extern MIPSInstr *MIPSInstr_XDirect ( Addr64 dstGA, MIPSAMode* amPC,
639 MIPSCondCode cond, Bool toFastEP );
640 extern MIPSInstr *MIPSInstr_XIndir(HReg dstGA, MIPSAMode* amPC,
641 MIPSCondCode cond);
642 extern MIPSInstr *MIPSInstr_XAssisted(HReg dstGA, MIPSAMode* amPC,
643 MIPSCondCode cond, IRJumpKind jk);
644
645 extern MIPSInstr *MIPSInstr_FpUnary(MIPSFpOp op, HReg dst, HReg src);
646 extern MIPSInstr *MIPSInstr_FpBinary(MIPSFpOp op, HReg dst, HReg srcL,
647 HReg srcR);
648 extern MIPSInstr *MIPSInstr_FpTernary ( MIPSFpOp op, HReg dst, HReg src1,
649 HReg src2, HReg src3 );
650 extern MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src);
651 extern MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL,
652 HReg srcR);
653 extern MIPSInstr *MIPSInstr_FpMulAcc(MIPSFpOp op, HReg dst, HReg srcML,
654 HReg srcMR, HReg srcAcc);
655 extern MIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg, MIPSAMode *);
656 extern MIPSInstr *MIPSInstr_FpSTFIW(HReg addr, HReg data);
657 extern MIPSInstr *MIPSInstr_FpRSP(HReg dst, HReg src);
658 extern MIPSInstr *MIPSInstr_FpCftI(Bool fromI, Bool int32, HReg dst, HReg src);
659 extern MIPSInstr *MIPSInstr_FpCMov(MIPSCondCode, HReg dst, HReg src);
660 extern MIPSInstr *MIPSInstr_MtFCSR(HReg src);
661 extern MIPSInstr *MIPSInstr_MfFCSR(HReg dst);
662 extern MIPSInstr *MIPSInstr_FpCmp(HReg dst, HReg srcL, HReg srcR);
663
664 extern MIPSInstr *MIPSInstr_Mfhi(HReg dst);
665 extern MIPSInstr *MIPSInstr_Mflo(HReg dst);
666 extern MIPSInstr *MIPSInstr_Mthi(HReg src);
667 extern MIPSInstr *MIPSInstr_Mtlo(HReg src);
668
669 extern MIPSInstr *MIPSInstr_RdWrLR(Bool wrLR, HReg gpr);
670
671 extern MIPSInstr *MIPSInstr_MoveCond ( MIPSMoveCondOp op, HReg dst,
672 HReg src, HReg cond );
673
674 extern MIPSInstr *MIPSInstr_FpGpMove ( MIPSFpGpMoveOp op, HReg dst, HReg src );
675
676 extern MIPSInstr *MIPSInstr_EvCheck(MIPSAMode* amCounter,
677 MIPSAMode* amFailAddr );
678 extern MIPSInstr *MIPSInstr_ProfInc( void );
679
680 extern void ppMIPSInstr(const MIPSInstr *, Bool mode64);
681
682 /* Some functions that insulate the register allocator from details
683 of the underlying instruction set. */
684 extern void getRegUsage_MIPSInstr (HRegUsage *, const MIPSInstr *, Bool);
685 extern void mapRegs_MIPSInstr (HRegRemap *, MIPSInstr *, Bool mode64);
686 extern Bool isMove_MIPSInstr (const MIPSInstr *, HReg *, HReg *);
687 extern 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
696 extern void genSpill_MIPS ( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
697 HReg rreg, Int offset, Bool);
698 extern void genReload_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
699 HReg rreg, Int offset, Bool);
700
701 extern const RRegUniverse* getRRegUniverse_MIPS ( Bool mode64 );
702
703 extern 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. */
718 extern Int evCheckSzB_MIPS (void);
719
720 /* Perform a chaining and unchaining of an XDirect jump. */
721 extern 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
727 extern 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. */
734 extern 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