8e783d3425f303b669c70fe178408cd4628f7b39
[openocd.git] / src / target / arm_disassembler.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2009 by David Brownell *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "target.h"
26 #include "arm_disassembler.h"
27 #include <helper/log.h>
28
29 /*
30 * This disassembler supports two main functions for OpenOCD:
31 *
32 * - Various "disassemble" commands. OpenOCD can serve as a
33 * machine-language debugger, without help from GDB.
34 *
35 * - Single stepping. Not all ARM cores support hardware single
36 * stepping. To work without that support, the debugger must
37 * be able to decode instructions to find out where to put a
38 * "next instruction" breakpoint.
39 *
40 * In addition, interpretation of ETM trace data needs some of the
41 * decoding mechanisms.
42 *
43 * At this writing (September 2009) neither function is complete.
44 *
45 * - ARM decoding
46 * * Old-style syntax (not UAL) is generally used
47 * * VFP instructions are not understood (ARMv5 and later)
48 * except as coprocessor 10/11 operations
49 * * Most ARM instructions through ARMv6 are decoded, but some
50 * of the post-ARMv4 opcodes may not be handled yet
51 * CPS, SDIV, UDIV, LDREX*, STREX*, QASX, ...
52 * * NEON instructions are not understood (ARMv7-A)
53 *
54 * - Thumb/Thumb2 decoding
55 * * UAL syntax should be consistently used
56 * * Any Thumb2 instructions used in Cortex-M3 (ARMv7-M) should
57 * be handled properly. Accordingly, so should the subset
58 * used in Cortex-M0/M1; and "original" 16-bit Thumb from
59 * ARMv4T and ARMv5T.
60 * * Conditional effects of Thumb2 "IT" (if-then) instructions
61 * are not handled: the affected instructions are not shown
62 * with their now-conditional suffixes.
63 * * Some ARMv6 and ARMv7-M Thumb2 instructions may not be
64 * handled (minimally for coprocessor access).
65 * * SIMD instructions, and some other Thumb2 instructions
66 * from ARMv7-A, are not understood.
67 *
68 * - ThumbEE decoding
69 * * As a Thumb2 variant, the Thumb2 comments (above) apply.
70 * * Opcodes changed by ThumbEE mode are not handled; these
71 * instructions wrongly decode as LDM and STM.
72 *
73 * - Jazelle decoding ... no support whatsoever for Jazelle mode
74 * or decoding. ARM encourages use of the more generic ThumbEE
75 * mode, instead of Jazelle mode, in current chips.
76 *
77 * - Single-step/emulation ... spotty support, which is only weakly
78 * tested. Thumb2 is not supported. (Arguably a full simulator
79 * is not needed to support just single stepping. Recognizing
80 * branch vs non-branch instructions suffices, except when the
81 * instruction faults and triggers a synchronous exception which
82 * can be intercepted using other means.)
83 *
84 * ARM DDI 0406B "ARM Architecture Reference Manual, ARM v7-A and
85 * ARM v7-R edition" gives the most complete coverage of the various
86 * generations of ARM instructions. At this writing it is publicly
87 * accessible to anyone willing to create an account at the ARM
88 * web site; see http://www.arm.com/documentation/ for information.
89 *
90 * ARM DDI 0403C "ARMv7-M Architecture Reference Manual" provides
91 * more details relevant to the Thumb2-only processors (such as
92 * the Cortex-M implementations).
93 */
94
95 /* textual represenation of the condition field
96 * ALways (default) is ommitted (empty string) */
97 static const char *arm_condition_strings[] = {
98 "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
99 };
100
101 /* make up for C's missing ROR */
102 static uint32_t ror(uint32_t value, int places)
103 {
104 return (value >> places) | (value << (32 - places));
105 }
106
107 static int evaluate_unknown(uint32_t opcode,
108 uint32_t address, struct arm_instruction *instruction)
109 {
110 instruction->type = ARM_UNDEFINED_INSTRUCTION;
111 snprintf(instruction->text, 128,
112 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
113 "\tUNDEFINED INSTRUCTION", address, opcode);
114 return ERROR_OK;
115 }
116
117 static int evaluate_pld(uint32_t opcode,
118 uint32_t address, struct arm_instruction *instruction)
119 {
120 /* PLD */
121 if ((opcode & 0x0d70f000) == 0x0550f000) {
122 instruction->type = ARM_PLD;
123
124 snprintf(instruction->text,
125 128,
126 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...",
127 address,
128 opcode);
129
130 return ERROR_OK;
131 }
132 /* DSB */
133 if ((opcode & 0x07f000f0) == 0x05700040) {
134 instruction->type = ARM_DSB;
135
136 char *opt;
137 switch (opcode & 0x0000000f) {
138 case 0xf:
139 opt = "SY";
140 break;
141 case 0xe:
142 opt = "ST";
143 break;
144 case 0xb:
145 opt = "ISH";
146 break;
147 case 0xa:
148 opt = "ISHST";
149 break;
150 case 0x7:
151 opt = "NSH";
152 break;
153 case 0x6:
154 opt = "NSHST";
155 break;
156 case 0x3:
157 opt = "OSH";
158 break;
159 case 0x2:
160 opt = "OSHST";
161 break;
162 default:
163 opt = "UNK";
164 }
165
166 snprintf(instruction->text,
167 128,
168 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB %s",
169 address, opcode, opt);
170
171 return ERROR_OK;
172 }
173 /* ISB */
174 if ((opcode & 0x07f000f0) == 0x05700060) {
175 instruction->type = ARM_ISB;
176
177 snprintf(instruction->text,
178 128,
179 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISB %s",
180 address, opcode,
181 ((opcode & 0x0000000f) == 0xf) ? "SY" : "UNK");
182
183 return ERROR_OK;
184 }
185 return evaluate_unknown(opcode, address, instruction);
186 }
187
188 static int evaluate_srs(uint32_t opcode,
189 uint32_t address, struct arm_instruction *instruction)
190 {
191 const char *wback = (opcode & (1 << 21)) ? "!" : "";
192 const char *mode = "";
193
194 switch ((opcode >> 23) & 0x3) {
195 case 0:
196 mode = "DA";
197 break;
198 case 1:
199 /* "IA" is default */
200 break;
201 case 2:
202 mode = "DB";
203 break;
204 case 3:
205 mode = "IB";
206 break;
207 }
208
209 switch (opcode & 0x0e500000) {
210 case 0x08400000:
211 snprintf(instruction->text, 128, "0x%8.8" PRIx32
212 "\t0x%8.8" PRIx32
213 "\tSRS%s\tSP%s, #%d",
214 address, opcode,
215 mode, wback,
216 (unsigned)(opcode & 0x1f));
217 break;
218 case 0x08100000:
219 snprintf(instruction->text, 128, "0x%8.8" PRIx32
220 "\t0x%8.8" PRIx32
221 "\tRFE%s\tr%d%s",
222 address, opcode,
223 mode,
224 (unsigned)((opcode >> 16) & 0xf), wback);
225 break;
226 default:
227 return evaluate_unknown(opcode, address, instruction);
228 }
229 return ERROR_OK;
230 }
231
232 static int evaluate_swi(uint32_t opcode,
233 uint32_t address, struct arm_instruction *instruction)
234 {
235 instruction->type = ARM_SWI;
236
237 snprintf(instruction->text, 128,
238 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSVC %#6.6" PRIx32,
239 address, opcode, (opcode & 0xffffff));
240
241 return ERROR_OK;
242 }
243
244 static int evaluate_blx_imm(uint32_t opcode,
245 uint32_t address, struct arm_instruction *instruction)
246 {
247 int offset;
248 uint32_t immediate;
249 uint32_t target_address;
250
251 instruction->type = ARM_BLX;
252 immediate = opcode & 0x00ffffff;
253
254 /* sign extend 24-bit immediate */
255 if (immediate & 0x00800000)
256 offset = 0xff000000 | immediate;
257 else
258 offset = immediate;
259
260 /* shift two bits left */
261 offset <<= 2;
262
263 /* odd/event halfword */
264 if (opcode & 0x01000000)
265 offset |= 0x2;
266
267 target_address = address + 8 + offset;
268
269 snprintf(instruction->text,
270 128,
271 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "",
272 address,
273 opcode,
274 target_address);
275
276 instruction->info.b_bl_bx_blx.reg_operand = -1;
277 instruction->info.b_bl_bx_blx.target_address = target_address;
278
279 return ERROR_OK;
280 }
281
282 static int evaluate_b_bl(uint32_t opcode,
283 uint32_t address, struct arm_instruction *instruction)
284 {
285 uint8_t L;
286 uint32_t immediate;
287 int offset;
288 uint32_t target_address;
289
290 immediate = opcode & 0x00ffffff;
291 L = (opcode & 0x01000000) >> 24;
292
293 /* sign extend 24-bit immediate */
294 if (immediate & 0x00800000)
295 offset = 0xff000000 | immediate;
296 else
297 offset = immediate;
298
299 /* shift two bits left */
300 offset <<= 2;
301
302 target_address = address + 8 + offset;
303
304 if (L)
305 instruction->type = ARM_BL;
306 else
307 instruction->type = ARM_B;
308
309 snprintf(instruction->text,
310 128,
311 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32,
312 address,
313 opcode,
314 (L) ? "L" : "",
315 COND(opcode),
316 target_address);
317
318 instruction->info.b_bl_bx_blx.reg_operand = -1;
319 instruction->info.b_bl_bx_blx.target_address = target_address;
320
321 return ERROR_OK;
322 }
323
324 /* Coprocessor load/store and double register transfers
325 * both normal and extended instruction space (condition field b1111) */
326 static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
327 uint32_t address, struct arm_instruction *instruction)
328 {
329 uint8_t cp_num = (opcode & 0xf00) >> 8;
330
331 /* MCRR or MRRC */
332 if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c500000)) {
333 uint8_t cp_opcode, Rd, Rn, CRm;
334 char *mnemonic;
335
336 cp_opcode = (opcode & 0xf0) >> 4;
337 Rd = (opcode & 0xf000) >> 12;
338 Rn = (opcode & 0xf0000) >> 16;
339 CRm = (opcode & 0xf);
340
341 /* MCRR */
342 if ((opcode & 0x0ff00000) == 0x0c400000) {
343 instruction->type = ARM_MCRR;
344 mnemonic = "MCRR";
345 } else if ((opcode & 0x0ff00000) == 0x0c500000) {
346 /* MRRC */
347 instruction->type = ARM_MRRC;
348 mnemonic = "MRRC";
349 } else {
350 LOG_ERROR("Unknown instruction");
351 return ERROR_FAIL;
352 }
353
354 snprintf(instruction->text, 128,
355 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
356 "\t%s%s%s p%i, %x, r%i, r%i, c%i",
357 address, opcode, mnemonic,
358 ((opcode & 0xf0000000) == 0xf0000000)
359 ? "2" : COND(opcode),
360 COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
361 } else {/* LDC or STC */
362 uint8_t CRd, Rn, offset;
363 uint8_t U;
364 char *mnemonic;
365 char addressing_mode[32];
366
367 CRd = (opcode & 0xf000) >> 12;
368 Rn = (opcode & 0xf0000) >> 16;
369 offset = (opcode & 0xff) << 2;
370
371 /* load/store */
372 if (opcode & 0x00100000) {
373 instruction->type = ARM_LDC;
374 mnemonic = "LDC";
375 } else {
376 instruction->type = ARM_STC;
377 mnemonic = "STC";
378 }
379
380 U = (opcode & 0x00800000) >> 23;
381
382 /* addressing modes */
383 if ((opcode & 0x01200000) == 0x01000000)/* offset */
384 snprintf(addressing_mode, 32, "[r%i, #%s%d]",
385 Rn, U ? "" : "-", offset);
386 else if ((opcode & 0x01200000) == 0x01200000) /* pre-indexed */
387 snprintf(addressing_mode, 32, "[r%i, #%s%d]!",
388 Rn, U ? "" : "-", offset);
389 else if ((opcode & 0x01200000) == 0x00200000) /* post-indexed */
390 snprintf(addressing_mode, 32, "[r%i], #%s%d",
391 Rn, U ? "" : "-", offset);
392 else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
393 snprintf(addressing_mode, 32, "[r%i], {%d}",
394 Rn, offset >> 2);
395
396 snprintf(instruction->text, 128, "0x%8.8" PRIx32
397 "\t0x%8.8" PRIx32
398 "\t%s%s%s p%i, c%i, %s",
399 address, opcode, mnemonic,
400 ((opcode & 0xf0000000) == 0xf0000000)
401 ? "2" : COND(opcode),
402 (opcode & (1 << 22)) ? "L" : "",
403 cp_num, CRd, addressing_mode);
404 }
405
406 return ERROR_OK;
407 }
408
409 /* Coprocessor data processing instructions
410 * Coprocessor register transfer instructions
411 * both normal and extended instruction space (condition field b1111) */
412 static int evaluate_cdp_mcr_mrc(uint32_t opcode,
413 uint32_t address, struct arm_instruction *instruction)
414 {
415 const char *cond;
416 char *mnemonic;
417 uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
418
419 cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
420 cp_num = (opcode & 0xf00) >> 8;
421 CRd_Rd = (opcode & 0xf000) >> 12;
422 CRn = (opcode & 0xf0000) >> 16;
423 CRm = (opcode & 0xf);
424 opcode_2 = (opcode & 0xe0) >> 5;
425
426 /* CDP or MRC/MCR */
427 if (opcode & 0x00000010) { /* bit 4 set -> MRC/MCR */
428 if (opcode & 0x00100000) { /* bit 20 set -> MRC */
429 instruction->type = ARM_MRC;
430 mnemonic = "MRC";
431 } else {/* bit 20 not set -> MCR */
432 instruction->type = ARM_MCR;
433 mnemonic = "MCR";
434 }
435
436 opcode_1 = (opcode & 0x00e00000) >> 21;
437
438 snprintf(instruction->text,
439 128,
440 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x",
441 address,
442 opcode,
443 mnemonic,
444 cond,
445 cp_num,
446 opcode_1,
447 CRd_Rd,
448 CRn,
449 CRm,
450 opcode_2);
451 } else {/* bit 4 not set -> CDP */
452 instruction->type = ARM_CDP;
453 mnemonic = "CDP";
454
455 opcode_1 = (opcode & 0x00f00000) >> 20;
456
457 snprintf(instruction->text,
458 128,
459 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x",
460 address,
461 opcode,
462 mnemonic,
463 cond,
464 cp_num,
465 opcode_1,
466 CRd_Rd,
467 CRn,
468 CRm,
469 opcode_2);
470 }
471
472 return ERROR_OK;
473 }
474
475 /* Load/store instructions */
476 static int evaluate_load_store(uint32_t opcode,
477 uint32_t address, struct arm_instruction *instruction)
478 {
479 uint8_t I, P, U, B, W, L;
480 uint8_t Rn, Rd;
481 char *operation;/* "LDR" or "STR" */
482 char *suffix; /* "", "B", "T", "BT" */
483 char offset[32];
484
485 /* examine flags */
486 I = (opcode & 0x02000000) >> 25;
487 P = (opcode & 0x01000000) >> 24;
488 U = (opcode & 0x00800000) >> 23;
489 B = (opcode & 0x00400000) >> 22;
490 W = (opcode & 0x00200000) >> 21;
491 L = (opcode & 0x00100000) >> 20;
492
493 /* target register */
494 Rd = (opcode & 0xf000) >> 12;
495
496 /* base register */
497 Rn = (opcode & 0xf0000) >> 16;
498
499 instruction->info.load_store.Rd = Rd;
500 instruction->info.load_store.Rn = Rn;
501 instruction->info.load_store.U = U;
502
503 /* determine operation */
504 if (L)
505 operation = "LDR";
506 else
507 operation = "STR";
508
509 /* determine instruction type and suffix */
510 if (B) {
511 if ((P == 0) && (W == 1)) {
512 if (L)
513 instruction->type = ARM_LDRBT;
514 else
515 instruction->type = ARM_STRBT;
516 suffix = "BT";
517 } else {
518 if (L)
519 instruction->type = ARM_LDRB;
520 else
521 instruction->type = ARM_STRB;
522 suffix = "B";
523 }
524 } else {
525 if ((P == 0) && (W == 1)) {
526 if (L)
527 instruction->type = ARM_LDRT;
528 else
529 instruction->type = ARM_STRT;
530 suffix = "T";
531 } else {
532 if (L)
533 instruction->type = ARM_LDR;
534 else
535 instruction->type = ARM_STR;
536 suffix = "";
537 }
538 }
539
540 if (!I) { /* #+-<offset_12> */
541 uint32_t offset_12 = (opcode & 0xfff);
542 if (offset_12)
543 snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
544 else
545 snprintf(offset, 32, "%s", "");
546
547 instruction->info.load_store.offset_mode = 0;
548 instruction->info.load_store.offset.offset = offset_12;
549 } else {/* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
550 uint8_t shift_imm, shift;
551 uint8_t Rm;
552
553 shift_imm = (opcode & 0xf80) >> 7;
554 shift = (opcode & 0x60) >> 5;
555 Rm = (opcode & 0xf);
556
557 /* LSR encodes a shift by 32 bit as 0x0 */
558 if ((shift == 0x1) && (shift_imm == 0x0))
559 shift_imm = 0x20;
560
561 /* ASR encodes a shift by 32 bit as 0x0 */
562 if ((shift == 0x2) && (shift_imm == 0x0))
563 shift_imm = 0x20;
564
565 /* ROR by 32 bit is actually a RRX */
566 if ((shift == 0x3) && (shift_imm == 0x0))
567 shift = 0x4;
568
569 instruction->info.load_store.offset_mode = 1;
570 instruction->info.load_store.offset.reg.Rm = Rm;
571 instruction->info.load_store.offset.reg.shift = shift;
572 instruction->info.load_store.offset.reg.shift_imm = shift_imm;
573
574 if ((shift_imm == 0x0) && (shift == 0x0)) /* +-<Rm> */
575 snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm);
576 else { /* +-<Rm>, <Shift>, #<shift_imm> */
577 switch (shift) {
578 case 0x0: /* LSL */
579 snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
580 break;
581 case 0x1: /* LSR */
582 snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
583 break;
584 case 0x2: /* ASR */
585 snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
586 break;
587 case 0x3: /* ROR */
588 snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
589 break;
590 case 0x4: /* RRX */
591 snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm);
592 break;
593 }
594 }
595 }
596
597 if (P == 1) {
598 if (W == 0) { /* offset */
599 snprintf(instruction->text,
600 128,
601 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
602 address,
603 opcode,
604 operation,
605 COND(opcode),
606 suffix,
607 Rd,
608 Rn,
609 offset);
610
611 instruction->info.load_store.index_mode = 0;
612 } else {/* pre-indexed */
613 snprintf(instruction->text,
614 128,
615 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
616 address,
617 opcode,
618 operation,
619 COND(opcode),
620 suffix,
621 Rd,
622 Rn,
623 offset);
624
625 instruction->info.load_store.index_mode = 1;
626 }
627 } else {/* post-indexed */
628 snprintf(instruction->text,
629 128,
630 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
631 address,
632 opcode,
633 operation,
634 COND(opcode),
635 suffix,
636 Rd,
637 Rn,
638 offset);
639
640 instruction->info.load_store.index_mode = 2;
641 }
642
643 return ERROR_OK;
644 }
645
646 static int evaluate_extend(uint32_t opcode, uint32_t address, char *cp)
647 {
648 unsigned rm = (opcode >> 0) & 0xf;
649 unsigned rd = (opcode >> 12) & 0xf;
650 unsigned rn = (opcode >> 16) & 0xf;
651 char *type, *rot;
652
653 switch ((opcode >> 24) & 0x3) {
654 case 0:
655 type = "B16";
656 break;
657 case 1:
658 sprintf(cp, "UNDEFINED");
659 return ARM_UNDEFINED_INSTRUCTION;
660 case 2:
661 type = "B";
662 break;
663 default:
664 type = "H";
665 break;
666 }
667
668 switch ((opcode >> 10) & 0x3) {
669 case 0:
670 rot = "";
671 break;
672 case 1:
673 rot = ", ROR #8";
674 break;
675 case 2:
676 rot = ", ROR #16";
677 break;
678 default:
679 rot = ", ROR #24";
680 break;
681 }
682
683 if (rn == 0xf) {
684 sprintf(cp, "%cXT%s%s\tr%d, r%d%s",
685 (opcode & (1 << 22)) ? 'U' : 'S',
686 type, COND(opcode),
687 rd, rm, rot);
688 return ARM_MOV;
689 } else {
690 sprintf(cp, "%cXTA%s%s\tr%d, r%d, r%d%s",
691 (opcode & (1 << 22)) ? 'U' : 'S',
692 type, COND(opcode),
693 rd, rn, rm, rot);
694 return ARM_ADD;
695 }
696 }
697
698 static int evaluate_p_add_sub(uint32_t opcode, uint32_t address, char *cp)
699 {
700 char *prefix;
701 char *op;
702 int type;
703
704 switch ((opcode >> 20) & 0x7) {
705 case 1:
706 prefix = "S";
707 break;
708 case 2:
709 prefix = "Q";
710 break;
711 case 3:
712 prefix = "SH";
713 break;
714 case 5:
715 prefix = "U";
716 break;
717 case 6:
718 prefix = "UQ";
719 break;
720 case 7:
721 prefix = "UH";
722 break;
723 default:
724 goto undef;
725 }
726
727 switch ((opcode >> 5) & 0x7) {
728 case 0:
729 op = "ADD16";
730 type = ARM_ADD;
731 break;
732 case 1:
733 op = "ADDSUBX";
734 type = ARM_ADD;
735 break;
736 case 2:
737 op = "SUBADDX";
738 type = ARM_SUB;
739 break;
740 case 3:
741 op = "SUB16";
742 type = ARM_SUB;
743 break;
744 case 4:
745 op = "ADD8";
746 type = ARM_ADD;
747 break;
748 case 7:
749 op = "SUB8";
750 type = ARM_SUB;
751 break;
752 default:
753 goto undef;
754 }
755
756 sprintf(cp, "%s%s%s\tr%d, r%d, r%d", prefix, op, COND(opcode),
757 (int) (opcode >> 12) & 0xf,
758 (int) (opcode >> 16) & 0xf,
759 (int) (opcode >> 0) & 0xf);
760 return type;
761
762 undef:
763 /* these opcodes might be used someday */
764 sprintf(cp, "UNDEFINED");
765 return ARM_UNDEFINED_INSTRUCTION;
766 }
767
768 /* ARMv6 and later support "media" instructions (includes SIMD) */
769 static int evaluate_media(uint32_t opcode, uint32_t address,
770 struct arm_instruction *instruction)
771 {
772 char *cp = instruction->text;
773 char *mnemonic = NULL;
774
775 sprintf(cp,
776 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t",
777 address, opcode);
778 cp = strchr(cp, 0);
779
780 /* parallel add/subtract */
781 if ((opcode & 0x01800000) == 0x00000000) {
782 instruction->type = evaluate_p_add_sub(opcode, address, cp);
783 return ERROR_OK;
784 }
785
786 /* halfword pack */
787 if ((opcode & 0x01f00020) == 0x00800000) {
788 char *type, *shift;
789 unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
790
791 if (opcode & (1 << 6)) {
792 type = "TB";
793 shift = "ASR";
794 if (imm == 0)
795 imm = 32;
796 } else {
797 type = "BT";
798 shift = "LSL";
799 }
800 sprintf(cp, "PKH%s%s\tr%d, r%d, r%d, %s #%d",
801 type, COND(opcode),
802 (int) (opcode >> 12) & 0xf,
803 (int) (opcode >> 16) & 0xf,
804 (int) (opcode >> 0) & 0xf,
805 shift, imm);
806 return ERROR_OK;
807 }
808
809 /* word saturate */
810 if ((opcode & 0x01a00020) == 0x00a00000) {
811 char *shift;
812 unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
813
814 if (opcode & (1 << 6)) {
815 shift = "ASR";
816 if (imm == 0)
817 imm = 32;
818 } else
819 shift = "LSL";
820
821 sprintf(cp, "%cSAT%s\tr%d, #%d, r%d, %s #%d",
822 (opcode & (1 << 22)) ? 'U' : 'S',
823 COND(opcode),
824 (int) (opcode >> 12) & 0xf,
825 (int) (opcode >> 16) & 0x1f,
826 (int) (opcode >> 0) & 0xf,
827 shift, imm);
828 return ERROR_OK;
829 }
830
831 /* sign extension */
832 if ((opcode & 0x018000f0) == 0x00800070) {
833 instruction->type = evaluate_extend(opcode, address, cp);
834 return ERROR_OK;
835 }
836
837 /* multiplies */
838 if ((opcode & 0x01f00080) == 0x01000000) {
839 unsigned rn = (opcode >> 12) & 0xf;
840
841 if (rn != 0xf)
842 sprintf(cp, "SML%cD%s%s\tr%d, r%d, r%d, r%d",
843 (opcode & (1 << 6)) ? 'S' : 'A',
844 (opcode & (1 << 5)) ? "X" : "",
845 COND(opcode),
846 (int) (opcode >> 16) & 0xf,
847 (int) (opcode >> 0) & 0xf,
848 (int) (opcode >> 8) & 0xf,
849 rn);
850 else
851 sprintf(cp, "SMU%cD%s%s\tr%d, r%d, r%d",
852 (opcode & (1 << 6)) ? 'S' : 'A',
853 (opcode & (1 << 5)) ? "X" : "",
854 COND(opcode),
855 (int) (opcode >> 16) & 0xf,
856 (int) (opcode >> 0) & 0xf,
857 (int) (opcode >> 8) & 0xf);
858 return ERROR_OK;
859 }
860 if ((opcode & 0x01f00000) == 0x01400000) {
861 sprintf(cp, "SML%cLD%s%s\tr%d, r%d, r%d, r%d",
862 (opcode & (1 << 6)) ? 'S' : 'A',
863 (opcode & (1 << 5)) ? "X" : "",
864 COND(opcode),
865 (int) (opcode >> 12) & 0xf,
866 (int) (opcode >> 16) & 0xf,
867 (int) (opcode >> 0) & 0xf,
868 (int) (opcode >> 8) & 0xf);
869 return ERROR_OK;
870 }
871 if ((opcode & 0x01f00000) == 0x01500000) {
872 unsigned rn = (opcode >> 12) & 0xf;
873
874 switch (opcode & 0xc0) {
875 case 3:
876 if (rn == 0xf)
877 goto undef;
878 /* FALL THROUGH */
879 case 0:
880 break;
881 default:
882 goto undef;
883 }
884
885 if (rn != 0xf)
886 sprintf(cp, "SMML%c%s%s\tr%d, r%d, r%d, r%d",
887 (opcode & (1 << 6)) ? 'S' : 'A',
888 (opcode & (1 << 5)) ? "R" : "",
889 COND(opcode),
890 (int) (opcode >> 16) & 0xf,
891 (int) (opcode >> 0) & 0xf,
892 (int) (opcode >> 8) & 0xf,
893 rn);
894 else
895 sprintf(cp, "SMMUL%s%s\tr%d, r%d, r%d",
896 (opcode & (1 << 5)) ? "R" : "",
897 COND(opcode),
898 (int) (opcode >> 16) & 0xf,
899 (int) (opcode >> 0) & 0xf,
900 (int) (opcode >> 8) & 0xf);
901 return ERROR_OK;
902 }
903
904 /* simple matches against the remaining decode bits */
905 switch (opcode & 0x01f000f0) {
906 case 0x00a00030:
907 case 0x00e00030:
908 /* parallel halfword saturate */
909 sprintf(cp, "%cSAT16%s\tr%d, #%d, r%d",
910 (opcode & (1 << 22)) ? 'U' : 'S',
911 COND(opcode),
912 (int) (opcode >> 12) & 0xf,
913 (int) (opcode >> 16) & 0xf,
914 (int) (opcode >> 0) & 0xf);
915 return ERROR_OK;
916 case 0x00b00030:
917 mnemonic = "REV";
918 break;
919 case 0x00b000b0:
920 mnemonic = "REV16";
921 break;
922 case 0x00f000b0:
923 mnemonic = "REVSH";
924 break;
925 case 0x008000b0:
926 /* select bytes */
927 sprintf(cp, "SEL%s\tr%d, r%d, r%d", COND(opcode),
928 (int) (opcode >> 12) & 0xf,
929 (int) (opcode >> 16) & 0xf,
930 (int) (opcode >> 0) & 0xf);
931 return ERROR_OK;
932 case 0x01800010:
933 /* unsigned sum of absolute differences */
934 if (((opcode >> 12) & 0xf) == 0xf)
935 sprintf(cp, "USAD8%s\tr%d, r%d, r%d", COND(opcode),
936 (int) (opcode >> 16) & 0xf,
937 (int) (opcode >> 0) & 0xf,
938 (int) (opcode >> 8) & 0xf);
939 else
940 sprintf(cp, "USADA8%s\tr%d, r%d, r%d, r%d", COND(opcode),
941 (int) (opcode >> 16) & 0xf,
942 (int) (opcode >> 0) & 0xf,
943 (int) (opcode >> 8) & 0xf,
944 (int) (opcode >> 12) & 0xf);
945 return ERROR_OK;
946 }
947 if (mnemonic) {
948 unsigned rm = (opcode >> 0) & 0xf;
949 unsigned rd = (opcode >> 12) & 0xf;
950
951 sprintf(cp, "%s%s\tr%d, r%d", mnemonic, COND(opcode), rm, rd);
952 return ERROR_OK;
953 }
954
955 undef:
956 /* these opcodes might be used someday */
957 sprintf(cp, "UNDEFINED");
958 return ERROR_OK;
959 }
960
961 /* Miscellaneous load/store instructions */
962 static int evaluate_misc_load_store(uint32_t opcode,
963 uint32_t address, struct arm_instruction *instruction)
964 {
965 uint8_t P, U, I, W, L, S, H;
966 uint8_t Rn, Rd;
967 char *operation;/* "LDR" or "STR" */
968 char *suffix; /* "H", "SB", "SH", "D" */
969 char offset[32];
970
971 /* examine flags */
972 P = (opcode & 0x01000000) >> 24;
973 U = (opcode & 0x00800000) >> 23;
974 I = (opcode & 0x00400000) >> 22;
975 W = (opcode & 0x00200000) >> 21;
976 L = (opcode & 0x00100000) >> 20;
977 S = (opcode & 0x00000040) >> 6;
978 H = (opcode & 0x00000020) >> 5;
979
980 /* target register */
981 Rd = (opcode & 0xf000) >> 12;
982
983 /* base register */
984 Rn = (opcode & 0xf0000) >> 16;
985
986 instruction->info.load_store.Rd = Rd;
987 instruction->info.load_store.Rn = Rn;
988 instruction->info.load_store.U = U;
989
990 /* determine instruction type and suffix */
991 if (S) {/* signed */
992 if (L) {/* load */
993 if (H) {
994 operation = "LDR";
995 instruction->type = ARM_LDRSH;
996 suffix = "SH";
997 } else {
998 operation = "LDR";
999 instruction->type = ARM_LDRSB;
1000 suffix = "SB";
1001 }
1002 } else {/* there are no signed stores, so this is used to encode double-register
1003 *load/stores */
1004 suffix = "D";
1005 if (H) {
1006 operation = "STR";
1007 instruction->type = ARM_STRD;
1008 } else {
1009 operation = "LDR";
1010 instruction->type = ARM_LDRD;
1011 }
1012 }
1013 } else {/* unsigned */
1014 suffix = "H";
1015 if (L) {/* load */
1016 operation = "LDR";
1017 instruction->type = ARM_LDRH;
1018 } else {/* store */
1019 operation = "STR";
1020 instruction->type = ARM_STRH;
1021 }
1022 }
1023
1024 if (I) {/* Immediate offset/index (#+-<offset_8>)*/
1025 uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
1026 snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
1027
1028 instruction->info.load_store.offset_mode = 0;
1029 instruction->info.load_store.offset.offset = offset_8;
1030 } else {/* Register offset/index (+-<Rm>) */
1031 uint8_t Rm;
1032 Rm = (opcode & 0xf);
1033 snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
1034
1035 instruction->info.load_store.offset_mode = 1;
1036 instruction->info.load_store.offset.reg.Rm = Rm;
1037 instruction->info.load_store.offset.reg.shift = 0x0;
1038 instruction->info.load_store.offset.reg.shift_imm = 0x0;
1039 }
1040
1041 if (P == 1) {
1042 if (W == 0) { /* offset */
1043 snprintf(instruction->text,
1044 128,
1045 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
1046 address,
1047 opcode,
1048 operation,
1049 COND(opcode),
1050 suffix,
1051 Rd,
1052 Rn,
1053 offset);
1054
1055 instruction->info.load_store.index_mode = 0;
1056 } else {/* pre-indexed */
1057 snprintf(instruction->text,
1058 128,
1059 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
1060 address,
1061 opcode,
1062 operation,
1063 COND(opcode),
1064 suffix,
1065 Rd,
1066 Rn,
1067 offset);
1068
1069 instruction->info.load_store.index_mode = 1;
1070 }
1071 } else {/* post-indexed */
1072 snprintf(instruction->text,
1073 128,
1074 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
1075 address,
1076 opcode,
1077 operation,
1078 COND(opcode),
1079 suffix,
1080 Rd,
1081 Rn,
1082 offset);
1083
1084 instruction->info.load_store.index_mode = 2;
1085 }
1086
1087 return ERROR_OK;
1088 }
1089
1090 /* Load/store multiples instructions */
1091 static int evaluate_ldm_stm(uint32_t opcode,
1092 uint32_t address, struct arm_instruction *instruction)
1093 {
1094 uint8_t P, U, S, W, L, Rn;
1095 uint32_t register_list;
1096 char *addressing_mode;
1097 char *mnemonic;
1098 char reg_list[69];
1099 char *reg_list_p;
1100 int i;
1101 int first_reg = 1;
1102
1103 P = (opcode & 0x01000000) >> 24;
1104 U = (opcode & 0x00800000) >> 23;
1105 S = (opcode & 0x00400000) >> 22;
1106 W = (opcode & 0x00200000) >> 21;
1107 L = (opcode & 0x00100000) >> 20;
1108 register_list = (opcode & 0xffff);
1109 Rn = (opcode & 0xf0000) >> 16;
1110
1111 instruction->info.load_store_multiple.Rn = Rn;
1112 instruction->info.load_store_multiple.register_list = register_list;
1113 instruction->info.load_store_multiple.S = S;
1114 instruction->info.load_store_multiple.W = W;
1115
1116 if (L) {
1117 instruction->type = ARM_LDM;
1118 mnemonic = "LDM";
1119 } else {
1120 instruction->type = ARM_STM;
1121 mnemonic = "STM";
1122 }
1123
1124 if (P) {
1125 if (U) {
1126 instruction->info.load_store_multiple.addressing_mode = 1;
1127 addressing_mode = "IB";
1128 } else {
1129 instruction->info.load_store_multiple.addressing_mode = 3;
1130 addressing_mode = "DB";
1131 }
1132 } else {
1133 if (U) {
1134 instruction->info.load_store_multiple.addressing_mode = 0;
1135 /* "IA" is the default in UAL syntax */
1136 addressing_mode = "";
1137 } else {
1138 instruction->info.load_store_multiple.addressing_mode = 2;
1139 addressing_mode = "DA";
1140 }
1141 }
1142
1143 reg_list_p = reg_list;
1144 for (i = 0; i <= 15; i++) {
1145 if ((register_list >> i) & 1) {
1146 if (first_reg) {
1147 first_reg = 0;
1148 reg_list_p += snprintf(reg_list_p,
1149 (reg_list + 69 - reg_list_p),
1150 "r%i",
1151 i);
1152 } else
1153 reg_list_p += snprintf(reg_list_p,
1154 (reg_list + 69 - reg_list_p),
1155 ", r%i",
1156 i);
1157 }
1158 }
1159
1160 snprintf(instruction->text, 128,
1161 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
1162 "\t%s%s%s r%i%s, {%s}%s",
1163 address, opcode,
1164 mnemonic, addressing_mode, COND(opcode),
1165 Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
1166
1167 return ERROR_OK;
1168 }
1169
1170 /* Multiplies, extra load/stores */
1171 static int evaluate_mul_and_extra_ld_st(uint32_t opcode,
1172 uint32_t address, struct arm_instruction *instruction)
1173 {
1174 /* Multiply (accumulate) (long) and Swap/swap byte */
1175 if ((opcode & 0x000000f0) == 0x00000090) {
1176 /* Multiply (accumulate) */
1177 if ((opcode & 0x0f800000) == 0x00000000) {
1178 uint8_t Rm, Rs, Rn, Rd, S;
1179 Rm = opcode & 0xf;
1180 Rs = (opcode & 0xf00) >> 8;
1181 Rn = (opcode & 0xf000) >> 12;
1182 Rd = (opcode & 0xf0000) >> 16;
1183 S = (opcode & 0x00100000) >> 20;
1184
1185 /* examine A bit (accumulate) */
1186 if (opcode & 0x00200000) {
1187 instruction->type = ARM_MLA;
1188 snprintf(instruction->text,
1189 128,
1190 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
1191 address,
1192 opcode,
1193 COND(opcode),
1194 (S) ? "S" : "",
1195 Rd,
1196 Rm,
1197 Rs,
1198 Rn);
1199 } else {
1200 instruction->type = ARM_MUL;
1201 snprintf(instruction->text,
1202 128,
1203 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
1204 address,
1205 opcode,
1206 COND(opcode),
1207 (S) ? "S" : "",
1208 Rd,
1209 Rm,
1210 Rs);
1211 }
1212
1213 return ERROR_OK;
1214 }
1215
1216 /* Multiply (accumulate) long */
1217 if ((opcode & 0x0f800000) == 0x00800000) {
1218 char *mnemonic = NULL;
1219 uint8_t Rm, Rs, RdHi, RdLow, S;
1220 Rm = opcode & 0xf;
1221 Rs = (opcode & 0xf00) >> 8;
1222 RdHi = (opcode & 0xf000) >> 12;
1223 RdLow = (opcode & 0xf0000) >> 16;
1224 S = (opcode & 0x00100000) >> 20;
1225
1226 switch ((opcode & 0x00600000) >> 21) {
1227 case 0x0:
1228 instruction->type = ARM_UMULL;
1229 mnemonic = "UMULL";
1230 break;
1231 case 0x1:
1232 instruction->type = ARM_UMLAL;
1233 mnemonic = "UMLAL";
1234 break;
1235 case 0x2:
1236 instruction->type = ARM_SMULL;
1237 mnemonic = "SMULL";
1238 break;
1239 case 0x3:
1240 instruction->type = ARM_SMLAL;
1241 mnemonic = "SMLAL";
1242 break;
1243 }
1244
1245 snprintf(instruction->text,
1246 128,
1247 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
1248 address,
1249 opcode,
1250 mnemonic,
1251 COND(opcode),
1252 (S) ? "S" : "",
1253 RdLow,
1254 RdHi,
1255 Rm,
1256 Rs);
1257
1258 return ERROR_OK;
1259 }
1260
1261 /* Swap/swap byte */
1262 if ((opcode & 0x0f800000) == 0x01000000) {
1263 uint8_t Rm, Rd, Rn;
1264 Rm = opcode & 0xf;
1265 Rd = (opcode & 0xf000) >> 12;
1266 Rn = (opcode & 0xf0000) >> 16;
1267
1268 /* examine B flag */
1269 instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
1270
1271 snprintf(instruction->text,
1272 128,
1273 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
1274 address,
1275 opcode,
1276 (opcode & 0x00400000) ? "SWPB" : "SWP",
1277 COND(opcode),
1278 Rd,
1279 Rm,
1280 Rn);
1281 return ERROR_OK;
1282 }
1283
1284 }
1285
1286 return evaluate_misc_load_store(opcode, address, instruction);
1287 }
1288
1289 static int evaluate_mrs_msr(uint32_t opcode,
1290 uint32_t address, struct arm_instruction *instruction)
1291 {
1292 int R = (opcode & 0x00400000) >> 22;
1293 char *PSR = (R) ? "SPSR" : "CPSR";
1294
1295 /* Move register to status register (MSR) */
1296 if (opcode & 0x00200000) {
1297 instruction->type = ARM_MSR;
1298
1299 /* immediate variant */
1300 if (opcode & 0x02000000) {
1301 uint8_t immediate = (opcode & 0xff);
1302 uint8_t rotate = (opcode & 0xf00);
1303
1304 snprintf(instruction->text,
1305 128,
1306 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32,
1307 address,
1308 opcode,
1309 COND(opcode),
1310 PSR,
1311 (opcode & 0x10000) ? "c" : "",
1312 (opcode & 0x20000) ? "x" : "",
1313 (opcode & 0x40000) ? "s" : "",
1314 (opcode & 0x80000) ? "f" : "",
1315 ror(immediate, (rotate * 2))
1316 );
1317 } else {/* register variant */
1318 uint8_t Rm = opcode & 0xf;
1319 snprintf(instruction->text,
1320 128,
1321 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
1322 address,
1323 opcode,
1324 COND(opcode),
1325 PSR,
1326 (opcode & 0x10000) ? "c" : "",
1327 (opcode & 0x20000) ? "x" : "",
1328 (opcode & 0x40000) ? "s" : "",
1329 (opcode & 0x80000) ? "f" : "",
1330 Rm
1331 );
1332 }
1333
1334 } else {/* Move status register to register (MRS) */
1335 uint8_t Rd;
1336
1337 instruction->type = ARM_MRS;
1338 Rd = (opcode & 0x0000f000) >> 12;
1339
1340 snprintf(instruction->text,
1341 128,
1342 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
1343 address,
1344 opcode,
1345 COND(opcode),
1346 Rd,
1347 PSR);
1348 }
1349
1350 return ERROR_OK;
1351 }
1352
1353 /* Miscellaneous instructions */
1354 static int evaluate_misc_instr(uint32_t opcode,
1355 uint32_t address, struct arm_instruction *instruction)
1356 {
1357 /* MRS/MSR */
1358 if ((opcode & 0x000000f0) == 0x00000000)
1359 evaluate_mrs_msr(opcode, address, instruction);
1360
1361 /* BX */
1362 if ((opcode & 0x006000f0) == 0x00200010) {
1363 uint8_t Rm;
1364 instruction->type = ARM_BX;
1365 Rm = opcode & 0xf;
1366
1367 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
1368 address, opcode, COND(opcode), Rm);
1369
1370 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1371 instruction->info.b_bl_bx_blx.target_address = -1;
1372 }
1373
1374 /* BXJ - "Jazelle" support (ARMv5-J) */
1375 if ((opcode & 0x006000f0) == 0x00200020) {
1376 uint8_t Rm;
1377 instruction->type = ARM_BX;
1378 Rm = opcode & 0xf;
1379
1380 snprintf(instruction->text, 128,
1381 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBXJ%s r%i",
1382 address, opcode, COND(opcode), Rm);
1383
1384 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1385 instruction->info.b_bl_bx_blx.target_address = -1;
1386 }
1387
1388 /* CLZ */
1389 if ((opcode & 0x006000f0) == 0x00600010) {
1390 uint8_t Rm, Rd;
1391 instruction->type = ARM_CLZ;
1392 Rm = opcode & 0xf;
1393 Rd = (opcode & 0xf000) >> 12;
1394
1395 snprintf(instruction->text,
1396 128,
1397 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
1398 address,
1399 opcode,
1400 COND(opcode),
1401 Rd,
1402 Rm);
1403 }
1404
1405 /* BLX(2) */
1406 if ((opcode & 0x006000f0) == 0x00200030) {
1407 uint8_t Rm;
1408 instruction->type = ARM_BLX;
1409 Rm = opcode & 0xf;
1410
1411 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
1412 address, opcode, COND(opcode), Rm);
1413
1414 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1415 instruction->info.b_bl_bx_blx.target_address = -1;
1416 }
1417
1418 /* Enhanced DSP add/subtracts */
1419 if ((opcode & 0x0000000f0) == 0x00000050) {
1420 uint8_t Rm, Rd, Rn;
1421 char *mnemonic = NULL;
1422 Rm = opcode & 0xf;
1423 Rd = (opcode & 0xf000) >> 12;
1424 Rn = (opcode & 0xf0000) >> 16;
1425
1426 switch ((opcode & 0x00600000) >> 21) {
1427 case 0x0:
1428 instruction->type = ARM_QADD;
1429 mnemonic = "QADD";
1430 break;
1431 case 0x1:
1432 instruction->type = ARM_QSUB;
1433 mnemonic = "QSUB";
1434 break;
1435 case 0x2:
1436 instruction->type = ARM_QDADD;
1437 mnemonic = "QDADD";
1438 break;
1439 case 0x3:
1440 instruction->type = ARM_QDSUB;
1441 mnemonic = "QDSUB";
1442 break;
1443 }
1444
1445 snprintf(instruction->text,
1446 128,
1447 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
1448 address,
1449 opcode,
1450 mnemonic,
1451 COND(opcode),
1452 Rd,
1453 Rm,
1454 Rn);
1455 }
1456
1457 /* exception return */
1458 if ((opcode & 0x0000000f0) == 0x00000060) {
1459 if (((opcode & 0x600000) >> 21) == 3)
1460 instruction->type = ARM_ERET;
1461 snprintf(instruction->text,
1462 128,
1463 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tERET",
1464 address,
1465 opcode);
1466 }
1467
1468 /* exception generate instructions */
1469 if ((opcode & 0x0000000f0) == 0x00000070) {
1470 uint32_t immediate = 0;
1471 char *mnemonic = NULL;
1472
1473 switch ((opcode & 0x600000) >> 21) {
1474 case 0x1:
1475 instruction->type = ARM_BKPT;
1476 mnemonic = "BRKT";
1477 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1478 break;
1479 case 0x2:
1480 instruction->type = ARM_HVC;
1481 mnemonic = "HVC";
1482 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1483 break;
1484 case 0x3:
1485 instruction->type = ARM_SMC;
1486 mnemonic = "SMC";
1487 immediate = (opcode & 0xf);
1488 break;
1489 }
1490
1491 snprintf(instruction->text,
1492 128,
1493 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s 0x%4.4" PRIx32 "",
1494 address,
1495 opcode,
1496 mnemonic,
1497 immediate);
1498 }
1499
1500 /* Enhanced DSP multiplies */
1501 if ((opcode & 0x000000090) == 0x00000080) {
1502 int x = (opcode & 0x20) >> 5;
1503 int y = (opcode & 0x40) >> 6;
1504
1505 /* SMLA < x><y> */
1506 if ((opcode & 0x00600000) == 0x00000000) {
1507 uint8_t Rd, Rm, Rs, Rn;
1508 instruction->type = ARM_SMLAxy;
1509 Rd = (opcode & 0xf0000) >> 16;
1510 Rm = (opcode & 0xf);
1511 Rs = (opcode & 0xf00) >> 8;
1512 Rn = (opcode & 0xf000) >> 12;
1513
1514 snprintf(instruction->text,
1515 128,
1516 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1517 address,
1518 opcode,
1519 (x) ? "T" : "B",
1520 (y) ? "T" : "B",
1521 COND(opcode),
1522 Rd,
1523 Rm,
1524 Rs,
1525 Rn);
1526 }
1527
1528 /* SMLAL < x><y> */
1529 if ((opcode & 0x00600000) == 0x00400000) {
1530 uint8_t RdLow, RdHi, Rm, Rs;
1531 instruction->type = ARM_SMLAxy;
1532 RdHi = (opcode & 0xf0000) >> 16;
1533 RdLow = (opcode & 0xf000) >> 12;
1534 Rm = (opcode & 0xf);
1535 Rs = (opcode & 0xf00) >> 8;
1536
1537 snprintf(instruction->text,
1538 128,
1539 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1540 address,
1541 opcode,
1542 (x) ? "T" : "B",
1543 (y) ? "T" : "B",
1544 COND(opcode),
1545 RdLow,
1546 RdHi,
1547 Rm,
1548 Rs);
1549 }
1550
1551 /* SMLAW < y> */
1552 if (((opcode & 0x00600000) == 0x00100000) && (x == 0)) {
1553 uint8_t Rd, Rm, Rs, Rn;
1554 instruction->type = ARM_SMLAWy;
1555 Rd = (opcode & 0xf0000) >> 16;
1556 Rm = (opcode & 0xf);
1557 Rs = (opcode & 0xf00) >> 8;
1558 Rn = (opcode & 0xf000) >> 12;
1559
1560 snprintf(instruction->text,
1561 128,
1562 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
1563 address,
1564 opcode,
1565 (y) ? "T" : "B",
1566 COND(opcode),
1567 Rd,
1568 Rm,
1569 Rs,
1570 Rn);
1571 }
1572
1573 /* SMUL < x><y> */
1574 if ((opcode & 0x00600000) == 0x00300000) {
1575 uint8_t Rd, Rm, Rs;
1576 instruction->type = ARM_SMULxy;
1577 Rd = (opcode & 0xf0000) >> 16;
1578 Rm = (opcode & 0xf);
1579 Rs = (opcode & 0xf00) >> 8;
1580
1581 snprintf(instruction->text,
1582 128,
1583 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
1584 address,
1585 opcode,
1586 (x) ? "T" : "B",
1587 (y) ? "T" : "B",
1588 COND(opcode),
1589 Rd,
1590 Rm,
1591 Rs);
1592 }
1593
1594 /* SMULW < y> */
1595 if (((opcode & 0x00600000) == 0x00100000) && (x == 1)) {
1596 uint8_t Rd, Rm, Rs;
1597 instruction->type = ARM_SMULWy;
1598 Rd = (opcode & 0xf0000) >> 16;
1599 Rm = (opcode & 0xf);
1600 Rs = (opcode & 0xf00) >> 8;
1601
1602 snprintf(instruction->text,
1603 128,
1604 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
1605 address,
1606 opcode,
1607 (y) ? "T" : "B",
1608 COND(opcode),
1609 Rd,
1610 Rm,
1611 Rs);
1612 }
1613 }
1614
1615 return ERROR_OK;
1616 }
1617
1618 static int evaluate_mov_imm(uint32_t opcode,
1619 uint32_t address, struct arm_instruction *instruction)
1620 {
1621 uint16_t immediate;
1622 uint8_t Rd;
1623 bool T;
1624
1625 Rd = (opcode & 0xf000) >> 12;
1626 T = opcode & 0x00400000;
1627 immediate = (opcode & 0xf0000) >> 4 | (opcode & 0xfff);
1628
1629 instruction->type = ARM_MOV;
1630 instruction->info.data_proc.Rd = Rd;
1631
1632 snprintf(instruction->text,
1633 128,
1634 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMOV%s%s r%i, #0x%" PRIx16,
1635 address,
1636 opcode,
1637 T ? "T" : "W",
1638 COND(opcode),
1639 Rd,
1640 immediate);
1641
1642 return ERROR_OK;
1643 }
1644
1645 static int evaluate_data_proc(uint32_t opcode,
1646 uint32_t address, struct arm_instruction *instruction)
1647 {
1648 uint8_t I, op, S, Rn, Rd;
1649 char *mnemonic = NULL;
1650 char shifter_operand[32];
1651
1652 I = (opcode & 0x02000000) >> 25;
1653 op = (opcode & 0x01e00000) >> 21;
1654 S = (opcode & 0x00100000) >> 20;
1655
1656 Rd = (opcode & 0xf000) >> 12;
1657 Rn = (opcode & 0xf0000) >> 16;
1658
1659 instruction->info.data_proc.Rd = Rd;
1660 instruction->info.data_proc.Rn = Rn;
1661 instruction->info.data_proc.S = S;
1662
1663 switch (op) {
1664 case 0x0:
1665 instruction->type = ARM_AND;
1666 mnemonic = "AND";
1667 break;
1668 case 0x1:
1669 instruction->type = ARM_EOR;
1670 mnemonic = "EOR";
1671 break;
1672 case 0x2:
1673 instruction->type = ARM_SUB;
1674 mnemonic = "SUB";
1675 break;
1676 case 0x3:
1677 instruction->type = ARM_RSB;
1678 mnemonic = "RSB";
1679 break;
1680 case 0x4:
1681 instruction->type = ARM_ADD;
1682 mnemonic = "ADD";
1683 break;
1684 case 0x5:
1685 instruction->type = ARM_ADC;
1686 mnemonic = "ADC";
1687 break;
1688 case 0x6:
1689 instruction->type = ARM_SBC;
1690 mnemonic = "SBC";
1691 break;
1692 case 0x7:
1693 instruction->type = ARM_RSC;
1694 mnemonic = "RSC";
1695 break;
1696 case 0x8:
1697 instruction->type = ARM_TST;
1698 mnemonic = "TST";
1699 break;
1700 case 0x9:
1701 instruction->type = ARM_TEQ;
1702 mnemonic = "TEQ";
1703 break;
1704 case 0xa:
1705 instruction->type = ARM_CMP;
1706 mnemonic = "CMP";
1707 break;
1708 case 0xb:
1709 instruction->type = ARM_CMN;
1710 mnemonic = "CMN";
1711 break;
1712 case 0xc:
1713 instruction->type = ARM_ORR;
1714 mnemonic = "ORR";
1715 break;
1716 case 0xd:
1717 instruction->type = ARM_MOV;
1718 mnemonic = "MOV";
1719 break;
1720 case 0xe:
1721 instruction->type = ARM_BIC;
1722 mnemonic = "BIC";
1723 break;
1724 case 0xf:
1725 instruction->type = ARM_MVN;
1726 mnemonic = "MVN";
1727 break;
1728 }
1729
1730 if (I) {/* immediate shifter operand (#<immediate>)*/
1731 uint8_t immed_8 = opcode & 0xff;
1732 uint8_t rotate_imm = (opcode & 0xf00) >> 8;
1733 uint32_t immediate;
1734
1735 immediate = ror(immed_8, rotate_imm * 2);
1736
1737 snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
1738
1739 instruction->info.data_proc.variant = 0;
1740 instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
1741 } else {/* register-based shifter operand */
1742 uint8_t shift, Rm;
1743 shift = (opcode & 0x60) >> 5;
1744 Rm = (opcode & 0xf);
1745
1746 if ((opcode & 0x10) != 0x10) { /* Immediate shifts ("<Rm>" or "<Rm>, <shift>
1747 *#<shift_immediate>") */
1748 uint8_t shift_imm;
1749 shift_imm = (opcode & 0xf80) >> 7;
1750
1751 instruction->info.data_proc.variant = 1;
1752 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1753 instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm =
1754 shift_imm;
1755 instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
1756
1757 /* LSR encodes a shift by 32 bit as 0x0 */
1758 if ((shift == 0x1) && (shift_imm == 0x0))
1759 shift_imm = 0x20;
1760
1761 /* ASR encodes a shift by 32 bit as 0x0 */
1762 if ((shift == 0x2) && (shift_imm == 0x0))
1763 shift_imm = 0x20;
1764
1765 /* ROR by 32 bit is actually a RRX */
1766 if ((shift == 0x3) && (shift_imm == 0x0))
1767 shift = 0x4;
1768
1769 if ((shift_imm == 0x0) && (shift == 0x0))
1770 snprintf(shifter_operand, 32, "r%i", Rm);
1771 else {
1772 if (shift == 0x0) /* LSL */
1773 snprintf(shifter_operand,
1774 32,
1775 "r%i, LSL #0x%x",
1776 Rm,
1777 shift_imm);
1778 else if (shift == 0x1) /* LSR */
1779 snprintf(shifter_operand,
1780 32,
1781 "r%i, LSR #0x%x",
1782 Rm,
1783 shift_imm);
1784 else if (shift == 0x2) /* ASR */
1785 snprintf(shifter_operand,
1786 32,
1787 "r%i, ASR #0x%x",
1788 Rm,
1789 shift_imm);
1790 else if (shift == 0x3) /* ROR */
1791 snprintf(shifter_operand,
1792 32,
1793 "r%i, ROR #0x%x",
1794 Rm,
1795 shift_imm);
1796 else if (shift == 0x4) /* RRX */
1797 snprintf(shifter_operand, 32, "r%i, RRX", Rm);
1798 }
1799 } else {/* Register shifts ("<Rm>, <shift> <Rs>") */
1800 uint8_t Rs = (opcode & 0xf00) >> 8;
1801
1802 instruction->info.data_proc.variant = 2;
1803 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
1804 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
1805 instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
1806
1807 if (shift == 0x0) /* LSL */
1808 snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
1809 else if (shift == 0x1) /* LSR */
1810 snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
1811 else if (shift == 0x2) /* ASR */
1812 snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
1813 else if (shift == 0x3) /* ROR */
1814 snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
1815 }
1816 }
1817
1818 if ((op < 0x8) || (op == 0xc) || (op == 0xe)) { /* <opcode3>{<cond>}{S} <Rd>, <Rn>,
1819 *<shifter_operand> */
1820 snprintf(instruction->text,
1821 128,
1822 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
1823 address,
1824 opcode,
1825 mnemonic,
1826 COND(opcode),
1827 (S) ? "S" : "",
1828 Rd,
1829 Rn,
1830 shifter_operand);
1831 } else if ((op == 0xd) || (op == 0xf)) { /* <opcode1>{<cond>}{S} <Rd>,
1832 *<shifter_operand> */
1833 if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */
1834 snprintf(instruction->text,
1835 128,
1836 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",
1837 address,
1838 opcode);
1839 else
1840 snprintf(instruction->text,
1841 128,
1842 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
1843 address,
1844 opcode,
1845 mnemonic,
1846 COND(opcode),
1847 (S) ? "S" : "",
1848 Rd,
1849 shifter_operand);
1850 } else {/* <opcode2>{<cond>} <Rn>, <shifter_operand> */
1851 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
1852 address, opcode, mnemonic, COND(opcode),
1853 Rn, shifter_operand);
1854 }
1855
1856 return ERROR_OK;
1857 }
1858
1859 int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
1860 struct arm_instruction *instruction)
1861 {
1862 /* clear fields, to avoid confusion */
1863 memset(instruction, 0, sizeof(struct arm_instruction));
1864 instruction->opcode = opcode;
1865 instruction->instruction_size = 4;
1866
1867 /* catch opcodes with condition field [31:28] = b1111 */
1868 if ((opcode & 0xf0000000) == 0xf0000000) {
1869 /* Undefined instruction (or ARMv5E cache preload PLD) */
1870 if ((opcode & 0x08000000) == 0x00000000)
1871 return evaluate_pld(opcode, address, instruction);
1872
1873 /* Undefined instruction (or ARMv6+ SRS/RFE) */
1874 if ((opcode & 0x0e000000) == 0x08000000)
1875 return evaluate_srs(opcode, address, instruction);
1876
1877 /* Branch and branch with link and change to Thumb */
1878 if ((opcode & 0x0e000000) == 0x0a000000)
1879 return evaluate_blx_imm(opcode, address, instruction);
1880
1881 /* Extended coprocessor opcode space (ARMv5 and higher)
1882 * Coprocessor load/store and double register transfers */
1883 if ((opcode & 0x0e000000) == 0x0c000000)
1884 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1885
1886 /* Coprocessor data processing */
1887 if ((opcode & 0x0f000100) == 0x0c000000)
1888 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1889
1890 /* Coprocessor register transfers */
1891 if ((opcode & 0x0f000010) == 0x0c000010)
1892 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1893
1894 /* Undefined instruction */
1895 if ((opcode & 0x0f000000) == 0x0f000000) {
1896 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1897 snprintf(instruction->text,
1898 128,
1899 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1900 address,
1901 opcode);
1902 return ERROR_OK;
1903 }
1904 }
1905
1906 /* catch opcodes with [27:25] = b000 */
1907 if ((opcode & 0x0e000000) == 0x00000000) {
1908 /* Multiplies, extra load/stores */
1909 if ((opcode & 0x00000090) == 0x00000090)
1910 return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
1911
1912 /* Miscellaneous instructions */
1913 if ((opcode & 0x0f900000) == 0x01000000)
1914 return evaluate_misc_instr(opcode, address, instruction);
1915
1916 return evaluate_data_proc(opcode, address, instruction);
1917 }
1918
1919 /* catch opcodes with [27:25] = b001 */
1920 if ((opcode & 0x0e000000) == 0x02000000) {
1921 /* 16-bit immediate load */
1922 if ((opcode & 0x0fb00000) == 0x03000000)
1923 return evaluate_mov_imm(opcode, address, instruction);
1924
1925 /* Move immediate to status register */
1926 if ((opcode & 0x0fb00000) == 0x03200000)
1927 return evaluate_mrs_msr(opcode, address, instruction);
1928
1929 return evaluate_data_proc(opcode, address, instruction);
1930
1931 }
1932
1933 /* catch opcodes with [27:25] = b010 */
1934 if ((opcode & 0x0e000000) == 0x04000000) {
1935 /* Load/store immediate offset */
1936 return evaluate_load_store(opcode, address, instruction);
1937 }
1938
1939 /* catch opcodes with [27:25] = b011 */
1940 if ((opcode & 0x0e000000) == 0x06000000) {
1941 /* Load/store register offset */
1942 if ((opcode & 0x00000010) == 0x00000000)
1943 return evaluate_load_store(opcode, address, instruction);
1944
1945 /* Architecturally Undefined instruction
1946 * ... don't expect these to ever be used
1947 */
1948 if ((opcode & 0x07f000f0) == 0x07f000f0) {
1949 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1950 snprintf(instruction->text, 128,
1951 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF",
1952 address, opcode);
1953 return ERROR_OK;
1954 }
1955
1956 /* "media" instructions */
1957 return evaluate_media(opcode, address, instruction);
1958 }
1959
1960 /* catch opcodes with [27:25] = b100 */
1961 if ((opcode & 0x0e000000) == 0x08000000) {
1962 /* Load/store multiple */
1963 return evaluate_ldm_stm(opcode, address, instruction);
1964 }
1965
1966 /* catch opcodes with [27:25] = b101 */
1967 if ((opcode & 0x0e000000) == 0x0a000000) {
1968 /* Branch and branch with link */
1969 return evaluate_b_bl(opcode, address, instruction);
1970 }
1971
1972 /* catch opcodes with [27:25] = b110 */
1973 if ((opcode & 0x0e000000) == 0x0c000000) {
1974 /* Coprocessor load/store and double register transfers */
1975 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1976 }
1977
1978 /* catch opcodes with [27:25] = b111 */
1979 if ((opcode & 0x0e000000) == 0x0e000000) {
1980 /* Software interrupt */
1981 if ((opcode & 0x0f000000) == 0x0f000000)
1982 return evaluate_swi(opcode, address, instruction);
1983
1984 /* Coprocessor data processing */
1985 if ((opcode & 0x0f000010) == 0x0e000000)
1986 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1987
1988 /* Coprocessor register transfers */
1989 if ((opcode & 0x0f000010) == 0x0e000010)
1990 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1991 }
1992
1993 LOG_ERROR("ARM: should never reach this point (opcode=%08x)",
1994 (unsigned) opcode);
1995 return -1;
1996 }
1997
1998 static int evaluate_b_bl_blx_thumb(uint16_t opcode,
1999 uint32_t address, struct arm_instruction *instruction)
2000 {
2001 uint32_t offset = opcode & 0x7ff;
2002 uint32_t opc = (opcode >> 11) & 0x3;
2003 uint32_t target_address;
2004 char *mnemonic = NULL;
2005
2006 /* sign extend 11-bit offset */
2007 if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
2008 offset = 0xfffff800 | offset;
2009
2010 target_address = address + 4 + (offset << 1);
2011
2012 switch (opc) {
2013 /* unconditional branch */
2014 case 0:
2015 instruction->type = ARM_B;
2016 mnemonic = "B";
2017 break;
2018 /* BLX suffix */
2019 case 1:
2020 instruction->type = ARM_BLX;
2021 mnemonic = "BLX";
2022 target_address &= 0xfffffffc;
2023 break;
2024 /* BL/BLX prefix */
2025 case 2:
2026 instruction->type = ARM_UNKNOWN_INSTUCTION;
2027 mnemonic = "prefix";
2028 target_address = offset << 12;
2029 break;
2030 /* BL suffix */
2031 case 3:
2032 instruction->type = ARM_BL;
2033 mnemonic = "BL";
2034 break;
2035 }
2036
2037 /* TODO: deal correctly with dual opcode (prefixed) BL/BLX;
2038 * these are effectively 32-bit instructions even in Thumb1. For
2039 * disassembly, it's simplest to always use the Thumb2 decoder.
2040 *
2041 * But some cores will evidently handle them as two instructions,
2042 * where exceptions may occur between the two. The ETMv3.2+ ID
2043 * register has a bit which exposes this behavior.
2044 */
2045
2046 snprintf(instruction->text, 128,
2047 "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%#8.8" PRIx32,
2048 address, opcode, mnemonic, target_address);
2049
2050 instruction->info.b_bl_bx_blx.reg_operand = -1;
2051 instruction->info.b_bl_bx_blx.target_address = target_address;
2052
2053 return ERROR_OK;
2054 }
2055
2056 static int evaluate_add_sub_thumb(uint16_t opcode,
2057 uint32_t address, struct arm_instruction *instruction)
2058 {
2059 uint8_t Rd = (opcode >> 0) & 0x7;
2060 uint8_t Rn = (opcode >> 3) & 0x7;
2061 uint8_t Rm_imm = (opcode >> 6) & 0x7;
2062 uint32_t opc = opcode & (1 << 9);
2063 uint32_t reg_imm = opcode & (1 << 10);
2064 char *mnemonic;
2065
2066 if (opc) {
2067 instruction->type = ARM_SUB;
2068 mnemonic = "SUBS";
2069 } else {
2070 /* REVISIT: if reg_imm == 0, display as "MOVS" */
2071 instruction->type = ARM_ADD;
2072 mnemonic = "ADDS";
2073 }
2074
2075 instruction->info.data_proc.Rd = Rd;
2076 instruction->info.data_proc.Rn = Rn;
2077 instruction->info.data_proc.S = 1;
2078
2079 if (reg_imm) {
2080 instruction->info.data_proc.variant = 0;/*immediate*/
2081 instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
2082 snprintf(instruction->text, 128,
2083 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%d",
2084 address, opcode, mnemonic, Rd, Rn, Rm_imm);
2085 } else {
2086 instruction->info.data_proc.variant = 1;/*immediate shift*/
2087 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
2088 snprintf(instruction->text, 128,
2089 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, r%i",
2090 address, opcode, mnemonic, Rd, Rn, Rm_imm);
2091 }
2092
2093 return ERROR_OK;
2094 }
2095
2096 static int evaluate_shift_imm_thumb(uint16_t opcode,
2097 uint32_t address, struct arm_instruction *instruction)
2098 {
2099 uint8_t Rd = (opcode >> 0) & 0x7;
2100 uint8_t Rm = (opcode >> 3) & 0x7;
2101 uint8_t imm = (opcode >> 6) & 0x1f;
2102 uint8_t opc = (opcode >> 11) & 0x3;
2103 char *mnemonic = NULL;
2104
2105 switch (opc) {
2106 case 0:
2107 instruction->type = ARM_MOV;
2108 mnemonic = "LSLS";
2109 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
2110 break;
2111 case 1:
2112 instruction->type = ARM_MOV;
2113 mnemonic = "LSRS";
2114 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
2115 break;
2116 case 2:
2117 instruction->type = ARM_MOV;
2118 mnemonic = "ASRS";
2119 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
2120 break;
2121 }
2122
2123 if ((imm == 0) && (opc != 0))
2124 imm = 32;
2125
2126 instruction->info.data_proc.Rd = Rd;
2127 instruction->info.data_proc.Rn = -1;
2128 instruction->info.data_proc.S = 1;
2129
2130 instruction->info.data_proc.variant = 1;/*immediate_shift*/
2131 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2132 instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
2133
2134 snprintf(instruction->text, 128,
2135 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%#2.2x",
2136 address, opcode, mnemonic, Rd, Rm, imm);
2137
2138 return ERROR_OK;
2139 }
2140
2141 static int evaluate_data_proc_imm_thumb(uint16_t opcode,
2142 uint32_t address, struct arm_instruction *instruction)
2143 {
2144 uint8_t imm = opcode & 0xff;
2145 uint8_t Rd = (opcode >> 8) & 0x7;
2146 uint32_t opc = (opcode >> 11) & 0x3;
2147 char *mnemonic = NULL;
2148
2149 instruction->info.data_proc.Rd = Rd;
2150 instruction->info.data_proc.Rn = Rd;
2151 instruction->info.data_proc.S = 1;
2152 instruction->info.data_proc.variant = 0;/*immediate*/
2153 instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
2154
2155 switch (opc) {
2156 case 0:
2157 instruction->type = ARM_MOV;
2158 mnemonic = "MOVS";
2159 instruction->info.data_proc.Rn = -1;
2160 break;
2161 case 1:
2162 instruction->type = ARM_CMP;
2163 mnemonic = "CMP";
2164 instruction->info.data_proc.Rd = -1;
2165 break;
2166 case 2:
2167 instruction->type = ARM_ADD;
2168 mnemonic = "ADDS";
2169 break;
2170 case 3:
2171 instruction->type = ARM_SUB;
2172 mnemonic = "SUBS";
2173 break;
2174 }
2175
2176 snprintf(instruction->text, 128,
2177 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, #%#2.2x",
2178 address, opcode, mnemonic, Rd, imm);
2179
2180 return ERROR_OK;
2181 }
2182
2183 static int evaluate_data_proc_thumb(uint16_t opcode,
2184 uint32_t address, struct arm_instruction *instruction)
2185 {
2186 uint8_t high_reg, op, Rm, Rd, H1, H2;
2187 char *mnemonic = NULL;
2188 bool nop = false;
2189
2190 high_reg = (opcode & 0x0400) >> 10;
2191 op = (opcode & 0x03C0) >> 6;
2192
2193 Rd = (opcode & 0x0007);
2194 Rm = (opcode & 0x0038) >> 3;
2195 H1 = (opcode & 0x0080) >> 7;
2196 H2 = (opcode & 0x0040) >> 6;
2197
2198 instruction->info.data_proc.Rd = Rd;
2199 instruction->info.data_proc.Rn = Rd;
2200 instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
2201 instruction->info.data_proc.variant = 1 /*immediate shift*/;
2202 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2203
2204 if (high_reg) {
2205 Rd |= H1 << 3;
2206 Rm |= H2 << 3;
2207 op >>= 2;
2208
2209 switch (op) {
2210 case 0x0:
2211 instruction->type = ARM_ADD;
2212 mnemonic = "ADD";
2213 break;
2214 case 0x1:
2215 instruction->type = ARM_CMP;
2216 mnemonic = "CMP";
2217 break;
2218 case 0x2:
2219 instruction->type = ARM_MOV;
2220 mnemonic = "MOV";
2221 if (Rd == Rm)
2222 nop = true;
2223 break;
2224 case 0x3:
2225 if ((opcode & 0x7) == 0x0) {
2226 instruction->info.b_bl_bx_blx.reg_operand = Rm;
2227 if (H1) {
2228 instruction->type = ARM_BLX;
2229 snprintf(instruction->text, 128,
2230 "0x%8.8" PRIx32
2231 " 0x%4.4x \tBLX\tr%i",
2232 address, opcode, Rm);
2233 } else {
2234 instruction->type = ARM_BX;
2235 snprintf(instruction->text, 128,
2236 "0x%8.8" PRIx32
2237 " 0x%4.4x \tBX\tr%i",
2238 address, opcode, Rm);
2239 }
2240 } else {
2241 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2242 snprintf(instruction->text, 128,
2243 "0x%8.8" PRIx32
2244 " 0x%4.4x \t"
2245 "UNDEFINED INSTRUCTION",
2246 address, opcode);
2247 }
2248 return ERROR_OK;
2249 break;
2250 }
2251 } else {
2252 switch (op) {
2253 case 0x0:
2254 instruction->type = ARM_AND;
2255 mnemonic = "ANDS";
2256 break;
2257 case 0x1:
2258 instruction->type = ARM_EOR;
2259 mnemonic = "EORS";
2260 break;
2261 case 0x2:
2262 instruction->type = ARM_MOV;
2263 mnemonic = "LSLS";
2264 instruction->info.data_proc.variant = 2 /*register shift*/;
2265 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
2266 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2267 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2268 break;
2269 case 0x3:
2270 instruction->type = ARM_MOV;
2271 mnemonic = "LSRS";
2272 instruction->info.data_proc.variant = 2 /*register shift*/;
2273 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
2274 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2275 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2276 break;
2277 case 0x4:
2278 instruction->type = ARM_MOV;
2279 mnemonic = "ASRS";
2280 instruction->info.data_proc.variant = 2 /*register shift*/;
2281 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
2282 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2283 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2284 break;
2285 case 0x5:
2286 instruction->type = ARM_ADC;
2287 mnemonic = "ADCS";
2288 break;
2289 case 0x6:
2290 instruction->type = ARM_SBC;
2291 mnemonic = "SBCS";
2292 break;
2293 case 0x7:
2294 instruction->type = ARM_MOV;
2295 mnemonic = "RORS";
2296 instruction->info.data_proc.variant = 2 /*register shift*/;
2297 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
2298 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2299 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2300 break;
2301 case 0x8:
2302 instruction->type = ARM_TST;
2303 mnemonic = "TST";
2304 break;
2305 case 0x9:
2306 instruction->type = ARM_RSB;
2307 mnemonic = "RSBS";
2308 instruction->info.data_proc.variant = 0 /*immediate*/;
2309 instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
2310 instruction->info.data_proc.Rn = Rm;
2311 break;
2312 case 0xA:
2313 instruction->type = ARM_CMP;
2314 mnemonic = "CMP";
2315 break;
2316 case 0xB:
2317 instruction->type = ARM_CMN;
2318 mnemonic = "CMN";
2319 break;
2320 case 0xC:
2321 instruction->type = ARM_ORR;
2322 mnemonic = "ORRS";
2323 break;
2324 case 0xD:
2325 instruction->type = ARM_MUL;
2326 mnemonic = "MULS";
2327 break;
2328 case 0xE:
2329 instruction->type = ARM_BIC;
2330 mnemonic = "BICS";
2331 break;
2332 case 0xF:
2333 instruction->type = ARM_MVN;
2334 mnemonic = "MVNS";
2335 break;
2336 }
2337 }
2338
2339 if (nop)
2340 snprintf(instruction->text, 128,
2341 "0x%8.8" PRIx32 " 0x%4.4x \tNOP\t\t\t"
2342 "; (%s r%i, r%i)",
2343 address, opcode, mnemonic, Rd, Rm);
2344 else
2345 snprintf(instruction->text, 128,
2346 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i",
2347 address, opcode, mnemonic, Rd, Rm);
2348
2349 return ERROR_OK;
2350 }
2351
2352 /* PC-relative data addressing is word-aligned even with Thumb */
2353 static inline uint32_t thumb_alignpc4(uint32_t addr)
2354 {
2355 return (addr + 4) & ~3;
2356 }
2357
2358 static int evaluate_load_literal_thumb(uint16_t opcode,
2359 uint32_t address, struct arm_instruction *instruction)
2360 {
2361 uint32_t immediate;
2362 uint8_t Rd = (opcode >> 8) & 0x7;
2363
2364 instruction->type = ARM_LDR;
2365 immediate = opcode & 0x000000ff;
2366 immediate *= 4;
2367
2368 instruction->info.load_store.Rd = Rd;
2369 instruction->info.load_store.Rn = 15 /*PC*/;
2370 instruction->info.load_store.index_mode = 0; /*offset*/
2371 instruction->info.load_store.offset_mode = 0; /*immediate*/
2372 instruction->info.load_store.offset.offset = immediate;
2373
2374 snprintf(instruction->text, 128,
2375 "0x%8.8" PRIx32 " 0x%4.4x \t"
2376 "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32,
2377 address, opcode, Rd, immediate,
2378 thumb_alignpc4(address) + immediate);
2379
2380 return ERROR_OK;
2381 }
2382
2383 static int evaluate_load_store_reg_thumb(uint16_t opcode,
2384 uint32_t address, struct arm_instruction *instruction)
2385 {
2386 uint8_t Rd = (opcode >> 0) & 0x7;
2387 uint8_t Rn = (opcode >> 3) & 0x7;
2388 uint8_t Rm = (opcode >> 6) & 0x7;
2389 uint8_t opc = (opcode >> 9) & 0x7;
2390 char *mnemonic = NULL;
2391
2392 switch (opc) {
2393 case 0:
2394 instruction->type = ARM_STR;
2395 mnemonic = "STR";
2396 break;
2397 case 1:
2398 instruction->type = ARM_STRH;
2399 mnemonic = "STRH";
2400 break;
2401 case 2:
2402 instruction->type = ARM_STRB;
2403 mnemonic = "STRB";
2404 break;
2405 case 3:
2406 instruction->type = ARM_LDRSB;
2407 mnemonic = "LDRSB";
2408 break;
2409 case 4:
2410 instruction->type = ARM_LDR;
2411 mnemonic = "LDR";
2412 break;
2413 case 5:
2414 instruction->type = ARM_LDRH;
2415 mnemonic = "LDRH";
2416 break;
2417 case 6:
2418 instruction->type = ARM_LDRB;
2419 mnemonic = "LDRB";
2420 break;
2421 case 7:
2422 instruction->type = ARM_LDRSH;
2423 mnemonic = "LDRSH";
2424 break;
2425 }
2426
2427 snprintf(instruction->text, 128,
2428 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [r%i, r%i]",
2429 address, opcode, mnemonic, Rd, Rn, Rm);
2430
2431 instruction->info.load_store.Rd = Rd;
2432 instruction->info.load_store.Rn = Rn;
2433 instruction->info.load_store.index_mode = 0; /*offset*/
2434 instruction->info.load_store.offset_mode = 1; /*register*/
2435 instruction->info.load_store.offset.reg.Rm = Rm;
2436
2437 return ERROR_OK;
2438 }
2439
2440 static int evaluate_load_store_imm_thumb(uint16_t opcode,
2441 uint32_t address, struct arm_instruction *instruction)
2442 {
2443 uint32_t offset = (opcode >> 6) & 0x1f;
2444 uint8_t Rd = (opcode >> 0) & 0x7;
2445 uint8_t Rn = (opcode >> 3) & 0x7;
2446 uint32_t L = opcode & (1 << 11);
2447 uint32_t B = opcode & (1 << 12);
2448 char *mnemonic;
2449 char suffix = ' ';
2450 uint32_t shift = 2;
2451
2452 if (L) {
2453 instruction->type = ARM_LDR;
2454 mnemonic = "LDR";
2455 } else {
2456 instruction->type = ARM_STR;
2457 mnemonic = "STR";
2458 }
2459
2460 if ((opcode&0xF000) == 0x8000) {
2461 suffix = 'H';
2462 shift = 1;
2463 } else if (B) {
2464 suffix = 'B';
2465 shift = 0;
2466 }
2467
2468 snprintf(instruction->text, 128,
2469 "0x%8.8" PRIx32 " 0x%4.4x \t%s%c\tr%i, [r%i, #%#" PRIx32 "]",
2470 address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
2471
2472 instruction->info.load_store.Rd = Rd;
2473 instruction->info.load_store.Rn = Rn;
2474 instruction->info.load_store.index_mode = 0; /*offset*/
2475 instruction->info.load_store.offset_mode = 0; /*immediate*/
2476 instruction->info.load_store.offset.offset = offset << shift;
2477
2478 return ERROR_OK;
2479 }
2480
2481 static int evaluate_load_store_stack_thumb(uint16_t opcode,
2482 uint32_t address, struct arm_instruction *instruction)
2483 {
2484 uint32_t offset = opcode & 0xff;
2485 uint8_t Rd = (opcode >> 8) & 0x7;
2486 uint32_t L = opcode & (1 << 11);
2487 char *mnemonic;
2488
2489 if (L) {
2490 instruction->type = ARM_LDR;
2491 mnemonic = "LDR";
2492 } else {
2493 instruction->type = ARM_STR;
2494 mnemonic = "STR";
2495 }
2496
2497 snprintf(instruction->text, 128,
2498 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [SP, #%#" PRIx32 "]",
2499 address, opcode, mnemonic, Rd, offset*4);
2500
2501 instruction->info.load_store.Rd = Rd;
2502 instruction->info.load_store.Rn = 13 /*SP*/;
2503 instruction->info.load_store.index_mode = 0; /*offset*/
2504 instruction->info.load_store.offset_mode = 0; /*immediate*/
2505 instruction->info.load_store.offset.offset = offset*4;
2506
2507 return ERROR_OK;
2508 }
2509
2510 static int evaluate_add_sp_pc_thumb(uint16_t opcode,
2511 uint32_t address, struct arm_instruction *instruction)
2512 {
2513 uint32_t imm = opcode & 0xff;
2514 uint8_t Rd = (opcode >> 8) & 0x7;
2515 uint8_t Rn;
2516 uint32_t SP = opcode & (1 << 11);
2517 const char *reg_name;
2518
2519 instruction->type = ARM_ADD;
2520
2521 if (SP) {
2522 reg_name = "SP";
2523 Rn = 13;
2524 } else {
2525 reg_name = "PC";
2526 Rn = 15;
2527 }
2528
2529 snprintf(instruction->text, 128,
2530 "0x%8.8" PRIx32 " 0x%4.4x \tADD\tr%i, %s, #%#" PRIx32,
2531 address, opcode, Rd, reg_name, imm * 4);
2532
2533 instruction->info.data_proc.variant = 0 /* immediate */;
2534 instruction->info.data_proc.Rd = Rd;
2535 instruction->info.data_proc.Rn = Rn;
2536 instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2537
2538 return ERROR_OK;
2539 }
2540
2541 static int evaluate_adjust_stack_thumb(uint16_t opcode,
2542 uint32_t address, struct arm_instruction *instruction)
2543 {
2544 uint32_t imm = opcode & 0x7f;
2545 uint8_t opc = opcode & (1 << 7);
2546 char *mnemonic;
2547
2548
2549 if (opc) {
2550 instruction->type = ARM_SUB;
2551 mnemonic = "SUB";
2552 } else {
2553 instruction->type = ARM_ADD;
2554 mnemonic = "ADD";
2555 }
2556
2557 snprintf(instruction->text, 128,
2558 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tSP, #%#" PRIx32,
2559 address, opcode, mnemonic, imm*4);
2560
2561 instruction->info.data_proc.variant = 0 /* immediate */;
2562 instruction->info.data_proc.Rd = 13 /*SP*/;
2563 instruction->info.data_proc.Rn = 13 /*SP*/;
2564 instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2565
2566 return ERROR_OK;
2567 }
2568
2569 static int evaluate_breakpoint_thumb(uint16_t opcode,
2570 uint32_t address, struct arm_instruction *instruction)
2571 {
2572 uint32_t imm = opcode & 0xff;
2573
2574 instruction->type = ARM_BKPT;
2575
2576 snprintf(instruction->text, 128,
2577 "0x%8.8" PRIx32 " 0x%4.4x \tBKPT\t%#2.2" PRIx32 "",
2578 address, opcode, imm);
2579
2580 return ERROR_OK;
2581 }
2582
2583 static int evaluate_load_store_multiple_thumb(uint16_t opcode,
2584 uint32_t address, struct arm_instruction *instruction)
2585 {
2586 uint32_t reg_list = opcode & 0xff;
2587 uint32_t L = opcode & (1 << 11);
2588 uint32_t R = opcode & (1 << 8);
2589 uint8_t Rn = (opcode >> 8) & 7;
2590 uint8_t addr_mode = 0 /* IA */;
2591 char reg_names[40];
2592 char *reg_names_p;
2593 char *mnemonic;
2594 char ptr_name[7] = "";
2595 int i;
2596
2597 /* REVISIT: in ThumbEE mode, there are no LDM or STM instructions.
2598 * The STMIA and LDMIA opcodes are used for other instructions.
2599 */
2600
2601 if ((opcode & 0xf000) == 0xc000) { /* generic load/store multiple */
2602 char *wback = "!";
2603
2604 if (L) {
2605 instruction->type = ARM_LDM;
2606 mnemonic = "LDM";
2607 if (opcode & (1 << Rn))
2608 wback = "";
2609 } else {
2610 instruction->type = ARM_STM;
2611 mnemonic = "STM";
2612 }
2613 snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback);
2614 } else {/* push/pop */
2615 Rn = 13;/* SP */
2616 if (L) {
2617 instruction->type = ARM_LDM;
2618 mnemonic = "POP";
2619 if (R)
2620 reg_list |= (1 << 15) /*PC*/;
2621 } else {
2622 instruction->type = ARM_STM;
2623 mnemonic = "PUSH";
2624 addr_mode = 3; /*DB*/
2625 if (R)
2626 reg_list |= (1 << 14) /*LR*/;
2627 }
2628 }
2629
2630 reg_names_p = reg_names;
2631 for (i = 0; i <= 15; i++) {
2632 if (reg_list & (1 << i))
2633 reg_names_p += snprintf(reg_names_p,
2634 (reg_names + 40 - reg_names_p),
2635 "r%i, ",
2636 i);
2637 }
2638 if (reg_names_p > reg_names)
2639 reg_names_p[-2] = '\0';
2640 else /* invalid op : no registers */
2641 reg_names[0] = '\0';
2642
2643 snprintf(instruction->text, 128,
2644 "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%s{%s}",
2645 address, opcode, mnemonic, ptr_name, reg_names);
2646
2647 instruction->info.load_store_multiple.register_list = reg_list;
2648 instruction->info.load_store_multiple.Rn = Rn;
2649 instruction->info.load_store_multiple.addressing_mode = addr_mode;
2650
2651 return ERROR_OK;
2652 }
2653
2654 static int evaluate_cond_branch_thumb(uint16_t opcode,
2655 uint32_t address, struct arm_instruction *instruction)
2656 {
2657 uint32_t offset = opcode & 0xff;
2658 uint8_t cond = (opcode >> 8) & 0xf;
2659 uint32_t target_address;
2660
2661 if (cond == 0xf) {
2662 instruction->type = ARM_SWI;
2663 snprintf(instruction->text, 128,
2664 "0x%8.8" PRIx32 " 0x%4.4x \tSVC\t%#2.2" PRIx32,
2665 address, opcode, offset);
2666 return ERROR_OK;
2667 } else if (cond == 0xe) {
2668 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2669 snprintf(instruction->text, 128,
2670 "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION",
2671 address, opcode);
2672 return ERROR_OK;
2673 }
2674
2675 /* sign extend 8-bit offset */
2676 if (offset & 0x00000080)
2677 offset = 0xffffff00 | offset;
2678
2679 target_address = address + 4 + (offset << 1);
2680
2681 snprintf(instruction->text, 128,
2682 "0x%8.8" PRIx32 " 0x%4.4x \tB%s\t%#8.8" PRIx32,
2683 address, opcode,
2684 arm_condition_strings[cond], target_address);
2685
2686 instruction->type = ARM_B;
2687 instruction->info.b_bl_bx_blx.reg_operand = -1;
2688 instruction->info.b_bl_bx_blx.target_address = target_address;
2689
2690 return ERROR_OK;
2691 }
2692
2693 static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
2694 struct arm_instruction *instruction)
2695 {
2696 unsigned offset;
2697
2698 /* added in Thumb2 */
2699 offset = (opcode >> 3) & 0x1f;
2700 offset |= (opcode & 0x0200) >> 4;
2701
2702 snprintf(instruction->text, 128,
2703 "0x%8.8" PRIx32 " 0x%4.4x \tCB%sZ\tr%d, %#8.8" PRIx32,
2704 address, opcode,
2705 (opcode & 0x0800) ? "N" : "",
2706 opcode & 0x7, address + 4 + (offset << 1));
2707
2708 return ERROR_OK;
2709 }
2710
2711 static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
2712 struct arm_instruction *instruction)
2713 {
2714 /* added in ARMv6 */
2715 snprintf(instruction->text, 128,
2716 "0x%8.8" PRIx32 " 0x%4.4x \t%cXT%c\tr%d, r%d",
2717 address, opcode,
2718 (opcode & 0x0080) ? 'U' : 'S',
2719 (opcode & 0x0040) ? 'B' : 'H',
2720 opcode & 0x7, (opcode >> 3) & 0x7);
2721
2722 return ERROR_OK;
2723 }
2724
2725 static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
2726 struct arm_instruction *instruction)
2727 {
2728 /* added in ARMv6 */
2729 if ((opcode & 0x0ff0) == 0x0650)
2730 snprintf(instruction->text, 128,
2731 "0x%8.8" PRIx32 " 0x%4.4x \tSETEND %s",
2732 address, opcode,
2733 (opcode & 0x80) ? "BE" : "LE");
2734 else /* ASSUME (opcode & 0x0fe0) == 0x0660 */
2735 snprintf(instruction->text, 128,
2736 "0x%8.8" PRIx32 " 0x%4.4x \tCPSI%c\t%s%s%s",
2737 address, opcode,
2738 (opcode & 0x0010) ? 'D' : 'E',
2739 (opcode & 0x0004) ? "A" : "",
2740 (opcode & 0x0002) ? "I" : "",
2741 (opcode & 0x0001) ? "F" : "");
2742
2743 return ERROR_OK;
2744 }
2745
2746 static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
2747 struct arm_instruction *instruction)
2748 {
2749 char *suffix;
2750
2751 /* added in ARMv6 */
2752 switch ((opcode >> 6) & 3) {
2753 case 0:
2754 suffix = "";
2755 break;
2756 case 1:
2757 suffix = "16";
2758 break;
2759 default:
2760 suffix = "SH";
2761 break;
2762 }
2763 snprintf(instruction->text, 128,
2764 "0x%8.8" PRIx32 " 0x%4.4x \tREV%s\tr%d, r%d",
2765 address, opcode, suffix,
2766 opcode & 0x7, (opcode >> 3) & 0x7);
2767
2768 return ERROR_OK;
2769 }
2770
2771 static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
2772 struct arm_instruction *instruction)
2773 {
2774 char *hint;
2775
2776 switch ((opcode >> 4) & 0x0f) {
2777 case 0:
2778 hint = "NOP";
2779 break;
2780 case 1:
2781 hint = "YIELD";
2782 break;
2783 case 2:
2784 hint = "WFE";
2785 break;
2786 case 3:
2787 hint = "WFI";
2788 break;
2789 case 4:
2790 hint = "SEV";
2791 break;
2792 default:
2793 hint = "HINT (UNRECOGNIZED)";
2794 break;
2795 }
2796
2797 snprintf(instruction->text, 128,
2798 "0x%8.8" PRIx32 " 0x%4.4x \t%s",
2799 address, opcode, hint);
2800
2801 return ERROR_OK;
2802 }
2803
2804 static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
2805 struct arm_instruction *instruction)
2806 {
2807 unsigned cond = (opcode >> 4) & 0x0f;
2808 char *x = "", *y = "", *z = "";
2809
2810 if (opcode & 0x01)
2811 z = (opcode & 0x02) ? "T" : "E";
2812 if (opcode & 0x03)
2813 y = (opcode & 0x04) ? "T" : "E";
2814 if (opcode & 0x07)
2815 x = (opcode & 0x08) ? "T" : "E";
2816
2817 snprintf(instruction->text, 128,
2818 "0x%8.8" PRIx32 " 0x%4.4x \tIT%s%s%s\t%s",
2819 address, opcode,
2820 x, y, z, arm_condition_strings[cond]);
2821
2822 /* NOTE: strictly speaking, the next 1-4 instructions should
2823 * now be displayed with the relevant conditional suffix...
2824 */
2825
2826 return ERROR_OK;
2827 }
2828
2829 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
2830 {
2831 /* clear fields, to avoid confusion */
2832 memset(instruction, 0, sizeof(struct arm_instruction));
2833 instruction->opcode = opcode;
2834 instruction->instruction_size = 2;
2835
2836 if ((opcode & 0xe000) == 0x0000) {
2837 /* add/substract register or immediate */
2838 if ((opcode & 0x1800) == 0x1800)
2839 return evaluate_add_sub_thumb(opcode, address, instruction);
2840 /* shift by immediate */
2841 else
2842 return evaluate_shift_imm_thumb(opcode, address, instruction);
2843 }
2844
2845 /* Add/substract/compare/move immediate */
2846 if ((opcode & 0xe000) == 0x2000)
2847 return evaluate_data_proc_imm_thumb(opcode, address, instruction);
2848
2849 /* Data processing instructions */
2850 if ((opcode & 0xf800) == 0x4000)
2851 return evaluate_data_proc_thumb(opcode, address, instruction);
2852
2853 /* Load from literal pool */
2854 if ((opcode & 0xf800) == 0x4800)
2855 return evaluate_load_literal_thumb(opcode, address, instruction);
2856
2857 /* Load/Store register offset */
2858 if ((opcode & 0xf000) == 0x5000)
2859 return evaluate_load_store_reg_thumb(opcode, address, instruction);
2860
2861 /* Load/Store immediate offset */
2862 if (((opcode & 0xe000) == 0x6000)
2863 || ((opcode & 0xf000) == 0x8000))
2864 return evaluate_load_store_imm_thumb(opcode, address, instruction);
2865
2866 /* Load/Store from/to stack */
2867 if ((opcode & 0xf000) == 0x9000)
2868 return evaluate_load_store_stack_thumb(opcode, address, instruction);
2869
2870 /* Add to SP/PC */
2871 if ((opcode & 0xf000) == 0xa000)
2872 return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2873
2874 /* Misc */
2875 if ((opcode & 0xf000) == 0xb000) {
2876 switch ((opcode >> 8) & 0x0f) {
2877 case 0x0:
2878 return evaluate_adjust_stack_thumb(opcode, address, instruction);
2879 case 0x1:
2880 case 0x3:
2881 case 0x9:
2882 case 0xb:
2883 return evaluate_cb_thumb(opcode, address, instruction);
2884 case 0x2:
2885 return evaluate_extend_thumb(opcode, address, instruction);
2886 case 0x4:
2887 case 0x5:
2888 case 0xc:
2889 case 0xd:
2890 return evaluate_load_store_multiple_thumb(opcode, address,
2891 instruction);
2892 case 0x6:
2893 return evaluate_cps_thumb(opcode, address, instruction);
2894 case 0xa:
2895 if ((opcode & 0x00c0) == 0x0080)
2896 break;
2897 return evaluate_byterev_thumb(opcode, address, instruction);
2898 case 0xe:
2899 return evaluate_breakpoint_thumb(opcode, address, instruction);
2900 case 0xf:
2901 if (opcode & 0x000f)
2902 return evaluate_ifthen_thumb(opcode, address,
2903 instruction);
2904 else
2905 return evaluate_hint_thumb(opcode, address,
2906 instruction);
2907 }
2908
2909 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2910 snprintf(instruction->text, 128,
2911 "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION",
2912 address, opcode);
2913 return ERROR_OK;
2914 }
2915
2916 /* Load/Store multiple */
2917 if ((opcode & 0xf000) == 0xc000)
2918 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2919
2920 /* Conditional branch + SWI */
2921 if ((opcode & 0xf000) == 0xd000)
2922 return evaluate_cond_branch_thumb(opcode, address, instruction);
2923
2924 if ((opcode & 0xe000) == 0xe000) {
2925 /* Undefined instructions */
2926 if ((opcode & 0xf801) == 0xe801) {
2927 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2928 snprintf(instruction->text, 128,
2929 "0x%8.8" PRIx32 " 0x%8.8x\t"
2930 "UNDEFINED INSTRUCTION",
2931 address, opcode);
2932 return ERROR_OK;
2933 } else /* Branch to offset */
2934 return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2935 }
2936
2937 LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
2938 return -1;
2939 }
2940
2941 static int t2ev_b_bl(uint32_t opcode, uint32_t address,
2942 struct arm_instruction *instruction, char *cp)
2943 {
2944 unsigned offset;
2945 unsigned b21 = 1 << 21;
2946 unsigned b22 = 1 << 22;
2947
2948 /* instead of combining two smaller 16-bit branch instructions,
2949 * Thumb2 uses only one larger 32-bit instruction.
2950 */
2951 offset = opcode & 0x7ff;
2952 offset |= (opcode & 0x03ff0000) >> 5;
2953 if (opcode & (1 << 26)) {
2954 offset |= 0xff << 23;
2955 if ((opcode & (1 << 11)) == 0)
2956 b21 = 0;
2957 if ((opcode & (1 << 13)) == 0)
2958 b22 = 0;
2959 } else {
2960 if (opcode & (1 << 11))
2961 b21 = 0;
2962 if (opcode & (1 << 13))
2963 b22 = 0;
2964 }
2965 offset |= b21;
2966 offset |= b22;
2967
2968
2969 address += 4;
2970 address += offset << 1;
2971
2972 char *inst;
2973 switch ((opcode >> 12) & 0x5) {
2974 case 0x1:
2975 inst = "B.W";
2976 instruction->type = ARM_B;
2977 break;
2978 case 0x4:
2979 inst = "BLX";
2980 instruction->type = ARM_BLX;
2981 address &= 0xfffffffc;
2982 break;
2983 case 0x5:
2984 inst = "BL";
2985 instruction->type = ARM_BL;
2986 break;
2987 default:
2988 return ERROR_COMMAND_SYNTAX_ERROR;
2989 }
2990 instruction->info.b_bl_bx_blx.reg_operand = -1;
2991 instruction->info.b_bl_bx_blx.target_address = address;
2992 sprintf(cp, "%s\t%#8.8" PRIx32, inst, address);
2993
2994 return ERROR_OK;
2995 }
2996
2997 static int t2ev_cond_b(uint32_t opcode, uint32_t address,
2998 struct arm_instruction *instruction, char *cp)
2999 {
3000 unsigned offset;
3001 unsigned b17 = 1 << 17;
3002 unsigned b18 = 1 << 18;
3003 unsigned cond = (opcode >> 22) & 0x0f;
3004
3005 offset = opcode & 0x7ff;
3006 offset |= (opcode & 0x003f0000) >> 5;
3007 if (opcode & (1 << 26)) {
3008 offset |= 0x1fff << 19;
3009 if ((opcode & (1 << 11)) == 0)
3010 b17 = 0;
3011 if ((opcode & (1 << 13)) == 0)
3012 b18 = 0;
3013 } else {
3014 if (opcode & (1 << 11))
3015 b17 = 0;
3016 if (opcode & (1 << 13))
3017 b18 = 0;
3018 }
3019 offset |= b17;
3020 offset |= b18;
3021
3022 address += 4;
3023 address += offset << 1;
3024
3025 instruction->type = ARM_B;
3026 instruction->info.b_bl_bx_blx.reg_operand = -1;
3027 instruction->info.b_bl_bx_blx.target_address = address;
3028 sprintf(cp, "B%s.W\t%#8.8" PRIx32,
3029 arm_condition_strings[cond],
3030 address);
3031
3032 return ERROR_OK;
3033 }
3034
3035 static const char *special_name(int number)
3036 {
3037 char *special = "(RESERVED)";
3038
3039 switch (number) {
3040 case 0:
3041 special = "apsr";
3042 break;
3043 case 1:
3044 special = "iapsr";
3045 break;
3046 case 2:
3047 special = "eapsr";
3048 break;
3049 case 3:
3050 special = "xpsr";
3051 break;
3052 case 5:
3053 special = "ipsr";
3054 break;
3055 case 6:
3056 special = "epsr";
3057 break;
3058 case 7:
3059 special = "iepsr";
3060 break;
3061 case 8:
3062 special = "msp";
3063 break;
3064 case 9:
3065 special = "psp";
3066 break;
3067 case 16:
3068 special = "primask";
3069 break;
3070 case 17:
3071 special = "basepri";
3072 break;
3073 case 18:
3074 special = "basepri_max";
3075 break;
3076 case 19:
3077 special = "faultmask";
3078 break;
3079 case 20:
3080 special = "control";
3081 break;
3082 }
3083 return special;
3084 }
3085
3086 static int t2ev_hint(uint32_t opcode, uint32_t address,
3087 struct arm_instruction *instruction, char *cp)
3088 {
3089 const char *mnemonic;
3090
3091 if (opcode & 0x0700) {
3092 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3093 strcpy(cp, "UNDEFINED");
3094 return ERROR_OK;
3095 }
3096
3097 if (opcode & 0x00f0) {
3098 sprintf(cp, "DBG\t#%d", (int) opcode & 0xf);
3099 return ERROR_OK;
3100 }
3101
3102 switch (opcode & 0x0f) {
3103 case 0:
3104 mnemonic = "NOP.W";
3105 break;
3106 case 1:
3107 mnemonic = "YIELD.W";
3108 break;
3109 case 2:
3110 mnemonic = "WFE.W";
3111 break;
3112 case 3:
3113 mnemonic = "WFI.W";
3114 break;
3115 case 4:
3116 mnemonic = "SEV.W";
3117 break;
3118 default:
3119 mnemonic = "HINT.W (UNRECOGNIZED)";
3120 break;
3121 }
3122 strcpy(cp, mnemonic);
3123 return ERROR_OK;
3124 }
3125
3126 static int t2ev_misc(uint32_t opcode, uint32_t address,
3127 struct arm_instruction *instruction, char *cp)
3128 {
3129 const char *mnemonic;
3130
3131 switch ((opcode >> 4) & 0x0f) {
3132 case 0:
3133 mnemonic = "LEAVEX";
3134 break;
3135 case 1:
3136 mnemonic = "ENTERX";
3137 break;
3138 case 2:
3139 mnemonic = "CLREX";
3140 break;
3141 case 4:
3142 mnemonic = "DSB";
3143 break;
3144 case 5:
3145 mnemonic = "DMB";
3146 break;
3147 case 6:
3148 mnemonic = "ISB";
3149 break;
3150 default:
3151 return ERROR_COMMAND_SYNTAX_ERROR;
3152 }
3153 strcpy(cp, mnemonic);
3154 return ERROR_OK;
3155 }
3156
3157 static int t2ev_b_misc(uint32_t opcode, uint32_t address,
3158 struct arm_instruction *instruction, char *cp)
3159 {
3160 /* permanently undefined */
3161 if ((opcode & 0x07f07000) == 0x07f02000) {
3162 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3163 strcpy(cp, "UNDEFINED");
3164 return ERROR_OK;
3165 }
3166
3167 switch ((opcode >> 12) & 0x5) {
3168 case 0x1:
3169 case 0x4:
3170 case 0x5:
3171 return t2ev_b_bl(opcode, address, instruction, cp);
3172 case 0:
3173 if (((opcode >> 23) & 0x07) != 0x07)
3174 return t2ev_cond_b(opcode, address, instruction, cp);
3175 if (opcode & (1 << 26))
3176 goto undef;
3177 break;
3178 }
3179
3180 switch ((opcode >> 20) & 0x7f) {
3181 case 0x38:
3182 case 0x39:
3183 sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff),
3184 (int) (opcode >> 16) & 0x0f);
3185 return ERROR_OK;
3186 case 0x3a:
3187 return t2ev_hint(opcode, address, instruction, cp);
3188 case 0x3b:
3189 return t2ev_misc(opcode, address, instruction, cp);
3190 case 0x3c:
3191 sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f);
3192 return ERROR_OK;
3193 case 0x3e:
3194 case 0x3f:
3195 sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f,
3196 special_name(opcode & 0xff));
3197 return ERROR_OK;
3198 }
3199
3200 undef:
3201 return ERROR_COMMAND_SYNTAX_ERROR;
3202 }
3203
3204 static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
3205 struct arm_instruction *instruction, char *cp)
3206 {
3207 char *mnemonic = NULL;
3208 int rn = (opcode >> 16) & 0xf;
3209 int rd = (opcode >> 8) & 0xf;
3210 unsigned immed = opcode & 0xff;
3211 unsigned func;
3212 bool one = false;
3213 char *suffix = "";
3214 char *suffix2 = "";
3215
3216 /* ARMv7-M: A5.3.2 Modified immediate constants */
3217 func = (opcode >> 11) & 0x0e;
3218 if (immed & 0x80)
3219 func |= 1;
3220 if (opcode & (1 << 26))
3221 func |= 0x10;
3222
3223 /* "Modified" immediates */
3224 switch (func >> 1) {
3225 case 0:
3226 break;
3227 case 2:
3228 immed <<= 8;
3229 /* FALLTHROUGH */
3230 case 1:
3231 immed += immed << 16;
3232 break;
3233 case 3:
3234 immed += immed << 8;
3235 immed += immed << 16;
3236 break;
3237 default:
3238 immed |= 0x80;
3239 immed = ror(immed, func);
3240 }
3241
3242 if (opcode & (1 << 20))
3243 suffix = "S";
3244
3245 switch ((opcode >> 21) & 0xf) {
3246 case 0:
3247 if (rd == 0xf) {
3248 instruction->type = ARM_TST;
3249 mnemonic = "TST";
3250 one = true;
3251 suffix = "";
3252 rd = rn;
3253 } else {
3254 instruction->type = ARM_AND;
3255 mnemonic = "AND";
3256 }
3257 break;
3258 case 1:
3259 instruction->type = ARM_BIC;
3260 mnemonic = "BIC";
3261 break;
3262 case 2:
3263 if (rn == 0xf) {
3264 instruction->type = ARM_MOV;
3265 mnemonic = "MOV";
3266 one = true;
3267 suffix2 = ".W";
3268 } else {
3269 instruction->type = ARM_ORR;
3270 mnemonic = "ORR";
3271 }
3272 break;
3273 case 3:
3274 if (rn == 0xf) {
3275 instruction->type = ARM_MVN;
3276 mnemonic = "MVN";
3277 one = true;
3278 } else {
3279 /* instruction->type = ARM_ORN; */
3280 mnemonic = "ORN";
3281 }
3282 break;
3283 case 4:
3284 if (rd == 0xf) {
3285 instruction->type = ARM_TEQ;
3286 mnemonic = "TEQ";
3287 one = true;
3288 suffix = "";
3289 rd = rn;
3290 } else {
3291 instruction->type = ARM_EOR;
3292 mnemonic = "EOR";
3293 }
3294 break;
3295 case 8:
3296 if (rd == 0xf) {
3297 instruction->type = ARM_CMN;
3298 mnemonic = "CMN";
3299 one = true;
3300 suffix = "";
3301 rd = rn;
3302 } else {
3303 instruction->type = ARM_ADD;
3304 mnemonic = "ADD";
3305 suffix2 = ".W";
3306 }
3307 break;
3308 case 10:
3309 instruction->type = ARM_ADC;
3310 mnemonic = "ADC";
3311 suffix2 = ".W";
3312 break;
3313 case 11:
3314 instruction->type = ARM_SBC;
3315 mnemonic = "SBC";
3316 break;
3317 case 13:
3318 if (rd == 0xf) {
3319 instruction->type = ARM_CMP;
3320 mnemonic = "CMP";
3321 one = true;
3322 suffix = "";
3323 rd = rn;
3324 } else {
3325 instruction->type = ARM_SUB;
3326 mnemonic = "SUB";
3327 }
3328 suffix2 = ".W";
3329 break;
3330 case 14:
3331 instruction->type = ARM_RSB;
3332 mnemonic = "RSB";
3333 suffix2 = ".W";
3334 break;
3335 default:
3336 return ERROR_COMMAND_SYNTAX_ERROR;
3337 }
3338
3339 if (one)
3340 sprintf(cp, "%s%s\tr%d, #%d\t; %#8.8x",
3341 mnemonic, suffix2, rd, immed, immed);
3342 else
3343 sprintf(cp, "%s%s%s\tr%d, r%d, #%d\t; %#8.8x",
3344 mnemonic, suffix, suffix2,
3345 rd, rn, immed, immed);
3346
3347 return ERROR_OK;
3348 }
3349
3350 static int t2ev_data_immed(uint32_t opcode, uint32_t address,
3351 str