1 /* radare - LGPL - Copyright 2016-2017 - bobby.smiles32@gmail.com */
2 /*
3 * TODO: finish esil support of the non vector instructions
4 * TODO: implement vector instruction using custom esil commands
5 * (will be easier than pure esil approach)
6 * TODO: refactor code to simplify per opcode analysis
7 */
8
9 #include <string.h>
10 #include <r_types.h>
11 #include <r_lib.h>
12 #include <r_asm.h>
13 #include <r_anal.h>
14 #include "../../asm/arch/rsp/rsp_idec.h"
15
rsp_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * b,int len,RAnalOpMask mask)16 static int rsp_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len, RAnalOpMask mask) {
17 int i;
18 typedef struct {
19 RAnalValue* value;
20 char esil[32];
21 } ParsedOperands;
22
23 ParsedOperands parsed_operands[RSP_MAX_OPNDS];
24 memset (parsed_operands, 0, sizeof (ParsedOperands) * RSP_MAX_OPNDS);
25 ut32 iw;
26 rsp_instruction r_instr;
27
28 if (!op) {
29 return 4;
30 }
31
32 op->type = R_ANAL_OP_TYPE_UNK;
33 op->size = 4;
34 op->addr = addr;
35 r_strbuf_set (&op->esil, "TODO");
36
37 iw = r_read_ble32 (b, anal->big_endian);
38 r_instr = rsp_instruction_decode (addr, iw);
39
40 /* parse operands */
41 for (i = 0; i < r_instr.noperands; i++) {
42 parsed_operands[i].value = r_anal_value_new ();
43 parsed_operands[i].esil[0] = '\0';
44
45 switch (r_instr.operands[i].type) {
46 case RSP_OPND_GP_REG:
47 snprintf (parsed_operands[i].esil, sizeof (parsed_operands[i].esil), "%s", rsp_gp_reg_soft_names[r_instr.operands[i].u]);
48 parsed_operands[i].value->reg = r_reg_get (anal->reg, rsp_gp_reg_soft_names[r_instr.operands[i].u], R_REG_TYPE_GPR);
49 break;
50 case RSP_OPND_ZIMM:
51 case RSP_OPND_SHIFT_AMOUNT:
52 snprintf (parsed_operands[i].esil, sizeof (parsed_operands[i].esil), "%"PFMT64d, r_instr.operands[i].u);
53 parsed_operands[i].value->imm = op->val = r_instr.operands[i].u;
54 break;
55 case RSP_OPND_SIMM:
56 snprintf (parsed_operands[i].esil, sizeof (parsed_operands[i].esil), "%"PFMT64d, r_instr.operands[i].s);
57 parsed_operands[i].value->imm = op->val = r_instr.operands[i].s;
58 break;
59 case RSP_OPND_BASE_OFFSET:
60 snprintf (parsed_operands[i].esil, sizeof (parsed_operands[i].esil),
61 "%"PFMT64d",%s,+", r_instr.operands[i].s, rsp_gp_reg_soft_names[r_instr.operands[i].u]);
62 parsed_operands[i].value->reg = r_reg_get (anal->reg, rsp_gp_reg_soft_names[r_instr.operands[i].u], R_REG_TYPE_GPR);
63 parsed_operands[i].value->imm = r_instr.operands[i].s;
64 break;
65 case RSP_OPND_OFFSET:
66 case RSP_OPND_TARGET:
67 op->delay = 1;
68 op->jump = r_instr.operands[i].u;
69 op->fail = rsp_mem_addr (addr + 8, RSP_IMEM_OFFSET);
70 op->eob = 1;
71 snprintf (parsed_operands[i].esil, sizeof (parsed_operands[i].esil), "%"PFMT64d, r_instr.operands[i].u);
72 parsed_operands[i].value->imm = r_instr.operands[i].u;
73 parsed_operands[i].value->memref = 4;
74 break;
75 case RSP_OPND_C0_REG:
76 snprintf (parsed_operands[i].esil, sizeof (parsed_operands[i].esil), "%s", rsp_c0_reg_names[r_instr.operands[i].u]);
77 parsed_operands[i].value->reg = r_reg_get (anal->reg, rsp_c0_reg_names[r_instr.operands[i].u], R_REG_TYPE_GPR);
78 break;
79 case RSP_OPND_C2_CREG:
80 case RSP_OPND_C2_ACCU:
81 case RSP_OPND_C2_VREG:
82 case RSP_OPND_C2_VREG_BYTE:
83 case RSP_OPND_C2_VREG_SCALAR:
84 case RSP_OPND_C2_VREG_ELEMENT:
85 /* TODO */
86 break;
87 }
88 }
89
90 switch (r_instr.opcode) {
91 case RSP_OP_INVALID:
92 op->type = R_ANAL_OP_TYPE_ILL;
93 break;
94 case RSP_OP_NOP:
95 op->type = R_ANAL_OP_TYPE_NOP;
96 r_strbuf_set (&op->esil, ",");
97 break;
98 case RSP_OP_BREAK:
99 op->type = R_ANAL_OP_TYPE_TRAP;
100 // TODO
101 break;
102 case RSP_OP_LUI:
103 op->type = R_ANAL_OP_TYPE_MOV;
104 op->dst = parsed_operands[0].value;
105 op->src[0] = parsed_operands[1].value;
106 r_strbuf_setf (&op->esil, "%s,%s,=", parsed_operands[1].esil, parsed_operands[0].esil);
107 break;
108 case RSP_OP_ADD:
109 case RSP_OP_ADDU:
110 case RSP_OP_ADDI:
111 case RSP_OP_ADDIU:
112 op->type = R_ANAL_OP_TYPE_ADD;
113 op->dst = parsed_operands[0].value;
114 op->src[0] = parsed_operands[1].value;
115 op->src[1] = parsed_operands[2].value;
116 r_strbuf_setf (&op->esil, "%s,%s,+,%s,=", parsed_operands[2].esil, parsed_operands[1].esil, parsed_operands[0].esil);
117 break;
118 case RSP_OP_SUB:
119 case RSP_OP_SUBU:
120 op->type = R_ANAL_OP_TYPE_SUB;
121 op->dst = parsed_operands[0].value;
122 op->src[0] = parsed_operands[1].value;
123 op->src[1] = parsed_operands[2].value;
124 r_strbuf_setf (&op->esil, "%s,%s,-,%s,=", parsed_operands[2].esil, parsed_operands[1].esil, parsed_operands[0].esil);
125 break;
126 case RSP_OP_AND:
127 case RSP_OP_ANDI:
128 op->type = R_ANAL_OP_TYPE_AND;
129 op->dst = parsed_operands[0].value;
130 op->src[0] = parsed_operands[1].value;
131 op->src[1] = parsed_operands[2].value;
132 r_strbuf_setf (&op->esil, "%s,%s,&,%s,=", parsed_operands[2].esil, parsed_operands[1].esil, parsed_operands[0].esil);
133 break;
134 case RSP_OP_OR:
135 case RSP_OP_ORI:
136 op->type = R_ANAL_OP_TYPE_OR;
137 op->dst = parsed_operands[0].value;
138 op->src[0] = parsed_operands[1].value;
139 op->src[1] = parsed_operands[2].value;
140 r_strbuf_setf (&op->esil, "%s,%s,|,%s,=", parsed_operands[2].esil, parsed_operands[1].esil, parsed_operands[0].esil);
141 break;
142 case RSP_OP_XOR:
143 case RSP_OP_XORI:
144 op->type = R_ANAL_OP_TYPE_XOR;
145 op->dst = parsed_operands[0].value;
146 op->src[0] = parsed_operands[1].value;
147 op->src[1] = parsed_operands[2].value;
148 r_strbuf_setf (&op->esil, "%s,%s,^,%s,=", parsed_operands[2].esil, parsed_operands[1].esil, parsed_operands[0].esil);
149 break;
150 case RSP_OP_NOR:
151 op->type = R_ANAL_OP_TYPE_NOR;
152 op->dst = parsed_operands[0].value;
153 op->src[0] = parsed_operands[1].value;
154 op->src[1] = parsed_operands[2].value;
155 // TODO
156 break;
157 case RSP_OP_SLL:
158 case RSP_OP_SLLV:
159 op->type = R_ANAL_OP_TYPE_SHL;
160 op->dst = parsed_operands[0].value;
161 op->src[0] = parsed_operands[1].value;
162 op->src[1] = parsed_operands[2].value;
163 r_strbuf_setf (&op->esil, "%s,%s,<<,%s,=", parsed_operands[2].esil, parsed_operands[1].esil, parsed_operands[0].esil);
164 break;
165 case RSP_OP_SRL:
166 case RSP_OP_SRLV:
167 op->type = R_ANAL_OP_TYPE_SHR;
168 op->dst = parsed_operands[0].value;
169 op->src[0] = parsed_operands[1].value;
170 op->src[1] = parsed_operands[2].value;
171 r_strbuf_setf (&op->esil, "%s,%s,>>,%s,=", parsed_operands[2].esil, parsed_operands[1].esil, parsed_operands[0].esil);
172 break;
173 case RSP_OP_SRA:
174 case RSP_OP_SRAV:
175 op->type = R_ANAL_OP_TYPE_SAR;
176 op->dst = parsed_operands[0].value;
177 op->src[0] = parsed_operands[1].value;
178 op->src[1] = parsed_operands[2].value;
179 // TODO
180 break;
181 case RSP_OP_SLT:
182 case RSP_OP_SLTU:
183 case RSP_OP_SLTI:
184 case RSP_OP_SLTIU:
185 op->type = R_ANAL_OP_TYPE_CMOV;
186 op->cond = R_ANAL_COND_LT;
187 op->dst = parsed_operands[0].value;
188 op->src[0] = parsed_operands[1].value;
189 op->src[1] = parsed_operands[2].value;
190 r_strbuf_setf (&op->esil, "%s,%s,<,$z,?{,1,%s,=,}{,0,%s,=,}", parsed_operands[2].esil, parsed_operands[1].esil, parsed_operands[0].esil, parsed_operands[0].esil);
191 break;
192 case RSP_OP_J:
193 op->type = R_ANAL_OP_TYPE_JMP;
194 op->dst = r_anal_value_new ();
195 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
196 op->src[0] = parsed_operands[0].value;
197 r_strbuf_setf (&op->esil, "%s,PC,=", parsed_operands[0].esil);
198 break;
199 case RSP_OP_JAL:
200 op->type = R_ANAL_OP_TYPE_CALL;
201 op->dst = r_anal_value_new ();
202 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
203 op->src[0] = parsed_operands[0].value;
204 r_strbuf_setf (&op->esil, "%s,PC,=,0x%08" PFMT64x ",RA,=", parsed_operands[0].esil, op->fail);
205 break;
206 case RSP_OP_JR:
207 /* if register is RA, this is a return */
208 op->type = (r_instr.operands[0].u == 29)
209 ? R_ANAL_OP_TYPE_RET
210 : R_ANAL_OP_TYPE_UJMP;
211 op->delay = 1;
212 op->eob = 1;
213 op->fail = rsp_mem_addr (addr + 8, RSP_IMEM_OFFSET);
214 op->dst = r_anal_value_new ();
215 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
216 op->src[0] = parsed_operands[0].value;
217 r_strbuf_setf (&op->esil, "%s,PC,=", parsed_operands[0].esil);
218 break;
219 case RSP_OP_BEQ:
220 op->type = R_ANAL_OP_TYPE_CJMP;
221 op->cond = R_ANAL_COND_EQ;
222 op->dst = r_anal_value_new ();
223 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
224 op->src[0] = parsed_operands[0].value;
225 op->src[1] = parsed_operands[1].value;
226 r_strbuf_setf (&op->esil, "%s,%s,==,$z,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[1].esil, parsed_operands[2].esil);
227 break;
228 case RSP_OP_BNE:
229 op->type = R_ANAL_OP_TYPE_CJMP;
230 op->cond = R_ANAL_COND_NE;
231 op->dst = r_anal_value_new ();
232 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
233 op->src[0] = parsed_operands[0].value;
234 op->src[1] = parsed_operands[1].value;
235 r_strbuf_setf (&op->esil, "%s,%s,==,$z,!,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[1].esil, parsed_operands[2].esil);
236 break;
237 case RSP_OP_BLEZ:
238 op->type = R_ANAL_OP_TYPE_CJMP;
239 op->cond = R_ANAL_COND_LE;
240 op->dst = r_anal_value_new ();
241 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
242 op->src[0] = parsed_operands[0].value;
243 op->src[1] = parsed_operands[1].value;
244 r_strbuf_setf (&op->esil, "%s,!,%s,0x80000000,&,!,!,|,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[0].esil, parsed_operands[1].esil);
245 // r_strbuf_setf (&op->esil, "0,%s,<=,$z,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[1].esil);
246 break;
247 case RSP_OP_BGTZ:
248 op->type = R_ANAL_OP_TYPE_CJMP;
249 op->cond = R_ANAL_COND_GT;
250 op->dst = r_anal_value_new ();
251 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
252 op->src[0] = parsed_operands[0].value;
253 op->src[1] = parsed_operands[1].value;
254 r_strbuf_setf (&op->esil, "%s,0x80000000,&,!,%s,!,!,&,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[0].esil, parsed_operands[1].esil);
255 // r_strbuf_setf (&op->esil, "0,%s,>,$z,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[1].esil);
256 break;
257 case RSP_OP_BLTZ:
258 op->type = R_ANAL_OP_TYPE_CJMP;
259 op->cond = R_ANAL_COND_LT;
260 op->dst = r_anal_value_new ();
261 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
262 op->src[0] = parsed_operands[0].value;
263 op->src[1] = parsed_operands[1].value;
264 r_strbuf_setf (&op->esil, "%s,0x80000000,&,!,!,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[1].esil);
265 // r_strbuf_setf (&op->esil, "0,%s,<,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[1].esil);
266 break;
267 case RSP_OP_BGEZ:
268 op->type = R_ANAL_OP_TYPE_CJMP;
269 op->cond = R_ANAL_COND_GE;
270 op->dst = r_anal_value_new ();
271 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
272 op->src[0] = parsed_operands[0].value;
273 op->src[1] = parsed_operands[1].value;
274 r_strbuf_setf (&op->esil, "%s,0x80000000,&,!,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[1].esil);
275 // r_strbuf_setf (&op->esil, "0,%s,>=,?{,%s,PC,=,}", parsed_operands[0].esil, parsed_operands[1].esil);
276 break;
277 case RSP_OP_BLTZAL:
278 op->type = R_ANAL_OP_TYPE_CCALL;
279 op->cond = R_ANAL_COND_LT;
280 op->dst = r_anal_value_new ();
281 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
282 op->src[0] = parsed_operands[0].value;
283 op->src[1] = parsed_operands[1].value;
284 // TODO
285 break;
286 case RSP_OP_BGEZAL:
287 op->type = R_ANAL_OP_TYPE_CCALL;
288 op->cond = R_ANAL_COND_GE;
289 op->dst = r_anal_value_new ();
290 op->dst->reg = r_reg_get (anal->reg, "PC", R_REG_TYPE_GPR);
291 op->src[0] = parsed_operands[0].value;
292 op->src[1] = parsed_operands[1].value;
293 // TODO
294 break;
295 case RSP_OP_LB:
296 op->type = R_ANAL_OP_TYPE_LOAD;
297 op->dst = parsed_operands[0].value;
298 op->src[0] = parsed_operands[1].value;
299 op->src[0]->memref = op->refptr = 1;
300 // FIXME: sign extend
301 r_strbuf_setf (&op->esil, "%s,[1],%s,=", parsed_operands[1].esil, parsed_operands[0].esil);
302 break;
303 case RSP_OP_LH:
304 op->type = R_ANAL_OP_TYPE_LOAD;
305 op->dst = parsed_operands[0].value;
306 op->src[0] = parsed_operands[1].value;
307 op->src[0]->memref = op->refptr = 2;
308 // FIXME: sign extend
309 r_strbuf_setf (&op->esil, "%s,[2],%s,=", parsed_operands[1].esil, parsed_operands[0].esil);
310 break;
311 case RSP_OP_LW:
312 op->type = R_ANAL_OP_TYPE_LOAD;
313 op->dst = parsed_operands[0].value;
314 op->src[0] = parsed_operands[1].value;
315 op->src[0]->memref = op->refptr = 4;
316 r_strbuf_setf (&op->esil, "%s,[4],%s,=", parsed_operands[1].esil, parsed_operands[0].esil);
317 break;
318 case RSP_OP_LBU:
319 op->type = R_ANAL_OP_TYPE_LOAD;
320 op->dst = parsed_operands[0].value;
321 op->src[0] = parsed_operands[1].value;
322 op->src[0]->memref = op->refptr = 1;
323 r_strbuf_setf (&op->esil, "%s,[1],%s,=", parsed_operands[1].esil, parsed_operands[0].esil);
324 break;
325 case RSP_OP_LHU:
326 op->type = R_ANAL_OP_TYPE_LOAD;
327 op->dst = parsed_operands[0].value;
328 op->src[0] = parsed_operands[1].value;
329 op->src[0]->memref = op->refptr = 2;
330 r_strbuf_setf (&op->esil, "%s,[2],%s,=", parsed_operands[1].esil, parsed_operands[0].esil);
331 break;
332 case RSP_OP_SB:
333 op->type = R_ANAL_OP_TYPE_STORE;
334 op->src[0] = parsed_operands[0].value;
335 op->dst = parsed_operands[1].value;
336 op->dst->memref = op->refptr = 1;
337 r_strbuf_setf (&op->esil, "%s,%s,=[1]", parsed_operands[0].esil, parsed_operands[1].esil);
338 break;
339 case RSP_OP_SH:
340 op->type = R_ANAL_OP_TYPE_STORE;
341 op->src[0] = parsed_operands[0].value;
342 op->dst = parsed_operands[1].value;
343 op->dst->memref = op->refptr = 2;
344 r_strbuf_setf (&op->esil, "%s,%s,=[2]", parsed_operands[0].esil, parsed_operands[1].esil);
345 break;
346 case RSP_OP_SW:
347 op->type = R_ANAL_OP_TYPE_STORE;
348 op->src[0] = parsed_operands[0].value;
349 op->dst = parsed_operands[1].value;
350 op->dst->memref = op->refptr = 4;
351 r_strbuf_setf (&op->esil, "%s,%s,=[4]", parsed_operands[0].esil, parsed_operands[1].esil);
352 break;
353 case RSP_OP_MFC0:
354 op->type = R_ANAL_OP_TYPE_MOV;
355 op->dst = parsed_operands[0].value;
356 op->src[0] = parsed_operands[1].value;
357 r_strbuf_setf (&op->esil, "%s,%s,=", parsed_operands[1].esil, parsed_operands[0].esil);
358 break;
359 case RSP_OP_MTC0:
360 op->type = R_ANAL_OP_TYPE_MOV;
361 op->src[0] = parsed_operands[0].value;
362 op->dst = parsed_operands[1].value;
363 r_strbuf_setf (&op->esil, "%s,%s,=", parsed_operands[0].esil, parsed_operands[1].esil);
364 break;
365 case RSP_OP_MFC2:
366 op->type = R_ANAL_OP_TYPE_MOV;
367 op->dst = parsed_operands[0].value;
368 //op->src[0] = parsed_operands[1].value;
369 break;
370 case RSP_OP_MTC2:
371 op->type = R_ANAL_OP_TYPE_MOV;
372 op->src[0] = parsed_operands[0].value;
373 //op->dst = parsed_operands[1].value;
374 break;
375 case RSP_OP_CFC2:
376 op->type = R_ANAL_OP_TYPE_MOV;
377 break;
378 case RSP_OP_CTC2:
379 op->type = R_ANAL_OP_TYPE_MOV;
380 break;
381 case RSP_OP_VMULF:
382 op->type = R_ANAL_OP_TYPE_MUL;
383 break;
384 case RSP_OP_VMULU:
385 op->type = R_ANAL_OP_TYPE_MUL;
386 break;
387 case RSP_OP_VMUDL:
388 op->type = R_ANAL_OP_TYPE_MUL;
389 break;
390 case RSP_OP_VMUDM:
391 op->type = R_ANAL_OP_TYPE_MUL;
392 break;
393 case RSP_OP_VMUDN:
394 op->type = R_ANAL_OP_TYPE_MUL;
395 break;
396 case RSP_OP_VMUDH:
397 op->type = R_ANAL_OP_TYPE_MUL;
398 break;
399 case RSP_OP_VMACF:
400 op->type = R_ANAL_OP_TYPE_MUL;
401 break;
402 case RSP_OP_VMACU:
403 op->type = R_ANAL_OP_TYPE_MUL;
404 break;
405 case RSP_OP_VMADL:
406 op->type = R_ANAL_OP_TYPE_MUL;
407 break;
408 case RSP_OP_VMADM:
409 op->type = R_ANAL_OP_TYPE_MUL;
410 break;
411 case RSP_OP_VMADN:
412 op->type = R_ANAL_OP_TYPE_MUL;
413 break;
414 case RSP_OP_VMADH:
415 op->type = R_ANAL_OP_TYPE_MUL;
416 break;
417 case RSP_OP_VADD:
418 op->type = R_ANAL_OP_TYPE_ADD;
419 break;
420 case RSP_OP_VSUB:
421 op->type = R_ANAL_OP_TYPE_SUB;
422 break;
423 case RSP_OP_VABS:
424 op->type = R_ANAL_OP_TYPE_ABS;
425 break;
426 case RSP_OP_VADDC:
427 op->type = R_ANAL_OP_TYPE_ADD;
428 break;
429 case RSP_OP_VSUBC:
430 op->type = R_ANAL_OP_TYPE_SUB;
431 break;
432 case RSP_OP_VSAR:
433 op->type = R_ANAL_OP_TYPE_MOV;
434 break;
435 case RSP_OP_VLT:
436 op->type = R_ANAL_OP_TYPE_CMP;
437 op->cond = R_ANAL_COND_LT;
438 break;
439 case RSP_OP_VEQ:
440 op->type = R_ANAL_OP_TYPE_CMP;
441 op->cond = R_ANAL_COND_EQ;
442 break;
443 case RSP_OP_VNE:
444 op->type = R_ANAL_OP_TYPE_CMP;
445 op->cond = R_ANAL_COND_NE;
446 break;
447 case RSP_OP_VGE:
448 op->type = R_ANAL_OP_TYPE_CMP;
449 op->cond = R_ANAL_COND_GE;
450 break;
451 case RSP_OP_VCL:
452 op->type = R_ANAL_OP_TYPE_UNK;
453 break;
454 case RSP_OP_VCH:
455 op->type = R_ANAL_OP_TYPE_UNK;
456 break;
457 case RSP_OP_VCR:
458 op->type = R_ANAL_OP_TYPE_UNK;
459 break;
460 case RSP_OP_VMRG:
461 op->type = R_ANAL_OP_TYPE_UNK;
462 break;
463 case RSP_OP_VAND:
464 op->type = R_ANAL_OP_TYPE_AND;
465 break;
466 case RSP_OP_VNAND:
467 op->type = R_ANAL_OP_TYPE_AND;
468 break;
469 case RSP_OP_VOR:
470 op->type = R_ANAL_OP_TYPE_OR;
471 break;
472 case RSP_OP_VNOR:
473 op->type = R_ANAL_OP_TYPE_NOR;
474 break;
475 case RSP_OP_VXOR:
476 op->type = R_ANAL_OP_TYPE_XOR;
477 break;
478 case RSP_OP_VNXOR:
479 op->type = R_ANAL_OP_TYPE_XOR;
480 break;
481 case RSP_OP_VRCP:
482 op->type = R_ANAL_OP_TYPE_UNK;
483 break;
484 case RSP_OP_VRCPL:
485 op->type = R_ANAL_OP_TYPE_UNK;
486 break;
487 case RSP_OP_VRCPH:
488 op->type = R_ANAL_OP_TYPE_UNK;
489 break;
490 case RSP_OP_VMOV:
491 op->type = R_ANAL_OP_TYPE_MOV;
492 break;
493 case RSP_OP_VRSQ:
494 op->type = R_ANAL_OP_TYPE_UNK;
495 break;
496 case RSP_OP_VRSQL:
497 op->type = R_ANAL_OP_TYPE_UNK;
498 break;
499 case RSP_OP_VRSQH:
500 op->type = R_ANAL_OP_TYPE_UNK;
501 break;
502 case RSP_OP_VNOP:
503 op->type = R_ANAL_OP_TYPE_NOP;
504 break;
505 case RSP_OP_LBV:
506 op->type = R_ANAL_OP_TYPE_LOAD;
507 break;
508 case RSP_OP_LSV:
509 op->type = R_ANAL_OP_TYPE_LOAD;
510 break;
511 case RSP_OP_LLV:
512 op->type = R_ANAL_OP_TYPE_LOAD;
513 break;
514 case RSP_OP_LDV:
515 op->type = R_ANAL_OP_TYPE_LOAD;
516 break;
517 case RSP_OP_LQV:
518 op->type = R_ANAL_OP_TYPE_LOAD;
519 break;
520 case RSP_OP_LRV:
521 op->type = R_ANAL_OP_TYPE_LOAD;
522 break;
523 case RSP_OP_LPV:
524 op->type = R_ANAL_OP_TYPE_LOAD;
525 break;
526 case RSP_OP_LUV:
527 op->type = R_ANAL_OP_TYPE_LOAD;
528 break;
529 case RSP_OP_LHV:
530 op->type = R_ANAL_OP_TYPE_LOAD;
531 break;
532 case RSP_OP_LFV:
533 op->type = R_ANAL_OP_TYPE_LOAD;
534 break;
535 case RSP_OP_LTV:
536 op->type = R_ANAL_OP_TYPE_LOAD;
537 break;
538 case RSP_OP_SBV:
539 op->type = R_ANAL_OP_TYPE_STORE;
540 break;
541 case RSP_OP_SSV:
542 op->type = R_ANAL_OP_TYPE_STORE;
543 break;
544 case RSP_OP_SLV:
545 op->type = R_ANAL_OP_TYPE_STORE;
546 break;
547 case RSP_OP_SDV:
548 op->type = R_ANAL_OP_TYPE_STORE;
549 break;
550 case RSP_OP_SQV:
551 op->type = R_ANAL_OP_TYPE_STORE;
552 break;
553 case RSP_OP_SRV:
554 op->type = R_ANAL_OP_TYPE_STORE;
555 break;
556 case RSP_OP_SPV:
557 op->type = R_ANAL_OP_TYPE_STORE;
558 break;
559 case RSP_OP_SUV:
560 op->type = R_ANAL_OP_TYPE_STORE;
561 break;
562 case RSP_OP_SHV:
563 op->type = R_ANAL_OP_TYPE_STORE;
564 break;
565 case RSP_OP_SFV:
566 op->type = R_ANAL_OP_TYPE_STORE;
567 break;
568 case RSP_OP_SWV:
569 op->type = R_ANAL_OP_TYPE_STORE;
570 break;
571 case RSP_OP_STV:
572 op->type = R_ANAL_OP_TYPE_STORE;
573 break;
574 default: break;
575 }
576
577 return op->size;
578 }
579
580
get_reg_profile(RAnal * anal)581 static char *get_reg_profile(RAnal *anal) {
582 static const char *p =
583 "=PC pc\n"
584 "=SP sp\n"
585 "=A0 a0\n"
586 "=A1 a1\n"
587 "=A2 a2\n"
588 "=A3 a3\n"
589 "=R0 v0\n"
590 "=R1 v1\n"
591 /* GP registers */
592 "gpr zero .32 0 0\n"
593 "gpr at .32 4 0\n"
594 "gpr v0 .32 8 0\n"
595 "gpr v1 .32 12 0\n"
596 "gpr a0 .32 16 0\n"
597 "gpr a1 .32 20 0\n"
598 "gpr a2 .32 24 0\n"
599 "gpr a3 .32 28 0\n"
600 "gpr t0 .32 32 0\n"
601 "gpr t1 .32 36 0\n"
602 "gpr t2 .32 40 0\n"
603 "gpr t3 .32 44 0\n"
604 "gpr t4 .32 48 0\n"
605 "gpr t5 .32 52 0\n"
606 "gpr t6 .32 56 0\n"
607 "gpr t7 .32 60 0\n"
608 "gpr s0 .32 64 0\n"
609 "gpr s1 .32 68 0\n"
610 "gpr s2 .32 72 0\n"
611 "gpr s3 .32 76 0\n"
612 "gpr s4 .32 80 0\n"
613 "gpr s5 .32 84 0\n"
614 "gpr s6 .32 88 0\n"
615 "gpr s7 .32 92 0\n"
616 "gpr t8 .32 96 0\n"
617 "gpr t9 .32 100 0\n"
618 "gpr k0 .32 104 0\n"
619 "gpr k1 .32 108 0\n"
620 "gpr gp .32 112 0\n"
621 "gpr sp .32 116 0\n"
622 "gpr s8 .32 120 0\n"
623 "gpr ra .32 124 0\n"
624 /* PC register */
625 "gpr pc .32 128 0\n"
626 /* C0 registers */
627 "gpr $c0 .32 132 0\n"
628 "gpr $c1 .32 136 0\n"
629 "gpr $c2 .32 140 0\n"
630 "gpr $c3 .32 144 0\n"
631 "gpr $c4 .32 148 0\n"
632 "gpr $c5 .32 152 0\n"
633 "gpr $c6 .32 156 0\n"
634 "gpr $c7 .32 160 0\n"
635 "gpr $c8 .32 164 0\n"
636 "gpr $c9 .32 168 0\n"
637 "gpr $c10 .32 172 0\n"
638 "gpr $c11 .32 176 0\n"
639 "gpr $c12 .32 180 0\n"
640 "gpr $c13 .32 184 0\n"
641 "gpr $c14 .32 188 0\n"
642 "gpr $c15 .32 192 0\n"
643 /* C2 vector registers - (32 x 128 bit) */
644 "gpr $v0 .128 196 0\n"
645 "gpr $v1 .128 212 0\n"
646 "gpr $v2 .128 228 0\n"
647 "gpr $v3 .128 244 0\n"
648 "gpr $v4 .128 260 0\n"
649 "gpr $v5 .128 276 0\n"
650 "gpr $v6 .128 292 0\n"
651 "gpr $v7 .128 308 0\n"
652 "gpr $v8 .128 324 0\n"
653 "gpr $v9 .128 340 0\n"
654 "gpr $v10 .128 356 0\n"
655 "gpr $v11 .128 372 0\n"
656 "gpr $v12 .128 388 0\n"
657 "gpr $v13 .128 404 0\n"
658 "gpr $v14 .128 420 0\n"
659 "gpr $v15 .128 436 0\n"
660 "gpr $v16 .128 452 0\n"
661 "gpr $v17 .128 468 0\n"
662 "gpr $v18 .128 484 0\n"
663 "gpr $v19 .128 500 0\n"
664 "gpr $v20 .128 516 0\n"
665 "gpr $v21 .128 532 0\n"
666 "gpr $v22 .128 548 0\n"
667 "gpr $v23 .128 564 0\n"
668 "gpr $v24 .128 580 0\n"
669 "gpr $v25 .128 596 0\n"
670 "gpr $v26 .128 612 0\n"
671 "gpr $v27 .128 628 0\n"
672 "gpr $v28 .128 644 0\n"
673 "gpr $v29 .128 660 0\n"
674 "gpr $v30 .128 676 0\n"
675 "gpr $v31 .128 692 0\n"
676 /* C2 control registers - (vco, vcc, vce) */
677 "gpr $vco .128 708 0\n"
678 "gpr $vcc .128 724 0\n"
679 "gpr $vce .128 740 0\n"
680 ;
681
682 return strdup (p);
683 }
684
archinfo(RAnal * anal,int q)685 static int archinfo(RAnal *anal, int q) {
686 return 4;
687 }
688
689 RAnalPlugin r_anal_plugin_rsp = {
690 .name = "rsp",
691 .desc = "RSP code analysis plugin",
692 .license = "LGPL3",
693 .arch = "rsp",
694 .esil = true,
695 .bits = 32,
696 .op = &rsp_op,
697 .archinfo = &archinfo,
698 .get_reg_profile = &get_reg_profile,
699 };
700
701 #ifndef R2_PLUGIN_INCORE
702 R_API RLibStruct radare_plugin = {
703 .type = R_LIB_TYPE_ANAL,
704 .data = &r_anal_plugin_rsp,
705 .version = R2_VERSION
706 };
707 #endif
708