2 /*---------------------------------------------------------------*/
3 /*--- begin mips_defs.h ---*/
4 /*---------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2017-2019 RT-RK
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, see <http://www.gnu.org/licenses/>.
25 The GNU General Public License is contained in the file COPYING.
27 #ifndef __VEX_MIPS_DEFS_H
28 #define __VEX_MIPS_DEFS_H
30 #include "libvex_basictypes.h"
31 #include "libvex_ir.h"
34 /* MOD: The IRSB* into which we're generating code. */
37 /* Is our guest binary 32 or 64bit? Set at each call to
38 disInstr_MIPS below. */
41 /* Pointer to the guest code area. */
42 extern const UChar
*guest_code
;
44 /*------------------------------------------------------------*/
45 /*--- DSP to IR function ---*/
46 /*------------------------------------------------------------*/
48 UInt
disDSPInstr_MIPS_WRK ( UInt
);
50 /*------------------------------------------------------------*/
51 /*--- Debugging output ---*/
52 /*------------------------------------------------------------*/
54 #define DIP(format, args...) \
55 if (vex_traceflags & VEX_TRACE_FE) \
56 vex_printf(format, ## args)
58 /* ------------ MIPS32 DSP ASE(r2) accumulators ------------- */
60 extern UInt
accumulatorGuestRegOffset( UInt
);
62 /*------------------------------------------------------------*/
63 /*--- Helper bits and pieces for creating IR fragments. ---*/
64 /*------------------------------------------------------------*/
66 static inline IRExpr
*mkU8(UInt i
)
69 return IRExpr_Const(IRConst_U8((UChar
) i
));
72 /* Create an expression node for a 16-bit integer constant. */
73 static inline IRExpr
*mkU16(UInt i
)
75 return IRExpr_Const(IRConst_U16(i
));
78 /* Create an expression node for a 32-bit integer constant. */
79 static inline IRExpr
*mkU32(UInt i
)
81 return IRExpr_Const(IRConst_U32(i
));
84 /* Create an expression node for a 64-bit integer constant. */
85 static inline IRExpr
*mkU64(ULong i
)
87 return IRExpr_Const(IRConst_U64(i
));
90 static inline IRExpr
*mkexpr(IRTemp tmp
)
92 return IRExpr_RdTmp(tmp
);
95 static inline IRExpr
*unop(IROp op
, IRExpr
* a
)
97 return IRExpr_Unop(op
, a
);
100 static inline IRExpr
*binop(IROp op
, IRExpr
* a1
, IRExpr
* a2
)
102 return IRExpr_Binop(op
, a1
, a2
);
105 static inline IRExpr
*triop(IROp op
, IRExpr
* a1
, IRExpr
* a2
, IRExpr
* a3
)
107 return IRExpr_Triop(op
, a1
, a2
, a3
);
110 static inline IRExpr
*qop ( IROp op
, IRExpr
* a1
, IRExpr
* a2
, IRExpr
* a3
,
113 return IRExpr_Qop(op
, a1
, a2
, a3
, a4
);
116 static inline IRExpr
*load(IRType ty
, IRExpr
* addr
)
118 IRExpr
*load1
= NULL
;
119 #if defined (_MIPSEL)
120 load1
= IRExpr_Load(Iend_LE
, ty
, addr
);
121 #elif defined (_MIPSEB)
122 load1
= IRExpr_Load(Iend_BE
, ty
, addr
);
127 /* Add a statement to the list held by "irsb". */
128 static inline void stmt(IRStmt
* st
)
130 addStmtToIRSB(irsb
, st
);
133 static inline void assign(IRTemp dst
, IRExpr
* e
)
135 stmt(IRStmt_WrTmp(dst
, e
));
138 static inline void store(IRExpr
* addr
, IRExpr
* data
)
140 #if defined (_MIPSEL)
141 stmt(IRStmt_Store(Iend_LE
, addr
, data
));
142 #elif defined (_MIPSEB)
143 stmt(IRStmt_Store(Iend_BE
, addr
, data
));
147 /* Generate a new temporary of the given type. */
148 static inline IRTemp
newTemp(IRType ty
)
150 vassert(isPlausibleIRType(ty
));
151 return newIRTemp(irsb
->tyenv
, ty
);
154 static inline UShort
extend_s_9to16(UInt x
)
156 return (UShort
) ((((Int
) x
) << 23) >> 23);
159 static inline UShort
extend_s_10to16(UInt x
)
161 return (UShort
) ((((Int
) x
) << 22) >> 22);
164 static inline UInt
extend_s_10to32(UInt x
)
166 return (UInt
)((((Int
) x
) << 22) >> 22);
169 static inline ULong
extend_s_10to64(UInt x
)
171 return (ULong
)((((Long
) x
) << 54) >> 54);
174 static inline UInt
extend_s_16to32(UInt x
)
176 return (UInt
) ((((Int
) x
) << 16) >> 16);
179 static inline UInt
extend_s_18to32(UInt x
)
181 return (UInt
) ((((Int
) x
) << 14) >> 14);
184 static inline UInt
extend_s_19to32(UInt x
)
186 return (UInt
) ((((Int
) x
) << 13) >> 13);
189 static inline UInt
extend_s_23to32(UInt x
)
191 return (UInt
) ((((Int
) x
) << 9) >> 9);
194 static inline UInt
extend_s_26to32(UInt x
)
196 return (UInt
) ((((Int
) x
) << 6) >> 6);
199 static inline ULong
extend_s_16to64 ( UInt x
)
201 return (ULong
) ((((Long
) x
) << 48) >> 48);
204 static inline ULong
extend_s_18to64 ( UInt x
)
206 return (ULong
) ((((Long
) x
) << 46) >> 46);
209 static inline ULong
extend_s_19to64(UInt x
)
211 return (ULong
) ((((Long
) x
) << 45) >> 45);
214 static inline ULong
extend_s_23to64(UInt x
)
216 return (ULong
) ((((Long
) x
) << 41) >> 41);
219 static inline ULong
extend_s_26to64(UInt x
)
221 return (ULong
) ((((Long
) x
) << 38) >> 38);
224 static inline ULong
extend_s_32to64 ( UInt x
)
226 return (ULong
) ((((Long
) x
) << 32) >> 32);
229 extern IRExpr
*getIReg(UInt
);
231 extern void putIReg(UInt
, IRExpr
*);
233 /* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
234 This function should be called before any other operation if widening
235 multiplications are used. */
236 extern IRExpr
*getAcc(UInt acNo
);
238 extern IRExpr
*getDSPControl(void);
240 extern IRExpr
*mkNarrowTo32(IRType
, IRExpr
*);
242 extern void putLO(IRExpr
*);
244 extern void putHI(IRExpr
*);
246 /*------------------------------------------------------------*/
247 /*--- Field helpers ---*/
248 /*------------------------------------------------------------*/
250 static inline UInt
get_opcode(UInt mipsins
)
252 return (0xFC000000 & mipsins
) >> 26;
255 static inline UInt
get_rs(UInt mipsins
)
257 return (0x03E00000 & mipsins
) >> 21;
260 static inline UInt
get_rt(UInt mipsins
)
262 return (0x001F0000 & mipsins
) >> 16;
265 static inline UInt
get_imm(UInt mipsins
)
267 return (0x0000FFFF & mipsins
);
270 static inline UInt
get_instr_index(UInt mipsins
)
272 return (0x03FFFFFF & mipsins
);
275 static inline UInt
get_rd(UInt mipsins
)
277 return (0x0000F800 & mipsins
) >> 11;
280 static inline UInt
get_sa(UInt mipsins
)
282 return (0x000007C0 & mipsins
) >> 6;
285 static inline UInt
get_function(UInt mipsins
)
287 return (0x0000003F & mipsins
);
290 static inline UInt
get_ft(UInt mipsins
)
292 return (0x001F0000 & mipsins
) >> 16;
295 static inline UInt
get_fs(UInt mipsins
)
297 return (0x0000F800 & mipsins
) >> 11;
300 static inline UInt
get_fd(UInt mipsins
)
302 return (0x000007C0 & mipsins
) >> 6;
305 static inline UInt
get_mov_cc(UInt mipsins
)
307 return (0x001C0000 & mipsins
) >> 18;
310 static inline UInt
get_bc1_cc(UInt mipsins
)
312 return (0x001C0000 & mipsins
) >> 18;
315 static inline UInt
get_fpc_cc(UInt mipsins
)
317 return (0x00000700 & mipsins
) >> 8;
320 static inline UInt
get_tf(UInt mipsins
)
322 return (0x00010000 & mipsins
) >> 16;
325 static inline UInt
get_nd(UInt mipsins
)
327 return (0x00020000 & mipsins
) >> 17;
330 static inline UInt
get_fmt(UInt mipsins
)
332 return (0x03E00000 & mipsins
) >> 21;
335 static inline UInt
get_FC(UInt mipsins
)
337 return (0x000000F0 & mipsins
) >> 4;
340 static inline UInt
get_cond(UInt mipsins
)
342 return (0x0000000F & mipsins
);
345 /* for break & syscall */
346 static inline UInt
get_code(UInt mipsins
)
348 return (0xFFC0 & mipsins
) >> 6;
351 static inline UInt
get_lsb(UInt mipsins
)
353 return (0x7C0 & mipsins
) >> 6;
356 static inline UInt
get_msb(UInt mipsins
)
358 return (0x0000F800 & mipsins
) >> 11;
361 static inline UInt
get_rot(UInt mipsins
)
363 return (0x00200000 & mipsins
) >> 21;
366 static inline UInt
get_rotv(UInt mipsins
)
368 return (0x00000040 & mipsins
) >> 6;
371 static inline UInt
get_sel(UInt mipsins
)
373 return (0x00000007 & mipsins
);
376 /* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
377 except for MFHI and MFLO. */
378 static inline UInt
get_acNo(UInt mipsins
)
380 return (0x00001800 & mipsins
) >> 11;
383 /* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
384 static inline UInt
get_acNo_mfhilo(UInt mipsins
)
386 return (0x00600000 & mipsins
) >> 21;
389 /* Get mask field (helper function for wrdsp instruction). */
390 static inline UInt
get_wrdspMask(UInt mipsins
)
392 return (0x001ff800 & mipsins
) >> 11;
395 /* Get mask field (helper function for rddsp instruction). */
396 static inline UInt
get_rddspMask(UInt mipsins
)
398 return (0x03ff0000 & mipsins
) >> 16;
401 /* Get shift field (helper function for DSP ASE instructions). */
402 static inline UInt
get_shift(UInt mipsins
)
404 return (0x03f00000 & mipsins
) >> 20;
407 /* Get immediate field for DSP ASE instructions. */
408 static inline UInt
get_dspImm(UInt mipsins
)
410 return (0x03ff0000 & mipsins
) >> 16;
416 /*---------------------------------------------------------------*/
417 /*--- end mips_defs.h ---*/
418 /*---------------------------------------------------------------*/