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