blob: 8e2d0dce67e6e134404d412b7157573c0218a8df [file] [log] [blame]
sewardj362cf842012-06-07 08:59:53 +00001
2/*---------------------------------------------------------------*/
3/*--- begin host_mips_defs.h ---*/
4/*---------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
petarjb92a9542013-02-27 22:57:17 +000010 Copyright (C) 2010-2013 RT-RK
sewardj362cf842012-06-07 08:59:53 +000011 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
florian58a637b2012-09-30 20:30:17 +000034#include "libvex_basictypes.h"
petarjb92a9542013-02-27 22:57:17 +000035#include "libvex.h" /* VexArch */
36#include "host_generic_regs.h" /* HReg */
florian58a637b2012-09-30 20:30:17 +000037
sewardj362cf842012-06-07 08:59:53 +000038/* Num registers used for function calls */
dejanjc5295552013-08-15 13:38:26 +000039#if defined(VGP_mips32_linux)
petarjb92a9542013-02-27 22:57:17 +000040/* a0, a1, a2, a3 */
sewardj362cf842012-06-07 08:59:53 +000041#define MIPS_N_REGPARMS 4
dejanjc5295552013-08-15 13:38:26 +000042#else
43/* a0, a1, a2, a3, a4, a5, a6, a7 */
44#define MIPS_N_REGPARMS 8
petarjb92a9542013-02-27 22:57:17 +000045#endif
sewardj362cf842012-06-07 08:59:53 +000046/* --------- Registers. --------- */
47
48/* The usual HReg abstraction.
49 There are 32 general purpose regs.
50*/
51
52extern void ppHRegMIPS(HReg, Bool);
53
petarjb92a9542013-02-27 22:57:17 +000054extern HReg hregMIPS_GPR0(Bool mode64); /* scratch reg / zero reg */
55extern HReg hregMIPS_GPR1(Bool mode64);
56extern HReg hregMIPS_GPR2(Bool mode64);
sewardj362cf842012-06-07 08:59:53 +000057extern 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);
petarjb92a9542013-02-27 22:57:17 +000077extern HReg hregMIPS_GPR23(Bool mode64); /* GuestStatePtr */
78extern HReg hregMIPS_GPR24(Bool mode64);
sewardj362cf842012-06-07 08:59:53 +000079extern 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
petarjb92a9542013-02-27 22:57:17 +0000147#define GuestStatePointer(_mode64) hregMIPS_GPR23(_mode64)
sewardj362cf842012-06-07 08:59:53 +0000148
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
petarjb92a9542013-02-27 22:57:17 +0000158#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)
sewardj362cf842012-06-07 08:59:53 +0000162/* a0, a1, a2, a3 */
163#define MIPS_N_ARGREGS 4
petarjb92a9542013-02-27 22:57:17 +0000164#endif
sewardj362cf842012-06-07 08:59:53 +0000165
166/* --------- Condition codes, Intel encoding. --------- */
167typedef enum {
petarjb92a9542013-02-27 22:57:17 +0000168 MIPScc_EQ = 0, /* equal */
169 MIPScc_NE = 1, /* not equal */
sewardj362cf842012-06-07 08:59:53 +0000170
petarjb92a9542013-02-27 22:57:17 +0000171 MIPScc_HS = 2, /* >=u (higher or same) */
172 MIPScc_LO = 3, /* <u (lower) */
sewardj362cf842012-06-07 08:59:53 +0000173
petarjb92a9542013-02-27 22:57:17 +0000174 MIPScc_MI = 4, /* minus (negative) */
175 MIPScc_PL = 5, /* plus (zero or +ve) */
sewardj362cf842012-06-07 08:59:53 +0000176
petarjb92a9542013-02-27 22:57:17 +0000177 MIPScc_VS = 6, /* overflow */
178 MIPScc_VC = 7, /* no overflow */
sewardj362cf842012-06-07 08:59:53 +0000179
petarjb92a9542013-02-27 22:57:17 +0000180 MIPScc_HI = 8, /* >u (higher) */
181 MIPScc_LS = 9, /* <=u (lower or same) */
sewardj362cf842012-06-07 08:59:53 +0000182
petarjb92a9542013-02-27 22:57:17 +0000183 MIPScc_GE = 10, /* >=s (signed greater or equal) */
184 MIPScc_LT = 11, /* <s (signed less than) */
sewardj362cf842012-06-07 08:59:53 +0000185
petarjb92a9542013-02-27 22:57:17 +0000186 MIPScc_GT = 12, /* >s (signed greater) */
187 MIPScc_LE = 13, /* <=s (signed less or equal) */
sewardj362cf842012-06-07 08:59:53 +0000188
petarjb92a9542013-02-27 22:57:17 +0000189 MIPScc_AL = 14, /* always (unconditional) */
190 MIPScc_NV = 15 /* never (unconditional): */
sewardj362cf842012-06-07 08:59:53 +0000191} MIPSCondCode;
192
florian55085f82012-11-21 00:36:55 +0000193extern const HChar *showMIPSCondCode(MIPSCondCode);
sewardj362cf842012-06-07 08:59:53 +0000194
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
sewardj362cf842012-06-07 08:59:53 +0000249/* --------- Instructions. --------- */
250
251/*Tags for operations*/
252
253/* --------- */
254typedef enum {
255 Mun_CLO,
256 Mun_CLZ,
petarjb92a9542013-02-27 22:57:17 +0000257 Mun_DCLO,
258 Mun_DCLZ,
sewardj362cf842012-06-07 08:59:53 +0000259 Mun_NOP,
260} MIPSUnaryOp;
261
florian55085f82012-11-21 00:36:55 +0000262extern const HChar *showMIPSUnaryOp(MIPSUnaryOp);
sewardj362cf842012-06-07 08:59:53 +0000263/* --------- */
264
265/* --------- */
266
267typedef enum {
268 Malu_INVALID,
269 Malu_ADD, Malu_SUB,
270 Malu_AND, Malu_OR, Malu_NOR, Malu_XOR,
petarjb92a9542013-02-27 22:57:17 +0000271 Malu_DADD, Malu_DSUB,
272 Malu_SLT
sewardj362cf842012-06-07 08:59:53 +0000273} MIPSAluOp;
274
florian55085f82012-11-21 00:36:55 +0000275extern const HChar *showMIPSAluOp(MIPSAluOp,
sewardj362cf842012-06-07 08:59:53 +0000276 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
florian55085f82012-11-21 00:36:55 +0000285extern const HChar *showMIPSShftOp(MIPSShftOp,
sewardj362cf842012-06-07 08:59:53 +0000286 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
florian55085f82012-11-21 00:36:55 +0000295extern const HChar *showMIPSMaccOp(MIPSMaccOp, Bool);
sewardj362cf842012-06-07 08:59:53 +0000296/* --------- */
297
298/* ----- Instruction tags ----- */
299typedef enum {
petarjb92a9542013-02-27 22:57:17 +0000300 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 */
sewardj362cf842012-06-07 08:59:53 +0000304
petarjb92a9542013-02-27 22:57:17 +0000305 Min_Cmp, /* word compare (fake insn) */
sewardj362cf842012-06-07 08:59:53 +0000306
petarjb92a9542013-02-27 22:57:17 +0000307 Min_Mul, /* widening/non-widening multiply */
308 Min_Div, /* div */
sewardj362cf842012-06-07 08:59:53 +0000309
petarjb92a9542013-02-27 22:57:17 +0000310 Min_Call, /* call to address in register */
sewardj362cf842012-06-07 08:59:53 +0000311
312 /* The following 5 insns are mandated by translation chaining */
petarjb92a9542013-02-27 22:57:17 +0000313 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 */
sewardj362cf842012-06-07 08:59:53 +0000318
petarjb92a9542013-02-27 22:57:17 +0000319 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 */
sewardj362cf842012-06-07 08:59:53 +0000325
petarjb92a9542013-02-27 22:57:17 +0000326 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 */
dejanj6ced72b2014-06-04 11:28:07 +0000328 Min_Cas, /* compare and swap */
petarjb92a9542013-02-27 22:57:17 +0000329 Min_LoadL, /* mips Load Linked Word - LL */
330 Min_StoreC, /* mips Store Conditional Word - SC */
sewardj362cf842012-06-07 08:59:53 +0000331
petarjb92a9542013-02-27 22:57:17 +0000332 Min_FpUnary, /* FP unary op */
333 Min_FpBinary, /* FP binary op */
334 Min_FpTernary, /* FP ternary op */
335 Min_FpConvert, /* FP conversion op */
336 Min_FpMulAcc, /* FP multipy-accumulate style op */
337 Min_FpLdSt, /* FP load/store */
338 Min_FpSTFIW, /* stfiwx */
339 Min_FpRSP, /* FP round IEEE754 double to IEEE754 single */
340 Min_FpCftI, /* fcfid/fctid/fctiw */
341 Min_FpCMov, /* FP floating point conditional move */
342 Min_MtFCSR, /* set FCSR register */
343 Min_MfFCSR, /* get FCSR register */
344 Min_FpCompare, /* FP compare, generating value into int reg */
345
346 Min_FpGpMove, /* Move from/to fpr to/from gpr */
347 Min_MoveCond /* Move Conditional */
sewardj362cf842012-06-07 08:59:53 +0000348} MIPSInstrTag;
349
350/* --------- */
351typedef enum {
352 Mfp_INVALID,
353
354 /* Ternary */
355 Mfp_MADDD, Mfp_MSUBD,
356 Mfp_MADDS, Mfp_MSUBS,
357
358 /* Binary */
359 Mfp_ADDD, Mfp_SUBD, Mfp_MULD, Mfp_DIVD,
petarjb92a9542013-02-27 22:57:17 +0000360 Mfp_ADDS, Mfp_SUBS, Mfp_MULS, Mfp_DIVS,
sewardj362cf842012-06-07 08:59:53 +0000361
362 /* Unary */
dejanjc3fee0d2013-07-25 09:08:03 +0000363 Mfp_SQRTS, Mfp_SQRTD,
sewardj362cf842012-06-07 08:59:53 +0000364 Mfp_ABSS, Mfp_ABSD, Mfp_NEGS, Mfp_NEGD, Mfp_MOVS, Mfp_MOVD,
petarjb92a9542013-02-27 22:57:17 +0000365
366 /* FP convert */
367 Mfp_CVTSD, Mfp_CVTSW, Mfp_CVTWD,
368 Mfp_CVTWS, Mfp_CVTDL, Mfp_CVTSL, Mfp_CVTLS, Mfp_CVTLD, Mfp_TRULS, Mfp_TRULD,
369 Mfp_TRUWS, Mfp_TRUWD, Mfp_FLOORWS, Mfp_FLOORWD, Mfp_ROUNDWS, Mfp_ROUNDWD,
dejanjf37c0862014-02-25 15:25:49 +0000370 Mfp_CVTDW, Mfp_CEILWS, Mfp_CEILWD, Mfp_CEILLS, Mfp_CEILLD, Mfp_CVTDS,
371 Mfp_ROUNDLD, Mfp_FLOORLD,
372
373 /* FP compare */
374 Mfp_CMP_UN, Mfp_CMP_EQ, Mfp_CMP_LT, Mfp_CMP_NGT
petarjb92a9542013-02-27 22:57:17 +0000375
sewardj362cf842012-06-07 08:59:53 +0000376} MIPSFpOp;
377
florian55085f82012-11-21 00:36:55 +0000378extern const HChar *showMIPSFpOp(MIPSFpOp);
sewardj362cf842012-06-07 08:59:53 +0000379
petarjb92a9542013-02-27 22:57:17 +0000380/* Move from/to fpr to/from gpr */
381typedef enum {
382 MFpGpMove_mfc1, /* Move Word From Floating Point - MIPS32 */
383 MFpGpMove_dmfc1, /* Doubleword Move from Floating Point - MIPS64 */
384 MFpGpMove_mtc1, /* Move Word to Floating Point - MIPS32 */
385 MFpGpMove_dmtc1 /* Doubleword Move to Floating Point - MIPS64 */
386} MIPSFpGpMoveOp;
387
388extern const HChar *showMIPSFpGpMoveOp ( MIPSFpGpMoveOp );
389
390/* Move Conditional */
391typedef enum {
392 MFpMoveCond_movns, /* FP Move Conditional on Not Zero - MIPS32 */
393 MFpMoveCond_movnd,
394 MMoveCond_movn /* Move Conditional on Not Zero */
395} MIPSMoveCondOp;
396
397extern const HChar *showMIPSMoveCondOp ( MIPSMoveCondOp );
398
sewardj362cf842012-06-07 08:59:53 +0000399/*--------- Structure for instructions ----------*/
400/* Destinations are on the LEFT (first operand) */
401
402typedef struct {
403 MIPSInstrTag tag;
404 union {
405 /* Get a 32/64-bit literal into a register.
406 May turn into a number of real insns. */
407 struct {
408 HReg dst;
409 ULong imm;
410 } LI;
411 /* Integer add/sub/and/or/xor. Limitations:
412 - For add, the immediate, if it exists, is a signed 16.
413 - For sub, the immediate, if it exists, is a signed 16
414 which may not be -32768, since no such instruction
415 exists, and so we have to emit addi with +32768, but
416 that is not possible.
417 - For and/or/xor, the immediate, if it exists,
418 is an unsigned 16.
419 */
420 struct {
421 MIPSAluOp op;
422 HReg dst;
423 HReg srcL;
424 MIPSRH *srcR;
425 } Alu;
426 /* Integer shl/shr/sar.
427 Limitations: the immediate, if it exists,
428 is a signed 5-bit value between 1 and 31 inclusive.
429 */
430 struct {
431 MIPSShftOp op;
432 Bool sz32; /* mode64 has both 32 and 64bit shft */
433 HReg dst;
434 HReg srcL;
435 MIPSRH *srcR;
436 } Shft;
437 /* Clz, Clo, nop */
438 struct {
439 MIPSUnaryOp op;
440 HReg dst;
441 HReg src;
442 } Unary;
443 /* Word compare. Fake instruction, used for basic block ending */
444 struct {
445 Bool syned;
446 Bool sz32;
447 HReg dst;
448 HReg srcL;
449 HReg srcR;
450
451 MIPSCondCode cond;
452 } Cmp;
453 struct {
petarjb92a9542013-02-27 22:57:17 +0000454 Bool widening; /* True => widening, False => non-widening */
455 Bool syned; /* signed/unsigned - meaningless if widenind = False */
sewardj362cf842012-06-07 08:59:53 +0000456 Bool sz32;
457 HReg dst;
458 HReg srcL;
459 HReg srcR;
460 } Mul;
461 struct {
petarjb92a9542013-02-27 22:57:17 +0000462 Bool syned; /* signed/unsigned - meaningless if widenind = False */
sewardj362cf842012-06-07 08:59:53 +0000463 Bool sz32;
464 HReg srcL;
465 HReg srcR;
466 } Div;
467 /* Pseudo-insn. Call target (an absolute address), on given
468 condition (which could be Mcc_ALWAYS). argiregs indicates
petarjb92a9542013-02-27 22:57:17 +0000469 which of $4 .. $7 (mips32) or $4 .. $11 (mips64)
sewardj362cf842012-06-07 08:59:53 +0000470 carries argument values for this call,
petarjb92a9542013-02-27 22:57:17 +0000471 using a bit mask (1<<N is set if $N holds an arg, for N in
472 $4 .. $7 or $4 .. $11 inclusive).
sewardj362cf842012-06-07 08:59:53 +0000473 If cond is != Mcc_ALWAYS, src is checked.
474 Otherwise, unconditional call */
475 struct {
476 MIPSCondCode cond;
petarjb92a9542013-02-27 22:57:17 +0000477 Addr64 target;
sewardj362cf842012-06-07 08:59:53 +0000478 UInt argiregs;
479 HReg src;
sewardjcfe046e2013-01-17 14:23:53 +0000480 RetLoc rloc; /* where the return value will be */
sewardj362cf842012-06-07 08:59:53 +0000481 } Call;
482 /* Update the guest EIP value, then exit requesting to chain
483 to it. May be conditional. Urr, use of Addr32 implicitly
484 assumes that wordsize(guest) == wordsize(host). */
485 struct {
petarjb92a9542013-02-27 22:57:17 +0000486 Addr64 dstGA; /* next guest address */
487 MIPSAMode* amPC; /* amode in guest state for PC */
488 MIPSCondCode cond; /* can be MIPScc_AL */
489 Bool toFastEP; /* chain to the slow or fast point? */
sewardj362cf842012-06-07 08:59:53 +0000490 } XDirect;
491 /* Boring transfer to a guest address not known at JIT time.
492 Not chainable. May be conditional. */
493 struct {
494 HReg dstGA;
495 MIPSAMode* amPC;
496 MIPSCondCode cond; /* can be MIPScc_AL */
497 } XIndir;
498 /* Assisted transfer to a guest address, most general case.
499 Not chainable. May be conditional. */
500 struct {
501 HReg dstGA;
502 MIPSAMode* amPC;
503 MIPSCondCode cond; /* can be MIPScc_AL */
504 IRJumpKind jk;
505 } XAssisted;
506 /* Zero extending loads. Dst size is host word size */
507 struct {
508 UChar sz; /* 1|2|4|8 */
509 HReg dst;
510 MIPSAMode *src;
511 } Load;
512 /* 64/32/16/8 bit stores */
513 struct {
514 UChar sz; /* 1|2|4|8 */
515 MIPSAMode *dst;
516 HReg src;
517 } Store;
518 struct {
519 UChar sz; /* 4|8 */
520 HReg dst;
521 MIPSAMode *src;
522 } LoadL;
523 struct {
524 UChar sz; /* 4|8 */
dejanj6ced72b2014-06-04 11:28:07 +0000525 HReg old;
526 HReg addr;
527 HReg expd;
528 HReg data;
529 } Cas;
530 struct {
531 UChar sz; /* 4|8 */
sewardj362cf842012-06-07 08:59:53 +0000532 MIPSAMode *dst;
533 HReg src;
534 } StoreC;
535 /* Move from HI/LO register to GP register. */
536 struct {
537 HReg dst;
538 } MfHL;
539
540 /* Move to HI/LO register from GP register. */
541 struct {
542 HReg src;
543 } MtHL;
544
545 /* Read/Write Link Register */
546 struct {
547 Bool wrLR;
548 HReg gpr;
549 } RdWrLR;
550
551 /* MIPS Multiply and accumulate instructions. */
552 struct {
553 MIPSMaccOp op;
554 Bool syned;
555
556 HReg srcL;
557 HReg srcR;
558 } Macc;
559
560 /* MIPS Floating point */
561 struct {
562 MIPSFpOp op;
563 HReg dst;
564 HReg src;
565 } FpUnary;
566 struct {
567 MIPSFpOp op;
568 HReg dst;
569 HReg srcL;
570 HReg srcR;
571 } FpBinary;
572 struct {
573 MIPSFpOp op;
574 HReg dst;
petarjb92a9542013-02-27 22:57:17 +0000575 HReg src1;
576 HReg src2;
577 HReg src3;
578 } FpTernary;
579 struct {
580 MIPSFpOp op;
581 HReg dst;
sewardj362cf842012-06-07 08:59:53 +0000582 HReg srcML;
583 HReg srcMR;
584 HReg srcAcc;
585 } FpMulAcc;
586 struct {
587 Bool isLoad;
588 UChar sz; /* only 4 (IEEE single) or 8 (IEEE double) */
589 HReg reg;
590 MIPSAMode *addr;
591 } FpLdSt;
592
593 struct {
594 MIPSFpOp op;
595 HReg dst;
596 HReg src;
597 } FpConvert;
598 struct {
599 MIPSFpOp op;
600 HReg dst;
601 HReg srcL;
602 HReg srcR;
603 UChar cond1;
604 } FpCompare;
sewardj362cf842012-06-07 08:59:53 +0000605 /* Move from GP register to FCSR register. */
606 struct {
607 HReg src;
608 } MtFCSR;
609 /* Move from FCSR register to GP register. */
610 struct {
611 HReg dst;
612 } MfFCSR;
613 struct {
614 MIPSAMode* amCounter;
615 MIPSAMode* amFailAddr;
616 } EvCheck;
617 struct {
618 /* No fields. The address of the counter to inc is
619 installed later, post-translation, by patching it in,
620 as it is not known at translation time. */
621 } ProfInc;
622
petarjb92a9542013-02-27 22:57:17 +0000623 /* Move from/to fpr to/from gpr */
624 struct {
625 MIPSFpGpMoveOp op;
626 HReg dst;
627 HReg src;
628 } FpGpMove;
629 struct {
630 MIPSMoveCondOp op;
631 HReg dst;
632 HReg src;
633 HReg cond;
634 } MoveCond;
635
sewardj362cf842012-06-07 08:59:53 +0000636 } Min;
637} MIPSInstr;
638
639extern MIPSInstr *MIPSInstr_LI(HReg, ULong);
640extern MIPSInstr *MIPSInstr_Alu(MIPSAluOp, HReg, HReg, MIPSRH *);
641extern MIPSInstr *MIPSInstr_Shft(MIPSShftOp, Bool sz32, HReg, HReg, MIPSRH *);
642extern MIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src);
643extern MIPSInstr *MIPSInstr_Cmp(Bool, Bool, HReg, HReg, HReg, MIPSCondCode);
644
645extern MIPSInstr *MIPSInstr_Mul(Bool syned, Bool hi32, Bool sz32, HReg,
646 HReg, HReg);
647extern MIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg, HReg);
648extern MIPSInstr *MIPSInstr_Madd(Bool, HReg, HReg);
649extern MIPSInstr *MIPSInstr_Msub(Bool, HReg, HReg);
650
651extern MIPSInstr *MIPSInstr_Load(UChar sz, HReg dst, MIPSAMode * src,
652 Bool mode64);
653extern MIPSInstr *MIPSInstr_Store(UChar sz, MIPSAMode * dst, HReg src,
654 Bool mode64);
655
656extern MIPSInstr *MIPSInstr_LoadL(UChar sz, HReg dst, MIPSAMode * src,
657 Bool mode64);
658extern MIPSInstr *MIPSInstr_StoreC(UChar sz, MIPSAMode * dst, HReg src,
659 Bool mode64);
dejanj6ced72b2014-06-04 11:28:07 +0000660extern MIPSInstr *MIPSInstr_Cas(UChar sz, HReg old, HReg addr,
661 HReg expd, HReg data, Bool mode64);
sewardj362cf842012-06-07 08:59:53 +0000662
petarjb92a9542013-02-27 22:57:17 +0000663extern MIPSInstr *MIPSInstr_Call ( MIPSCondCode, Addr64, UInt, HReg, RetLoc );
664extern MIPSInstr *MIPSInstr_CallAlways ( MIPSCondCode, Addr64, UInt, RetLoc );
sewardj362cf842012-06-07 08:59:53 +0000665
petarjb92a9542013-02-27 22:57:17 +0000666extern MIPSInstr *MIPSInstr_XDirect ( Addr64 dstGA, MIPSAMode* amPC,
667 MIPSCondCode cond, Bool toFastEP );
sewardj362cf842012-06-07 08:59:53 +0000668extern MIPSInstr *MIPSInstr_XIndir(HReg dstGA, MIPSAMode* amPC,
669 MIPSCondCode cond);
670extern MIPSInstr *MIPSInstr_XAssisted(HReg dstGA, MIPSAMode* amPC,
671 MIPSCondCode cond, IRJumpKind jk);
672
673extern MIPSInstr *MIPSInstr_FpUnary(MIPSFpOp op, HReg dst, HReg src);
674extern MIPSInstr *MIPSInstr_FpBinary(MIPSFpOp op, HReg dst, HReg srcL,
675 HReg srcR);
petarjb92a9542013-02-27 22:57:17 +0000676extern MIPSInstr *MIPSInstr_FpTernary ( MIPSFpOp op, HReg dst, HReg src1,
677 HReg src2, HReg src3 );
sewardj362cf842012-06-07 08:59:53 +0000678extern MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src);
679extern MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL,
dejanjf37c0862014-02-25 15:25:49 +0000680 HReg srcR);
sewardj362cf842012-06-07 08:59:53 +0000681extern MIPSInstr *MIPSInstr_FpMulAcc(MIPSFpOp op, HReg dst, HReg srcML,
682 HReg srcMR, HReg srcAcc);
683extern MIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg, MIPSAMode *);
684extern MIPSInstr *MIPSInstr_FpSTFIW(HReg addr, HReg data);
685extern MIPSInstr *MIPSInstr_FpRSP(HReg dst, HReg src);
686extern MIPSInstr *MIPSInstr_FpCftI(Bool fromI, Bool int32, HReg dst, HReg src);
687extern MIPSInstr *MIPSInstr_FpCMov(MIPSCondCode, HReg dst, HReg src);
688extern MIPSInstr *MIPSInstr_MtFCSR(HReg src);
689extern MIPSInstr *MIPSInstr_MfFCSR(HReg dst);
690extern MIPSInstr *MIPSInstr_FpCmp(HReg dst, HReg srcL, HReg srcR);
691
692extern MIPSInstr *MIPSInstr_Mfhi(HReg dst);
693extern MIPSInstr *MIPSInstr_Mflo(HReg dst);
694extern MIPSInstr *MIPSInstr_Mthi(HReg src);
695extern MIPSInstr *MIPSInstr_Mtlo(HReg src);
696
697extern MIPSInstr *MIPSInstr_RdWrLR(Bool wrLR, HReg gpr);
698
petarjb92a9542013-02-27 22:57:17 +0000699extern MIPSInstr *MIPSInstr_MoveCond ( MIPSMoveCondOp op, HReg dst,
700 HReg src, HReg cond );
701
702extern MIPSInstr *MIPSInstr_FpGpMove ( MIPSFpGpMoveOp op, HReg dst, HReg src );
sewardj362cf842012-06-07 08:59:53 +0000703
704extern MIPSInstr *MIPSInstr_EvCheck(MIPSAMode* amCounter,
705 MIPSAMode* amFailAddr );
706extern MIPSInstr *MIPSInstr_ProfInc( void );
707
floriand8c64e02014-10-08 08:54:44 +0000708extern void ppMIPSInstr(const MIPSInstr *, Bool mode64);
sewardj362cf842012-06-07 08:59:53 +0000709
710/* Some functions that insulate the register allocator from details
711 of the underlying instruction set. */
floriand8c64e02014-10-08 08:54:44 +0000712extern void getRegUsage_MIPSInstr (HRegUsage *, const MIPSInstr *, Bool);
713extern void mapRegs_MIPSInstr (HRegRemap *, MIPSInstr *, Bool mode64);
714extern Bool isMove_MIPSInstr (const MIPSInstr *, HReg *, HReg *);
florian8462d112014-09-24 15:18:09 +0000715extern Int emit_MIPSInstr (/*MB_MOD*/Bool* is_profInc,
floriand8c64e02014-10-08 08:54:44 +0000716 UChar* buf, Int nbuf, const MIPSInstr* i,
florian8462d112014-09-24 15:18:09 +0000717 Bool mode64,
718 VexEndness endness_host,
719 const void* disp_cp_chain_me_to_slowEP,
720 const void* disp_cp_chain_me_to_fastEP,
721 const void* disp_cp_xindir,
722 const void* disp_cp_xassisted );
sewardj362cf842012-06-07 08:59:53 +0000723
724extern void genSpill_MIPS ( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
725 HReg rreg, Int offset, Bool);
726extern void genReload_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
727 HReg rreg, Int offset, Bool);
728
729extern void getAllocableRegs_MIPS (Int *, HReg **, Bool mode64);
730extern HInstrArray *iselSB_MIPS ( IRSB*,
731 VexArch,
floriand8c64e02014-10-08 08:54:44 +0000732 const VexArchInfo*,
733 const VexAbiInfo*,
sewardj362cf842012-06-07 08:59:53 +0000734 Int offs_Host_EvC_Counter,
735 Int offs_Host_EvC_FailAddr,
736 Bool chainingAllowed,
737 Bool addProfInc,
738 Addr64 max_ga );
739
740/* How big is an event check? This is kind of a kludge because it
741 depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
742 and so assumes that they are both <= 128, and so can use the short
743 offset encoding. This is all checked with assertions, so in the
744 worst case we will merely assert at startup. */
sewardj9b769162014-07-24 12:42:03 +0000745extern Int evCheckSzB_MIPS ( VexEndness endness_host );
sewardj362cf842012-06-07 08:59:53 +0000746
747/* Perform a chaining and unchaining of an XDirect jump. */
sewardj9b769162014-07-24 12:42:03 +0000748extern VexInvalRange chainXDirect_MIPS ( VexEndness endness_host,
749 void* place_to_chain,
florian7d6f81d2014-09-22 21:43:37 +0000750 const void* disp_cp_chain_me_EXPECTED,
751 const void* place_to_jump_to,
sewardj362cf842012-06-07 08:59:53 +0000752 Bool mode64 );
753
sewardj9b769162014-07-24 12:42:03 +0000754extern VexInvalRange unchainXDirect_MIPS ( VexEndness endness_host,
755 void* place_to_unchain,
florian7d6f81d2014-09-22 21:43:37 +0000756 const void* place_to_jump_to_EXPECTED,
757 const void* disp_cp_chain_me,
sewardj362cf842012-06-07 08:59:53 +0000758 Bool mode64 );
759
760/* Patch the counter location into an existing ProfInc point. */
sewardj9b769162014-07-24 12:42:03 +0000761extern VexInvalRange patchProfInc_MIPS ( VexEndness endness_host,
762 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +0000763 const ULong* location_of_counter,
sewardj362cf842012-06-07 08:59:53 +0000764 Bool mode64 );
765
sewardj9b769162014-07-24 12:42:03 +0000766#endif /* ndef __VEX_HOST_MIPS_DEFS_H */
sewardj362cf842012-06-07 08:59:53 +0000767
768/*---------------------------------------------------------------*/
769/*--- end host-mips_defs.h ---*/
770/*---------------------------------------------------------------*/