1 /* radare - LGPL - Copyright 2010-2015 - pancake */
2 
3 #include <string.h>
4 #include <r_types.h>
5 #include <r_lib.h>
6 #include <r_asm.h>
7 #include <r_anal.h>
8 
9 
10 static ut64 t9_pre = UT64_MAX;
11 #define REG_BUF_MAX 32
12 // ESIL macros:
13 
14 // put the sign bit on the stack
15 #define ES_IS_NEGATIVE(arg) "1,"arg",<<<,1,&"
16 
17 #define ES_B(x) "0xff,"x",&"
18 #define ES_H(x) "0xffff,"x",&"
19 #define ES_W(x) "0xffffffff,"x",&"
20 // call with delay slot
21 #define ES_CALL_DR(ra, addr) "pc,4,+,"ra",=,"ES_J(addr)
22 #define ES_CALL_D(addr) ES_CALL_DR("ra", addr)
23 
24 // call without delay slot
25 #define ES_CALL_NDR(ra, addr) "pc,"ra",=,"ES_J(addr)
26 #define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr)
27 
28 #define USE_DS 0
29 #if USE_DS
30 // emit ERR trap if executed in a delay slot
31 #define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,},"
32 // jump to address
33 #define ES_J(addr) addr",SETJT,1,SETD"
34 #else
35 #define ES_TRAP_DS() ""
36 #define ES_J(addr) addr",pc,="
37 #endif
38 
39 #define ES_SIGN32_64(arg)	es_sign_n_64 (a, op, arg, 32)
40 #define ES_SIGN16_64(arg)	es_sign_n_64 (a, op, arg, 16)
41 
42 #define ES_ADD_CK32_OVERF(x, y, z) es_add_ck (op, x, y, z, 32)
43 #define ES_ADD_CK64_OVERF(x, y, z) es_add_ck (op, x, y, z, 64)
44 
es_sign_n_64(RAnal * a,RAnalOp * op,const char * arg,int bit)45 static inline void es_sign_n_64(RAnal *a, RAnalOp *op, const char *arg, int bit)
46 {
47 	if (a->bits == 64) {
48 		r_strbuf_appendf (&op->esil, ",%d,%s,~,%s,=,", bit, arg, arg);
49 	} else {
50 		r_strbuf_append (&op->esil,",");
51 	}
52 }
53 
es_add_ck(RAnalOp * op,const char * a1,const char * a2,const char * re,int bit)54 static inline void es_add_ck(RAnalOp *op, const char *a1, const char *a2, const char *re, int bit)
55 {
56 	ut64 mask = 1ULL << (bit-1);
57 	r_strbuf_appendf (&op->esil,
58 		"%d,0x%" PFMT64x ",%s,%s,^,&,>>,%d,0x%" PFMT64x ",%s,%s,+,&,>>,|,1,==,$z,?{,$$,1,TRAP,}{,%s,%s,+,%s,=,}",
59 		bit-2, mask, a1, a2, bit-1, mask, a1, a2, a1, a2, re);
60 }
61 // MIPS instruction
62 typedef enum mips_insn {
63 	MIPS_INS_INVALID = 0,
64 
65 	MIPS_INS_ABSQ_S,
66 	MIPS_INS_ADD,
67 	MIPS_INS_ADDIUPC,
68 	MIPS_INS_ADDIUR1SP,
69 	MIPS_INS_ADDIUR2,
70 	MIPS_INS_ADDIUS5,
71 	MIPS_INS_ADDIUSP,
72 	MIPS_INS_ADDQH,
73 	MIPS_INS_ADDQH_R,
74 	MIPS_INS_ADDQ,
75 	MIPS_INS_ADDQ_S,
76 	MIPS_INS_ADDSC,
77 	MIPS_INS_ADDS_A,
78 	MIPS_INS_ADDS_S,
79 	MIPS_INS_ADDS_U,
80 	MIPS_INS_ADDU16,
81 	MIPS_INS_ADDUH,
82 	MIPS_INS_ADDUH_R,
83 	MIPS_INS_ADDU,
84 	MIPS_INS_ADDU_S,
85 	MIPS_INS_ADDVI,
86 	MIPS_INS_ADDV,
87 	MIPS_INS_ADDWC,
88 	MIPS_INS_ADD_A,
89 	MIPS_INS_ADDI,
90 	MIPS_INS_ADDIU,
91 	MIPS_INS_ALIGN,
92 	MIPS_INS_ALUIPC,
93 	MIPS_INS_AND,
94 	MIPS_INS_AND16,
95 	MIPS_INS_ANDI16,
96 	MIPS_INS_ANDI,
97 	MIPS_INS_APPEND,
98 	MIPS_INS_ASUB_S,
99 	MIPS_INS_ASUB_U,
100 	MIPS_INS_AUI,
101 	MIPS_INS_AUIPC,
102 	MIPS_INS_AVER_S,
103 	MIPS_INS_AVER_U,
104 	MIPS_INS_AVE_S,
105 	MIPS_INS_AVE_U,
106 	MIPS_INS_B16,
107 	MIPS_INS_BADDU,
108 	MIPS_INS_BAL,
109 	MIPS_INS_BALC,
110 	MIPS_INS_BALIGN,
111 	MIPS_INS_BBIT0,
112 	MIPS_INS_BBIT032,
113 	MIPS_INS_BBIT1,
114 	MIPS_INS_BBIT132,
115 	MIPS_INS_BC,
116 	MIPS_INS_BC0F,
117 	MIPS_INS_BC0FL,
118 	MIPS_INS_BC0T,
119 	MIPS_INS_BC0TL,
120 	MIPS_INS_BC1EQZ,
121 	MIPS_INS_BC1F,
122 	MIPS_INS_BC1FL,
123 	MIPS_INS_BC1NEZ,
124 	MIPS_INS_BC1T,
125 	MIPS_INS_BC1TL,
126 	MIPS_INS_BC2EQZ,
127 	MIPS_INS_BC2F,
128 	MIPS_INS_BC2FL,
129 	MIPS_INS_BC2NEZ,
130 	MIPS_INS_BC2T,
131 	MIPS_INS_BC2TL,
132 	MIPS_INS_BC3F,
133 	MIPS_INS_BC3FL,
134 	MIPS_INS_BC3T,
135 	MIPS_INS_BC3TL,
136 	MIPS_INS_BCLRI,
137 	MIPS_INS_BCLR,
138 	MIPS_INS_BEQ,
139 	MIPS_INS_BEQC,
140 	MIPS_INS_BEQL,
141 	MIPS_INS_BEQZ16,
142 	MIPS_INS_BEQZALC,
143 	MIPS_INS_BEQZC,
144 	MIPS_INS_BGEC,
145 	MIPS_INS_BGEUC,
146 	MIPS_INS_BGEZ,
147 	MIPS_INS_BGEZAL,
148 	MIPS_INS_BGEZALC,
149 	MIPS_INS_BGEZALL,
150 	MIPS_INS_BGEZALS,
151 	MIPS_INS_BGEZC,
152 	MIPS_INS_BGEZL,
153 	MIPS_INS_BGTZ,
154 	MIPS_INS_BGTZALC,
155 	MIPS_INS_BGTZC,
156 	MIPS_INS_BGTZL,
157 	MIPS_INS_BINSLI,
158 	MIPS_INS_BINSL,
159 	MIPS_INS_BINSRI,
160 	MIPS_INS_BINSR,
161 	MIPS_INS_BITREV,
162 	MIPS_INS_BITSWAP,
163 	MIPS_INS_BLEZ,
164 	MIPS_INS_BLEZALC,
165 	MIPS_INS_BLEZC,
166 	MIPS_INS_BLEZL,
167 	MIPS_INS_BLTC,
168 	MIPS_INS_BLTUC,
169 	MIPS_INS_BLTZ,
170 	MIPS_INS_BLTZAL,
171 	MIPS_INS_BLTZALC,
172 	MIPS_INS_BLTZALL,
173 	MIPS_INS_BLTZALS,
174 	MIPS_INS_BLTZC,
175 	MIPS_INS_BLTZL,
176 	MIPS_INS_BMNZI,
177 	MIPS_INS_BMNZ,
178 	MIPS_INS_BMZI,
179 	MIPS_INS_BMZ,
180 	MIPS_INS_BNE,
181 	MIPS_INS_BNEC,
182 	MIPS_INS_BNEGI,
183 	MIPS_INS_BNEG,
184 	MIPS_INS_BNEL,
185 	MIPS_INS_BNEZ16,
186 	MIPS_INS_BNEZALC,
187 	MIPS_INS_BNEZC,
188 	MIPS_INS_BNVC,
189 	MIPS_INS_BNZ,
190 	MIPS_INS_BOVC,
191 	MIPS_INS_BPOSGE32,
192 	MIPS_INS_BREAK,
193 	MIPS_INS_BREAK16,
194 	MIPS_INS_BSELI,
195 	MIPS_INS_BSEL,
196 	MIPS_INS_BSETI,
197 	MIPS_INS_BSET,
198 	MIPS_INS_BZ,
199 	MIPS_INS_BEQZ,
200 	MIPS_INS_B,
201 	MIPS_INS_BNEZ,
202 	MIPS_INS_BTEQZ,
203 	MIPS_INS_BTNEZ,
204 	MIPS_INS_CACHE,
205 	MIPS_INS_CEIL,
206 	MIPS_INS_CEQI,
207 	MIPS_INS_CEQ,
208 	MIPS_INS_CFC1,
209 	MIPS_INS_CFCMSA,
210 	MIPS_INS_CINS,
211 	MIPS_INS_CINS32,
212 	MIPS_INS_CLASS,
213 	MIPS_INS_CLEI_S,
214 	MIPS_INS_CLEI_U,
215 	MIPS_INS_CLE_S,
216 	MIPS_INS_CLE_U,
217 	MIPS_INS_CLO,
218 	MIPS_INS_CLTI_S,
219 	MIPS_INS_CLTI_U,
220 	MIPS_INS_CLT_S,
221 	MIPS_INS_CLT_U,
222 	MIPS_INS_CLZ,
223 	MIPS_INS_CMPGDU,
224 	MIPS_INS_CMPGU,
225 	MIPS_INS_CMPU,
226 	MIPS_INS_CMP,
227 	MIPS_INS_COPY_S,
228 	MIPS_INS_COPY_U,
229 	MIPS_INS_CTC1,
230 	MIPS_INS_CTCMSA,
231 	MIPS_INS_CVT,
232 	MIPS_INS_C,
233 	MIPS_INS_CMPI,
234 	MIPS_INS_DADD,
235 	MIPS_INS_DADDI,
236 	MIPS_INS_DADDIU,
237 	MIPS_INS_DADDU,
238 	MIPS_INS_DAHI,
239 	MIPS_INS_DALIGN,
240 	MIPS_INS_DATI,
241 	MIPS_INS_DAUI,
242 	MIPS_INS_DBITSWAP,
243 	MIPS_INS_DCLO,
244 	MIPS_INS_DCLZ,
245 	MIPS_INS_DDIV,
246 	MIPS_INS_DDIVU,
247 	MIPS_INS_DERET,
248 	MIPS_INS_DEXT,
249 	MIPS_INS_DEXTM,
250 	MIPS_INS_DEXTU,
251 	MIPS_INS_DI,
252 	MIPS_INS_DINS,
253 	MIPS_INS_DINSM,
254 	MIPS_INS_DINSU,
255 	MIPS_INS_DIV,
256 	MIPS_INS_DIVU,
257 	MIPS_INS_DIV_S,
258 	MIPS_INS_DIV_U,
259 	MIPS_INS_DLSA,
260 	MIPS_INS_DMFC0,
261 	MIPS_INS_DMFC1,
262 	MIPS_INS_DMFC2,
263 	MIPS_INS_DMOD,
264 	MIPS_INS_DMODU,
265 	MIPS_INS_DMTC0,
266 	MIPS_INS_DMTC1,
267 	MIPS_INS_DMTC2,
268 	MIPS_INS_DMUH,
269 	MIPS_INS_DMUHU,
270 	MIPS_INS_DMUL,
271 	MIPS_INS_DMULT,
272 	MIPS_INS_DMULTU,
273 	MIPS_INS_DMULU,
274 	MIPS_INS_DOTP_S,
275 	MIPS_INS_DOTP_U,
276 	MIPS_INS_DPADD_S,
277 	MIPS_INS_DPADD_U,
278 	MIPS_INS_DPAQX_SA,
279 	MIPS_INS_DPAQX_S,
280 	MIPS_INS_DPAQ_SA,
281 	MIPS_INS_DPAQ_S,
282 	MIPS_INS_DPAU,
283 	MIPS_INS_DPAX,
284 	MIPS_INS_DPA,
285 	MIPS_INS_DPOP,
286 	MIPS_INS_DPSQX_SA,
287 	MIPS_INS_DPSQX_S,
288 	MIPS_INS_DPSQ_SA,
289 	MIPS_INS_DPSQ_S,
290 	MIPS_INS_DPSUB_S,
291 	MIPS_INS_DPSUB_U,
292 	MIPS_INS_DPSU,
293 	MIPS_INS_DPSX,
294 	MIPS_INS_DPS,
295 	MIPS_INS_DROTR,
296 	MIPS_INS_DROTR32,
297 	MIPS_INS_DROTRV,
298 	MIPS_INS_DSBH,
299 	MIPS_INS_DSHD,
300 	MIPS_INS_DSLL,
301 	MIPS_INS_DSLL32,
302 	MIPS_INS_DSLLV,
303 	MIPS_INS_DSRA,
304 	MIPS_INS_DSRA32,
305 	MIPS_INS_DSRAV,
306 	MIPS_INS_DSRL,
307 	MIPS_INS_DSRL32,
308 	MIPS_INS_DSRLV,
309 	MIPS_INS_DSUB,
310 	MIPS_INS_DSUBU,
311 	MIPS_INS_EHB,
312 	MIPS_INS_EI,
313 	MIPS_INS_ERET,
314 	MIPS_INS_EXT,
315 	MIPS_INS_EXTP,
316 	MIPS_INS_EXTPDP,
317 	MIPS_INS_EXTPDPV,
318 	MIPS_INS_EXTPV,
319 	MIPS_INS_EXTRV_RS,
320 	MIPS_INS_EXTRV_R,
321 	MIPS_INS_EXTRV_S,
322 	MIPS_INS_EXTRV,
323 	MIPS_INS_EXTR_RS,
324 	MIPS_INS_EXTR_R,
325 	MIPS_INS_EXTR_S,
326 	MIPS_INS_EXTR,
327 	MIPS_INS_EXTS,
328 	MIPS_INS_EXTS32,
329 	MIPS_INS_ABS,
330 	MIPS_INS_FADD,
331 	MIPS_INS_FCAF,
332 	MIPS_INS_FCEQ,
333 	MIPS_INS_FCLASS,
334 	MIPS_INS_FCLE,
335 	MIPS_INS_FCLT,
336 	MIPS_INS_FCNE,
337 	MIPS_INS_FCOR,
338 	MIPS_INS_FCUEQ,
339 	MIPS_INS_FCULE,
340 	MIPS_INS_FCULT,
341 	MIPS_INS_FCUNE,
342 	MIPS_INS_FCUN,
343 	MIPS_INS_FDIV,
344 	MIPS_INS_FEXDO,
345 	MIPS_INS_FEXP2,
346 	MIPS_INS_FEXUPL,
347 	MIPS_INS_FEXUPR,
348 	MIPS_INS_FFINT_S,
349 	MIPS_INS_FFINT_U,
350 	MIPS_INS_FFQL,
351 	MIPS_INS_FFQR,
352 	MIPS_INS_FILL,
353 	MIPS_INS_FLOG2,
354 	MIPS_INS_FLOOR,
355 	MIPS_INS_FMADD,
356 	MIPS_INS_FMAX_A,
357 	MIPS_INS_FMAX,
358 	MIPS_INS_FMIN_A,
359 	MIPS_INS_FMIN,
360 	MIPS_INS_MOV,
361 	MIPS_INS_FMSUB,
362 	MIPS_INS_FMUL,
363 	MIPS_INS_MUL,
364 	MIPS_INS_NEG,
365 	MIPS_INS_FRCP,
366 	MIPS_INS_FRINT,
367 	MIPS_INS_FRSQRT,
368 	MIPS_INS_FSAF,
369 	MIPS_INS_FSEQ,
370 	MIPS_INS_FSLE,
371 	MIPS_INS_FSLT,
372 	MIPS_INS_FSNE,
373 	MIPS_INS_FSOR,
374 	MIPS_INS_FSQRT,
375 	MIPS_INS_SQRT,
376 	MIPS_INS_FSUB,
377 	MIPS_INS_SUB,
378 	MIPS_INS_FSUEQ,
379 	MIPS_INS_FSULE,
380 	MIPS_INS_FSULT,
381 	MIPS_INS_FSUNE,
382 	MIPS_INS_FSUN,
383 	MIPS_INS_FTINT_S,
384 	MIPS_INS_FTINT_U,
385 	MIPS_INS_FTQ,
386 	MIPS_INS_FTRUNC_S,
387 	MIPS_INS_FTRUNC_U,
388 	MIPS_INS_HADD_S,
389 	MIPS_INS_HADD_U,
390 	MIPS_INS_HSUB_S,
391 	MIPS_INS_HSUB_U,
392 	MIPS_INS_ILVEV,
393 	MIPS_INS_ILVL,
394 	MIPS_INS_ILVOD,
395 	MIPS_INS_ILVR,
396 	MIPS_INS_INS,
397 	MIPS_INS_INSERT,
398 	MIPS_INS_INSV,
399 	MIPS_INS_INSVE,
400 	MIPS_INS_J,
401 	MIPS_INS_JAL,
402 	MIPS_INS_JALR,
403 	MIPS_INS_JALRS16,
404 	MIPS_INS_JALRS,
405 	MIPS_INS_JALS,
406 	MIPS_INS_JALX,
407 	MIPS_INS_JIALC,
408 	MIPS_INS_JIC,
409 	MIPS_INS_JR,
410 	MIPS_INS_JR16,
411 	MIPS_INS_JRADDIUSP,
412 	MIPS_INS_JRC,
413 	MIPS_INS_JALRC,
414 	MIPS_INS_LB,
415 	MIPS_INS_LBU16,
416 	MIPS_INS_LBUX,
417 	MIPS_INS_LBU,
418 	MIPS_INS_LD,
419 	MIPS_INS_LDC1,
420 	MIPS_INS_LDC2,
421 	MIPS_INS_LDC3,
422 	MIPS_INS_LDI,
423 	MIPS_INS_LDL,
424 	MIPS_INS_LDPC,
425 	MIPS_INS_LDR,
426 	MIPS_INS_LDXC1,
427 	MIPS_INS_LH,
428 	MIPS_INS_LHU16,
429 	MIPS_INS_LHX,
430 	MIPS_INS_LHU,
431 	MIPS_INS_LI16,
432 	MIPS_INS_LL,
433 	MIPS_INS_LLD,
434 	MIPS_INS_LSA,
435 	MIPS_INS_LUXC1,
436 	MIPS_INS_LUI,
437 	MIPS_INS_LW,
438 	MIPS_INS_LW16,
439 	MIPS_INS_LWC1,
440 	MIPS_INS_LWC2,
441 	MIPS_INS_LWC3,
442 	MIPS_INS_LWL,
443 	MIPS_INS_LWM16,
444 	MIPS_INS_LWM32,
445 	MIPS_INS_LWPC,
446 	MIPS_INS_LWP,
447 	MIPS_INS_LWR,
448 	MIPS_INS_LWUPC,
449 	MIPS_INS_LWU,
450 	MIPS_INS_LWX,
451 	MIPS_INS_LWXC1,
452 	MIPS_INS_LWXS,
453 	MIPS_INS_LI,
454 	MIPS_INS_MADD,
455 	MIPS_INS_MADDF,
456 	MIPS_INS_MADDR_Q,
457 	MIPS_INS_MADDU,
458 	MIPS_INS_MADDV,
459 	MIPS_INS_MADD_Q,
460 	MIPS_INS_MAQ_SA,
461 	MIPS_INS_MAQ_S,
462 	MIPS_INS_MAXA,
463 	MIPS_INS_MAXI_S,
464 	MIPS_INS_MAXI_U,
465 	MIPS_INS_MAX_A,
466 	MIPS_INS_MAX,
467 	MIPS_INS_MAX_S,
468 	MIPS_INS_MAX_U,
469 	MIPS_INS_MFC0,
470 	MIPS_INS_MFC1,
471 	MIPS_INS_MFC2,
472 	MIPS_INS_MFHC1,
473 	MIPS_INS_MFHI,
474 	MIPS_INS_MFLO,
475 	MIPS_INS_MINA,
476 	MIPS_INS_MINI_S,
477 	MIPS_INS_MINI_U,
478 	MIPS_INS_MIN_A,
479 	MIPS_INS_MIN,
480 	MIPS_INS_MIN_S,
481 	MIPS_INS_MIN_U,
482 	MIPS_INS_MOD,
483 	MIPS_INS_MODSUB,
484 	MIPS_INS_MODU,
485 	MIPS_INS_MOD_S,
486 	MIPS_INS_MOD_U,
487 	MIPS_INS_MOVE,
488 	MIPS_INS_MOVEP,
489 	MIPS_INS_MOVF,
490 	MIPS_INS_MOVN,
491 	MIPS_INS_MOVT,
492 	MIPS_INS_MOVZ,
493 	MIPS_INS_MSUB,
494 	MIPS_INS_MSUBF,
495 	MIPS_INS_MSUBR_Q,
496 	MIPS_INS_MSUBU,
497 	MIPS_INS_MSUBV,
498 	MIPS_INS_MSUB_Q,
499 	MIPS_INS_MTC0,
500 	MIPS_INS_MTC1,
501 	MIPS_INS_MTC2,
502 	MIPS_INS_MTHC1,
503 	MIPS_INS_MTHI,
504 	MIPS_INS_MTHLIP,
505 	MIPS_INS_MTLO,
506 	MIPS_INS_MTM0,
507 	MIPS_INS_MTM1,
508 	MIPS_INS_MTM2,
509 	MIPS_INS_MTP0,
510 	MIPS_INS_MTP1,
511 	MIPS_INS_MTP2,
512 	MIPS_INS_MUH,
513 	MIPS_INS_MUHU,
514 	MIPS_INS_MULEQ_S,
515 	MIPS_INS_MULEU_S,
516 	MIPS_INS_MULQ_RS,
517 	MIPS_INS_MULQ_S,
518 	MIPS_INS_MULR_Q,
519 	MIPS_INS_MULSAQ_S,
520 	MIPS_INS_MULSA,
521 	MIPS_INS_MULT,
522 	MIPS_INS_MULTU,
523 	MIPS_INS_MULU,
524 	MIPS_INS_MULV,
525 	MIPS_INS_MUL_Q,
526 	MIPS_INS_MUL_S,
527 	MIPS_INS_NLOC,
528 	MIPS_INS_NLZC,
529 	MIPS_INS_NMADD,
530 	MIPS_INS_NMSUB,
531 	MIPS_INS_NOR,
532 	MIPS_INS_NORI,
533 	MIPS_INS_NOT16,
534 	MIPS_INS_NOT,
535 	MIPS_INS_OR,
536 	MIPS_INS_OR16,
537 	MIPS_INS_ORI,
538 	MIPS_INS_PACKRL,
539 	MIPS_INS_PAUSE,
540 	MIPS_INS_PCKEV,
541 	MIPS_INS_PCKOD,
542 	MIPS_INS_PCNT,
543 	MIPS_INS_PICK,
544 	MIPS_INS_POP,
545 	MIPS_INS_PRECEQU,
546 	MIPS_INS_PRECEQ,
547 	MIPS_INS_PRECEU,
548 	MIPS_INS_PRECRQU_S,
549 	MIPS_INS_PRECRQ,
550 	MIPS_INS_PRECRQ_RS,
551 	MIPS_INS_PRECR,
552 	MIPS_INS_PRECR_SRA,
553 	MIPS_INS_PRECR_SRA_R,
554 	MIPS_INS_PREF,
555 	MIPS_INS_PREPEND,
556 	MIPS_INS_RADDU,
557 	MIPS_INS_RDDSP,
558 	MIPS_INS_RDHWR,
559 	MIPS_INS_REPLV,
560 	MIPS_INS_REPL,
561 	MIPS_INS_RINT,
562 	MIPS_INS_ROTR,
563 	MIPS_INS_ROTRV,
564 	MIPS_INS_ROUND,
565 	MIPS_INS_SAT_S,
566 	MIPS_INS_SAT_U,
567 	MIPS_INS_SB,
568 	MIPS_INS_SB16,
569 	MIPS_INS_SC,
570 	MIPS_INS_SCD,
571 	MIPS_INS_SD,
572 	MIPS_INS_SDBBP,
573 	MIPS_INS_SDBBP16,
574 	MIPS_INS_SDC1,
575 	MIPS_INS_SDC2,
576 	MIPS_INS_SDC3,
577 	MIPS_INS_SDL,
578 	MIPS_INS_SDR,
579 	MIPS_INS_SDXC1,
580 	MIPS_INS_SEB,
581 	MIPS_INS_SEH,
582 	MIPS_INS_SELEQZ,
583 	MIPS_INS_SELNEZ,
584 	MIPS_INS_SEL,
585 	MIPS_INS_SEQ,
586 	MIPS_INS_SEQI,
587 	MIPS_INS_SH,
588 	MIPS_INS_SH16,
589 	MIPS_INS_SHF,
590 	MIPS_INS_SHILO,
591 	MIPS_INS_SHILOV,
592 	MIPS_INS_SHLLV,
593 	MIPS_INS_SHLLV_S,
594 	MIPS_INS_SHLL,
595 	MIPS_INS_SHLL_S,
596 	MIPS_INS_SHRAV,
597 	MIPS_INS_SHRAV_R,
598 	MIPS_INS_SHRA,
599 	MIPS_INS_SHRA_R,
600 	MIPS_INS_SHRLV,
601 	MIPS_INS_SHRL,
602 	MIPS_INS_SLDI,
603 	MIPS_INS_SLD,
604 	MIPS_INS_SLL,
605 	MIPS_INS_SLL16,
606 	MIPS_INS_SLLI,
607 	MIPS_INS_SLLV,
608 	MIPS_INS_SLT,
609 	MIPS_INS_SLTI,
610 	MIPS_INS_SLTIU,
611 	MIPS_INS_SLTU,
612 	MIPS_INS_SNE,
613 	MIPS_INS_SNEI,
614 	MIPS_INS_SPLATI,
615 	MIPS_INS_SPLAT,
616 	MIPS_INS_SRA,
617 	MIPS_INS_SRAI,
618 	MIPS_INS_SRARI,
619 	MIPS_INS_SRAR,
620 	MIPS_INS_SRAV,
621 	MIPS_INS_SRL,
622 	MIPS_INS_SRL16,
623 	MIPS_INS_SRLI,
624 	MIPS_INS_SRLRI,
625 	MIPS_INS_SRLR,
626 	MIPS_INS_SRLV,
627 	MIPS_INS_SSNOP,
628 	MIPS_INS_ST,
629 	MIPS_INS_SUBQH,
630 	MIPS_INS_SUBQH_R,
631 	MIPS_INS_SUBQ,
632 	MIPS_INS_SUBQ_S,
633 	MIPS_INS_SUBSUS_U,
634 	MIPS_INS_SUBSUU_S,
635 	MIPS_INS_SUBS_S,
636 	MIPS_INS_SUBS_U,
637 	MIPS_INS_SUBU16,
638 	MIPS_INS_SUBUH,
639 	MIPS_INS_SUBUH_R,
640 	MIPS_INS_SUBU,
641 	MIPS_INS_SUBU_S,
642 	MIPS_INS_SUBVI,
643 	MIPS_INS_SUBV,
644 	MIPS_INS_SUXC1,
645 	MIPS_INS_SW,
646 	MIPS_INS_SW16,
647 	MIPS_INS_SWC1,
648 	MIPS_INS_SWC2,
649 	MIPS_INS_SWC3,
650 	MIPS_INS_SWL,
651 	MIPS_INS_SWM16,
652 	MIPS_INS_SWM32,
653 	MIPS_INS_SWP,
654 	MIPS_INS_SWR,
655 	MIPS_INS_SWXC1,
656 	MIPS_INS_SYNC,
657 	MIPS_INS_SYNCI,
658 	MIPS_INS_SYSCALL,
659 	MIPS_INS_TEQ,
660 	MIPS_INS_TEQI,
661 	MIPS_INS_TGE,
662 	MIPS_INS_TGEI,
663 	MIPS_INS_TGEIU,
664 	MIPS_INS_TGEU,
665 	MIPS_INS_TLBP,
666 	MIPS_INS_TLBR,
667 	MIPS_INS_TLBWI,
668 	MIPS_INS_TLBWR,
669 	MIPS_INS_TLT,
670 	MIPS_INS_TLTI,
671 	MIPS_INS_TLTIU,
672 	MIPS_INS_TLTU,
673 	MIPS_INS_TNE,
674 	MIPS_INS_TNEI,
675 	MIPS_INS_TRUNC,
676 	MIPS_INS_V3MULU,
677 	MIPS_INS_VMM0,
678 	MIPS_INS_VMULU,
679 	MIPS_INS_VSHF,
680 	MIPS_INS_WAIT,
681 	MIPS_INS_WRDSP,
682 	MIPS_INS_WSBH,
683 	MIPS_INS_XOR,
684 	MIPS_INS_XOR16,
685 	MIPS_INS_XORI,
686 
687 	//> some alias instructions
688 	MIPS_INS_NOP,
689 	MIPS_INS_NEGU,
690 
691 	//> special instructions
692 	MIPS_INS_JALR_HB,	// jump and link with Hazard Barrier
693 	MIPS_INS_JR_HB,		// jump register with Hazard Barrier
694 
695 	MIPS_INS_ENDING,
696 } mips_insn;
697 
698 
699 struct gnu_rreg {
700 	const char *rs;
701 	const char *rt;
702 	const char *rd;
703 	ut8 sa[REG_BUF_MAX];
704 };
705 
706 struct gnu_jreg {
707 	ut8 jump[REG_BUF_MAX];
708 };
709 
710 struct gnu_ireg {
711 	const char *rs;
712 	const char *rt;
713 	union {
714 		ut8 imm[REG_BUF_MAX];
715 		ut8 jump[REG_BUF_MAX];
716 	};
717 };
718 
719 typedef struct gnu_insn {
720 	ut8 optype;
721 	ut32 id;
722 	union {
723 		struct gnu_rreg r_reg;
724 		struct gnu_ireg i_reg;
725 		struct gnu_jreg j_reg;
726 	};
727 } gnu_insn;
728 
729 
730 #define R_REG(x) ((const char *)insn->r_reg.x)
731 #define I_REG(x) ((const char *)insn->i_reg.x)
732 #define J_REG(x) ((const char *)insn->j_reg.x)
733 
734 
735 /* Return a mapping from the register number i.e. $0 .. $31 to string name */
mips_reg_decode(ut32 reg_num)736 static const char* mips_reg_decode(ut32 reg_num) {
737 /* See page 36 of "See Mips Run Linux, 2e, D. Sweetman, 2007"*/
738 	static const char *REGISTERS[32] = {
739 		"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
740 		"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
741 		"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
742 		"t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
743 	};
744 	if (reg_num < 32) {
745 		return REGISTERS[reg_num];
746 	}
747 	return NULL;
748 }
749 
analop_esil(RAnal * a,RAnalOp * op,ut64 addr,gnu_insn * insn)750 static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, gnu_insn*insn) {
751 
752 	switch (insn->id) {
753 		case MIPS_INS_NOP:
754 			r_strbuf_setf (&op->esil, ",");
755 			break;
756 		case MIPS_INS_BREAK:
757 			//r_strbuf_setf (&op->esil, "%d,%d,TRAP", IMM (0), IMM (0));
758 			break;
759 		case MIPS_INS_SD:
760 			r_strbuf_appendf (&op->esil, "%s,%s,%s,+,=[8]",
761 				I_REG (rt), I_REG (imm), I_REG (rs));
762 			break;
763 		case MIPS_INS_SW:
764 		case MIPS_INS_SWL:
765 		case MIPS_INS_SWR:
766 			r_strbuf_appendf (&op->esil, "%s,%s,%s,+,=[4]",
767 				I_REG (rt),I_REG (imm), I_REG (rs));
768 			break;
769 		case MIPS_INS_SH:
770 			r_strbuf_appendf (&op->esil, "%s,%s,%s,+,=[2]",
771 				I_REG (rt),I_REG (imm), I_REG (rs));
772 			break;
773 		case MIPS_INS_SWC1:
774 		case MIPS_INS_SWC2:
775 			break;
776 		case MIPS_INS_SB:
777 			r_strbuf_appendf (&op->esil, "%s,%s,%s,+,=[1]",
778 				I_REG (rt),I_REG (imm), I_REG (rs));
779 			break;
780 		case MIPS_INS_CMP:
781 		case MIPS_INS_CMPU:
782 		case MIPS_INS_CMPGU:
783 		case MIPS_INS_CMPGDU:
784 		case MIPS_INS_CMPI:
785 			break;
786 		case MIPS_INS_SHRAV:
787 		case MIPS_INS_SHRAV_R:
788 		case MIPS_INS_SHRA:
789 		case MIPS_INS_SHRA_R:
790 			break;
791 		case MIPS_INS_SRA:
792 			r_strbuf_appendf (&op->esil,
793 				ES_W ("%s,%s")",>>,31,%s,>>,?{,%s,32,-,0xffffffff,<<,0xffffffff,&,}{,0,},|,%s,=",
794 				R_REG (sa), R_REG (rt), R_REG (rt), R_REG (sa), R_REG (rd));
795 			break;
796 		case MIPS_INS_DSRA:
797 			r_strbuf_appendf (&op->esil,
798 				"%s,%s,>>,31,%s,>>,?{,32,%s,32,-,0xffffffff,<<,0xffffffff,&,<<,}{,0,},|,%s,=",
799 				R_REG (sa), R_REG (rt), R_REG (rt), R_REG (sa), R_REG (rd));
800 			break;
801 		case MIPS_INS_SHRL:
802 			// suffix 'S' forces conditional flag to be updated
803 			break;
804 		case MIPS_INS_SRLV:
805 		case MIPS_INS_SRL:
806 			r_strbuf_appendf (&op->esil, "%s,%s,>>,%s,=", \
807 							R_REG (rs)?R_REG (rs):R_REG (sa), R_REG (rt),R_REG (rd) );
808 			break;
809 		case MIPS_INS_SLLV:
810 		case MIPS_INS_SLL:
811 			r_strbuf_appendf (&op->esil, "%s,%s,<<,%s,=", \
812 							R_REG (rs)?R_REG (rs):R_REG (sa),R_REG (rt),R_REG (rd) );
813 			break;
814 		case MIPS_INS_BAL:
815 		case MIPS_INS_JAL:
816 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_D ("%s"), I_REG (jump));
817 			break;
818 		case MIPS_INS_JALR:
819 		case MIPS_INS_JALRS:
820 			if (strcmp(R_REG(rd), "rd")==0) {
821 				r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_D ("%s"), R_REG (rs));
822 			} else {
823 				r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_CALL_DR ("%s", "%s"), R_REG (rd), R_REG (rs));
824 			}
825 			break;
826 		case MIPS_INS_JR:
827 		case MIPS_INS_JRC:
828 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J ("%s"), R_REG (rs));
829 			break;
830 		case MIPS_INS_J:
831 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J ("%s"), J_REG (jump));
832 		case MIPS_INS_B:
833 			// jump to address with conditional
834 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "" ES_J ("%s"), I_REG (jump));
835 			break;
836 		case MIPS_INS_BNE: // bne $s, $t, offset
837 		case MIPS_INS_BNEL:
838 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J ("%s") ",}",
839 				I_REG (rs), I_REG (rt), I_REG (jump));
840 			break;
841 		case MIPS_INS_BEQ:
842 		case MIPS_INS_BEQL:
843 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J ("%s") ",}",
844 				I_REG (rs), I_REG (rt), I_REG (jump));
845 			break;
846 		case MIPS_INS_BZ:
847 		case MIPS_INS_BEQZ:
848 		case MIPS_INS_BEQZC:
849 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,?{," ES_J ("%s") ",}",
850 				I_REG (rs), I_REG (jump));
851 			break;
852 		case MIPS_INS_BNEZ:
853 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J ("%s") ",}",
854 				I_REG (rs), I_REG (jump));
855 			break;
856 		case MIPS_INS_BLEZ:
857 		case MIPS_INS_BLEZC:
858 		case MIPS_INS_BLEZL:
859 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{," ES_J ("%s") ",BREAK,},",
860 				I_REG (rs), I_REG (jump));
861 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
862 				I_REG (rs), I_REG (jump));
863 			break;
864 		case MIPS_INS_BGEZ:
865 		case MIPS_INS_BGEZC:
866 		case MIPS_INS_BGEZL:
867 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
868 				I_REG (rs), I_REG (jump));
869 			break;
870 		case MIPS_INS_BGEZAL:
871 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_CALL_D ("%s") ",}",
872 				I_REG (rs), I_REG (jump));
873 			break;
874 		case MIPS_INS_BLTZAL:
875 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_CALL_D ("%s") ",}",
876 				I_REG (rs), I_REG (jump));
877 			break;
878 		case MIPS_INS_BLTZ:
879 		case MIPS_INS_BLTZC:
880 		case MIPS_INS_BLTZL:
881 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "1," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
882 				I_REG (rs), I_REG (jump));
883 			break;
884 		case MIPS_INS_BGTZ:
885 		case MIPS_INS_BGTZC:
886 		case MIPS_INS_BGTZL:
887 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0,%s,==,$z,?{,BREAK,},", I_REG (rs));
888 			r_strbuf_appendf (&op->esil, ES_TRAP_DS () "0," ES_IS_NEGATIVE ("%s") ",==,$z,?{," ES_J ("%s") ",}",
889 				I_REG (rs), I_REG (jump));
890 			break;
891 		case MIPS_INS_BTEQZ:
892 			break;
893 		case MIPS_INS_BTNEZ:
894 			break;
895 		case MIPS_INS_MOV:
896 		case MIPS_INS_MOVE:
897 			r_strbuf_appendf (&op->esil, "%s,%s,=", R_REG (rs), R_REG (rd));
898 			break;
899 		case MIPS_INS_MOVZ:
900 		case MIPS_INS_MOVF:
901 			r_strbuf_appendf (&op->esil, "0,%s,==,$z,?{,%s,%s,=,}",
902 				R_REG (rt), R_REG (rs), R_REG (rd));
903 			break;
904 		case MIPS_INS_MOVT:
905 			r_strbuf_appendf (&op->esil, "1,%s,==,$z,?{,%s,%s,=,}",
906 				R_REG (rt), R_REG (rs), R_REG (rd));
907 			break;
908 		case MIPS_INS_FSUB:
909 		case MIPS_INS_SUB:
910 		case MIPS_INS_SUBU:
911 		case MIPS_INS_DSUB:
912 		case MIPS_INS_DSUBU:
913 			r_strbuf_appendf (&op->esil, "%s,%s,-,%s,=",
914 				R_REG (rt), R_REG (rs), R_REG (rd));
915 			break;
916 		case MIPS_INS_NEG:
917 		case MIPS_INS_NEGU:
918 			break;
919 		/** signed -- sets overflow flag */
920 		case MIPS_INS_ADD:
921 			ES_ADD_CK32_OVERF(R_REG (rs), R_REG (rt), R_REG (rd));
922 		break;
923 		case MIPS_INS_ADDI:
924 			ES_ADD_CK32_OVERF(I_REG (imm), I_REG (rs), I_REG (rt));
925 			break;
926 		case MIPS_INS_DADD:
927 			ES_ADD_CK64_OVERF(R_REG (rs), R_REG (rt), R_REG (rd));
928 			break;
929 		case MIPS_INS_DADDU:
930 		case MIPS_INS_ADDU:
931 			r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=",\
932 				R_REG (rt), R_REG (rs), R_REG (rd));
933 			break;
934 		case MIPS_INS_DADDI:
935 		ES_ADD_CK64_OVERF(I_REG (imm), I_REG (rs), I_REG (rt));
936 		break;
937 		case MIPS_INS_ADDIU:
938 		case MIPS_INS_DADDIU:
939 			r_strbuf_appendf (&op->esil, "%s,%s,+,%s,=",
940 				I_REG (imm), I_REG (rs), I_REG (rt));
941 			ES_SIGN32_64 (I_REG (rt));
942 			break;
943 		case MIPS_INS_LI:
944 		case MIPS_INS_LDI:
945 			r_strbuf_appendf (&op->esil, "%s,%s,=", I_REG (imm), I_REG (rt));
946 			break;
947 		case MIPS_INS_LUI:
948 			r_strbuf_appendf (&op->esil, "%s0000,%s,=",I_REG (imm), I_REG (rt));
949 			break;
950 		case MIPS_INS_LB:
951 			op->sign = true;	//To load a byte from memory as a signed value
952 			/* fallthrough */
953 		case MIPS_INS_LBU:
954 			//one of these is wrong
955 			r_strbuf_appendf (&op->esil, "%s,%s,+,[1],%s,=",\
956 				I_REG (imm), I_REG (rs), I_REG (rt));\
957 			break;
958 		case MIPS_INS_LW:
959 		case MIPS_INS_LWC1:
960 		case MIPS_INS_LWC2:
961 		case MIPS_INS_LWL:
962 		case MIPS_INS_LWR:
963 		case MIPS_INS_LWU:
964 		case MIPS_INS_LL:
965 			r_strbuf_appendf (&op->esil, "%s,%s,+,[4],%s,=",\
966 				I_REG (imm), I_REG (rs), I_REG (rt));\
967 			break;
968 		case MIPS_INS_LDL:
969 		case MIPS_INS_LDC1:
970 		case MIPS_INS_LDC2:
971 		case MIPS_INS_LLD:
972 		case MIPS_INS_LD:
973 			r_strbuf_appendf (&op->esil, "%s,%s,+,[8],%s,=",\
974 				I_REG (imm), I_REG (rs), I_REG (rt));\
975 			break;
976 		case MIPS_INS_LH:
977 			op->sign = true;	//To load a byte from memory as a signed value
978 			/* fallthrough */
979 		case MIPS_INS_LHU:
980 			r_strbuf_appendf (&op->esil, "%s,%s,+,[2],%s,=",\
981 				I_REG (imm), I_REG (rs), I_REG (rt));\
982 			break;
983 		case MIPS_INS_LHX:
984 		case MIPS_INS_LWX:
985 			break;
986 		case MIPS_INS_AND:
987 			r_strbuf_appendf (&op->esil, "%s,%s,&,%s,=", R_REG (rt), R_REG (rs), R_REG (rd));
988 		break;
989 		case MIPS_INS_ANDI:
990 			r_strbuf_appendf (&op->esil, "%s,%s,&,%s,=", I_REG (imm), I_REG (rs), I_REG (rt));
991 			break;
992 		case MIPS_INS_OR:
993 			r_strbuf_appendf (&op->esil, "%s,%s,|,%s,=", R_REG (rt), R_REG (rs), R_REG (rd));
994 			break;
995 		case MIPS_INS_ORI:
996 			r_strbuf_appendf (&op->esil, "%s,%s,|,%s,=", I_REG (imm), I_REG (rs), I_REG (rt));
997 			break;
998 		case MIPS_INS_XOR:
999 			r_strbuf_appendf (&op->esil, "%s,%s,^,%s,=", R_REG (rt), R_REG (rs), R_REG (rd));
1000 			break;
1001 		case MIPS_INS_XORI:
1002 			r_strbuf_appendf (&op->esil, "%s,%s,^,%s,=", I_REG (imm), I_REG (rs), I_REG (rt));
1003 			break;
1004 		case MIPS_INS_NOR:
1005 			r_strbuf_appendf (&op->esil, "%s,%s,|,0xffffffff,^,%s,=",R_REG (rs), R_REG (rt), R_REG (rd));
1006 			break;
1007 		case MIPS_INS_SLT:
1008 			r_strbuf_appendf (&op->esil, "%s,%s,<,t,=", R_REG (rs), R_REG (rt));
1009 			break;
1010 		case MIPS_INS_SLTI:
1011 			r_strbuf_appendf (&op->esil, "%s,%s,<,%s,=", I_REG (imm), I_REG (rs), I_REG (rt));
1012 			break;
1013 		case MIPS_INS_SLTU:
1014 			r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,t,=",
1015 				R_REG (rs), R_REG (rt));
1016 			break;
1017 		case MIPS_INS_SLTIU:
1018 			r_strbuf_appendf (&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,%s,=",
1019 				I_REG (imm), I_REG (rs), I_REG (rt));
1020 			break;
1021 		case MIPS_INS_MUL:
1022 		r_strbuf_appendf (&op->esil, ES_W("%s,%s,*")",%s,=", R_REG (rs), R_REG (rt), R_REG (rd));
1023 		ES_SIGN32_64 (R_REG (rd));
1024 			break;
1025 		case MIPS_INS_MULT:
1026 		case MIPS_INS_MULTU:
1027 			r_strbuf_appendf (&op->esil, ES_W("%s,%s,*")",lo,=", R_REG (rs), R_REG (rt));
1028 			ES_SIGN32_64 ("lo");
1029 			r_strbuf_appendf (&op->esil, ES_W("32,%s,%s,*,>>")",hi,=", R_REG (rs), R_REG (rt));
1030 			ES_SIGN32_64 ("hi");
1031 			break;
1032 		case MIPS_INS_MFLO:
1033 			r_strbuf_appendf (&op->esil, "lo,%s,=", R_REG (rd));
1034 		break;
1035 	case MIPS_INS_MFHI:
1036 			r_strbuf_appendf (&op->esil, "hi,%s,=", R_REG (rd));
1037 		break;
1038 	case MIPS_INS_MTLO:
1039 		r_strbuf_appendf (&op->esil, "%s,lo,=,", R_REG (rs));
1040 		ES_SIGN32_64 ("lo");
1041 		break;
1042 	case MIPS_INS_MTHI:
1043 		r_strbuf_appendf (&op->esil, "%s,hi,=,", R_REG (rs));
1044 		ES_SIGN32_64 ("hi");
1045 		break;
1046 	default:
1047 		return -1;
1048 	}
1049 
1050 	return 0;
1051 }
1052 
1053 
mips_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * b,int len,RAnalOpMask mask)1054 static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len, RAnalOpMask mask) {
1055 	ut32 opcode;
1056 	// WIP char buf[10]; int reg; int family;
1057 	int optype, oplen = (anal->bits==16)?2:4;
1058 	const ut8 * buf;
1059 	gnu_insn insn;
1060 
1061 	if (!op) {
1062 		return oplen;
1063 	}
1064 
1065 	op->type = R_ANAL_OP_TYPE_UNK;
1066 	op->size = oplen;
1067 	op->addr = addr;
1068 	// Be endian aware
1069 	opcode = r_read_ble32 (b, anal->big_endian);
1070 
1071 	// eprintf ("MIPS: %02x %02x %02x %02x (after endian: big=%d)\n", buf[0], buf[1], buf[2], buf[3], anal->big_endian);
1072 	if (opcode == 0) {
1073 		op->type = R_ANAL_OP_TYPE_NOP;
1074 		return oplen;
1075 	}
1076 
1077 	opcode = r_swap_ut32(opcode);
1078 	buf = (ut8 *) & opcode;
1079 
1080 	optype = (buf[0]>>2);
1081 	insn.optype = optype;
1082 	insn.id = 0;
1083 
1084 	if (optype == 0) {
1085 /*
1086 	R-TYPE
1087 	======
1088 	opcode (6)  rs (5)  rt (5)  rd (5)  sa (5)  function (6)
1089 	rs = register source
1090 	rt = register target
1091 	rd = register destination
1092 	sa =
1093 	fu =
1094 		 |--[0]--|  |--[1]--|  |--[2]--|  |--[3]--|
1095 		 1111 1111  1111 1111  1111 1111  1111 1111
1096 		 \_op__/\_rs__/\_rt_/  \_rd_/\_sa__/\_fun_/
1097 		   |      |      |       |      |      |
1098 		 buf[0]>>2  |  (buf[1]&31)   |      |   buf[3]&63
1099 		          |          (buf[2]>>3)  |
1100 		  (buf[0]&3)<<3)+(buf[1]>>5)   (buf[2]&7)+(buf[3]>>6)
1101 */
1102 		int rs = ((buf[0]&3)<<3) + (buf[1]>>5);
1103 		int rt = buf[1]&31;
1104 		int rd = buf[2]>>3;
1105 		int sa = ((buf[2]&7)<<2)+(buf[3]>>6);
1106 		int fun = buf[3]&63;
1107 
1108 		insn.r_reg.rs = mips_reg_decode (rs);
1109 		insn.r_reg.rd = mips_reg_decode (rd);
1110 		insn.r_reg.rt = mips_reg_decode (rt);
1111 		snprintf ((char *)insn.r_reg.sa, REG_BUF_MAX, "%"PFMT32d, sa);
1112 
1113 		switch (fun) {
1114 		case 0: // sll
1115 			insn.id = MIPS_INS_SLL;
1116 			insn.r_reg.rs = NULL;
1117 			op->val = sa;
1118 		case 4: // sllv
1119 			insn.id = MIPS_INS_SLLV;
1120 			op->type = R_ANAL_OP_TYPE_SHL;
1121 			break;
1122 		case 2: // srl
1123 			insn.id = MIPS_INS_SRL;
1124 			insn.r_reg.rs = NULL;
1125 			op->val = sa;
1126 		case 6: // srlv
1127 			insn.id = MIPS_INS_SRLV;
1128 			op->type = R_ANAL_OP_TYPE_SHR;
1129 			break;
1130 		case 3: // sra
1131 			insn.id = MIPS_INS_SRA;
1132 			op->type = R_ANAL_OP_TYPE_SAR;
1133 			break;
1134 		case 7: // srav
1135 			insn.id = MIPS_INS_SRAV;
1136 			op->type = R_ANAL_OP_TYPE_SAR;
1137 			break;
1138 		case 59: // dsra
1139 			insn.id = MIPS_INS_DSRA;	//TODO double
1140 			op->type = R_ANAL_OP_TYPE_SAR;
1141 			break;
1142 		case 63: // dsra32
1143 			insn.id = MIPS_INS_DSRA32;
1144 			op->type = R_ANAL_OP_TYPE_SAR;
1145 			break;
1146 		case 8: // jr
1147 			//eprintf ("%llx jr\n", addr);
1148 			// TODO: check return value or gtfo
1149 			op->delay = 1;
1150 			insn.id = MIPS_INS_JR;
1151 			if (rs == 31) {
1152 				op->type = R_ANAL_OP_TYPE_RET;
1153 			} else if (rs == 25) {
1154 				op->type = R_ANAL_OP_TYPE_RJMP;
1155 				op->jump = t9_pre;
1156 				break;
1157 
1158 			} else {
1159 				op->type = R_ANAL_OP_TYPE_RJMP;
1160 			}
1161 			break;
1162 		case 9: // jalr
1163 			//eprintf ("%llx jalr\n", addr);
1164 			op->delay = 1;
1165 			insn.id = MIPS_INS_JALR;
1166 			if (rs  == 25){
1167 				op->type = R_ANAL_OP_TYPE_RCALL;
1168 				op->jump = t9_pre;
1169 				break;
1170 			}
1171 			op->type = R_ANAL_OP_TYPE_UCALL;
1172 			break;
1173 		case 10: //movz
1174 			insn.id = MIPS_INS_MOVZ;
1175 			break;
1176 		case 12: // syscall
1177 			op->type = R_ANAL_OP_TYPE_SWI;
1178 			break;
1179 		case 13: // break
1180 			op->type = R_ANAL_OP_TYPE_TRAP;
1181 			break;
1182 		case 16: // mfhi
1183 			insn.id = MIPS_INS_MFHI;
1184 			break;
1185 		case 18: // mflo
1186 			insn.id = MIPS_INS_MFLO;
1187 			break;
1188 		case 17: // mthi
1189 			insn.id = MIPS_INS_MTHI;
1190 			break;
1191 		case 19: // mtlo
1192 			insn.id = MIPS_INS_MTLO;
1193 			op->type = R_ANAL_OP_TYPE_MOV;
1194 			break;
1195 		case 24: // mult
1196 			insn.id = MIPS_INS_MULT;
1197 		case 25: // multu
1198 			insn.id = MIPS_INS_MULTU;
1199 			op->type = R_ANAL_OP_TYPE_MUL;
1200 			break;
1201 		case 26: // div
1202 		case 27: // divu
1203 			op->type = R_ANAL_OP_TYPE_DIV;
1204 			insn.id = MIPS_INS_DIV;
1205 			break;
1206 		case 32: // add
1207 			insn.id = MIPS_INS_ADD;
1208 		case 33: // addu	//TODO:表明位数
1209 			insn.id = MIPS_INS_ADDU;
1210 			op->type = R_ANAL_OP_TYPE_ADD;
1211 			break;
1212 		case 44: //dadd
1213 			insn.id = MIPS_INS_DADD;
1214 			op->type = R_ANAL_OP_TYPE_ADD;
1215 			break;
1216 		case 45: //daddu move
1217 			if(rt == 0) {
1218 				op->type = R_ANAL_OP_TYPE_MOV;
1219 				insn.id = MIPS_INS_MOV;
1220 				break;
1221 			}
1222 			op->type = R_ANAL_OP_TYPE_ADD;
1223 			insn.id = MIPS_INS_DADDU;
1224 			break;
1225 		case 34: // sub
1226 		case 35: // subu
1227 			insn.id = MIPS_INS_SUB;
1228 			op->type = R_ANAL_OP_TYPE_SUB;
1229 			break;
1230 		case 46: //dsub
1231 			insn.id = MIPS_INS_SUB;
1232 			op->type = R_ANAL_OP_TYPE_SUB;
1233 			break;
1234 		case 47: //dsubu
1235 			insn.id = MIPS_INS_SUB;
1236 			op->type = R_ANAL_OP_TYPE_SUB;
1237 			break;
1238 		case 36: // and
1239 			insn.id = MIPS_INS_AND;
1240 			op->type = R_ANAL_OP_TYPE_AND;
1241 			break;
1242 		case 37: // or
1243 			insn.id = MIPS_INS_OR;
1244 			op->type = R_ANAL_OP_TYPE_OR;
1245 			break;
1246 		case 38: // xor
1247 			insn.id = MIPS_INS_XOR;
1248 			op->type = R_ANAL_OP_TYPE_XOR;
1249 			break;
1250 		case 39: // nor
1251 			insn.id = MIPS_INS_NOR;
1252 			op->type = R_ANAL_OP_TYPE_NOR;
1253 			break;
1254 		case 42: // slt
1255 			insn.id = MIPS_INS_SLT;
1256 			break;
1257 		case 43: // sltu
1258 			insn.id = MIPS_INS_SLTU;
1259 			break;
1260 		default:
1261 		//	eprintf ("%llx %d\n", addr, optype);
1262 			break;
1263 		}
1264 		//family = 'R';
1265 	} else
1266 	if ((optype & 0x3e) == 2) {
1267 /*
1268 		// J-TYPE
1269 		 |--[0]--|  |--[1]--|  |--[2]--|  |--[3]--|
1270 		 1111 1111  1111 1111  1111 1111  1111 1111
1271 		 \_op__/\______address____________________/
1272                    |             |
1273                (buf[0]>>2)  ((buf[0]&3)<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3]
1274 */
1275 		// FIXME: what happens when addr is using a virtual map?
1276 		// ANS: address will be E 0x000000..0x0ffffffc
1277 		//      but addr could be anywhere
1278 		//      so address needs to be adjusted for that, somehow...
1279 		// MIPS is strange.  For example, the same code memory may be
1280 		// mapped simultaneously to 0x00600000 and 0x80600000.  The program is
1281 		// executing at 0x80600000 if we are operating in 'KSEG0' space
1282 		// (unmapped cached mode) vs 0x00600000 (KUSEG or user space)
1283 		// An immediate jump can only reach within 2^28 bits.
1284 		// HACK: if the user specified a mapping for the program
1285 		// then assume that they know which MIPS segment they
1286 		// are analysing in, and use the high order bits of addr
1287 		// to be add to the jump.
1288 		// WARNING: it is possible that this may not be the case
1289 		// in all situations!
1290 		// Maybe better solution: use a cfg. variable to do
1291 		// the offset... but I dont yet know how to get to that
1292 		// from this static function
1293 		int address = (((buf[0]&3)<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3]) << 2;
1294 		ut64 page_hack = addr & 0xf0000000;
1295 
1296 		switch (optype) {
1297 		case 2: // j
1298 			insn.id = MIPS_INS_J;
1299 			op->type = R_ANAL_OP_TYPE_JMP;
1300 			op->jump = page_hack + address;
1301 			op->delay = 1;
1302 			snprintf ((char *)insn.j_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump);
1303 			break;
1304 		case 3: // jal
1305 			insn.id = MIPS_INS_JAL;
1306 			op->type = R_ANAL_OP_TYPE_CALL;
1307 			op->jump = page_hack + address;
1308 			op->fail = addr + 8;
1309 			op->delay = 1;
1310 			snprintf ((char *)insn.j_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump);
1311 			break;
1312 		}
1313 		//family = 'J';
1314 	} else if ((optype & 0x3c) == 0x10) {
1315 /*
1316 	C-TYPE
1317 	======
1318 	opcode (6) format (5) ft (5) fs (5) fd (5) function (6)
1319 
1320 		 |--[0]--|  |--[1]--|  |--[2]--|  |--[3]--|
1321 		 1111 1111  1111 1111  1111 1111  1111 1111
1322 		 \_op__/\_fmt_/\_ft_/  \_fs_/\_fd__/\_fun_/
1323 		   |      |      |       |      |      |
1324 		 buf[0]>>2  |  (buf[1]&31)   |      |   buf[3]&63
1325 		          |          (buf[2]>>3)  |
1326 		  (buf[0]&3)<<3)+(buf[1]>>5)   (buf[2]&7)+(buf[3]>>6)
1327 */
1328 #if WIP
1329 		int fmt = ((buf[0]&3)<<3) + (buf[1]>>5);
1330 		int ft = (buf[1]&31);
1331 		int fs = (buf[2]>>3);
1332 		int fd = (buf[2]&7)+(buf[3]>>6);
1333 #endif
1334 		int fun = (buf[3]&63);
1335 		//family = 'C';
1336 		switch (fun) {
1337 		case 0: // mtc1
1338 			break;
1339 		case 1: // sub.s
1340 			break;
1341 		case 2: // mul.s
1342 			break;
1343 		case 3: // div.s
1344 			break;
1345 		// ....
1346 		}
1347 	} else {
1348 /*
1349 	I-TYPE
1350 	======
1351    	all opcodes but 000000 000001x and 0100xx
1352 	opcode (6)  rs (5)  rt (5) immediate (16)
1353 
1354 		 |--[0]--|  |--[1]--|  |--[2]--|  |--[3]--|
1355 		 1111 1111  1111 1111  1111 1111  1111 1111
1356 		 \_op__/\_rs__/\_rt_/  \_______imm________/
1357 		   |      |      |              |
1358 		 buf[0]>>2  |  (buf[1]&31)          |
1359 		          |                     |
1360 		 ((buf[0]&3)<<3)+(buf[1]>>5)   (buf[2]<<8)+buf[3]
1361 */
1362 		op->refptr = 0;
1363 		int rs = ((buf[0] & 3) << 3) + (buf[1] >> 5);
1364 		int rt = buf[1] & 31;
1365 		int imm = (buf[2] << 8) + buf[3];
1366 		if (((optype >> 2) ^ 0x3) && (imm & 0x8000)) {
1367 			imm = 0 - (0x10000 - imm);
1368 		}
1369 
1370 		insn.i_reg.rs = mips_reg_decode (rs);
1371 		insn.i_reg.rt = mips_reg_decode (rt);
1372 		snprintf ((char *)insn.i_reg.imm, REG_BUF_MAX, "%"PFMT32d, imm);
1373 
1374 		switch (optype) {
1375 		case 1:
1376 			switch (rt) {
1377 				case 0: //bltz
1378 					insn.id = MIPS_INS_BLTZ;
1379 					break;
1380 				case 1: //bgez
1381 					insn.id = MIPS_INS_BGEZ;
1382 					break;
1383 				case 17: //bal  bgezal
1384 					if (rs==0) {
1385 						op->jump = addr+(imm<<2)+4;
1386 						snprintf ((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump) ;
1387 						insn.id = MIPS_INS_BAL;
1388 					} else {
1389 						op->fail = addr+8;
1390 						insn.id = MIPS_INS_BGEZAL;
1391 					}
1392 					op->delay = 1;
1393 					op->type = R_ANAL_OP_TYPE_CALL;
1394 					break;
1395 				default:
1396 					op->delay = 1;
1397 					op->fail = addr+8;
1398 					break;
1399 			}
1400 			break;
1401 		case 4: // beq
1402 			if (!insn.id) {
1403 				insn.id = MIPS_INS_BEQ;
1404 				if(rt == 0) {
1405 					insn.id = MIPS_INS_BEQZ ;
1406 				}
1407 			}
1408 		case 5: // bne // also bnez
1409 			if (!insn.id) {
1410 				insn.id = MIPS_INS_BNE;
1411 				if(rt == 0) {
1412 					insn.id = MIPS_INS_BNEZ;
1413 				}
1414 			}
1415 		case 6: // blez
1416 			if (!insn.id) {
1417 				insn.id = MIPS_INS_BLEZ;
1418 			}
1419 		case 7: // bgtz
1420 			// XXX: use imm here
1421 			if (!insn.id) {
1422 				insn.id = MIPS_INS_BGTZ;
1423 			}
1424 			op->type = R_ANAL_OP_TYPE_CJMP;
1425 			op->jump = addr + (imm << 2) + 4;
1426 			op->fail = addr + 8;
1427 			op->delay = 1;
1428 
1429 			snprintf ((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump);
1430 			break;
1431 		// The following idiom is very common in mips 32 bit:
1432 		//
1433 		//     lui a0,0x8123
1434 		//     ; maybe other opcodes
1435 		//     ; maybe even a jump with branch delay
1436 		//     addui a0,a0,-12345
1437 		//
1438 		// Here, a0 might typically be any a0 or s0 register, and -12345 is a signed 16-bit number
1439 		// This is used to address const or static data in a 64kb page
1440 		// 0x8123 is the upper 16 bits of the register
1441 		// The net result: a0 := 0x8122cfc7
1442 		// The cases vary, so for now leave the smarts in a human generated macro to decide
1443 		// but the macro needs the opcode values as input
1444 		//
1445 		// TODO: this is a stop-gap. Really we need some smarts in here to tie this into the
1446 		// flags directly, as suggested here: https://github.com/radareorg/radare2/issues/949#issuecomment-43654922
1447 		case 15: // lui
1448 			insn.id = MIPS_INS_LUI;
1449 			snprintf ((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%"PFMT32x, imm);
1450 			op->dst = r_anal_value_new ();
1451 			op->dst->reg = r_reg_get (anal->reg, mips_reg_decode (rt), R_REG_TYPE_GPR);
1452 			// TODO: currently there is no way for the macro to get access to this register
1453 			op->val = imm;
1454 			break;
1455 		case 9: // addiu
1456 			insn.id = MIPS_INS_ADDIU;
1457 			op->type = R_ANAL_OP_TYPE_ADD;
1458 			op->dst = r_anal_value_new ();
1459 			op->dst->reg = r_reg_get (anal->reg, mips_reg_decode(rt), R_REG_TYPE_GPR);
1460 			// TODO: currently there is no way for the macro to get access to this register
1461 			op->src[0] = r_anal_value_new ();
1462 			op->src[0]->reg = r_reg_get (anal->reg, mips_reg_decode(rs), R_REG_TYPE_GPR);
1463 			op->val = imm; // Beware: this one is signed... use `?vi $v`
1464 			if (rs == 0) {
1465 				insn.id = MIPS_INS_LI;
1466 				snprintf ((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%"PFMT32x, imm);
1467 			}
1468 			break;
1469 		case 8: // addi
1470 			insn.id = MIPS_INS_ADDI;
1471 			op->type = R_ANAL_OP_TYPE_ADD;
1472 			break;
1473 		case 10: // slti
1474 			insn.id = MIPS_INS_SLTI;
1475 			break;
1476 		case 11: // sltiu
1477 			insn.id = MIPS_INS_SLTIU;
1478 			break;
1479 		case 12: // andi
1480 			insn.id = MIPS_INS_ANDI;
1481 			op->type = R_ANAL_OP_TYPE_AND;
1482 			break;
1483 		case 13: // ori
1484 			insn.id = MIPS_INS_ORI;
1485 			op->type = R_ANAL_OP_TYPE_OR;
1486 			break;
1487 		case 14: // xori
1488 			insn.id = MIPS_INS_XORI;
1489 			op->type = R_ANAL_OP_TYPE_XOR;
1490 			break;
1491 		case 24: // daddi
1492 			insn.id = MIPS_INS_DADDI;
1493 			op->type = R_ANAL_OP_TYPE_ADD;
1494 			break;
1495 		case 25: // daddiu
1496 			insn.id = MIPS_INS_DADDIU;
1497 			op->type = R_ANAL_OP_TYPE_ADD;
1498 			if (rs == 0) {
1499 				insn.id = MIPS_INS_LDI;
1500 				snprintf ((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%"PFMT32x, imm);
1501 			}
1502 			break;
1503 		case 32: // lb
1504 			op->refptr =  1;
1505 			insn.id = MIPS_INS_LB;
1506 			 /* fallthrough */
1507 		case 33: // lh
1508 			if (!op->refptr) {
1509 				op->refptr =  2;
1510 				insn.id = MIPS_INS_LB;
1511 			}
1512 			 /* fallthrough */
1513 		case 35: // lw
1514 			if (!op->refptr) {
1515 				op->refptr =  4;
1516 				insn.id = MIPS_INS_LW;
1517 			}
1518 			 /* fallthrough */
1519 		case 55: // ld
1520 			if (!op->refptr) {
1521 				op->refptr =  8;
1522 				insn.id = MIPS_INS_LD;
1523 			}
1524 
1525 			if (rs == 28) {
1526 				op->ptr = anal->gp + imm;
1527 			} else {
1528 				op->ptr = imm;
1529 			}
1530 			if (rt == 25) {
1531 				t9_pre = op->ptr;
1532 			}
1533 			op->type = R_ANAL_OP_TYPE_LOAD;
1534 			break;
1535 		case 36: // lbu
1536 			insn.id = MIPS_INS_LBU;
1537 			op->type = R_ANAL_OP_TYPE_LOAD;
1538 			break;
1539 		case 37: // lhu
1540 			insn.id = MIPS_INS_LHU;
1541 			op->type = R_ANAL_OP_TYPE_LOAD;
1542 			break;
1543 		case 40: // sb
1544 			insn.id = MIPS_INS_SB;
1545 			op->type = R_ANAL_OP_TYPE_STORE;
1546 			break;
1547 		case 41: // sh
1548 			insn.id = MIPS_INS_SH;
1549 			op->type = R_ANAL_OP_TYPE_STORE;
1550 			break;
1551 		case 43: // sw
1552 			insn.id = MIPS_INS_SW;
1553 			op->type = R_ANAL_OP_TYPE_STORE;
1554 			break;
1555 		case 63: //sd
1556 			insn.id = MIPS_INS_SD;
1557 			op->type = R_ANAL_OP_TYPE_STORE;
1558 			break;
1559 		case 49: // lwc1
1560 		case 57: // swc1
1561 			break;
1562 		case 29: // jalx
1563 			insn.id = MIPS_INS_JALX;
1564 			op->type = R_ANAL_OP_TYPE_CALL;
1565 			op->jump = addr + 4*((buf[3] | buf[2]<<8 | buf[1]<<16));
1566 			op->fail = addr + 8;
1567 			op->delay = 1;
1568 			snprintf ((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%"PFMT64x, op->jump);
1569 
1570 			break;
1571 		}
1572 		//family = 'I';
1573 	}
1574 
1575 	if (mask & R_ANAL_OP_MASK_ESIL) {
1576 		if (analop_esil (anal, op, addr, &insn)) {
1577 			r_strbuf_fini (&op->esil);
1578 		}
1579 	}
1580 	if (mask & R_ANAL_OP_MASK_VAL) {
1581 		//TODO: add op_fillval (anal, op, &insn);
1582 	}
1583 	return oplen;
1584 /*
1585  R - all instructions that only take registers as arguments (jalr, jr)
1586      opcode 000000
1587      opcode (6) 	rs (5) 	rt (5) 	rd (5) 	sa (5) 	function (6)
1588 		add 	rd, rs, rt 	100000
1589 		addu 	rd, rs, rt 	100001
1590 		and 	rd, rs, rt 	100100
1591 		break 		001101
1592 		div 	rs, rt 	011010
1593 		divu 	rs, rt 	011011
1594 		jalr 	rd, rs 	001001
1595 		jr 	rs 	001000
1596 
1597 		mfhi 	rd 	010000
1598 		mflo 	rd 	010010
1599 		mthi 	rs 	010001
1600 		mtlo 	rs 	010011
1601 		mult 	rs, rt 	011000
1602 		multu 	rs, rt 	011001
1603 
1604 		nor 	rd, rs, rt 	100111
1605 		or 	rd, rs, rt 	100101
1606 		sll 	rd, rt, sa 	000000
1607 		sllv 	rd, rt, rs 	000100
1608 		slt 	rd, rs, rt 	101010
1609 		sltu 	rd, rs, rt 	101011
1610 
1611 		sra 	rd, rt, sa 	000011
1612 		srav 	rd, rt, rs 	000111
1613 
1614 		srl 	rd, rt, sa 	000010
1615 		srlv 	rd, rt, rs 	000110
1616 
1617 		sub 	rd, rs, rt 	100010
1618 		subu 	rd, rs, rt 	100011
1619 		syscall 		001100
1620 		xor 	rd, rs, rt 	100110
1621  I - instructions with immediate operand, load/store/..
1622      all opcodes but 000000 000001x and 0100xx
1623      opcode (6) 	rs (5) 	rt (5) 	immediate (16)
1624 		addi 	rt, rs, immediate 	001000
1625 		addiu 	rt, rs, immediate 	001001
1626 		andi 	rt, rs, immediate 	001100
1627 		beq 	rs, rt, label 	000100
1628 
1629 		bgez 	rs, label 	000001 	rt = 00001
1630 
1631 		bgtz 	rs, label 	000111 	rt = 00000
1632 		blez 	rs, label 	000110 	rt = 00000
1633 
1634 		bltz 	rs, label 	000001 	rt = 00000
1635 		bne 	rs, rt, label 	000101
1636 		lb 	rt, immediate(rs) 	100000
1637 		lbu 	rt, immediate(rs) 	100100
1638 
1639 		lh 	rt, immediate(rs) 	100001
1640 		lhu 	rt, immediate(rs) 	100101
1641 
1642 		lui 	rt, immediate 	 	001111
1643 
1644 		lw 	rt, immediate(rs) 	100011
1645 		lwc1 	rt, immediate(rs) 	110001
1646 
1647 		ori 	rt, rs, immediate 	001101
1648 		sb 	rt, immediate(rs) 	101000
1649 
1650 		slti 	rt, rs, immediate 	001010
1651 		sltiu 	rt, rs, immediate 	001011
1652 		sh 	rt, immediate(rs) 	101001
1653 		sw 	rt, immediate(rs) 	101011
1654 		swc1 	rt, immediate(rs) 	111001
1655 		xori 	rt, rs, immediate 	001110
1656  J - require memory address like j, jal
1657      00001x
1658      opcode (6) 	target (26)
1659 		j 	label 	000010 	coded address of label
1660 		jal 	label 	000011 	coded address of label
1661  C - coprocessor insutrctions that use cp0, cp1, ..
1662      0100xx
1663      opcode (6) 	format (5) 	ft (5) 	fs (5) 	fd (5) 	function (6)
1664 		add.s 	fd, fs, ft 	000000 	10000
1665 		cvt.s.w	fd, fs, ft 	100000 	10100
1666 		cvt.w.s	fd, fs, ft 	100100 	10000
1667 		div.s 	fd, fs, ft 	000011 	10000
1668 		mfc1 	ft, fs 		000000 	00000
1669 		mov.s 	fd, fs 		000110 	10000
1670 		mtc1 	ft, fs 		000000 	00100
1671 		mul.s 	fd, fs, ft 	000010 	10000
1672 		sub.s 	fd, fs, ft 	000001 	10000
1673 */
1674 	return op->size;
1675 }
1676 /* Set the profile register */
mips_set_reg_profile(RAnal * anal)1677 static bool mips_set_reg_profile(RAnal* anal){
1678      const char *p =
1679 #if 0
1680           "=PC    pc\n"
1681 	  "=SP    sp\n"
1682 	  "=A0    a0\n"
1683 	  "=A1    a1\n"
1684 	  "=A2    a2\n"
1685 	  "=A3    a3\n"
1686 	  "gpr	zero	.32	0	0\n"
1687 	  "gpr	at	.32	4	0\n"
1688 	  "gpr	v0	.32	8	0\n"
1689 	  "gpr	v1	.32	12	0\n"
1690 	  "gpr	a0	.32	16	0\n"
1691 	  "gpr	a1	.32	20	0\n"
1692 	  "gpr	a2	.32	24	0\n"
1693 	  "gpr	a3	.32	28	0\n"
1694 	  "gpr	t0	.32	32	0\n"
1695 	  "gpr	t1	.32	36	0\n"
1696 	  "gpr	t2 	.32	40	0\n"
1697 	  "gpr	t3 	.32	44	0\n"
1698 	  "gpr	t4 	.32	48	0\n"
1699 	  "gpr	t5 	.32	52	0\n"
1700 	  "gpr	t6 	.32	56	0\n"
1701 	  "gpr	t7 	.32	60	0\n"
1702 	  "gpr	s0	.32	64	0\n"
1703 	  "gpr	s1	.32	68	0\n"
1704 	  "gpr	s2 	.32	72	0\n"
1705 	  "gpr	s3 	.32	76	0\n"
1706 	  "gpr	s4 	.32	80	0\n"
1707 	  "gpr	s5 	.32	84	0\n"
1708 	  "gpr	s6 	.32	88	0\n"
1709 	  "gpr	s7 	.32	92	0\n"
1710 	  "gpr	t8 	.32	96	0\n"
1711 	  "gpr	t9 	.32	100	0\n"
1712 	  "gpr	k0 	.32	104	0\n"
1713 	  "gpr	k1 	.32	108	0\n"
1714 	  "gpr	gp 	.32	112	0\n"
1715 	  "gpr	sp	.32	116	0\n"
1716 	  "gpr	fp	.32	120	0\n"
1717 	  "gpr	ra	.32	124	0\n"
1718 	  "gpr	pc	.32	128	0\n";
1719 #else
1720      // take the one from the debugger //
1721 	"=PC	pc\n"
1722 	"=SP	sp\n"
1723 	"=BP	fp\n"
1724 	"=A0	a0\n"
1725 	"=A1	a1\n"
1726 	"=A2	a2\n"
1727 	"=A3	a3\n"
1728 	"gpr	zero	.64	0	0\n"
1729 	// XXX DUPPED CAUSES FAILURE "gpr	at	.32	8	0\n"
1730 	"gpr	at	.64	8	0\n"
1731 	"gpr	v0	.64	16	0\n"
1732 	"gpr	v1	.64	24	0\n"
1733 	/* args */
1734 	"gpr	a0	.64	32	0\n"
1735 	"gpr	a1	.64	40	0\n"
1736 	"gpr	a2	.64	48	0\n"
1737 	"gpr	a3	.64	56	0\n"
1738 	/* tmp */
1739 	"gpr	t0	.64	64	0\n"
1740 	"gpr	t1	.64	72	0\n"
1741 	"gpr	t2	.64	80	0\n"
1742 	"gpr	t3	.64	88	0\n"
1743 	"gpr	t4	.64	96	0\n"
1744 	"gpr	t5	.64	104	0\n"
1745 	"gpr	t6	.64	112	0\n"
1746 	"gpr	t7	.64	120	0\n"
1747 	/* saved */
1748 	"gpr	s0	.64	128	0\n"
1749 	"gpr	s1	.64	136	0\n"
1750 	"gpr	s2	.64	144	0\n"
1751 	"gpr	s3	.64	152	0\n"
1752 	"gpr	s4	.64	160	0\n"
1753 	"gpr	s5	.64	168	0\n"
1754 	"gpr	s6	.64	176	0\n"
1755 	"gpr	s7	.64	184	0\n"
1756 	"gpr	t8	.64	192	0\n"
1757 	"gpr	t9	.64	200	0\n"
1758 	/* special */
1759 	"gpr	k0	.64	208	0\n"
1760 	"gpr	k1	.64	216	0\n"
1761 	"gpr	gp	.64	224	0\n"
1762 	"gpr	sp	.64	232	0\n"
1763 	"gpr	fp	.64	240	0\n"
1764 	"gpr	ra	.64	248	0\n"
1765 	/* extra */
1766 	"gpr	pc	.64	272	0\n"
1767 	;
1768 #endif
1769 	return r_reg_set_profile_string (anal->reg, p);
1770 }
1771 
archinfo(RAnal * anal,int q)1772 static int archinfo(RAnal *anal, int q) {
1773 	return 4;
1774 }
1775 
1776 RAnalPlugin r_anal_plugin_mips_gnu = {
1777 	.name = "mips.gnu",
1778 	.desc = "MIPS code analysis plugin",
1779 	.license = "LGPL3",
1780 	.arch = "mips",
1781 	.bits = 32,
1782 	.esil = true,
1783 	.archinfo = archinfo,
1784 	.op = &mips_op,
1785 	.set_reg_profile = mips_set_reg_profile,
1786 };
1787 
1788 #ifndef R2_PLUGIN_INCORE
1789 R_API RLibStruct radare_plugin = {
1790         .type = R_LIB_TYPE_ANAL,
1791         .data = &r_anal_plugin_mips_gnu
1792 };
1793 #endif
1794