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