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