1 /* radare - LGPL - Copyright 2015-2018 - pancake */
2 
3 #include <stdio.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <stdlib.h>
7 #include <r_util.h>
8 
9 typedef enum optype_t {
10 	ARM_NOTYPE = -1,
11 	ARM_GPR = 1,
12 	ARM_CONSTANT = 2,
13 	ARM_FP = 4,
14 	ARM_MEM_OPT = 8,
15 	ARM_SHIFT = 16,
16 	ARM_EXTEND = 32
17 } OpType;
18 
19 typedef enum regtype_t {
20 	ARM_UNDEFINED = -1,
21 	ARM_REG64 = 1,
22 	ARM_REG32 = 2,
23 	ARM_SP = 4,
24 	ARM_PC = 8,
25 	ARM_SIMD = 16
26 } RegType;
27 
28 typedef enum shifttype_t {
29 	ARM_LSL = 0,
30 	ARM_LSR = 1,
31 	ARM_ASR = 2,
32 	ARM_ROR = 3,
33 	ARM_UXTB,
34 	ARM_UXTH,
35 	ARM_UXTW,
36 	ARM_UXTX,
37 	ARM_SXTB,
38 	ARM_SXTH,
39 	ARM_SXTW,
40 	ARM_SXTX
41 } ShiftType;
42 
43 typedef enum logicalop_t {
44 	ARM_AND = 0,
45 	ARM_ORR = 1,
46 	ARM_EOR = 2,
47 	ARM_ANDS = 3
48 } LogicalOp;
49 
50 typedef struct operand_t {
51 	OpType type;
52 	union {
53 		struct {
54 			int reg;
55 			RegType reg_type;
56 			ut16 sp_val;
57 		};
58 		struct {
59 			ut64 immediate;
60 			bool sign;
61 			bool preindex;
62 		};
63 		struct {
64 			ut64 shift_amount;
65 			ShiftType shift;
66 			bool amount_present;
67 		};
68 		struct {
69 			ut32 mem_option;
70 		};
71 	};
72 } Operand;
73 
74 #define MAX_OPERANDS 7
75 
76 typedef struct Opcode_t {
77 	char *mnemonic;
78 	ut32 op[3];
79 	size_t op_len;
80 	ut8 opcode[3];
81 	bool writeback;
82 	int operands_count;
83 	Operand operands[MAX_OPERANDS];
84 } ArmOp;
85 
86 #define check_cond(cond) if (!(cond)) { return data; }
87 
get_mem_option(char * token)88 static int get_mem_option(char *token) {
89 	// values 4, 8, 12, are unused. XXX to adjust
90 	const char *options[] = {"sy", "st", "ld", "xxx", "ish", "ishst",
91 	                         "ishld", "xxx", "nsh", "nshst", "nshld",
92 	                         "xxx", "osh", "oshst", "oshld", NULL};
93 	int i = 0;
94 	while (options[i]) {
95 		if (!r_str_casecmp (token, options[i])) {
96 			return 15 - i;
97 		}
98 		i++;
99 	}
100 	return -1;
101 }
102 
countLeadingZeros(ut64 x)103 static int countLeadingZeros(ut64 x) {
104 	int count = 64;
105 	while (x) {
106 		x >>= 1;
107 		--count;
108 	}
109 	return count;
110 }
111 
countTrailingZeros(ut64 x)112 static int countTrailingZeros(ut64 x) {
113 	int count = 0;
114 	while (x && !(x & 1)) {
115 		count++;
116 		x >>= 1;
117 	}
118 	return count;
119 }
120 
calcNegOffset(int n,int shift)121 static int calcNegOffset(int n, int shift) {
122 	int a = n >> shift;
123 	if (a == 0) {
124 		return 0xff;
125 	}
126 	// find first set bit then invert it and all
127 	// bits below it
128 	int t = 0x400;
129 	while (!(t & a) && a != 0 && t != 0) {
130 		t = t >> 1;
131 	}
132 	t = t & (t - 1);
133 	a = a ^ t;
134 	// If bits below 32 are set
135 	if (countTrailingZeros(n) > shift) {
136 		a--;
137 	}
138 	return 0xff & (0xff - a);
139 }
140 
countLeadingOnes(ut64 x)141 static int countLeadingOnes(ut64 x) {
142 	return countLeadingZeros (~x);
143 }
144 
countTrailingOnes(ut64 x)145 static int countTrailingOnes(ut64 x) {
146 	return countTrailingZeros (~x);
147 }
148 
isMask(ut64 value)149 static bool isMask(ut64 value) {
150   return value && ((value + 1) & value) == 0;
151 }
152 
isShiftedMask(ut64 value)153 static bool isShiftedMask (ut64 value) {
154   return value && isMask ((value - 1) | value);
155 }
156 
157 // https://llvm.org/doxygen/AArch64AddressingModes_8h_source.html
encodeBitMasksWithSize(ut64 imm,ut32 reg_size)158 static ut32 encodeBitMasksWithSize(ut64 imm, ut32 reg_size) {
159 	if (imm == 0 || imm == UT64_MAX || (reg_size != 64
160 		&& (imm >> reg_size != 0 || imm == (~0ULL >> (64 - reg_size))))) {
161 		return UT32_MAX;
162 	}
163 	// get element size
164 	ut32 size = reg_size;
165 	do {
166 		size >>= 1;
167 		ut64 mask = (1ull << size) - 1;
168 		if ((imm & mask) != ((imm >> size) & mask)) {
169 			size <<= 1;
170 			break;
171 		}
172    } while (size > 2);
173 	// determine rot to make element be 0^m 1^n
174 	ut32 cto, i;
175 	ut64 mask = UT64_MAX >> (64 - size);
176 	imm &= mask;
177 
178 	if (isShiftedMask (imm)) {
179 		i = countTrailingZeros (imm);
180 		cto = countTrailingOnes (imm >> i);
181 	} else {
182 		imm |= ~mask;
183 		if (!isShiftedMask (~imm)) {
184 			return UT32_MAX;
185 		}
186 
187 		ut32 clo = countLeadingOnes (imm);
188 		i = 64 - clo;
189 		cto = clo + countTrailingOnes (imm) - (64 - size);
190 	}
191 
192 	// Encode in Immr the number of RORs it would take to get *from* 0^m 1^n
193 	// to our target value, where I is the number of RORs to go the opposite
194 	// direction
195 	ut32 immr = (size - i) & (size - 1);
196 	// If size has a 1 in the n'th bit, create a value that has zeroes in
197 	// bits [0, n] and ones above that.
198 	ut64 nimms = ~(size - 1) << 1;
199 	// Or the cto value into the low bits, which must be below the Nth bit
200 	// bit mentioned above.
201 	nimms |= (cto - 1);
202 	// Extract and toggle seventh bit to make N field.
203 	ut32 n = ((nimms >> 6) & 1) ^ 1;
204 	ut32 encoding = (n << 12) | (immr << 6) | (nimms & 0x3f);
205 	return encoding;
206 }
207 
encode1reg(ArmOp * op)208 static inline ut32 encode1reg(ArmOp *op) {
209 	return op->operands[0].reg << 24;
210 }
211 
encode2regs(ArmOp * op)212 static inline ut32 encode2regs(ArmOp *op) {
213 	return (op->operands[1].reg & 0x7) << 29 | (op->operands[1].reg & 0x18) << 13
214 		| encode1reg (op);
215 }
216 
encodeImm9(ut32 n)217 static inline ut32 encodeImm9(ut32 n) {
218 	return (n & 0x1f0) << 4 | (n & 0xf) << 20;
219 }
220 
mov(ArmOp * op)221 static ut32 mov(ArmOp *op) {
222 	ut32 k = 0;
223 	ut32 data = UT32_MAX;
224 	check_cond (op->operands_count >= 2);
225 	check_cond (op->operands[0].type == ARM_GPR);
226 	int bits = (op->operands[0].reg_type & ARM_REG64) ? 64 : 32;
227 	if (bits == 64) {
228 		k = 0x0080;
229 	}
230 	k |= encode1reg (op);
231 	if (!strcmp (op->mnemonic, "mov")) {
232 		check_cond (op->operands_count == 2);
233 		if (op->operands[1].type == ARM_GPR) {
234 			check_cond (bits == ((op->operands[1].reg_type & ARM_REG64) ? 64 : 32));
235 			if (op->operands[0].reg_type & ARM_SP || op->operands[1].reg_type & ARM_SP) { // alias of add
236 				k |= 0x0011;
237 				data = k | encode2regs (op);
238 				return data;
239 			}
240 			k |= 0xe003002a; // alias of orr
241 			data = k | op->operands[1].reg << 8;
242 			return data;
243 		}
244 		check_cond (op->operands[1].type & ARM_CONSTANT);
245 		ut64 imm = op->operands[1].immediate;
246 		ut64 imm_inverse = ~imm;
247 		if (bits == 32) {
248 			check_cond (imm <= 0xffffffff || imm_inverse <= 0xffffffff);
249 			imm &= 0xffffffff;
250 			imm_inverse &= 0xffffffff;
251 		}
252 		int shift;
253 		ut64 mask = 0xffff;
254 		for (shift = 0; shift < bits; shift += 16, mask <<= 16) {
255 			if (imm == (imm & mask)) { // movz
256 				data = k | 0x00008052;
257 				imm >>= shift;
258 				data |= (imm & 7) << 29 | (imm & 0x7f8) << 13 | (imm & 0xf800) >> 3;
259 				data |= shift << 9;
260 				return data;
261 			}
262 		}
263 		mask = 0xffff;
264 		for (shift = 0; shift < bits; shift += 16, mask <<= 16) {
265 			if (imm_inverse == (imm_inverse & mask)) { // movn
266 				data = k | 0x00008012;
267 				imm_inverse >>= shift;
268 				data |= (imm_inverse & 7) << 29 | (imm_inverse & 0x7f8) << 13 | (imm_inverse & 0xf800) >> 3;
269 				data |= shift << 9;
270 				return data;
271 			}
272 		}
273 		ut32 bitmask = encodeBitMasksWithSize (op->operands[1].immediate, bits); // orr
274 		check_cond (bitmask != UT32_MAX);
275 		data = k | 0xe0030032;
276 		data |= (bitmask & 0x3f) << 18 | (bitmask & 0x1fc0) << 2;
277 		return data;
278 	}
279 	if (!strcmp (op->mnemonic, "movz")) {
280 		k |= 0x8052;
281 	} else if (!strcmp (op->mnemonic, "movk")) {
282 		k |= 0x8072;
283 	} else if (!strcmp (op->mnemonic, "movn")) {
284 		k |= 0x8012;
285 	} else {
286 		return data;
287 	}
288 	check_cond (op->operands[1].type == ARM_CONSTANT);
289 	ut64 imm = op->operands[1].immediate;
290 	check_cond (imm <= 0xffff);
291 	int shift = 0;
292 	if (op->operands_count >= 3) {
293 		check_cond (op->operands_count == 3);
294 		check_cond (op->operands[2].type == ARM_SHIFT);
295 		check_cond (op->operands[2].shift == ARM_LSL);
296 		shift = op->operands[2].shift_amount;
297 		check_cond (!(shift & 0xf));
298 		check_cond (shift < bits);
299 	}
300 	data = k;
301 	data |= (imm & 7) << 29; // arg(1)
302 	data |= (imm & 0x7f8) << 13; // arg(1)
303 	data |= (imm & 0xf800) >> 3; // arg(1)
304 	data |= shift << 9; // arg(2)
305 	return data;
306 }
307 
cb(ArmOp * op)308 static ut32 cb(ArmOp *op) {
309 	ut32 data = UT32_MAX;
310 	int k = 0;
311     if (!strncmp (op->mnemonic, "cbnz", 4)) {
312         if (op->operands[0].reg_type & ARM_REG64) {
313             k =  0x000000b5;
314         } else if (op->operands[0].reg_type & ARM_REG32) {
315             k =  0x00000035;
316         } else {
317             return UT32_MAX;
318         }
319     } else if (!strncmp (op->mnemonic, "cbz", 3)) {
320         if (op->operands[0].reg_type & ARM_REG64) {
321             k =  0x000000b4;
322         } else if (op->operands[0].reg_type & ARM_REG32) {
323             k =  0x00000034;
324         } else {
325             return UT32_MAX;
326         }
327     } else {
328         return UT32_MAX;
329     }
330     //printf ("%s %d, %llu\n", op->mnemonic, op->operands[0].reg, op->operands[1].immediate);
331     ut32 imm = op->operands[1].immediate;
332 	data = k | encode1reg (op) | ((imm & 0x1c) << 27) | ((imm & 0x1fe0) << 11);
333     data = data | ((imm & 0x1fe000) >> 5);
334 
335 	return data;
336 }
337 
338 
cmp(ArmOp * op)339 static ut32 cmp(ArmOp *op) {
340 	ut32 data = UT32_MAX;
341 	int k = 0;
342 	if (op->operands[0].reg_type & ARM_REG64 && op->operands[1].reg_type & ARM_REG64) {
343 		k =  0x1f0000eb;
344 	} else if (op->operands[0].reg_type & ARM_REG32 && op->operands[1].reg_type & ARM_REG32) {
345 		if (op->operands[2].shift_amount > 31) {
346 			return UT32_MAX;
347 		}
348 		k =  0x1f00006b;
349 	} else {
350 		return UT32_MAX;
351 	}
352 
353 	data = k | (op->operands[0].reg & 0x18) << 13 | op->operands[0].reg << 29 | op->operands[1].reg << 8;
354 
355 	if (op->operands[2].type != ARM_SHIFT) {
356 		data |= op->operands[2].shift_amount << 18 | op->operands[2].shift << 14;
357 	}
358 	return data;
359 }
360 
361 
regsluop(ArmOp * op,int k)362 static ut32 regsluop(ArmOp *op, int k) {
363 	ut32 data = UT32_MAX;
364 
365 	if (op->operands[1].reg_type & ARM_REG32) {
366 		return data;
367 	}
368 	if (op->operands[0].reg_type & ARM_REG32) {
369 		k -= 0x40;
370 	}
371 	if (op->operands[2].type & ARM_GPR) {
372 		return data;
373 	}
374 
375 	int n = op->operands[2].immediate;
376 	if (n > 0xff || n < -0x100) {
377 		return data;
378 	}
379 
380 	data = k | encode2regs (op);
381 
382 	if (n < 0) {
383 		n *= -1;
384 		data |= ( 0xf & (0xf - (n - 1)) ) << 20;
385 
386 		if (countTrailingZeros(n) > 3) {
387 			data |= (0x1f - ((n >> 4) - 1)) << 8;
388 		} else {
389 			data |= (0x1f - (n >> 4)) << 8;
390 		}
391 	} else {
392 		data |= (0xf & (n & 63)) << 20;
393 		if (countTrailingZeros(n) < 4) {
394 			data |= (n >> 4) << 8;
395 		} else {
396 			data |= (0xff & n) << 4;
397 		}
398 		data |= (n >> 8) << 8;
399 	}
400 
401 	return data;
402 }
403 
404 // Register Load/store ops
reglsop(ArmOp * op,int k)405 static ut32 reglsop(ArmOp *op, int k) {
406 	ut32 data = UT32_MAX;
407 
408 	if (op->operands[1].reg_type & ARM_REG32) {
409 		return data;
410 	}
411 	if (op->operands[0].reg_type & ARM_REG32) {
412 		k -= 0x40;
413 	}
414 	if (op->operands[2].type & ARM_GPR) {
415 		k += 0x00682000;
416 		data = k | encode2regs (op);
417 		data |= op->operands[2].reg << 8;
418 	} else {
419 		int n = op->operands[2].immediate;
420 		if (n > 0x100 || n < -0x100) {
421 			return UT32_MAX;
422 		}
423 
424 		if (n == 0 || (n > 0 && countTrailingZeros(n) >= 4)) {
425 			k ++;
426 		}
427 		data = k | encode2regs (op);
428 
429 		if (n < 0) {
430 			n *= -1;
431 			data |= ( 0xf & (0xf - (n - 1)) ) << 20;
432 			if (countTrailingZeros(n) > 3) {
433 				data |= (0x1f - ((n >> 4) - 1)) << 8;
434 			} else {
435 				data |= (0x1f - (n >> 4)) << 8;
436 			}
437 		} else {
438 			if (op->operands[0].reg_type & ARM_REG32) {
439 				if (countTrailingZeros(n) < 2) {
440 					data |= (0xf & (n & 63)) << 20;
441 					data |= (n >> 4) << 8;
442 				} else {
443 						data++;
444 						data |= (0xff & n) << 16;
445 				}
446 				data |= (n >> 8) << 8;
447 			} else {
448 				data |= (0xf & (n & 63)) << 20;
449 				if (countTrailingZeros(n) < 4) {
450 					data |= (n >> 4) << 8;
451 				} else {
452 					data |= (0xff & n) << 15;
453 				}
454 				data |= (n >> 8) << 23;
455 			}
456 		}
457 	}
458 	return data;
459 }
460 
461 // load/store ops
lsop(ArmOp * op,int k,ut64 addr)462 static ut32 lsop(ArmOp *op, int k, ut64 addr) {
463 	ut32 data = UT32_MAX;
464 	int op_count = op->operands_count;
465 	if (k == 0x00000098) { // ldrsw
466 		if (op->operands[0].type & ARM_GPR
467 			&& op->operands[1].type & ARM_CONSTANT) { // (literal)
468 			st64 offset = op->operands[1].immediate - addr;
469 			check_cond (op->operands[0].reg_type & ARM_REG64);
470 			check_cond (!(offset & 0x3));
471 			check_cond (-0x100000 <= offset && offset < 0x100000);
472 			offset >>= 2;
473 			data = k | (offset & 0x7f800) >> 3 | (offset & 0x7f8) << 13
474 				| (offset & 0x7) << 29 | encode1reg (op);
475 			return data;
476 		}
477 		k = 0x000080b8;
478 	}
479 	check_cond (op->operands[0].type == ARM_GPR);
480 	check_cond (op->operands[1].type == ARM_GPR);
481 	check_cond (op->operands[1].reg_type & ARM_REG64);
482 	k |= encode2regs (op);
483 	if (!strcmp (op->mnemonic, "ldrb") || !strcmp (op->mnemonic, "ldrh")
484 		|| !strcmp (op->mnemonic, "strb") || !strcmp (op->mnemonic, "strh")) {
485 		check_cond (op->operands[0].reg_type & ARM_REG32);
486 	} else if (!strcmp (op->mnemonic, "ldrsw")) {
487 		check_cond (op->operands[0].reg_type & ARM_REG64);
488 	} else { // ldrsh, ldrsb
489 		if (op->operands[0].reg_type & ARM_REG32) {
490 			k |= 0x00004000;
491 		}
492 	}
493 	char width = op->mnemonic[strlen (op->mnemonic) - 1];
494 	if (op->operands[2].type & ARM_GPR) {
495 		k |= 0x00482000;
496 		if (op->operands[3].type == ARM_EXTEND) {
497 			switch (op->operands[3].shift) {
498 			case ARM_SXTW:
499 				k |= 0x00800000;
500 			// fall through
501 			case ARM_UXTW:
502 				check_cond (op->operands[2].reg_type & ARM_REG32);
503 				break;
504 			case ARM_SXTX:
505 				k |= 0x00a00000;
506 				check_cond (op->operands[2].reg_type & ARM_REG64);
507 				break;
508 			default:
509 				return data;
510 			}
511 		} else if (op->operands[3].type == ARM_SHIFT) {
512 			check_cond (op->operands[3].shift == ARM_LSL);
513 			check_cond (op->operands[2].reg_type & ARM_REG64);
514 			k |= 0x00200000;
515 		}
516 		if (op->operands[3].type == ARM_EXTEND || op->operands[3].type == ARM_SHIFT) {
517 			if (width == 'b') {
518 				check_cond (op->operands[3].shift_amount == 0);
519 				if (op->operands[3].amount_present) {
520 					k |= 0x00100000;
521 				}
522 			} else if (width == 'h') {
523 				switch (op->operands[3].shift_amount) {
524 				case 1:
525 					k |= 0x00100000;
526 				// fall through
527 				case 0:
528 					break;
529 				default:
530 					return data;
531 				}
532 			} else { // w
533 				switch (op->operands[3].shift_amount) {
534 				case 2:
535 					k |= 0x00100000;
536 				// fall through
537 				case 0:
538 					break;
539 				default:
540 					return data;
541 				}
542 			}
543 		} else { // lsl 0 by default
544 			check_cond (op->operands[2].reg_type & ARM_REG64);
545 			k |= 0x00200000;
546 		}
547 		data = k | op->operands[2].reg << 8;
548 		return data;
549 	}
550 	check_cond (op_count == 2 || op->operands[2].type == ARM_CONSTANT);
551 	check_cond (!op->writeback || op->operands[2].preindex);
552 	int n = op_count == 2 ? 0 : op->operands[2].immediate;
553 	if (!op->writeback && (op_count == 2 || op->operands[2].preindex)) { // unsigned offset
554 		check_cond (n >= 0);
555 		if (width == 'b') {
556 			check_cond (n <= 0xfff);
557 		} else if (width == 'h') {
558 			check_cond (n <= 0x1ffe && !(n & 1))
559 			n >>= 1;
560 		} else { // w
561 			check_cond (n <= 0x3ffc && !(n & 3));
562 			n >>= 2;
563 		}
564 		data = k | (n & 0x3f) << 18 | (n & 0xfc0) << 2 | 1;
565 		return data;
566 	}
567 	check_cond (-0x100 <= n && n < 0x100)
568 	if (op->operands[2].preindex) {
569 		k |= 0x00080000;
570 	}
571 	data = k | encodeImm9 (n) | 0x00040000;
572 	return data;
573 }
574 
branch(ArmOp * op,ut64 addr,int k)575 static ut32 branch(ArmOp *op, ut64 addr, int k) {
576 	ut32 data = UT32_MAX;
577 	ut64 n = 0;
578 	if (op->operands[0].type & ARM_CONSTANT) {
579 		n = op->operands[0].immediate;
580 		if (!(n & 0x3)) {
581 			if (n >= addr) {
582 				n -= addr;
583 			} else {
584 				n -= addr;
585 				n = n & 0xfffffff;
586 				k |= 3;
587 			}
588 			n = n >> 2;
589 			int t = (n & 0xff000000) >> 24;
590 			int h = (n & 0xff0000) >> 16;
591 			int m = (n & 0xff00) >> 8;
592 			n &= 0xff;
593 			data = k;
594 			data |= n << 24;
595 			data |= m << 16;
596 			data |= h << 8;
597 			data |= t;
598 		}
599 	} else {
600 		n = op->operands[0].reg;
601 		if (n >= 31) {
602 			return -1;
603 		}
604 		n = n << 5;
605 		int h = n >> 8;
606 		n &= 0xff;
607 		data = k;
608 		data |= n << 24;
609 		data |= h << 16;
610 	}
611 	return data;
612 }
613 
bdot(ArmOp * op,ut64 addr,int k)614 static ut32 bdot(ArmOp *op, ut64 addr, int k) {
615 	ut32 data = UT32_MAX;
616 	int n = 0;
617 	int a = 0;
618 	n = op->operands[0].immediate;
619 	// I am sure there's a logical way to do negative offsets,
620 	// but I was unable to find any sensible docs so I did my best
621 	if (!(n & 0x3 || n > 0x7ffffff)) {
622 		n -= addr;
623 		data = k;
624 		if (n < 0) {
625 			n *= -1;
626 			a = (n << 3) - 1;
627 			data |= (0xff - a) << 24;
628 
629 			a = calcNegOffset(n, 5);
630 			data |= a << 16;
631 
632 			a = calcNegOffset(n, 13);
633 			data |= a << 8;
634 		} else {
635 			data |= (n & 31) << 27;
636 			data |= (0xff & (n >> 5)) << 16;
637 			data |= (0xff & (n >> 13)) << 8;
638 		}
639 	}
640 
641 	return data;
642 }
643 
mem_barrier(ArmOp * op,ut64 addr,int k)644 static ut32 mem_barrier(ArmOp *op, ut64 addr, int k) {
645 	ut32 data = UT32_MAX;
646 	data = k;
647 	if (!strncmp (op->mnemonic, "isb", 3)) {
648 		if (op->operands[0].mem_option == 15 || op->operands[0].type == ARM_NOTYPE) {
649 			return data;
650 		} else {
651 			return UT32_MAX;
652 		}
653 	}
654 	if (op->operands[0].type == ARM_MEM_OPT) {
655 		data |= op->operands[0].mem_option << 16;
656 	} else if (op->operands_count == 1 && op->operands[0].type == ARM_CONSTANT) {
657 		data |= (op->operands[0].immediate << 16);
658 	}
659 	return data;
660 }
661 
662 #include "armass64_const.h"
663 
msr(ArmOp * op,int w)664 static ut32 msr(ArmOp *op, int w) {
665 	ut32 data = UT32_MAX;
666 	ut32 seq_data = UT32_MAX;
667 	int is_immediate = 0;
668 	int i;
669 	ut32 r, b;
670 	/* handle swapped args */
671 	if (w) {
672 		if (op->operands[1].reg_type != (ARM_REG64 | ARM_SP)) {
673 			if (op->operands[1].type == ARM_CONSTANT) {
674 				for (i = 0; msr_const[i].name; i++) {
675 					if (op->operands[1].immediate == msr_const[i].val) {
676 						op->operands[1].sp_val = msr_const[i].val;
677 						op->operands[1].reg = op->operands[1].immediate;
678 						break;
679 					}
680 				}
681 			} else {
682 				return data;
683 			}
684 		}
685 		r = op->operands[0].reg;
686 		b = op->operands[1].sp_val;
687 	} else {
688 		if (op->operands[0].reg_type != (ARM_REG64 | ARM_SP)) {
689 			if (op->operands[0].type == ARM_CONSTANT) {
690 				for (i = 0; msr_const[i].name; i++) {
691 					if (op->operands[0].immediate == msr_const[i].val) {
692 						op->operands[0].sp_val = msr_const[i].val;
693 						op->operands[0].reg = op->operands[0].immediate;
694 						break;
695 					}
696 				}
697 			} else {
698 				return data;
699 			}
700 		}
701 		r = op->operands[1].reg;
702 		if ( op->operands[1].sp_val == 0xfffe ) {
703 			is_immediate = 1;
704 			r = op->operands[1].immediate;
705 		}
706 		b = op->operands[0].sp_val;
707 	}
708 	data = 0x00000000;
709 
710 	if (is_immediate) {
711 		//only msr has immediate mode
712 		data = 0xd500401f;
713 		if (b == 0xc210) { //op0 is SPSel
714 			b = 0x05; //set to immediate mode encoding
715 		}
716 
717 		data |= (b & 0xf0) << 12; //op1
718 		data |= (b & 0x0f) << 5; //op2
719 		data |= (r & 0xf) << 8; //CRm(#imm)
720 
721 	} else {
722 		if (w) {
723 			/* mrs */
724 			data |= 0xd5200000;
725 		} else {
726 			data |= 0xd5000000;
727 		}
728 		data |= b << 5;
729 		data |= r;
730 	}
731 	seq_data = 0x00000000;
732 	seq_data |= (data & 0xff) << 8*3;
733 	seq_data |= (data & 0xff00) << 8*1;
734 	seq_data |= (data & 0xff0000) >> 8*1;
735 	seq_data |= (data & 0xff000000) >> 8*3;
736 /*
737 if (op->operands[1].reg_type == ARM_REG64) {
738 		data |= op->operands[1].reg << 24;
739 	}
740 */
741 	return seq_data;
742 }
743 
logical(ArmOp * op,bool invert,LogicalOp opc)744 static ut32 logical(ArmOp *op, bool invert, LogicalOp opc) {
745 	ut32 data = UT32_MAX;
746 	RegType reg_type = op->operands[0].reg_type;
747 
748 	// Reg types need to match
749 	if (!(reg_type == op->operands[1].reg_type)) {
750 		return data;
751 	}
752 
753 	OpType op2_type = op->operands[2].type;
754 	if (op2_type == ARM_CONSTANT) {
755 		if (invert) {
756 			/* there aren't inverted immediates in arm64 */
757 			return UT32_MAX;
758 		}
759 		if (reg_type & ARM_REG64) {
760 			data = 0x92000000;
761 		} else if (reg_type & ARM_REG32) {
762 			data = 0x12000000;
763 		} else {
764 			return UT32_MAX;
765 		}
766 
767 		bool is64bit = reg_type & ARM_REG64;
768 
769 		data |= op->operands[0].reg;
770 		data |= op->operands[1].reg << 5;
771 		data |= (opc & 3) << 29;
772 
773 		ut32 imm_orig = op->operands[2].immediate;
774 		ut32 imm = encodeBitMasksWithSize (invert? ~imm_orig: imm_orig, is64bit? 64: 32);
775 		if (imm == UT32_MAX) {
776 			return UT32_MAX;
777 		}
778 		data |= (imm & 0x1fff) << 10;
779 	} else if (op2_type == ARM_GPR) {
780 		if (reg_type & ARM_REG64) {
781 			data = 0x8a000000;
782 		} else if (reg_type & ARM_REG32) {
783 			data = 0x0a000000;
784 		} else {
785 			return UT32_MAX;
786 		}
787 
788 		data |= op->operands[0].reg;
789 		data |= op->operands[1].reg << 5;
790 		data |= op->operands[2].reg << 16;
791 		data |= (opc & 3) << 29;
792 
793 		if (op->operands_count == 4) {
794 			Operand shift_op = op->operands[3];
795 			if (shift_op.type == ARM_SHIFT) {
796 				data |= (shift_op.shift_amount & 0x3f) << 10;
797 				data |= (shift_op.shift & 0x3) << 22;
798 			}
799 		}
800 
801 		if (invert) {
802 			data |= 1 << 21;
803 		}
804 	} else {
805 		return UT32_MAX;
806 	}
807 
808 	return r_read_be32 (&data);
809 }
810 
adrp(ArmOp * op,ut64 addr,ut32 k)811 static ut32 adrp(ArmOp *op, ut64 addr, ut32 k) { //, int reg, ut64 dst) {
812 	ut64 at = 0LL;
813 	ut32 data = k;
814 	if (op->operands[0].type == ARM_GPR) {
815 		data |= encode1reg (op);
816 	} else {
817 		eprintf ("Usage: adrp x0, addr\n");
818 		return UT32_MAX;
819 	}
820 	if (op->operands[1].type == ARM_CONSTANT) {
821 		// XXX what about negative values?
822 		at = op->operands[1].immediate - addr;
823 		at /= 4;
824 	} else {
825 		eprintf ("Usage: adrp, x0, addr\n");
826 		return UT32_MAX;
827 	}
828 	ut8 b0 = at;
829 	ut8 b1 = (at >> 3) & 0xff;
830 
831 #if 0
832 	ut8 b2 = (at >> (8 + 7)) & 0xff;
833 	data += b0 << 29;
834 	data += b1 << 16;
835 	data += b2 << 24;
836 #endif
837 	data += b0 << 16;
838 	data += b1 << 8;
839 	return data;
840 }
841 
adr(ArmOp * op,int addr)842 static ut32 adr(ArmOp *op, int addr) {
843 	ut32 data = UT32_MAX;
844 	ut64 at = 0LL;
845 
846 	if (op->operands[1].type & ARM_CONSTANT) {
847 		// XXX what about negative values?
848 		at = op->operands[1].immediate - addr;
849 		at /= 4;
850 	}
851 	data = 0x00000030;
852 	data |= encode1reg (op);
853 	ut8 b0 = at;
854 	ut8 b1 = (at >> 3) & 0xff;
855 	ut8 b2 = (at >> (8 + 7)) & 0xff;
856 	data += b0 << 29;
857 	data += b1 << 16;
858 	data += b2 << 24;
859 	return data;
860 }
861 
stp(ArmOp * op,int k)862 static ut32 stp(ArmOp *op, int k) {
863 	ut32 data = UT32_MAX;
864 
865 	if (op->operands[3].immediate & 0x7) {
866 		return data;
867 	}
868 	if (k == 0x000040a9 && (op->operands[0].reg == op->operands[1].reg)) {
869 		return data;
870 	}
871 
872 	data = k;
873 	data |= encode2regs (op);
874 	data += (op->operands[3].immediate & 0x8) << 20;
875 	data += (op->operands[3].immediate >> 4) << 8;
876 	return data;
877 }
878 
exception(ArmOp * op,ut32 k)879 static ut32 exception(ArmOp *op, ut32 k) {
880 	ut32 data = UT32_MAX;
881 
882 	if (op->operands[0].type == ARM_CONSTANT) {
883 		int n = op->operands[0].immediate;
884 		data = k;
885 		data += (((n / 8) & 0xff) << 16);
886 		data += n << 29;//((n >> 8) << 8);
887 	}
888 	return data;
889 }
890 
arithmetic(ArmOp * op,int k)891 static ut32 arithmetic(ArmOp *op, int k) {
892 	ut32 data = UT32_MAX;
893 	if (op->operands_count < 3) {
894 		return data;
895 	}
896 
897 	if (!(op->operands[0].type & ARM_GPR &&
898 	      op->operands[1].type & ARM_GPR)) {
899 		return data;
900 	}
901 	if (op->operands[2].type & ARM_GPR) {
902 		k -= 6;
903 	}
904 
905 	data = k;
906 	data += encode1reg (op);
907 	data += (op->operands[1].reg & 7) << (24 + 5);
908 	data += (op->operands[1].reg >> 3) << 16;
909 	if (op->operands[2].type & ARM_GPR) {
910 		data += op->operands[2].reg << 8;
911 	} else {
912 		data += (op->operands[2].reg & 0x3f) << 18;
913 		data += (op->operands[2].reg >> 6) << 8;
914 	}
915 	return data;
916 }
917 
neg(ArmOp * op)918 static ut32 neg(ArmOp *op) {
919 	if (op->operands_count < 2) {
920 		return -1;
921 	}
922 	op->operands_count++;
923 	op->operands[2] = op->operands[1];
924 	op->operands[1].reg = 31; // xzr
925 
926 	return arithmetic (op, 0xd1); // sub reg0, xzr, reg1
927 }
928 
bitfield(ArmOp * op,int k)929 static ut32 bitfield(ArmOp *op, int k) {
930 	ut32 data = UT32_MAX;
931 	check_cond (op->operands_count == 4);
932 	check_cond (op->operands[0].type == ARM_GPR);
933 	check_cond (op->operands[1].type == ARM_GPR);
934 	check_cond (op->operands[0].reg_type == op->operands[1].reg_type);
935 	check_cond (op->operands[2].type == ARM_CONSTANT);
936 	check_cond (op->operands[3].type == ARM_CONSTANT);
937 	int bits = (op->operands[0].reg_type & ARM_REG64) ? 64 : 32;
938 	// unalias
939 	if (!strcmp (op->mnemonic, "sbfx") || !strcmp (op->mnemonic, "ubfx")) {
940 		op->operands[3].immediate += op->operands[2].immediate - 1;
941 	} else if (!strcmp (op->mnemonic, "sbfiz") || !strcmp (op->mnemonic, "ubfiz")) {
942 		check_cond (op->operands[2].immediate < bits);
943 		int temp = bits - op->operands[2].immediate;
944 		check_cond (op->operands[3].immediate <= temp);
945 		op->operands[2].immediate = temp & (bits - 1);
946 		op->operands[3].immediate--;
947 	}
948 	check_cond (op->operands[2].immediate < bits);
949 	check_cond (op->operands[3].immediate < bits);
950 	if (bits == 64) {
951 		k |= 0x00004080;
952 	}
953 	k |= op->operands[2].immediate << 8 | op->operands[3].immediate << 18;
954 	data = k | encode2regs (op);
955 	return data;
956 }
957 
parseOperands(char * str,ArmOp * op)958 static bool parseOperands(char* str, ArmOp *op) {
959 	char *t = strdup (str);
960 	int operand = 0;
961 	char *token = t;
962 	char *x;
963 	int imm_count = 0;
964 	int mem_opt = 0;
965 	int msr_op_index = 0;
966 	size_t index_bound = strcspn (t, "]");
967 	if (!token) {
968 		return false;
969 	}
970 
971 	while (token) {
972 		char *next = strchr (token, ',');
973 		if (next) {
974 			// Change the ',' in token to null byte
975 			// essentialy split the token by commas
976 			*next++ = '\0';
977 		}
978 		while (token[0] == ' ') {
979 			token++;
980 		}
981 		if (operand >= MAX_OPERANDS) {
982 			eprintf ("Too many operands\n");
983 			return false;
984 		}
985 		op->operands[operand].type = ARM_NOTYPE;
986 		op->operands[operand].reg_type = ARM_UNDEFINED;
987 
988 		//parse MSR (immediate) operand 1
989 		if (strcmp (op->mnemonic, "msr") == 0 && operand == 1) {
990 
991 			//operand 1 must be a immediate
992 			if ( token[0] == '#' || (token[0] >= '0' && token[0] <= '9')) {
993 				//immediate operand found.
994 				op->operands[operand].sp_val = 0xfffe; //not regiter, but a immediate
995 				op->operands[operand].immediate = r_num_math (NULL, token[0]=='#'?token+1:token);
996 				operand ++;
997 				token = next;
998 				continue;
999 			}
1000 		}
1001 
1002 		//parse system registers
1003 		if ((strcmp (op->mnemonic, "mrs") == 0 && operand == 1) || (strcmp (op->mnemonic, "msr") == 0 && operand == 0)) {
1004 			for(msr_op_index = 0; msr_const[msr_op_index].name; msr_op_index++) {
1005 				if (strcasecmp (token, msr_const[msr_op_index].name) == 0) {
1006 					op->operands_count ++;
1007 					op->operands[operand].type = ARM_CONSTANT;
1008 					op->operands[operand].immediate = msr_const[msr_op_index].val;
1009 					imm_count++;
1010 					break;
1011 				}
1012 			}
1013 			if (msr_const[msr_op_index].name) {
1014 				operand ++;
1015 				token = next;
1016 				continue;
1017 			}
1018 		}
1019 
1020 		while (token[0] == ' ' || token[0] == '[' || token[0] == ']') {
1021 			token ++;
1022 		}
1023 
1024 		if (!strncmp (token, "lsl", 3)) {
1025 			op->operands[operand].type = ARM_SHIFT;
1026 			op->operands[operand].shift = ARM_LSL;
1027 		} else if (!strncmp (token, "lsr", 3)) {
1028 			op->operands[operand].type = ARM_SHIFT;
1029 			op->operands[operand].shift = ARM_LSR;
1030 		} else if (!strncmp (token, "asr", 3)) {
1031 			op->operands[operand].type = ARM_SHIFT;
1032 			op->operands[operand].shift = ARM_ASR;
1033 		} else if (!strncmp (token, "ror", 3)) {
1034 			op->operands[operand].type = ARM_SHIFT;
1035 			op->operands[operand].shift = ARM_ROR;
1036 		} else if (!strncmp (token, "uxtb", 4)) {
1037 			op->operands[operand].type = ARM_EXTEND;
1038 			op->operands[operand].shift = ARM_UXTB;
1039 		} else if (!strncmp (token, "uxth", 4)) {
1040 			op->operands[operand].type = ARM_EXTEND;
1041 			op->operands[operand].shift = ARM_UXTH;
1042 		} else if (!strncmp (token, "uxtw", 4)) {
1043 			op->operands[operand].type = ARM_EXTEND;
1044 			op->operands[operand].shift = ARM_UXTW;
1045 		} else if (!strncmp (token, "uxtx", 4)) {
1046 			op->operands[operand].type = ARM_EXTEND;
1047 			op->operands[operand].shift = ARM_UXTX;
1048 		} else if (!strncmp (token, "sxtb", 4)) {
1049 			op->operands[operand].type = ARM_EXTEND;
1050 			op->operands[operand].shift = ARM_SXTB;
1051 		} else if (!strncmp (token, "sxth", 4)) {
1052 			op->operands[operand].type = ARM_EXTEND;
1053 			op->operands[operand].shift = ARM_SXTH;
1054 		} else if (!strncmp (token, "sxtw", 4)) {
1055 			op->operands[operand].type = ARM_EXTEND;
1056 			op->operands[operand].shift = ARM_SXTW;
1057 		} else if (!strncmp (token, "sxtx", 4)) {
1058 			op->operands[operand].type = ARM_EXTEND;
1059 			op->operands[operand].shift = ARM_SXTX;
1060 		}
1061 		if (op->operands[operand].type == ARM_SHIFT) {
1062 			op->operands_count ++;
1063 			token += 3;
1064 			while (*token && *token == ' ') {
1065 				token++;
1066 			}
1067 			if (*token == '#') {
1068 				token++;
1069 			}
1070 			if (!*token || !isdigit((unsigned char)*token)) {
1071 				return false;
1072 			}
1073 			op->operands[operand].shift_amount = r_num_math (NULL, token);
1074 			op->operands[operand].amount_present = true;
1075 			if (op->operands[operand].shift_amount > 63) {
1076 				free (t);
1077 				return false;
1078 			}
1079 			operand ++;
1080 			token = next;
1081 			continue;
1082 		}
1083 		if (op->operands[operand].type == ARM_EXTEND) {
1084 			op->operands_count++;
1085 			token += 4;
1086 			while (*token && *token == ' ') {
1087 				token++;
1088 			}
1089 			bool present = false;
1090 			if (*token == '#') {
1091 				present = true;
1092 				++token;
1093 			}
1094 			if (!*token || !isdigit((unsigned char)*token)) {
1095 				if (present) {
1096 					return false;
1097 				}
1098 				op->operands[operand].shift_amount = 0;
1099 				op->operands[operand].amount_present = false;
1100 			} else {
1101 				op->operands[operand].shift_amount = r_num_math (NULL, token);
1102 				op->operands[operand].amount_present = true;
1103 			}
1104 			operand++;
1105 			token = next;
1106 			continue;
1107 		}
1108 
1109 		switch (token[0]) {
1110 		case 'x':
1111 			x = strchr (token, ',');
1112 			if (x) {
1113 				x[0] = '\0';
1114 			}
1115 			op->operands_count ++;
1116 			op->operands[operand].type = ARM_GPR;
1117 			op->operands[operand].reg_type = ARM_REG64;
1118 
1119 			if (!strncmp(token + 1, "zr", 2)) {
1120 				// XZR
1121 				op->operands[operand].reg = 31;
1122 			} else {
1123 				op->operands[operand].reg = r_num_math (NULL, token + 1);
1124 			}
1125 
1126 			if (op->operands[operand].reg > 31) {
1127 				free (t);
1128 				return false;
1129 			}
1130 			break;
1131 		case 'w':
1132 			op->operands_count ++;
1133 			op->operands[operand].type = ARM_GPR;
1134 			op->operands[operand].reg_type = ARM_REG32;
1135 
1136 			if (!strncmp(token + 1, "zr", 2)) {
1137 				// WZR
1138 				op->operands[operand].reg = 31;
1139 			} else if (!strncmp(token + 1, "sp", 2)) {
1140 				// WSP
1141 				op->operands[operand].reg = 31;
1142 				op->operands[operand].reg_type |= ARM_SP;
1143 			} else {
1144 				op->operands[operand].reg = r_num_math (NULL, token + 1);
1145 			}
1146 
1147 			if (op->operands[operand].reg > 31) {
1148 				free (t);
1149 				return false;
1150 			}
1151 			break;
1152 		case 'v':
1153 			op->operands_count ++;
1154 			op->operands[operand].type = ARM_FP;
1155 			op->operands[operand].reg = r_num_math (NULL, token + 1);
1156 			break;
1157 		case 's':
1158 		case 'S':
1159 			if (token[1] == 'P' || token [1] == 'p') {
1160 				int i;
1161 				for (i = 0; msr_const[i].name; i++) {
1162 					if (!r_str_ncasecmp (token, msr_const[i].name, strlen (msr_const[i].name))) {
1163 						op->operands[operand].sp_val = msr_const[i].val;
1164 						break;
1165 					}
1166 				}
1167 				op->operands_count ++;
1168 				op->operands[operand].type = ARM_GPR;
1169 				op->operands[operand].reg_type = ARM_SP | ARM_REG64;
1170 				op->operands[operand].reg = 31;
1171 				break;
1172 			}
1173 			mem_opt = get_mem_option (token);
1174 			if (mem_opt != -1) {
1175 				op->operands_count ++;
1176 				op->operands[operand].type = ARM_MEM_OPT;
1177 				op->operands[operand].mem_option = mem_opt;
1178 			}
1179 			break;
1180 		case 'L':
1181 		case 'l':
1182 		case 'I':
1183 		case 'i':
1184 		case 'N':
1185 		case 'n':
1186 		case 'O':
1187 		case 'o':
1188 		case 'p':
1189 		case 'P':
1190 			mem_opt = get_mem_option (token);
1191 			if (mem_opt != -1) {
1192 				op->operands_count ++;
1193 				op->operands[operand].type = ARM_MEM_OPT;
1194 				op->operands[operand].mem_option = mem_opt;
1195 			}
1196 			break;
1197 		case '#':
1198 			if (token[1] == '-') {
1199 				op->operands[operand].sign = -1;
1200 			}
1201 			op->operands_count ++;
1202 			op->operands[operand].type = ARM_CONSTANT;
1203 			op->operands[operand].immediate = r_num_math (NULL, token + 1);
1204 			op->operands[operand].preindex = token - t < index_bound;
1205 			imm_count++;
1206 			break;
1207 		case '-':
1208 			op->operands[operand].sign = -1;
1209 			// falthru
1210 		default:
1211 			op->operands_count ++;
1212 			op->operands[operand].type = ARM_CONSTANT;
1213 			op->operands[operand].immediate = r_num_math (NULL, token);
1214 			op->operands[operand].preindex = token - t < index_bound;
1215 			imm_count++;
1216 			break;
1217 		}
1218 		token = next;
1219 
1220 		operand ++;
1221 		if (operand > MAX_OPERANDS) {
1222 			free (t);
1223 			return false;
1224 		}
1225 	}
1226 	free (t);
1227 	return true;
1228 }
1229 
parseOpcode(const char * str,ArmOp * op)1230 static bool parseOpcode(const char *str, ArmOp *op) {
1231 	char *in = strdup (str);
1232 	char *space = strchr (in, ' ');
1233 	if (!space) {
1234 		op->operands[0].type = ARM_NOTYPE;
1235 		op->mnemonic = in;
1236  		return true;
1237 	}
1238 	space[0] = '\0';
1239 	op->mnemonic = in;
1240 	space ++;
1241 	op->writeback = strstr (space, "]!") != NULL;
1242 	return parseOperands (space, op);
1243 }
1244 
handlePAC(ut32 * op,const char * str)1245 static bool handlePAC(ut32 *op, const char *str) {
1246 	if (!strcmp (str, "autiasp")) {
1247 		*op = 0xbf2303d5;
1248 		return true;
1249 	}
1250 	if (!strcmp (str, "autiaz")) {
1251 		*op = 0x9f2303d5;
1252 		return true;
1253 	}
1254 	if (!strcmp (str, "autibsp")) {
1255 		*op = 0xff2303d5;
1256 		return true;
1257 	}
1258 	if (!strcmp (str, "autibz")) {
1259 		*op = 0xdf2303d5;
1260 		return true;
1261 	}
1262 	if (!strcmp (str, "paciaz")) {
1263 		*op = 0x1f2303d5;
1264 		return true;
1265 	}
1266 	if (!strcmp (str, "pacibz")) {
1267 		*op = 0x5f2303d5;
1268 		return true;
1269 	}
1270 	if (!strcmp (str, "paciasp")) {
1271 		*op = 0x3f2303d5;
1272 		return true;
1273 	}
1274 	if (!strcmp (str, "pacibsp")) {
1275 		*op = 0x7f2303d5;
1276 		return true;
1277 	}
1278 	if (!strcmp (str, "retab")) {
1279 		*op = 0xff0f5fd6;
1280 		return true;
1281 	}
1282 	return false;
1283 }
1284 
arm64ass(const char * str,ut64 addr,ut32 * op)1285 bool arm64ass(const char *str, ut64 addr, ut32 *op) {
1286 	ArmOp ops = {0};
1287 	if (!parseOpcode (str, &ops)) {
1288 		free (ops.mnemonic);
1289 		return false;
1290 	}
1291 	/* TODO: write tests for this and move out the regsize logic into the mov */
1292 	if (!strncmp (str, "mov", 3)) {
1293 		*op = mov (&ops);
1294 	} else if (!strncmp (str, "cb", 2)) {
1295 		*op = cb (&ops);
1296 	} else if (!strncmp (str, "cmp", 3)) {
1297 		*op = cmp (&ops);
1298 	} else if (!strncmp (str, "ldrb", 4)) {
1299 		*op = lsop (&ops, 0x00004038, -1);
1300 	} else if (!strncmp (str, "ldrh", 4)) {
1301 		*op = lsop (&ops, 0x00004078, -1);
1302 	} else if (!strncmp (str, "ldrsh", 5)) {
1303 		*op = lsop (&ops, 0x00008078, -1);
1304 	} else if (!strncmp (str, "ldrsw", 5)) {
1305 		*op = lsop (&ops, 0x00000098, addr);
1306 	} else if (!strncmp (str, "ldrsb", 5)) {
1307 		*op = lsop (&ops, 0x00008038, -1);
1308 	} else if (!strncmp (str, "strb", 4)) {
1309 		*op = lsop (&ops, 0x00000038, -1);
1310 	} else if (!strncmp (str, "strh", 4)) {
1311 		*op = lsop (&ops, 0x00000078, -1);
1312 	} else if (!strncmp (str, "ldr", 3)) {
1313 		*op = reglsop (&ops, 0x000040f8);
1314 	} else if (!strncmp (str, "stur", 4)) {
1315 		*op = regsluop (&ops, 0x000000f8);
1316 	} else if (!strncmp (str, "ldur", 4)) {
1317 		*op = regsluop (&ops, 0x000040f8);
1318 	} else if (!strncmp (str, "str", 3)) {
1319 		*op = reglsop (&ops, 0x000000f8);
1320 	} else if (!strncmp (str, "stp", 3)) {
1321 		*op = stp (&ops, 0x000000a9);
1322 	} else if (!strncmp (str, "ldp", 3)) {
1323 		*op = stp (&ops, 0x000040a9);
1324 	} else if (!strncmp (str, "sub", 3)) { // w
1325 		*op = arithmetic (&ops, 0xd1);
1326 	} else if (!strncmp (str, "add x", 5)) {
1327 		*op = arithmetic (&ops, 0x91);
1328 	} else if (!strncmp (str, "add w", 5)) {
1329 		*op = arithmetic (&ops, 0x11);
1330 	} else if (!strncmp (str, "adr x", 5)) { // w
1331 		*op = adr (&ops, addr);
1332 	} else if (!strncmp (str, "adrp x", 6)) {
1333 		*op = adrp (&ops, addr, 0x00000090);
1334 	} else if (!strncmp (str, "neg", 3)) {
1335 		*op = neg (&ops);
1336 	} else if (!strcmp (str, "isb")) {
1337 		*op = 0xdf3f03d5;
1338 	} else if (handlePAC (op, str)) { // PAC
1339 		free (ops.mnemonic);
1340 		return true;
1341 	} else if (!strcmp (str, "nop")) {
1342 		*op = 0x1f2003d5;
1343 	} else if (!strcmp (str, "ret")) {
1344 		*op = 0xc0035fd6;
1345 	} else if (!strncmp (str, "msr ", 4)) {
1346 		*op = msr (&ops, 0);
1347 	} else if (!strncmp (str, "mrs ", 4)) {
1348 		*op = msr (&ops, 1);
1349 	} else if (!strncmp (str, "ands ", 5)) {
1350 		*op = logical (&ops, false, ARM_ANDS);
1351 	} else if (!strncmp (str, "and ", 4)) {
1352 		*op = logical (&ops, false, ARM_AND);
1353 	} else if (!strncmp (str, "bics ", 5)) {
1354 		*op = logical (&ops, true, ARM_ANDS);
1355 	} else if (!strncmp (str, "bic ", 4)) {
1356 		*op = logical (&ops, true, ARM_AND);
1357 	} else if (!strncmp (str, "eon ", 4)) {
1358 		*op = logical (&ops, true, ARM_EOR);
1359 	} else if (!strncmp (str, "eor ", 4)) {
1360 		*op = logical (&ops, false, ARM_EOR);
1361 	} else if (!strncmp (str, "orn ", 4)) {
1362 		*op = logical (&ops, true, ARM_ORR);
1363 	} else if (!strncmp (str, "orr ", 4)) {
1364 		*op = logical (&ops, false, ARM_ORR);
1365 	} else if (!strncmp (str, "svc ", 4)) { // system level exception
1366 		*op = exception (&ops, 0x010000d4);
1367 	} else if (!strncmp (str, "hvc ", 4)) { // hypervisor level exception
1368 		*op = exception (&ops, 0x020000d4);
1369 	} else if (!strncmp (str, "smc ", 4)) { // secure monitor exception
1370 		*op = exception (&ops, 0x030000d4);
1371 	} else if (!strncmp (str, "brk ", 4)) { // breakpoint
1372 		*op = exception (&ops, 0x000020d4);
1373 	} else if (!strncmp (str, "hlt ", 4)) { // halt
1374 		*op = exception (&ops, 0x000040d4);
1375 	} else if (!strncmp (str, "b ", 2)) {
1376 		*op = branch (&ops, addr, 0x14);
1377 	} else if (!strncmp (str, "b.eq ", 5)) {
1378 		*op = bdot (&ops, addr, 0x00000054);
1379 	} else if (!strncmp (str, "b.hs ", 5)) {
1380 		*op = bdot (&ops, addr, 0x02000054);
1381 	} else if (!strncmp (str, "bl ", 3)) {
1382 		*op = branch (&ops, addr, 0x94);
1383 	} else if (!strncmp (str, "br x", 4)) {
1384 		*op = branch (&ops, addr, 0x1fd6);
1385 	} else if (!strncmp (str, "blr x", 5)) {
1386 		*op = branch (&ops, addr, 0x3fd6);
1387 	} else if (!strncmp (str, "dmb ", 4)) {
1388 		*op = mem_barrier (&ops, addr, 0xbf3003d5);
1389 	} else if (!strncmp (str, "dsb ", 4)) {
1390 		*op = mem_barrier (&ops, addr, 0x9f3003d5);
1391 	} else if (!strncmp (str, "isb", 3)) {
1392 		*op = mem_barrier (&ops, addr, 0xdf3f03d5);
1393 	} else if (!strncmp (str, "sbfiz ", 6) || !strncmp (str, "sbfm ", 5)
1394 		|| !strncmp (str, "sbfx ", 5)) {
1395 		*op = bitfield (&ops, 0x00000013);
1396 	} else if (!strncmp (str, "ubfiz ", 6) || !strncmp (str, "ubfm ", 5)
1397 		|| !strncmp (str, "ubfx ", 5)) {
1398 		*op = bitfield (&ops, 0x00000053);
1399 	}
1400 	free (ops.mnemonic);
1401 	return *op != UT32_MAX;
1402 }
1403