1 /* radare - LGPL - Copyright 2011-2019 - pancake, Roc Valles, condret, killabyte */
2 
3 #if 0
4 http://www.atmel.com/images/atmel-0856-avr-instruction-set-manual.pdf
5 https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set
6 #endif
7 
8 #include <string.h>
9 #include <r_types.h>
10 #include <r_util.h>
11 #include <r_crypto.h>
12 #include <r_lib.h>
13 #include <r_asm.h>
14 #include <r_anal.h>
15 
16 #include "../../asm/arch/avr/disasm.h"
17 
18 static RDESContext desctx;
19 
20 typedef struct _cpu_const_tag {
21 	const char *const key;
22 	ut8 type;
23 	ut32 value;
24 	ut8 size;
25 } CPU_CONST;
26 
27 #define CPU_CONST_NONE	0
28 #define CPU_CONST_PARAM	1
29 #define CPU_CONST_REG	2
30 
31 typedef struct _cpu_model_tag {
32 	const char *const model;
33 	int pc;
34 	char *inherit;
35 	struct _cpu_model_tag *inherit_cpu_p;
36 	CPU_CONST *consts[10];
37 } CPU_MODEL;
38 
39 typedef void (*inst_handler_t) (RAnal *anal, RAnalOp *op, const ut8 *buf, int len, int *fail, CPU_MODEL *cpu);
40 
41 typedef struct _opcodes_tag_ {
42 	const char *const name;
43 	int mask;
44 	int selector;
45 	inst_handler_t handler;
46 	int cycles;
47 	int size;
48 	ut64 type;
49 } OPCODE_DESC;
50 
51 static OPCODE_DESC* avr_op_analyze(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, CPU_MODEL *cpu);
52 
53 #define CPU_MODEL_DECL(model, pc, consts)				\
54 	{								\
55 		model,							\
56 		pc,							\
57 		consts							\
58 	}
59 #define MASK(bits)			((bits) == 32 ? 0xffffffff : (~((~((ut32) 0)) << (bits))))
60 #define CPU_PC_MASK(cpu)		MASK((cpu)->pc)
61 #define CPU_PC_SIZE(cpu)		((((cpu)->pc) >> 3) + ((((cpu)->pc) & 0x07) ? 1 : 0))
62 
63 #define INST_HANDLER(OPCODE_NAME)	static void _inst__ ## OPCODE_NAME (RAnal *anal, RAnalOp *op, const ut8 *buf, int len, int *fail, CPU_MODEL *cpu)
64 #define INST_DECL(OP, M, SL, C, SZ, T)	{ #OP, (M), (SL), _inst__ ## OP, (C), (SZ), R_ANAL_OP_TYPE_ ## T }
65 #define INST_LAST			{ "unknown", 0, 0, (void *) 0, 2, 1, R_ANAL_OP_TYPE_UNK }
66 
67 #define INST_CALL(OPCODE_NAME)		_inst__ ## OPCODE_NAME (anal, op, buf, len, fail, cpu)
68 #define INST_INVALID			{ *fail = 1; return; }
69 #define INST_ASSERT(x)			{ if (!(x)) { INST_INVALID; } }
70 
71 #define ESIL_A(e, ...)			r_strbuf_appendf (&op->esil, e, ##__VA_ARGS__)
72 
73 #define STR_BEGINS(in, s)		r_str_ncasecmp (in, s, strlen (s))
74 
75 // Following IO definitions are valid for:
76 //	ATmega8
77 //	ATmega88
78 CPU_CONST cpu_reg_common[] = {
79 	{ "spl",    CPU_CONST_REG, 0x3d, sizeof (ut8) },
80 	{ "sph",    CPU_CONST_REG, 0x3e, sizeof (ut8) },
81 	{ "sreg",   CPU_CONST_REG, 0x3f, sizeof (ut8) },
82 	{ "spmcsr", CPU_CONST_REG, 0x37, sizeof (ut8) },
83 	{ NULL, 0, 0, 0 },
84 };
85 
86 CPU_CONST cpu_memsize_common[] = {
87 	{ "eeprom_size", CPU_CONST_PARAM,  512, sizeof (ut32) },
88 	{ "io_size",     CPU_CONST_PARAM, 0x40, sizeof (ut32) },
89 	{ "sram_start",  CPU_CONST_PARAM, 0x60, sizeof (ut32) },
90 	{ "sram_size",   CPU_CONST_PARAM, 1024, sizeof (ut32) },
91 	{ NULL, 0, 0, 0 },
92 };
93 
94 CPU_CONST cpu_memsize_m640_m1280m_m1281_m2560_m2561[] = {
95 	{ "eeprom_size", CPU_CONST_PARAM,    512, sizeof (ut32) },
96 	{ "io_size",     CPU_CONST_PARAM,  0x1ff, sizeof (ut32) },
97 	{ "sram_start",  CPU_CONST_PARAM,  0x200, sizeof (ut32) },
98 	{ "sram_size",   CPU_CONST_PARAM, 0x2000, sizeof (ut32) },
99 	{ NULL, 0, 0, 0 },
100 };
101 
102 CPU_CONST cpu_memsize_xmega128a4u[] = {
103 	{ "eeprom_size", CPU_CONST_PARAM,  0x800, sizeof (ut32) },
104 	{ "io_size",     CPU_CONST_PARAM, 0x1000, sizeof (ut32) },
105 	{ "sram_start",  CPU_CONST_PARAM,  0x800, sizeof (ut32) },
106 	{ "sram_size",   CPU_CONST_PARAM, 0x2000, sizeof (ut32) },
107 	{ NULL, 0, 0, 0 },
108 };
109 
110 CPU_CONST cpu_pagesize_5_bits[] = {
111 	{ "page_size", CPU_CONST_PARAM, 5, sizeof (ut8) },
112 	{ NULL, 0, 0, 0 },
113 };
114 
115 CPU_CONST cpu_pagesize_7_bits[] = {
116 	{ "page_size", CPU_CONST_PARAM, 7, sizeof (ut8) },
117 	{ NULL, 0, 0, 0 },
118 };
119 
120 CPU_MODEL cpu_models[] = {
121 	{ .model = "ATmega640",   .pc = 15,
122 		.consts = {
123 			cpu_reg_common,
124 			cpu_memsize_m640_m1280m_m1281_m2560_m2561,
125 			cpu_pagesize_7_bits,
126 			NULL
127 		},
128 	},
129 	{
130 		.model = "ATxmega128a4u", .pc = 17,
131 		.consts = {
132 			cpu_reg_common,
133 			cpu_memsize_xmega128a4u,
134 			cpu_pagesize_7_bits,
135 			NULL
136 		}
137 	},
138 	{ .model = "ATmega1280",  .pc = 16, .inherit = "ATmega640" },
139 	{ .model = "ATmega1281",  .pc = 16, .inherit = "ATmega640" },
140 	{ .model = "ATmega2560",  .pc = 17, .inherit = "ATmega640" },
141 	{ .model = "ATmega2561",  .pc = 17, .inherit = "ATmega640" },
142 	{ .model = "ATmega88",    .pc = 8,  .inherit = "ATmega8" },
143 //	CPU_MODEL_DECL ("ATmega168",   13, 512, 512),
144 	// last model is the default AVR - ATmega8 forever!
145 	{
146 		.model = "ATmega8", .pc = 13,
147 		.consts = {
148 			cpu_reg_common,
149 			cpu_memsize_common,
150 			cpu_pagesize_5_bits,
151 			NULL
152 		}
153 	},
154 };
155 
156 static CPU_MODEL *get_cpu_model(char *model);
157 
__get_cpu_model_recursive(char * model)158 static CPU_MODEL *__get_cpu_model_recursive(char *model) {
159 	CPU_MODEL *cpu = NULL;
160 
161 	for (cpu = cpu_models; cpu < cpu_models + ((sizeof (cpu_models) / sizeof (CPU_MODEL))) - 1; cpu++) {
162 		if (!r_str_casecmp (model, cpu->model)) {
163 			break;
164 		}
165 	}
166 
167 	// fix inheritance tree
168 	if (cpu->inherit && !cpu->inherit_cpu_p) {
169 		cpu->inherit_cpu_p = get_cpu_model (cpu->inherit);
170 		if (!cpu->inherit_cpu_p) {
171 			eprintf ("ERROR: Cannot inherit from unknown CPU model '%s'.\n", cpu->inherit);
172 		}
173 	}
174 
175 	return cpu;
176 }
177 
get_cpu_model(char * model)178 static CPU_MODEL *get_cpu_model(char *model) {
179 	static CPU_MODEL *cpu = NULL;
180 	// cached value?
181 	if (cpu && !r_str_casecmp (model, cpu->model)) {
182 		return cpu;
183 	}
184 	// do the real search
185 	cpu = __get_cpu_model_recursive (model);
186 	return cpu;
187 }
188 
const_get_value(CPU_CONST * c)189 static ut32 const_get_value(CPU_CONST *c) {
190 	return c ? MASK (c->size * 8) & c->value : 0;
191 }
192 
193 
const_by_name(CPU_MODEL * cpu,int type,char * c)194 static CPU_CONST *const_by_name(CPU_MODEL *cpu, int type, char *c) {
195 	CPU_CONST **clist, *citem;
196 
197 	for (clist = cpu->consts; *clist; clist++) {
198 		for (citem = *clist; citem->key; citem++) {
199 			if (!strcmp (c, citem->key)
200 			&& (type == CPU_CONST_NONE || type == citem->type)) {
201 				return citem;
202 			}
203 		}
204 	}
205 	if (cpu->inherit_cpu_p) {
206 		return const_by_name (cpu->inherit_cpu_p, type, c);
207 	}
208 	eprintf ("ERROR: CONSTANT key[%s] NOT FOUND.\n", c);
209 	return NULL;
210 }
211 
__esil_pop_argument(RAnalEsil * esil,ut64 * v)212 static int __esil_pop_argument(RAnalEsil *esil, ut64 *v) {
213 	char *t = r_anal_esil_pop (esil);
214 	if (!t || !r_anal_esil_get_parm (esil, t, v)) {
215 		free (t);
216 		return false;
217 	}
218 	free (t);
219 	return true;
220 }
221 
const_by_value(CPU_MODEL * cpu,int type,ut32 v)222 static CPU_CONST *const_by_value(CPU_MODEL *cpu, int type, ut32 v) {
223 	CPU_CONST **clist, *citem;
224 
225 	for (clist = cpu->consts; *clist; clist++) {
226 		for (citem = *clist; citem && citem->key; citem++) {
227 			if (citem->value == (MASK (citem->size * 8) & v)
228 			&& (type == CPU_CONST_NONE || type == citem->type)) {
229 				return citem;
230 			}
231 		}
232 	}
233 	if (cpu->inherit_cpu_p) {
234 		return const_by_value (cpu->inherit_cpu_p, type, v);
235 	}
236 	return NULL;
237 }
238 
__generic_io_dest(ut8 port,int write,CPU_MODEL * cpu)239 static RStrBuf *__generic_io_dest(ut8 port, int write, CPU_MODEL *cpu) {
240 	RStrBuf *r = r_strbuf_new ("");
241 	CPU_CONST *c = const_by_value (cpu, CPU_CONST_REG, port);
242 	if (c != NULL) {
243 		r_strbuf_set (r, c->key);
244 		if (write) {
245 			r_strbuf_append (r, ",=");
246 		}
247 	} else {
248 		r_strbuf_setf (r, "_io,%d,+,%s[1]", port, write ? "=" : "");
249 	}
250 
251 	return r;
252 }
253 
__generic_ld_st(RAnalOp * op,char * mem,char ireg,int use_ramp,int prepostdec,int offset,int st)254 static void __generic_ld_st(RAnalOp *op, char *mem, char ireg, int use_ramp, int prepostdec, int offset, int st) {
255 	if (ireg) {
256 		// preincrement index register
257 		if (prepostdec < 0) {
258 			ESIL_A ("1,%c,-,%c,=,", ireg, ireg);
259 		}
260 		// set register index address
261 		ESIL_A ("%c,", ireg);
262 		// add offset
263 		if (offset != 0) {
264 			ESIL_A ("%d,+,", offset);
265 		}
266 	} else {
267 		ESIL_A ("%d,", offset);
268 	}
269 	if (use_ramp) {
270 		ESIL_A ("16,ramp%c,<<,+,", ireg ? ireg : 'd');
271 	}
272 	// set SRAM base address
273 	ESIL_A ("_%s,+,", mem);
274 	// read/write from SRAM
275 	ESIL_A ("%s[1],", st ? "=" : "");
276 	// postincrement index register
277 	if (ireg && prepostdec > 0) {
278 		ESIL_A ("1,%c,+,%c,=,", ireg, ireg);
279 	}
280 }
281 
__generic_pop(RAnalOp * op,int sz)282 static void __generic_pop(RAnalOp *op, int sz) {
283 	if (sz > 1) {
284 		ESIL_A ("1,sp,+,_ram,+,");	// calc SRAM(sp+1)
285 		ESIL_A ("[%d],", sz);		// read value
286 		ESIL_A ("%d,sp,+=,", sz);	// sp += item_size
287 	} else {
288 		ESIL_A ("1,sp,+=,"		// increment stack pointer
289 			"sp,_ram,+,[1],");	// load SRAM[sp]
290 	}
291 }
292 
__generic_push(RAnalOp * op,int sz)293 static void __generic_push(RAnalOp *op, int sz) {
294 	ESIL_A ("sp,_ram,+,");			// calc pointer SRAM(sp)
295 	if (sz > 1) {
296 		ESIL_A ("-%d,+,", sz - 1);	// dec SP by 'sz'
297 	}
298 	ESIL_A ("=[%d],", sz);			// store value in stack
299 	ESIL_A ("-%d,sp,+=,", sz);		// decrement stack pointer
300 }
301 
INST_HANDLER(adc)302 INST_HANDLER (adc) {	// ADC Rd, Rr
303 			// ROL Rd
304 	if (len < 2) {
305 		return;
306 	}
307 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
308 	const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
309 	ESIL_A ("r%d,cf,+,r%d,+=,", r, d);		// Rd + Rr + C
310 	ESIL_A ("$z,zf,:=,");
311 	ESIL_A ("3,$c,hf,:=,");
312 	ESIL_A ("7,$c,cf,:=,");
313 	ESIL_A ("7,$o,vf,:=,");
314 	ESIL_A ("0x80,r%d,&,!,!,nf,:=", d);
315 }
316 
INST_HANDLER(add)317 INST_HANDLER (add) {	// ADD Rd, Rr
318 			// LSL Rd
319 	if (len < 2) {
320 		return;
321 	}
322 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
323 	const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
324 	ESIL_A ("r%d,r%d,+=,", r, d);			// Rd + Rr
325 	ESIL_A ("$z,zf,:=,");
326 	ESIL_A ("3,$c,hf,:=,");
327 	ESIL_A ("7,$c,cf,:=,");
328 	ESIL_A ("7,$o,vf,:=,");
329 	ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
330 }
331 
INST_HANDLER(adiw)332 INST_HANDLER (adiw) {	// ADIW Rd+1:Rd, K
333 	if (len < 1) {
334 		return;
335 	}
336 	const ut32 d = ((buf[0] & 0x30) >> 3) + 24;
337 	const ut32 k = (buf[0] & 0x0f) | ((buf[0] >> 2) & 0x30);
338 	op->val = k;
339 	ESIL_A ("%d,r%d_r%d,+=,", k, d + 1, d);			// Rd+1_Rd + k
340 								// FLAGS:
341 	ESIL_A ("7,$o,vf,:=,");					// V
342 	ESIL_A ("r%d_r%d,0x8000,&,!,!,nf,:=,", d + 1, d);	// N
343 	ESIL_A ("$z,zf,:=,");					// Z
344 	ESIL_A ("15,$c,cf,:=,");				// C
345 	ESIL_A ("vf,nf,^,sf,:=");				// S
346 }
347 
INST_HANDLER(and)348 INST_HANDLER (and) {	// AND Rd, Rr
349 			// TST Rd
350 	if (len < 2) {
351 		return;
352 	}
353 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
354 	const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
355 	ESIL_A ("r%d,r%d,&=,$z,zf,:=,r%d,0x80,&,!,!,nf,:=,0,vf,:=,nf,sf,:=,", r, d, d);
356 }
357 
INST_HANDLER(andi)358 INST_HANDLER (andi) {	// ANDI Rd, K
359 			// CBR Rd, K (= ANDI Rd, 1-K)
360 	if (len < 2) {
361 		return;
362 	}
363 	const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
364 	const ut32 k = ((buf[1] & 0x0f) << 4) | (buf[0] & 0x0f);
365 	op->val = k;
366 	ESIL_A ("%d,r%d,&=,$z,zf,:=,r%d,0x80,&,!,!,nf,:=,0,vf,:=,nf,sf,:=,", k, d, d);
367 }
368 
INST_HANDLER(asr)369 INST_HANDLER (asr) {	// ASR Rd
370 	if (len < 2) {
371 		return;
372 	}
373 	int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
374 	ESIL_A ("r%d,0x1,&,cf,:=,0x1,r%d,>>,r%d,0x80,&,|,", d, d, d);
375 								// 0: R=(Rd >> 1) | Rd7
376 	ESIL_A ("$z,zf,:=,");					// Z
377 	ESIL_A ("r%d,0x80,&,!,!,nf,:=,", d);			// N
378 	ESIL_A ("nf,cf,^,vf,:=,");				// V
379 	ESIL_A ("nf,vf,^,sf,:=,");				// S
380 }
381 
INST_HANDLER(bclr)382 INST_HANDLER (bclr) {	// BCLR s
383 			// CLC
384 			// CLH
385 			// CLI
386 			// CLN
387 			// CLR
388 			// CLS
389 			// CLT
390 			// CLV
391 			// CLZ
392 	if (len < 1) {
393 		return;
394 	}
395 	int s = (buf[0] >> 4) & 0x7;
396 	ESIL_A ("0xff,%d,1,<<,^,sreg,&=,", s);
397 }
398 
INST_HANDLER(bld)399 INST_HANDLER (bld) {	// BLD Rd, b
400 	if (len < 2) {
401 		return;
402 	}
403 	int d = ((buf[1] & 0x01) << 4) | ((buf[0] >> 4) & 0xf);
404 	int b = buf[0] & 0x7;
405 	ESIL_A ("r%d,%d,1,<<,0xff,^,&,", d, b);			// Rd/b = 0
406 	ESIL_A ("%d,tf,<<,|,r%d,=,", b, d);			// Rd/b |= T<<b
407 }
408 
INST_HANDLER(brbx)409 INST_HANDLER (brbx) {	// BRBC s, k
410 			// BRBS s, k
411 			// BRBC/S 0:		BRCC		BRCS
412 			//			BRSH		BRLO
413 			// BRBC/S 1:		BREQ		BRNE
414 			// BRBC/S 2:		BRPL		BRMI
415 			// BRBC/S 3:		BRVC		BRVS
416 			// BRBC/S 4:		BRGE		BRLT
417 			// BRBC/S 5:		BRHC		BRHS
418 			// BRBC/S 6:		BRTC		BRTS
419 			// BRBC/S 7:		BRID		BRIE
420 	if (len < 2) {
421 		return;
422 	}
423 	int s = buf[0] & 0x7;
424 	op->jump = op->addr
425 		+ ((((buf[1] & 0x03) << 6) | ((buf[0] & 0xf8) >> 2))
426 			| (buf[1] & 0x2 ? ~((int) 0x7f) : 0))
427 		+ 2;
428 	op->fail = op->addr + op->size;
429 	op->cycles = 1;	// XXX: This is a bug, because depends on eval state,
430 			// so it cannot be really be known until this
431 			// instruction is executed by the ESIL interpreter!!!
432 			// In case of evaluating to true, this instruction
433 			// needs 2 cycles, elsewhere it needs only 1 cycle.
434 	ESIL_A ("%d,1,<<,sreg,&,", s);				// SREG(s)
435 	ESIL_A (buf[1] & 0x4
436 			? "!,"		// BRBC => branch if cleared
437 			: "!,!,");	// BRBS => branch if set
438 	ESIL_A ("?{,%"PFMT64d",pc,=,},", op->jump);	// ?true => jmp
439 }
440 
INST_HANDLER(break)441 INST_HANDLER (break) {	// BREAK
442 	ESIL_A ("BREAK");
443 }
444 
INST_HANDLER(bset)445 INST_HANDLER (bset) {	// BSET s
446 			// SEC
447 			// SEH
448 			// SEI
449 			// SEN
450 			// SER
451 			// SES
452 			// SET
453 			// SEV
454 			// SEZ
455 	if (len < 1) {
456 		return;
457 	}
458 	int s = (buf[0] >> 4) & 0x7;
459 	ESIL_A ("%d,1,<<,sreg,|=,", s);
460 }
461 
INST_HANDLER(bst)462 INST_HANDLER (bst) {	// BST Rd, b
463 	if (len < 2) {
464 		return;
465 	}
466 	ESIL_A ("r%d,%d,1,<<,&,!,!,tf,=,",			// tf = Rd/b
467 		((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf),	// r
468 		buf[0] & 0x7);					// b
469 }
470 
INST_HANDLER(call)471 INST_HANDLER (call) {	// CALL k
472 	if (len < 4) {
473 		return;
474 	}
475 	op->jump = (buf[2] << 1)
476 		 | (buf[3] << 9)
477 		 | (buf[1] & 0x01) << 23
478 		 | (buf[0] & 0x01) << 17
479 		 | (buf[0] & 0xf0) << 14;
480 	op->fail = op->addr + op->size;
481 	op->cycles = cpu->pc <= 16 ? 3 : 4;
482 	if (!STR_BEGINS (cpu->model, "ATxmega")) {
483 		op->cycles--;	// AT*mega optimizes one cycle
484 	}
485 	ESIL_A ("pc,");				// esil is already pointing to
486 						// next instruction (@ret)
487 	__generic_push (op, CPU_PC_SIZE (cpu));	// push @ret in stack
488 	ESIL_A ("%"PFMT64d",pc,=,", op->jump);	// jump!
489 }
490 
INST_HANDLER(cbi)491 INST_HANDLER (cbi) {	// CBI A, b
492 	if (len < 1) {
493 		return;
494 	}
495 	int a = (buf[0] >> 3) & 0x1f;
496 	int b = buf[0] & 0x07;
497 	RStrBuf *io_port;
498 
499 	op->family = R_ANAL_OP_FAMILY_IO;
500 	op->type2 = 1;
501 	op->val = a;
502 
503 	// read port a and clear bit b
504 	io_port = __generic_io_dest (a, 0, cpu);
505 	ESIL_A ("0xff,%d,1,<<,^,%s,&,", b, r_strbuf_get (io_port));
506 	r_strbuf_free (io_port);
507 
508 	// write result to port a
509 	io_port = __generic_io_dest (a, 1, cpu);
510 	ESIL_A ("%s,", r_strbuf_get (io_port));
511 	r_strbuf_free (io_port);
512 }
513 
INST_HANDLER(com)514 INST_HANDLER (com) {	// COM Rd
515 	if (len < 2) {
516 		return;
517 	}
518 	int r = ((buf[0] >> 4) & 0x0f) | ((buf[1] & 1) << 4);
519 
520 	ESIL_A ("r%d,0xff,-,r%d,=,$z,zf,:=,0,cf,:=,0,vf,:=,r%d,0x80,&,!,!,nf,:=,vf,nf,^,sf,:=", r, r, r);
521 	// Rd = 0xFF-Rd
522 }
523 
INST_HANDLER(cp)524 INST_HANDLER (cp) {	// CP Rd, Rr
525 	if (len < 2) {
526 		return;
527 	}
528 	const ut32 r = (buf[0]        & 0x0f) | ((buf[1] << 3) & 0x10);
529 	const ut32 d = ((buf[0] >> 4) & 0x0f) | ((buf[1] << 4) & 0x10);
530 	ESIL_A ("r%d,r%d,-,0x80,&,!,!,nf,:=,", r, d);
531 	ESIL_A ("r%d,r%d,==,", r, d);
532 	ESIL_A ("$z,zf,:=,");
533 	ESIL_A ("3,$b,hf,:=,");
534 	ESIL_A ("8,$b,cf,:=,");
535 	ESIL_A ("7,$o,vf,:=,");
536 	ESIL_A ("vf,nf,^,sf,:=");
537 }
538 
INST_HANDLER(cpc)539 INST_HANDLER (cpc) {	// CPC Rd, Rr
540 	if (len < 2) {
541 		return;
542 	}
543 	const ut32 r = (buf[0]        & 0x0f) | ((buf[1] << 3) & 0x10);
544 	const ut32 d = ((buf[0] >> 4) & 0x0f) | ((buf[1] << 4) & 0x10);
545 
546 	ESIL_A ("cf,r%d,+,DUP,r%d,-,0x80,&,!,!,nf,:=,", r, d);		// Rd - Rr - C
547 	ESIL_A ("r%d,==,", d);
548 	ESIL_A ("$z,zf,:=,");
549 	ESIL_A ("3,$b,hf,:=,");
550 	ESIL_A ("8,$b,cf,:=,");
551 	ESIL_A ("7,$o,vf,:=,");
552 	ESIL_A ("vf,nf,^,sf,:=");
553 }
554 
INST_HANDLER(cpi)555 INST_HANDLER (cpi) { // CPI Rd, K
556 	if (len < 2) {
557 		return;
558 	}
559 	const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
560 	const ut32 k = (buf[0] & 0xf) | ((buf[1] & 0xf) << 4);
561 	ESIL_A ("%d,r%d,-,0x80,&,!,!,nf,:=,", k, d);			// Rd - k
562 	ESIL_A ("%d,r%d,==,", k, d);
563 	ESIL_A ("$z,zf,:=,");
564 	ESIL_A ("3,$b,hf,:=,");
565 	ESIL_A ("8,$b,cf,:=,");
566 	ESIL_A ("7,$o,vf,:=,");
567 	ESIL_A ("vf,nf,^,sf,:=");
568 }
569 
INST_HANDLER(cpse)570 INST_HANDLER (cpse) {	// CPSE Rd, Rr
571 	if (len < 2) {
572 		return;
573 	}
574 	int r = (buf[0] & 0xf) | ((buf[1] & 0x2) << 3);
575 	int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
576 	RAnalOp next_op = {0};
577 
578 	// calculate next instruction size (call recursively avr_op_analyze)
579 	// and free next_op's esil string (we dont need it now)
580 	avr_op_analyze (anal,
581 			&next_op,
582 			op->addr + op->size, buf + op->size, len - op->size,
583 			cpu);
584 	r_strbuf_fini (&next_op.esil);
585 	op->jump = op->addr + next_op.size + 2;
586 	op->fail = op->addr + 2;
587 
588 	// cycles
589 	op->cycles = 1;	// XXX: This is a bug, because depends on eval state,
590 			// so it cannot be really be known until this
591 			// instruction is executed by the ESIL interpreter!!!
592 			// In case of evaluating to true, this instruction
593 			// needs 2/3 cycles, elsewhere it needs only 1 cycle.
594 	ESIL_A ("r%d,r%d,^,!,", r, d);			// Rr == Rd
595 	ESIL_A ("?{,%"PFMT64d",pc,=,},", op->jump);	// ?true => jmp
596 }
597 
INST_HANDLER(dec)598 INST_HANDLER (dec) {	// DEC Rd
599 	if (len < 2) {
600 		return;
601 	}
602 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
603 	ESIL_A ("0x1,r%d,-=,", d);			// Rd--
604 							// FLAGS:
605 	ESIL_A ("7,$o,vf,:=,");				// V
606 	ESIL_A ("r%d,0x80,&,!,!,nf,:=,", d);		// N
607 	ESIL_A ("$z,zf,:=,");				// Z
608 	ESIL_A ("vf,nf,^,sf,:=,");			// S
609 }
610 
INST_HANDLER(des)611 INST_HANDLER (des) {	// DES k
612 	if (desctx.round < 16) {	//DES
613 		op->type = R_ANAL_OP_TYPE_CRYPTO;
614 		op->cycles = 1;		//redo this
615 		r_strbuf_setf (&op->esil, "%d,des", desctx.round);
616 	}
617 }
618 
INST_HANDLER(eijmp)619 INST_HANDLER (eijmp) {	// EIJMP
620 	ut64 z, eind;
621 	// read z and eind for calculating jump address on runtime
622 	r_anal_esil_reg_read (anal->esil, "z",    &z,    NULL);
623 	r_anal_esil_reg_read (anal->esil, "eind", &eind, NULL);
624 	// real target address may change during execution, so this value will
625 	// be changing all the time
626 	op->jump = ((eind << 16) + z) << 1;
627 	// jump
628 	ESIL_A ("1,z,16,eind,<<,+,<<,pc,=,");
629 	// cycles
630 	op->cycles = 2;
631 }
632 
INST_HANDLER(eicall)633 INST_HANDLER (eicall) {	// EICALL
634 	// push pc in stack
635 	ESIL_A ("pc,");				// esil is already pointing to
636 						// next instruction (@ret)
637 	__generic_push (op, CPU_PC_SIZE (cpu));	// push @ret in stack
638 	// do a standard EIJMP
639 	INST_CALL (eijmp);
640 	// fix cycles
641 	op->cycles = !STR_BEGINS (cpu->model, "ATxmega") ? 3 : 4;
642 }
643 
INST_HANDLER(elpm)644 INST_HANDLER (elpm) {	// ELPM
645 			// ELPM Rd
646 			// ELPM Rd, Z+
647 	if (len < 2) {
648 		return;
649 	}
650 	int d = ((buf[1] & 0xfe) == 0x90)
651 			? ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf)	// Rd
652 			: 0;						// R0
653 	ESIL_A ("16,rampz,<<,z,+,_prog,+,[1],");	// read RAMPZ:Z
654 	ESIL_A ("r%d,=,", d);				// Rd = [1]
655 	if ((buf[1] & 0xfe) == 0x90 && (buf[0] & 0xf) == 0x7) {
656 		ESIL_A ("16,1,z,+,DUP,z,=,>>,1,&,rampz,+=,");	// ++(rampz:z)
657 	}
658 }
659 
INST_HANDLER(eor)660 INST_HANDLER (eor) {	// EOR Rd, Rr
661 			// CLR Rd
662 	if (len < 2) {
663 		return;
664 	}
665 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
666 	const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
667 	ESIL_A ("r%d,r%d,^=,$z,zf,:=,0,vf,:=,r%d,0x80,&,!,!,nf,:=,nf,sf,:=", r, d, d);
668 	// 0: Rd ^= Rr
669 }
670 
INST_HANDLER(fmul)671 INST_HANDLER (fmul) {	// FMUL Rd, Rr
672 	if (len < 1) {
673 		return;
674 	}
675 	const ut32 d = ((buf[0] >> 4) & 0x7) + 16;
676 	const ut32 r = (buf[0] & 0x7) + 16;
677 
678 	ESIL_A ("0xffff,1,r%d,r%d,*,<<,&,r1_r0,=,", r, d);	// 0: r1_r0 = (rd * rr) << 1
679 	ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,");			// C = R/15
680 	ESIL_A ("$z,zf,:=");					// Z = !R
681 
682 }
683 
INST_HANDLER(fmuls)684 INST_HANDLER (fmuls) {	// FMULS Rd, Rr
685 	if (len < 1) {
686 		return;
687 	}
688 	const ut32 d = ((buf[0] >> 4) & 0x7) + 16;
689 	const ut32 r = (buf[0] & 0x7) + 16;
690 
691 	ESIL_A ("1,");
692 	ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", d);	// sign extension Rd
693 	ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", r);	// sign extension Rr
694 	ESIL_A ("*,<<,r1_r0,=,");			// 0: (Rd*Rr)<<1
695 
696 	ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,");		// C = R/16
697 	ESIL_A ("$z,zf,:=");				// Z = !R
698 }
699 
INST_HANDLER(fmulsu)700 INST_HANDLER (fmulsu) {	// FMULSU Rd, Rr
701 	if (len < 1) {
702 		return;
703 	}
704 	const ut32 d = ((buf[0] >> 4) & 0x7) + 16;
705 	const ut32 r = (buf[0] & 0x7) + 16;
706 
707 	ESIL_A ("1,");
708 	ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", d);	// sign extension Rd
709 	ESIL_A ("r%d,*,<<,r1_r0,=,", r);		// 0: (Rd*Rr)<<1
710 
711 	ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,");		// C = R/16
712 	ESIL_A ("$z,zf,:=");				// Z = !R
713 }
714 
INST_HANDLER(ijmp)715 INST_HANDLER (ijmp) {	// IJMP k
716 	ut64 z;
717 	// read z for calculating jump address on runtime
718 	r_anal_esil_reg_read (anal->esil, "z", &z, NULL);
719 	// real target address may change during execution, so this value will
720 	// be changing all the time
721 	op->jump = z << 1;
722 	op->cycles = 2;
723 	ESIL_A ("1,z,<<,pc,=,");		// jump!
724 }
725 
INST_HANDLER(icall)726 INST_HANDLER (icall) {	// ICALL k
727 	// push pc in stack
728 	ESIL_A ("pc,");				// esil is already pointing to
729 						// next instruction (@ret)
730 	__generic_push (op, CPU_PC_SIZE (cpu));	// push @ret in stack
731 	// do a standard IJMP
732 	INST_CALL (ijmp);
733 	// fix cycles
734 	if (!STR_BEGINS (cpu->model, "ATxmega")) {
735 		// AT*mega optimizes 1 cycle!
736 		op->cycles--;
737 	}
738 }
739 
INST_HANDLER(in)740 INST_HANDLER (in) {	// IN Rd, A
741 	if (len < 2) {
742 		return;
743 	}
744 	int r = ((buf[0] >> 4) & 0x0f) | ((buf[1] & 0x01) << 4);
745 	int a = (buf[0] & 0x0f) | ((buf[1] & 0x6) << 3);
746 	RStrBuf *io_src = __generic_io_dest (a, 0, cpu);
747 	op->type2 = 0;
748 	op->val = a;
749 	op->family = R_ANAL_OP_FAMILY_IO;
750 	ESIL_A ("%s,r%d,=,", r_strbuf_get (io_src), r);
751 	r_strbuf_free (io_src);
752 }
753 
INST_HANDLER(inc)754 INST_HANDLER (inc) {	// INC Rd
755 	if (len < 2) {
756 		return;
757 	}
758 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
759 	ESIL_A ("1,r%d,+=,", d);			// Rd++
760 							// FLAGS:
761 	ESIL_A ("7,$o,vf,:=,");				// V
762 	ESIL_A ("r%d,0x80,&,!,!,nf,:=,", d);		// N
763 	ESIL_A ("$z,zf,:=,");				// Z
764 	ESIL_A ("vf,nf,^,sf,:=,");			// S
765 }
766 
INST_HANDLER(jmp)767 INST_HANDLER (jmp) {	// JMP k
768 	if (len < 4) {
769 		return;
770 	}
771 	op->jump = (buf[2] << 1)
772 		 | (buf[3] << 9)
773 		 | (buf[1] & 0x01) << 23
774 		 | (buf[0] & 0x01) << 17
775 		 | (buf[0] & 0xf0) << 14;
776 	op->cycles = 3;
777 	ESIL_A ("%"PFMT64d",pc,=,", op->jump);	// jump!
778 }
779 
INST_HANDLER(lac)780 INST_HANDLER (lac) {	// LAC Z, Rd
781 	if (len < 2) {
782 		return;
783 	}
784 	int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
785 
786 	// read memory from RAMPZ:Z
787 	__generic_ld_st (op, "ram", 'z', 1, 0, 0, 0);	// 0: Read (RAMPZ:Z)
788 	ESIL_A ("r%d,0xff,^,&,", d);			// 0: (Z) & ~Rd
789 	ESIL_A ("DUP,r%d,=,", d);			// Rd = [0]
790 	__generic_ld_st (op, "ram", 'z', 1, 0, 0, 1);	// Store in RAM
791 }
792 
INST_HANDLER(las)793 INST_HANDLER (las) {	// LAS Z, Rd
794 	if (len < 2) {
795 		return;
796 	}
797 	int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
798 
799 	// read memory from RAMPZ:Z
800 	__generic_ld_st (op, "ram", 'z', 1, 0, 0, 0);	// 0: Read (RAMPZ:Z)
801 	ESIL_A ("r%d,|,", d);				// 0: (Z) | Rd
802 	ESIL_A ("DUP,r%d,=,", d);			// Rd = [0]
803 	__generic_ld_st (op, "ram", 'z', 1, 0, 0, 1);	// Store in RAM
804 }
805 
INST_HANDLER(lat)806 INST_HANDLER (lat) {	// LAT Z, Rd
807 	if (len < 2) {
808 		return;
809 	}
810 	int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
811 
812 	// read memory from RAMPZ:Z
813 	__generic_ld_st (op, "ram", 'z', 1, 0, 0, 0);	// 0: Read (RAMPZ:Z)
814 	ESIL_A ("r%d,^,", d);				// 0: (Z) ^ Rd
815 	ESIL_A ("DUP,r%d,=,", d);			// Rd = [0]
816 	__generic_ld_st (op, "ram", 'z', 1, 0, 0, 1);	// Store in RAM
817 }
818 
INST_HANDLER(ld)819 INST_HANDLER (ld) {	// LD Rd, X
820 			// LD Rd, X+
821 			// LD Rd, -X
822 	if (len < 2) {
823 		return;
824 	}
825 	// read memory
826 	__generic_ld_st (
827 		op, "ram",
828 		'x',				// use index register X
829 		0,				// no use RAMP* registers
830 		(buf[0] & 0xf) == 0xe
831 			? -1			// pre decremented
832 			: (buf[0] & 0xf) == 0xd
833 				? 1		// post incremented
834 				: 0,		// no increment
835 		0,				// offset always 0
836 		0);				// load operation (!st)
837 	// load register
838 	ESIL_A ("r%d,=,", ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf));
839 	// cycles
840 	op->cycles = (buf[0] & 0x3) == 0
841 			? 2			// LD Rd, X
842 			: (buf[0] & 0x3) == 1
843 				? 2		// LD Rd, X+
844 				: 3;		// LD Rd, -X
845 	if (!STR_BEGINS (cpu->model, "ATxmega") && op->cycles > 1) {
846 		// AT*mega optimizes 1 cycle!
847 		op->cycles--;
848 	}
849 }
850 
INST_HANDLER(ldd)851 INST_HANDLER (ldd) {	// LD Rd, Y	LD Rd, Z
852 			// LD Rd, Y+	LD Rd, Z+
853 			// LD Rd, -Y	LD Rd, -Z
854 			// LD Rd, Y+q	LD Rd, Z+q
855 	if (len < 2) {
856 		return;
857 	}
858 	// calculate offset (this value only has sense in some opcodes,
859 	// but we are optimistic and we calculate it always)
860 	int offset = (buf[1] & 0x20)
861 			| ((buf[1] & 0xc) << 1)
862 			| (buf[0] & 0x7);
863 	// read memory
864 	__generic_ld_st (
865 		op, "ram",
866 		buf[0] & 0x8 ? 'y' : 'z',	// index register Y/Z
867 		0,				// no use RAMP* registers
868 		!(buf[1] & 0x10)
869 			? 0			// no increment
870 			: buf[0] & 0x1
871 				? 1		// post incremented
872 				: -1,		// pre decremented
873 		!(buf[1] & 0x10) ? offset : 0,	// offset or not offset
874 		0);				// load operation (!st)
875 	// load register
876 	ESIL_A ("r%d,=,", ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf));
877 	// cycles
878 	op->cycles =
879 		(buf[1] & 0x10) == 0
880 			? (!offset ? 1 : 3)		// LDD
881 			: (buf[0] & 0x3) == 0
882 				? 1			// LD Rd, X
883 				: (buf[0] & 0x3) == 1
884 					? 2		// LD Rd, X+
885 					: 3;		// LD Rd, -X
886 	if (!STR_BEGINS (cpu->model, "ATxmega") && op->cycles > 1) {
887 		// AT*mega optimizes 1 cycle!
888 		op->cycles--;
889 	}
890 }
891 
INST_HANDLER(ldi)892 INST_HANDLER (ldi) {	// LDI Rd, K
893 	if (len < 2) {
894 		return;
895 	}
896 	int k = (buf[0] & 0xf) + ((buf[1] & 0xf) << 4);
897 	int d = ((buf[0] >> 4) & 0xf) + 16;
898 	op->val = k;
899 	ESIL_A ("0x%x,r%d,=,", k, d);
900 }
901 
INST_HANDLER(lds)902 INST_HANDLER (lds) {	// LDS Rd, k
903 	if (len < 4) {
904 		return;
905 	}
906 	int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
907 	int k = (buf[3] << 8) | buf[2];
908 	op->ptr = k;
909 
910 	// load value from RAMPD:k
911 	__generic_ld_st (op, "ram", 0, 1, 0, k, 0);
912 	ESIL_A ("r%d,=,", d);
913 }
914 
INST_HANDLER(sts)915 INST_HANDLER (sts) {	// STS k, Rr
916 	if (len < 4) {
917 		return;
918 	}
919 	int r = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
920 	int k = (buf[3] << 8) | buf[2];
921 	op->ptr = k;
922 
923 	ESIL_A ("r%d,", r);
924 	__generic_ld_st (op, "ram", 0, 1, 0, k, 1);
925 
926 	op->cycles = 2;
927 }
928 
929 #if 0
930 INST_HANDLER (lds16) {	// LDS Rd, k
931 	int d = ((buf[0] >> 4) & 0xf) + 16;
932 	int k = (buf[0] & 0x0f)
933 		| ((buf[1] << 3) & 0x30)
934 		| ((buf[1] << 4) & 0x40)
935 		| (~(buf[1] << 4) & 0x80);
936 	op->ptr = k;
937 
938 	// load value from @k
939 	__generic_ld_st (op, "ram", 0, 0, 0, k, 0);
940 	ESIL_A ("r%d,=,", d);
941 }
942 #endif
943 
INST_HANDLER(lpm)944 INST_HANDLER (lpm) {	// LPM
945 			// LPM Rd, Z
946 			// LPM Rd, Z+
947 	if (len < 2) {
948 		return;
949 	}
950 	ut16 ins = (((ut16) buf[1]) << 8) | ((ut16) buf[0]);
951 	// read program memory
952 	__generic_ld_st (
953 		op, "prog",
954 		'z',				// index register Y/Z
955 		1,				// use RAMP* registers
956 		(ins & 0xfe0f) == 0x9005
957 			? 1			// post incremented
958 			: 0,			// no increment
959 		0,				// not offset
960 		0);				// load operation (!st)
961 	// load register
962 	ESIL_A ("r%d,=,",
963 		(ins == 0x95c8)
964 			? 0			// LPM (r0)
965 			: ((buf[0] >> 4) & 0xf)	// LPM Rd
966 				| ((buf[1] & 0x1) << 4));
967 }
968 
INST_HANDLER(lsr)969 INST_HANDLER (lsr) {	// LSR Rd
970 	if (len < 2) {
971 		return;
972 	}
973 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
974 	ESIL_A ("r%d,0x1,&,cf,:=,", d);				// C = Rd0
975 	ESIL_A ("1,r%d,>>=,", d);				// 0: R=(Rd >> 1)
976 	ESIL_A ("$z,zf,:=,");					// Z
977 	ESIL_A ("0,nf,:=,");					// N
978 	ESIL_A ("cf,vf,:=,");					// V
979 	ESIL_A ("cf,sf,:=,");					// S
980 }
981 
INST_HANDLER(mov)982 INST_HANDLER (mov) {	// MOV Rd, Rr
983 	if (len < 2) {
984 		return;
985 	}
986 	const ut32 d = ((buf[1] << 4) & 0x10) | ((buf[0] >> 4) & 0x0f);
987 	const ut32 r = ((buf[1] << 3) & 0x10) | (buf[0] & 0x0f);
988 	ESIL_A ("r%d,r%d,=,", r, d);
989 }
990 
INST_HANDLER(movw)991 INST_HANDLER (movw) {	// MOVW Rd+1:Rd, Rr+1:Rr
992 	if (len < 1) {
993 		return;
994 	}
995 	const ut32 d = (buf[0] & 0xf0) >> 3;
996 	const ut32 r = (buf[0] & 0x0f) << 1;
997 	ESIL_A ("r%d,r%d,=,r%d,r%d,=,", r, d, r + 1, d + 1);
998 }
999 
INST_HANDLER(mul)1000 INST_HANDLER (mul) {	// MUL Rd, Rr
1001 	if (len < 2) {
1002 		return;
1003 	}
1004 	const ut32 d = ((buf[1] << 4) & 0x10) | ((buf[0] >> 4) & 0x0f);
1005 	const ut32 r = ((buf[1] << 3) & 0x10) | (buf[0] & 0x0f);
1006 
1007 	ESIL_A ("r%d,r%d,*,r1_r0,=,", r, d);		// 0: r1_r0 = rd * rr
1008 	ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,");		// C = R/15
1009 	ESIL_A ("$z,zf,:=");				// Z = !R
1010 }
1011 
INST_HANDLER(muls)1012 INST_HANDLER (muls) {	// MULS Rd, Rr
1013 	if (len < 1) {
1014 		return;
1015 	}
1016 	const ut32 d = (buf[0] >> 4 & 0x0f) + 16;
1017 	const ut32 r = (buf[0] & 0x0f) + 16;
1018 
1019 	ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", d);	// sign extension Rd
1020 	ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", r);	// sign extension Rr
1021 	ESIL_A ("*,r1_r0,=,");				// 0: (Rd*Rr)
1022 
1023 	ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,");		// C = R/16
1024 	ESIL_A ("$z,zf,:=");				// Z = !R
1025 }
1026 
INST_HANDLER(mulsu)1027 INST_HANDLER (mulsu) {	// MULSU Rd, Rr
1028 	if (len < 1) {
1029 		return;
1030 	}
1031 	const ut32 d = (buf[0] >> 4 & 0x07) + 16;
1032 	const ut32 r = (buf[0] & 0x07) + 16;
1033 
1034 	ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", d);	// sign extension Rd
1035 	ESIL_A ("r%d,*,r1_r0,=,", r);			// 0: (Rd*Rr)
1036 
1037 	ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,");		// C = R/16
1038 	ESIL_A ("$z,zf,:=");				// Z = !R
1039 }
1040 
INST_HANDLER(neg)1041 INST_HANDLER (neg) {	// NEG Rd
1042 	if (len < 2) {
1043 		return;
1044 	}
1045 	int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
1046 	ESIL_A ("r%d,0x00,-,0xff,&,", d);			// 0: (0-Rd)
1047 	ESIL_A ("DUP,r%d,0xff,^,|,0x08,&,!,!,hf,=,", d);	// H
1048 	ESIL_A ("DUP,0x80,-,!,vf,=,");			// V
1049 	ESIL_A ("DUP,0x80,&,!,!,nf,=,");			// N
1050 	ESIL_A ("DUP,!,zf,=,");					// Z
1051 	ESIL_A ("DUP,!,!,cf,=,");				// C
1052 	ESIL_A ("vf,nf,^,sf,=,");				// S
1053 	ESIL_A ("r%d,=,", d);					// Rd = result
1054 }
1055 
INST_HANDLER(nop)1056 INST_HANDLER (nop) {	// NOP
1057 	ESIL_A (",,");
1058 }
1059 
INST_HANDLER(or)1060 INST_HANDLER (or) {	// OR Rd, Rr
1061 	if (len < 2) {
1062 		return;
1063 	}
1064 	int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
1065 	int r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
1066 	ESIL_A ("r%d,r%d,|=,", r, d);				// 0: (Rd | Rr)
1067 	ESIL_A ("$z,zf,:=,");					// Z
1068 	ESIL_A ("r%d,&,!,!,nf,:=,", d);				// N
1069 	ESIL_A ("0,vf,:=,");					// V
1070 	ESIL_A ("nf,sf,:=");					// S
1071 }
1072 
INST_HANDLER(ori)1073 INST_HANDLER (ori) {	// ORI Rd, K
1074 			// SBR Rd, K
1075 	if (len < 2) {
1076 		return;
1077 	}
1078 	const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
1079 	const ut32 k = (buf[0] & 0xf) | ((buf[1] & 0xf) << 4);
1080 	op->val = k;
1081 	ESIL_A ("%d,r%d,|=,", k, d);				// 0: (Rd | k)
1082 	ESIL_A ("$z,zf,:=,");					// Z
1083 	ESIL_A ("r%d,0x80,&,!,!,nf,:=,", d);			// N
1084 	ESIL_A ("0,vf,:=,");					// V
1085 	ESIL_A ("nf,sf,:=");					// S
1086 }
1087 
INST_HANDLER(out)1088 INST_HANDLER (out) {	// OUT A, Rr
1089 	if (len < 2) {
1090 		return;
1091 	}
1092 	int r = ((buf[0] >> 4) & 0x0f) | ((buf[1] & 0x01) << 4);
1093 	int a = (buf[0] & 0x0f) | ((buf[1] & 0x6) << 3);
1094 	RStrBuf *io_dst = __generic_io_dest (a, 1, cpu);
1095 	op->type2 = 1;
1096 	op->val = a;
1097 	op->family = R_ANAL_OP_FAMILY_IO;
1098 	ESIL_A ("r%d,%s,", r, r_strbuf_get (io_dst));
1099 	r_strbuf_free (io_dst);
1100 }
1101 
INST_HANDLER(pop)1102 INST_HANDLER (pop) {	// POP Rd
1103 	if (len < 2) {
1104 		return;
1105 	}
1106 	int d = ((buf[1] & 0x1) << 4) | ((buf[0] >> 4) & 0xf);
1107 	__generic_pop (op, 1);
1108 	ESIL_A ("r%d,=,", d);	// store in Rd
1109 
1110 }
1111 
INST_HANDLER(push)1112 INST_HANDLER (push) {	// PUSH Rr
1113 	if (len < 2) {
1114 		return;
1115 	}
1116 	int r = ((buf[1] & 0x1) << 4) | ((buf[0] >> 4) & 0xf);
1117 	ESIL_A ("r%d,", r);	// load Rr
1118 	__generic_push (op, 1);	// push it into stack
1119 	// cycles
1120 	op->cycles = !STR_BEGINS (cpu->model, "ATxmega")
1121 			? 1	// AT*mega optimizes one cycle
1122 			: 2;
1123 }
1124 
INST_HANDLER(rcall)1125 INST_HANDLER (rcall) {	// RCALL k
1126 	if (len < 2) {
1127 		return;
1128 	}
1129 	// target address
1130 	op->jump = op->addr + (
1131 		(((((buf[1] & 0xf) << 8) | buf[0]) << 1)
1132 			| (((buf[1] & 0x8) ? ~((int) 0x1fff) : 0)))
1133 		+ 2);
1134 	op->fail = op->addr + op->size;
1135 	// esil
1136 	ESIL_A ("pc,");				// esil already points to next
1137 						// instruction (@ret)
1138 	__generic_push (op, CPU_PC_SIZE (cpu));	// push @ret addr
1139 	ESIL_A ("%"PFMT64d",pc,=,", op->jump);	// jump!
1140 	// cycles
1141 	if (!r_str_ncasecmp (cpu->model, "ATtiny", 6)) {
1142 		op->cycles = 4;	// ATtiny is always slow
1143 	} else {
1144 		// PC size decides required runtime!
1145 		op->cycles = cpu->pc <= 16 ? 3 : 4;
1146 		if (!STR_BEGINS (cpu->model, "ATxmega")) {
1147 			op->cycles--;	// ATxmega optimizes one cycle
1148 		}
1149 	}
1150 }
1151 
INST_HANDLER(ret)1152 INST_HANDLER (ret) {	// RET
1153 	op->eob = true;
1154 	// esil
1155 	__generic_pop (op, CPU_PC_SIZE (cpu));
1156 	ESIL_A ("pc,=,");	// jump!
1157 	// cycles
1158 	if (CPU_PC_SIZE (cpu) > 2) {	// if we have a bus bigger than 16 bit
1159 		op->cycles++;	// (i.e. a 22-bit bus), add one extra cycle
1160 	}
1161 }
1162 
INST_HANDLER(reti)1163 INST_HANDLER (reti) {	// RETI
1164 	//XXX: There are not privileged instructions in ATMEL/AVR
1165 	op->family = R_ANAL_OP_FAMILY_PRIV;
1166 
1167 	// first perform a standard 'ret'
1168 	INST_CALL (ret);
1169 
1170 	// RETI: The I-bit is cleared by hardware after an interrupt
1171 	// has occurred, and is set by the RETI instruction to enable
1172 	// subsequent interrupts
1173 	ESIL_A ("1,if,=,");
1174 }
1175 
INST_HANDLER(rjmp)1176 INST_HANDLER (rjmp) {	// RJMP k
1177 	st32 jump = ((((( buf[1] & 0xf) << 9) | (buf[0] << 1)))
1178 			| (buf[1] & 0x8 ? ~(0x1fff) : 0))
1179 		+ 2;
1180 	op->jump = op->addr + jump;
1181 	ESIL_A ("%"PFMT64d",pc,=,", op->jump);
1182 }
1183 
INST_HANDLER(ror)1184 INST_HANDLER (ror) {	// ROR Rd
1185 	const ut32 d = ((buf[0] >> 4) & 0x0f) | ((buf[1] << 4) & 0x10);
1186 	ESIL_A ("cf,nf,:=,");					// N
1187 	ESIL_A ("r%d,0x1,&,", d);				// C
1188 	ESIL_A ("1,r%d,>>,7,cf,<<,|,r%d,=,cf,:=,", d, d);	// 0: (Rd>>1) | (cf<<7)
1189 	ESIL_A ("$z,zf,:=,");					// Z
1190 	ESIL_A ("nf,cf,^,vf,:=,");				// V
1191 	ESIL_A ("vf,nf,^,sf,:=");				// S
1192 }
1193 
INST_HANDLER(sbc)1194 INST_HANDLER (sbc) {	// SBC Rd, Rr
1195 	if (len < 2) {
1196 		return;
1197 	}
1198 	const ut32 r = (buf[0] & 0x0f) | ((buf[1] & 0x2) << 3);
1199 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
1200 
1201 	ESIL_A ("cf,r%d,+,r%d,-=,", r, d);		// 0: (Rd-Rr-C)
1202 	ESIL_A ("$z,zf,:=,");
1203 	ESIL_A ("3,$b,hf,:=,");
1204 	ESIL_A ("8,$b,cf,:=,");
1205 	ESIL_A ("7,$o,vf,:=,");
1206 	ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
1207 	ESIL_A ("vf,nf,^,sf,:=");
1208 }
1209 
INST_HANDLER(sbci)1210 INST_HANDLER (sbci) {	// SBCI Rd, k
1211 	if (len < 2) {
1212 		return;
1213 	}
1214 	const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
1215 	const ut32 k = ((buf[1] & 0xf) << 4) | (buf[0] & 0xf);
1216 	op->val = k;
1217 
1218 	ESIL_A ("cf,%d,+,r%d,-=,", k, d);		// 0: (Rd-k-C)
1219 	ESIL_A ("$z,zf,:=,");
1220 	ESIL_A ("3,$b,hf,:=,");
1221 	ESIL_A ("8,$b,cf,:=,");
1222 	ESIL_A ("7,$o,vf,:=,");
1223 	ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
1224 	ESIL_A ("vf,nf,^,sf,:=");
1225 }
1226 
INST_HANDLER(sub)1227 INST_HANDLER (sub) {	// SUB Rd, Rr
1228 	if (len < 2) {
1229 		return;
1230 	}
1231 	const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
1232 	const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
1233 
1234 	ESIL_A ("r%d,r%d,-=,", r, d);			// 0: (Rd-k)
1235 	ESIL_A ("$z,zf,:=,");
1236 	ESIL_A ("3,$b,hf,:=,");
1237 	ESIL_A ("8,$b,cf,:=,");
1238 	ESIL_A ("7,$o,vf,:=,");
1239 	ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
1240 	ESIL_A ("vf,nf,^,sf,:=");
1241 }
1242 
INST_HANDLER(subi)1243 INST_HANDLER (subi) {	// SUBI Rd, k
1244 	if (len < 2) {
1245 		return;
1246 	}
1247 	const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
1248 	const ut32 k = ((buf[1] & 0xf) << 4) | (buf[0] & 0xf);
1249 	op->val = k;
1250 
1251 	ESIL_A ("%d,r%d,-=,", k, d);			// 0: (Rd-k)
1252 	ESIL_A ("$z,zf,:=,");
1253 	ESIL_A ("3,$b,hf,:=,");
1254 	ESIL_A ("8,$b,cf,:=,");
1255 	ESIL_A ("7,$o,vf,:=,");
1256 	ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
1257 	ESIL_A ("vf,nf,^,sf,:=");
1258 }
1259 
INST_HANDLER(sbi)1260 INST_HANDLER (sbi) {	// SBI A, b
1261 	if (len < 1) {
1262 		return;
1263 	}
1264 	int a = (buf[0] >> 3) & 0x1f;
1265 	int b = buf[0] & 0x07;
1266 	RStrBuf *io_port;
1267 
1268 	op->type2 = 1;
1269 	op->val = a;
1270 	op->family = R_ANAL_OP_FAMILY_IO;
1271 
1272 	// read port a and clear bit b
1273 	io_port = __generic_io_dest (a, 0, cpu);
1274 	ESIL_A ("0xff,%d,1,<<,|,%s,&,", b, r_strbuf_get (io_port));
1275 	r_strbuf_free (io_port);
1276 
1277 	// write result to port a
1278 	io_port = __generic_io_dest (a, 1, cpu);
1279 	ESIL_A ("%s,", r_strbuf_get (io_port));
1280 	r_strbuf_free (io_port);
1281 }
1282 
INST_HANDLER(sbix)1283 INST_HANDLER (sbix) {	// SBIC A, b
1284 			// SBIS A, b
1285 	if (len < 2) {
1286 		return;
1287 	}
1288 	int a = (buf[0] >> 3) & 0x1f;
1289 	int b = buf[0] & 0x07;
1290 	RAnalOp next_op = { 0 };
1291 	RStrBuf *io_port;
1292 
1293 	op->type2 = 0;
1294 	op->val = a;
1295 	op->family = R_ANAL_OP_FAMILY_IO;
1296 
1297 	// calculate next instruction size (call recursively avr_op_analyze)
1298 	// and free next_op's esil string (we dont need it now)
1299 	avr_op_analyze (anal,
1300 			&next_op,
1301 			op->addr + op->size, buf + op->size,
1302 			len - op->size,
1303 			cpu);
1304 	r_strbuf_fini (&next_op.esil);
1305 	op->jump = op->addr + next_op.size + 2;
1306 	op->fail = op->addr + op->size;
1307 
1308 	// cycles
1309 	op->cycles = 1;	// XXX: This is a bug, because depends on eval state,
1310 			// so it cannot be really be known until this
1311 			// instruction is executed by the ESIL interpreter!!!
1312 			// In case of evaluating to false, this instruction
1313 			// needs 2/3 cycles, elsewhere it needs only 1 cycle.
1314 
1315 	// read port a and clear bit b
1316 	io_port = __generic_io_dest (a, 0, cpu);
1317 	ESIL_A ("%d,1,<<,%s,&,", b, r_strbuf_get (io_port));		// IO(A,b)
1318 	ESIL_A ((buf[1] & 0xe) == 0xc
1319 			? "!,"				// SBIC => branch if 0
1320 			: "!,!,");			// SBIS => branch if 1
1321 	ESIL_A ("?{,%"PFMT64d",pc,=,},", op->jump);	// ?true => jmp
1322 	r_strbuf_free (io_port);
1323 }
1324 
INST_HANDLER(sbiw)1325 INST_HANDLER (sbiw) {	// SBIW Rd+1:Rd, K
1326 	if (len < 1) {
1327 		return;
1328 	}
1329 	int d = ((buf[0] & 0x30) >> 3) + 24;
1330 	int k = (buf[0] & 0xf) | ((buf[0] >> 2) & 0x30);
1331 	op->val = k;
1332 	ESIL_A ("%d,r%d_r%d,-=,", k, d + 1, d);			// 0(Rd+1:Rd - Rr)
1333 	ESIL_A ("$z,zf,:=,");
1334 	ESIL_A ("15,$c,cf,:=,");				// C
1335 	ESIL_A ("r%d_r%d,0x8000,&,!,!,nf,:=,", d + 1, d);	// N
1336 	ESIL_A ("r%d_r%d,0x8080,&,0x8080,!,vf,:=,", d + 1, d);	// V
1337 	ESIL_A ("vf,nf,^,sf,:=");				// S
1338 }
1339 
INST_HANDLER(sbrx)1340 INST_HANDLER (sbrx) {	// SBRC Rr, b
1341 			// SBRS Rr, b
1342 	if (len < 2) {
1343 		return;
1344 	}
1345 	int b = buf[0] & 0x7;
1346 	int r = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x01) << 4);
1347 	RAnalOp next_op = {0};
1348 
1349 	// calculate next instruction size (call recursively avr_op_analyze)
1350 	// and free next_op's esil string (we dont need it now)
1351 	avr_op_analyze (anal,
1352 			&next_op,
1353 			op->addr + op->size, buf + op->size, len - op->size,
1354 			cpu);
1355 	r_strbuf_fini (&next_op.esil);
1356 	op->jump = op->addr + next_op.size + 2;
1357 	op->fail = op->addr + 2;
1358 
1359 	// cycles
1360 	op->cycles = 1;	// XXX: This is a bug, because depends on eval state,
1361 			// so it cannot be really be known until this
1362 			// instruction is executed by the ESIL interpreter!!!
1363 			// In case of evaluating to false, this instruction
1364 			// needs 2/3 cycles, elsewhere it needs only 1 cycle.
1365 	ESIL_A ("%d,1,<<,r%d,&,", b, r);			// Rr(b)
1366 	ESIL_A ((buf[1] & 0xe) == 0xc
1367 			? "!,"		// SBRC => branch if cleared
1368 			: "!,!,");	// SBRS => branch if set
1369 	ESIL_A ("?{,%"PFMT64d",pc,=,},", op->jump);	// ?true => jmp
1370 }
1371 
INST_HANDLER(sleep)1372 INST_HANDLER (sleep) {	// SLEEP
1373 	ESIL_A ("BREAK");
1374 }
1375 
INST_HANDLER(spm)1376 INST_HANDLER (spm) {	// SPM Z+
1377 	ut64 spmcsr;
1378 
1379 	// read SPM Control Register (SPMCR)
1380 	r_anal_esil_reg_read (anal->esil, "spmcsr", &spmcsr, NULL);
1381 
1382 	// clear SPMCSR
1383 	ESIL_A ("0x7c,spmcsr,&=,");
1384 
1385 	// decide action depending on the old value of SPMCSR
1386 	switch (spmcsr & 0x7f) {
1387 	case 0x03: // PAGE ERASE
1388 		// invoke SPM_CLEAR_PAGE (erases target page writing
1389 		// the 0xff value
1390 		ESIL_A ("16,rampz,<<,z,+,"); // push target address
1391 		ESIL_A ("SPM_PAGE_ERASE,");  // do magic
1392 		break;
1393 
1394 	case 0x01: // FILL TEMPORARY BUFFER
1395 		ESIL_A ("r1,r0,");           // push data
1396 		ESIL_A ("z,");               // push target address
1397 		ESIL_A ("SPM_PAGE_FILL,");   // do magic
1398 		break;
1399 
1400 	case 0x05: // WRITE PAGE
1401 		ESIL_A ("16,rampz,<<,z,+,"); // push target address
1402 		ESIL_A ("SPM_PAGE_WRITE,");  // do magic
1403 		break;
1404 
1405 	default:
1406 		eprintf ("SPM: I dont know what to do with SPMCSR %02x.\n",
1407 				(unsigned int) spmcsr);
1408 	}
1409 
1410 	op->cycles = 1;	// This is truly false. Datasheets do not publish how
1411 			// many cycles this instruction uses in all its
1412 			// operation modes and I am pretty sure that this value
1413 			// can vary substantially from one MCU type to another.
1414 			// So... one cycle is fine.
1415 }
1416 
INST_HANDLER(st)1417 INST_HANDLER (st) {	// ST X, Rr
1418 			// ST X+, Rr
1419 			// ST -X, Rr
1420 	if (len < 2) {
1421 		return;
1422 	}
1423 	// load register
1424 	ESIL_A ("r%d,", ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf));
1425 	// write in memory
1426 	__generic_ld_st (
1427 		op, "ram",
1428 		'x',				// use index register X
1429 		0,				// no use RAMP* registers
1430 		(buf[0] & 0xf) == 0xe
1431 			? -1			// pre decremented
1432 			: (buf[0] & 0xf) == 0xd
1433 				? 1		// post increment
1434 				: 0,		// no increment
1435 		0,				// offset always 0
1436 		1);				// store operation (st)
1437 //	// cycles
1438 //	op->cycles = buf[0] & 0x3 == 0
1439 //			? 2			// LD Rd, X
1440 //			: buf[0] & 0x3 == 1
1441 //				? 2		// LD Rd, X+
1442 //				: 3;		// LD Rd, -X
1443 //	if (!STR_BEGINS (cpu->model, "ATxmega") && op->cycles > 1) {
1444 //		// AT*mega optimizes 1 cycle!
1445 //		op->cycles--;
1446 //	}
1447 }
1448 
INST_HANDLER(std)1449 INST_HANDLER (std) {	// ST Y, Rr	ST Z, Rr
1450 			// ST Y+, Rr	ST Z+, Rr
1451 			// ST -Y, Rr	ST -Z, Rr
1452 			// ST Y+q, Rr	ST Z+q, Rr
1453 	if (len < 2) {
1454 		return;
1455 	}
1456 	// load register
1457 	ESIL_A ("r%d,", ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf));
1458 	// write in memory
1459 	__generic_ld_st (
1460 		op, "ram",
1461 		buf[0] & 0x8 ? 'y' : 'z',	// index register Y/Z
1462 		0,				// no use RAMP* registers
1463 		!(buf[1] & 0x10)
1464 			? 0			// no increment
1465 			: buf[0] & 0x1
1466 				? 1		// post incremented
1467 				: -1,		// pre decremented
1468 		!(buf[1] & 0x10)
1469 			? (buf[1] & 0x20)	// offset
1470 			| ((buf[1] & 0xc) << 1)
1471 			| (buf[0] & 0x7)
1472 			: 0,			// no offset
1473 		1);				// load operation (!st)
1474 //	// cycles
1475 //	op->cycles =
1476 //		buf[1] & 0x1 == 0
1477 //			? !(offset ? 1 : 3)		// LDD
1478 //			: buf[0] & 0x3 == 0
1479 //				? 1			// LD Rd, X
1480 //				: buf[0] & 0x3 == 1
1481 //					? 2		// LD Rd, X+
1482 //					: 3;		// LD Rd, -X
1483 //	if (!STR_BEGINS (cpu->model, "ATxmega") && op->cycles > 1) {
1484 //		// AT*mega optimizes 1 cycle!
1485 //		op->cycles--;
1486 //	}
1487 }
1488 
INST_HANDLER(swap)1489 INST_HANDLER (swap) {	// SWAP Rd
1490 	if (len < 2) {
1491 		return;
1492 	}
1493 	int d = ((buf[1] & 0x1) << 4) | ((buf[0] >> 4) & 0xf);
1494 	ESIL_A ("4,r%d,>>,0x0f,&,", d);		// (Rd >> 4) & 0xf
1495 	ESIL_A ("4,r%d,<<,0xf0,&,", d);		// (Rd >> 4) & 0xf
1496 	ESIL_A ("|,");			// S[0] | S[1]
1497 	ESIL_A ("r%d,=,", d);			// Rd = result
1498 }
1499 
1500 OPCODE_DESC opcodes[] = {
1501 	//         op      mask    select  cycles  size type
1502 	INST_DECL (break,  0xffff, 0x9698, 1,      2,   TRAP   ), // BREAK
1503 	INST_DECL (eicall, 0xffff, 0x9519, 0,      2,   UCALL  ), // EICALL
1504 	INST_DECL (eijmp,  0xffff, 0x9419, 0,      2,   UJMP   ), // EIJMP
1505 	INST_DECL (icall,  0xffff, 0x9509, 0,      2,   UCALL  ), // ICALL
1506 	INST_DECL (ijmp,   0xffff, 0x9409, 0,      2,   UJMP   ), // IJMP
1507 	INST_DECL (lpm,    0xffff, 0x95c8, 3,      2,   LOAD   ), // LPM
1508 	INST_DECL (nop,    0xffff, 0x0000, 1,      2,   NOP    ), // NOP
1509 	INST_DECL (ret,    0xffff, 0x9508, 4,      2,   RET    ), // RET
1510 	INST_DECL (reti,   0xffff, 0x9518, 4,      2,   RET    ), // RETI
1511 	INST_DECL (sleep,  0xffff, 0x9588, 1,      2,   NOP    ), // SLEEP
1512 	INST_DECL (spm,    0xffff, 0x95e8, 1,      2,   TRAP   ), // SPM ...
1513 	INST_DECL (bclr,   0xff8f, 0x9488, 1,      2,   MOV    ), // BCLR s
1514 	INST_DECL (bset,   0xff8f, 0x9408, 1,      2,   MOV    ), // BSET s
1515 	INST_DECL (fmul,   0xff88, 0x0308, 2,      2,   MUL    ), // FMUL Rd, Rr
1516 	INST_DECL (fmuls,  0xff88, 0x0380, 2,      2,   MUL    ), // FMULS Rd, Rr
1517 	INST_DECL (fmulsu, 0xff88, 0x0388, 2,      2,   MUL    ), // FMULSU Rd, Rr
1518 	INST_DECL (mulsu,  0xff88, 0x0300, 2,      2,   AND    ), // MUL Rd, Rr
1519 	INST_DECL (des,    0xff0f, 0x940b, 0,      2,   CRYPTO ), // DES k
1520 	INST_DECL (adiw,   0xff00, 0x9600, 2,      2,   ADD    ), // ADIW Rd+1:Rd, K
1521 	INST_DECL (sbiw,   0xff00, 0x9700, 2,      2,   SUB    ), // SBIW Rd+1:Rd, K
1522 	INST_DECL (cbi,    0xff00, 0x9800, 1,      2,   IO     ), // CBI A, K
1523 	INST_DECL (sbi,    0xff00, 0x9a00, 1,      2,   IO     ), // SBI A, K
1524 	INST_DECL (movw,   0xff00, 0x0100, 1,      2,   MOV    ), // MOVW Rd+1:Rd, Rr+1:Rr
1525 	INST_DECL (muls,   0xff00, 0x0200, 2,      2,   AND    ), // MUL Rd, Rr
1526 	INST_DECL (asr,    0xfe0f, 0x9405, 1,      2,   SAR    ), // ASR Rd
1527 	INST_DECL (com,    0xfe0f, 0x9400, 1,      2,   NOT    ), // BLD Rd, b
1528 	INST_DECL (dec,    0xfe0f, 0x940a, 1,      2,   SUB    ), // DEC Rd
1529 	INST_DECL (elpm,   0xfe0f, 0x9006, 0,      2,   LOAD   ), // ELPM Rd, Z
1530 	INST_DECL (elpm,   0xfe0f, 0x9007, 0,      2,   LOAD   ), // ELPM Rd, Z+
1531 	INST_DECL (inc,    0xfe0f, 0x9403, 1,      2,   ADD    ), // INC Rd
1532 	INST_DECL (lac,    0xfe0f, 0x9206, 2,      2,   LOAD   ), // LAC Z, Rd
1533 	INST_DECL (las,    0xfe0f, 0x9205, 2,      2,   LOAD   ), // LAS Z, Rd
1534 	INST_DECL (lat,    0xfe0f, 0x9207, 2,      2,   LOAD   ), // LAT Z, Rd
1535 	INST_DECL (ld,     0xfe0f, 0x900c, 0,      2,   LOAD   ), // LD Rd, X
1536 	INST_DECL (ld,     0xfe0f, 0x900d, 0,      2,   LOAD   ), // LD Rd, X+
1537 	INST_DECL (ld,     0xfe0f, 0x900e, 0,      2,   LOAD   ), // LD Rd, -X
1538 	INST_DECL (lds,    0xfe0f, 0x9000, 0,      4,   LOAD   ), // LDS Rd, k
1539 	INST_DECL (sts,    0xfe0f, 0x9200, 2,      4,   STORE  ), // STS k, Rr
1540 	INST_DECL (lpm,    0xfe0f, 0x9004, 3,      2,   LOAD   ), // LPM Rd, Z
1541 	INST_DECL (lpm,    0xfe0f, 0x9005, 3,      2,   LOAD   ), // LPM Rd, Z+
1542 	INST_DECL (lsr,    0xfe0f, 0x9406, 1,      2,   SHR    ), // LSR Rd
1543 	INST_DECL (neg,    0xfe0f, 0x9401, 2,      2,   SUB    ), // NEG Rd
1544 	INST_DECL (pop,    0xfe0f, 0x900f, 2,      2,   POP    ), // POP Rd
1545 	INST_DECL (push,   0xfe0f, 0x920f, 0,      2,   PUSH   ), // PUSH Rr
1546 	INST_DECL (ror,    0xfe0f, 0x9407, 1,      2,   SAR    ), // ROR Rd
1547 	INST_DECL (st,     0xfe0f, 0x920c, 2,      2,   STORE  ), // ST X, Rr
1548 	INST_DECL (st,     0xfe0f, 0x920d, 0,      2,   STORE  ), // ST X+, Rr
1549 	INST_DECL (st,     0xfe0f, 0x920e, 0,      2,   STORE  ), // ST -X, Rr
1550 	INST_DECL (swap,   0xfe0f, 0x9402, 1,      2,   SAR    ), // SWAP Rd
1551 	INST_DECL (call,   0xfe0e, 0x940e, 0,      4,   CALL   ), // CALL k
1552 	INST_DECL (jmp,    0xfe0e, 0x940c, 2,      4,   JMP    ), // JMP k
1553 	INST_DECL (bld,    0xfe08, 0xf800, 1,      2,   MOV    ), // BLD Rd, b
1554 	INST_DECL (bst,    0xfe08, 0xfa00, 1,      2,   MOV    ), // BST Rd, b
1555 	INST_DECL (sbix,   0xff00, 0x9900, 2,      2,   CJMP   ), // SBIC A, b
1556 	INST_DECL (sbix,   0xff00, 0x9b00, 2,      2,   CJMP   ), // SBIS A, b
1557 	INST_DECL (sbrx,   0xfe08, 0xfc00, 2,      2,   CJMP   ), // SBRC Rr, b
1558 	INST_DECL (sbrx,   0xfe08, 0xfe00, 2,      2,   CJMP   ), // SBRS Rr, b
1559 	INST_DECL (ldd,    0xfe07, 0x9001, 0,      2,   LOAD   ), // LD Rd, Y/Z+
1560 	INST_DECL (ldd,    0xfe07, 0x9002, 0,      2,   LOAD   ), // LD Rd, -Y/Z
1561 	INST_DECL (std,    0xfe07, 0x9201, 0,      2,   STORE  ), // ST Y/Z+, Rr
1562 	INST_DECL (std,    0xfe07, 0x9202, 0,      2,   STORE  ), // ST -Y/Z, Rr
1563 	INST_DECL (adc,    0xfc00, 0x1c00, 1,      2,   ADD    ), // ADC Rd, Rr
1564 	INST_DECL (add,    0xfc00, 0x0c00, 1,      2,   ADD    ), // ADD Rd, Rr
1565 	INST_DECL (and,    0xfc00, 0x2000, 1,      2,   AND    ), // AND Rd, Rr
1566 	INST_DECL (brbx,   0xfc00, 0xf000, 0,      2,   CJMP   ), // BRBS s, k
1567 	INST_DECL (brbx,   0xfc00, 0xf400, 0,      2,   CJMP   ), // BRBC s, k
1568 	INST_DECL (cp,     0xfc00, 0x1400, 1,      2,   CMP    ), // CP Rd, Rr
1569 	INST_DECL (cpc,    0xfc00, 0x0400, 1,      2,   CMP    ), // CPC Rd, Rr
1570 	INST_DECL (cpse,   0xfc00, 0x1000, 0,      2,   CJMP   ), // CPSE Rd, Rr
1571 	INST_DECL (eor,    0xfc00, 0x2400, 1,      2,   XOR    ), // EOR Rd, Rr
1572 	INST_DECL (mov,    0xfc00, 0x2c00, 1,      2,   MOV    ), // MOV Rd, Rr
1573 	INST_DECL (mul,    0xfc00, 0x9c00, 2,      2,   AND    ), // MUL Rd, Rr
1574 	INST_DECL (or,     0xfc00, 0x2800, 1,      2,   OR     ), // OR Rd, Rr
1575 	INST_DECL (sbc,    0xfc00, 0x0800, 1,      2,   SUB    ), // SBC Rd, Rr
1576 	INST_DECL (sub,    0xfc00, 0x1800, 1,      2,   SUB    ), // SUB Rd, Rr
1577 	INST_DECL (in,     0xf800, 0xb000, 1,      2,   IO     ), // IN Rd, A
1578 	//INST_DECL (lds16,  0xf800, 0xa000, 1,      2,   LOAD   ), // LDS Rd, k
1579 	INST_DECL (out,    0xf800, 0xb800, 1,      2,   IO     ), // OUT A, Rr
1580 	INST_DECL (andi,   0xf000, 0x7000, 1,      2,   AND    ), // ANDI Rd, K
1581 	INST_DECL (cpi,    0xf000, 0x3000, 1,      2,   CMP    ), // CPI Rd, K
1582 	INST_DECL (ldi,    0xf000, 0xe000, 1,      2,   LOAD   ), // LDI Rd, K
1583 	INST_DECL (ori,    0xf000, 0x6000, 1,      2,   OR     ), // ORI Rd, K
1584 	INST_DECL (rcall,  0xf000, 0xd000, 0,      2,   CALL   ), // RCALL k
1585 	INST_DECL (rjmp,   0xf000, 0xc000, 2,      2,   JMP    ), // RJMP k
1586 	INST_DECL (sbci,   0xf000, 0x4000, 1,      2,   SUB    ), // SBC Rd, Rr
1587 	INST_DECL (subi,   0xf000, 0x5000, 1,      2,   SUB    ), // SUBI Rd, Rr
1588 	INST_DECL (ldd,    0xd200, 0x8000, 0,      2,   LOAD   ), // LD Rd, Y/Z+q
1589 	INST_DECL (std,    0xd200, 0x8200, 0,      2,   STORE  ), // ST Y/Z+q, Rr
1590 
1591 	INST_LAST
1592 };
1593 
set_invalid_op(RAnalOp * op,ut64 addr)1594 static void set_invalid_op(RAnalOp *op, ut64 addr) {
1595 	// Unknown or invalid instruction.
1596 	op->family = R_ANAL_OP_FAMILY_UNKNOWN;
1597 	op->type = R_ANAL_OP_TYPE_UNK;
1598 	op->addr = addr;
1599 	op->nopcode = 1;
1600 	op->cycles = 1;
1601 	op->size = 2;
1602 	// set an esil trap to prevent the execution of it
1603 	r_strbuf_set (&op->esil, "1,$");
1604 }
1605 
avr_op_analyze(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,CPU_MODEL * cpu)1606 static OPCODE_DESC* avr_op_analyze(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, CPU_MODEL *cpu) {
1607 	OPCODE_DESC *opcode_desc;
1608 	if (len < 2) {
1609 		return NULL;
1610 	}
1611 	ut16 ins = (buf[1] << 8) | buf[0];
1612 	int fail;
1613 	char *t;
1614 
1615 	// process opcode
1616 	for (opcode_desc = opcodes; opcode_desc->handler; opcode_desc++) {
1617 		if ((ins & opcode_desc->mask) == opcode_desc->selector) {
1618 			fail = 0;
1619 
1620 			// copy default cycles/size values
1621 			op->cycles = opcode_desc->cycles;
1622 			op->size = opcode_desc->size;
1623 			op->type = opcode_desc->type;
1624 			op->jump = UT64_MAX;
1625 			op->fail = UT64_MAX;
1626 			// op->fail = addr + op->size;
1627 			op->addr = addr;
1628 
1629 			// start void esil expression
1630 			r_strbuf_setf (&op->esil, "%s", "");
1631 
1632 			// handle opcode
1633 			opcode_desc->handler (anal, op, buf, len, &fail, cpu);
1634 			if (fail) {
1635 				goto INVALID_OP;
1636 			}
1637 			if (op->cycles <= 0) {
1638 				// eprintf ("opcode %s @%"PFMT64x" returned 0 cycles.\n", opcode_desc->name, op->addr);
1639 				opcode_desc->cycles = 2;
1640 			}
1641 			op->nopcode = (op->type == R_ANAL_OP_TYPE_UNK);
1642 
1643 			// remove trailing coma (COMETE LA COMA)
1644 			t = r_strbuf_get (&op->esil);
1645 			if (t && strlen (t) > 1) {
1646 				t += strlen (t) - 1;
1647 				if (*t == ',') {
1648 					*t = '\0';
1649 				}
1650 			}
1651 
1652 			return opcode_desc;
1653 		}
1654 	}
1655 #if 0
1656 	// ignore reserved opcodes (if they have not been caught by the previous loop)
1657 	if ((ins & 0xff00) == 0xff00 && (ins & 0xf) > 7) {
1658 		goto INVALID_OP;
1659 	}
1660 
1661 INVALID_OP:
1662 	// An unknown or invalid option has appeared.
1663 	//  -- Throw pokeball!
1664 	op->family = R_ANAL_OP_FAMILY_UNKNOWN;
1665 	op->type = R_ANAL_OP_TYPE_UNK;
1666 	op->addr = addr;
1667 	op->nopcode = 1;
1668 	op->cycles = 1;
1669 	op->size = 2;
1670 	// launch esil trap (for communicating upper layers about this weird
1671 	// and stinky situation
1672 	r_strbuf_set (&op->esil, "1,$");
1673 #else
1674 INVALID_OP:
1675 	set_invalid_op (op, addr);
1676 #endif
1677 
1678 	return NULL;
1679 }
1680 
avr_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)1681 static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
1682 	CPU_MODEL *cpu;
1683 	ut64 offset;
1684 	int size = -1;
1685 	char mnemonic[32] = {0};
1686 
1687 	set_invalid_op (op, addr);
1688 
1689 	size = avr_decode (mnemonic, addr, buf, len);
1690 	if (!strcmp (mnemonic, "invalid") ||
1691 		!strcmp (mnemonic, "truncated")) {
1692 		op->eob = true;
1693 		op->mnemonic = strdup(mnemonic);
1694 		return -1;
1695 	}
1696 
1697 	if (!op) {
1698 		return -1;
1699 	}
1700 
1701 	// select cpu info
1702 	cpu = get_cpu_model (anal->cpu);
1703 
1704 	// set memory layout registers
1705 	if (anal->esil) {
1706 		offset = 0;
1707 		r_anal_esil_reg_write (anal->esil, "_prog", offset);
1708 
1709 		offset += (1 << cpu->pc);
1710 		r_anal_esil_reg_write (anal->esil, "_io", offset);
1711 
1712 		offset += const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "sram_start"));
1713 		r_anal_esil_reg_write (anal->esil, "_sram", offset);
1714 
1715 		offset += const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "sram_size"));
1716 		r_anal_esil_reg_write (anal->esil, "_eeprom", offset);
1717 
1718 		offset += const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "eeprom_size"));
1719 		r_anal_esil_reg_write (anal->esil, "_page", offset);
1720 	}
1721 	// process opcode
1722 	avr_op_analyze (anal, op, addr, buf, len, cpu);
1723 
1724 	op->mnemonic = strdup(mnemonic);
1725 	op->size = size;
1726 
1727 	return size;
1728 }
1729 
avr_custom_des(RAnalEsil * esil)1730 static bool avr_custom_des (RAnalEsil *esil) {
1731 	ut64 key, encrypt, text,des_round;
1732 	ut32 key_lo, key_hi, buf_lo, buf_hi;
1733 	if (!esil || !esil->anal || !esil->anal->reg) {
1734 		return false;
1735 	}
1736 	if (!__esil_pop_argument (esil, &des_round)) {
1737 		return false;
1738 	}
1739 	r_anal_esil_reg_read (esil, "hf", &encrypt, NULL);
1740 	r_anal_esil_reg_read (esil, "deskey", &key, NULL);
1741 	r_anal_esil_reg_read (esil, "text", &text, NULL);
1742 
1743 	key_lo = key & UT32_MAX;
1744 	key_hi = key >> 32;
1745 	buf_lo = text & UT32_MAX;
1746 	buf_hi = text >> 32;
1747 
1748 	if (des_round != desctx.round) {
1749 		desctx.round = des_round;
1750 	}
1751 
1752 	if (!desctx.round) {
1753 		int i;
1754 		//generating all round keys
1755 		r_des_permute_key (&key_lo, &key_hi);
1756 		for (i = 0; i < 16; i++) {
1757 			r_des_round_key (i, &desctx.round_key_lo[i], &desctx.round_key_hi[i], &key_lo, &key_hi);
1758 		}
1759 		r_des_permute_block0 (&buf_lo, &buf_hi);
1760 	}
1761 
1762 	if (encrypt) {
1763 		r_des_round (&buf_lo, &buf_hi, &desctx.round_key_lo[desctx.round], &desctx.round_key_hi[desctx.round]);
1764 	} else {
1765 		r_des_round (&buf_lo, &buf_hi, &desctx.round_key_lo[15 - desctx.round], &desctx.round_key_hi[15 - desctx.round]);
1766 	}
1767 
1768 	if (desctx.round == 15) {
1769 		r_des_permute_block1 (&buf_hi, &buf_lo);
1770 		desctx.round = 0;
1771 	} else {
1772 		desctx.round++;
1773 	}
1774 
1775 	r_anal_esil_reg_write (esil, "text", text);
1776 	return true;
1777 }
1778 
1779 // ESIL operation SPM_PAGE_ERASE
avr_custom_spm_page_erase(RAnalEsil * esil)1780 static bool avr_custom_spm_page_erase(RAnalEsil *esil) {
1781 	CPU_MODEL *cpu;
1782 	ut8 c;
1783 	ut64 addr, page_size_bits, i;
1784 
1785 	// sanity check
1786 	if (!esil || !esil->anal || !esil->anal->reg) {
1787 		return false;
1788 	}
1789 
1790 	// get target address
1791 	if (!__esil_pop_argument(esil, &addr)) {
1792 		return false;
1793 	}
1794 
1795 	// get details about current MCU and fix input address
1796 	cpu = get_cpu_model (esil->anal->cpu);
1797 	page_size_bits = const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "page_size"));
1798 
1799 	// align base address to page_size_bits
1800 	addr &= ~(MASK (page_size_bits));
1801 
1802 	// perform erase
1803 	//eprintf ("SPM_PAGE_ERASE %ld bytes @ 0x%08" PFMT64x ".\n", page_size, addr);
1804 	c = 0xff;
1805 	for (i = 0; i < (1ULL << page_size_bits); i++) {
1806 		r_anal_esil_mem_write (
1807 			esil, (addr + i) & CPU_PC_MASK (cpu), &c, 1);
1808 	}
1809 
1810 	return true;
1811 }
1812 
1813 // ESIL operation SPM_PAGE_FILL
avr_custom_spm_page_fill(RAnalEsil * esil)1814 static bool avr_custom_spm_page_fill(RAnalEsil *esil) {
1815 	CPU_MODEL *cpu;
1816 	ut64 addr, page_size_bits, i;
1817 	ut8 r0, r1;
1818 
1819 	// sanity check
1820 	if (!esil || !esil->anal || !esil->anal->reg) {
1821 		return false;
1822 	}
1823 
1824 	// get target address, r0, r1
1825 	if (!__esil_pop_argument(esil, &addr)) {
1826 		return false;
1827 	}
1828 
1829 	if (!__esil_pop_argument (esil, &i)) {
1830 		return false;
1831 	}
1832 	r0 = i;
1833 
1834 	if (!__esil_pop_argument (esil, &i)) {
1835 		return false;
1836 	}
1837 	r1 = i;
1838 
1839 	// get details about current MCU and fix input address
1840 	cpu = get_cpu_model (esil->anal->cpu);
1841 	page_size_bits = const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "page_size"));
1842 
1843 	// align and crop base address
1844 	addr &= (MASK (page_size_bits) ^ 1);
1845 
1846 	// perform write to temporary page
1847 	//eprintf ("SPM_PAGE_FILL bytes (%02x, %02x) @ 0x%08" PFMT64x ".\n", r1, r0, addr);
1848 	r_anal_esil_mem_write (esil, addr++, &r0, 1);
1849 	r_anal_esil_mem_write (esil, addr++, &r1, 1);
1850 
1851 	return true;
1852 }
1853 
1854 // ESIL operation SPM_PAGE_WRITE
avr_custom_spm_page_write(RAnalEsil * esil)1855 static bool avr_custom_spm_page_write(RAnalEsil *esil) {
1856 	CPU_MODEL *cpu;
1857 	char *t = NULL;
1858 	ut64 addr, page_size_bits, tmp_page;
1859 
1860 	// sanity check
1861 	if (!esil || !esil->anal || !esil->anal->reg) {
1862 		return false;
1863 	}
1864 
1865 	// get target address
1866 	if (!__esil_pop_argument (esil, &addr)) {
1867 		return false;
1868 	}
1869 
1870 	// get details about current MCU and fix input address and base address
1871 	// of the internal temporary page
1872 	cpu = get_cpu_model (esil->anal->cpu);
1873 	page_size_bits = const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "page_size"));
1874 	r_anal_esil_reg_read (esil, "_page", &tmp_page, NULL);
1875 
1876 	// align base address to page_size_bits
1877 	addr &= (~(MASK (page_size_bits)) & CPU_PC_MASK (cpu));
1878 
1879 	// perform writing
1880 	//eprintf ("SPM_PAGE_WRITE %ld bytes @ 0x%08" PFMT64x ".\n", page_size, addr);
1881 	if (!(t = malloc (1 << page_size_bits))) {
1882 		eprintf ("Cannot alloc a buffer for copying the temporary page.\n");
1883 		return false;
1884 	}
1885 	r_anal_esil_mem_read (esil, tmp_page, (ut8 *) t, 1 << page_size_bits);
1886 	r_anal_esil_mem_write (esil, addr, (ut8 *) t, 1 << page_size_bits);
1887 
1888 	return true;
1889 }
1890 
esil_avr_hook_reg_write(RAnalEsil * esil,const char * name,ut64 * val)1891 static int esil_avr_hook_reg_write(RAnalEsil *esil, const char *name, ut64 *val) {
1892 	CPU_MODEL *cpu;
1893 
1894 	if (!esil || !esil->anal) {
1895 		return 0;
1896 	}
1897 
1898 	// select cpu info
1899 	cpu = get_cpu_model (esil->anal->cpu);
1900 
1901 	// crop registers and force certain values
1902 	if (!strcmp (name, "pc")) {
1903 		*val &= CPU_PC_MASK (cpu);
1904 	} else if (!strcmp (name, "pcl")) {
1905 		if (cpu->pc < 8) {
1906 			*val &= MASK (8);
1907 		}
1908 	} else if (!strcmp (name, "pch")) {
1909 		*val = cpu->pc > 8
1910 			? *val & MASK (cpu->pc - 8)
1911 			: 0;
1912 	}
1913 
1914 	return 0;
1915 }
1916 
esil_avr_init(RAnalEsil * esil)1917 static int esil_avr_init(RAnalEsil *esil) {
1918 	if (!esil) {
1919 		return false;
1920 	}
1921 	desctx.round = 0;
1922 	r_anal_esil_set_op (esil, "des", avr_custom_des, 0, 0, R_ANAL_ESIL_OP_TYPE_CUSTOM);		//better meta info plz
1923 	r_anal_esil_set_op (esil, "SPM_PAGE_ERASE", avr_custom_spm_page_erase, 0, 0, R_ANAL_ESIL_OP_TYPE_CUSTOM);
1924 	r_anal_esil_set_op (esil, "SPM_PAGE_FILL", avr_custom_spm_page_fill, 0, 0, R_ANAL_ESIL_OP_TYPE_CUSTOM);
1925 	r_anal_esil_set_op (esil, "SPM_PAGE_WRITE", avr_custom_spm_page_write, 0, 0, R_ANAL_ESIL_OP_TYPE_CUSTOM);
1926 	esil->cb.hook_reg_write = esil_avr_hook_reg_write;
1927 
1928 	return true;
1929 }
1930 
esil_avr_fini(RAnalEsil * esil)1931 static int esil_avr_fini(RAnalEsil *esil) {
1932 	return true;
1933 }
1934 
set_reg_profile(RAnal * anal)1935 static bool set_reg_profile(RAnal *anal) {
1936 	const char *p =
1937 		"=PC	pcl\n"
1938 		"=SN	r24\n"
1939 		"=SP	sp\n"
1940 		"=BP    y\n"
1941 // explained in http://www.nongnu.org/avr-libc/user-manual/FAQ.html
1942 // and http://www.avrfreaks.net/forum/function-calling-convention-gcc-generated-assembly-file
1943 		"=A0	r25\n"
1944 		"=A1	r24\n"
1945 		"=A2	r23\n"
1946 		"=A3	r22\n"
1947 		"=R0	r24\n"
1948 #if 0
1949 PC: 16- or 22-bit program counter
1950 SP: 8- or 16-bit stack pointer
1951 SREG: 8-bit status register
1952 RAMPX, RAMPY, RAMPZ, RAMPD and EIND:
1953 #endif
1954 // 8bit registers x 32
1955 		"gpr	r0	.8	0	0\n"
1956 		"gpr	r1	.8	1	0\n"
1957 		"gpr	r2	.8	2	0\n"
1958 		"gpr	r3	.8	3	0\n"
1959 		"gpr	r4	.8	4	0\n"
1960 		"gpr	r5	.8	5	0\n"
1961 		"gpr	r6	.8	6	0\n"
1962 		"gpr	r7	.8	7	0\n"
1963 		"gpr	text	.64	0	0\n"
1964 		"gpr	r8	.8	8	0\n"
1965 		"gpr	r9	.8	9	0\n"
1966 		"gpr	r10	.8	10	0\n"
1967 		"gpr	r11	.8	11	0\n"
1968 		"gpr	r12	.8	12	0\n"
1969 		"gpr	r13	.8	13	0\n"
1970 		"gpr	r14	.8	14	0\n"
1971 		"gpr	r15	.8	15	0\n"
1972 		"gpr	deskey	.64	8	0\n"
1973 		"gpr	r16	.8	16	0\n"
1974 		"gpr	r17	.8	17	0\n"
1975 		"gpr	r18	.8	18	0\n"
1976 		"gpr	r19	.8	19	0\n"
1977 		"gpr	r20	.8	20	0\n"
1978 		"gpr	r21	.8	21	0\n"
1979 		"gpr	r22	.8	22	0\n"
1980 		"gpr	r23	.8	23	0\n"
1981 		"gpr	r24	.8	24	0\n"
1982 		"gpr	r25	.8	25	0\n"
1983 		"gpr	r26	.8	26	0\n"
1984 		"gpr	r27	.8	27	0\n"
1985 		"gpr	r28	.8	28	0\n"
1986 		"gpr	r29	.8	29	0\n"
1987 		"gpr	r30	.8	30	0\n"
1988 		"gpr	r31	.8	31	0\n"
1989 
1990 // 16 bit overlapped registers for 16 bit math
1991 		"gpr	r1_r0	.16	0	0\n"	//this is a hack for mul
1992 		"gpr	r17_r16	.16	16	0\n"
1993 		"gpr	r19_r18	.16	18	0\n"
1994 		"gpr	r21_r20	.16	20	0\n"
1995 		"gpr	r23_r22	.16	22	0\n"
1996 		"gpr	r25_r24	.16	24	0\n"
1997 		"gpr	r27_r26	.16	26	0\n"
1998 		"gpr	r29_r28	.16	28	0\n"
1999 		"gpr	r31_r30	.16	30	0\n"
2000 
2001 // 16 bit overlapped registers for memory addressing
2002 		"gpr	x	.16	26	0\n"
2003 		"gpr	y	.16	28	0\n"
2004 		"gpr	z	.16	30	0\n"
2005 // program counter
2006 // NOTE: program counter size in AVR depends on the CPU model. It seems that
2007 // the PC may range from 16 bits to 22 bits.
2008 		"gpr	pc	.32	32	0\n"
2009 		"gpr	pcl	.16	32	0\n"
2010 		"gpr	pch	.16	34	0\n"
2011 // special purpose registers
2012 		"gpr	sp	.16	36	0\n"
2013 		"gpr	spl	.8	36	0\n"
2014 		"gpr	sph	.8	37	0\n"
2015 // status bit register (SREG)
2016 		"gpr	sreg	.8	38	0\n"
2017 		"gpr	cf	.1	38.0	0\n" // Carry. This is a borrow flag on subtracts.
2018 		"gpr	zf	.1	38.1	0\n" // Zero. Set to 1 when an arithmetic result is zero.
2019 		"gpr	nf	.1	38.2	0\n" // Negative. Set to a copy of the most significant bit of an arithmetic result.
2020 		"gpr	vf	.1	38.3	0\n" // Overflow flag. Set in case of two's complement overflow.
2021 		"gpr	sf	.1	38.4	0\n" // Sign flag. Unique to AVR, this is always (N ^ V) (xor), and shows the true sign of a comparison.
2022 		"gpr	hf	.1	38.5	0\n" // Half carry. This is an internal carry from additions and is used to support BCD arithmetic.
2023 		"gpr	tf	.1	38.6	0\n" // Bit copy. Special bit load and bit store instructions use this bit.
2024 		"gpr	if	.1	38.7	0\n" // Interrupt flag. Set when interrupts are enabled.
2025 // 8bit segment registers to be added to X, Y, Z to get 24bit offsets
2026 		"gpr	rampx	.8	39	0\n"
2027 		"gpr	rampy	.8	40	0\n"
2028 		"gpr	rampz	.8	41	0\n"
2029 		"gpr	rampd	.8	42	0\n"
2030 		"gpr	eind	.8	43	0\n"
2031 // memory mapping emulator registers
2032 //      _prog
2033 //		the program flash. It has its own address space.
2034 //	_ram
2035 //	_io
2036 //		start of the data addres space. It is the same address of IO,
2037 //		because IO is the first memory space addressable in the AVR.
2038 //	_sram
2039 //		start of the SRAM (this offset depends on IO size, and it is
2040 //		inside the _ram address space)
2041 //      _eeprom
2042 //              this is another address space, outside ram and flash
2043 //      _page
2044 //              this is the temporary page used by the SPM instruction. This
2045 //              memory is not directly addressable and it is used internally by
2046 //              the CPU when autoflashing.
2047 		"gpr	_prog	.32	44	0\n"
2048 		"gpr    _page   .32     48	0\n"
2049 		"gpr	_eeprom	.32	52	0\n"
2050 		"gpr	_ram	.32	56	0\n"
2051 		"gpr	_io	.32	56	0\n"
2052 		"gpr	_sram	.32	60	0\n"
2053 // other important MCU registers
2054 //	spmcsr/spmcr
2055 //		Store Program Memory Control and Status Register (SPMCSR)
2056 		"gpr    spmcsr  .8      64      0\n"
2057 		;
2058 
2059 	return r_reg_set_profile_string (anal->reg, p);
2060 }
2061 
archinfo(RAnal * anal,int q)2062 static int archinfo(RAnal *anal, int q) {
2063 	if (q == R_ANAL_ARCHINFO_ALIGN) {
2064 		return 2;
2065 	}
2066 	if (q == R_ANAL_ARCHINFO_MAX_OP_SIZE) {
2067 		return 4;
2068 	}
2069 	if (q == R_ANAL_ARCHINFO_MIN_OP_SIZE) {
2070 		return 2;
2071 	}
2072 	return 2; // XXX
2073 }
2074 
anal_mask_avr(RAnal * anal,int size,const ut8 * data,ut64 at)2075 static ut8 *anal_mask_avr(RAnal *anal, int size, const ut8 *data, ut64 at) {
2076 	RAnalOp *op = NULL;
2077 	ut8 *ret = NULL;
2078 	int idx;
2079 
2080 	if (!(op = r_anal_op_new ())) {
2081 		return NULL;
2082 	}
2083 
2084 	if (!(ret = malloc (size))) {
2085 		r_anal_op_free (op);
2086 		return NULL;
2087 	}
2088 
2089 	memset (ret, 0xff, size);
2090 
2091 	CPU_MODEL *cpu = get_cpu_model (anal->cpu);
2092 
2093 	for (idx = 0; idx + 1 < size; idx += op->size) {
2094 		OPCODE_DESC* opcode_desc = avr_op_analyze (anal, op, at + idx, data + idx, size - idx, cpu);
2095 
2096 		if (op->size < 1) {
2097 			break;
2098 		}
2099 
2100 		if (!opcode_desc) { // invalid instruction
2101 			continue;
2102 		}
2103 
2104 		// the additional data for "long" opcodes (4 bytes) is usually something we want to ignore for matching
2105 		// (things like memory offsets or jump addresses)
2106 		if (op->size == 4) {
2107 			ret[idx + 2] = 0;
2108 			ret[idx + 3] = 0;
2109 		}
2110 
2111 		if (op->ptr != UT64_MAX || op->jump != UT64_MAX) {
2112 			ret[idx] = opcode_desc->mask;
2113 			ret[idx + 1] = opcode_desc->mask >> 8;
2114 		}
2115 	}
2116 
2117 	r_anal_op_free (op);
2118 
2119 	return ret;
2120 }
2121 
2122 RAnalPlugin r_anal_plugin_avr = {
2123 	.name = "avr",
2124 	.desc = "AVR code analysis plugin",
2125 	.license = "LGPL3",
2126 	.arch = "avr",
2127 	.esil = true,
2128 	.archinfo = archinfo,
2129 	.bits = 8 | 16, // 24 big regs conflicts
2130 	.op = &avr_op,
2131 	.set_reg_profile = &set_reg_profile,
2132 	.esil_init = esil_avr_init,
2133 	.esil_fini = esil_avr_fini,
2134 	.anal_mask = anal_mask_avr,
2135 };
2136 
2137 #ifndef R2_PLUGIN_INCORE
2138 R_API RLibStruct radare_plugin = {
2139 	.type = R_LIB_TYPE_ANAL,
2140 	.data = &r_anal_plugin_avr,
2141 	.version = R2_VERSION
2142 };
2143 #endif
2144