1 /* radare - LGPL - Copyright 2012-2020 - pancake
2 2014 - Fedor Sakharov <fedor.sakharov@gmail.com> */
3
4 #include <string.h>
5 #include <r_types.h>
6 #include <r_lib.h>
7 #include <r_asm.h>
8 #include <r_anal.h>
9 #include <r_util.h>
10 #include <r_endian.h>
11
12 #include <v850_disas.h>
13
14 // Format I
15 #define F1_REG1(instr) ((instr) & 0x1F)
16 #define F1_REG2(instr) (((instr) & 0xF800) >> 11)
17
18 #define F1_RN1(instr) (V850_REG_NAMES[F1_REG1(instr)])
19 #define F1_RN2(instr) (V850_REG_NAMES[F1_REG2(instr)])
20
21 // Format II
22 #define F2_IMM(instr) F1_REG1(instr)
23 #define F2_REG2(instr) F1_REG2(instr)
24
25 #define F2_RN2(instr) (V850_REG_NAMES[F2_REG2(instr)])
26
27 // Format III
28 #define F3_COND(instr) ((instr) & 0xF)
29 #define F3_DISP(instr) (((instr) & 0x70) >> 4) | (((instr) & 0xF800) >> 7)
30
31 // Format IV
32 #define F4_DISP(instr) ((instr) & 0x3F)
33 #define F4_REG2(instr) F1_REG2(instr)
34
35 #define F4_RN2(instr) (V850_REG_NAMES[F4_REG2(instr)])
36
37 // Format V
38 #define F5_REG2(instr) F1_REG2(instr)
39 #define F5_DISP(instr) ((((ut32)(instr) & 0xffff) << 31) | (((ut32)(instr) & 0xffff0000) << 1))
40 #define F5_RN2(instr) (V850_REG_NAMES[F5_REG2(instr)])
41
42 // Format VI
43 #define F6_REG1(instr) F1_REG1(instr)
44 #define F6_REG2(instr) F1_REG2(instr)
45 #define F6_IMM(instr) (((instr) & 0xFFFF0000) >> 16)
46
47 #define F6_RN1(instr) (V850_REG_NAMES[F6_REG1(instr)])
48 #define F6_RN2(instr) (V850_REG_NAMES[F6_REG2(instr)])
49
50 // Format VII
51 #define F7_REG1(instr) F1_REG1(instr)
52 #define F7_REG2(instr) F1_REG2(instr)
53 #define F7_DISP(instr) F6_IMM(instr)
54
55 #define F7_RN1(instr) (V850_REG_NAMES[F7_REG1(instr)])
56 #define F7_RN2(instr) (V850_REG_NAMES[F7_REG2(instr)])
57
58 // Format VIII
59 #define F8_REG1(instr) F1_REG1(instr)
60 #define F8_DISP(instr) F6_IMM(instr)
61 #define F8_BIT(instr) (((instr) & 0x3800) >> 11)
62 #define F8_SUB(instr) (((instr) & 0xC000) >> 14)
63
64 #define F8_RN1(instr) (V850_REG_NAMES[F8_REG1(instr)])
65 #define F8_RN2(instr) (V850_REG_NAMES[F8_REG2(instr)])
66
67 // Format IX
68 // Also regID/cond
69 #define F9_REG1(instr) F1_REG1(instr)
70 #define F9_REG2(instr) F1_REG2(instr)
71 #define F9_SUB(instr) (((instr) & 0x7E00000) >> 21)
72
73 #define F9_RN1(instr) (V850_REG_NAMES[F9_REG1(instr)])
74 #define F9_RN2(instr) (V850_REG_NAMES[F9_REG2(instr)])
75 // TODO: Format X
76
77 // Format XI
78 #define F11_REG1(instr) F1_REG1(instr)
79 #define F11_REG2(instr) F1_REG2(instr)
80 #define F11_REG3(instr) (((instr) & 0xF8000000) >> 27)
81 #define F11_SUB(instr) ((((instr) & 0x7E00000) >> 20) | (((instr) & 2) >> 1))
82
83 #define F11_RN1(instr) (V850_REG_NAMES[F11_REG1(instr)])
84 #define F11_RN2(instr) (V850_REG_NAMES[F11_REG2(instr)])
85 // Format XII
86 #define F12_IMM(instr) (F1_REG1(instr) | (((instr) & 0x7C0000) >> 13))
87 #define F12_REG2(instr) F1_REG2(instr)
88 #define F12_REG3(instr) (((instr) & 0xF8000000) >> 27)
89 #define F12_SUB(instr) ((((instr) & 0x7800001) >> 22) | (((instr) & 2) >> 1))
90
91 #define F12_RN2(instr) (V850_REG_NAMES[F12_REG2(instr)])
92 #define F12_RN3(instr) (V850_REG_NAMES[F12_REG3(instr)])
93
94 // Format XIII
95 #define F13_IMM(instr) (((instr) & 0x3E) >> 1)
96 // Also a subopcode
97 #define F13_REG2(instr) (((instr) & 0x1F0000) >> 16)
98 #define F13_LIST(instr) (((instr) && 0xFFE00000) >> 21)
99
100 #define F13_RN2(instr) (V850_REG_NAMES[F13_REG2(instr)])
101
102 static const char* V850_REG_NAMES[] = {
103 "zero",
104 "r1",
105 "r2",
106 "r3",
107 "r4",
108 "r5",
109 "r6",
110 "r7",
111 "r8",
112 "r9",
113 "r10",
114 "r11",
115 "r12",
116 "r13",
117 "r14",
118 "r15",
119 "r16",
120 "r17",
121 "r18",
122 "r19",
123 "r20",
124 "r21",
125 "r22",
126 "r23",
127 "r24",
128 "r25",
129 "r26",
130 "r27",
131 "r28",
132 "r29",
133 "ep",
134 "lp",
135 };
136
update_flags(RAnalOp * op,int flags)137 static void update_flags(RAnalOp *op, int flags) {
138 if (flags & V850_FLAG_CY) {
139 r_strbuf_append (&op->esil, "31,$c,cy,:=");
140 }
141 if (flags & V850_FLAG_OV) {
142 r_strbuf_append (&op->esil, ",31,$o,ov,:=");
143 }
144 if (flags & V850_FLAG_S) {
145 r_strbuf_append (&op->esil, ",31,$s,s,:=");
146 }
147 if (flags & V850_FLAG_Z) {
148 r_strbuf_append (&op->esil, ",$z,z,:=");
149 }
150 }
151
clear_flags(RAnalOp * op,int flags)152 static void clear_flags(RAnalOp *op, int flags) {
153 if (flags & V850_FLAG_CY) {
154 r_strbuf_append (&op->esil, ",0,cy,=");
155 }
156 if (flags & V850_FLAG_OV) {
157 r_strbuf_append (&op->esil, ",0,ov,=");
158 }
159 if (flags & V850_FLAG_S) {
160 r_strbuf_append (&op->esil, ",0,s,=");
161 }
162 if (flags & V850_FLAG_Z) {
163 r_strbuf_append (&op->esil, ",0,z,=");
164 }
165 }
166
v850_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)167 static int v850_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
168 int ret = 0;
169 ut8 opcode = 0;
170 const char *reg1 = NULL;
171 const char *reg2 = NULL;
172 ut32 bitmask = 0;
173 ut16 destaddr = 0;
174 st16 destaddrs = 0;
175 ut16 word1 = 0, word2 = 0;
176 struct v850_cmd cmd;
177
178 if (len < 1 || (len > 0 && !memcmp (buf, "\xff\xff\xff\xff\xff\xff", R_MIN (len, 6)))) {
179 return -1;
180 }
181
182 memset (&cmd, 0, sizeof (cmd));
183
184 ret = op->size = v850_decode_command (buf, len, &cmd);
185
186 if (ret < 1) {
187 return ret;
188 }
189
190 op->addr = addr;
191
192 word1 = r_read_le16 (buf);
193 if (ret == 4) {
194 word2 = r_read_le16 (buf + 2);
195 }
196 opcode = get_opcode (word1);
197
198 switch (opcode) {
199 case V850_MOV_IMM5:
200 case V850_MOV:
201 // 2 formats
202 op->type = R_ANAL_OP_TYPE_MOV;
203 if (opcode != V850_MOV_IMM5) { // Format I
204 r_strbuf_appendf (&op->esil, "%s,%s,=", F1_RN1(word1), F1_RN2(word1));
205 } else { // Format II
206 r_strbuf_appendf (&op->esil, "%"PFMT64d",%s,=", (st64)(F2_IMM(word1)), F2_RN2(word1));
207 }
208 break;
209 case V850_MOVEA:
210 op->type = R_ANAL_OP_TYPE_MOV;
211 // FIXME: to decide about reading 16/32 bit and use only macros to access
212 r_strbuf_appendf (&op->esil, "%s,0xffff,&,%u,+,%s,=", F6_RN1(word1), word2, F6_RN2(word1));
213 break;
214 case V850_SLDB:
215 case V850_SLDH:
216 case V850_SLDW:
217 op->type = R_ANAL_OP_TYPE_LOAD;
218 if (F4_REG2(word1) == V850_SP) {
219 op->stackop = R_ANAL_STACK_GET;
220 op->stackptr = 0;
221 op->ptr = 0;
222 }
223 break;
224 case V850_SSTB:
225 case V850_SSTH:
226 case V850_SSTW:
227 op->type = R_ANAL_OP_TYPE_STORE;
228 if (F4_REG2(word1) == V850_SP) {
229 op->stackop = R_ANAL_STACK_SET;
230 op->stackptr = 0;
231 op->ptr = 0;
232 }
233 break;
234 case V850_NOT:
235 op->type = R_ANAL_OP_TYPE_NOT;
236 r_strbuf_appendf (&op->esil, "%s,0xffffffff,^,%s,=",F1_RN1(word1), F1_RN2(word1));
237 update_flags (op, V850_FLAG_S | V850_FLAG_Z);
238 clear_flags (op, V850_FLAG_OV);
239 break;
240 case V850_DIVH:
241 op->type = R_ANAL_OP_TYPE_DIV;
242 r_strbuf_appendf (&op->esil, "%s,%s,0xffff,&,/,%s,=",
243 F1_RN1(word1), F1_RN2(word1), F1_RN2(word1));
244 update_flags (op, V850_FLAG_OV | V850_FLAG_S | V850_FLAG_Z);
245 break;
246 case V850_JMP:
247 if (F1_REG1(word1) == 31) {
248 op->type = R_ANAL_OP_TYPE_RET;
249 } else {
250 op->type = R_ANAL_OP_TYPE_UJMP;
251 }
252 op->jump = word1; // UT64_MAX; // this is n RJMP instruction .. F1_RN1 (word1);
253 op->fail = addr + 2;
254 r_strbuf_appendf (&op->esil, "%s,pc,=", F1_RN1(word1));
255 break;
256 case V850_JARL2:
257 // TODO: fix displacement reading
258 op->type = R_ANAL_OP_TYPE_JMP;
259 op->jump = addr + F5_DISP(((ut32)word2 << 16) | word1);
260 op->fail = addr + 4;
261 r_strbuf_appendf (&op->esil, "pc,%s,=,pc,%u,+=", F5_RN2(word1), F5_DISP(((ut32)word2 << 16) | word1));
262 break;
263 #if 0 // WTF - same opcode as JARL?
264 case V850_JR:
265 jumpdisp = DISP26(word1, word2);
266 op->type = R_ANAL_OP_TYPE_JMP;
267 r_strbuf_appendf (&op->esil, "$$,%d,+,pc,=", jumpdisp);
268 break;
269 #endif
270 case V850_OR:
271 op->type = R_ANAL_OP_TYPE_OR;
272 r_strbuf_appendf (&op->esil, "%s,%s,|=", F1_RN1(word1), F1_RN2(word1));
273 update_flags (op, V850_FLAG_S | V850_FLAG_Z);
274 clear_flags (op, V850_FLAG_OV);
275 break;
276 case V850_ORI:
277 op->type = R_ANAL_OP_TYPE_OR;
278 r_strbuf_appendf (&op->esil, "%hu,%s,|,%s,=",
279 word2, F6_RN1(word1), F6_RN2(word1));
280 update_flags (op, V850_FLAG_S | V850_FLAG_Z);
281 clear_flags (op, V850_FLAG_OV);
282 break;
283 case V850_MULH:
284 case V850_MULH_IMM5:
285 op->type = R_ANAL_OP_TYPE_MUL;
286 break;
287 case V850_XOR:
288 op->type = R_ANAL_OP_TYPE_XOR;
289 r_strbuf_appendf (&op->esil, "%s,%s,^=", F1_RN1(word1), F1_RN2(word1));
290 update_flags (op, V850_FLAG_S | V850_FLAG_Z);
291 clear_flags (op, V850_FLAG_OV);
292 break;
293 case V850_XORI:
294 op->type = R_ANAL_OP_TYPE_XOR;
295 r_strbuf_appendf (&op->esil, "%hu,%s,^,%s,=", word2, F6_RN1(word1), F6_RN2(word1));
296 update_flags (op, V850_FLAG_S | V850_FLAG_Z);
297 clear_flags (op, V850_FLAG_OV);
298 break;
299 case V850_AND:
300 op->type = R_ANAL_OP_TYPE_AND;
301 r_strbuf_appendf (&op->esil, "%s,%s,&=", F1_RN1(word1), F1_RN2(word1));
302 update_flags (op, V850_FLAG_S | V850_FLAG_Z);
303 clear_flags (op, V850_FLAG_OV);
304 break;
305 case V850_ANDI:
306 op->type = R_ANAL_OP_TYPE_AND;
307 r_strbuf_appendf (&op->esil, "%hu,%s,&,%s,=", word2, F6_RN1(word1), F6_RN2(word1));
308 update_flags (op, V850_FLAG_Z);
309 clear_flags (op, V850_FLAG_OV | V850_FLAG_S);
310 break;
311 case V850_CMP:
312 op->type = R_ANAL_OP_TYPE_CMP;
313 r_strbuf_appendf (&op->esil, "%s,%s,==", F1_RN1(word1), F1_RN2(word1));
314 update_flags (op, -1);
315 break;
316 case V850_CMP_IMM5:
317 op->type = R_ANAL_OP_TYPE_CMP;
318 r_strbuf_appendf (&op->esil, "%d,%s,==", (st8)SEXT5(F2_IMM(word1)), F2_RN2(word1));
319 update_flags (op, -1);
320 break;
321 case V850_TST:
322 op->type = R_ANAL_OP_TYPE_CMP;
323 r_strbuf_appendf (&op->esil, "%s,%s,&", F1_RN1(word1), F1_RN2(word1));
324 update_flags (op, V850_FLAG_S | V850_FLAG_Z);
325 clear_flags (op, V850_FLAG_OV);
326 break;
327 case V850_SUB:
328 op->type = R_ANAL_OP_TYPE_SUB;
329 r_strbuf_appendf (&op->esil, "%s,%s,-=", F1_RN1(word1), F1_RN2(word1));
330 update_flags (op, -1);
331 break;
332 case V850_SUBR:
333 op->type = R_ANAL_OP_TYPE_SUB;
334 r_strbuf_appendf (&op->esil, "%s,%s,-,%s=", F1_RN2 (word1), F1_RN1 (word1), F1_RN2 (word1));
335 update_flags (op, -1);
336 break;
337 case V850_ADD:
338 op->type = R_ANAL_OP_TYPE_ADD;
339 r_strbuf_appendf (&op->esil, "%s,%s,+=", F1_RN1 (word1), F1_RN2 (word1));
340 update_flags (op, -1);
341 break;
342 case V850_ADD_IMM5:
343 op->type = R_ANAL_OP_TYPE_ADD;
344 if (F2_REG2(word1) == V850_SP) {
345 op->stackop = R_ANAL_STACK_INC;
346 op->stackptr = F2_IMM (word1);
347 op->val = op->stackptr;
348 }
349 r_strbuf_appendf (&op->esil, "%d,%s,+=", (st8)SEXT5(F2_IMM (word1)), F2_RN2 (word1));
350 update_flags (op, -1);
351 break;
352 case V850_ADDI:
353 op->type = R_ANAL_OP_TYPE_ADD;
354 if (F6_REG2(word1) == V850_SP) {
355 op->stackop = R_ANAL_STACK_INC;
356 op->stackptr = (st64) word2;
357 op->val = op->stackptr;
358 }
359 r_strbuf_appendf (&op->esil, "%d,%s,+,%s,=", (st32) word2, F6_RN1 (word1), F6_RN2 (word1));
360 update_flags (op, -1);
361 break;
362 case V850_SHR_IMM5:
363 op->type = R_ANAL_OP_TYPE_SHR;
364 r_strbuf_appendf (&op->esil, "%u,%s,>>=", (ut8)F2_IMM (word1), F2_RN2 (word1));
365 update_flags (op, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
366 clear_flags (op, V850_FLAG_OV);
367 break;
368 case V850_SAR_IMM5:
369 op->type = R_ANAL_OP_TYPE_SAR;
370 ut16 imm5 = F2_IMM(word1);
371 reg2 = F2_RN2(word1);
372 r_strbuf_appendf (&op->esil, "31,%s,>>,?{,%u,32,-,%u,1,<<,--,<<,}{,0,},%u,%s,>>,|,%s,=", reg2, (ut8)imm5, (ut8)imm5, (ut8)imm5, reg2, reg2);
373 update_flags (op, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
374 clear_flags (op, V850_FLAG_OV);
375 break;
376 case V850_SHL_IMM5:
377 op->type = R_ANAL_OP_TYPE_SHL;
378 r_strbuf_appendf (&op->esil, "%u,%s,<<=", (ut8)F2_IMM(word1), F2_RN2(word1));
379 update_flags (op, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
380 clear_flags (op, V850_FLAG_OV);
381 break;
382 case V850_BCOND:
383 case V850_BCOND2:
384 case V850_BCOND3:
385 case V850_BCOND4:
386 destaddr = ((((word1 >> 4) & 0x7) |
387 ((word1 >> 11) << 3)) << 1);
388 if (destaddr & 0x100) {
389 destaddrs = destaddr | 0xFE00;
390 } else {
391 destaddrs = destaddr;
392 }
393 op->jump = addr + destaddrs;
394 op->fail = addr + 2;
395 op->type = R_ANAL_OP_TYPE_CJMP;
396 switch (F3_COND(word1)) {
397 case V850_COND_V:
398 r_strbuf_appendf (&op->esil, "ov");
399 break;
400 case V850_COND_CL:
401 r_strbuf_appendf (&op->esil, "cy");
402 break;
403 case V850_COND_ZE:
404 r_strbuf_appendf (&op->esil, "z");
405 break;
406 case V850_COND_NH:
407 r_strbuf_appendf (&op->esil, "cy,z,|");
408 break;
409 case V850_COND_N:
410 r_strbuf_appendf (&op->esil, "s");
411 break;
412 case V850_COND_AL: // Always
413 r_strbuf_appendf (&op->esil, "1");
414 break;
415 case V850_COND_LT:
416 r_strbuf_appendf (&op->esil, "s,ov,^");
417 break;
418 case V850_COND_LE:
419 r_strbuf_appendf (&op->esil, "s,ov,^,z,|");
420 break;
421 case V850_COND_NV:
422 r_strbuf_appendf (&op->esil, "ov,!");
423 break;
424 case V850_COND_NL:
425 r_strbuf_appendf (&op->esil, "cy,!");
426 break;
427 case V850_COND_NE:
428 r_strbuf_appendf (&op->esil, "z,!");
429 break;
430 case V850_COND_H:
431 r_strbuf_appendf (&op->esil, "cy,z,|,!");
432 break;
433 case V850_COND_P:
434 r_strbuf_appendf (&op->esil, "s,!");
435 break;
436 case V850_COND_GE:
437 r_strbuf_appendf (&op->esil, "s,ov,^,!");
438 break;
439 case V850_COND_GT:
440 r_strbuf_appendf (&op->esil, "s,ov,^,z,|,!");
441 break;
442 }
443 r_strbuf_appendf (&op->esil, ",?{,$$,%d,+,pc,=,}", destaddrs);
444 break;
445 case V850_BIT_MANIP:
446 {
447 ut8 bitop = word1 >> 14;
448 switch (bitop) {
449 case V850_BIT_CLR1:
450 bitmask = (1 << F8_BIT(word1));
451 r_strbuf_appendf (&op->esil, "%hu,%s,+,[1],%u,&,%hu,%s,+,=[1]", word2, F8_RN1(word1), bitmask, word2, F8_RN1(word1));
452 // TODO: Read the value of the memory byte and set zero flag accordingly!
453 break;
454 case V850_BIT_NOT1:
455 bitmask = (1 << F8_BIT(word1));
456 r_strbuf_appendf (&op->esil, "%hu,%s,+,[1],%u,^,%hu,%s,+,=[1]", word2, F8_RN1(word1), bitmask, word2, F8_RN1(word1));
457 // TODO: Read the value of the memory byte and set zero flag accordingly!
458 break;
459 }
460 }
461 break;
462 case V850_EXT1:
463 switch (get_subopcode(word1 | (ut32)word2 << 16)) {
464 case V850_EXT_SHL:
465 op->type = R_ANAL_OP_TYPE_SHL;
466 r_strbuf_appendf (&op->esil, "%s,%s,<<=", F9_RN1(word1), F9_RN2(word1));
467 update_flags (op, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
468 clear_flags (op, V850_FLAG_OV);
469 break;
470 case V850_EXT_SHR:
471 op->type = R_ANAL_OP_TYPE_SHR;
472 r_strbuf_appendf (&op->esil, "%s,%s,>>=", F9_RN1(word1), F9_RN2(word1));
473 update_flags (op, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
474 clear_flags (op, V850_FLAG_OV);
475 break;
476 case V850_EXT_SAR:
477 op->type = R_ANAL_OP_TYPE_SAR;
478 reg1 = F9_RN1(word1);
479 reg2 = F9_RN2(word1);
480 r_strbuf_appendf (&op->esil, "31,%s,>>,?{,%s,32,-,%s,1,<<,--,<<,}{,0,},%s,%s,>>,|,%s,=", reg2, reg1, reg1, reg1, reg2, reg2);
481 update_flags (op, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
482 clear_flags (op, V850_FLAG_OV);
483 break;
484 }
485 break;
486 }
487
488 return ret;
489 }
490
get_reg_profile(RAnal * anal)491 static char *get_reg_profile(RAnal *anal) {
492 const char *p =
493 "=PC pc\n"
494 "=SP r3\n"
495 "=ZF z\n"
496 "=A0 r1\n"
497 "=A1 r5\n"
498 "=A2 r6\n"
499 "=A3 r7\n"
500 "=A4 r8\n"
501 "=SF s\n"
502 "=OF ov\n"
503 "=CF cy\n"
504
505 "gpr zero .32 ? 0\n"
506 "gpr r0 .32 0 0\n"
507 "gpr r1 .32 4 0\n"
508 "gpr r2 .32 8 0\n"
509 "gpr r3 .32 12 0\n"
510 "gpr sp .32 12 0\n"
511 "gpr r4 .32 16 0\n"
512 "gpr gp .32 16 0\n"
513 "gpr r5 .32 20 0\n"
514 "gpr tp .32 20 0\n"
515 "gpr r6 .32 24 0\n"
516 "gpr r7 .32 28 0\n"
517 "gpr r8 .32 32 0\n"
518 "gpr r9 .32 36 0\n"
519 "gpr r10 .32 40 0\n"
520 "gpr r11 .32 44 0\n"
521 "gpr r12 .32 48 0\n"
522 "gpr r13 .32 52 0\n"
523 "gpr r14 .32 56 0\n"
524 "gpr r15 .32 60 0\n"
525 "gpr r16 .32 64 0\n"
526 "gpr r17 .32 68 0\n"
527 "gpr r18 .32 72 0\n"
528 "gpr r19 .32 76 0\n"
529 "gpr r20 .32 80 0\n"
530 "gpr r21 .32 84 0\n"
531 "gpr r22 .32 88 0\n"
532 "gpr r23 .32 92 0\n"
533 "gpr r24 .32 96 0\n"
534 "gpr r25 .32 100 0\n"
535 "gpr r26 .32 104 0\n"
536 "gpr r27 .32 108 0\n"
537 "gpr r28 .32 112 0\n"
538 "gpr r29 .32 116 0\n"
539 "gpr r30 .32 120 0\n"
540 "gpr ep .32 120 0\n"
541 "gpr r31 .32 124 0\n"
542 "gpr lp .32 124 0\n"
543 "gpr pc .32 128 0\n"
544
545 "gpr psw .32 132 0\n"
546 "gpr np .1 132.16 0\n"
547 "gpr ep .1 132.17 0\n"
548 "gpr ae .1 132.18 0\n"
549 "gpr id .1 132.19 0\n"
550 "flg cy .1 132.28 0\n"
551 "flg ov .1 132.29 0\n"
552 "flg s .1 132.30 0\n"
553 "flg z .1 132.31 0\n";
554 return strdup (p);
555 }
556
anal_preludes(RAnal * anal)557 static RList *anal_preludes(RAnal *anal) {
558 #define KW(d,ds,m,ms) r_list_append (l, r_search_keyword_new((const ut8*)d,ds,(const ut8*)m, ms, NULL))
559 RList *l = r_list_newf ((RListFree)r_search_keyword_free);
560 KW ("\x80\x07", 2, "\xf0\xff", 2);
561 KW ("\x50\x1a\x63\x0f", 4, "\xf0\xff\xff\x0f", 4);
562 return l;
563 }
564
archinfo(RAnal * anal,int q)565 static int archinfo(RAnal *anal, int q) {
566 switch (q) {
567 case R_ANAL_ARCHINFO_ALIGN:
568 return 2;
569 case R_ANAL_ARCHINFO_MAX_OP_SIZE:
570 return 8;
571 case R_ANAL_ARCHINFO_MIN_OP_SIZE:
572 return 2;
573 }
574 return 0;
575 }
576
577 RAnalPlugin r_anal_plugin_v850 = {
578 .name = "v850",
579 .desc = "V850 code analysis plugin",
580 .license = "LGPL3",
581 .preludes = anal_preludes,
582 .arch = "v850",
583 .bits = 32,
584 .op = v850_op,
585 .esil = true,
586 .archinfo = archinfo,
587 .get_reg_profile = get_reg_profile,
588 };
589
590 #ifndef R2_PLUGIN_INCORE
591 R_API RLibStruct radare_plugin = {
592 .type = R_LIB_TYPE_ANAL,
593 .data = &r_anal_plugin_v850,
594 .version = R2_VERSION
595 };
596 #endif
597