Rizin
unix-like reverse engineering framework and cli tools
avr_il.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021-2022 RizinOrg <info@rizin.re>
2 // SPDX-FileCopyrightText: 2021-2022 deroad <wargio@libero.it>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include "avr_il.h"
7 
15 #define AVR_REG_SIZE 8
16 #define AVR_SREG_SIZE 8
17 #define AVR_MMIO_SIZE 8
18 #define AVR_SP_SIZE 16
19 #define AVR_IND_SIZE 16
20 #define AVR_ADDR_SIZE 32 // should be 22 bits max, but we can ignore this
21 
22 #define AVR_SREG "sreg"
23 #define AVR_SP "sp"
24 #define AVR_SPH "spl"
25 #define AVR_SPL "sph"
26 #define AVR_RAMPX "rampx"
27 #define AVR_RAMPY "rampy"
28 #define AVR_RAMPZ "rampz"
29 #define AVR_RAMPD "rampd"
30 #define AVR_EIND "eind"
31 #define AVR_SPMCSR "spmcsr"
32 #define AVR_LET_RES "RES"
33 #define AVR_LET_IND "IND"
34 
35 // Below is described the status register
36 // SREG = I|T|H|S|V|N|Z|C
37 // bits 7|6|5|4|3|2|1|0
38 #define AVR_SREG_I_BIT ((ut8)(1u << 7))
39 #define AVR_SREG_I "if"
40 #define AVR_SREG_T_BIT ((ut8)(1u << 6))
41 #define AVR_SREG_T "tf"
42 #define AVR_SREG_H_BIT ((ut8)(1u << 5))
43 #define AVR_SREG_H "hf"
44 #define AVR_SREG_S_BIT ((ut8)(1u << 4))
45 #define AVR_SREG_S "sf"
46 #define AVR_SREG_V_BIT ((ut8)(1u << 3))
47 #define AVR_SREG_V "vf"
48 #define AVR_SREG_N_BIT ((ut8)(1u << 2))
49 #define AVR_SREG_N "nf"
50 #define AVR_SREG_Z_BIT ((ut8)(1u << 1))
51 #define AVR_SREG_Z "zf"
52 #define AVR_SREG_C_BIT ((ut8)(1u << 0))
53 #define AVR_SREG_C "cf"
54 
55 #define AVR_ADDR(x) UNSIGNED(AVR_ADDR_SIZE, x)
56 #define AVR_PC(x) UN(AVR_ADDR_SIZE, x)
57 #define AVR_SH(sh) U32((sh))
58 #define AVR_IMM(imm) UN(AVR_REG_SIZE, (imm))
59 #define AVR_IMM16(imm) U16((imm))
60 #define AVR_REG(reg) VARG(avr_registers[reg])
61 #define AVR_REG_SET(reg, x) SETG(avr_registers[reg], x)
62 #define AVR_ONE() UN(AVR_REG_SIZE, 1)
63 #define AVR_ZERO() UN(AVR_REG_SIZE, 0)
64 #define AVR_X() avr_il_get_indirect_address_reg(27, 26)
65 #define AVR_Y() avr_il_get_indirect_address_reg(29, 28)
66 #define AVR_Z() avr_il_get_indirect_address_reg(31, 30)
67 #define AVR_SET_X(l, n, add) avr_il_update_indirect_address_reg(l, 27, 26, n, add)
68 #define AVR_SET_Y(l, n, add) avr_il_update_indirect_address_reg(l, 29, 28, n, add)
69 #define AVR_SET_Z(l, n, add) avr_il_update_indirect_address_reg(l, 31, 30, n, add)
70 
71 #define AVR_SREG_I_SET(x) avr_il_assign_bool(AVR_SREG_I, x)
72 #define AVR_SREG_T_SET(x) avr_il_assign_bool(AVR_SREG_T, x)
73 #define AVR_SREG_H_SET(x) avr_il_assign_bool(AVR_SREG_H, x)
74 #define AVR_SREG_S_SET(x) avr_il_assign_bool(AVR_SREG_S, x)
75 #define AVR_SREG_V_SET(x) avr_il_assign_bool(AVR_SREG_V, x)
76 #define AVR_SREG_N_SET(x) avr_il_assign_bool(AVR_SREG_N, x)
77 #define AVR_SREG_Z_SET(x) avr_il_assign_bool(AVR_SREG_Z, x)
78 #define AVR_SREG_C_SET(x) avr_il_assign_bool(AVR_SREG_C, x)
79 
80 #define avr_return_val_if_invalid_gpr(x, v) \
81  if (x >= 32) { \
82  RZ_LOG_ERROR("RzIL: AVR: invalid register R%u\n", x); \
83  return v; \
84  }
85 
86 #define avr_return_val_if_invalid_indirect_address(x, v) \
87  if (x != 'X' && x != 'Y' && x != 'Z') { \
88  RZ_LOG_ERROR("RzIL: AVR: invalid indirect address register %c\n", x); \
89  return v; \
90  }
91 
95 const char *avr_registers[32] = {
96  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
97  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18",
98  "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27",
99  "r28", "r29", "r30", "r31"
100 };
101 
105 static const char *avr_global_registers[] = {
106  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
107  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18",
108  "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27",
109  "r28", "r29", "r30", "r31", AVR_SREG_I, AVR_SREG_T, AVR_SREG_H,
113 };
114 
116  RzILOpPure *high = AVR_REG(reg_high); // rH
117  RzILOpPure *low = AVR_REG(reg_low); // rL
118  return rz_il_op_new_append(high, low); // addr
119 }
120 
121 static RzILOpEffect *avr_il_update_indirect_address_reg(const char *local, ut16 reg_high, ut16 reg_low, ut64 n, bool add) {
122  RzILOpBitVector *_iar, *_num;
123  RzILOpEffect *_high, *_low;
124  const char *Rh = avr_registers[reg_high]; // register high
125  const char *Rl = avr_registers[reg_low]; // register low
126 
127  _iar = VARL(local);
128  if (n > 0) {
129  _num = UN(AVR_IND_SIZE, n);
130  if (add) {
131  _iar = ADD(_iar, _num);
132  } else {
133  _iar = SUB(_iar, _num);
134  }
135  }
136  _num = AVR_SH(8);
137  _iar = SHIFTR0(_iar, _num);
138  _iar = UNSIGNED(AVR_REG_SIZE, _iar);
139  _high = SETG(Rh, _iar);
140 
141  _iar = VARL(local);
142  if (n > 0) {
143  _num = UN(AVR_IND_SIZE, n);
144  if (add) {
145  _iar = ADD(_iar, _num);
146  } else {
147  _iar = SUB(_iar, _num);
148  }
149  }
150  _iar = UNSIGNED(AVR_REG_SIZE, _iar);
151  _low = SETG(Rl, _iar);
152  return SEQ2(_high, _low);
153 }
154 
155 static inline RzILOpEffect *avr_il_jump_relative(AVROp *aop, RzAnalysis *analysis, ut64 where) {
156  RzILOpBitVector *_loc = UN(AVR_ADDR_SIZE, where);
157  return JMP(_loc);
158 }
159 
160 static inline RzILOpEffect *avr_il_branch_when(AVROp *aop, RzAnalysis *analysis, ut64 where, RzILOpBool *when, bool cond) {
161  RzILOpEffect *_jmp = avr_il_jump_relative(aop, analysis, where);
162  if (cond) {
163  return BRANCH(when, _jmp, NULL);
164  }
165  return BRANCH(when, NULL, _jmp);
166 }
167 
168 static inline RzILOpEffect *avr_il_assign_imm(const char *reg, ut16 imm) {
170  return SETG(reg, _bv);
171 }
172 
173 static inline RzILOpEffect *avr_il_assign_bool(const char *reg, ut16 value) {
174  return SETG(reg, value ? IL_TRUE : IL_FALSE);
175 }
176 
177 static inline RzILOpEffect *avr_il_assign_reg(const char *dst, const char *src) {
178  RzILOpPure *_var = VARG(src);
179  return SETG(dst, _var);
180 }
181 
184  return STOREW(_loc, var);
185 }
186 
187 static inline RzILOpEffect *avr_il_store_reg(ut64 addr, const char *reg) {
188  RzILOpPure *_var = VARG(reg);
189  return avr_il_store_pure(addr, _var);
190 }
191 
192 static inline RzILOpEffect *avr_il_load_reg(ut64 addr, const char *reg, ut16 size) {
194  RzILOpBitVector *_val = LOADW(size, _loc);
195  return SETG(reg, _val);
196 }
197 
198 static inline RzILOpEffect *avr_il_set16_from_reg(const char *dst, const char *src, ut16 mask, ut16 sh) {
199  RzILOpPure *_dst = VARG(dst);
200  RzILOpBitVector *_mask = UN(16, mask);
201  RzILOpBitVector *_and = LOGAND(_dst, _mask);
202  RzILOpPure *_src = VARG(src);
203  RzILOpBitVector *_extz = UNSIGNED(16, _src);
204  if (sh) {
205  RzILOpBitVector *_sh = AVR_SH(sh);
206  _extz = SHIFTL0(_extz, _sh);
207  }
208  RzILOpBitVector *_or = LOGOR(_extz, _and);
209  return SETG(dst, _or);
210 }
211 
212 static inline RzILOpEffect *avr_il_set_sreg_bit_from_reg(const char *src, ut8 bit_val, const char *bit_reg) {
213  RzILOpPure *reg = VARG(src);
214  RzILOpBitVector *bit = UN(AVR_REG_SIZE, bit_val);
215  RzILOpBitVector *and = LOGAND(reg, bit);
216  return SETG(bit_reg, and);
217 }
218 
219 static inline RzILOpBitVector *avr_il_sreg_bit_as_imm(const char *sreg_bit, ut8 bit) {
220  RzILOpPure *_bit = VARG(sreg_bit);
221  RzILOpPure *_true = AVR_IMM(bit);
222  RzILOpPure *_false = AVR_ZERO();
223  return rz_il_op_new_ite(_bit, _true, _false);
224 }
225 
226 static inline const char *resolve_mmio(RzAnalysis *analysis, ut16 address) {
227  RzPlatformProfile *profile = analysis->arch_target ? analysis->arch_target->profile : NULL;
228  if (!profile) {
229  return NULL;
230  }
231  return rz_platform_profile_resolve_mmio(profile, address);
232 }
233 
234 static RzILOpEffect *avr_il_check_zero_flag_local(const char *local, bool and_zero) {
235  // set Z to 1 if !(x - y) or !(x - y - C)
236  RzILOpPure *_alu = VARL(local);
237  RzILOpBool *_is_zero = IS_ZERO(_alu);
238  if (and_zero) {
240  _is_zero = AND(_is_zero, Z);
241  }
242  return SETG(AVR_SREG_Z, _is_zero);
243 }
244 
246  RzILOpPure *x = AVR_REG(reg);
247  x = IS_ZERO(x);
248  return SETG(AVR_SREG_Z, x);
249 }
250 
252  RzILOpBitVector *Rd, *Rr, *bit, *not0, *Res, *and0, *and1, *and2, *or0;
253  // Rd = X, Rr = Y, Res = Rd + Rr or Res = Rd + Rr + C
254  // H: (Rd3 & Rr3) | (Rr3 & !Res3) | (!Res3 & Rd3)
255  // Set if there was a carry from bit 3; cleared otherwise
256 
257  // and0 = (Rd3 & Rr3)
258  Rd = DUP(x);
259  Rr = DUP(y);
260  and0 = LOGAND(Rd, Rr);
261 
262  // and1 = (Rr3 & !Res3)
263  Res = VARL(local);
264  not0 = LOGNOT(Res);
265  and1 = LOGAND(y, not0);
266 
267  // and2 = (!Res3 & Rd3)
268  Res = VARL(local);
269  not0 = LOGNOT(Res);
270  and2 = LOGAND(not0, x);
271 
272  // or = (and0 | and1)
273  or0 = LOGOR(and0, and1);
274 
275  // or |= and2
276  or0 = LOGOR(or0, and2);
277 
278  // extract bit 3 from or
279  bit = AVR_IMM(1u << 3);
280  and0 = LOGAND(or0, bit);
281  and0 = NON_ZERO(and0); // cast to bool
282  return SETG(AVR_SREG_H, and0);
283 }
284 
286  RzILOpBitVector *Rd, *Rr, *bit, *not0, *Res, *and0, *and1, *and2, *or0;
287  // Rd = X, Rr = Y, Res = Rd - Rr or Res = Rd - Rr - C
288  // H: (!Rd3 & Rr3) | (Rr3 & Res3) | (Res3 & !Rd3)
289  // Set if there was a carry from bit 3; cleared otherwise
290 
291  Rr = DUP(y);
292  // and0 = (!Rd3 & Rr3)
293  Rd = DUP(x);
294  not0 = LOGNOT(Rd); // !Rd
295  and0 = LOGAND(not0, Rr);
296 
297  // and1 = (Rr3 & Res3)
298  Res = VARL(local);
299  and1 = LOGAND(y, Res);
300 
301  // and2 = (Res3 & !Rd3)
302  Res = VARL(local);
303  not0 = LOGNOT(x);
304  and2 = LOGAND(Res, not0);
305 
306  // or = (and0 | and1)
307  or0 = LOGOR(and0, and1);
308 
309  // or |= and2
310  or0 = LOGOR(or0, and2);
311 
312  // extract bit 3 from or
313  bit = AVR_IMM(1u << 3);
314  and0 = LOGAND(or0, bit);
315  and0 = NON_ZERO(and0); // cast to bool
316  return SETG(AVR_SREG_H, and0);
317 }
318 
320  RzILOpBitVector *Rd, *Rr, *not0, *not1, *Res, *and0, *and1, *or0;
321  // Rd = X, Rr = Y, Res = Rd - Rr or Res = Rd - Rr - C
322  // V: (Rd7 & Rr7 & !Res7) | (!Rd7 & !Rr7 & Res7)
323  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
324 
325  // and0 = Rd7 & Rr7 & !Res7
326  Res = VARL(local);
327  Rd = DUP(x);
328  Rr = DUP(y);
329  not0 = LOGNOT(Res); // !Res
330  and0 = LOGAND(Rd, Rr); // Rd & Rr
331  and0 = LOGAND(and0, not0); // Rd & Rr & !Res
332 
333  // and1 = !Rd7 & !Rr7 & Res7
334  Res = VARL(local);
335  not0 = LOGNOT(x); // !Rd
336  not1 = LOGNOT(y); // !Rr
337  and1 = LOGAND(not0, not1); // !Rd & !Rr
338  and1 = LOGAND(and1, Res); // !Rd & Rr & Res
339 
340  // or = and0 | and1
341  or0 = LOGOR(and0, and1);
342 
343  // extract bit 7 from or
344  return SETG(AVR_SREG_V, MSB(or0));
345 }
346 
348  RzILOpPure *ovf, *Rdh, *Res;
349  // Rdh = X, Res = Rd+1:Rd
350  // V: !Rdh7 & Res15
351  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
352 
353  Rdh = AVR_REG(reg);
354  Rdh = MSB(Rdh); // Rdh7
355  Rdh = INV(Rdh); // !Rdh7
356 
357  Res = VARL(local);
358  Res = MSB(Res); // Res15
359 
360  ovf = AND(Rdh, Res); // !Rdh7 & Res15
361  return SETG(AVR_SREG_V, ovf);
362 }
363 
365  RzILOpBitVector *Rd, *Rr, *not0, *not1, *Res, *and0, *and1, *or0;
366  // Rd = X, Rr = Y, Res = Rd - Rr or Res = Rd - Rr - C
367  // V: (Rd7 & !Rr7 & !Res7) | (!Rd7 & Rr7 & Res7)
368  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
369 
370  // and0 = Rd7 & !Rr7 & !Res7
371  Res = VARL(local);
372  Rr = DUP(y);
373  not0 = LOGNOT(Rr); // !Rr
374  not1 = LOGNOT(Res); // !Res
375  Rd = DUP(x);
376  and0 = LOGAND(Rd, not0); // Rd & !Rr
377  and0 = LOGAND(and0, not1); // Rd & !Rr & !Res
378 
379  // and1 = !Rd7 & Rr7 & Res7
380  Res = VARL(local);
381  not0 = LOGNOT(x); // !Rd
382  and1 = LOGAND(not0, y); // !Rd & Rr
383  and1 = LOGAND(and1, Res); // !Rd & Rr & Res
384 
385  // or = and0 | and1
386  or0 = LOGOR(and0, and1);
387 
388  return SETG(AVR_SREG_V, MSB(or0));
389 }
390 
392  RzILOpPure *ovf, *Rdh, *Res;
393  // Rdh = X, Res = Rd+1:Rd
394  // V: Rdh7 & !Res15
395  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
396 
397  // extract bit 7 from Rdh
398  Rdh = AVR_REG(reg); // Rdh
399  Rdh = MSB(Rdh); // Rdh7
400 
401  // extract bit 15 from Res
402  Res = VARL(local);
403  Res = MSB(Res); // Res15
404  Res = INV(Res); // !Res15
405 
406  ovf = AND(Rdh, Res); // Rdh7 & !Res15
407  return SETG(AVR_SREG_V, ovf);
408 }
409 
411  // N: Res7 is set, AKA MSB
412  // extract bit 7 from Res
413  RzILOpPure *x = VARL(local);
414  x = MSB(x);
415  return SETG(AVR_SREG_N, x);
416 }
417 
419  // N: Res7 is set, AKA MSB
420  // extract bit 7 from Res
421  RzILOpPure *x = AVR_REG(reg);
422  x = MSB(x);
423  return SETG(AVR_SREG_N, x);
424 }
425 
427  RzILOpBitVector *Rd, *Rr, *not0, *Res, *and0, *and1, *and2, *or0;
428  // Rd = X, Rr = Y, Res = Rd + Rr or Res = Rd + Rr + C
429  // H: (Rd7 & Rr7) | (Rr7 & !Res7) | (!Res7 & Rd7)
430  // Set if there was a carry from bit 7; cleared otherwise
431 
432  // and0 = (Rd7 & Rr7)
433  Rd = DUP(x);
434  Rr = DUP(y);
435  and0 = LOGAND(Rd, Rr);
436 
437  // and1 = (Rr7 & !Res7)
438  Res = VARL(local);
439  not0 = LOGNOT(Res);
440  and1 = LOGAND(y, not0);
441 
442  // and2 = (!Res7 & Rd7)
443  Res = VARL(local);
444  not0 = LOGNOT(Res);
445  and2 = LOGAND(not0, x);
446 
447  // or = (and0 | and1)
448  or0 = LOGOR(and0, and1);
449 
450  // or |= and2
451  or0 = LOGOR(or0, and2);
452 
453  return SETG(AVR_SREG_C, MSB(or0));
454 }
455 
457  RzILOpBitVector *carry, *Rdh, *Res;
458  // Res = Rd+1:Rd
459  // !Res15 & Rdh7
460  // Set if the absolute value of K is larger than the absolute value of Rd; cleared otherwise
461 
462  // extract bit 7 from Rdh
463  Rdh = AVR_REG(reg); // Rdh
464  Rdh = MSB(Rdh); // Rdh7
465 
466  // extract bit 15 from Res
467  Res = VARL(local);
468  Res = MSB(Res); // Res15
469  Res = INV(Res); // !Res15
470 
471  carry = AND(Res, Rdh); // !Res15 & Rdh7
472  return SETG(AVR_SREG_C, carry);
473 }
474 
476  RzILOpBitVector *Rd, *Rr, *bit, *not0, *Res, *and0, *and1, *and2, *or0;
477  // Rd = X, Rr = Y, Res = Rd - Rr or Res = Rd - Rr - C
478  // H: (!Rd7 & Rr7) | (Rr7 & Res7) | (Res7 & !Rd7)
479  // Set if there was a carry from bit 7; cleared otherwise
480 
481  Rr = DUP(y);
482  // and0 = (!Rd7 & Rr7)
483  Rd = DUP(x);
484  not0 = LOGNOT(Rd); // !Rd
485  and0 = LOGAND(not0, Rr);
486 
487  // and1 = (Rr7 & Res7)
488  Res = VARL(local);
489  and1 = LOGAND(y, Res);
490 
491  // and2 = (Res7 & !Rd7)
492  Res = VARL(local);
493  not0 = LOGNOT(x);
494  and2 = LOGAND(Res, not0);
495 
496  // or = (and0 | and1)
497  or0 = LOGOR(and0, and1);
498 
499  // or |= and2
500  or0 = LOGOR(or0, and2);
501 
502  // extract bit 7 from or
503  bit = AVR_IMM(1u << 7);
504  and0 = LOGAND(or0, bit);
505  and0 = NON_ZERO(and0); // cast to bool
506  return SETG(AVR_SREG_C, and0);
507 }
508 
510  RzILOpBitVector *carry, *Rdh, *Res;
511  // Res = Rd+1:Rd
512  // Res15 & !Rdh7
513  // Set if the absolute value of K is larger than the absolute value of Rd; cleared otherwise
514 
515  // extract bit 7 from Rdh
516  Rdh = AVR_REG(reg); // Rdh
517  Rdh = MSB(Rdh); // Rdh7
518  Rdh = INV(Rdh); // !Rdh7
519 
520  // extract bit 15 from Res
521  Res = VARL(local);
522  Res = MSB(Res); // Res15
523 
524  carry = AND(Res, Rdh); // Res15 & !Rdh7
525  return SETG(AVR_SREG_C, carry);
526 }
527 
529  // S: N ^ V, For signed tests.
532  RzILOpBool *_xor = XOR(N, V);
533  return SETG(AVR_SREG_S, _xor);
534 }
535 
537  // V: N ^ C, Overflow with negative xor carry
540  RzILOpBool *_xor = XOR(N, C);
541  return SETG(AVR_SREG_V, _xor);
542 }
543 
544 static RzILOpPure *avr_subtract_if(ut32 bitsize, ut64 limit, RzILOpPure *minuend, ut64 subtrahend, bool invert) {
545  RzILOpPure *x, *y, *cmp;
546 
547  // cmp = minuend > limit
548  x = UN(bitsize, limit);
549  y = DUP(minuend);
550  cmp = UGT(y, x);
551 
552  x = DUP(minuend);
553  y = UN(bitsize, subtrahend);
554  if (invert) {
555  // x = subtrahend - minuend
556  x = SUB(y, x);
557  } else {
558  // x = minuend - subtrahend
559  x = SUB(x, y);
560  }
561 
562  return ITE(cmp, x, minuend);
563 }
564 
565 /* ops */
566 
567 static RzILOpEffect *avr_il_unk(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
568  return NULL; // rz_il_op_new_nop();
569 }
570 
571 static RzILOpEffect *avr_il_nop(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
572  return NOP();
573 }
574 
575 static RzILOpEffect *avr_il_adc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
576  RzILOpPure *x, *y;
577  RzILOpEffect *adc, *let, *H, *S, *V, *N, *Z, *C;
578  // Rd = Rd + Rr + C
579  ut16 Rd = aop->param[0];
580  ut16 Rr = aop->param[1];
583 
584  // TMP = Rd + Rr + C
585  x = AVR_REG(Rd);
586  y = AVR_REG(Rr);
587  x = ADD(x, y);
589  x = ADD(x, y);
590  let = SETL(AVR_LET_RES, x);
591 
592  // Rd = TMP
593  x = VARL(AVR_LET_RES);
594  adc = AVR_REG_SET(Rd, x);
595 
596  // V: (Rd7 & Rr7 & !Res7) | (!Rd7 & !Rr7 & Res7)
597  x = AVR_REG(Rd);
598  y = AVR_REG(Rr);
600 
601  // H: (Rd3 & Rr3) | (Rr3 & !R3) | (!R3 & Rd3)
602  x = AVR_REG(Rd);
603  y = AVR_REG(Rr);
605 
606  // N: Res7
608 
609  // Z: !Res
611 
612  // C: (Rd7 & Rr7) | (Rr7 & !R7) | (!R7 & Rd7)
613  x = AVR_REG(Rd);
614  y = AVR_REG(Rr);
616 
617  // S: N ^ V, For signed tests.
619 
620  return SEQ8(let, H, V, N, Z, C, S, adc);
621 }
622 
623 static RzILOpEffect *avr_il_add(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
624  RzILOpPure *x, *y;
625  RzILOpEffect *adc, *let, *H, *S, *V, *N, *Z, *C;
626  // Rd = Rd + Rr
627  ut16 Rd = aop->param[0];
628  ut16 Rr = aop->param[1];
631 
632  // TMP = Rd + Rr
633  x = AVR_REG(Rd);
634  y = AVR_REG(Rr);
635  x = ADD(x, y);
636  let = SETL(AVR_LET_RES, x);
637 
638  // Rd = TMP
639  x = VARL(AVR_LET_RES);
640  adc = AVR_REG_SET(Rd, x);
641 
642  // V: (Rd7 & Rr7 & !Res7) | (!Rd7 & !Rr7 & Res7)
643  x = AVR_REG(Rd);
644  y = AVR_REG(Rr);
646 
647  // H: (Rd3 & Rr3) | (Rr3 & !R3) | (!R3 & Rd3)
648  x = AVR_REG(Rd);
649  y = AVR_REG(Rr);
651 
652  // N: Res7
654 
655  // Z: !Res
657 
658  // C: (Rd7 & Rr7) | (Rr7 & !R7) | (!R7 & Rd7)
659  x = AVR_REG(Rd);
660  y = AVR_REG(Rr);
662 
663  // S: N ^ V, For signed tests.
665 
666  return SEQ8(let, H, V, N, Z, C, S, adc);
667 }
668 
669 static RzILOpEffect *avr_il_adiw(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
670  RzILOpPure *x, *imm;
671  RzILOpEffect *let, *adiw, *Z, *S, *V, *N, *C;
672  // Rd+1:Rd = Rd+1:Rd + K
673  // Rd can be only 24,26,28,30
674  ut16 Rdh = aop->param[0];
675  ut16 Rdl = aop->param[1];
676  ut16 K = aop->param[2];
679 
680  // IND = Rd+1:Rd + K
681  imm = UN(AVR_IND_SIZE, K);
683  x = ADD(x, imm);
684  let = SETL(AVR_LET_IND, x);
685 
686  // Rd+1:Rd = IND
687  adiw = avr_il_update_indirect_address_reg(AVR_LET_IND, Rdh, Rdl, 0, false);
688 
689  // set Z to 1 if !IND
691 
692  // Res = IND
693  // V: !Rdh7 & Res15
694  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
696 
697  // Res = IND
698  // N: Res15
699  // Set if MSB of the result is set; cleared otherwise.
701 
702  // Res = IND
703  // C: !Res15 & Rdh7
705 
706  // S: N ^ V, For signed tests.
708 
709  return SEQ7(let, adiw, Z, V, N, C, S);
710 }
711 
712 static RzILOpEffect *avr_il_and(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
713  RzILOpPure *x, *y;
714  RzILOpEffect *and0, *S, *V, *N, *Z;
715  // Rd = Rd & Rr
716  ut16 Rd = aop->param[0];
717  ut16 Rr = aop->param[1];
720 
721  // Rd = Rd & Rr
722  x = AVR_REG(Rd);
723  y = AVR_REG(Rr);
724  x = LOGAND(x, y);
725  and0 = AVR_REG_SET(Rd, x);
726 
727  // V: 0 (Cleared)
728  V = AVR_SREG_V_SET(false);
729 
730  // N: Res7
732 
733  // Z: !Res
735 
736  // S: N ^ V, For signed tests.
738 
739  return SEQ5(and0, V, N, Z, S);
740 }
741 
742 static RzILOpEffect *avr_il_andi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
743  RzILOpPure *x, *y;
744  RzILOpEffect *andi, *S, *V, *N, *Z;
745  // Rd = Rd & K
746  ut16 Rd = aop->param[0];
747  ut16 K = aop->param[1];
749 
750  // Rd = Rd & K
751  x = AVR_REG(Rd);
752  y = AVR_IMM(K);
753  x = LOGAND(x, y);
754  andi = AVR_REG_SET(Rd, x);
755 
756  // V: 0 (Cleared)
757  V = AVR_SREG_V_SET(false);
758 
759  // N: Res7
761 
762  // Z: !Res
764 
765  // S: N ^ V, For signed tests.
767 
768  return SEQ5(andi, V, N, Z, S);
769 }
770 
771 static RzILOpEffect *avr_il_asr(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
772  // Arithmetic Signed Shift Right
773  RzILOpPure *x, *y, *z;
774  RzILOpEffect *asr, *S, *V, *N, *Z, *C;
775  // Rd >>= 1
776  ut16 Rd = aop->param[0];
778 
779  // simplified by adding itself
780  x = AVR_REG(Rd);
781  z = MSB(x);
782  x = AVR_REG(Rd);
783  y = AVR_SH(1);
784  x = SHIFTR(z, x, y);
785  asr = AVR_REG_SET(Rd, x);
786 
787  // C: Rd0
788  x = AVR_REG(Rd);
789  x = LSB(x);
790  C = SETG(AVR_SREG_C, x);
791 
792  // N: Res7
794 
795  // Z: !Res
797 
798  // S: N ^ V, For signed tests.
800 
801  // V: N ^ C, For N and C after the shift
803 
804  return SEQ6(C, asr, N, Z, S, V);
805 }
806 
807 static RzILOpEffect *avr_il_bld(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
808  // Copies the T Flag in the SREG (Status Register) to bit b in register Rd
809  // all the other bits are unchanged
810  ut16 Rd = aop->param[0];
811  ut16 b = aop->param[1];
813 
814  RzILOpPure *reg, *add_bit, *remove_bit, *bit, *res;
815 
816  reg = AVR_REG(Rd);
817  bit = AVR_IMM(1u << b);
818  add_bit = LOGOR(reg, bit);
819 
820  bit = AVR_IMM(~(1u << b));
821  reg = AVR_REG(Rd);
822  remove_bit = LOGAND(reg, bit);
823 
824  res = ITE(VARG(AVR_SREG_T), add_bit, remove_bit);
825  return AVR_REG_SET(Rd, res);
826 }
827 
828 static RzILOpEffect *avr_il_brcc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
829  // branch if C = 0
830  ut16 k = aop->param[0];
831 
833  return avr_il_branch_when(aop, analysis, k, when, false);
834 }
835 
836 static RzILOpEffect *avr_il_brcs(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
837  // branch if C = 1
838  ut16 k = aop->param[0];
839 
841  return avr_il_branch_when(aop, analysis, k, when, true);
842 }
843 
844 static RzILOpEffect *avr_il_breq(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
845  // branch if Z = 1
846  ut16 k = aop->param[0];
847 
849  return avr_il_branch_when(aop, analysis, k, when, true);
850 }
851 
852 static RzILOpEffect *avr_il_brge(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
853  // branch if N ^ V = 0
854  ut16 k = aop->param[0];
855 
858  RzILOpPure *when = XOR(N, V);
859  return avr_il_branch_when(aop, analysis, k, when, false);
860 }
861 
862 static RzILOpEffect *avr_il_brhc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
863  // branch if H = 0
864  ut16 k = aop->param[0];
865 
867  return avr_il_branch_when(aop, analysis, k, when, false);
868 }
869 
870 static RzILOpEffect *avr_il_brhs(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
871  // branch if H = 1
872  ut16 k = aop->param[0];
873 
875  return avr_il_branch_when(aop, analysis, k, when, true);
876 }
877 
878 static RzILOpEffect *avr_il_brid(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
879  // branch if I = 0
880  ut16 k = aop->param[0];
881 
883  return avr_il_branch_when(aop, analysis, k, when, false);
884 }
885 
886 static RzILOpEffect *avr_il_brie(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
887  // branch if I = 1
888  ut16 k = aop->param[0];
889 
891  return avr_il_branch_when(aop, analysis, k, when, true);
892 }
893 
894 static RzILOpEffect *avr_il_brlt(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
895  // branch if N ^ V = 1
896  ut16 k = aop->param[0];
897 
900  RzILOpPure *when = XOR(N, V);
901  return avr_il_branch_when(aop, analysis, k, when, true);
902 }
903 
904 static RzILOpEffect *avr_il_brmi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
905  // branch if N = 1
906  ut16 k = aop->param[0];
907 
909  return avr_il_branch_when(aop, analysis, k, when, true);
910 }
911 
912 static RzILOpEffect *avr_il_brne(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
913  // branch if Z = 0
914  ut16 k = aop->param[0];
915 
917  return avr_il_branch_when(aop, analysis, k, when, false);
918 }
919 
920 static RzILOpEffect *avr_il_brpl(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
921  // branch if N = 0
922  ut16 k = aop->param[0];
923 
925  return avr_il_branch_when(aop, analysis, k, when, false);
926 }
927 
928 static RzILOpEffect *avr_il_brtc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
929  // branch if T = 0
930  ut16 k = aop->param[0];
931 
933  return avr_il_branch_when(aop, analysis, k, when, false);
934 }
935 
936 static RzILOpEffect *avr_il_brts(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
937  // branch if T = 1
938  ut16 k = aop->param[0];
939 
941  return avr_il_branch_when(aop, analysis, k, when, true);
942 }
943 
944 static RzILOpEffect *avr_il_brvc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
945  // branch if V = 0
946  ut16 k = aop->param[0];
947 
949  return avr_il_branch_when(aop, analysis, k, when, false);
950 }
951 
952 static RzILOpEffect *avr_il_brvs(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
953  // branch if V = 1
954  ut16 k = aop->param[0];
955 
957  return avr_il_branch_when(aop, analysis, k, when, true);
958 }
959 
960 static RzILOpEffect *avr_il_bst(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
961  // Stores bit b from Rd to the T Flag in SREG (Status Register)
962  ut16 Rd = aop->param[0];
963  ut16 b = aop->param[1];
965 
966  RzILOpPure *reg, *bit;
967 
968  reg = AVR_REG(Rd);
969  bit = AVR_IMM(1u << b);
970  bit = LOGAND(reg, bit);
971  bit = NON_ZERO(bit);
972  return SETG(AVR_SREG_T, bit);
973 }
974 
975 static RzILOpEffect *avr_il_call(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
976  // PC = k
977  ut32 k = aop->param[0];
978  k <<= 16;
979  k |= aop->param[1];
980 
981  RzILOpPure *val, *num;
982  RzILOpEffect *jmp, *push, *sub;
983 
984  jmp = avr_il_jump_relative(aop, analysis, k);
985 
986  val = VARG(AVR_SP);
987  val = AVR_ADDR(val);
988  num = AVR_PC((AVR_ADDR_SIZE / 8) - 1);
989  val = SUB(val, num);
990  num = AVR_PC(pc + aop->size);
991  push = STOREW(val, num);
992 
993  num = AVR_IMM16(AVR_ADDR_SIZE / 8);
994  val = VARG(AVR_SP);
995  val = SUB(val, num);
996  sub = SETG(AVR_SP, val);
997 
998  return SEQ3(push, sub, jmp);
999 }
1000 
1001 static RzILOpEffect *avr_il_cbi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1002  // Clears a specified bit in an I/O Register.
1003  ut16 A = aop->param[0];
1004  ut16 b = aop->param[1];
1005 
1006  RzILOpPure *clearb, *target, *result;
1007  const char *reg = resolve_mmio(analysis, A);
1008  if (!reg && A < 32) {
1009  // profiles that does not map registers between 0 and 31 have MMIO regs at this range
1010  reg = avr_registers[A];
1011  }
1012 
1013  clearb = AVR_IMM(~(1u << b));
1014  target = VARG(reg);
1015  result = LOGAND(clearb, target);
1016  return SETG(reg, result);
1017 }
1018 
1019 static RzILOpEffect *avr_il_clc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1020  // C = 0
1021  return AVR_SREG_C_SET(false);
1022 }
1023 
1024 static RzILOpEffect *avr_il_clh(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1025  // H = 0
1026  return AVR_SREG_H_SET(false);
1027 }
1028 
1029 static RzILOpEffect *avr_il_cli(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1030  // I = 0
1031  return AVR_SREG_I_SET(false);
1032 }
1033 
1034 static RzILOpEffect *avr_il_cln(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1035  // N = 0
1036  return AVR_SREG_N_SET(false);
1037 }
1038 
1039 static RzILOpEffect *avr_il_clr(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1040  // Rd = Rd ^ Rd -> S=0, V=0, N=0, Z=1
1041  ut16 Rd = aop->param[0];
1043 
1044  RzILOpEffect *clr, *S, *V, *N, *Z;
1045  clr = avr_il_assign_imm(avr_registers[Rd], 0);
1046  S = AVR_SREG_S_SET(false);
1047  V = AVR_SREG_V_SET(false);
1048  N = AVR_SREG_N_SET(false);
1049  Z = AVR_SREG_Z_SET(true);
1050 
1051  return SEQ5(clr, S, V, N, Z);
1052 }
1053 
1054 static RzILOpEffect *avr_il_cls(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1055  // S = 0
1056  return AVR_SREG_S_SET(false);
1057 }
1058 
1059 static RzILOpEffect *avr_il_clt(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1060  // T = 0
1061  return AVR_SREG_T_SET(false);
1062 }
1063 
1064 static RzILOpEffect *avr_il_clv(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1065  // V = 0
1066  return AVR_SREG_V_SET(false);
1067 }
1068 
1069 static RzILOpEffect *avr_il_clz(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1070  // Z = 0
1071  return AVR_SREG_Z_SET(false);
1072 }
1073 
1074 static RzILOpEffect *avr_il_com(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1075  // Rd = 0xFF - Rd
1076  // changes S|V|N|Z|C with V = 0 and C = 1
1077  ut16 Rd = aop->param[0];
1079 
1080  RzILOpPure *x, *y, *sub;
1081  RzILOpEffect *set, *S, *V, *N, *Z, *C;
1082 
1083  x = AVR_REG(Rd);
1084  y = AVR_IMM(0xFF);
1085  sub = SUB(y, x);
1086  set = AVR_REG_SET(Rd, sub);
1087 
1088  // C = 1
1089  C = AVR_SREG_C_SET(true);
1090 
1091  // V = 0
1092  V = AVR_SREG_V_SET(false);
1093 
1094  // set Z to 1 if !(0xFF - Rd)
1095  x = AVR_REG(Rd);
1096  x = IS_ZERO(x);
1097  Z = SETG(AVR_SREG_Z, x);
1098 
1099  // N = Res7
1100  x = AVR_REG(Rd);
1101  y = AVR_IMM(1u << 7);
1102  x = LOGAND(x, y);
1103  x = NON_ZERO(x); // cast to bool
1104  N = SETG(AVR_SREG_N, x);
1105 
1106  // S: N ^ V, For signed tests.
1108 
1109  return SEQ6(set, C, V, Z, N, S);
1110 }
1111 
1112 static RzILOpEffect *avr_il_cp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1113  // compare Rd with Rr and sets the SREG flags
1114  // changes H|S|V|N|Z|C
1115  ut16 Rd = aop->param[0];
1116  ut16 Rr = aop->param[1];
1119  RzILOpPure *x, *y;
1120  RzILOpEffect *let, *Z, *H, *S, *V, *N, *C;
1121  RzILOpBitVector *sub;
1122 
1123  // result local variable
1124  x = AVR_REG(Rd);
1125  y = AVR_REG(Rr);
1126  sub = SUB(x, y);
1127  let = SETL(AVR_LET_RES, sub);
1128 
1129  // set Z to 1 if !(x - y)
1131 
1132  // Res = Rd - Rr
1133  // H: (!Rd3 & Rr3) | (Rr3 & Res3) | (Res3 & !Rd3)
1134  // Set if there was a borrow from bit 3; cleared otherwise
1135  x = AVR_REG(Rd);
1136  y = AVR_REG(Rr);
1138 
1139  // Res = Rd - Rr
1140  // V: (Rd7 & !Rr7 & !Res7) | (!Rd7 & Rr7 & Res7)
1141  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
1142  x = AVR_REG(Rd);
1143  y = AVR_REG(Rr);
1145 
1146  // Res = Rd - Rr
1147  // N: Res7
1148  // Set if MSB of the result is set; cleared otherwise.
1150 
1151  // Res = Rd - Rr
1152  // C: (!Rd7 & Rr7) | (Rr7 & Res7) | (Res7 & !Rd7)
1153  // Set if the absolute value of Rr is larger than the absolute value of Rd; cleared otherwise
1154  x = AVR_REG(Rd);
1155  y = AVR_REG(Rr);
1157 
1158  // S: N ^ V, For signed tests.
1160 
1161  return SEQ7(let, Z, H, V, N, C, S);
1162 }
1163 
1164 static RzILOpEffect *avr_il_cpi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1165  // compare Rd with Imm and sets the SREG flags
1166  // changes H|S|V|N|Z|C
1167  ut16 Rd = aop->param[0];
1168  ut16 K = aop->param[1];
1170  RzILOpPure *x, *y;
1171  RzILOpEffect *let, *Z, *H, *S, *V, *N, *C;
1172  RzILOpBitVector *sub;
1173 
1174  // result local variable
1175  x = AVR_REG(Rd);
1176  y = AVR_IMM(K);
1177  sub = SUB(x, y);
1178  let = SETL(AVR_LET_RES, sub);
1179 
1180  // set Z to 1 if !(x - y)
1182 
1183  // H: (!Rd3 & Rr3) | (Rr3 & Res3) | (Res3 & !Rd3)
1184  // Set if there was a borrow from bit 3; cleared otherwise
1185  x = AVR_REG(Rd);
1186  y = AVR_IMM(K);
1188 
1189  // V: (Rd7 & !Rr7 & !Res7) | (!Rd7 & Rr7 & Res7)
1190  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
1191  x = AVR_REG(Rd);
1192  y = AVR_IMM(K);
1194 
1195  // N: Res7
1196  // Set if MSB of the result is set; cleared otherwise.
1198 
1199  // C: (!Rd7 & Rr7) | (Rr7 & Res7) | (Res7 & !Rd7)
1200  // Set if the absolute value of Rr is larger than the absolute value of Rd; cleared otherwise
1201  x = AVR_REG(Rd);
1202  y = AVR_IMM(K);
1204 
1205  // S: N ^ V, For signed tests.
1207 
1208  return SEQ7(let, Z, H, V, N, C, S);
1209 }
1210 
1211 static RzILOpEffect *avr_il_cpc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1212  // compare Rd with Rr with Carry and sets the SREG flags
1213  // changes H|S|V|N|Z|C
1214  ut16 Rd = aop->param[0];
1215  ut16 Rr = aop->param[1];
1218  RzILOpPure *x, *y, *carry;
1219  RzILOpEffect *let, *Z, *H, *S, *V, *N, *C;
1220  RzILOpBitVector *sub;
1221 
1222  // result local variable
1223  x = AVR_REG(Rd);
1224  y = AVR_REG(Rr);
1225  carry = VARG(AVR_SREG_C);
1226  carry = rz_il_op_new_ite(carry, AVR_ONE(), AVR_ZERO());
1227  sub = SUB(x, y);
1228  sub = SUB(sub, carry);
1229  let = SETL(AVR_LET_RES, sub);
1230 
1231  // set Z to 1 if !(x - y - C)
1233 
1234  // Res = Rd - Rr - C
1235  // H: (!Rd3 & Rr3) | (Rr3 & Res3) | (Res3 & !Rd3)
1236  // Set if there was a borrow from bit 3; cleared otherwise
1237  x = AVR_REG(Rd);
1238  y = AVR_REG(Rr);
1240 
1241  // Res = Rd - Rr - C
1242  // V: (Rd7 & !Rr7 & !Res7) | (!Rd7 & Rr7 & Res7)
1243  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
1244  x = AVR_REG(Rd);
1245  y = AVR_REG(Rr);
1247 
1248  // Res = Rd - Rr - C
1249  // N: Res7
1250  // Set if MSB of the result is set; cleared otherwise.
1252 
1253  // Res = Rd - Rr - C
1254  // C: (!Rd7 & Rr7) | (Rr7 & Res7) | (Res7 & !Rd7)
1255  // Set if the absolute value of Rr is larger than the absolute value of Rd; cleared otherwise
1256  x = AVR_REG(Rd);
1257  y = AVR_REG(Rr);
1259 
1260  // S: N ^ V, For signed tests.
1262 
1263  return SEQ7(let, Z, H, V, N, C, S);
1264 }
1265 
1266 static RzILOpEffect *avr_il_cpse(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1267  // branch if If Rd == Rr
1268  ut16 Rd = aop->param[0];
1269  ut16 Rr = aop->param[1];
1270 
1271  RzILOpBool *when = EQ(AVR_REG(Rd), AVR_REG(Rr));
1272  return avr_il_branch_when(aop, analysis, pc + next_op->size, when, true);
1273 }
1274 
1275 static RzILOpEffect *avr_il_dec(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1276  RzILOpPure *x, *y;
1277  RzILOpEffect *dec, *S, *V, *N, *Z;
1278  // Rd -= 1
1279  // changes S|V|N|Z
1280  ut16 Rd = aop->param[0];
1282 
1283  // V: Rd == 0x80
1284  x = AVR_REG(Rd);
1285  y = AVR_IMM(0x80);
1286  x = EQ(x, y);
1287  V = SETG(AVR_SREG_V, x);
1288 
1289  // Rd -= 1
1290  x = AVR_REG(Rd);
1291  y = AVR_ONE();
1292  x = SUB(x, y);
1293  dec = AVR_REG_SET(Rd, x);
1294 
1295  // N: Res7
1297 
1298  // Z: !Res
1299  x = AVR_REG(Rd);
1300  x = IS_ZERO(x);
1301  Z = SETG(AVR_SREG_Z, x);
1302 
1303  // S: N ^ V, For signed tests.
1305 
1306  return SEQ5(V, dec, N, Z, S);
1307 }
1308 
1309 static RzILOpEffect *avr_il_eicall(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1310  // *(SP--) = PC
1311  // PC = (EIND << 16) | Z
1312  RzILOpPure *x, *y;
1313  RzILOpEffect *jmp, *push, *sub;
1314 
1315  x = VARG(AVR_EIND);
1316  y = AVR_Z();
1317  x = APPEND(x, y);
1318  // extend to max PC address size
1319  x = UNSIGNED(AVR_ADDR_SIZE, x);
1320  y = AVR_PC(1);
1321  x = SHIFTL0(x, y);
1322  jmp = JMP(x);
1323 
1324  x = VARG(AVR_SP);
1325  x = AVR_ADDR(x);
1326  y = AVR_PC((AVR_ADDR_SIZE / 8) - 1);
1327  x = SUB(x, y);
1328  y = AVR_PC(pc + aop->size);
1329  push = STOREW(x, y);
1330 
1331  x = AVR_IMM16(AVR_ADDR_SIZE / 8);
1332  y = VARG(AVR_SP);
1333  y = SUB(y, x);
1334  sub = SETG(AVR_SP, y);
1335 
1336  return SEQ3(push, sub, jmp);
1337 }
1338 
1339 static RzILOpEffect *avr_il_eijmp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1340  // PC = (EIND << 16) | Z
1341  RzILOpPure *x, *y;
1342 
1343  x = VARG(AVR_EIND);
1344  y = AVR_Z();
1345  x = APPEND(x, y);
1346  // extend to max PC address size
1347  x = UNSIGNED(AVR_ADDR_SIZE, x);
1348  y = AVR_PC(1);
1349  x = SHIFTL0(x, y);
1350  return JMP(x);
1351 }
1352 
1353 static RzILOpEffect *avr_il_elpm(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1354  // Rd = *(RAMPZ:Z) # RAMPZ:Z: Unchanged
1355  // Rd = *(RAMPZ:Z++) # RAMPZ:Z: Post incremented
1356  ut16 Rd = aop->param[0];
1358  RzILOpPure *x, *y;
1359  RzILOpEffect *load, *rampz, *reg30, *reg31, *local;
1360 
1361  // RAMPZ:Z
1362  x = VARG(AVR_RAMPZ);
1363  y = AVR_Z();
1364  x = APPEND(x, y);
1365  // extend to max PC address size
1366  x = UNSIGNED(AVR_ADDR_SIZE, x);
1367 
1368  // Rd = *(RAMPZ:Z)
1369  y = LOADW(AVR_REG_SIZE, x);
1370  load = AVR_REG_SET(Rd, y);
1371 
1372  if (aop->param[2] != '+') {
1373  // do not need to post increment
1374  return load;
1375  }
1376 
1377  // RES = (RAMPZ:Z) + 1
1378  x = DUP(x);
1379  y = AVR_PC(1);
1380  x = ADD(x, y);
1381  local = SETL(AVR_LET_RES, x);
1382 
1383  // RAMPZ = (ut8)(RES >> 16)
1384  x = VARL(AVR_LET_RES);
1385  y = AVR_SH(AVR_IND_SIZE);
1386  x = SHIFTR0(x, y);
1387  x = UNSIGNED(AVR_REG_SIZE, x);
1388  rampz = SETG(AVR_RAMPZ, x);
1389 
1390  // R31 = (ut8)(RES >> 8)
1391  x = VARL(AVR_LET_RES);
1392  y = AVR_SH(AVR_REG_SIZE);
1393  x = SHIFTR0(x, y);
1394  x = UNSIGNED(AVR_REG_SIZE, x);
1395  reg31 = AVR_REG_SET(31, x);
1396 
1397  // R30 = (ut8)(RES)
1398  x = VARL(AVR_LET_RES);
1399  x = UNSIGNED(AVR_REG_SIZE, x);
1400  reg30 = AVR_REG_SET(30, x);
1401 
1402  return SEQ5(load, local, rampz, reg31, reg30);
1403 }
1404 
1405 static RzILOpEffect *avr_il_eor(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1406  RzILOpPure *x, *y;
1407  RzILOpEffect *eor, *S, *V, *N, *Z;
1408  // Rd = Rd ^ Rr
1409  // changes S|V|N|Z
1410  ut16 Rd = aop->param[0];
1411  ut16 Rr = aop->param[1];
1414 
1415  // Rd = Rd + Rr
1416  x = AVR_REG(Rd);
1417  y = AVR_REG(Rr);
1418  x = LOGXOR(x, y);
1419  eor = AVR_REG_SET(Rd, x);
1420 
1421  // V: cleared (0)
1422  V = AVR_SREG_V_SET(false);
1423 
1424  // N: Res7
1426 
1427  // Z: !Res
1428  x = AVR_REG(Rd);
1429  x = IS_ZERO(x);
1430  Z = SETG(AVR_SREG_Z, x);
1431 
1432  // S: N ^ V, For signed tests.
1434 
1435  return SEQ5(eor, V, N, Z, S);
1436 }
1437 
1438 static RzILOpEffect *avr_il_fmul(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1439  RzILOpPure *x, *y;
1440  RzILOpEffect *ind, *res, *mul, *Z, *C;
1441  // Rd and Rr are floating points that are in 1.7 format that
1442  // has values between [0, 2) and results in 1.15 format in R1:R0
1443  // bits 7 0
1444  // Rd = xxxxxxxx
1445  // |||||||`-- 2^-7 = 0.0078125
1446  // ||||||`--- 2^-6 = 0.015625
1447  // |||||`---- 2^-5 = 0.03125
1448  // ||||`----- 2^-4 = 0.0625
1449  // |||`------ 2^-3 = 0.125
1450  // ||`------- 2^-2 = 0.25
1451  // |`-------- 2^-1 = 0.5
1452  // `--------- 2^0 = 1
1453  // 01001100 = 0.5 + 0.0625 + 0.03125 = 0.59375
1454  // R1:R0 = ((unsigned)Rd * (unsigned)Rr)
1455  // changes Z|C
1456  ut16 Rd = aop->param[0];
1457  ut16 Rr = aop->param[1];
1460 
1461  // IND = Rd * Rr
1462  x = AVR_REG(Rd);
1463  x = UNSIGNED(AVR_IND_SIZE, x);
1464  y = AVR_REG(Rr);
1465  y = UNSIGNED(AVR_IND_SIZE, y);
1466  x = MUL(x, y);
1467  ind = SETL(AVR_LET_IND, x);
1468 
1469  // RES = ((IND > 0x7FFF) ? (IND - 0x8000) : IND) << 1
1470  x = VARL(AVR_LET_IND);
1471  x = avr_subtract_if(16, 0x7FFF, x, 0x8000, false);
1472  y = AVR_ONE();
1473  x = SHIFTL0(x, y);
1474  res = SETL(AVR_LET_RES, x);
1475 
1476  // R1:R0 = RES
1478 
1479  // set Z to 1 if !(RES)
1480  x = VARL(AVR_LET_RES);
1481  x = IS_ZERO(x);
1482  Z = SETG(AVR_SREG_Z, x);
1483 
1484  // C = Res16
1485  x = VARL(AVR_LET_RES);
1486  x = MSB(x); // most significant bit
1487  C = SETG(AVR_SREG_C, x);
1488 
1489  return SEQ5(ind, res, mul, Z, C);
1490 }
1491 
1492 static RzILOpEffect *avr_il_fmuls(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1493  RzILOpPure *x, *y, *z;
1494  RzILOpEffect *ind, *res, *high, *low, *Z, *C;
1495  // Rd and Rr are floating points that are in 1.7 format
1496  // R1:R0 = ((signed)Rd * (signed)Rr)
1497  // changes Z|C
1498  ut16 Rd = aop->param[0];
1499  ut16 Rr = aop->param[1];
1502 
1503  // IND = (Rd > 0x7F ? 0 - Rd : Rd) * (Rr > 0x7F ? 0 - Rr : Rr)
1504  x = AVR_REG(Rd);
1505  x = avr_subtract_if(AVR_REG_SIZE, 0x7F, x, 0, true);
1506  x = UNSIGNED(AVR_IND_SIZE, x);
1507 
1508  y = AVR_REG(Rr);
1509  y = avr_subtract_if(AVR_REG_SIZE, 0x7F, y, 0, true);
1510  y = UNSIGNED(AVR_IND_SIZE, y);
1511 
1512  x = MUL(x, y);
1513  ind = SETL(AVR_LET_IND, x);
1514 
1515  // checking if one of the original values are negative
1516  x = AVR_REG(Rd);
1517  x = MSB(x);
1518  y = AVR_REG(Rr);
1519  y = MSB(y);
1520  z = XOR(x, y);
1521 
1522  // RES = ((IND > 0x3FFF) ? (IND - 0x4000) : IND) << 1
1523  x = VARL(AVR_LET_IND);
1524  x = avr_subtract_if(16, 0x3FFF, x, 0x4000, false);
1525  y = AVR_ONE();
1526  x = SHIFTL0(x, y);
1527  res = SETL(AVR_LET_RES, x);
1528 
1529  // R1 = (ut8)((z ? (0 - RES) : RES) >> 8)
1530  x = AVR_IMM16(0);
1531  y = VARL(AVR_LET_RES);
1532  x = SUB(x, y);
1533  y = VARL(AVR_LET_RES);
1534  x = ITE(z, x, y);
1535  y = AVR_SH(AVR_REG_SIZE);
1536  x = SHIFTR0(x, y);
1537  x = UNSIGNED(AVR_REG_SIZE, x);
1538  high = SETG("r1", x);
1539 
1540  // R0 = (ut8)(z ? (0 - RES) : RES)
1541  x = AVR_IMM16(0);
1542  y = VARL(AVR_LET_RES);
1543  x = SUB(x, y);
1544  y = VARL(AVR_LET_RES);
1545  z = DUP(z);
1546  x = ITE(z, x, y);
1547  x = UNSIGNED(AVR_REG_SIZE, x);
1548  low = SETG("r0", x);
1549 
1550  // set Z to 1 if !(r0:r1)
1551  x = VARG("r0");
1552  x = IS_ZERO(x);
1553  y = VARG("r1");
1554  y = IS_ZERO(y);
1555  x = AND(x, y);
1556  Z = SETG(AVR_SREG_Z, x);
1557 
1558  // C = Res16 = r1
1559  x = VARG("r1");
1560  x = MSB(x); // most significant bit
1561  C = SETG(AVR_SREG_C, x);
1562 
1563  return SEQ6(ind, res, high, low, Z, C);
1564 }
1565 
1566 static RzILOpEffect *avr_il_fmulsu(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1567  RzILOpPure *x, *y, *z;
1568  RzILOpEffect *ind, *res, *high, *low, *Z, *C;
1569  // Rd and Rr are floating points that are in 1.7 format
1570  // R1:R0 = ((signed)Rd * (unsigned)Rr)
1571  // changes Z|C
1572  ut16 Rd = aop->param[0];
1573  ut16 Rr = aop->param[1];
1576 
1577  // IND = (Rd > 0x7F ? Rd - 0x80 : Rd) * Rr
1578  x = AVR_REG(Rd);
1579  x = UNSIGNED(AVR_IND_SIZE, x);
1580  x = avr_subtract_if(AVR_IND_SIZE, 0x7F, x, 0x80, false);
1581  y = AVR_REG(Rr);
1582  y = UNSIGNED(AVR_IND_SIZE, y);
1583  x = MUL(x, y);
1584  ind = SETL(AVR_LET_IND, x);
1585 
1586  // checking if Rd is negative
1587  x = AVR_REG(Rd);
1588  z = MSB(x);
1589 
1590  // RES = ((IND > 0x3FFF) ? (IND - 0x4000) : IND) << 1
1591  x = VARL(AVR_LET_IND);
1592  x = avr_subtract_if(16, 0x3FFF, x, 0x4000, false);
1593  y = AVR_ONE();
1594  x = SHIFTL0(x, y);
1595  res = SETL(AVR_LET_RES, x);
1596 
1597  // R1 = (ut8)((z ? (0 - RES) : RES) >> 8)
1598  x = AVR_IMM16(0);
1599  y = VARL(AVR_LET_RES);
1600  x = SUB(x, y);
1601  y = VARL(AVR_LET_RES);
1602  x = ITE(z, x, y);
1603  y = AVR_SH(AVR_REG_SIZE);
1604  x = SHIFTR0(x, y);
1605  x = UNSIGNED(AVR_REG_SIZE, x);
1606  high = SETG("r1", x);
1607 
1608  // R0 = (ut8)(z ? (0 - RES) : RES)
1609  x = AVR_IMM16(0);
1610  y = VARL(AVR_LET_RES);
1611  x = SUB(x, y);
1612  y = VARL(AVR_LET_RES);
1613  z = DUP(z);
1614  x = ITE(z, x, y);
1615  x = UNSIGNED(AVR_REG_SIZE, x);
1616  low = SETG("r0", x);
1617 
1618  // set Z to 1 if !(r0:r1)
1619  x = VARG("r0");
1620  x = IS_ZERO(x);
1621  y = VARG("r1");
1622  y = IS_ZERO(y);
1623  x = AND(x, y);
1624  Z = SETG(AVR_SREG_Z, x);
1625 
1626  // C = Res16 = r1
1627  x = VARG("r1");
1628  x = MSB(x); // most significant bit
1629  C = SETG(AVR_SREG_C, x);
1630 
1631  return SEQ6(ind, res, high, low, Z, C);
1632 }
1633 
1634 static RzILOpEffect *avr_il_icall(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1635  // *(SP--) = PC
1636  // PC = Z << 1
1637  RzILOpPure *x, *y;
1638  RzILOpEffect *jmp, *push, *sub;
1639 
1640  x = AVR_Z();
1641  x = UNSIGNED(AVR_ADDR_SIZE, x);
1642  y = AVR_SH(1);
1643  x = SHIFTL0(x, y);
1644  jmp = JMP(x);
1645 
1646  x = VARG(AVR_SP);
1647  x = AVR_ADDR(x);
1648  y = AVR_PC((AVR_ADDR_SIZE / 8) - 1);
1649  x = SUB(x, y);
1650  y = AVR_PC(pc + aop->size);
1651  push = STOREW(x, y);
1652 
1653  x = AVR_IMM16(AVR_ADDR_SIZE / 8);
1654  y = VARG(AVR_SP);
1655  y = SUB(y, x);
1656  sub = SETG(AVR_SP, y);
1657 
1658  return SEQ3(push, sub, jmp);
1659 }
1660 
1661 static RzILOpEffect *avr_il_ijmp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1662  RzILOpPure *loc, *one;
1663  // PC = Z << 1
1664  loc = AVR_Z();
1665  loc = UNSIGNED(AVR_ADDR_SIZE, loc);
1666  one = AVR_SH(1);
1667  loc = SHIFTL0(loc, one);
1668  return JMP(loc);
1669 }
1670 
1671 static RzILOpEffect *avr_il_in(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1672  // Rd = I/O(A)
1673  ut16 Rd = aop->param[0];
1674  ut16 A = aop->param[1];
1676 
1677  const char *reg = resolve_mmio(analysis, A);
1678  if (!reg && A < 32) {
1679  // profiles that does not map registers between 0 and 31 have MMIO regs at this range
1681  } else if (!reg) {
1682  // memory read
1684  } else if (!rz_str_ncasecmp(reg, AVR_SPL, strlen(AVR_SPL))) {
1685  // zeros low 8 bits and OR new value
1686  RzILOpPure *x = VARG(AVR_SP);
1687  x = UNSIGNED(AVR_REG_SIZE, x);
1688  return AVR_REG_SET(Rd, x);
1689  } else if (!rz_str_ncasecmp(reg, AVR_SPH, strlen(AVR_SPH))) {
1690  // zeros high 8 bits and OR new value
1691  RzILOpPure *x = VARG(AVR_SP);
1693  x = SHIFTR0(x, y);
1694  x = UNSIGNED(AVR_REG_SIZE, x);
1695  return AVR_REG_SET(Rd, x);
1696  } else if (!rz_str_ncasecmp(reg, AVR_SREG, strlen(AVR_SREG))) {
1697  // this could be optimized to just be Rd = SREG
1698  RzILOpBitVector *x, *I, *T, *H, *S, *V, *N, *Z, *C;
1707  x = LOGOR(I, T);
1708  x = LOGOR(x, H);
1709  x = LOGOR(x, S);
1710  x = LOGOR(x, V);
1711  x = LOGOR(x, N);
1712  x = LOGOR(x, Z);
1713  x = LOGOR(x, C);
1714  return AVR_REG_SET(Rd, x);
1715  }
1716  // assign the register value.
1717  return avr_il_assign_reg(avr_registers[Rd], reg);
1718 }
1719 
1720 static RzILOpEffect *avr_il_inc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1721  RzILOpPure *x, *y;
1722  RzILOpEffect *inc, *S, *V, *N, *Z;
1723  // Rd += 1
1724  // changes S|V|N|Z
1725  ut16 Rd = aop->param[0];
1727 
1728  // V: Rd == 0x7F
1729  x = AVR_REG(Rd);
1730  y = AVR_IMM(0x7F);
1731  x = EQ(x, y);
1732  V = SETG(AVR_SREG_V, x);
1733 
1734  // Rd += 1
1735  x = AVR_REG(Rd);
1736  y = AVR_ONE();
1737  x = ADD(x, y);
1738  inc = AVR_REG_SET(Rd, x);
1739 
1740  // N: Res7
1742 
1743  // Z: !Res
1744  x = AVR_REG(Rd);
1745  x = IS_ZERO(x);
1746  Z = SETG(AVR_SREG_Z, x);
1747 
1748  // S: N ^ V, For signed tests.
1750 
1751  return SEQ5(V, inc, N, Z, S);
1752 }
1753 
1754 static RzILOpEffect *avr_il_jmp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1755  // PC = PC + k + 1
1756  st32 k = aop->param[0];
1757  k <<= 16;
1758  k |= aop->param[1];
1759 
1760  return avr_il_jump_relative(aop, analysis, k);
1761 }
1762 
1763 static RzILOpEffect *avr_il_lac(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1764  // it's swap like op but clears the bits
1765  // *(Z) = 0xFF – Rd and Rd = *(Z)
1766  st32 Rd = aop->param[0];
1768  RzILOpPure *x, *y;
1769  RzILOpEffect *local, *load, *store;
1770 
1771  // RES = 0xFF – Rd
1772  x = AVR_IMM(0xFF);
1773  y = AVR_REG(Rd);
1774  x = SUB(x, y);
1775  local = SETL(AVR_LET_RES, x);
1776 
1777  // Rd = *(Z)
1778  x = AVR_Z();
1779  x = UNSIGNED(AVR_ADDR_SIZE, x);
1780  x = LOADW(AVR_REG_SIZE, x);
1781  load = AVR_REG_SET(Rd, x);
1782 
1783  // *(Z) = RES
1784  x = AVR_Z();
1785  x = UNSIGNED(AVR_ADDR_SIZE, x);
1786  y = VARL(AVR_LET_RES);
1787  store = STOREW(x, y);
1788 
1789  return SEQ3(local, load, store);
1790 }
1791 
1792 static RzILOpEffect *avr_il_las(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1793  // it's swap like op
1794  // *(Z) = Rd and Rd = *(Z)
1795  st32 Rd = aop->param[0];
1797  RzILOpPure *x, *y;
1798  RzILOpEffect *local, *load, *store;
1799 
1800  // RES = 0xFF – Rd
1801  x = AVR_REG(Rd);
1802  local = SETL(AVR_LET_RES, x);
1803 
1804  // Rd = *(Z)
1805  x = AVR_Z();
1806  x = UNSIGNED(AVR_ADDR_SIZE, x);
1807  x = LOADW(AVR_REG_SIZE, x);
1808  load = AVR_REG_SET(Rd, x);
1809 
1810  // *(Z) = RES
1811  x = AVR_Z();
1812  x = UNSIGNED(AVR_ADDR_SIZE, x);
1813  y = VARL(AVR_LET_RES);
1814  store = STOREW(x, y);
1815 
1816  return SEQ3(local, load, store);
1817 }
1818 
1819 static RzILOpEffect *avr_il_lat(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1820  // it's swap like op but xor the memory value
1821  // *(Z) ^= Rd and Rd = *(Z)
1822  st32 Rd = aop->param[0];
1824  RzILOpPure *x, *y;
1825  RzILOpEffect *local, *load, *store;
1826 
1827  // RES = *(Z)
1828  x = AVR_Z();
1829  x = UNSIGNED(AVR_ADDR_SIZE, x);
1830  x = LOADW(AVR_REG_SIZE, x);
1831  local = SETL(AVR_LET_RES, x);
1832 
1833  // *(Z) = RES ^ Rd
1834  x = VARL(AVR_LET_RES);
1835  y = AVR_REG(Rd);
1836  y = LOGXOR(x, y);
1837  x = AVR_Z();
1838  x = UNSIGNED(AVR_ADDR_SIZE, x);
1839  store = STOREW(x, y);
1840 
1841  // Rd = RES
1842  x = VARL(AVR_LET_RES);
1843  load = AVR_REG_SET(Rd, x);
1844 
1845  return SEQ3(local, store, load);
1846 }
1847 
1848 static RzILOpEffect *avr_il_ld(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1849  RzILOpPure *src;
1850  RzILOpEffect *ld, *post_op, *let;
1851  // Rd = *((ut8*)X) where X = (r27 << 8) | r26;
1852  // Rd = *((ut8*)Y) where Y = (r29 << 8) | r28;
1853  // Rd = *((ut8*)Z) where Z = (r31 << 8) | r30;
1854  // When Z+ , Z is incremented by 1 after the execution (applies also to X and Y).
1855  // When -X , X is decremented by 1 after the execution (applies also to Z and Y).
1856  // When Y+q, Y is incremented by q after the execution (applies also to X and Z).
1857 
1858  // undefined behaviour per ISA below
1859  // ld r26, X+
1860  // ld r27, X+
1861  // ld r26, -X
1862  // ld r27, -X
1863 
1864  ut16 Rd = aop->param[0];
1865  char Rr = (char)aop->param[1]; // 'X' or 'Y' or 'Z'
1866  char Op = (char)aop->param[2]; // 0 or '+' or '-'
1867  ut16 q = aop->param[3];
1868 
1871 
1872  switch (Rr) {
1873  case 'X':
1874  src = AVR_X();
1875  break;
1876  case 'Y':
1877  src = AVR_Y();
1878  break;
1879  default: // 'Z'
1880  src = AVR_Z();
1881  break;
1882  }
1883 
1884  src = AVR_ADDR(src);
1885  src = LOADW(AVR_REG_SIZE, src);
1886  ld = AVR_REG_SET(Rd, src);
1887 
1888  if (Op != '+' && Op != '-') {
1889  return ld;
1890  }
1891 
1892  switch (Rr) {
1893  case 'X':
1894  src = AVR_X();
1895  post_op = AVR_SET_X(AVR_LET_IND, q, Op == '+');
1896  break;
1897  case 'Y':
1898  src = AVR_Y();
1899  post_op = AVR_SET_Y(AVR_LET_IND, q, Op == '+');
1900  break;
1901  default: // 'Z'
1902  src = AVR_Z();
1903  post_op = AVR_SET_Z(AVR_LET_IND, q, Op == '+');
1904  break;
1905  }
1906 
1907  let = SETL(AVR_LET_IND, src);
1908  return SEQ3(ld, let, post_op);
1909 }
1910 
1911 static RzILOpEffect *avr_il_ldi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1912  // Rd = K
1913  ut16 Rd = aop->param[0];
1914  ut16 K = aop->param[1];
1916 
1917  return avr_il_assign_imm(avr_registers[Rd], K);
1918 }
1919 
1920 static RzILOpEffect *avr_il_lds(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1921  // Rd = *(k)
1922  ut16 Rd = aop->param[0];
1923  ut16 k = aop->param[1];
1925 
1927 }
1928 
1929 static RzILOpEffect *avr_il_lpm(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1930  // R0 = *((ut8*)Z) where Z = (r31 << 8) | r30;
1931  // when Z+, Z is incremented after the execution.
1932  // LPM r30, Z+ and LPM r31, Z+ have an undefined behaviour per ISA
1933  // Z is always implied with lpm so we need to check only for post increment
1934 
1935  ut16 Rd = aop->param[0];
1936  bool post_inc = aop->param[2] == '+';
1938 
1939  RzILOpBitVector *z, *load;
1940  RzILOpEffect *lpm, *let, *zpp;
1941 
1942  z = AVR_Z();
1943  z = AVR_ADDR(z);
1945  lpm = AVR_REG_SET(Rd, load);
1946 
1947  if (!post_inc) {
1948  return lpm;
1949  }
1950  z = AVR_Z();
1951  let = SETL(AVR_LET_IND, z);
1952  zpp = AVR_SET_Z(AVR_LET_IND, 1, true); // Z++
1953  return SEQ3(lpm, let, zpp);
1954 }
1955 
1956 static RzILOpEffect *avr_il_lsl(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1957  RzILOpPure *x, *y;
1958  RzILOpEffect *lsl, *H, *S, *V, *N, *Z, *C;
1959  // Rd <<= 1
1960  ut16 Rd = aop->param[0];
1962 
1963  // simplified by adding itself
1964  x = AVR_REG(Rd);
1965  y = AVR_REG(Rd);
1966  x = ADD(x, y);
1967  lsl = AVR_REG_SET(Rd, x);
1968 
1969  // H: Rd3
1970  x = AVR_REG(Rd);
1971  y = AVR_IMM(1u << 3);
1972  x = LOGAND(x, y);
1973  x = NON_ZERO(x); // cast to bool
1974  H = SETG(AVR_SREG_H, x);
1975 
1976  // C: Rd7
1977  x = AVR_REG(Rd);
1978  x = MSB(x);
1979  C = SETG(AVR_SREG_C, x);
1980 
1981  // N: Res7
1983 
1984  // Z: !Res
1985  x = AVR_REG(Rd);
1986  x = IS_ZERO(x);
1987  Z = SETG(AVR_SREG_Z, x);
1988 
1989  // S: N ^ V, For signed tests.
1991 
1992  // V: N ^ C, For N and C after the shift
1994 
1995  return SEQ7(H, C, lsl, N, Z, S, V);
1996 }
1997 
1998 static RzILOpEffect *avr_il_lsr(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
1999  RzILOpPure *x, *y;
2000  RzILOpEffect *lsr, *S, *V, *N, *Z, *C;
2001  // Rd >>= 1
2002  ut16 Rd = aop->param[0];
2004 
2005  x = AVR_REG(Rd);
2006  y = AVR_SH(1);
2007  x = SHIFTR0(x, y);
2008  lsr = AVR_REG_SET(Rd, x);
2009 
2010  // C: Rd0
2011  x = AVR_REG(Rd);
2012  x = LSB(x);
2013  C = SETG(AVR_SREG_C, x);
2014 
2015  // perform shift since we need the result for the SREG flags.
2016  // N: 0
2017  N = AVR_SREG_N_SET(false);
2018 
2019  // Z: !Res
2020  x = AVR_REG(Rd);
2021  x = IS_ZERO(x);
2022  Z = SETG(AVR_SREG_Z, x);
2023 
2024  // S: N ^ V, For signed tests.
2026 
2027  // V: N ^ C, For N and C after the shift
2029 
2030  return SEQ6(C, N, lsr, Z, S, V);
2031 }
2032 
2033 static RzILOpEffect *avr_il_mov(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2034  // Rd = Rr
2035  ut16 Rd = aop->param[0];
2036  ut16 Rr = aop->param[1];
2039 
2041 }
2042 
2043 static RzILOpEffect *avr_il_movw(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2044  RzILOpPure *x;
2045 
2046  RzILOpEffect *let, *movw;
2047  // Rd+1:Rd = Rr+1:Rr
2048  ut16 Rd = aop->param[0];
2049  ut16 Rr = aop->param[1];
2052 
2053  x = avr_il_get_indirect_address_reg(Rr + 1, Rr);
2054  let = SETL(AVR_LET_IND, x);
2055 
2056  movw = avr_il_update_indirect_address_reg(AVR_LET_IND, Rd + 1, Rd, 0, false);
2057  return SEQ2(let, movw);
2058 }
2059 
2060 static RzILOpEffect *avr_il_mul(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2061  RzILOpPure *x, *y;
2062  RzILOpEffect *let, *mul, *Z, *C;
2063  // R1:R0 = (signed)Rd * (signed)Rr
2064  // changes Z|C
2065  ut16 Rd = aop->param[0];
2066  ut16 Rr = aop->param[1];
2069 
2070  // RES = (signed)Rd * (signed)Rr
2071  x = AVR_REG(Rd);
2072  x = UNSIGNED(AVR_IND_SIZE, x); // (unsigned)Rd
2073  y = AVR_REG(Rr);
2074  y = UNSIGNED(AVR_IND_SIZE, y); // (unsigned)Rr
2075  x = MUL(x, y);
2076  let = SETL(AVR_LET_RES, x);
2077 
2078  // R1:R0 = RES
2080 
2081  // set Z to 1 if !(RES)
2082  x = VARL(AVR_LET_RES);
2083  x = IS_ZERO(x);
2084  Z = SETG(AVR_SREG_Z, x);
2085 
2086  // C = Res16
2087  x = VARL(AVR_LET_RES);
2088  x = MSB(x); // most significant bit
2089  C = SETG(AVR_SREG_C, x);
2090 
2091  return SEQ4(let, mul, Z, C);
2092 }
2093 
2094 static RzILOpEffect *avr_il_muls(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2095  RzILOpPure *x, *y;
2096  RzILOpEffect *let, *mul, *Z, *C;
2097  // R1:R0 = (signed)Rd * (signed)Rr
2098  // changes Z|C
2099  ut16 Rd = aop->param[0];
2100  ut16 Rr = aop->param[1];
2103 
2104  // RES = (signed)Rd * (signed)Rr
2105  x = AVR_REG(Rd);
2106  x = SIGNED(AVR_IND_SIZE, x); // (signed)Rd
2107  y = AVR_REG(Rr);
2108  y = SIGNED(AVR_IND_SIZE, y); // (signed)Rr
2109  x = MUL(x, y);
2110  let = SETL(AVR_LET_RES, x);
2111 
2112  // R1:R0 = RES
2114 
2115  // set Z to 1 if !(RES)
2116  x = VARL(AVR_LET_RES);
2117  x = IS_ZERO(x);
2118  Z = SETG(AVR_SREG_Z, x);
2119 
2120  // C = Res16
2121  x = VARL(AVR_LET_RES);
2122  x = MSB(x); // most significant bit
2123  C = SETG(AVR_SREG_C, x);
2124 
2125  return SEQ4(let, mul, Z, C);
2126 }
2127 
2128 static RzILOpEffect *avr_il_mulsu(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2129  RzILOpPure *x, *y;
2130  RzILOpEffect *let, *mul, *Z, *C;
2131  // R1:R0 = (signed)Rd * (unsigned)Rr
2132  // changes Z|C
2133  ut16 Rd = aop->param[0];
2134  ut16 Rr = aop->param[1];
2137 
2138  // RES = (signed)Rd * (unsigned)Rr
2139  x = AVR_REG(Rd);
2140  x = SIGNED(AVR_IND_SIZE, x); // (signed)Rd
2141  y = AVR_REG(Rr);
2142  y = UNSIGNED(AVR_IND_SIZE, y); // (unsigned)Rr
2143  x = MUL(x, y);
2144  let = SETL(AVR_LET_RES, x);
2145 
2146  // R1:R0 = RES
2148 
2149  // set Z to 1 if !(RES)
2150  x = VARL(AVR_LET_RES);
2151  x = IS_ZERO(x);
2152  Z = SETG(AVR_SREG_Z, x);
2153 
2154  // C = Res16
2155  x = VARL(AVR_LET_RES);
2156  x = MSB(x); // most significant bit
2157  C = SETG(AVR_SREG_C, x);
2158 
2159  return SEQ4(let, mul, Z, C);
2160 }
2161 
2162 static RzILOpEffect *avr_il_neg(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2163  RzILOpPure *x, *y, *cmp;
2164  RzILOpEffect *let, *neg, *H, *S, *V, *N, *Z, *C;
2165  // Rd = 0x00 - Rd (when Rd == 0x80 it stays 0x80)
2166  // changes H|S|V|N|Z|C
2167  ut16 Rd = aop->param[0];
2169 
2170  // IND = Rd
2171  let = SETL(AVR_LET_IND, AVR_REG(Rd));
2172 
2173  // Rd = (Rd == 0x80) ? Rd : (0x00 - Rd)
2174  x = AVR_REG(Rd);
2175  y = AVR_IMM(0x80);
2176  cmp = EQ(x, y); // Rd == 0x80
2177 
2178  x = AVR_ZERO();
2179  y = AVR_REG(Rd);
2180  x = SUB(x, y); // 0x00 - Rd
2181 
2182  y = AVR_REG(Rd); // Rd
2183  x = ITE(cmp, y, x); // (Rd == 0x80) ? Rd : (0x00 - Rd)
2184  neg = AVR_REG_SET(Rd, x); // Rd = (Rd == 0x80) ? Rd : (0x00 - Rd)
2185 
2186  // H: Res3 | Rd3
2187  x = AVR_REG(Rd); // Rd is now Res
2188  y = VARL(AVR_LET_IND); // IND is the old Rd
2189  x = LOGOR(x, y); // Rd | IND
2190  y = AVR_IMM(1u << 3);
2191  x = LOGAND(x, y); // extract bit 3
2192  x = NON_ZERO(x); // cast to bool
2193  H = SETG(AVR_SREG_H, x);
2194 
2195  // V: Res == 0x80 (after operation)
2196  x = AVR_REG(Rd); // Rd is now Res
2197  y = AVR_IMM(0x80);
2198  x = EQ(x, y); // Rd == 0x80
2199  V = SETG(AVR_SREG_V, x);
2200 
2201  // N: Res7
2203 
2204  // C: Res != 0x00
2205  x = AVR_REG(Rd); // Rd is now Res
2206  x = NON_ZERO(x); // Rd != 0x00
2207  C = SETG(AVR_SREG_C, x);
2208 
2209  // Z: Res == 0x00
2210  x = AVR_REG(Rd); // Rd is now Res
2211  x = IS_ZERO(x); // Rd == 0x00
2212  Z = SETG(AVR_SREG_Z, x);
2213 
2214  // S: N ^ V
2216 
2217  return SEQ8(let, neg, H, V, N, C, Z, S);
2218 }
2219 
2220 static RzILOpEffect *avr_il_or(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2221  RzILOpPure *x, *y;
2222  RzILOpEffect * or, *S, *V, *N, *Z;
2223  // Rd = Rd | Rr
2224  // changes S|V|N|Z
2225  ut16 Rd = aop->param[0];
2226  ut16 Rr = aop->param[1];
2229 
2230  // Rd |= Rr
2231  x = AVR_REG(Rd);
2232  y = AVR_REG(Rr);
2233  x = LOGOR(x, y);
2234  or = AVR_REG_SET(Rd, x);
2235 
2236  // V: 0
2237  V = AVR_SREG_V_SET(false);
2238 
2239  // N: Res7
2241 
2242  // Z: Res == 0x00
2243  x = AVR_REG(Rd); // Rd is now Res
2244  x = IS_ZERO(x); // Rd == 0x00
2245  Z = SETG(AVR_SREG_Z, x);
2246 
2247  // S: N ^ V
2249 
2250  return SEQ5(or, V, N, Z, S);
2251 }
2252 
2253 static RzILOpEffect *avr_il_ori(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2254  RzILOpPure *x, *y;
2255  RzILOpEffect * or, *S, *V, *N, *Z;
2256  // Rd = Rd | K
2257  // changes S|V|N|Z
2258  ut16 Rd = aop->param[0];
2259  ut16 K = aop->param[1];
2261 
2262  // Rd |= K
2263  x = AVR_REG(Rd);
2264  y = AVR_IMM(K);
2265  x = LOGOR(x, y);
2266  or = AVR_REG_SET(Rd, x);
2267 
2268  // V: 0
2269  V = AVR_SREG_V_SET(false);
2270 
2271  // N: Res7
2273 
2274  // Z: Res == 0x00
2275  x = AVR_REG(Rd); // Rd is now Res
2276  x = IS_ZERO(x); // Rd == 0x00
2277  Z = SETG(AVR_SREG_Z, x);
2278 
2279  // S: N ^ V
2281 
2282  return SEQ5(or, V, N, Z, S);
2283 }
2284 
2285 static RzILOpEffect *avr_il_out(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2286  // I/O(A) = Rr -> None
2287  ut16 A = aop->param[0];
2288  ut16 Rr = aop->param[1];
2290 
2291  const char *reg = resolve_mmio(analysis, A);
2292  if (!reg && A < 32) {
2293  // profiles that does not map registers between 0 and 31 have MMIO regs at this range
2295  } else if (!reg) {
2296  // memory write
2297  return avr_il_store_reg(A, avr_registers[Rr]);
2298  } else if (!rz_str_ncasecmp(reg, AVR_SPL, strlen(AVR_SPL))) {
2299  // zeros low 8 bits and OR new value
2300  return avr_il_set16_from_reg(AVR_SP, avr_registers[Rr], 0xFF00, 0);
2301  } else if (!rz_str_ncasecmp(reg, AVR_SPH, strlen(AVR_SPH))) {
2302  // zeros high 8 bits and OR new value
2303  return avr_il_set16_from_reg(AVR_SP, avr_registers[Rr], 0x00FF, 8);
2304  } else if (!rz_str_ncasecmp(reg, AVR_SREG, strlen(AVR_SREG))) {
2314  return SEQ9(I, T, H, S, V, N, Z, C, SREG);
2315  }
2316  // assign the register value.
2317  return avr_il_assign_reg(reg, avr_registers[Rr]);
2318 }
2319 
2320 static RzILOpEffect *avr_il_pop(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2321  // SP++
2322  // Rd = *(SP)
2323  st32 Rd = aop->param[0];
2325  RzILOpPure *x, *y;
2326  RzILOpEffect *pop, *inc;
2327 
2328  // SP++
2329  x = VARG(AVR_SP);
2330  y = AVR_IMM16(1);
2331  x = ADD(x, y);
2332  inc = SETG(AVR_SP, x);
2333 
2334  // Rd = *(SP)
2335  y = VARG(AVR_SP);
2336  y = UNSIGNED(AVR_ADDR_SIZE, y);
2337  x = LOADW(AVR_REG_SIZE, y);
2338  pop = AVR_REG_SET(Rd, x);
2339 
2340  return SEQ2(inc, pop);
2341 }
2342 
2343 static RzILOpEffect *avr_il_push(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2344  // *(SP) = Rd
2345  // SP--
2346  st32 Rd = aop->param[0];
2348  RzILOpPure *x, *y;
2349  RzILOpEffect *push, *dec;
2350 
2351  // *(SP) = Rd
2352  y = VARG(AVR_SP);
2353  y = UNSIGNED(AVR_ADDR_SIZE, y);
2354  x = AVR_REG(Rd);
2355  push = STOREW(y, x);
2356 
2357  // SP--
2358  x = VARG(AVR_SP);
2359  y = AVR_IMM16(1);
2360  x = SUB(x, y);
2361  dec = SETG(AVR_SP, x);
2362 
2363  return SEQ2(push, dec);
2364 }
2365 
2366 static RzILOpEffect *avr_il_rcall(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2367  // PC = PC + k + 1
2368  st32 k = (st16)aop->param[0];
2369 
2370  RzILOpPure *val, *num;
2371  RzILOpEffect *jmp, *push, *sub;
2372 
2373  jmp = avr_il_jump_relative(aop, analysis, k);
2374 
2375  val = VARG(AVR_SP);
2376  val = AVR_ADDR(val);
2377  num = AVR_PC((AVR_ADDR_SIZE / 8) - 1);
2378  val = SUB(val, num);
2379  num = AVR_PC(pc + aop->size);
2380  push = STOREW(val, num);
2381 
2382  num = AVR_IMM16(AVR_ADDR_SIZE / 8);
2383  val = VARG(AVR_SP);
2384  val = SUB(val, num);
2385  sub = SETG(AVR_SP, val);
2386 
2387  return SEQ3(push, sub, jmp);
2388 }
2389 
2390 static RzILOpEffect *avr_il_ret(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2391  // SP += PC_SIZE
2392  // PC = *(SP - PC_SIZE + 1)
2393  RzILOpPure *x, *y;
2394  RzILOpEffect *jmp, *inc;
2395 
2396  // PC = *(SP - PC_SIZE + 1)
2397  y = VARG(AVR_SP);
2398  y = UNSIGNED(AVR_ADDR_SIZE, y);
2399  x = AVR_PC((AVR_ADDR_SIZE / 8) - 1);
2400  y = SUB(y, x);
2401  x = LOADW(AVR_ADDR_SIZE, y);
2402  jmp = JMP(x);
2403 
2404  // SP += PC_SIZE
2405  x = VARG(AVR_SP);
2406  y = AVR_IMM16(AVR_ADDR_SIZE / 8);
2407  x = ADD(x, y);
2408  inc = SETG(AVR_SP, x);
2409 
2410  return SEQ2(inc, jmp);
2411 }
2412 
2413 static RzILOpEffect *avr_il_rjmp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2414  // PC = PC + k + 1
2415  st32 k = (st16)aop->param[0];
2416 
2417  return avr_il_jump_relative(aop, analysis, k);
2418 }
2419 
2420 static RzILOpEffect *avr_il_rol(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2421  RzILOpPure *x, *y, *carry;
2422  RzILOpEffect *let, *rol, *H, *S, *V, *N, *Z, *C;
2423  // Rd = rot_left(Rd, 1)
2424  ut16 Rd = aop->param[0];
2426 
2427  // copy C into RES
2428  carry = VARG(AVR_SREG_C);
2429  let = SETL(AVR_LET_RES, carry);
2430 
2431  x = AVR_REG(Rd);
2432  y = AVR_SH(1);
2433  // Use carry as bit filler
2434  carry = VARL(AVR_LET_RES);
2435  x = SHIFTL(carry, x, y);
2436  rol = AVR_REG_SET(Rd, x);
2437 
2438  // H: Rd3
2439  x = AVR_REG(Rd);
2440  y = AVR_IMM(1u << 3);
2441  x = LOGAND(x, y);
2442  x = NON_ZERO(x); // cast to bool
2443  H = SETG(AVR_SREG_H, x);
2444 
2445  // C: Rd7
2446  x = AVR_REG(Rd);
2447  x = MSB(x);
2448  C = SETG(AVR_SREG_C, x);
2449 
2450  // N: Res7
2452 
2453  // Z: !Res
2454  x = AVR_REG(Rd);
2455  x = IS_ZERO(x);
2456  Z = SETG(AVR_SREG_Z, x);
2457 
2458  // S: N ^ V, For signed tests.
2460 
2461  // V: N ^ C, For N and C after the shift
2463 
2464  return SEQ8(let, H, C, rol, N, Z, S, V);
2465 }
2466 
2467 static RzILOpEffect *avr_il_ror(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2468  RzILOpPure *x, *y, *carry;
2469  RzILOpEffect *let, *ror, *S, *V, *N, *Z, *C;
2470  // Rd = rot_right(Rd, 1)
2471  ut16 Rd = aop->param[0];
2473 
2474  // copy C into RES
2475  carry = VARG(AVR_SREG_C);
2476  let = SETL(AVR_LET_RES, carry);
2477 
2478  x = AVR_REG(Rd);
2479  y = AVR_SH(1);
2480  // Use carry as bit filler
2481  carry = VARL(AVR_LET_RES);
2482  x = SHIFTR(carry, x, y);
2483  ror = AVR_REG_SET(Rd, x);
2484 
2485  // C: Rd0
2486  x = AVR_REG(Rd);
2487  x = LSB(x);
2488  C = SETG(AVR_SREG_C, x);
2489 
2490  // N: Res7
2492 
2493  // Z: !Res
2494  x = AVR_REG(Rd);
2495  x = IS_ZERO(x);
2496  Z = SETG(AVR_SREG_Z, x);
2497 
2498  // S: N ^ V, For signed tests.
2500 
2501  // V: N ^ C, For N and C after the shift
2503 
2504  return SEQ7(let, C, ror, N, Z, S, V);
2505 }
2506 
2507 static RzILOpEffect *avr_il_sbc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2508  // Rd = Rd - Rr - C
2509  // changes H|S|V|N|Z|C
2510  ut16 Rd = aop->param[0];
2511  ut16 Rr = aop->param[1];
2514  RzILOpPure *x, *y;
2515  RzILOpEffect *let, *subt, *Z, *H, *S, *V, *N, *C;
2516  RzILOpBitVector *sub;
2517 
2518  // TMP = Rd - Rr - C
2519  x = AVR_REG(Rd);
2520  y = AVR_REG(Rr);
2521  x = SUB(x, y);
2523  sub = SUB(x, y);
2524  let = SETL(AVR_LET_RES, sub);
2525 
2526  // Rd = TMP
2527  x = VARL(AVR_LET_RES);
2528  subt = AVR_REG_SET(Rd, x);
2529 
2530  // set Z to 1 if !(x - y - C)
2532 
2533  // H: (!Rd3 & Rr3) | (Rr3 & Res3) | (Res3 & !Rd3)
2534  // Set if there was a borrow from bit 3; cleared otherwise
2535  x = AVR_REG(Rd);
2536  y = AVR_REG(Rr);
2538 
2539  // V: (Rd7 & !Rr7 & !Res7) | (!Rd7 & Rr7 & Res7)
2540  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
2541  x = AVR_REG(Rd);
2542  y = AVR_REG(Rr);
2544 
2545  // N: Res7
2546  // Set if MSB of the result is set; cleared otherwise.
2548 
2549  // C: (!Rd7 & Rr7) | (Rr7 & Res7) | (Res7 & !Rd7)
2550  // Set if the absolute value of Rr is larger than the absolute value of Rd; cleared otherwise
2551  x = AVR_REG(Rd);
2552  y = AVR_REG(Rr);
2554 
2555  // S: N ^ V, For signed tests.
2557 
2558  return SEQ8(let, Z, H, V, N, C, S, subt);
2559 }
2560 
2561 static RzILOpEffect *avr_il_sbci(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2562  // Rd = Rd - K - C
2563  // changes H|S|V|N|Z|C
2564  ut16 Rd = aop->param[0];
2565  ut16 K = aop->param[1];
2567  RzILOpPure *x, *y;
2568  RzILOpEffect *let, *subt, *Z, *H, *S, *V, *N, *C;
2569  RzILOpBitVector *sub;
2570 
2571  // TMP = Rd - K - C
2572  x = AVR_REG(Rd);
2573  y = AVR_IMM(K);
2574  x = SUB(x, y);
2576  sub = SUB(x, y);
2577  let = SETL(AVR_LET_RES, sub);
2578 
2579  // Rd = TMP
2580  x = VARL(AVR_LET_RES);
2581  subt = AVR_REG_SET(Rd, x);
2582 
2583  // set Z to 1 if !(x - y - C)
2585 
2586  // H: (!Rd3 & K3) | (K3 & Res3) | (Res3 & !Rd3)
2587  // Set if there was a borrow from bit 3; cleared otherwise
2588  x = AVR_REG(Rd);
2589  y = AVR_IMM(K);
2591 
2592  // V: (Rd7 & !K7 & !Res7) | (!Rd7 & K7 & Res7)
2593  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
2594  x = AVR_REG(Rd);
2595  y = AVR_IMM(K);
2597 
2598  // N: Res7
2599  // Set if MSB of the result is set; cleared otherwise.
2601 
2602  // C: (!Rd7 & K7) | (K7 & Res7) | (Res7 & !Rd7)
2603  // Set if the absolute value of K is larger than the absolute value of Rd; cleared otherwise
2604  x = AVR_REG(Rd);
2605  y = AVR_IMM(K);
2607 
2608  // S: N ^ V, For signed tests.
2610 
2611  return SEQ8(let, Z, H, V, N, C, S, subt);
2612 }
2613 
2614 static RzILOpEffect *avr_il_sbi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2615  // Sets a specified bit in an I/O Register.
2616  ut16 A = aop->param[0];
2617  ut16 b = aop->param[1];
2618 
2619  RzILOpPure *setb, *target, *result;
2620  const char *reg = resolve_mmio(analysis, A);
2621  if (!reg && A < 32) {
2622  // profiles that does not map registers between 0 and 31 have MMIO regs at this range
2623  reg = avr_registers[A];
2624  }
2625 
2626  setb = AVR_IMM(1u << b);
2627  target = VARG(reg);
2628  result = LOGOR(setb, target);
2629  return SETG(reg, result);
2630 }
2631 
2632 static RzILOpEffect *avr_il_sbic(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2633  // Skip if Bit in I/O Register is Cleared.
2634  ut16 A = aop->param[0];
2635  ut16 b = aop->param[1];
2636 
2637  RzILOpPure *clearb, *target, *result;
2638  const char *reg = resolve_mmio(analysis, A);
2639  if (!reg && A < 32) {
2640  // profiles that does not map registers between 0 and 31 have MMIO regs at this range
2641  reg = avr_registers[A];
2642  }
2643 
2644  clearb = AVR_IMM(~(1u << b));
2645  target = VARG(reg);
2646  result = LOGAND(clearb, target);
2647  result = IS_ZERO(result);
2648  return avr_il_branch_when(aop, analysis, pc + next_op->size, result, true);
2649 }
2650 
2651 static RzILOpEffect *avr_il_sbis(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2652  // Skip if Bit in I/O Register is Set.
2653  ut16 A = aop->param[0];
2654  ut16 b = aop->param[1];
2655 
2656  RzILOpPure *clearb, *target, *result;
2657  const char *reg = resolve_mmio(analysis, A);
2658  if (!reg && A < 32) {
2659  // profiles that does not map registers between 0 and 31 have MMIO regs at this range
2660  reg = avr_registers[A];
2661  }
2662 
2663  clearb = AVR_IMM(~(1u << b));
2664  target = VARG(reg);
2665  result = LOGAND(clearb, target);
2666  result = IS_ZERO(result);
2667  return avr_il_branch_when(aop, analysis, pc + next_op->size, result, false);
2668 }
2669 
2670 static RzILOpEffect *avr_il_sbiw(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2671  RzILOpPure *x, *imm;
2672  RzILOpEffect *let, *sbiw, *Z, *S, *V, *N, *C;
2673  // Rd+1:Rd = Rd+1:Rd - K
2674  // Rd can be only 24,26,28,30
2675  ut16 Rdh = aop->param[0];
2676  ut16 Rdl = aop->param[1];
2677  ut16 K = aop->param[2];
2680 
2681  // IND = Rd+1:Rd - K
2682  imm = UN(AVR_IND_SIZE, K);
2683  x = avr_il_get_indirect_address_reg(Rdh, Rdl);
2684  x = SUB(x, imm);
2685  let = SETL(AVR_LET_IND, x);
2686 
2687  // Rd+1:Rd = IND
2688  sbiw = avr_il_update_indirect_address_reg(AVR_LET_IND, Rdh, Rdl, 0, false);
2689 
2690  // set Z to 1 if !IND
2692 
2693  // Res = IND
2694  // V: Rdh7 & !Res15
2695  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
2697 
2698  // Res = IND
2699  // N: Res15
2700  // Set if MSB of the result is set; cleared otherwise.
2702 
2703  // Res = IND
2704  // C: !Rdh7 & Res15
2706 
2707  // S: N ^ V, For signed tests.
2709 
2710  return SEQ7(let, sbiw, Z, V, N, C, S);
2711 }
2712 
2713 static RzILOpEffect *avr_il_sbrc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2714  // Skip if Bit in Register is Cleared.
2715  ut16 Rd = aop->param[0];
2716  ut16 b = aop->param[1];
2718 
2719  RzILOpPure *clearb, *target, *result;
2720 
2721  clearb = AVR_IMM(~(1u << b));
2722  target = AVR_REG(Rd);
2723  result = LOGAND(clearb, target);
2724  result = IS_ZERO(result);
2725  return avr_il_branch_when(aop, analysis, pc + next_op->size, result, true);
2726 }
2727 
2728 static RzILOpEffect *avr_il_sbrs(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2729  // Skip if Bit in Register is Set.
2730  ut16 Rd = aop->param[0];
2731  ut16 b = aop->param[1];
2733 
2734  RzILOpPure *clearb, *target, *result;
2735 
2736  clearb = AVR_IMM(~(1u << b));
2737  target = AVR_REG(Rd);
2738  result = LOGAND(clearb, target);
2739  result = IS_ZERO(result);
2740  return avr_il_branch_when(aop, analysis, pc + next_op->size, result, false);
2741 }
2742 
2743 static RzILOpEffect *avr_il_sec(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2744  // C = 1
2745  return AVR_SREG_C_SET(true);
2746 }
2747 
2748 static RzILOpEffect *avr_il_seh(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2749  // H = 1
2750  return AVR_SREG_H_SET(true);
2751 }
2752 
2753 static RzILOpEffect *avr_il_sei(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2754  // I = 1
2755  return AVR_SREG_I_SET(true);
2756 }
2757 
2758 static RzILOpEffect *avr_il_sen(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2759  // N = 1
2760  return AVR_SREG_N_SET(true);
2761 }
2762 
2763 static RzILOpEffect *avr_il_ser(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2764  // Rd = $FF
2765  ut16 Rd = aop->param[0];
2767 
2768  return avr_il_assign_imm(avr_registers[Rd], 0xFF);
2769 }
2770 
2771 static RzILOpEffect *avr_il_ses(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2772  // S = 1
2773  return AVR_SREG_S_SET(true);
2774 }
2775 
2776 static RzILOpEffect *avr_il_set(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2777  // T = 1
2778  return AVR_SREG_T_SET(true);
2779 }
2780 
2781 static RzILOpEffect *avr_il_sev(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2782  // V = 1
2783  return AVR_SREG_V_SET(true);
2784 }
2785 
2786 static RzILOpEffect *avr_il_sez(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2787  // Z = 1
2788  return AVR_SREG_Z_SET(true);
2789 }
2790 
2791 static RzILOpEffect *avr_il_st(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2793  RzILOpPure *src;
2794  RzILOpEffect *st, *post_op, *let;
2795  // *((ut8*)X) = Rd where X = (r27 << 8) | r26;
2796  // *((ut8*)Y) = Rd where Y = (r29 << 8) | r28;
2797  // *((ut8*)Z) = Rd where Z = (r31 << 8) | r30;
2798  // When Z+ , Z is incremented by 1 after the execution (applies also to X and Y).
2799  // When -X , X is decremented by 1 after the execution (applies also to Z and Y).
2800  // When Y+q, Y is incremented by q after the execution (applies also to X and Z).
2801 
2802  // undefined behaviour per ISA below
2803  // st X+, r26 ; st X+, r27 ; st -X, r26 ; st -X, r27
2804  // st Y+, r28 ; st Y+, r29 ; st -Y, r28 ; st -Y, r29
2805  // st Z+, r30 ; st Z+, r31 ; st -Z, r30 ; st -Z, r31
2806 
2807  ut16 Rd = aop->param[0];
2808  char Rr = (char)aop->param[1]; // 'X' or 'Y' or 'Z'
2809  char Op = (char)aop->param[2]; // 0 or '+' or '-'
2810  ut16 q = aop->param[3];
2811 
2814 
2815  switch (Rr) {
2816  case 'X':
2817  addr = AVR_X();
2818  break;
2819  case 'Y':
2820  addr = AVR_Y();
2821  break;
2822  default: // 'Z'
2823  addr = AVR_Z();
2824  break;
2825  }
2826 
2827  addr = AVR_ADDR(addr);
2828  src = AVR_REG(Rd);
2829  st = STOREW(addr, src);
2830 
2831  if (Op != '+' && Op != '-') {
2832  return st;
2833  }
2834 
2835  switch (Rr) {
2836  case 'X':
2837  addr = AVR_X();
2838  post_op = AVR_SET_X(AVR_LET_IND, q, Op == '+');
2839  break;
2840  case 'Y':
2841  addr = AVR_Y();
2842  post_op = AVR_SET_Y(AVR_LET_IND, q, Op == '+');
2843  break;
2844  default: // 'Z'
2845  addr = AVR_Z();
2846  post_op = AVR_SET_Z(AVR_LET_IND, q, Op == '+');
2847  break;
2848  }
2849 
2850  let = SETL(AVR_LET_IND, addr);
2851  return SEQ3(st, let, post_op);
2852 }
2853 
2854 static RzILOpEffect *avr_il_sts(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2855  // Rd = *(k)
2856  ut16 k = aop->param[0];
2857  ut16 Rd = aop->param[1];
2859 
2860  return avr_il_store_reg(k, avr_registers[Rd]);
2861 }
2862 
2863 static RzILOpEffect *avr_il_sub(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2864  // Rd = Rd - Rr
2865  // changes H|S|V|N|Z|C
2866  ut16 Rd = aop->param[0];
2867  ut16 Rr = aop->param[1];
2870  RzILOpPure *x, *y;
2871  RzILOpEffect *let, *subt, *Z, *H, *S, *V, *N, *C;
2872  RzILOpBitVector *sub;
2873 
2874  // TMP = Rd - Rr
2875  x = AVR_REG(Rd);
2876  y = AVR_REG(Rr);
2877  sub = SUB(x, y);
2878  let = SETL(AVR_LET_RES, sub);
2879 
2880  // Rd = TMP
2881  x = VARL(AVR_LET_RES);
2882  subt = AVR_REG_SET(Rd, x);
2883 
2884  // set Z to 1 if !(x - y)
2886 
2887  // H: (!Rd3 & Rr3) | (Rr3 & Res3) | (Res3 & !Rd3)
2888  // Set if there was a borrow from bit 3; cleared otherwise
2889  x = AVR_REG(Rd);
2890  y = AVR_REG(Rr);
2892 
2893  // V: (Rd7 & !Rr7 & !Res7) | (!Rd7 & Rr7 & Res7)
2894  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
2895  x = AVR_REG(Rd);
2896  y = AVR_REG(Rr);
2898 
2899  // N: Res7
2900  // Set if MSB of the result is set; cleared otherwise.
2902 
2903  // C: (!Rd7 & Rr7) | (Rr7 & Res7) | (Res7 & !Rd7)
2904  // Set if the absolute value of Rr is larger than the absolute value of Rd; cleared otherwise
2905  x = AVR_REG(Rd);
2906  y = AVR_REG(Rr);
2908 
2909  // S: N ^ V, For signed tests.
2911 
2912  return SEQ8(let, Z, H, V, N, C, S, subt);
2913 }
2914 
2915 static RzILOpEffect *avr_il_subi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2916  // Rd = Rd - K
2917  // changes H|S|V|N|Z|C
2918  ut16 Rd = aop->param[0];
2919  ut16 K = aop->param[1];
2921  RzILOpPure *x, *y;
2922  RzILOpEffect *let, *subt, *Z, *H, *S, *V, *N, *C;
2923  RzILOpBitVector *sub;
2924 
2925  // TMP = Rd - K
2926  x = AVR_REG(Rd);
2927  y = AVR_IMM(K);
2928  sub = SUB(x, y);
2929  let = SETL(AVR_LET_RES, sub);
2930 
2931  // Rd = TMP
2932  x = VARL(AVR_LET_RES);
2933  subt = AVR_REG_SET(Rd, x);
2934 
2935  // set Z to 1 if !(x - y)
2937 
2938  // H: (!Rd3 & Rr3) | (Rr3 & Res3) | (Res3 & !Rd3)
2939  // Set if there was a borrow from bit 3; cleared otherwise
2940  x = AVR_REG(Rd);
2941  y = AVR_IMM(K);
2943 
2944  // V: (Rd7 & !Rr7 & !Res7) | (!Rd7 & Rr7 & Res7)
2945  // Set if two’s complement overflow resulted from the operation; cleared otherwise.
2946  x = AVR_REG(Rd);
2947  y = AVR_IMM(K);
2949 
2950  // N: Res7
2951  // Set if MSB of the result is set; cleared otherwise.
2953 
2954  // C: (!Rd7 & Rr7) | (Rr7 & Res7) | (Res7 & !Rd7)
2955  // Set if the absolute value of Rr is larger than the absolute value of Rd; cleared otherwise
2956  x = AVR_REG(Rd);
2957  y = AVR_IMM(K);
2959 
2960  // S: N ^ V, For signed tests.
2962 
2963  return SEQ8(let, Z, H, V, N, C, S, subt);
2964 }
2965 
2966 static RzILOpEffect *avr_il_swap(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2967  // Swaps high and low nibbles in a register.
2968  // R(7:4) = Rd(3:0), R(3:0) = Rd(7:4)
2969  ut16 Rd = aop->param[0];
2971  RzILOpPure *x, *y, *z;
2972  RzILOpEffect *let, *swap;
2973 
2974  // copy Rd
2975  x = AVR_REG(Rd);
2976  let = SETL(AVR_LET_RES, x);
2977 
2978  // Rd <<= 4
2979  x = AVR_REG(Rd);
2980  y = AVR_SH(4);
2981  x = SHIFTL0(x, y);
2982 
2983  // Rd |= RES >> 4
2984  z = VARL(AVR_LET_RES);
2985  y = AVR_SH(4);
2986  z = SHIFTR0(z, y);
2987 
2988  // Rd = (Rd << 4) | (RES >> 4)
2989  x = LOGOR(x, z);
2990  swap = AVR_REG_SET(Rd, x);
2991 
2992  return SEQ2(let, swap);
2993 }
2994 
2995 static RzILOpEffect *avr_il_xch(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis) {
2996  // Swaps the register content with the contents pointed by Z.
2997  // *(Z) = Rd and Rd = *(Z)
2998  ut16 Rd = aop->param[0];
3000  RzILOpPure *x, *y;
3001  RzILOpEffect *let, *set, *store;
3002 
3003  // copy Rd
3004  x = AVR_REG(Rd);
3005  let = SETL(AVR_LET_RES, x);
3006 
3007  // Rd = *(Z)
3008  x = AVR_Z();
3009  x = UNSIGNED(AVR_ADDR_SIZE, x);
3010  x = LOADW(AVR_REG_SIZE, x);
3011  set = AVR_REG_SET(Rd, x);
3012 
3013  // *(Z) = RES
3014  x = AVR_Z();
3015  x = UNSIGNED(AVR_ADDR_SIZE, x);
3016  y = VARL(AVR_LET_RES);
3017  store = STOREW(x, y);
3018 
3019  return SEQ3(let, set, store);
3020 }
3021 
3022 #include <rz_il/rz_il_opbuilder_end.h>
3023 
3024 typedef RzILOpEffect *(*avr_il_op)(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis);
3025 
3027  avr_il_unk, /* AVR_OP_INVALID */
3028  avr_il_adc,
3029  avr_il_add,
3030  avr_il_adiw,
3031  avr_il_and,
3032  avr_il_andi,
3033  avr_il_asr,
3034  avr_il_bld,
3035  avr_il_brcc,
3036  avr_il_brcs,
3037  avr_il_nop, /* AVR_OP_BREAK - the CPU treats the BREAK instruction as a NOP when not in JTAG mode */
3038  avr_il_breq,
3039  avr_il_brge,
3040  avr_il_brhc,
3041  avr_il_brhs,
3042  avr_il_brid,
3043  avr_il_brie,
3044  avr_il_brcs, /* AVR_OP_BRLO - alias of brcs */
3045  avr_il_brlt,
3046  avr_il_brmi,
3047  avr_il_brne,
3048  avr_il_brpl,
3049  avr_il_brcc, /* AVR_OP_BRSH - alias of brcc */
3050  avr_il_brtc,
3051  avr_il_brts,
3052  avr_il_brvc,
3053  avr_il_brvs,
3054  avr_il_bst,
3055  avr_il_call,
3056  avr_il_cbi,
3057  avr_il_clc,
3058  avr_il_clh,
3059  avr_il_cli,
3060  avr_il_cln,
3061  avr_il_clr,
3062  avr_il_cls,
3063  avr_il_clt,
3064  avr_il_clv,
3065  avr_il_clz,
3066  avr_il_com,
3067  avr_il_cp,
3068  avr_il_cpc,
3069  avr_il_cpi,
3070  avr_il_cpse,
3071  avr_il_dec,
3072  avr_il_unk, /* AVR_OP_DES */
3073  avr_il_eicall,
3074  avr_il_eijmp,
3075  avr_il_elpm,
3076  avr_il_eor,
3077  avr_il_fmul,
3078  avr_il_fmuls,
3079  avr_il_fmulsu,
3080  avr_il_icall,
3081  avr_il_ijmp,
3082  avr_il_in,
3083  avr_il_inc,
3084  avr_il_jmp,
3085  avr_il_lac,
3086  avr_il_las,
3087  avr_il_lat,
3088  avr_il_ld,
3089  avr_il_ld, /* AVR_OP_LDD - like ld */
3090  avr_il_ldi,
3091  avr_il_lds,
3092  avr_il_lpm,
3093  avr_il_lsl,
3094  avr_il_lsr,
3095  avr_il_mov,
3096  avr_il_movw,
3097  avr_il_mul,
3098  avr_il_muls,
3099  avr_il_mulsu,
3100  avr_il_neg,
3101  avr_il_nop,
3102  avr_il_or,
3103  avr_il_ori,
3104  avr_il_out,
3105  avr_il_pop,
3106  avr_il_push,
3107  avr_il_rcall,
3108  avr_il_ret,
3109  avr_il_ret, /* AVR_OP_RETI - works same way as ret */
3110  avr_il_rjmp,
3111  avr_il_rol,
3112  avr_il_ror,
3113  avr_il_sbc,
3114  avr_il_sbci,
3115  avr_il_sbi,
3116  avr_il_sbic,
3117  avr_il_sbis,
3118  avr_il_sbiw,
3119  avr_il_sbrc,
3120  avr_il_sbrs,
3121  avr_il_sec,
3122  avr_il_seh,
3123  avr_il_sei,
3124  avr_il_sen,
3125  avr_il_ser,
3126  avr_il_ses,
3127  avr_il_set,
3128  avr_il_sev,
3129  avr_il_sez,
3130  avr_il_nop, /* AVR_OP_SLEEP - is a NOP for RzIL */
3131  avr_il_unk, /* AVR_OP_SPM - this cannot be implemented. */
3132  avr_il_st,
3133  avr_il_st, /* AVR_OP_STD - same as ST */
3134  avr_il_sts,
3135  avr_il_sub,
3136  avr_il_subi,
3137  avr_il_swap,
3138  avr_il_and, /* AVR_OP_TST - same as and */
3139  avr_il_nop, /* AVR_OP_WDR - is a NOP for RzIL */
3140  avr_il_xch,
3141 };
3142 
3143 RZ_IPI bool rz_avr_il_opcode(RzAnalysis *analysis, RzAnalysisOp *op, ut64 pc, AVROp *aop, AVROp *next_op) {
3144  rz_return_val_if_fail(analysis && op && aop && next_op, false);
3145  if (aop->mnemonic >= AVR_OP_SIZE) {
3146  RZ_LOG_ERROR("RzIL: AVR: out of bounds op\n");
3147  return false;
3148  }
3149 
3150  avr_il_op create_op = avr_ops[aop->mnemonic];
3151  op->il_op = create_op(aop, next_op, pc, analysis);
3152 
3153  return true;
3154 }
3155 
3157  rz_return_val_if_fail(analysis, NULL);
3158 
3160  r->reg_bindings = avr_global_registers;
3161  return r;
3162 }
#define T(op)
static unsigned invert(unsigned x)
Definition: aesdata.c:73
#define jmp
#define mask()
#define imm
RZ_API RZ_OWN RzAnalysisILConfig * rz_analysis_il_config_new(ut32 pc_size, bool big_endian, ut32 mem_key_size)
Definition: analysis_il.c:53
#define RZ_IPI
Definition: analysis_wasm.c:11
lzma_index * src
Definition: index.h:567
#define BRANCH
#define A(x)
Definition: arc.h:165
#define I(x)
Definition: arc.h:164
#define C(x)
Definition: arc.h:167
static RzILOpEffect * cmp(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:942
static RzILOpEffect * mul(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:539
static ut32 neg(ArmOp *op)
Definition: armass64.c:981
ut16 val
Definition: armass64_const.h:6
@ AVR_OP_SIZE
Definition: disassembler.h:125
static RzILOpEffect * avr_il_sub(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2863
static RzILOpEffect * avr_il_nop(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:571
static RzILOpEffect * avr_il_las(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1792
static RzILOpEffect * avr_il_brcs(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:836
static RzILOpEffect * avr_il_rcall(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2366
static RzILOpEffect * avr_il_fmuls(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1492
static RzILOpEffect * avr_il_set(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2776
static RzILOpEffect * avr_il_cln(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1034
static RzILOpEffect * avr_il_lsr(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1998
static RzILOpEffect * avr_il_check_two_complement_overflow_flag_subtraction_wide(const char *local, ut16 reg)
Definition: avr_il.c:391
static RzILOpEffect * avr_il_cpi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1164
#define avr_return_val_if_invalid_indirect_address(x, v)
Definition: avr_il.c:86
static RzILOpEffect * avr_il_icall(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1634
#define AVR_SREG_H_BIT
Definition: avr_il.c:42
static RzILOpEffect * avr_il_eijmp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1339
#define AVR_IND_SIZE
Definition: avr_il.c:19
static RzILOpEffect * avr_il_inc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1720
static RzILOpEffect * avr_il_check_half_carry_flag_addition(const char *local, RzILOpPure *x, RzILOpPure *y)
Definition: avr_il.c:251
#define AVR_SREG_Z
Definition: avr_il.c:51
static RzILOpEffect * avr_il_sev(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2781
#define AVR_ADDR_SIZE
Definition: avr_il.c:20
static RzILOpEffect * avr_il_cli(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1029
static RzILOpEffect * avr_il_check_two_complement_overflow_flag_addition(const char *local, RzILOpPure *x, RzILOpPure *y)
Definition: avr_il.c:319
static RzILOpEffect * avr_il_neg(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2162
static RzILOpEffect * avr_il_com(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1074
static RzILOpEffect * avr_il_eicall(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1309
static RzILOpEffect * avr_il_cls(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1054
static RzILOpEffect * avr_il_ser(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2763
static RzILOpEffect * avr_il_unk(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:567
#define AVR_SREG_N_BIT
Definition: avr_il.c:48
static RzILOpEffect * avr_il_check_two_complement_overflow_flag_addition_wide(const char *local, ut16 reg)
Definition: avr_il.c:347
#define AVR_SREG_I_SET(x)
Definition: avr_il.c:71
static RzILOpEffect * avr_il_check_zero_flag_local(const char *local, bool and_zero)
Definition: avr_il.c:234
static RzILOpEffect * avr_il_brpl(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:920
static RzILOpEffect * avr_il_brne(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:912
RzILOpEffect *(* avr_il_op)(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:3024
#define AVR_SPMCSR
Definition: avr_il.c:31
static RzILOpEffect * avr_il_brvs(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:952
static RzILOpBitVector * avr_il_get_indirect_address_reg(ut16 reg_high, ut16 reg_low)
Definition: avr_il.c:115
static RzILOpEffect * avr_il_lpm(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1929
#define AVR_SREG_S_SET(x)
Definition: avr_il.c:74
static RzILOpEffect * avr_il_clv(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1064
static avr_il_op avr_ops[AVR_OP_SIZE]
Definition: avr_il.c:3026
static RzILOpEffect * avr_il_check_signess_flag()
Definition: avr_il.c:528
static RzILOpEffect * avr_il_xch(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2995
static RzILOpEffect * avr_il_add(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:623
#define AVR_IMM(imm)
Definition: avr_il.c:58
static RzILOpEffect * avr_il_ldi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1911
#define AVR_PC(x)
Definition: avr_il.c:56
RZ_IPI RzAnalysisILConfig * rz_avr_il_config(RZ_NONNULL RzAnalysis *analysis)
Definition: avr_il.c:3156
static RzILOpEffect * avr_il_rjmp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2413
static RzILOpEffect * avr_il_movw(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2043
#define AVR_SREG_C_BIT
Definition: avr_il.c:52
static RzILOpEffect * avr_il_jump_relative(AVROp *aop, RzAnalysis *analysis, ut64 where)
Definition: avr_il.c:155
static RzILOpEffect * avr_il_brhs(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:870
static RzILOpEffect * avr_il_andi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:742
static RzILOpEffect * avr_il_sts(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2854
static RzILOpEffect * avr_il_out(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2285
#define AVR_SREG_I
Definition: avr_il.c:39
#define AVR_LET_RES
Definition: avr_il.c:32
static RzILOpEffect * avr_il_sbis(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2651
static RzILOpEffect * avr_il_adiw(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:669
static RzILOpEffect * avr_il_ses(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2771
static RzILOpEffect * avr_il_elpm(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1353
#define AVR_RAMPX
Definition: avr_il.c:26
static RzILOpEffect * avr_il_lds(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1920
#define AVR_SP
Definition: avr_il.c:23
static RzILOpEffect * avr_il_check_zero_flag_reg(ut16 reg)
Definition: avr_il.c:245
#define AVR_SREG
Definition: avr_il.c:22
static RzILOpEffect * avr_il_ret(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2390
static RzILOpEffect * avr_il_assign_reg(const char *dst, const char *src)
Definition: avr_il.c:177
#define AVR_SREG_C_SET(x)
Definition: avr_il.c:78
static RzILOpEffect * avr_il_brvc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:944
#define avr_return_val_if_invalid_gpr(x, v)
Definition: avr_il.c:80
static RzILOpEffect * avr_il_push(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2343
static const char * avr_global_registers[]
Definition: avr_il.c:105
static RzILOpEffect * avr_il_muls(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2094
static RzILOpEffect * avr_il_clh(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1024
#define AVR_X()
Definition: avr_il.c:64
#define AVR_SREG_Z_BIT
Definition: avr_il.c:50
#define AVR_SREG_I_BIT
Definition: avr_il.c:38
static RzILOpEffect * avr_il_brts(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:936
static RzILOpEffect * avr_il_lsl(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1956
static RzILOpEffect * avr_il_check_negative_flag_reg(ut16 reg)
Definition: avr_il.c:418
static RzILOpEffect * avr_il_jmp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1754
static RzILOpEffect * avr_il_brmi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:904
static RzILOpEffect * avr_il_check_carry_flag_addition(const char *local, RzILOpPure *x, RzILOpPure *y)
Definition: avr_il.c:426
static RzILOpEffect * avr_il_mov(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2033
#define AVR_SREG_H_SET(x)
Definition: avr_il.c:73
static RzILOpEffect * avr_il_load_reg(ut64 addr, const char *reg, ut16 size)
Definition: avr_il.c:192
#define AVR_IMM16(imm)
Definition: avr_il.c:59
#define AVR_REG_SIZE
Definition: avr_il.c:15
static RzILOpEffect * avr_il_fmul(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1438
static RzILOpEffect * avr_il_eor(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1405
#define AVR_SREG_Z_SET(x)
Definition: avr_il.c:77
static RzILOpEffect * avr_il_check_two_complement_overflow_flag_subtraction(const char *local, RzILOpPure *x, RzILOpPure *y)
Definition: avr_il.c:364
#define AVR_SET_X(l, n, add)
Definition: avr_il.c:67
#define AVR_SET_Y(l, n, add)
Definition: avr_il.c:68
#define AVR_SREG_H
Definition: avr_il.c:43
#define AVR_SREG_T_BIT
Definition: avr_il.c:40
static RzILOpEffect * avr_il_store_reg(ut64 addr, const char *reg)
Definition: avr_il.c:187
#define AVR_SREG_V_SET(x)
Definition: avr_il.c:75
static RzILOpEffect * avr_il_check_half_carry_flag_subtraction(const char *local, RzILOpPure *x, RzILOpPure *y)
Definition: avr_il.c:285
#define AVR_SREG_T
Definition: avr_il.c:41
static RzILOpEffect * avr_il_check_carry_flag_addition_wide(const char *local, ut16 reg)
Definition: avr_il.c:456
#define AVR_REG(reg)
Definition: avr_il.c:60
RZ_IPI bool rz_avr_il_opcode(RzAnalysis *analysis, RzAnalysisOp *op, ut64 pc, AVROp *aop, AVROp *next_op)
Definition: avr_il.c:3143
static RzILOpEffect * avr_il_swap(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2966
#define AVR_Z()
Definition: avr_il.c:66
static RzILOpEffect * avr_il_brcc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:828
static RzILOpEffect * avr_il_st(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2791
static RzILOpEffect * avr_il_branch_when(AVROp *aop, RzAnalysis *analysis, ut64 where, RzILOpBool *when, bool cond)
Definition: avr_il.c:160
static RzILOpEffect * avr_il_asr(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:771
static RzILOpEffect * avr_il_assign_bool(const char *reg, ut16 value)
Definition: avr_il.c:173
#define AVR_SREG_C
Definition: avr_il.c:53
static RzILOpEffect * avr_il_sbrc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2713
static RzILOpEffect * avr_il_check_carry_flag_subtraction(const char *local, RzILOpPure *x, RzILOpPure *y)
Definition: avr_il.c:475
static RzILOpEffect * avr_il_bld(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:807
static RzILOpEffect * avr_il_brhc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:862
static RzILOpEffect * avr_il_rol(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2420
static RzILOpEffect * avr_il_seh(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2748
#define AVR_RAMPZ
Definition: avr_il.c:28
static RzILOpEffect * avr_il_check_carry_flag_subtraction_wide(const char *local, ut16 reg)
Definition: avr_il.c:509
static RzILOpEffect * avr_il_sbiw(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2670
#define AVR_SPH
Definition: avr_il.c:24
static RzILOpEffect * avr_il_update_indirect_address_reg(const char *local, ut16 reg_high, ut16 reg_low, ut64 n, bool add)
Definition: avr_il.c:121
static RzILOpEffect * avr_il_sec(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2743
#define AVR_SREG_T_SET(x)
Definition: avr_il.c:72
static RzILOpEffect * avr_il_cpc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1211
#define AVR_ZERO()
Definition: avr_il.c:63
static RzILOpEffect * avr_il_call(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:975
static RzILOpEffect * avr_il_brid(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:878
static RzILOpEffect * avr_il_lac(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1763
#define AVR_SREG_V
Definition: avr_il.c:47
static RzILOpEffect * avr_il_sbi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2614
static RzILOpEffect * avr_il_and(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:712
static const char * resolve_mmio(RzAnalysis *analysis, ut16 address)
Definition: avr_il.c:226
static RzILOpEffect * avr_il_brge(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:852
static RzILOpEffect * avr_il_adc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:575
static RzILOpEffect * avr_il_sen(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2758
#define AVR_SREG_N
Definition: avr_il.c:49
static RzILOpEffect * avr_il_brie(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:886
static RzILOpEffect * avr_il_lat(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1819
static RzILOpEffect * avr_il_set16_from_reg(const char *dst, const char *src, ut16 mask, ut16 sh)
Definition: avr_il.c:198
#define AVR_REG_SET(reg, x)
Definition: avr_il.c:61
static RzILOpPure * avr_subtract_if(ut32 bitsize, ut64 limit, RzILOpPure *minuend, ut64 subtrahend, bool invert)
Definition: avr_il.c:544
#define AVR_SREG_S_BIT
Definition: avr_il.c:44
static RzILOpEffect * avr_il_ori(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2253
#define AVR_RAMPY
Definition: avr_il.c:27
static RzILOpEffect * avr_il_mul(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2060
static RzILOpEffect * avr_il_sez(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2786
static RzILOpEffect * avr_il_set_sreg_bit_from_reg(const char *src, ut8 bit_val, const char *bit_reg)
Definition: avr_il.c:212
#define AVR_EIND
Definition: avr_il.c:30
static RzILOpEffect * avr_il_dec(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1275
#define AVR_ONE()
Definition: avr_il.c:62
static RzILOpEffect * avr_il_ld(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1848
#define AVR_SREG_N_SET(x)
Definition: avr_il.c:76
static RzILOpEffect * avr_il_sbic(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2632
#define AVR_LET_IND
Definition: avr_il.c:33
#define AVR_RAMPD
Definition: avr_il.c:29
static RzILOpEffect * avr_il_pop(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2320
static RzILOpEffect * avr_il_cbi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1001
static RzILOpEffect * avr_il_sbrs(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2728
#define AVR_SET_Z(l, n, add)
Definition: avr_il.c:69
static RzILOpEffect * avr_il_brtc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:928
static RzILOpEffect * avr_il_fmulsu(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1566
static RzILOpEffect * avr_il_sbci(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2561
#define AVR_SH(sh)
Definition: avr_il.c:57
static RzILOpEffect * avr_il_clr(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1039
static RzILOpEffect * avr_il_bst(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:960
static RzILOpEffect * avr_il_store_pure(ut64 addr, RzILOpPure *var)
Definition: avr_il.c:182
static RzILOpEffect * avr_il_clt(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1059
static RzILOpEffect * avr_il_mulsu(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2128
#define AVR_SPL
Definition: avr_il.c:25
static RzILOpEffect * avr_il_clz(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1069
static RzILOpBitVector * avr_il_sreg_bit_as_imm(const char *sreg_bit, ut8 bit)
Definition: avr_il.c:219
#define AVR_SREG_V_BIT
Definition: avr_il.c:46
static RzILOpEffect * avr_il_sei(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2753
static RzILOpEffect * avr_il_sbc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2507
static RzILOpEffect * avr_il_or(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2220
#define AVR_Y()
Definition: avr_il.c:65
static RzILOpEffect * avr_il_cp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1112
static RzILOpEffect * avr_il_cpse(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1266
static RzILOpEffect * avr_il_check_negative_flag_local(const char *local)
Definition: avr_il.c:410
const char * avr_registers[32]
Definition: avr_il.c:95
static RzILOpEffect * avr_il_ror(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2467
#define AVR_ADDR(x)
Definition: avr_il.c:55
static RzILOpEffect * avr_il_clc(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1019
static RzILOpEffect * avr_il_ijmp(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1661
static RzILOpEffect * avr_il_brlt(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:894
#define AVR_SREG_S
Definition: avr_il.c:45
static RzILOpEffect * avr_il_in(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:1671
static RzILOpEffect * avr_il_check_nc_overflow_flag()
Definition: avr_il.c:536
static RzILOpEffect * avr_il_subi(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:2915
static RzILOpEffect * avr_il_breq(AVROp *aop, AVROp *next_op, ut64 pc, RzAnalysis *analysis)
Definition: avr_il.c:844
static RzILOpEffect * avr_il_assign_imm(const char *reg, ut16 imm)
Definition: avr_il.c:168
#define H(x)
#define local
Definition: blast.c:36
static int value
Definition: cmd_api.c:93
#define NULL
Definition: cris-opc.c:27
RzCryptoSelector bit
Definition: crypto.c:16
#define r
Definition: crypto_rc6.c:12
uint16_t ut16
uint32_t ut32
const char * k
Definition: dsignal.c:11
when
Definition: fread.c:45
RZ_API RZ_OWN RzILOpPure * rz_il_op_new_loadw(RzILMemIndex mem, RZ_NONNULL RzILOpBitVector *key, ut32 n_bits)
Helper to create RzILOpArgsLoadW.
Definition: il_opcodes.c:738
RZ_API RZ_OWN RzILOpPure * rz_il_op_new_ite(RZ_NONNULL RzILOpPure *condition, RZ_NULLABLE RzILOpPure *x, RZ_NULLABLE RzILOpPure *y)
op structure for ite (bool -> 'a pure -> 'a pure -> 'a pure)
Definition: il_opcodes.c:53
RZ_API RZ_OWN RzILOpBitVector * rz_il_op_new_append(RZ_NONNULL RzILOpBitVector *high, RZ_NONNULL RzILOpBitVector *low)
op structure for appending 2 bitv: MSB:LSB high:low
Definition: il_opcodes.c:547
voidpf void uLong size
Definition: ioapi.h:138
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
#define SIGNED
Definition: ansidecl.h:248
#define AND
Definition: ansidecl.h:254
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
char * dst
Definition: lz4.h:724
static uint32_t const uint8_t uint32_t uint32_t limit
Definition: memcmplen.h:45
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
RZ_API RZ_BORROW const char * rz_platform_profile_resolve_mmio(RZ_NONNULL RzPlatformProfile *profile, ut64 address)
Resolves an address and returns the linked mmio.
void * load(const char *name, size_t *len)
Definition: pufftest.c:60
#define swap(a, b)
Definition: qsort.h:111
#define XOR
Definition: rsp_idec.c:212
#define NOP
Definition: rsp_idec.c:182
#define ADD
Definition: rsp_idec.c:200
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
Syntax Macros for RzIL Lifting.
#define LOGOR(x, y)
#define UGT(x, y)
#define LOGNOT(x)
#define IS_ZERO(x)
#define SHIFTR0(v, dist)
#define LOADW(n, addr)
#define SEQ8(e0, e1, e2, e3, e4, e5, e6, e7)
#define MUL(x, y)
#define LSB(x)
#define SHIFTL(f, v, dist)
#define APPEND(high, low)
#define UN(l, val)
#define IL_FALSE
#define EQ(x, y)
#define SEQ3(e0, e1, e2)
#define STOREW(addr, val)
#define SEQ5(e0, e1, e2, e3, e4)
#define SETL(name, v)
#define SEQ4(e0, e1, e2, e3)
#define SHIFTR(f, v, dist)
#define IL_TRUE
#define SEQ9(e0, e1, e2, e3, e4, e5, e6, e7, e8)
#define INV(x)
#define SEQ2(e0, e1)
#define ITE(c, t, f)
#define LOGXOR(x, y)
#define NON_ZERO(x)
#define UNSIGNED(n, x)
#define SEQ7(e0, e1, e2, e3, e4, e5, e6)
#define SEQ6(e0, e1, e2, e3, e4, e5)
#define SHIFTL0(v, dist)
#define VARL(name)
#define MSB(x)
#define LOGAND(x, y)
#define VARG(name)
#define JMP(tgt)
#define SETG(name, v)
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API int rz_str_ncasecmp(const char *dst, const char *orig, size_t n)
Definition: str.c:129
#define RZ_NONNULL
Definition: rz_types.h:64
#define st16
Definition: rz_types_base.h:14
#define st32
Definition: rz_types_base.h:12
@ DUP
Definition: packet.c:12
#define SUB(ns, call)
#define b(i)
Definition: sha256.c:42
#define cond(bop, top, mask, flags)
ut16 param[4]
Definition: disassembler.h:131
AVROpMnem mnemonic
Definition: disassembler.h:129
Definition: gun.c:81
Description of the global context of an RzAnalysisILVM.
Definition: rz_analysis.h:1134
RzPlatformTarget * arch_target
Definition: rz_analysis.h:622
An IL op performing a pure computation, 'a pure.
RzPlatformProfile * profile
Definition: rz_platform.h:34
#define rol(x, n)
Definition: md5.h:163
#define V(handle, symbol)
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58
#define N
Definition: zip_err_str.c:8
#define Z
Definition: zip_err_str.c:10
#define S
Definition: zip_err_str.c:9
static int add(char *argv[])
Definition: ziptool.c:84