Rizin
unix-like reverse engineering framework and cli tools
arm_il64.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2022 Florian Märkl <info@florianmaerkl.de>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_analysis.h>
5 #include <capstone/capstone.h>
6 
7 #include "arm_cs.h"
8 
9 #include "arm_accessors64.h"
10 // This source file is 64-bit specific, so avoid having to type 64 all the time:
11 #define IMM IMM64
12 #define REGID REGID64
13 #define ISIMM ISIMM64
14 #define ISREG ISREG64
15 #define ISMEM ISMEM64
16 #define OPCOUNT OPCOUNT64
17 #undef MEMDISP64 // the original one casts to ut64 which we don't want here
18 #define MEMDISP(x) insn->detail->arm64.operands[x].mem.disp
19 
21 
22 #include "arm_il_common.inc"
23 
27 static const char *regs_bound[] = {
28  "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
29  "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp",
30  "nf", "zf", "cf", "vf",
31  NULL
32 };
33 
39  switch (c) {
40  case ARM64_CC_EQ:
41  return VARG("zf");
42  case ARM64_CC_NE:
43  return INV(VARG("zf"));
44  case ARM64_CC_HS:
45  return VARG("cf");
46  case ARM64_CC_LO:
47  return INV(VARG("cf"));
48  case ARM64_CC_MI:
49  return VARG("nf");
50  case ARM64_CC_PL:
51  return INV(VARG("nf"));
52  case ARM64_CC_VS:
53  return VARG("vf");
54  case ARM64_CC_VC:
55  return INV(VARG("vf"));
56  case ARM64_CC_HI:
57  return AND(VARG("cf"), INV(VARG("zf")));
58  case ARM64_CC_LS:
59  return OR(INV(VARG("cf")), VARG("zf"));
60  case ARM64_CC_GE:
61  return INV(XOR(VARG("nf"), VARG("vf")));
62  case ARM64_CC_LT:
63  return XOR(VARG("nf"), VARG("vf"));
64  case ARM64_CC_GT:
65  return INV(OR(XOR(VARG("nf"), VARG("vf")), VARG("zf")));
66  case ARM64_CC_LE:
67  return OR(XOR(VARG("nf"), VARG("vf")), VARG("zf"));
68  default:
69  return NULL;
70  }
71 }
72 
73 static arm64_reg xreg(ut8 idx) {
74  // for some reason, the ARM64_REG_X0...ARM64_REG_X30 enum values are not contiguous,
75  // so use switch here and let the compiler optimize:
76  switch (idx) {
77  case 0: return ARM64_REG_X0;
78  case 1: return ARM64_REG_X1;
79  case 2: return ARM64_REG_X2;
80  case 3: return ARM64_REG_X3;
81  case 4: return ARM64_REG_X4;
82  case 5: return ARM64_REG_X5;
83  case 6: return ARM64_REG_X6;
84  case 7: return ARM64_REG_X7;
85  case 8: return ARM64_REG_X8;
86  case 9: return ARM64_REG_X9;
87  case 10: return ARM64_REG_X10;
88  case 11: return ARM64_REG_X11;
89  case 12: return ARM64_REG_X12;
90  case 13: return ARM64_REG_X13;
91  case 14: return ARM64_REG_X14;
92  case 15: return ARM64_REG_X15;
93  case 16: return ARM64_REG_X16;
94  case 17: return ARM64_REG_X17;
95  case 18: return ARM64_REG_X18;
96  case 19: return ARM64_REG_X19;
97  case 20: return ARM64_REG_X20;
98  case 21: return ARM64_REG_X21;
99  case 22: return ARM64_REG_X22;
100  case 23: return ARM64_REG_X23;
101  case 24: return ARM64_REG_X24;
102  case 25: return ARM64_REG_X25;
103  case 26: return ARM64_REG_X26;
104  case 27: return ARM64_REG_X27;
105  case 28: return ARM64_REG_X28;
106  case 29: return ARM64_REG_X29;
107  case 30: return ARM64_REG_X30;
108  case 31: return ARM64_REG_SP;
109  case 32: return ARM64_REG_XZR;
110  default:
112  return ARM64_REG_INVALID;
113  }
114 }
115 
116 static bool is_xreg(arm64_reg reg) {
117  switch (reg) {
118  case ARM64_REG_X0:
119  case ARM64_REG_X1:
120  case ARM64_REG_X2:
121  case ARM64_REG_X3:
122  case ARM64_REG_X4:
123  case ARM64_REG_X5:
124  case ARM64_REG_X6:
125  case ARM64_REG_X7:
126  case ARM64_REG_X8:
127  case ARM64_REG_X9:
128  case ARM64_REG_X10:
129  case ARM64_REG_X11:
130  case ARM64_REG_X12:
131  case ARM64_REG_X13:
132  case ARM64_REG_X14:
133  case ARM64_REG_X15:
134  case ARM64_REG_X16:
135  case ARM64_REG_X17:
136  case ARM64_REG_X18:
137  case ARM64_REG_X19:
138  case ARM64_REG_X20:
139  case ARM64_REG_X21:
140  case ARM64_REG_X22:
141  case ARM64_REG_X23:
142  case ARM64_REG_X24:
143  case ARM64_REG_X25:
144  case ARM64_REG_X26:
145  case ARM64_REG_X27:
146  case ARM64_REG_X28:
147  case ARM64_REG_X29:
148  case ARM64_REG_X30:
149  case ARM64_REG_SP:
150  case ARM64_REG_XZR:
151  return true;
152  default:
153  return false;
154  }
155 }
156 
158  if (reg >= ARM64_REG_W0 && reg <= ARM64_REG_W30) {
159  return reg - ARM64_REG_W0;
160  }
161  if (reg == ARM64_REG_WSP) {
162  return 31;
163  }
164  if (reg == ARM64_REG_WZR) {
165  return 32;
166  }
168  return 0;
169 }
170 
171 static bool is_wreg(arm64_reg reg) {
172  return (reg >= ARM64_REG_W0 && reg <= ARM64_REG_W30) || reg == ARM64_REG_WSP || reg == ARM64_REG_WZR;
173 }
174 
176  if (is_wreg(reg)) {
177  return xreg(wreg_idx(reg));
178  }
179  return reg;
180 }
181 
185 static const char *reg_var_name(arm64_reg reg) {
186  reg = xreg_of_reg(reg);
187  switch (reg) {
188  case ARM64_REG_X0: return "x0";
189  case ARM64_REG_X1: return "x1";
190  case ARM64_REG_X2: return "x2";
191  case ARM64_REG_X3: return "x3";
192  case ARM64_REG_X4: return "x4";
193  case ARM64_REG_X5: return "x5";
194  case ARM64_REG_X6: return "x6";
195  case ARM64_REG_X7: return "x7";
196  case ARM64_REG_X8: return "x8";
197  case ARM64_REG_X9: return "x9";
198  case ARM64_REG_X10: return "x10";
199  case ARM64_REG_X11: return "x11";
200  case ARM64_REG_X12: return "x12";
201  case ARM64_REG_X13: return "x13";
202  case ARM64_REG_X14: return "x14";
203  case ARM64_REG_X15: return "x15";
204  case ARM64_REG_X16: return "x16";
205  case ARM64_REG_X17: return "x17";
206  case ARM64_REG_X18: return "x18";
207  case ARM64_REG_X19: return "x19";
208  case ARM64_REG_X20: return "x20";
209  case ARM64_REG_X21: return "x21";
210  case ARM64_REG_X22: return "x22";
211  case ARM64_REG_X23: return "x23";
212  case ARM64_REG_X24: return "x24";
213  case ARM64_REG_X25: return "x25";
214  case ARM64_REG_X26: return "x26";
215  case ARM64_REG_X27: return "x27";
216  case ARM64_REG_X28: return "x28";
217  case ARM64_REG_X29: return "x29";
218  case ARM64_REG_X30: return "x30";
219  case ARM64_REG_SP: return "sp";
220  default: return NULL;
221  }
222 }
223 
228  if (is_xreg(reg) || reg == ARM64_REG_XZR) {
229  return 64;
230  }
231  if (is_wreg(reg) || reg == ARM64_REG_WZR) {
232  return 32;
233  }
234  return 0;
235 }
236 
241  if (reg == ARM64_REG_XZR) {
242  return U64(0);
243  }
244  if (reg == ARM64_REG_WZR) {
245  return U32(0);
246  }
247  const char *var = reg_var_name(reg);
248  if (!var) {
249  return NULL;
250  }
251  if (is_wreg(reg)) {
252  return UNSIGNED(32, VARG(var));
253  }
254  return VARG(var);
255 }
256 
261  if (v->code == RZ_IL_OP_CAST) {
262  // reuse any existing cast
263  v->op.cast.length = bits;
264  } else if (v->code != RZ_IL_OP_BITV || rz_bv_len(v->op.bitv.value) != bits) {
265  v = UNSIGNED(bits, v);
266  }
267  return v;
268 }
269 
271  bool is_signed = false;
272  ut32 src_bits;
273  switch (ext) {
274  case ARM64_EXT_SXTB:
275  is_signed = true;
276  // fallthrough
277  case ARM64_EXT_UXTB:
278  src_bits = 8;
279  break;
280 
281  case ARM64_EXT_SXTH:
282  is_signed = true;
283  // fallthrough
284  case ARM64_EXT_UXTH:
285  src_bits = 16;
286  break;
287 
288  case ARM64_EXT_SXTW:
289  is_signed = true;
290  // fallthrough
291  case ARM64_EXT_UXTW:
292  src_bits = 32;
293  break;
294 
295  case ARM64_EXT_SXTX:
296  is_signed = true;
297  // fallthrough
298  case ARM64_EXT_UXTX:
299  src_bits = 64;
300  break;
301 
302  default:
303  if (dst_bits == v_bits) {
304  return v;
305  } else {
306  return adjust_unsigned(dst_bits, v);
307  }
308  }
309 
310  v = adjust_unsigned(src_bits, v);
311  return is_signed ? SIGNED(dst_bits, v) : UNSIGNED(dst_bits, v);
312 }
313 
315  if (!dist) {
316  return v;
317  }
318  switch (sft) {
319  case ARM64_SFT_LSL:
320  return SHIFTL0(v, UN(6, dist));
321  case ARM64_SFT_LSR:
322  return SHIFTR0(v, UN(6, dist));
323  case ARM64_SFT_ASR:
324  return SHIFTRA(v, UN(6, dist));
325  default:
326  return v;
327  }
328 }
329 
330 #define REG(n) read_reg(REGID(n))
331 #define REGBITS(n) reg_bits(REGID(n))
332 #define MEMBASEID(x) insn->detail->arm64.operands[x].mem.base
333 #define MEMBASE(x) read_reg(MEMBASEID(x))
334 
340  const char *var = reg_var_name(reg);
341  if (!var) {
343  return NULL;
344  }
345  if (is_wreg(reg)) {
346  v = UNSIGNED(64, v);
347  }
348  return SETG(var, v);
349 }
350 
352  if (op->mem.index == ARM64_REG_INVALID) {
353  return base_plus_disp;
354  }
355  RzILOpBitVector *index = read_reg(op->mem.index);
356  index = extend(64, op->ext, index, reg_bits(op->mem.index));
357  index = apply_shift(op->shift.type, op->shift.value, index);
358  return ADD(base_plus_disp, index);
359 }
360 
367 static RzILOpBitVector *arg(cs_insn *insn, size_t n, ut32 *bits_inout) {
368  ut32 bits_requested = bits_inout ? *bits_inout : 0;
369  cs_arm64_op *op = &insn->detail->arm64.operands[n];
370  switch (op->type) {
371  case ARM64_OP_REG: {
372  if (!bits_requested) {
373  bits_requested = REGBITS(n);
374  if (!bits_requested) {
375  return NULL;
376  }
377  if (bits_inout) {
378  *bits_inout = bits_requested;
379  }
380  }
381  RzILOpBitVector *r = REG(n);
382  if (!r) {
383  return NULL;
384  }
385  return apply_shift(op->shift.type, op->shift.value, extend(bits_requested, op->ext, r, REGBITS(n)));
386  }
387  case ARM64_OP_IMM: {
388  if (!bits_requested) {
389  return NULL;
390  }
391  ut64 val = IMM(n);
392  if (op->shift.type == ARM64_SFT_LSL) {
393  val <<= op->shift.value;
394  }
395  return UN(bits_requested, val);
396  }
397  case ARM64_OP_MEM: {
399  st64 disp = MEMDISP(n);
400  if (disp > 0) {
401  addr = ADD(addr, U64(disp));
402  } else if (disp < 0) {
403  addr = SUB(addr, U64(-disp));
404  }
405  return arg_mem(addr, &insn->detail->arm64.operands[n]);
406  }
407  default:
408  break;
409  }
410  return NULL;
411 }
412 
413 #define ARG(n, bits) arg(insn, n, bits)
414 
420  return SEQ2(
421  SETG("zf", IS_ZERO(v)),
422  SETG("nf", MSB(DUP(v))));
423 }
424 
432  return SEQ3(
434  SETG("cf", IL_FALSE),
435  SETG("vf", IL_FALSE));
436 }
437 
442 static RzILOpEffect *add_sub(cs_insn *insn) {
443  if (!ISREG(0)) {
444  return NULL;
445  }
446  bool is_sub = insn->id == ARM64_INS_SUB || insn->id == ARM64_INS_SBC
447 #if CS_API_MAJOR > 4
448  || insn->id == ARM64_INS_SUBS || insn->id == ARM64_INS_SBCS
449 #endif
450  ;
451  ut32 bits = REGBITS(0);
452  if (!bits) {
453  return NULL;
454  }
455  RzILOpBitVector *a = ARG(1, &bits);
456  RzILOpBitVector *b = ARG(2, &bits);
457  if (!a || !b) {
460  return NULL;
461  }
462  RzILOpBitVector *res = is_sub ? SUB(a, b) : ADD(a, b);
463  bool with_carry = false;
464  if (insn->id == ARM64_INS_ADC
465 #if CS_API_MAJOR > 4
466  || insn->id == ARM64_INS_ADCS
467 #endif
468  ) {
469  res = ADD(res, ITE(VARG("cf"), UN(bits, 1), UN(bits, 0)));
470  with_carry = true;
471  } else if (insn->id == ARM64_INS_SBC
472 #if CS_API_MAJOR > 4
473  || insn->id == ARM64_INS_SBCS
474 #endif
475  ) {
476  res = SUB(res, ITE(VARG("cf"), UN(bits, 0), UN(bits, 1)));
477  with_carry = true;
478  }
479  RzILOpEffect *set = write_reg(REGID(0), res);
480  bool update_flags = insn->detail->arm64.update_flags;
481  if (update_flags) {
482  return SEQ6(
483  SETL("a", DUP(a)),
484  SETL("b", DUP(b)),
485  set,
486  SETG("cf", (is_sub ? sub_carry : add_carry)(VARL("a"), VARL("b"), with_carry, bits)),
487  SETG("vf", (is_sub ? sub_overflow : add_overflow)(VARL("a"), VARL("b"), REG(0))),
488  update_flags_zn(REG(0)));
489  }
490  return set;
491 }
492 
497 static RzILOpEffect *adr(cs_insn *insn) {
498  if (!ISREG(0)) {
499  return NULL;
500  }
501  return write_reg(REGID(0), U64(IMM(1)));
502 }
503 
508 static RzILOpEffect *bitwise(cs_insn *insn) {
509  if (!ISREG(0)) {
510  return NULL;
511  }
512  ut32 bits = REGBITS(0);
513  if (!bits) {
514  return NULL;
515  }
516  RzILOpBitVector *a = ARG(1, &bits);
517  RzILOpBitVector *b = ARG(2, &bits);
518  if (!a || !b) {
521  return NULL;
522  }
523  RzILOpBitVector *res;
524  switch (insn->id) {
525  case ARM64_INS_EOR:
526  res = LOGXOR(a, b);
527  break;
528  case ARM64_INS_EON:
529  res = LOGXOR(a, LOGNOT(b));
530  break;
531  case ARM64_INS_ORN:
532  res = LOGOR(a, LOGNOT(b));
533  break;
534  case ARM64_INS_ORR:
535  res = LOGOR(a, b);
536  break;
537  default: // ARM64_INS_AND
538  res = LOGAND(a, b);
539  break;
540  }
541  RzILOpEffect *eff = write_reg(REGID(0), res);
542  if (!eff) {
543  return NULL;
544  }
545  if (insn->detail->arm64.update_flags) {
546  return SEQ2(eff, update_flags_zn00(REG(0)));
547  }
548  return eff;
549 }
550 
555 static RzILOpEffect *shift(cs_insn *insn) {
556  if (!ISREG(0)) {
557  return NULL;
558  }
559  ut32 bits = REGBITS(0);
560  if (!bits) {
561  return NULL;
562  }
563  RzILOpBitVector *a = ARG(1, &bits);
564  if (!a) {
565  return NULL;
566  }
567  bits = bits == 32 ? 5 : 6; // cast to log2(bits) to perform exactly mod bits
568  RzILOpBitVector *b = ARG(2, &bits);
569  if (!b) {
571  return NULL;
572  }
573  RzILOpBitVector *res;
574  switch (insn->id) {
575  case ARM64_INS_ASR:
576  res = SHIFTRA(a, b);
577  break;
578  case ARM64_INS_LSR:
579  res = SHIFTR0(a, b);
580  break;
581  case ARM64_INS_ROR:
582  res = LOGOR(SHIFTR0(a, b), SHIFTL0(DUP(a), NEG(DUP(b))));
583  break;
584  default: // ARM64_INS_LSL
585  res = SHIFTL0(a, b);
586  break;
587  }
588  return write_reg(REGID(0), res);
589 }
590 
595 static RzILOpEffect *branch(cs_insn *insn) {
597  if (OPCOUNT() == 0) {
598  // for ARM64_INS_RET and similar
600  } else {
601  ut32 bits = 64;
602  a = ARG(0, &bits);
603  }
604  if (!a) {
605  return NULL;
606  }
607  RzILOpBool *c = cond(insn->detail->arm64.cc);
608  if (c) {
609  return BRANCH(c, JMP(a), NOP());
610  }
611  return JMP(a);
612 }
613 
618 static RzILOpEffect *bl(cs_insn *insn) {
619  ut32 bits = 64;
620  RzILOpBitVector *a = ARG(0, &bits);
621  if (!a) {
622  return NULL;
623  }
624  return SEQ2(
625  SETG("x30", U64(insn->address + 4)),
626  JMP(a));
627 }
628 
633 static RzILOpEffect *bfm(cs_insn *insn) {
634  if (!ISREG(0)) {
635  return NULL;
636  }
637  ut32 bits = 0;
638  RzILOpBitVector *a = ARG(0, &bits);
639  if (!a) {
640  return NULL;
641  }
642  if (ISIMM(1) && ISIMM(2)) {
643  // bfc
644  ut64 mask = rz_num_bitmask(IMM(2)) << RZ_MIN(63, IMM(1));
645  return write_reg(REGID(0), LOGAND(a, UN(bits, mask)));
646  }
647  RzILOpBitVector *b = ARG(1, &bits);
648  if (!b) {
649  return NULL;
650  }
651  ut64 mask_base = rz_num_bitmask(IMM(3));
652  ut64 mask = mask_base << RZ_MIN(63, IMM(2));
653  if (insn->id == ARM64_INS_BFI) {
654  return write_reg(REGID(0), LOGOR(LOGAND(a, UN(bits, ~mask)), SHIFTL0(LOGAND(b, UN(bits, mask_base)), UN(6, IMM(2)))));
655  }
656  // insn->id == ARM64_INS_BFXIL
657  return write_reg(REGID(0), LOGOR(LOGAND(a, UN(bits, ~mask_base)), SHIFTR0(LOGAND(b, UN(bits, mask)), UN(6, IMM(2)))));
658 }
659 
664 static RzILOpEffect *bic(cs_insn *insn) {
665  if (!ISREG(0)) {
666  return NULL;
667  }
668  ut32 bits = REGBITS(0);
669  if (!bits) {
670  return NULL;
671  }
672  RzILOpBitVector *a = ARG(1, &bits);
673  RzILOpBitVector *b = ARG(2, &bits);
674  if (!a || !b) {
677  return NULL;
678  }
679  RzILOpBitVector *res = LOGAND(a, LOGNOT(b));
680  RzILOpEffect *eff = NULL;
681  if (REGID(0) != ARM64_REG_XZR && REGID(0) != ARM64_REG_WZR) {
682  eff = write_reg(REGID(0), res);
683  if (!eff) {
684  return NULL;
685  }
686  res = NULL;
687  }
688  if (insn->detail->arm64.update_flags) {
689  RzILOpEffect *eff1 = update_flags_zn00(res ? res : REG(0));
690  return eff ? SEQ2(eff, eff1) : eff1;
691  }
692  if (!eff) {
693  rz_il_op_pure_free(res);
694  }
695  return eff;
696 }
697 
698 #if CS_API_MAJOR > 4
705 static RzILOpEffect *cas(cs_insn *insn) {
706  if (!ISREG(0) || !ISMEM(2)) {
707  return NULL;
708  }
709  ut32 bits = REGBITS(0);
710  if (!bits) {
711  return NULL;
712  }
713  switch (insn->id) {
714  case ARM64_INS_CASB:
715  case ARM64_INS_CASAB:
716  case ARM64_INS_CASALB:
717  case ARM64_INS_CASLB:
718  bits = 8;
719  break;
720  case ARM64_INS_CASH:
721  case ARM64_INS_CASAH:
722  case ARM64_INS_CASALH:
723  case ARM64_INS_CASLH:
724  bits = 16;
725  break;
726  default:
727  break;
728  }
729  RzILOpBitVector *addr = ARG(2, NULL);
730  RzILOpBitVector *cmpval = ARG(0, &bits);
731  RzILOpBitVector *newval = ARG(1, &bits);
732  RzILOpEffect *write_old_eff = write_reg(REGID(0), VARL("old"));
733  if (!addr || !cmpval || !newval || !write_old_eff) {
735  rz_il_op_pure_free(cmpval);
736  rz_il_op_pure_free(newval);
737  rz_il_op_effect_free(write_old_eff);
738  return NULL;
739  }
740  return SEQ3(
741  SETL("old", bits == 8 ? LOAD(addr) : LOADW(bits, addr)),
742  BRANCH(EQ(VARL("old"), cmpval), bits == 8 ? STORE(DUP(addr), newval) : STOREW(DUP(addr), newval), NULL),
743  write_old_eff);
744 }
745 
750 static RzILOpEffect *casp(cs_insn *insn) {
751  if (!ISREG(0) || !ISREG(1) || !ISMEM(4)) {
752  return NULL;
753  }
754  RzILOpBitVector *addr = ARG(4, NULL);
755  ut32 bits = 0;
756  RzILOpBitVector *cmpval0 = ARG(0, &bits);
757  RzILOpBitVector *cmpval1 = ARG(1, &bits);
758  RzILOpBitVector *newval0 = ARG(2, &bits);
759  RzILOpBitVector *newval1 = ARG(3, &bits);
760  RzILOpEffect *write_old0_eff = write_reg(REGID(0), VARL("old0"));
761  RzILOpEffect *write_old1_eff = write_reg(REGID(1), VARL("old1"));
762  if (!addr || !cmpval0 || !cmpval1 || !newval0 || !newval1 || !write_old0_eff || !write_old1_eff) {
764  rz_il_op_pure_free(cmpval0);
765  rz_il_op_pure_free(cmpval1);
766  rz_il_op_pure_free(newval0);
767  rz_il_op_pure_free(newval1);
768  rz_il_op_effect_free(write_old0_eff);
769  rz_il_op_effect_free(write_old1_eff);
770  return NULL;
771  }
772  return SEQ5(
773  SETL("old0", LOADW(bits, addr)),
774  SETL("old1", LOADW(bits, ADD(DUP(addr), U64(bits / 8)))),
775  BRANCH(AND(EQ(VARL("old0"), cmpval0), EQ(VARL("old1"), cmpval1)),
776  SEQ2(
777  STOREW(DUP(addr), newval0),
778  STOREW(ADD(DUP(addr), U64(bits / 8)), newval1)),
779  NULL),
780  write_old0_eff,
781  write_old1_eff);
782 }
783 #endif
784 
789 static RzILOpEffect *cbz(cs_insn *insn) {
790  RzILOpBitVector *v = ARG(0, NULL);
791  ut32 bits = 64;
792  RzILOpBitVector *tgt = ARG(1, &bits);
793  if (!v || !tgt) {
795  rz_il_op_pure_free(tgt);
796  return NULL;
797  }
798  return BRANCH(insn->id == ARM64_INS_CBNZ ? INV(IS_ZERO(v)) : IS_ZERO(v), JMP(tgt), NULL);
799 }
800 
805 static RzILOpEffect *cmp(cs_insn *insn) {
806  ut32 bits = 0;
807  RzILOpBitVector *a = ARG(0, &bits);
808  RzILOpBitVector *b = ARG(1, &bits);
809  if (!a || !b) {
812  return NULL;
813  }
814  bool is_neg = insn->id == ARM64_INS_CMN || insn->id == ARM64_INS_CCMN;
815  RzILOpEffect *eff = SEQ6(
816  SETL("a", a),
817  SETL("b", b),
818  SETL("r", is_neg ? ADD(VARL("a"), VARL("b")) : SUB(VARL("a"), VARL("b"))),
819  SETG("cf", (is_neg ? add_carry : sub_carry)(VARL("a"), VARL("b"), false, bits)),
820  SETG("vf", (is_neg ? add_overflow : sub_overflow)(VARL("a"), VARL("b"), VARL("r"))),
821  update_flags_zn(VARL("r")));
822  RzILOpBool *c = cond(insn->detail->arm64.cc);
823  if (c) {
824  ut64 imm = IMM(2);
825  return BRANCH(c,
826  eff,
827  SEQ4(
828  SETG("nf", imm & (1 << 3) ? IL_TRUE : IL_FALSE),
829  SETG("zf", imm & (1 << 2) ? IL_TRUE : IL_FALSE),
830  SETG("cf", imm & (1 << 1) ? IL_TRUE : IL_FALSE),
831  SETG("vf", imm & (1 << 0) ? IL_TRUE : IL_FALSE)));
832  }
833  return eff;
834 }
835 
840 static RzILOpEffect *csinc(cs_insn *insn) {
841  size_t dst_idx = 0;
842  size_t src0_idx = 1;
843  size_t src1_idx = OPCOUNT() > 2 ? 2 : 1;
844  if (!ISREG(dst_idx)) {
845  return NULL;
846  }
847  ut32 bits = REGBITS(dst_idx);
848  if (!bits) {
849  return NULL;
850  }
851  RzILOpBitVector *src0 = ARG(src0_idx, &bits);
852  if (!src0) {
853  return NULL;
854  }
855  RzILOpBool *c = cond(insn->detail->arm64.cc);
856  if (!c) {
857  // al/nv conditions, only possible in cs(inc|inv|neg)
858  return write_reg(REGID(dst_idx), src0);
859  }
860  RzILOpBitVector *src1 = ARG(src1_idx, &bits);
861  if (!src1) {
862  rz_il_op_pure_free(src0);
864  return NULL;
865  }
866  RzILOpBitVector *res;
867  bool invert_cond = false;
868  switch (insn->id) {
869  case ARM64_INS_CSEL:
870  invert_cond = true;
871  res = src1;
872  break;
873  case ARM64_INS_CSINV:
874  invert_cond = true;
875  // fallthrough
876  case ARM64_INS_CINV:
877  res = LOGNOT(src1);
878  break;
879  case ARM64_INS_CSNEG:
880  invert_cond = true;
881  // fallthrough
882  case ARM64_INS_CNEG:
883  res = NEG(src1);
884  break;
885  case ARM64_INS_CSINC:
886  invert_cond = true;
887  // fallthrough
888  default: // ARM64_INS_CINC, ARM64_INS_CSINC
889  res = ADD(src1, UN(bits, 1));
890  break;
891  }
892  return write_reg(REGID(dst_idx), invert_cond ? ITE(c, src0, res) : ITE(c, res, src0));
893 }
894 
899 static RzILOpEffect *cset(cs_insn *insn) {
900  if (!ISREG(0) || !REGBITS(0)) {
901  return NULL;
902  }
903  RzILOpBool *c = cond(insn->detail->arm64.cc);
904  if (!c) {
905  return NULL;
906  }
907  ut32 bits = REGBITS(0);
908  return write_reg(REGID(0), ITE(c, SN(bits, insn->id == ARM64_INS_CSETM ? -1 : 1), SN(bits, 0)));
909 }
910 
915 static RzILOpEffect *cls(cs_insn *insn) {
916  if (!ISREG(0)) {
917  return NULL;
918  }
919  ut32 bits = 0;
920  RzILOpBitVector *v = ARG(1, &bits);
921  if (!v) {
922  return NULL;
923  }
924  return SEQ5(
925  SETL("v", v),
926  SETL("i", SN(bits, -1)),
927  SETL("msb", MSB(VARL("v"))),
928  REPEAT(INV(XOR(MSB(VARL("v")), VARL("msb"))),
929  SEQ2(
930  SETL("v", SHIFTL(INV(VARL("msb")), VARL("v"), UN(6, 1))),
931  SETL("i", ADD(VARL("i"), UN(bits, 1))))),
932  write_reg(REGID(0), VARL("i")));
933 }
934 
939 static RzILOpEffect *clz(cs_insn *insn) {
940  if (!ISREG(0)) {
941  return NULL;
942  }
943  ut32 bits = 0;
944  RzILOpBitVector *v = ARG(1, &bits);
945  if (!v) {
946  return NULL;
947  }
948  return SEQ4(
949  SETL("v", v),
950  SETL("i", UN(bits, bits)),
951  REPEAT(INV(IS_ZERO(VARL("v"))),
952  SEQ2(
953  SETL("v", SHIFTR0(VARL("v"), UN(6, 1))),
954  SETL("i", SUB(VARL("i"), UN(bits, 1))))),
955  write_reg(REGID(0), VARL("i")));
956 }
957 
962 static RzILOpEffect *extr(cs_insn *insn) {
963  if (!ISREG(0)) {
964  return NULL;
965  }
966  ut32 bits = REGBITS(0);
967  if (!bits) {
968  return NULL;
969  }
970  RzILOpBitVector *h = ARG(1, &bits);
971  RzILOpBitVector *l = ARG(2, &bits);
972  ut32 dist_bits = 6;
973  RzILOpBitVector *dist = ARG(3, &dist_bits);
974  if (!h || !l || !dist) {
977  rz_il_op_pure_free(dist);
978  return NULL;
979  }
980  return write_reg(REGID(0), UNSIGNED(bits, SHIFTR0(APPEND(h, l), dist)));
981 }
982 
987 static RzILOpEffect *svc(cs_insn *insn) {
988  return GOTO("svc");
989 }
990 
991 static void label_svc(RzILVM *vm, RzILOpEffect *op) {
992  // stub, nothing to do here
993 }
994 
999 static RzILOpEffect *hvc(cs_insn *insn) {
1000  return GOTO("hvc");
1001 }
1002 
1003 static void label_hvc(RzILVM *vm, RzILOpEffect *op) {
1004  // stub, nothing to do here
1005 }
1006 
1007 static RzILOpEffect *load_effect(ut32 bits, bool is_signed, arm64_reg dst_reg, RZ_OWN RzILOpBitVector *addr) {
1008  RzILOpBitVector *val = bits == 8 ? LOAD(addr) : LOADW(bits, addr);
1009  if (bits != 64) {
1010  if (is_signed) {
1011  if (is_wreg(dst_reg)) {
1012  val = UNSIGNED(64, SIGNED(32, val));
1013  } else {
1014  val = SIGNED(64, val);
1015  }
1016  } else {
1017  val = UNSIGNED(64, val);
1018  }
1019  }
1020  dst_reg = xreg_of_reg(dst_reg);
1021  return write_reg(dst_reg, val);
1022 }
1023 
1024 static RzILOpEffect *writeback(cs_insn *insn, size_t addr_op, RZ_BORROW RzILOpBitVector *addr) {
1025  if (!insn->detail->arm64.writeback || !is_xreg(MEMBASEID(addr_op))) {
1026  return NULL;
1027  }
1028  RzILOpBitVector *wbaddr = DUP(addr);
1029  if (ISIMM(addr_op + 1)) {
1030  // post-index
1031  st64 disp = IMM(addr_op + 1);
1032  if (disp > 0) {
1033  wbaddr = ADD(wbaddr, U64(disp));
1034  } else if (disp < 0) {
1035  wbaddr = SUB(wbaddr, U64(-disp));
1036  }
1037  }
1038  return write_reg(MEMBASEID(addr_op), wbaddr);
1039 }
1040 
1058 static RzILOpEffect *ldr(cs_insn *insn) {
1059  if (!ISREG(0)) {
1060  return NULL;
1061  }
1062  bool pair = insn->id == ARM64_INS_LDAXP || insn->id == ARM64_INS_LDXP ||
1063  insn->id == ARM64_INS_LDP || insn->id == ARM64_INS_LDNP || insn->id == ARM64_INS_LDPSW;
1064  if (pair && !ISREG(1)) {
1065  return NULL;
1066  }
1067  ut32 bits = 64;
1068  size_t addr_op = pair ? 2 : 1;
1069  RzILOpBitVector *addr = ARG(addr_op, &bits);
1070  if (!addr) {
1071  return NULL;
1072  }
1073  arm64_reg dst_reg = REGID(0);
1074  ut64 loadsz;
1075  bool is_signed = false;
1076  switch (insn->id) {
1077  case ARM64_INS_LDRSB:
1078  case ARM64_INS_LDURSB:
1079  case ARM64_INS_LDTRSB:
1080 #if CS_API_MAJOR > 4
1081  case ARM64_INS_LDAPURSB:
1082 #endif
1083  is_signed = true;
1084  // fallthrough
1085  case ARM64_INS_LDRB:
1086  case ARM64_INS_LDURB:
1087  case ARM64_INS_LDARB:
1088  case ARM64_INS_LDAXRB:
1089  case ARM64_INS_LDTRB:
1090  case ARM64_INS_LDXRB:
1091 #if CS_API_MAJOR > 4
1092  case ARM64_INS_LDLARB:
1093  case ARM64_INS_LDAPRB:
1094  case ARM64_INS_LDAPURB:
1095 #endif
1096  loadsz = 8;
1097  break;
1098  case ARM64_INS_LDRSH:
1099  case ARM64_INS_LDURSH:
1100  case ARM64_INS_LDTRSH:
1101 #if CS_API_MAJOR > 4
1102  case ARM64_INS_LDAPURSH:
1103 #endif
1104  is_signed = true;
1105  // fallthrough
1106  case ARM64_INS_LDRH:
1107  case ARM64_INS_LDURH:
1108  case ARM64_INS_LDARH:
1109  case ARM64_INS_LDAXRH:
1110  case ARM64_INS_LDTRH:
1111  case ARM64_INS_LDXRH:
1112 #if CS_API_MAJOR > 4
1113  case ARM64_INS_LDAPRH:
1114  case ARM64_INS_LDAPURH:
1115  case ARM64_INS_LDLARH:
1116 #endif
1117  loadsz = 16;
1118  break;
1119  case ARM64_INS_LDRSW:
1120  case ARM64_INS_LDURSW:
1121  case ARM64_INS_LDPSW:
1122  case ARM64_INS_LDTRSW:
1123 #if CS_API_MAJOR > 4
1124  case ARM64_INS_LDAPURSW:
1125 #endif
1126  is_signed = true;
1127  loadsz = 32;
1128  break;
1129  default:
1130  // ARM64_INS_LDR, ARM64_INS_LDRU, ARM64_INS_LDAPR, ARM64_INS_LDAPUR, ARM64_INS_LDAR, ARM64_INS_LDAXR, ARM64_INS_LDLAR,
1131  // ARM64_INS_LDP, ARM64_INS_LDNP, ARM64_INS_LDRAA, ARM64_INS_LDRAB, ARM64_INS_LDTR, ARM64_INS_LDXR
1132  loadsz = is_wreg(dst_reg) ? 32 : 64;
1133  break;
1134  }
1135  RzILOpEffect *eff = NULL;
1136  if (pair) {
1137  eff = SETL("addr", addr);
1138  addr = VARL("addr");
1139  }
1140  RzILOpEffect *eff1 = load_effect(loadsz, is_signed, dst_reg, addr);
1141  if (!eff1) {
1142  return NULL;
1143  }
1144  eff = eff ? SEQ2(eff, eff1) : eff1;
1145  if (pair) {
1146  RzILOpEffect *eff1 = load_effect(loadsz, is_signed, REGID(1), ADD(DUP(addr), U64(loadsz / 8)));
1147  if (!eff1) {
1148  rz_il_op_effect_free(eff);
1149  return NULL;
1150  }
1151  eff = SEQ2(eff, eff1);
1152  }
1153  RzILOpEffect *wb_eff = writeback(insn, addr_op, addr);
1154  if (wb_eff) {
1155  eff = SEQ2(eff, wb_eff);
1156  }
1157  return eff;
1158 }
1159 
1169 static RzILOpEffect *str(cs_insn *insn) {
1170  if (!ISREG(0) || !REGBITS(0)) {
1171  return NULL;
1172  }
1173  bool result = insn->id == ARM64_INS_STXR || insn->id == ARM64_INS_STXRB || insn->id == ARM64_INS_STXRH || insn->id == ARM64_INS_STXP ||
1174  insn->id == ARM64_INS_STLXR || insn->id == ARM64_INS_STLXRB || insn->id == ARM64_INS_STLXRH || insn->id == ARM64_INS_STLXP;
1175  bool pair = insn->id == ARM64_INS_STP || insn->id == ARM64_INS_STNP || insn->id == ARM64_INS_STXP || insn->id == ARM64_INS_STLXP;
1176  size_t src_op = result ? 1 : 0;
1177  size_t addr_op = (result ? 1 : 0) + 1 + (pair ? 1 : 0);
1178  ut32 addr_bits = 64;
1179  RzILOpBitVector *addr = ARG(addr_op, &addr_bits);
1180  if (!addr) {
1181  return NULL;
1182  }
1183  ut32 bits;
1184  switch (insn->id) {
1185  case ARM64_INS_STRB:
1186  case ARM64_INS_STURB:
1187  case ARM64_INS_STLRB:
1188  case ARM64_INS_STXRB:
1189  case ARM64_INS_STLXRB:
1190  case ARM64_INS_STTRB:
1191 #if CS_API_MAJOR > 4
1192  case ARM64_INS_STLLRB:
1193  case ARM64_INS_STLURB:
1194 #endif
1195  bits = 8;
1196  break;
1197  case ARM64_INS_STRH:
1198  case ARM64_INS_STURH:
1199  case ARM64_INS_STLRH:
1200  case ARM64_INS_STXRH:
1201  case ARM64_INS_STLXRH:
1202  case ARM64_INS_STTRH:
1203 #if CS_API_MAJOR > 4
1204  case ARM64_INS_STLLRH:
1205  case ARM64_INS_STLURH:
1206 #endif
1207  bits = 16;
1208  break;
1209  default:
1210  // ARM64_INS_STR, ARM64_INS_STUR, ARM64_INS_STLLR, ARM64_INS_STLR, ARM64_INS_STLUR, ARM64_INS_STP,
1211  // ARM64_INS_STXR, ARM64_INS_STXP, ARM64_INS_STLXR, ARM64_INS_STLXP, ARM64_INS_STNP, ARM64_INS_STTR
1212  bits = REGBITS(src_op);
1213  if (!bits) {
1215  return NULL;
1216  }
1217  break;
1218  }
1219  RzILOpBitVector *val = ARG(src_op, &bits);
1220  if (!val) {
1222  return NULL;
1223  }
1224  RzILOpBitVector *val2 = NULL;
1225  if (pair) {
1226  val2 = ARG(src_op + 1, &bits);
1227  if (!val2) {
1230  return NULL;
1231  }
1232  }
1233  RzILOpEffect *eff = bits == 8 ? STORE(addr, val) : STOREW(addr, val);
1234  if (pair) {
1235  RzILOpBitVector *addr2 = ADD(DUP(addr), U64(bits / 8));
1236  eff = SEQ2(eff, bits == 8 ? STORE(addr2, val2) : STOREW(addr2, val2));
1237  }
1238  RzILOpEffect *wb_eff = writeback(insn, addr_op, addr);
1239  if (wb_eff) {
1240  eff = SEQ2(eff, wb_eff);
1241  }
1242  if (result) {
1243  // always successful
1244  RzILOpEffect *res_eff = write_reg(REGID(0), UN(REGBITS(0), 0));
1245  if (!res_eff) {
1246  rz_il_op_effect_free(eff);
1247  return NULL;
1248  }
1249  eff = SEQ2(eff, res_eff);
1250  }
1251  return eff;
1252 }
1253 
1254 #if CS_API_MAJOR > 4
1299 static RzILOpEffect *ldadd(cs_insn *insn) {
1300  size_t addr_op = OPCOUNT() == 3 ? 2 : 1;
1301  if (!ISMEM(addr_op)) {
1302  return NULL;
1303  }
1304  arm64_reg addend_reg = REGID(0);
1305  ut64 loadsz;
1306  enum {
1307  OP_ADD,
1308  OP_CLR,
1309  OP_EOR,
1310  OP_SET,
1311  OP_SMAX,
1312  OP_SMIN,
1313  OP_UMAX,
1314  OP_UMIN
1315  } op = OP_ADD;
1316  switch (insn->id) {
1317  case ARM64_INS_LDCLRB:
1318  case ARM64_INS_LDCLRAB:
1319  case ARM64_INS_LDCLRALB:
1320  case ARM64_INS_LDCLRLB:
1321  case ARM64_INS_STCLRB:
1322  case ARM64_INS_STCLRLB:
1323  op = OP_CLR;
1324  loadsz = 8;
1325  break;
1326  case ARM64_INS_LDEORB:
1327  case ARM64_INS_LDEORAB:
1328  case ARM64_INS_LDEORALB:
1329  case ARM64_INS_LDEORLB:
1330  case ARM64_INS_STEORB:
1331  case ARM64_INS_STEORLB:
1332  op = OP_EOR;
1333  loadsz = 8;
1334  break;
1335  case ARM64_INS_LDSETB:
1336  case ARM64_INS_LDSETAB:
1337  case ARM64_INS_LDSETALB:
1338  case ARM64_INS_LDSETLB:
1339  case ARM64_INS_STSETB:
1340  case ARM64_INS_STSETLB:
1341  op = OP_SET;
1342  loadsz = 8;
1343  break;
1344  case ARM64_INS_LDSMAXB:
1345  case ARM64_INS_LDSMAXAB:
1346  case ARM64_INS_LDSMAXALB:
1347  case ARM64_INS_LDSMAXLB:
1348  case ARM64_INS_STSMAXB:
1349  case ARM64_INS_STSMAXLB:
1350  op = OP_SMAX;
1351  loadsz = 8;
1352  break;
1353  case ARM64_INS_LDSMINB:
1354  case ARM64_INS_LDSMINAB:
1355  case ARM64_INS_LDSMINALB:
1356  case ARM64_INS_LDSMINLB:
1357  case ARM64_INS_STSMINB:
1358  case ARM64_INS_STSMINLB:
1359  op = OP_SMIN;
1360  loadsz = 8;
1361  break;
1362  case ARM64_INS_LDUMAXB:
1363  case ARM64_INS_LDUMAXAB:
1364  case ARM64_INS_LDUMAXALB:
1365  case ARM64_INS_LDUMAXLB:
1366  case ARM64_INS_STUMAXB:
1367  case ARM64_INS_STUMAXLB:
1368  op = OP_UMAX;
1369  loadsz = 8;
1370  break;
1371  case ARM64_INS_LDUMINB:
1372  case ARM64_INS_LDUMINAB:
1373  case ARM64_INS_LDUMINALB:
1374  case ARM64_INS_LDUMINLB:
1375  case ARM64_INS_STUMINB:
1376  case ARM64_INS_STUMINLB:
1377  op = OP_UMIN;
1378  loadsz = 8;
1379  break;
1380  case ARM64_INS_LDADDB:
1381  case ARM64_INS_LDADDAB:
1382  case ARM64_INS_LDADDALB:
1383  case ARM64_INS_LDADDLB:
1384  case ARM64_INS_STADDB:
1385  case ARM64_INS_STADDLB:
1386  loadsz = 8;
1387  break;
1388 
1389  case ARM64_INS_LDCLRH:
1390  case ARM64_INS_LDCLRAH:
1391  case ARM64_INS_LDCLRALH:
1392  case ARM64_INS_LDCLRLH:
1393  case ARM64_INS_STCLRH:
1394  case ARM64_INS_STCLRLH:
1395  op = OP_CLR;
1396  loadsz = 16;
1397  break;
1398  case ARM64_INS_LDEORH:
1399  case ARM64_INS_LDEORAH:
1400  case ARM64_INS_LDEORALH:
1401  case ARM64_INS_LDEORLH:
1402  case ARM64_INS_STEORH:
1403  case ARM64_INS_STEORLH:
1404  op = OP_EOR;
1405  loadsz = 16;
1406  break;
1407  case ARM64_INS_LDSETH:
1408  case ARM64_INS_LDSETAH:
1409  case ARM64_INS_LDSETALH:
1410  case ARM64_INS_LDSETLH:
1411  case ARM64_INS_STSETH:
1412  case ARM64_INS_STSETLH:
1413  op = OP_SET;
1414  loadsz = 16;
1415  break;
1416  case ARM64_INS_LDSMAXH:
1417  case ARM64_INS_LDSMAXAH:
1418  case ARM64_INS_LDSMAXALH:
1419  case ARM64_INS_LDSMAXLH:
1420  case ARM64_INS_STSMAXH:
1421  case ARM64_INS_STSMAXLH:
1422  op = OP_SMAX;
1423  loadsz = 16;
1424  break;
1425  case ARM64_INS_LDSMINH:
1426  case ARM64_INS_LDSMINAH:
1427  case ARM64_INS_LDSMINALH:
1428  case ARM64_INS_LDSMINLH:
1429  case ARM64_INS_STSMINH:
1430  case ARM64_INS_STSMINLH:
1431  op = OP_SMIN;
1432  loadsz = 16;
1433  break;
1434  case ARM64_INS_LDUMAXH:
1435  case ARM64_INS_LDUMAXAH:
1436  case ARM64_INS_LDUMAXALH:
1437  case ARM64_INS_LDUMAXLH:
1438  case ARM64_INS_STUMAXH:
1439  case ARM64_INS_STUMAXLH:
1440  op = OP_UMAX;
1441  loadsz = 16;
1442  break;
1443  case ARM64_INS_LDUMINH:
1444  case ARM64_INS_LDUMINAH:
1445  case ARM64_INS_LDUMINALH:
1446  case ARM64_INS_LDUMINLH:
1447  case ARM64_INS_STUMINH:
1448  case ARM64_INS_STUMINLH:
1449  op = OP_UMIN;
1450  loadsz = 16;
1451  break;
1452  case ARM64_INS_LDADDH:
1453  case ARM64_INS_LDADDAH:
1454  case ARM64_INS_LDADDALH:
1455  case ARM64_INS_LDADDLH:
1456  case ARM64_INS_STADDH:
1457  case ARM64_INS_STADDLH:
1458  loadsz = 16;
1459  break;
1460 
1461  case ARM64_INS_LDCLR:
1462  case ARM64_INS_LDCLRA:
1463  case ARM64_INS_LDCLRAL:
1464  case ARM64_INS_LDCLRL:
1465  case ARM64_INS_STCLR:
1466  case ARM64_INS_STCLRL:
1467  op = OP_CLR;
1468  goto size_from_reg;
1469  case ARM64_INS_LDEOR:
1470  case ARM64_INS_LDEORA:
1471  case ARM64_INS_LDEORAL:
1472  case ARM64_INS_LDEORL:
1473  case ARM64_INS_STEOR:
1474  case ARM64_INS_STEORL:
1475  op = OP_EOR;
1476  goto size_from_reg;
1477  case ARM64_INS_LDSET:
1478  case ARM64_INS_LDSETA:
1479  case ARM64_INS_LDSETAL:
1480  case ARM64_INS_LDSETL:
1481  case ARM64_INS_STSET:
1482  case ARM64_INS_STSETL:
1483  op = OP_SET;
1484  goto size_from_reg;
1485  case ARM64_INS_LDSMAX:
1486  case ARM64_INS_LDSMAXA:
1487  case ARM64_INS_LDSMAXAL:
1488  case ARM64_INS_LDSMAXL:
1489  case ARM64_INS_STSMAX:
1490  case ARM64_INS_STSMAXL:
1491  op = OP_SMAX;
1492  goto size_from_reg;
1493  case ARM64_INS_LDSMIN:
1494  case ARM64_INS_LDSMINA:
1495  case ARM64_INS_LDSMINAL:
1496  case ARM64_INS_LDSMINL:
1497  case ARM64_INS_STSMIN:
1498  case ARM64_INS_STSMINL:
1499  op = OP_SMIN;
1500  goto size_from_reg;
1501  case ARM64_INS_LDUMAX:
1502  case ARM64_INS_LDUMAXA:
1503  case ARM64_INS_LDUMAXAL:
1504  case ARM64_INS_LDUMAXL:
1505  case ARM64_INS_STUMAX:
1506  case ARM64_INS_STUMAXL:
1507  op = OP_UMAX;
1508  goto size_from_reg;
1509  case ARM64_INS_LDUMIN:
1510  case ARM64_INS_LDUMINA:
1511  case ARM64_INS_LDUMINAL:
1512  case ARM64_INS_LDUMINL:
1513  case ARM64_INS_STUMIN:
1514  case ARM64_INS_STUMINL:
1515  op = OP_UMIN;
1516  // fallthrough
1517  size_from_reg:
1518  default: // ARM64_INS_LDADD, ARM64_INS_LDADDA, ARM64_INS_LDADDAL, ARM64_INS_LDADDL, ARM64_INS_STADD, ARM64_INS_STADDL
1519  loadsz = is_wreg(addend_reg) ? 32 : 64;
1520  break;
1521  }
1522  ut32 bits = 64;
1523  RzILOpBitVector *addr = ARG(addr_op, &bits);
1524  if (!addr) {
1525  return NULL;
1526  }
1527  addend_reg = xreg_of_reg(addend_reg);
1528  RzILOpEffect *ld_eff = NULL;
1529  if (OPCOUNT() == 3) {
1530  // LDADD... instead of STADD, which does not have a dst reg
1531  if (!ISREG(1)) {
1533  return NULL;
1534  }
1535  arm64_reg dst_reg = REGID(1);
1536  dst_reg = xreg_of_reg(dst_reg);
1537  ld_eff = write_reg(dst_reg, loadsz != 64 ? UNSIGNED(64, VARL("old")) : VARL("old"));
1538  if (!ld_eff) {
1540  return NULL;
1541  }
1542  }
1543  RzILOpBitVector *res = read_reg(addend_reg);
1544  if (!res) {
1545  rz_il_op_effect_free(ld_eff);
1546  return NULL;
1547  }
1548  if (loadsz != 64) {
1549  res = UNSIGNED(loadsz, res);
1550  }
1551  switch (op) {
1552  case OP_CLR:
1553  res = LOGAND(VARL("old"), LOGNOT(res));
1554  break;
1555  case OP_EOR:
1556  res = LOGXOR(VARL("old"), res);
1557  break;
1558  case OP_SET:
1559  res = LOGOR(VARL("old"), res);
1560  break;
1561  case OP_SMAX:
1562  res = LET("r", res, ITE(SLE(VARL("old"), VARLP("r")), VARLP("r"), VARL("old")));
1563  break;
1564  case OP_SMIN:
1565  res = LET("r", res, ITE(SLE(VARL("old"), VARLP("r")), VARL("old"), VARLP("r")));
1566  break;
1567  case OP_UMAX:
1568  res = LET("r", res, ITE(ULE(VARL("old"), VARLP("r")), VARLP("r"), VARL("old")));
1569  break;
1570  case OP_UMIN:
1571  res = LET("r", res, ITE(ULE(VARL("old"), VARLP("r")), VARL("old"), VARLP("r")));
1572  break;
1573  default: // OP_ADD
1574  res = ADD(VARL("old"), res);
1575  break;
1576  }
1577  RzILOpEffect *eff = SEQ2(
1578  SETL("old", loadsz == 8 ? LOAD(addr) : LOADW(loadsz, addr)),
1579  loadsz == 8 ? STORE(DUP(addr), res) : STOREW(DUP(addr), res));
1580  if (ld_eff) {
1581  eff = SEQ2(eff, ld_eff);
1582  }
1583  return eff;
1584 }
1585 #endif
1586 
1591 static RzILOpEffect *madd(cs_insn *insn) {
1592  if (!ISREG(0)) {
1593  return NULL;
1594  }
1595  ut32 bits = REGBITS(0);
1596  if (!bits) {
1597  return NULL;
1598  }
1599  RzILOpBitVector *ma = ARG(1, &bits);
1600  RzILOpBitVector *mb = ARG(2, &bits);
1601  RzILOpBitVector *addend = ARG(3, &bits);
1602  if (!ma || !mb || !addend) {
1603  return NULL;
1604  }
1605  RzILOpBitVector *res;
1606  if (insn->id == ARM64_INS_MSUB) {
1607  res = SUB(addend, MUL(ma, mb));
1608  } else {
1609  res = ADD(MUL(ma, mb), addend);
1610  }
1611  return write_reg(REGID(0), res);
1612 }
1613 
1618 static RzILOpEffect *mul(cs_insn *insn) {
1619  if (!ISREG(0)) {
1620  return NULL;
1621  }
1622  ut32 bits = REGBITS(0);
1623  if (!bits) {
1624  return NULL;
1625  }
1626  RzILOpBitVector *ma = ARG(1, &bits);
1627  RzILOpBitVector *mb = ARG(2, &bits);
1628  if (!ma || !mb) {
1629  rz_il_op_pure_free(ma);
1630  rz_il_op_pure_free(mb);
1631  return NULL;
1632  }
1633  RzILOpBitVector *res = MUL(ma, mb);
1634  if (insn->id == ARM64_INS_MNEG) {
1635  res = NEG(res);
1636  }
1637  return write_reg(REGID(0), res);
1638 }
1639 
1640 static RzILOpEffect *movn(cs_insn *insn);
1641 
1646 static RzILOpEffect *mov(cs_insn *insn) {
1647  if (!ISREG(0)) {
1648  return NULL;
1649  }
1650  if (ISIMM(1) && IMM(1) == 0 && !strcmp(insn->mnemonic, "movn")) {
1651  // Capstone bug making 0000a012 indistinguishable from 0000a052
1652  // https://github.com/capstone-engine/capstone/issues/1857
1653  return movn(insn);
1654  }
1655  ut32 bits = REGBITS(0);
1656  if (!bits) {
1657  return NULL;
1658  }
1659  RzILOpBitVector *src = ARG(1, &bits);
1660  if (!src) {
1661  return NULL;
1662  }
1663  return write_reg(REGID(0), src);
1664 }
1665 
1670 static RzILOpEffect *movk(cs_insn *insn) {
1671  if (!ISREG(0) || !ISIMM(1)) {
1672  return NULL;
1673  }
1674  ut32 bits = 0;
1675  RzILOpBitVector *src = ARG(0, &bits);
1676  if (!src) {
1677  return NULL;
1678  }
1679  cs_arm64_op *op = &insn->detail->arm64.operands[1];
1680  ut32 shift = op->shift.type == ARM64_SFT_LSL ? op->shift.value : 0;
1681  return write_reg(REGID(0), LOGOR(LOGAND(src, UN(bits, ~(0xffffull << shift))), UN(bits, ((ut64)op->imm) << shift)));
1682 }
1683 
1688 static RzILOpEffect *movn(cs_insn *insn) {
1689  if (!ISREG(0) || !ISIMM(1)) {
1690  return NULL;
1691  }
1692  // The only case where the movn encoding should be disassembled as "movn" is
1693  // when (IsZero(imm16) && hw != '00'), according to the "alias conditions" in the reference manual.
1694  // Unfortunately, capstone v4 seems to always disassemble as movn, so we still have to implement this.
1695  cs_arm64_op *op = &insn->detail->arm64.operands[1];
1696  ut32 shift = op->shift.type == ARM64_SFT_LSL ? op->shift.value : 0;
1697  ut32 bits = REGBITS(0);
1698  if (!bits) {
1699  return NULL;
1700  }
1701  return write_reg(REGID(0), UN(bits, ~(((ut64)op->imm) << shift)));
1702 }
1703 
1708 static RzILOpEffect *msr(cs_insn *insn) {
1709  cs_arm64_op *op = &insn->detail->arm64.operands[0];
1710 #if CS_API_MAJOR > 4
1711  if (op->type != ARM64_OP_SYS || op->sys != ARM64_SYSREG_NZCV) {
1712  return NULL;
1713  }
1714 #else
1715  if (op->type != ARM64_OP_REG_MSR || op->reg != 0xda10) {
1716  return NULL;
1717  }
1718 #endif
1719  ut32 bits = 0;
1720  RzILOpBitVector *val = ARG(1, &bits);
1721  if (!val) {
1722  return NULL;
1723  }
1724  return SEQ4(
1725  SETG("nf", INV(IS_ZERO(LOGAND(val, UN(bits, 1ull << 31))))),
1726  SETG("zf", INV(IS_ZERO(LOGAND(DUP(val), UN(bits, 1ull << 30))))),
1727  SETG("cf", INV(IS_ZERO(LOGAND(DUP(val), UN(bits, 1ull << 29))))),
1728  SETG("vf", INV(IS_ZERO(LOGAND(DUP(val), UN(bits, 1ull << 28))))));
1729 }
1730 
1731 #if CS_API_MAJOR > 4
1736 static RzILOpEffect *rmif(cs_insn *insn) {
1737  if (!ISIMM(1) || !ISIMM(2)) {
1738  return NULL;
1739  }
1740  ut32 bits = 64;
1741  RzILOpBitVector *val = ARG(0, &bits);
1742  if (!val) {
1743  return NULL;
1744  }
1745  ut64 lsb = IMM(1);
1746  ut64 mask = IMM(2);
1747  RzILOpEffect *eff = NULL;
1748  const char *flags[] = { "vf", "cf", "zf", "nf" };
1749  for (size_t i = 0; i < RZ_ARRAY_SIZE(flags); i++) {
1750  if (!(mask & (1ull << i))) {
1751  continue;
1752  }
1753  if (eff) {
1754  val = DUP(val);
1755  }
1756  RzILOpEffect *set = SETG(flags[i], INV(IS_ZERO(LOGAND(val, UN(bits, 1ull << ((i + lsb) % 64))))));
1757  eff = eff ? SEQ2(set, eff) : set;
1758  }
1759  if (!eff) {
1761  }
1762  return eff ? eff : NOP();
1763 }
1764 #endif
1765 
1770 static RzILOpEffect *sbfx(cs_insn *insn) {
1771  if (!ISREG(0) || !ISIMM(2) || !ISIMM(3)) {
1772  return NULL;
1773  }
1774  ut32 bits = REGBITS(0);
1775  if (!bits) {
1776  return NULL;
1777  }
1778  RzILOpBitVector *src = ARG(1, &bits);
1779  if (!src) {
1780  return NULL;
1781  }
1782  ut64 lsb = IMM(2);
1783  ut64 width = IMM(3);
1784  RzILOpBitVector *res;
1785  if (insn->id == ARM64_INS_SBFIZ || insn->id == ARM64_INS_UBFIZ) {
1786  res = SHIFTL0(UNSIGNED(width + lsb, src), UN(6, lsb));
1787  } else {
1788  // ARM64_INS_SBFX, ARM64_INS_UBFX
1789  res = UNSIGNED(width, SHIFTR0(src, UN(6, lsb)));
1790  }
1791  bool is_signed = insn->id == ARM64_INS_SBFX || insn->id == ARM64_INS_SBFIZ;
1792  res = LET("res", res, is_signed ? SIGNED(bits, VARLP("res")) : UNSIGNED(bits, VARLP("res")));
1793  return write_reg(REGID(0), res);
1794 }
1795 
1800 static RzILOpEffect *mrs(cs_insn *insn) {
1801  if (!ISREG(0)) {
1802  return NULL;
1803  }
1804  cs_arm64_op *op = &insn->detail->arm64.operands[1];
1805 #if CS_API_MAJOR > 4
1806  if (op->type != ARM64_OP_SYS || op->sys != ARM64_SYSREG_NZCV) {
1807  return NULL;
1808  }
1809 #else
1810  if (op->type != ARM64_OP_REG_MRS || op->reg != 0xda10) {
1811  return NULL;
1812  }
1813 #endif
1814  ut32 bits = REGBITS(0);
1815  if (!bits) {
1816  return NULL;
1817  }
1818  return write_reg(REGID(0),
1819  LOGOR(ITE(VARG("nf"), UN(bits, 1ull << 31), UN(bits, 0)),
1820  LOGOR(ITE(VARG("zf"), UN(bits, 1ull << 30), UN(bits, 0)),
1821  LOGOR(ITE(VARG("cf"), UN(bits, 1ull << 29), UN(bits, 0)),
1822  ITE(VARG("vf"), UN(bits, 1ull << 28), UN(bits, 0))))));
1823 }
1824 
1829 static RzILOpEffect *mvn(cs_insn *insn) {
1830  if (!ISREG(0)) {
1831  return NULL;
1832  }
1833  ut32 bits = 0;
1834  RzILOpBitVector *val = ARG(1, &bits);
1835  if (!val) {
1836  return NULL;
1837  }
1838  RzILOpBitVector *res;
1839  switch (insn->id) {
1840  case ARM64_INS_NEG:
1841 #if CS_API_MAJOR > 3
1842  case ARM64_INS_NEGS:
1843 #endif
1844  res = NEG(val);
1845  break;
1846  case ARM64_INS_NGC:
1847 #if CS_API_MAJOR > 3
1848  case ARM64_INS_NGCS:
1849 #endif
1850  res = NEG(ADD(val, ITE(VARG("cf"), UN(bits, 0), UN(bits, 1))));
1851  break;
1852  default: // ARM64_INS_MVN
1853  res = LOGNOT(val);
1854  break;
1855  }
1856  RzILOpEffect *set = write_reg(REGID(0), res);
1857  if (!set) {
1858  return NULL;
1859  }
1860  if (insn->detail->arm64.update_flags) {
1861  return SEQ5(
1862  SETL("b", DUP(val)),
1863  set,
1864  SETG("cf", sub_carry(UN(bits, 0), VARL("b"), insn->id == ARM64_INS_NGC, bits)),
1865  SETG("vf", sub_overflow(UN(bits, 0), VARL("b"), REG(0))),
1866  update_flags_zn(REG(0)));
1867  }
1868  return set;
1869 }
1870 
1875 static RzILOpEffect *rbit(cs_insn *insn) {
1876  if (!ISREG(0)) {
1877  return NULL;
1878  }
1879  ut32 bits = 0;
1880  RzILOpBitVector *v = ARG(1, &bits);
1881  if (!v) {
1882  return NULL;
1883  }
1884  RzILOpEffect *eff = write_reg(REGID(0), VARL("r"));
1885  if (!eff) {
1886  return NULL;
1887  }
1888  return SEQ5(
1889  SETL("v", v),
1890  SETL("i", UN(6, bits)),
1891  SETL("r", UN(bits, 0x0)),
1892  REPEAT(INV(IS_ZERO(VARL("v"))),
1893  SEQ3(
1894  SETL("i", SUB(VARL("i"), UN(6, 1))),
1895  SETL("r", LOGOR(VARL("r"), ITE(LSB(VARL("v")), SHIFTL0(UN(bits, 1), VARL("i")), UN(bits, 0)))),
1896  SETL("v", SHIFTR0(VARL("v"), UN(6, 1))))),
1897  eff);
1898 }
1899 
1904 static RzILOpEffect *rev(cs_insn *insn) {
1905  if (!ISREG(0) || !ISREG(1)) {
1906  return NULL;
1907  }
1908  ut32 dst_bits = REGBITS(0);
1909  if (!dst_bits) {
1910  return NULL;
1911  }
1912  arm64_reg src_reg = xreg_of_reg(REGID(1));
1913  ut32 container_bits = dst_bits;
1914  if (insn->id == ARM64_INS_REV32) {
1915  container_bits = 32;
1916  } else if (insn->id == ARM64_INS_REV16) {
1917  container_bits = 16;
1918  }
1919  RzILOpBitVector *src = read_reg(src_reg);
1920  if (!src) {
1921  return NULL;
1922  }
1923  RzILOpBitVector *res;
1924  if (container_bits == 16) {
1925  res = APPEND(
1926  APPEND(
1927  UNSIGNED(8, SHIFTR0(src, UN(6, 0x10))),
1928  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x18)))),
1929  APPEND(
1930  UNSIGNED(8, DUP(src)),
1931  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x8)))));
1932  } else {
1933  res = APPEND(
1934  APPEND(
1935  UNSIGNED(8, src),
1936  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x8)))),
1937  APPEND(
1938  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x10))),
1939  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x18)))));
1940  }
1941  if (dst_bits == 64) {
1942  if (container_bits == 16) {
1943  res = APPEND(
1944  APPEND(
1945  APPEND(
1946  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x30))),
1947  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x38)))),
1948  APPEND(
1949  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x20))),
1950  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x28))))),
1951  res);
1952  } else {
1953  RzILOpBitVector *high = APPEND(
1954  APPEND(
1955  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x20))),
1956  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x28)))),
1957  APPEND(
1958  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x30))),
1959  UNSIGNED(8, SHIFTR0(DUP(src), UN(6, 0x38)))));
1960  res = container_bits == 32 ? APPEND(high, res) : APPEND(res, high);
1961  }
1962  }
1963  return write_reg(REGID(0), res);
1964 }
1965 
1970 static RzILOpEffect *sdiv(cs_insn *insn) {
1971  if (!ISREG(0)) {
1972  return NULL;
1973  }
1974  ut32 bits = REGBITS(0);
1975  if (!bits) {
1976  return NULL;
1977  }
1978  RzILOpBitVector *a = ARG(1, &bits);
1979  RzILOpBitVector *b = ARG(2, &bits);
1980  if (!a || !b) {
1983  return NULL;
1984  }
1985  return write_reg(REGID(0),
1986  ITE(EQ(b, UN(bits, 0)), UN(bits, 0),
1987  ITE(AND(EQ(a, UN(bits, 1ull << (bits - 1))), EQ(DUP(b), UN(bits, -1))),
1988  UN(bits, 1ull << (bits - 1)),
1989  SDIV(DUP(a), DUP(b)))));
1990 }
1991 
1996 static RzILOpEffect *udiv(cs_insn *insn) {
1997  if (!ISREG(0)) {
1998  return NULL;
1999  }
2000  ut32 bits = REGBITS(0);
2001  if (!bits) {
2002  return NULL;
2003  }
2004  RzILOpBitVector *a = ARG(1, &bits);
2005  RzILOpBitVector *b = ARG(2, &bits);
2006  if (!a || !b) {
2009  return NULL;
2010  }
2011  return write_reg(REGID(0),
2012  ITE(EQ(b, UN(bits, 0)), UN(bits, 0), DIV(a, DUP(b))));
2013 }
2014 
2015 #if CS_API_MAJOR > 4
2020 static RzILOpEffect *setf(cs_insn *insn) {
2021  if (!ISREG(0)) {
2022  return NULL;
2023  }
2025  if (!val) {
2026  return NULL;
2027  }
2028  ut32 bits = insn->id == ARM64_INS_SETF16 ? 16 : 8;
2029  return SEQ2(
2030  SETG("vf", XOR(MSB(UNSIGNED(bits + 1, val)), MSB(UNSIGNED(bits, DUP(val))))),
2032 }
2033 #endif
2034 
2039 static RzILOpEffect *smaddl(cs_insn *insn) {
2040  if (!ISREG(0) || REGBITS(0) != 64) {
2041  return NULL;
2042  }
2043  ut32 bits = 32;
2044  RzILOpBitVector *x = ARG(1, &bits);
2045  RzILOpBitVector *y = ARG(2, &bits);
2046  bits = 64;
2047  RzILOpBitVector *addend = ARG(3, &bits);
2048  if (!x || !y || !addend) {
2050  rz_il_op_pure_free(y);
2051  rz_il_op_pure_free(addend);
2052  return NULL;
2053  }
2054  bool is_signed = insn->id == ARM64_INS_SMADDL || insn->id == ARM64_INS_SMSUBL;
2055  RzILOpBitVector *res = MUL(is_signed ? SIGNED(64, x) : UNSIGNED(64, x), is_signed ? SIGNED(64, y) : UNSIGNED(64, y));
2056  if (insn->id == ARM64_INS_SMSUBL || insn->id == ARM64_INS_UMSUBL) {
2057  res = SUB(addend, res);
2058  } else {
2059  res = ADD(addend, res);
2060  }
2061  return write_reg(REGID(0), res);
2062 }
2063 
2068 static RzILOpEffect *smull(cs_insn *insn) {
2069  if (!ISREG(0) || REGBITS(0) != 64) {
2070  return NULL;
2071  }
2072  ut32 bits = 32;
2073  RzILOpBitVector *x = ARG(1, &bits);
2074  RzILOpBitVector *y = ARG(2, &bits);
2075  if (!x || !y) {
2077  rz_il_op_pure_free(y);
2078  return NULL;
2079  }
2080  bool is_signed = insn->id == ARM64_INS_SMULL || insn->id == ARM64_INS_SMNEGL;
2081  RzILOpBitVector *res = MUL(is_signed ? SIGNED(64, x) : UNSIGNED(64, x), is_signed ? SIGNED(64, y) : UNSIGNED(64, y));
2082  if (insn->id == ARM64_INS_SMNEGL || insn->id == ARM64_INS_UMNEGL) {
2083  res = NEG(res);
2084  }
2085  return write_reg(REGID(0), res);
2086 }
2087 
2092 static RzILOpEffect *smulh(cs_insn *insn) {
2093  if (!ISREG(0) || REGBITS(0) != 64) {
2094  return NULL;
2095  }
2096  ut32 bits = 64;
2097  RzILOpBitVector *x = ARG(1, &bits);
2098  RzILOpBitVector *y = ARG(2, &bits);
2099  if (!x || !y) {
2101  rz_il_op_pure_free(y);
2102  return NULL;
2103  }
2104  bool is_signed = insn->id == ARM64_INS_SMULH;
2105  RzILOpBitVector *res = MUL(is_signed ? SIGNED(128, x) : UNSIGNED(128, x), is_signed ? SIGNED(128, y) : UNSIGNED(128, y));
2106  return write_reg(REGID(0), UNSIGNED(64, SHIFTR0(res, UN(7, 64))));
2107 }
2108 
2109 #if CS_API_MAJOR > 4
2116 static RzILOpEffect *swp(cs_insn *insn) {
2117  if (!ISREG(0) || !ISREG(1)) {
2118  return NULL;
2119  }
2120  ut32 bits;
2121  switch (insn->id) {
2122  case ARM64_INS_SWPB:
2123  case ARM64_INS_SWPAB:
2124  case ARM64_INS_SWPALB:
2125  case ARM64_INS_SWPLB:
2126  bits = 8;
2127  break;
2128  case ARM64_INS_SWPH:
2129  case ARM64_INS_SWPAH:
2130  case ARM64_INS_SWPALH:
2131  case ARM64_INS_SWPLH:
2132  bits = 16;
2133  break;
2134  default: // ARM64_INS_SWP, ARM64_INS_SWPA, ARM64_INS_SWPAL, ARM64_INS_SWPL:
2135  bits = REGBITS(0);
2136  if (!bits) {
2137  return NULL;
2138  }
2139  break;
2140  }
2141  ut32 addr_bits = 64;
2142  RzILOpBitVector *addr = ARG(2, &addr_bits);
2143  if (!addr) {
2144  return NULL;
2145  }
2146  RzILOpBitVector *store_val = ARG(0, &bits);
2147  if (!addr || !store_val) {
2149  rz_il_op_pure_free(store_val);
2150  return NULL;
2151  }
2152  RzILOpEffect *store_eff = bits == 8 ? STORE(addr, store_val) : STOREW(addr, store_val);
2153  arm64_reg ret_reg = xreg_of_reg(REGID(1));
2154  if (ret_reg == ARM64_REG_XZR) {
2155  return store_eff;
2156  }
2157  RzILOpEffect *ret_eff = write_reg(ret_reg, bits != 64 ? UNSIGNED(64, VARL("ret")) : VARL("ret"));
2158  if (!ret_eff) {
2159  rz_il_op_effect_free(store_eff);
2160  return NULL;
2161  }
2162  return SEQ3(
2163  SETL("ret", bits == 8 ? LOAD(DUP(addr)) : LOADW(bits, DUP(addr))),
2164  store_eff,
2165  ret_eff);
2166 }
2167 #endif
2168 
2173 static RzILOpEffect *sxt(cs_insn *insn) {
2174  if (!ISREG(0) || !REGBITS(0)) {
2175  return NULL;
2176  }
2177  ut32 bits;
2178  bool is_signed = true;
2179  switch (insn->id) {
2180  case ARM64_INS_UXTB:
2181  is_signed = false;
2182  // fallthrough
2183  case ARM64_INS_SXTB:
2184  bits = 8;
2185  break;
2186  case ARM64_INS_UXTH:
2187  is_signed = false;
2188  // fallthrough
2189  case ARM64_INS_SXTH:
2190  bits = 16;
2191  break;
2192  default: // ARM64_INS_SXTW
2193  bits = 32;
2194  break;
2195  }
2196  RzILOpBitVector *src = ARG(1, &bits);
2197  if (!src) {
2198  return NULL;
2199  }
2200  return write_reg(REGID(0), is_signed ? SIGNED(REGBITS(0), src) : UNSIGNED(REGBITS(0), src));
2201 }
2202 
2207 static RzILOpEffect *tbz(cs_insn *insn) {
2208  if (!ISIMM(1)) {
2209  return NULL;
2210  }
2211  ut32 bits = 64;
2212  RzILOpBitVector *src = ARG(0, &bits);
2213  RzILOpBitVector *tgt = ARG(2, &bits);
2214  if (!src || !tgt) {
2216  rz_il_op_pure_free(tgt);
2217  return NULL;
2218  }
2219  RzILOpBool *c = LSB(SHIFTR0(src, UN(6, IMM(1))));
2220  return insn->id == ARM64_INS_TBNZ
2221  ? BRANCH(c, JMP(tgt), NULL)
2222  : BRANCH(c, NULL, JMP(tgt));
2223 }
2224 
2229 static RzILOpEffect *tst(cs_insn *insn) {
2230  ut32 bits = 0;
2231  RzILOpBitVector *a = ARG(0, &bits);
2232  RzILOpBitVector *b = ARG(1, &bits);
2233  if (!a || !b) {
2236  return NULL;
2237  }
2238  return update_flags_zn00(LOGAND(a, b));
2239 }
2240 
2317  switch (insn->id) {
2318  case ARM64_INS_NOP:
2319  case ARM64_INS_HINT:
2320  case ARM64_INS_PRFM:
2321  case ARM64_INS_PRFUM:
2322  case ARM64_INS_SEV:
2323  case ARM64_INS_SEVL:
2324  case ARM64_INS_WFE:
2325  case ARM64_INS_WFI:
2326  case ARM64_INS_YIELD:
2327  return NOP();
2328  case ARM64_INS_ADD:
2329  case ARM64_INS_ADC:
2330  case ARM64_INS_SUB:
2331  case ARM64_INS_SBC:
2332 #if CS_API_MAJOR > 4
2333  case ARM64_INS_ADDS:
2334  case ARM64_INS_SUBS:
2335  case ARM64_INS_ADCS:
2336  case ARM64_INS_SBCS:
2337 #endif
2338  return add_sub(insn);
2339  case ARM64_INS_ADR:
2340  case ARM64_INS_ADRP:
2341  return adr(insn);
2342  case ARM64_INS_AND:
2343 #if CS_API_MAJOR > 4
2344  case ARM64_INS_ANDS:
2345 #endif
2346  case ARM64_INS_EOR:
2347  case ARM64_INS_EON:
2348  case ARM64_INS_ORN:
2349  case ARM64_INS_ORR:
2350  return bitwise(insn);
2351  case ARM64_INS_ASR:
2352  case ARM64_INS_LSL:
2353  case ARM64_INS_LSR:
2354  case ARM64_INS_ROR:
2355  return shift(insn);
2356  case ARM64_INS_B:
2357  case ARM64_INS_BR:
2358  case ARM64_INS_RET:
2359 #if CS_API_MAJOR > 4
2360  case ARM64_INS_BRAA:
2361  case ARM64_INS_BRAAZ:
2362  case ARM64_INS_BRAB:
2363  case ARM64_INS_BRABZ:
2364  case ARM64_INS_RETAA:
2365  case ARM64_INS_RETAB:
2366 #endif
2367  return branch(insn);
2368  case ARM64_INS_BL:
2369  case ARM64_INS_BLR:
2370 #if CS_API_MAJOR > 4
2371  case ARM64_INS_BLRAA:
2372  case ARM64_INS_BLRAAZ:
2373  case ARM64_INS_BLRAB:
2374  case ARM64_INS_BLRABZ:
2375 #endif
2376  return bl(insn);
2377  case ARM64_INS_BFM:
2378  case ARM64_INS_BFI:
2379  case ARM64_INS_BFXIL:
2380  return bfm(insn);
2381  case ARM64_INS_BIC:
2382 #if CS_API_MAJOR > 4
2383  case ARM64_INS_BICS:
2384 #endif
2385  return bic(insn);
2386 #if CS_API_MAJOR > 4
2387  case ARM64_INS_CAS:
2388  case ARM64_INS_CASA:
2389  case ARM64_INS_CASAL:
2390  case ARM64_INS_CASL:
2391  case ARM64_INS_CASB:
2392  case ARM64_INS_CASAB:
2393  case ARM64_INS_CASALB:
2394  case ARM64_INS_CASLB:
2395  case ARM64_INS_CASH:
2396  case ARM64_INS_CASAH:
2397  case ARM64_INS_CASALH:
2398  case ARM64_INS_CASLH:
2399  return cas(insn);
2400  case ARM64_INS_CASP:
2401  case ARM64_INS_CASPA:
2402  case ARM64_INS_CASPAL:
2403  case ARM64_INS_CASPL:
2404  return casp(insn);
2405 #endif
2406  case ARM64_INS_CBZ:
2407  case ARM64_INS_CBNZ:
2408  return cbz(insn);
2409  case ARM64_INS_CMP:
2410  case ARM64_INS_CMN:
2411  case ARM64_INS_CCMP:
2412  case ARM64_INS_CCMN:
2413  return cmp(insn);
2414 #if CS_API_MAJOR > 4
2415  case ARM64_INS_CFINV:
2416  return SETG("cf", INV(VARG("cf")));
2417 #endif
2418  case ARM64_INS_CINC:
2419  case ARM64_INS_CSINC:
2420  case ARM64_INS_CINV:
2421  case ARM64_INS_CSINV:
2422  case ARM64_INS_CNEG:
2423  case ARM64_INS_CSNEG:
2424  case ARM64_INS_CSEL:
2425  return csinc(insn);
2426  case ARM64_INS_CSET:
2427  case ARM64_INS_CSETM:
2428  return cset(insn);
2429  case ARM64_INS_CLS:
2430  return cls(insn);
2431  case ARM64_INS_CLZ:
2432  return clz(insn);
2433  case ARM64_INS_EXTR:
2434  return extr(insn);
2435  case ARM64_INS_HVC:
2436  return hvc(insn);
2437  case ARM64_INS_SVC:
2438  return svc(insn);
2439  case ARM64_INS_LDR:
2440  case ARM64_INS_LDRB:
2441  case ARM64_INS_LDRH:
2442  case ARM64_INS_LDUR:
2443  case ARM64_INS_LDURB:
2444  case ARM64_INS_LDURH:
2445  case ARM64_INS_LDRSW:
2446  case ARM64_INS_LDRSB:
2447  case ARM64_INS_LDRSH:
2448  case ARM64_INS_LDURSW:
2449  case ARM64_INS_LDURSB:
2450  case ARM64_INS_LDURSH:
2451  case ARM64_INS_LDAR:
2452  case ARM64_INS_LDARB:
2453  case ARM64_INS_LDARH:
2454  case ARM64_INS_LDAXP:
2455  case ARM64_INS_LDXP:
2456  case ARM64_INS_LDAXR:
2457  case ARM64_INS_LDAXRB:
2458  case ARM64_INS_LDAXRH:
2459  case ARM64_INS_LDP:
2460  case ARM64_INS_LDNP:
2461  case ARM64_INS_LDPSW:
2462  case ARM64_INS_LDTR:
2463  case ARM64_INS_LDTRB:
2464  case ARM64_INS_LDTRH:
2465  case ARM64_INS_LDTRSW:
2466  case ARM64_INS_LDTRSB:
2467  case ARM64_INS_LDTRSH:
2468  case ARM64_INS_LDXR:
2469  case ARM64_INS_LDXRB:
2470  case ARM64_INS_LDXRH:
2471 #if CS_API_MAJOR > 4
2472  case ARM64_INS_LDAPR:
2473  case ARM64_INS_LDAPRB:
2474  case ARM64_INS_LDAPRH:
2475  case ARM64_INS_LDAPUR:
2476  case ARM64_INS_LDAPURB:
2477  case ARM64_INS_LDAPURH:
2478  case ARM64_INS_LDAPURSB:
2479  case ARM64_INS_LDAPURSH:
2480  case ARM64_INS_LDAPURSW:
2481  case ARM64_INS_LDLAR:
2482  case ARM64_INS_LDLARB:
2483  case ARM64_INS_LDLARH:
2484  case ARM64_INS_LDRAA:
2485  case ARM64_INS_LDRAB:
2486 #endif
2487  return ldr(insn);
2488 #if CS_API_MAJOR > 4
2489  case ARM64_INS_LDADD:
2490  case ARM64_INS_LDADDA:
2491  case ARM64_INS_LDADDAL:
2492  case ARM64_INS_LDADDL:
2493  case ARM64_INS_LDADDB:
2494  case ARM64_INS_LDADDAB:
2495  case ARM64_INS_LDADDALB:
2496  case ARM64_INS_LDADDLB:
2497  case ARM64_INS_LDADDH:
2498  case ARM64_INS_LDADDAH:
2499  case ARM64_INS_LDADDALH:
2500  case ARM64_INS_LDADDLH:
2501  case ARM64_INS_STADD:
2502  case ARM64_INS_STADDL:
2503  case ARM64_INS_STADDB:
2504  case ARM64_INS_STADDLB:
2505  case ARM64_INS_STADDH:
2506  case ARM64_INS_STADDLH:
2507  case ARM64_INS_LDCLRB:
2508  case ARM64_INS_LDCLRAB:
2509  case ARM64_INS_LDCLRALB:
2510  case ARM64_INS_LDCLRLB:
2511  case ARM64_INS_LDCLRH:
2512  case ARM64_INS_LDCLRAH:
2513  case ARM64_INS_LDCLRALH:
2514  case ARM64_INS_LDCLRLH:
2515  case ARM64_INS_LDCLR:
2516  case ARM64_INS_LDCLRA:
2517  case ARM64_INS_LDCLRAL:
2518  case ARM64_INS_LDCLRL:
2519  case ARM64_INS_STCLR:
2520  case ARM64_INS_STCLRL:
2521  case ARM64_INS_STCLRB:
2522  case ARM64_INS_STCLRLB:
2523  case ARM64_INS_STCLRH:
2524  case ARM64_INS_STCLRLH:
2525  case ARM64_INS_LDEORB:
2526  case ARM64_INS_LDEORAB:
2527  case ARM64_INS_LDEORALB:
2528  case ARM64_INS_LDEORLB:
2529  case ARM64_INS_LDEORH:
2530  case ARM64_INS_LDEORAH:
2531  case ARM64_INS_LDEORALH:
2532  case ARM64_INS_LDEORLH:
2533  case ARM64_INS_LDEOR:
2534  case ARM64_INS_LDEORA:
2535  case ARM64_INS_LDEORAL:
2536  case ARM64_INS_LDEORL:
2537  case ARM64_INS_STEOR:
2538  case ARM64_INS_STEORL:
2539  case ARM64_INS_STEORB:
2540  case ARM64_INS_STEORLB:
2541  case ARM64_INS_STEORH:
2542  case ARM64_INS_STEORLH:
2543  case ARM64_INS_LDSETB:
2544  case ARM64_INS_LDSETAB:
2545  case ARM64_INS_LDSETALB:
2546  case ARM64_INS_LDSETLB:
2547  case ARM64_INS_LDSETH:
2548  case ARM64_INS_LDSETAH:
2549  case ARM64_INS_LDSETALH:
2550  case ARM64_INS_LDSETLH:
2551  case ARM64_INS_LDSET:
2552  case ARM64_INS_LDSETA:
2553  case ARM64_INS_LDSETAL:
2554  case ARM64_INS_LDSETL:
2555  case ARM64_INS_STSET:
2556  case ARM64_INS_STSETL:
2557  case ARM64_INS_STSETB:
2558  case ARM64_INS_STSETLB:
2559  case ARM64_INS_STSETH:
2560  case ARM64_INS_STSETLH:
2561  case ARM64_INS_LDSMAXB:
2562  case ARM64_INS_LDSMAXAB:
2563  case ARM64_INS_LDSMAXALB:
2564  case ARM64_INS_LDSMAXLB:
2565  case ARM64_INS_LDSMAXH:
2566  case ARM64_INS_LDSMAXAH:
2567  case ARM64_INS_LDSMAXALH:
2568  case ARM64_INS_LDSMAXLH:
2569  case ARM64_INS_LDSMAX:
2570  case ARM64_INS_LDSMAXA:
2571  case ARM64_INS_LDSMAXAL:
2572  case ARM64_INS_LDSMAXL:
2573  case ARM64_INS_STSMAX:
2574  case ARM64_INS_STSMAXL:
2575  case ARM64_INS_STSMAXB:
2576  case ARM64_INS_STSMAXLB:
2577  case ARM64_INS_STSMAXH:
2578  case ARM64_INS_STSMAXLH:
2579  case ARM64_INS_LDSMINB:
2580  case ARM64_INS_LDSMINAB:
2581  case ARM64_INS_LDSMINALB:
2582  case ARM64_INS_LDSMINLB:
2583  case ARM64_INS_LDSMINH:
2584  case ARM64_INS_LDSMINAH:
2585  case ARM64_INS_LDSMINALH:
2586  case ARM64_INS_LDSMINLH:
2587  case ARM64_INS_LDSMIN:
2588  case ARM64_INS_LDSMINA:
2589  case ARM64_INS_LDSMINAL:
2590  case ARM64_INS_LDSMINL:
2591  case ARM64_INS_STSMIN:
2592  case ARM64_INS_STSMINL:
2593  case ARM64_INS_STSMINB:
2594  case ARM64_INS_STSMINLB:
2595  case ARM64_INS_STSMINH:
2596  case ARM64_INS_STSMINLH:
2597  case ARM64_INS_LDUMAXB:
2598  case ARM64_INS_LDUMAXAB:
2599  case ARM64_INS_LDUMAXALB:
2600  case ARM64_INS_LDUMAXLB:
2601  case ARM64_INS_LDUMAXH:
2602  case ARM64_INS_LDUMAXAH:
2603  case ARM64_INS_LDUMAXALH:
2604  case ARM64_INS_LDUMAXLH:
2605  case ARM64_INS_LDUMAX:
2606  case ARM64_INS_LDUMAXA:
2607  case ARM64_INS_LDUMAXAL:
2608  case ARM64_INS_LDUMAXL:
2609  case ARM64_INS_STUMAX:
2610  case ARM64_INS_STUMAXL:
2611  case ARM64_INS_STUMAXB:
2612  case ARM64_INS_STUMAXLB:
2613  case ARM64_INS_STUMAXH:
2614  case ARM64_INS_STUMAXLH:
2615  case ARM64_INS_LDUMINB:
2616  case ARM64_INS_LDUMINAB:
2617  case ARM64_INS_LDUMINALB:
2618  case ARM64_INS_LDUMINLB:
2619  case ARM64_INS_LDUMINH:
2620  case ARM64_INS_LDUMINAH:
2621  case ARM64_INS_LDUMINALH:
2622  case ARM64_INS_LDUMINLH:
2623  case ARM64_INS_LDUMIN:
2624  case ARM64_INS_LDUMINA:
2625  case ARM64_INS_LDUMINAL:
2626  case ARM64_INS_LDUMINL:
2627  case ARM64_INS_STUMIN:
2628  case ARM64_INS_STUMINL:
2629  case ARM64_INS_STUMINB:
2630  case ARM64_INS_STUMINLB:
2631  case ARM64_INS_STUMINH:
2632  case ARM64_INS_STUMINLH:
2633  return ldadd(insn);
2634 #endif
2635  case ARM64_INS_MADD:
2636  case ARM64_INS_MSUB:
2637  return madd(insn);
2638  case ARM64_INS_MUL:
2639  case ARM64_INS_MNEG:
2640  return mul(insn);
2641  case ARM64_INS_MOV:
2642  case ARM64_INS_MOVZ:
2643  return mov(insn);
2644  case ARM64_INS_MOVK:
2645  return movk(insn);
2646  case ARM64_INS_MOVN:
2647  return movn(insn);
2648  case ARM64_INS_MSR:
2649  return msr(insn);
2650  case ARM64_INS_MRS:
2651  return mrs(insn);
2652  case ARM64_INS_MVN:
2653  case ARM64_INS_NEG:
2654  case ARM64_INS_NGC:
2655 #if CS_API_MAJOR > 3
2656  case ARM64_INS_NEGS:
2657  case ARM64_INS_NGCS:
2658 #endif
2659  return mvn(insn);
2660  case ARM64_INS_RBIT:
2661  return rbit(insn);
2662  case ARM64_INS_REV:
2663  case ARM64_INS_REV32:
2664  case ARM64_INS_REV16:
2665  return rev(insn);
2666 #if CS_API_MAJOR > 4
2667  case ARM64_INS_RMIF:
2668  return rmif(insn);
2669 #endif
2670  case ARM64_INS_SBFIZ:
2671  case ARM64_INS_SBFX:
2672  case ARM64_INS_UBFIZ:
2673  case ARM64_INS_UBFX:
2674  return sbfx(insn);
2675  case ARM64_INS_SDIV:
2676  return sdiv(insn);
2677 #if CS_API_MAJOR > 4
2678  case ARM64_INS_SETF8:
2679  case ARM64_INS_SETF16:
2680  return setf(insn);
2681 #endif
2682  case ARM64_INS_SMADDL:
2683  case ARM64_INS_SMSUBL:
2684  case ARM64_INS_UMADDL:
2685  case ARM64_INS_UMSUBL:
2686  return smaddl(insn);
2687  case ARM64_INS_SMULL:
2688  case ARM64_INS_SMNEGL:
2689  case ARM64_INS_UMULL:
2690  case ARM64_INS_UMNEGL:
2691  return smull(insn);
2692  case ARM64_INS_SMULH:
2693  case ARM64_INS_UMULH:
2694  return smulh(insn);
2695  case ARM64_INS_STR:
2696  case ARM64_INS_STUR:
2697  case ARM64_INS_STRB:
2698  case ARM64_INS_STURB:
2699  case ARM64_INS_STRH:
2700  case ARM64_INS_STURH:
2701  case ARM64_INS_STLR:
2702  case ARM64_INS_STLRB:
2703  case ARM64_INS_STLRH:
2704  case ARM64_INS_STP:
2705  case ARM64_INS_STNP:
2706  case ARM64_INS_STXR:
2707  case ARM64_INS_STXRB:
2708  case ARM64_INS_STXRH:
2709  case ARM64_INS_STXP:
2710  case ARM64_INS_STLXR:
2711  case ARM64_INS_STLXRB:
2712  case ARM64_INS_STLXRH:
2713  case ARM64_INS_STLXP:
2714  case ARM64_INS_STTR:
2715  case ARM64_INS_STTRB:
2716  case ARM64_INS_STTRH:
2717 #if CS_API_MAJOR > 4
2718  case ARM64_INS_STLLR:
2719  case ARM64_INS_STLLRB:
2720  case ARM64_INS_STLLRH:
2721  case ARM64_INS_STLUR:
2722  case ARM64_INS_STLURB:
2723  case ARM64_INS_STLURH:
2724 #endif
2725  return str(insn);
2726 #if CS_API_MAJOR > 4
2727  case ARM64_INS_SWP:
2728  case ARM64_INS_SWPA:
2729  case ARM64_INS_SWPAL:
2730  case ARM64_INS_SWPL:
2731  case ARM64_INS_SWPB:
2732  case ARM64_INS_SWPAB:
2733  case ARM64_INS_SWPALB:
2734  case ARM64_INS_SWPLB:
2735  case ARM64_INS_SWPH:
2736  case ARM64_INS_SWPAH:
2737  case ARM64_INS_SWPALH:
2738  case ARM64_INS_SWPLH:
2739  return swp(insn);
2740 #endif
2741  case ARM64_INS_SXTB:
2742  case ARM64_INS_SXTH:
2743  case ARM64_INS_SXTW:
2744  case ARM64_INS_UXTB:
2745  case ARM64_INS_UXTH:
2746  return sxt(insn);
2747  case ARM64_INS_TBNZ:
2748  case ARM64_INS_TBZ:
2749  return tbz(insn);
2750  case ARM64_INS_TST:
2751  return tst(insn);
2752  case ARM64_INS_UDIV:
2753  return udiv(insn);
2754  default:
2755  break;
2756  }
2757  return NULL;
2758 }
2759 
2760 #include <rz_il/rz_il_opbuilder_end.h>
2761 
2763  RzAnalysisILConfig *r = rz_analysis_il_config_new(64, big_endian, 64);
2764  r->reg_bindings = regs_bound;
2766  svc_label->hook = label_svc;
2767  rz_analysis_il_config_add_label(r, svc_label);
2769  hvc_label->hook = label_hvc;
2770  rz_analysis_il_config_add_label(r, hvc_label);
2771  return r;
2772 }
@ OP_CLR
Definition: 8051_ops.h:47
@ OP_ADD
Definition: 8051_ops.h:42
#define mask()
#define imm
RZ_API void rz_analysis_il_config_add_label(RZ_NONNULL RzAnalysisILConfig *cfg, RZ_NONNULL RZ_OWN RzILEffectLabel *label)
Definition: analysis_il.c:77
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
static void update_flags(RzAnalysisOp *op, int flags)
Definition: analysis_v810.c:20
#define RZ_IPI
Definition: analysis_wasm.c:11
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
static const char ext[]
Definition: apprentice.c:1981
#define BRANCH
static RzILOpEffect * msr(cs_insn *insn)
Definition: arm_il64.c:1708
#define ARG(n, bits)
Definition: arm_il64.c:413
static RzILOpEffect * movk(cs_insn *insn)
Definition: arm_il64.c:1670
#define ISIMM
Definition: arm_il64.c:13
static RzILOpEffect * cbz(cs_insn *insn)
Definition: arm_il64.c:789
static RzILOpEffect * update_flags_zn00(RzILOpBitVector *v)
Definition: arm_il64.c:431
static RzILOpEffect * writeback(cs_insn *insn, size_t addr_op, RZ_BORROW RzILOpBitVector *addr)
Definition: arm_il64.c:1024
static RzILOpEffect * smull(cs_insn *insn)
Definition: arm_il64.c:2068
static arm64_reg xreg(ut8 idx)
Definition: arm_il64.c:73
static RzILOpBitVector * adjust_unsigned(ut32 bits, RZ_OWN RzILOpBitVector *v)
Definition: arm_il64.c:260
static RzILOpEffect * bl(cs_insn *insn)
Definition: arm_il64.c:618
static RzILOpBitVector * apply_shift(arm64_shifter sft, ut32 dist, RZ_OWN RzILOpBitVector *v)
Definition: arm_il64.c:314
static RzILOpEffect * extr(cs_insn *insn)
Definition: arm_il64.c:962
static ut8 wreg_idx(arm64_reg reg)
Definition: arm_il64.c:157
static RzILOpEffect * tst(cs_insn *insn)
Definition: arm_il64.c:2229
static RzILOpEffect * bfm(cs_insn *insn)
Definition: arm_il64.c:633
static RzILOpEffect * write_reg(arm64_reg reg, RZ_OWN RZ_NONNULL RzILOpBitVector *v)
Definition: arm_il64.c:338
#define ISREG
Definition: arm_il64.c:14
static RzILOpEffect * sxt(cs_insn *insn)
Definition: arm_il64.c:2173
static RzILOpBitVector * extend(ut32 dst_bits, arm64_extender ext, RZ_OWN RzILOpBitVector *v, ut32 v_bits)
Definition: arm_il64.c:270
static RzILOpEffect * load_effect(ut32 bits, bool is_signed, arm64_reg dst_reg, RZ_OWN RzILOpBitVector *addr)
Definition: arm_il64.c:1007
static RzILOpEffect * str(cs_insn *insn)
Definition: arm_il64.c:1169
#define MEMBASEID(x)
Definition: arm_il64.c:332
#define MEMDISP(x)
Definition: arm_il64.c:18
static RzILOpEffect * mul(cs_insn *insn)
Definition: arm_il64.c:1618
static arm64_reg xreg_of_reg(arm64_reg reg)
Definition: arm_il64.c:175
static bool is_wreg(arm64_reg reg)
Definition: arm_il64.c:171
static RzILOpEffect * madd(cs_insn *insn)
Definition: arm_il64.c:1591
static RzILOpEffect * sdiv(cs_insn *insn)
Definition: arm_il64.c:1970
static RzILOpBitVector * arg(cs_insn *insn, size_t n, ut32 *bits_inout)
Definition: arm_il64.c:367
static RzILOpEffect * ldr(cs_insn *insn)
Definition: arm_il64.c:1058
static RzILOpEffect * cset(cs_insn *insn)
Definition: arm_il64.c:899
static RzILOpEffect * sbfx(cs_insn *insn)
Definition: arm_il64.c:1770
#define ISMEM
Definition: arm_il64.c:15
static void label_hvc(RzILVM *vm, RzILOpEffect *op)
Definition: arm_il64.c:1003
static RzILOpEffect * smulh(cs_insn *insn)
Definition: arm_il64.c:2092
static const char * reg_var_name(arm64_reg reg)
Definition: arm_il64.c:185
static RzILOpEffect * smaddl(cs_insn *insn)
Definition: arm_il64.c:2039
#define OPCOUNT
Definition: arm_il64.c:16
static RzILOpEffect * tbz(cs_insn *insn)
Definition: arm_il64.c:2207
static RzILOpEffect * udiv(cs_insn *insn)
Definition: arm_il64.c:1996
RZ_IPI RzAnalysisILConfig * rz_arm_cs_64_il_config(bool big_endian)
Definition: arm_il64.c:2762
static RzILOpEffect * rev(cs_insn *insn)
Definition: arm_il64.c:1904
static RzILOpEffect * bic(cs_insn *insn)
Definition: arm_il64.c:664
static void label_svc(RzILVM *vm, RzILOpEffect *op)
Definition: arm_il64.c:991
static ut32 reg_bits(arm64_reg reg)
Definition: arm_il64.c:227
static RzILOpEffect * hvc(cs_insn *insn)
Definition: arm_il64.c:999
static RzILOpEffect * adr(cs_insn *insn)
Definition: arm_il64.c:497
static RzILOpEffect * cls(cs_insn *insn)
Definition: arm_il64.c:915
static RzILOpBool * cond(arm64_cc c)
Definition: arm_il64.c:38
static RzILOpBitVector * read_reg(arm64_reg reg)
Definition: arm_il64.c:240
static RzILOpEffect * rbit(cs_insn *insn)
Definition: arm_il64.c:1875
RZ_IPI RzILOpEffect * rz_arm_cs_64_il(csh *handle, cs_insn *insn)
Definition: arm_il64.c:2316
static RzILOpEffect * shift(cs_insn *insn)
Definition: arm_il64.c:555
static RzILOpEffect * mrs(cs_insn *insn)
Definition: arm_il64.c:1800
static RzILOpEffect * csinc(cs_insn *insn)
Definition: arm_il64.c:840
static RzILOpEffect * add_sub(cs_insn *insn)
Definition: arm_il64.c:442
static RzILOpEffect * clz(cs_insn *insn)
Definition: arm_il64.c:939
static RzILOpEffect * bitwise(cs_insn *insn)
Definition: arm_il64.c:508
static RzILOpBitVector * arg_mem(RzILOpBitVector *base_plus_disp, cs_arm64_op *op)
Definition: arm_il64.c:351
static bool is_xreg(arm64_reg reg)
Definition: arm_il64.c:116
static RzILOpEffect * svc(cs_insn *insn)
Definition: arm_il64.c:987
static RzILOpEffect * cmp(cs_insn *insn)
Definition: arm_il64.c:805
#define REGID
Definition: arm_il64.c:12
static RzILOpEffect * movn(cs_insn *insn)
Definition: arm_il64.c:1688
static RzILOpEffect * branch(cs_insn *insn)
Definition: arm_il64.c:595
static RzILOpEffect * mvn(cs_insn *insn)
Definition: arm_il64.c:1829
#define REG(n)
Definition: arm_il64.c:330
static RzILOpEffect * update_flags_zn(RzILOpBitVector *v)
Definition: arm_il64.c:419
#define MEMBASE(x)
Definition: arm_il64.c:333
#define IMM
Definition: arm_il64.c:11
static const char * regs_bound[]
Definition: arm_il64.c:27
#define REGBITS(n)
Definition: arm_il64.c:331
static RzILOpEffect * mov(cs_insn *insn)
Definition: arm_il64.c:1646
ut16 val
Definition: armass64_const.h:6
static mcore_handle handle
Definition: asm_mcore.c:8
int bits(struct state *s, int need)
Definition: blast.c:72
@ ARM64_OP_REG
= CS_OP_REG (Register operand).
Definition: arm64.h:235
@ ARM64_OP_MEM
= CS_OP_MEM (Memory operand).
Definition: arm64.h:237
@ ARM64_OP_SYS
SYS operand for IC/DC/AT/TLBI instructions.
Definition: arm64.h:243
@ ARM64_OP_REG_MRS
MRS register operand.
Definition: arm64.h:240
@ ARM64_OP_IMM
= CS_OP_IMM (Immediate operand).
Definition: arm64.h:236
@ ARM64_OP_REG_MSR
MSR register operand.
Definition: arm64.h:241
arm64_shifter
ARM64 shift type.
Definition: arm64.h:18
@ ARM64_SFT_LSL
Definition: arm64.h:20
@ ARM64_SFT_LSR
Definition: arm64.h:22
@ ARM64_SFT_ASR
Definition: arm64.h:23
arm64_reg
ARM64 registers.
Definition: arm64.h:347
@ ARM64_REG_X19
Definition: arm64.h:567
@ ARM64_REG_X4
Definition: arm64.h:552
@ ARM64_REG_W0
Definition: arm64.h:517
@ ARM64_REG_X12
Definition: arm64.h:560
@ ARM64_REG_X6
Definition: arm64.h:554
@ ARM64_REG_X14
Definition: arm64.h:562
@ ARM64_REG_X8
Definition: arm64.h:556
@ ARM64_REG_WSP
Definition: arm64.h:354
@ ARM64_REG_SP
Definition: arm64.h:353
@ ARM64_REG_X1
Definition: arm64.h:549
@ ARM64_REG_X24
Definition: arm64.h:572
@ ARM64_REG_X28
Definition: arm64.h:576
@ ARM64_REG_X16
Definition: arm64.h:564
@ ARM64_REG_X2
Definition: arm64.h:550
@ ARM64_REG_X15
Definition: arm64.h:563
@ ARM64_REG_X22
Definition: arm64.h:570
@ ARM64_REG_X26
Definition: arm64.h:574
@ ARM64_REG_XZR
Definition: arm64.h:356
@ ARM64_REG_X13
Definition: arm64.h:561
@ ARM64_REG_X30
Definition: arm64.h:351
@ ARM64_REG_X11
Definition: arm64.h:559
@ ARM64_REG_X0
Definition: arm64.h:548
@ ARM64_REG_LR
Definition: arm64.h:618
@ ARM64_REG_X9
Definition: arm64.h:557
@ ARM64_REG_X3
Definition: arm64.h:551
@ ARM64_REG_X21
Definition: arm64.h:569
@ ARM64_REG_X27
Definition: arm64.h:575
@ ARM64_REG_X23
Definition: arm64.h:571
@ ARM64_REG_X5
Definition: arm64.h:553
@ ARM64_REG_X25
Definition: arm64.h:573
@ ARM64_REG_W30
Definition: arm64.h:547
@ ARM64_REG_WZR
Definition: arm64.h:355
@ ARM64_REG_INVALID
Definition: arm64.h:348
@ ARM64_REG_X18
Definition: arm64.h:566
@ ARM64_REG_X10
Definition: arm64.h:558
@ ARM64_REG_X29
Definition: arm64.h:350
@ ARM64_REG_X17
Definition: arm64.h:565
@ ARM64_REG_X20
Definition: arm64.h:568
@ ARM64_REG_X7
Definition: arm64.h:555
arm64_extender
ARM64 extender type.
Definition: arm64.h:28
@ ARM64_EXT_SXTW
Definition: arm64.h:36
@ ARM64_EXT_UXTB
Definition: arm64.h:30
@ ARM64_EXT_UXTW
Definition: arm64.h:32
@ ARM64_EXT_SXTH
Definition: arm64.h:35
@ ARM64_EXT_SXTB
Definition: arm64.h:34
@ ARM64_EXT_UXTX
Definition: arm64.h:33
@ ARM64_EXT_UXTH
Definition: arm64.h:31
@ ARM64_EXT_SXTX
Definition: arm64.h:37
@ ARM64_INS_SMSUBL
Definition: arm64.h:944
@ ARM64_INS_BFI
Definition: arm64.h:1110
@ ARM64_INS_LDAR
Definition: arm64.h:828
@ ARM64_INS_STNP
Definition: arm64.h:1000
@ ARM64_INS_AND
Definition: arm64.h:687
@ ARM64_INS_CSINC
Definition: arm64.h:725
@ ARM64_INS_NOP
Definition: arm64.h:1099
@ ARM64_INS_SEV
Definition: arm64.h:1103
@ ARM64_INS_LDTRH
Definition: arm64.h:843
@ ARM64_INS_SEVL
Definition: arm64.h:1104
@ ARM64_INS_MVN
Definition: arm64.h:1113
@ ARM64_INS_LDURH
Definition: arm64.h:851
@ ARM64_INS_RBIT
Definition: arm64.h:884
@ ARM64_INS_CCMN
Definition: arm64.h:701
@ ARM64_INS_TBNZ
Definition: arm64.h:1023
@ ARM64_INS_ORN
Definition: arm64.h:875
@ ARM64_INS_LDPSW
Definition: arm64.h:835
@ ARM64_INS_CSNEG
Definition: arm64.h:727
@ ARM64_INS_STUR
Definition: arm64.h:1009
@ ARM64_INS_CSETM
Definition: arm64.h:1117
@ ARM64_INS_LDRH
Definition: arm64.h:838
@ ARM64_INS_LDARH
Definition: arm64.h:827
@ ARM64_INS_WFE
Definition: arm64.h:1101
@ ARM64_INS_ADC
Definition: arm64.h:675
@ ARM64_INS_SXTH
Definition: arm64.h:1121
@ ARM64_INS_SVC
Definition: arm64.h:1019
@ ARM64_INS_CSINV
Definition: arm64.h:726
@ ARM64_INS_LDAXRB
Definition: arm64.h:830
@ ARM64_INS_STLXR
Definition: arm64.h:999
@ ARM64_INS_CMN
Definition: arm64.h:1112
@ ARM64_INS_LDXP
Definition: arm64.h:855
@ ARM64_INS_EON
Definition: arm64.h:735
@ ARM64_INS_CSEL
Definition: arm64.h:724
@ ARM64_INS_REV32
Definition: arm64.h:887
@ ARM64_INS_CCMP
Definition: arm64.h:702
@ ARM64_INS_UMADDL
Definition: arm64.h:1046
@ ARM64_INS_RET
Definition: arm64.h:885
@ ARM64_INS_TBZ
Definition: arm64.h:1025
@ ARM64_INS_LDXRH
Definition: arm64.h:857
@ ARM64_INS_LDTRSB
Definition: arm64.h:844
@ ARM64_INS_PRFM
Definition: arm64.h:880
@ ARM64_INS_LDTR
Definition: arm64.h:848
@ ARM64_INS_LDNP
Definition: arm64.h:833
@ ARM64_INS_LDRSW
Definition: arm64.h:841
@ ARM64_INS_LDAXRH
Definition: arm64.h:831
@ ARM64_INS_STXR
Definition: arm64.h:1014
@ ARM64_INS_LDARB
Definition: arm64.h:826
@ ARM64_INS_STXRB
Definition: arm64.h:1012
@ ARM64_INS_CINC
Definition: arm64.h:1116
@ ARM64_INS_MOVK
Definition: arm64.h:865
@ ARM64_INS_MRS
Definition: arm64.h:868
@ ARM64_INS_MOVN
Definition: arm64.h:866
@ ARM64_INS_STXP
Definition: arm64.h:1011
@ ARM64_INS_STURH
Definition: arm64.h:1010
@ ARM64_INS_UMULL
Definition: arm64.h:1061
@ ARM64_INS_SXTW
Definition: arm64.h:1122
@ ARM64_INS_ROR
Definition: arm64.h:890
@ ARM64_INS_CSET
Definition: arm64.h:1115
@ ARM64_INS_UXTH
Definition: arm64.h:1125
@ ARM64_INS_LDTRSW
Definition: arm64.h:847
@ ARM64_INS_LDURB
Definition: arm64.h:849
@ ARM64_INS_BFXIL
Definition: arm64.h:1111
@ ARM64_INS_LDURSB
Definition: arm64.h:852
@ ARM64_INS_REV
Definition: arm64.h:889
@ ARM64_INS_STLXRH
Definition: arm64.h:998
@ ARM64_INS_LDAXR
Definition: arm64.h:832
@ ARM64_INS_LDUR
Definition: arm64.h:850
@ ARM64_INS_HVC
Definition: arm64.h:813
@ ARM64_INS_BFM
Definition: arm64.h:690
@ ARM64_INS_STLXRB
Definition: arm64.h:997
@ ARM64_INS_UMNEGL
Definition: arm64.h:1097
@ ARM64_INS_LDXRB
Definition: arm64.h:856
@ ARM64_INS_UBFX
Definition: arm64.h:1109
@ ARM64_INS_ADR
Definition: arm64.h:681
@ ARM64_INS_SMULL
Definition: arm64.h:947
@ ARM64_INS_WFI
Definition: arm64.h:1102
@ ARM64_INS_CINV
Definition: arm64.h:1118
@ ARM64_INS_SMADDL
Definition: arm64.h:931
@ ARM64_INS_MSUB
Definition: arm64.h:870
@ ARM64_INS_LDTRB
Definition: arm64.h:842
@ ARM64_INS_UMSUBL
Definition: arm64.h:1058
@ ARM64_INS_ADRP
Definition: arm64.h:682
@ ARM64_INS_SMULH
Definition: arm64.h:945
@ ARM64_INS_STLRH
Definition: arm64.h:994
@ ARM64_INS_NGCS
Definition: arm64.h:1133
@ ARM64_INS_LDAXP
Definition: arm64.h:829
@ ARM64_INS_SBC
Definition: arm64.h:909
@ ARM64_INS_LDRSB
Definition: arm64.h:839
@ ARM64_INS_CNEG
Definition: arm64.h:1119
@ ARM64_INS_STRH
Definition: arm64.h:1004
@ ARM64_INS_MSR
Definition: arm64.h:869
@ ARM64_INS_CBNZ
Definition: arm64.h:699
@ ARM64_INS_STTRH
Definition: arm64.h:1006
@ ARM64_INS_LSL
Definition: arm64.h:859
@ ARM64_INS_LDR
Definition: arm64.h:837
@ ARM64_INS_PRFUM
Definition: arm64.h:881
@ ARM64_INS_STTR
Definition: arm64.h:1007
@ ARM64_INS_SDIV
Definition: arm64.h:912
@ ARM64_INS_UXTB
Definition: arm64.h:1124
@ ARM64_INS_MADD
Definition: arm64.h:861
@ ARM64_INS_SMNEGL
Definition: arm64.h:1098
@ ARM64_INS_LDRB
Definition: arm64.h:836
@ ARM64_INS_CLS
Definition: arm64.h:704
@ ARM64_INS_REV16
Definition: arm64.h:886
@ ARM64_INS_B
Definition: arm64.h:689
@ ARM64_INS_STR
Definition: arm64.h:1003
@ ARM64_INS_MOVZ
Definition: arm64.h:867
@ ARM64_INS_NEG
Definition: arm64.h:873
@ ARM64_INS_SXTB
Definition: arm64.h:1120
@ ARM64_INS_SBFIZ
Definition: arm64.h:1106
@ ARM64_INS_LDURSW
Definition: arm64.h:854
@ ARM64_INS_UMULH
Definition: arm64.h:1059
@ ARM64_INS_EXTR
Definition: arm64.h:738
@ ARM64_INS_UDIV
Definition: arm64.h:1043
@ ARM64_INS_STLR
Definition: arm64.h:995
@ ARM64_INS_ADD
Definition: arm64.h:679
@ ARM64_INS_SBFX
Definition: arm64.h:1108
@ ARM64_INS_HINT
Definition: arm64.h:811
@ ARM64_INS_STLRB
Definition: arm64.h:993
@ ARM64_INS_NGC
Definition: arm64.h:1105
@ ARM64_INS_MOV
Definition: arm64.h:715
@ ARM64_INS_YIELD
Definition: arm64.h:1100
@ ARM64_INS_LDRSH
Definition: arm64.h:840
@ ARM64_INS_CLZ
Definition: arm64.h:705
@ ARM64_INS_BR
Definition: arm64.h:696
@ ARM64_INS_LSR
Definition: arm64.h:860
@ ARM64_INS_LDP
Definition: arm64.h:834
@ ARM64_INS_BL
Definition: arm64.h:694
@ ARM64_INS_BIC
Definition: arm64.h:691
@ ARM64_INS_EOR
Definition: arm64.h:736
@ ARM64_INS_CMP
Definition: arm64.h:1123
@ ARM64_INS_MNEG
Definition: arm64.h:1096
@ ARM64_INS_STXRH
Definition: arm64.h:1013
@ ARM64_INS_MUL
Definition: arm64.h:871
@ ARM64_INS_STURB
Definition: arm64.h:1008
@ ARM64_INS_STTRB
Definition: arm64.h:1005
@ ARM64_INS_LDURSH
Definition: arm64.h:853
@ ARM64_INS_CBZ
Definition: arm64.h:700
@ ARM64_INS_ORR
Definition: arm64.h:876
@ ARM64_INS_LDTRSH
Definition: arm64.h:846
@ ARM64_INS_BLR
Definition: arm64.h:695
@ ARM64_INS_STRB
Definition: arm64.h:1002
@ ARM64_INS_SUB
Definition: arm64.h:1017
@ ARM64_INS_TST
Definition: arm64.h:1114
@ ARM64_INS_LDXR
Definition: arm64.h:858
@ ARM64_INS_STLXP
Definition: arm64.h:996
@ ARM64_INS_ASR
Definition: arm64.h:688
@ ARM64_INS_UBFIZ
Definition: arm64.h:1107
@ ARM64_INS_STP
Definition: arm64.h:1001
@ ARM64_INS_NEGS
Definition: arm64.h:1132
arm64_cc
ARM64 condition code.
Definition: arm64.h:41
@ ARM64_CC_HS
Unsigned higher or same: >, ==, or unordered.
Definition: arm64.h:45
@ ARM64_CC_PL
Plus, positive or zero: >, ==, or unordered.
Definition: arm64.h:48
@ ARM64_CC_EQ
Equal.
Definition: arm64.h:43
@ ARM64_CC_LT
Less than: Less than, or unordered.
Definition: arm64.h:54
@ ARM64_CC_VC
No overflow: Ordered.
Definition: arm64.h:50
@ ARM64_CC_LS
Unsigned lower or same: Less than or equal.
Definition: arm64.h:52
@ ARM64_CC_GE
Greater than or equal: Greater than or equal.
Definition: arm64.h:53
@ ARM64_CC_GT
Signed greater than: Greater than.
Definition: arm64.h:55
@ ARM64_CC_NE
Not equal: Not equal, or unordered.
Definition: arm64.h:44
@ ARM64_CC_LO
Unsigned lower or same: Less than.
Definition: arm64.h:46
@ ARM64_CC_VS
Overflow: Unordered.
Definition: arm64.h:49
@ ARM64_CC_HI
Unsigned higher: Greater than, or unordered.
Definition: arm64.h:51
@ ARM64_CC_LE
Signed less than or equal: <, ==, or unordered.
Definition: arm64.h:56
@ ARM64_CC_MI
Minus, negative: Less than.
Definition: arm64.h:47
size_t csh
Definition: capstone.h:71
#define CS_API_MAJOR
Definition: capstone.h:50
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
uint32_t ut32
const char * v
Definition: dsignal.c:12
@ GOTO
Definition: egg_lang.c:71
RZ_API void rz_il_op_pure_free(RZ_NULLABLE RzILOpPure *op)
Definition: il_opcodes.c:928
RZ_API void rz_il_op_effect_free(RZ_NULLABLE RzILOpEffect *op)
Definition: il_opcodes.c:1036
RZ_API RzILEffectLabel * rz_il_effect_label_new(RZ_NONNULL const char *name, RzILEffectLabelType type)
Definition: label.c:6
@ EFFECT_LABEL_SYSCALL
Definition: label.h:19
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
#define SIGNED
Definition: ansidecl.h:248
#define AND
Definition: ansidecl.h:254
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
int idx
Definition: setup.py:197
#define OR
Definition: rsp_idec.c:210
#define XOR
Definition: rsp_idec.c:212
#define NOP
Definition: rsp_idec.c:182
#define ADD
Definition: rsp_idec.c:200
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API ut32 rz_bv_len(RZ_NONNULL const RzBitVector *bv)
Definition: bitvector.c:1140
Syntax Macros for RzIL Lifting.
#define LOAD(addr)
#define LOGOR(x, y)
#define LOGNOT(x)
#define IS_ZERO(x)
#define SHIFTR0(v, dist)
#define LOADW(n, addr)
#define SDIV(x, y)
#define MUL(x, y)
#define LSB(x)
#define SHIFTL(f, v, dist)
#define VARLP(name)
#define APPEND(high, low)
#define LET(name, v, body)
#define UN(l, val)
#define DIV(x, y)
#define U32(val)
#define IL_FALSE
#define REPEAT(c, b)
#define ULE(x, y)
#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 IL_TRUE
#define INV(x)
#define SEQ2(e0, e1)
#define ITE(c, t, f)
#define LOGXOR(x, y)
#define NEG(x)
#define UNSIGNED(n, x)
#define U64(val)
#define SN(l, val)
#define SEQ6(e0, e1, e2, e3, e4, e5)
#define SLE(x, y)
#define SHIFTL0(v, dist)
#define SHIFTRA(v, dist)
#define VARL(name)
#define MSB(x)
#define LOGAND(x, y)
#define STORE(addr, val)
#define VARG(name)
#define JMP(tgt)
#define SETG(name, v)
@ RZ_IL_OP_CAST
@ RZ_IL_OP_BITV
static ut64 rz_num_bitmask(ut8 width)
Get the 64-bit value that has exactly its width lowest bits set to 1. e.g. rz_num_bitmask(2) == 0b11 ...
Definition: rz_num.h:134
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define RZ_BORROW
Definition: rz_types.h:63
#define RZ_MIN(x, y)
#define st64
Definition: rz_types_base.h:10
@ DUP
Definition: packet.c:12
#define SUB(ns, call)
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
#define h(i)
Definition: sha256.c:48
Instruction operand.
Definition: arm64.h:630
Description of the global context of an RzAnalysisILVM.
Definition: rz_analysis.h:1134
void * hook
Function pointer if EFFECT_LABEL_SYSCALL / EFFECT_LABEL_HOOK.
Definition: label.h:28
An IL op performing a pure computation, 'a pure.
Low-level VM to execute raw IL code.
Definition: rz_il_vm.h:37
int width
Definition: main.c:10
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58