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 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, #%d",
270  address, opcode,
271  mode, wback,
272  (unsigned)(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%d%s",
278  address, opcode,
279  mode,
280  (unsigned)((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 rm = (opcode >> 0) & 0xf;
705  unsigned rd = (opcode >> 12) & 0xf;
706  unsigned 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 imm = (unsigned) (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 imm = (unsigned) (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 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 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 rm = (opcode >> 0) & 0xf;
1005  unsigned 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=%08x)",
2050  (unsigned) opcode);
2051  return -1;
2052 }
2053 
2054 static int evaluate_b_bl_blx_thumb(uint16_t opcode,
2055  uint32_t address, struct arm_instruction *instruction)
2056 {
2057  uint32_t offset = opcode & 0x7ff;
2058  uint32_t opc = (opcode >> 11) & 0x3;
2059  uint32_t target_address;
2060  char *mnemonic = NULL;
2061 
2062  /* sign extend 11-bit offset */
2063  if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
2064  offset = 0xfffff800 | offset;
2065 
2066  target_address = address + 4 + (offset << 1);
2067 
2068  switch (opc) {
2069  /* unconditional branch */
2070  case 0:
2071  instruction->type = ARM_B;
2072  mnemonic = "B";
2073  break;
2074  /* BLX suffix */
2075  case 1:
2076  instruction->type = ARM_BLX;
2077  mnemonic = "BLX";
2078  target_address &= 0xfffffffc;
2079  break;
2080  /* BL/BLX prefix */
2081  case 2:
2082  instruction->type = ARM_UNKNOWN_INSTRUCTION;
2083  mnemonic = "prefix";
2084  target_address = offset << 12;
2085  break;
2086  /* BL suffix */
2087  case 3:
2088  instruction->type = ARM_BL;
2089  mnemonic = "BL";
2090  break;
2091  }
2092 
2093  /* TODO: deal correctly with dual opcode (prefixed) BL/BLX;
2094  * these are effectively 32-bit instructions even in Thumb1. For
2095  * disassembly, it's simplest to always use the Thumb2 decoder.
2096  *
2097  * But some cores will evidently handle them as two instructions,
2098  * where exceptions may occur between the two. The ETMv3.2+ ID
2099  * register has a bit which exposes this behavior.
2100  */
2101 
2102  snprintf(instruction->text, 128,
2103  "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%#8.8" PRIx32,
2104  address, opcode, mnemonic, target_address);
2105 
2106  instruction->info.b_bl_bx_blx.reg_operand = -1;
2107  instruction->info.b_bl_bx_blx.target_address = target_address;
2108 
2109  return ERROR_OK;
2110 }
2111 
2112 static int evaluate_add_sub_thumb(uint16_t opcode,
2113  uint32_t address, struct arm_instruction *instruction)
2114 {
2115  uint8_t rd = (opcode >> 0) & 0x7;
2116  uint8_t rn = (opcode >> 3) & 0x7;
2117  uint8_t rm_imm = (opcode >> 6) & 0x7;
2118  uint32_t opc = opcode & (1 << 9);
2119  uint32_t reg_imm = opcode & (1 << 10);
2120  char *mnemonic;
2121 
2122  if (opc) {
2123  instruction->type = ARM_SUB;
2124  mnemonic = "SUBS";
2125  } else {
2126  /* REVISIT: if reg_imm == 0, display as "MOVS" */
2127  instruction->type = ARM_ADD;
2128  mnemonic = "ADDS";
2129  }
2130 
2131  instruction->info.data_proc.rd = rd;
2132  instruction->info.data_proc.rn = rn;
2133  instruction->info.data_proc.s = 1;
2134 
2135  if (reg_imm) {
2136  instruction->info.data_proc.variant = 0;/*immediate*/
2137  instruction->info.data_proc.shifter_operand.immediate.immediate = rm_imm;
2138  snprintf(instruction->text, 128,
2139  "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%d",
2140  address, opcode, mnemonic, rd, rn, rm_imm);
2141  } else {
2142  instruction->info.data_proc.variant = 1;/*immediate shift*/
2143  instruction->info.data_proc.shifter_operand.immediate_shift.rm = rm_imm;
2144  snprintf(instruction->text, 128,
2145  "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, r%i",
2146  address, opcode, mnemonic, rd, rn, rm_imm);
2147  }
2148 
2149  return ERROR_OK;
2150 }
2151 
2152 static int evaluate_shift_imm_thumb(uint16_t opcode,
2153  uint32_t address, struct arm_instruction *instruction)
2154 {
2155  uint8_t rd = (opcode >> 0) & 0x7;
2156  uint8_t rm = (opcode >> 3) & 0x7;
2157  uint8_t imm = (opcode >> 6) & 0x1f;
2158  uint8_t opc = (opcode >> 11) & 0x3;
2159  char *mnemonic = NULL;
2160 
2161  switch (opc) {
2162  case 0:
2163  instruction->type = ARM_MOV;
2164  mnemonic = "LSLS";
2166  break;
2167  case 1:
2168  instruction->type = ARM_MOV;
2169  mnemonic = "LSRS";
2171  break;
2172  case 2:
2173  instruction->type = ARM_MOV;
2174  mnemonic = "ASRS";
2176  break;
2177  }
2178 
2179  if ((imm == 0) && (opc != 0))
2180  imm = 32;
2181 
2182  instruction->info.data_proc.rd = rd;
2183  instruction->info.data_proc.rn = -1;
2184  instruction->info.data_proc.s = 1;
2185 
2186  instruction->info.data_proc.variant = 1;/*immediate_shift*/
2187  instruction->info.data_proc.shifter_operand.immediate_shift.rm = rm;
2189 
2190  snprintf(instruction->text, 128,
2191  "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%#2.2x",
2192  address, opcode, mnemonic, rd, rm, imm);
2193 
2194  return ERROR_OK;
2195 }
2196 
2197 static int evaluate_data_proc_imm_thumb(uint16_t opcode,
2198  uint32_t address, struct arm_instruction *instruction)
2199 {
2200  uint8_t imm = opcode & 0xff;
2201  uint8_t rd = (opcode >> 8) & 0x7;
2202  uint32_t opc = (opcode >> 11) & 0x3;
2203  char *mnemonic = NULL;
2204 
2205  instruction->info.data_proc.rd = rd;
2206  instruction->info.data_proc.rn = rd;
2207  instruction->info.data_proc.s = 1;
2208  instruction->info.data_proc.variant = 0;/*immediate*/
2209  instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
2210 
2211  switch (opc) {
2212  case 0:
2213  instruction->type = ARM_MOV;
2214  mnemonic = "MOVS";
2215  instruction->info.data_proc.rn = -1;
2216  break;
2217  case 1:
2218  instruction->type = ARM_CMP;
2219  mnemonic = "CMP";
2220  instruction->info.data_proc.rd = -1;
2221  break;
2222  case 2:
2223  instruction->type = ARM_ADD;
2224  mnemonic = "ADDS";
2225  break;
2226  case 3:
2227  instruction->type = ARM_SUB;
2228  mnemonic = "SUBS";
2229  break;
2230  }
2231 
2232  snprintf(instruction->text, 128,
2233  "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, #%#2.2x",
2234  address, opcode, mnemonic, rd, imm);
2235 
2236  return ERROR_OK;
2237 }
2238 
2239 static int evaluate_data_proc_thumb(uint16_t opcode,
2240  uint32_t address, struct arm_instruction *instruction)
2241 {
2242  uint8_t high_reg, op, rm, rd, h1, h2;
2243  char *mnemonic = NULL;
2244  bool nop = false;
2245 
2246  high_reg = (opcode & 0x0400) >> 10;
2247  op = (opcode & 0x03C0) >> 6;
2248 
2249  rd = (opcode & 0x0007);
2250  rm = (opcode & 0x0038) >> 3;
2251  h1 = (opcode & 0x0080) >> 7;
2252  h2 = (opcode & 0x0040) >> 6;
2253 
2254  instruction->info.data_proc.rd = rd;
2255  instruction->info.data_proc.rn = rd;
2256  instruction->info.data_proc.s = (!high_reg || (instruction->type == ARM_CMP));
2257  instruction->info.data_proc.variant = 1 /*immediate shift*/;
2258  instruction->info.data_proc.shifter_operand.immediate_shift.rm = rm;
2259 
2260  if (high_reg) {
2261  rd |= h1 << 3;
2262  rm |= h2 << 3;
2263  op >>= 2;
2264 
2265  switch (op) {
2266  case 0x0:
2267  instruction->type = ARM_ADD;
2268  mnemonic = "ADD";
2269  break;
2270  case 0x1:
2271  instruction->type = ARM_CMP;
2272  mnemonic = "CMP";
2273  break;
2274  case 0x2:
2275  instruction->type = ARM_MOV;
2276  mnemonic = "MOV";
2277  if (rd == rm)
2278  nop = true;
2279  break;
2280  case 0x3:
2281  if ((opcode & 0x7) == 0x0) {
2282  instruction->info.b_bl_bx_blx.reg_operand = rm;
2283  if (h1) {
2284  instruction->type = ARM_BLX;
2285  snprintf(instruction->text, 128,
2286  "0x%8.8" PRIx32
2287  " 0x%4.4x \tBLX\tr%i",
2288  address, opcode, rm);
2289  } else {
2290  instruction->type = ARM_BX;
2291  snprintf(instruction->text, 128,
2292  "0x%8.8" PRIx32
2293  " 0x%4.4x \tBX\tr%i",
2294  address, opcode, rm);
2295  }
2296  } else {
2297  instruction->type = ARM_UNDEFINED_INSTRUCTION;
2298  snprintf(instruction->text, 128,
2299  "0x%8.8" PRIx32
2300  " 0x%4.4x \t"
2301  "UNDEFINED INSTRUCTION",
2302  address, opcode);
2303  }
2304  return ERROR_OK;
2305  }
2306  } else {
2307  switch (op) {
2308  case 0x0:
2309  instruction->type = ARM_AND;
2310  mnemonic = "ANDS";
2311  break;
2312  case 0x1:
2313  instruction->type = ARM_EOR;
2314  mnemonic = "EORS";
2315  break;
2316  case 0x2:
2317  instruction->type = ARM_MOV;
2318  mnemonic = "LSLS";
2319  instruction->info.data_proc.variant = 2 /*register shift*/;
2321  instruction->info.data_proc.shifter_operand.register_shift.rm = rd;
2322  instruction->info.data_proc.shifter_operand.register_shift.rs = rm;
2323  break;
2324  case 0x3:
2325  instruction->type = ARM_MOV;
2326  mnemonic = "LSRS";
2327  instruction->info.data_proc.variant = 2 /*register shift*/;
2329  instruction->info.data_proc.shifter_operand.register_shift.rm = rd;
2330  instruction->info.data_proc.shifter_operand.register_shift.rs = rm;
2331  break;
2332  case 0x4:
2333  instruction->type = ARM_MOV;
2334  mnemonic = "ASRS";
2335  instruction->info.data_proc.variant = 2 /*register shift*/;
2337  instruction->info.data_proc.shifter_operand.register_shift.rm = rd;
2338  instruction->info.data_proc.shifter_operand.register_shift.rs = rm;
2339  break;
2340  case 0x5:
2341  instruction->type = ARM_ADC;
2342  mnemonic = "ADCS";
2343  break;
2344  case 0x6:
2345  instruction->type = ARM_SBC;
2346  mnemonic = "SBCS";
2347  break;
2348  case 0x7:
2349  instruction->type = ARM_MOV;
2350  mnemonic = "RORS";
2351  instruction->info.data_proc.variant = 2 /*register shift*/;
2353  instruction->info.data_proc.shifter_operand.register_shift.rm = rd;
2354  instruction->info.data_proc.shifter_operand.register_shift.rs = rm;
2355  break;
2356  case 0x8:
2357  instruction->type = ARM_TST;
2358  mnemonic = "TST";
2359  break;
2360  case 0x9:
2361  instruction->type = ARM_RSB;
2362  mnemonic = "RSBS";
2363  instruction->info.data_proc.variant = 0 /*immediate*/;
2364  instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
2365  instruction->info.data_proc.rn = rm;
2366  break;
2367  case 0xA:
2368  instruction->type = ARM_CMP;
2369  mnemonic = "CMP";
2370  break;
2371  case 0xB:
2372  instruction->type = ARM_CMN;
2373  mnemonic = "CMN";
2374  break;
2375  case 0xC:
2376  instruction->type = ARM_ORR;
2377  mnemonic = "ORRS";
2378  break;
2379  case 0xD:
2380  instruction->type = ARM_MUL;
2381  mnemonic = "MULS";
2382  break;
2383  case 0xE:
2384  instruction->type = ARM_BIC;
2385  mnemonic = "BICS";
2386  break;
2387  case 0xF:
2388  instruction->type = ARM_MVN;
2389  mnemonic = "MVNS";
2390  break;
2391  }
2392  }
2393 
2394  if (nop)
2395  snprintf(instruction->text, 128,
2396  "0x%8.8" PRIx32 " 0x%4.4x \tNOP\t\t\t"
2397  "; (%s r%i, r%i)",
2398  address, opcode, mnemonic, rd, rm);
2399  else
2400  snprintf(instruction->text, 128,
2401  "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i",
2402  address, opcode, mnemonic, rd, rm);
2403 
2404  return ERROR_OK;
2405 }
2406 
2407 /* PC-relative data addressing is word-aligned even with Thumb */
2408 static inline uint32_t thumb_alignpc4(uint32_t addr)
2409 {
2410  return (addr + 4) & ~3;
2411 }
2412 
2413 static int evaluate_load_literal_thumb(uint16_t opcode,
2414  uint32_t address, struct arm_instruction *instruction)
2415 {
2416  uint32_t immediate;
2417  uint8_t rd = (opcode >> 8) & 0x7;
2418 
2419  instruction->type = ARM_LDR;
2420  immediate = opcode & 0x000000ff;
2421  immediate *= 4;
2422 
2423  instruction->info.load_store.rd = rd;
2424  instruction->info.load_store.rn = 15 /*PC*/;
2425  instruction->info.load_store.index_mode = 0; /*offset*/
2426  instruction->info.load_store.offset_mode = 0; /*immediate*/
2427  instruction->info.load_store.offset.offset = immediate;
2428 
2429  snprintf(instruction->text, 128,
2430  "0x%8.8" PRIx32 " 0x%4.4x \t"
2431  "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32,
2432  address, opcode, rd, immediate,
2433  thumb_alignpc4(address) + immediate);
2434 
2435  return ERROR_OK;
2436 }
2437 
2438 static int evaluate_load_store_reg_thumb(uint16_t opcode,
2439  uint32_t address, struct arm_instruction *instruction)
2440 {
2441  uint8_t rd = (opcode >> 0) & 0x7;
2442  uint8_t rn = (opcode >> 3) & 0x7;
2443  uint8_t rm = (opcode >> 6) & 0x7;
2444  uint8_t opc = (opcode >> 9) & 0x7;
2445  char *mnemonic = NULL;
2446 
2447  switch (opc) {
2448  case 0:
2449  instruction->type = ARM_STR;
2450  mnemonic = "STR";
2451  break;
2452  case 1:
2453  instruction->type = ARM_STRH;
2454  mnemonic = "STRH";
2455  break;
2456  case 2:
2457  instruction->type = ARM_STRB;
2458  mnemonic = "STRB";
2459  break;
2460  case 3:
2461  instruction->type = ARM_LDRSB;
2462  mnemonic = "LDRSB";
2463  break;
2464  case 4:
2465  instruction->type = ARM_LDR;
2466  mnemonic = "LDR";
2467  break;
2468  case 5:
2469  instruction->type = ARM_LDRH;
2470  mnemonic = "LDRH";
2471  break;
2472  case 6:
2473  instruction->type = ARM_LDRB;
2474  mnemonic = "LDRB";
2475  break;
2476  case 7:
2477  instruction->type = ARM_LDRSH;
2478  mnemonic = "LDRSH";
2479  break;
2480  }
2481 
2482  snprintf(instruction->text, 128,
2483  "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [r%i, r%i]",
2484  address, opcode, mnemonic, rd, rn, rm);
2485 
2486  instruction->info.load_store.rd = rd;
2487  instruction->info.load_store.rn = rn;
2488  instruction->info.load_store.index_mode = 0; /*offset*/
2489  instruction->info.load_store.offset_mode = 1; /*register*/
2490  instruction->info.load_store.offset.reg.rm = rm;
2491 
2492  return ERROR_OK;
2493 }
2494 
2495 static int evaluate_load_store_imm_thumb(uint16_t opcode,
2496  uint32_t address, struct arm_instruction *instruction)
2497 {
2498  uint32_t offset = (opcode >> 6) & 0x1f;
2499  uint8_t rd = (opcode >> 0) & 0x7;
2500  uint8_t rn = (opcode >> 3) & 0x7;
2501  uint32_t l = opcode & (1 << 11);
2502  uint32_t b = opcode & (1 << 12);
2503  char *mnemonic;
2504  char suffix = ' ';
2505  uint32_t shift = 2;
2506 
2507  if (l) {
2508  instruction->type = ARM_LDR;
2509  mnemonic = "LDR";
2510  } else {
2511  instruction->type = ARM_STR;
2512  mnemonic = "STR";
2513  }
2514 
2515  if ((opcode&0xF000) == 0x8000) {
2516  suffix = 'H';
2517  shift = 1;
2518  } else if (b) {
2519  suffix = 'B';
2520  shift = 0;
2521  }
2522 
2523  snprintf(instruction->text, 128,
2524  "0x%8.8" PRIx32 " 0x%4.4x \t%s%c\tr%i, [r%i, #%#" PRIx32 "]",
2525  address, opcode, mnemonic, suffix, rd, rn, offset << shift);
2526 
2527  instruction->info.load_store.rd = rd;
2528  instruction->info.load_store.rn = rn;
2529  instruction->info.load_store.index_mode = 0; /*offset*/
2530  instruction->info.load_store.offset_mode = 0; /*immediate*/
2531  instruction->info.load_store.offset.offset = offset << shift;
2532 
2533  return ERROR_OK;
2534 }
2535 
2536 static int evaluate_load_store_stack_thumb(uint16_t opcode,
2537  uint32_t address, struct arm_instruction *instruction)
2538 {
2539  uint32_t offset = opcode & 0xff;
2540  uint8_t rd = (opcode >> 8) & 0x7;
2541  uint32_t l = opcode & (1 << 11);
2542  char *mnemonic;
2543 
2544  if (l) {
2545  instruction->type = ARM_LDR;
2546  mnemonic = "LDR";
2547  } else {
2548  instruction->type = ARM_STR;
2549  mnemonic = "STR";
2550  }
2551 
2552  snprintf(instruction->text, 128,
2553  "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [SP, #%#" PRIx32 "]",
2554  address, opcode, mnemonic, rd, offset*4);
2555 
2556  instruction->info.load_store.rd = rd;
2557  instruction->info.load_store.rn = 13 /*SP*/;
2558  instruction->info.load_store.index_mode = 0; /*offset*/
2559  instruction->info.load_store.offset_mode = 0; /*immediate*/
2560  instruction->info.load_store.offset.offset = offset*4;
2561 
2562  return ERROR_OK;
2563 }
2564 
2565 static int evaluate_add_sp_pc_thumb(uint16_t opcode,
2566  uint32_t address, struct arm_instruction *instruction)
2567 {
2568  uint32_t imm = opcode & 0xff;
2569  uint8_t rd = (opcode >> 8) & 0x7;
2570  uint8_t rn;
2571  uint32_t sp = opcode & (1 << 11);
2572  const char *reg_name;
2573 
2574  instruction->type = ARM_ADD;
2575 
2576  if (sp) {
2577  reg_name = "SP";
2578  rn = 13;
2579  } else {
2580  reg_name = "PC";
2581  rn = 15;
2582  }
2583 
2584  snprintf(instruction->text, 128,
2585  "0x%8.8" PRIx32 " 0x%4.4x \tADD\tr%i, %s, #%#" PRIx32,
2586  address, opcode, rd, reg_name, imm * 4);
2587 
2588  instruction->info.data_proc.variant = 0 /* immediate */;
2589  instruction->info.data_proc.rd = rd;
2590  instruction->info.data_proc.rn = rn;
2591  instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2592 
2593  return ERROR_OK;
2594 }
2595 
2596 static int evaluate_adjust_stack_thumb(uint16_t opcode,
2597  uint32_t address, struct arm_instruction *instruction)
2598 {
2599  uint32_t imm = opcode & 0x7f;
2600  uint8_t opc = opcode & (1 << 7);
2601  char *mnemonic;
2602 
2603 
2604  if (opc) {
2605  instruction->type = ARM_SUB;
2606  mnemonic = "SUB";
2607  } else {
2608  instruction->type = ARM_ADD;
2609  mnemonic = "ADD";
2610  }
2611 
2612  snprintf(instruction->text, 128,
2613  "0x%8.8" PRIx32 " 0x%4.4x \t%s\tSP, #%#" PRIx32,
2614  address, opcode, mnemonic, imm*4);
2615 
2616  instruction->info.data_proc.variant = 0 /* immediate */;
2617  instruction->info.data_proc.rd = 13 /*SP*/;
2618  instruction->info.data_proc.rn = 13 /*SP*/;
2619  instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2620 
2621  return ERROR_OK;
2622 }
2623 
2624 static int evaluate_breakpoint_thumb(uint16_t opcode,
2625  uint32_t address, struct arm_instruction *instruction)
2626 {
2627  uint32_t imm = opcode & 0xff;
2628 
2629  instruction->type = ARM_BKPT;
2630 
2631  snprintf(instruction->text, 128,
2632  "0x%8.8" PRIx32 " 0x%4.4x \tBKPT\t%#2.2" PRIx32 "",
2633  address, opcode, imm);
2634 
2635  return ERROR_OK;
2636 }
2637 
2638 static int evaluate_load_store_multiple_thumb(uint16_t opcode,
2639  uint32_t address, struct arm_instruction *instruction)
2640 {
2641  uint32_t reg_list = opcode & 0xff;
2642  uint32_t l = opcode & (1 << 11);
2643  uint32_t r = opcode & (1 << 8);
2644  uint8_t rn = (opcode >> 8) & 7;
2645  uint8_t addr_mode = 0 /* IA */;
2646  char reg_names[40];
2647  char *reg_names_p;
2648  char *mnemonic;
2649  char ptr_name[7] = "";
2650  int i;
2651 
2652  /* REVISIT: in ThumbEE mode, there are no LDM or STM instructions.
2653  * The STMIA and LDMIA opcodes are used for other instructions.
2654  */
2655 
2656  if ((opcode & 0xf000) == 0xc000) { /* generic load/store multiple */
2657  char *wback = "!";
2658 
2659  if (l) {
2660  instruction->type = ARM_LDM;
2661  mnemonic = "LDM";
2662  if (opcode & (1 << rn))
2663  wback = "";
2664  } else {
2665  instruction->type = ARM_STM;
2666  mnemonic = "STM";
2667  }
2668  snprintf(ptr_name, sizeof(ptr_name), "r%i%s, ", rn, wback);
2669  } else {/* push/pop */
2670  rn = 13;/* SP */
2671  if (l) {
2672  instruction->type = ARM_LDM;
2673  mnemonic = "POP";
2674  if (r)
2675  reg_list |= (1 << 15) /*PC*/;
2676  } else {
2677  instruction->type = ARM_STM;
2678  mnemonic = "PUSH";
2679  addr_mode = 3; /*DB*/
2680  if (r)
2681  reg_list |= (1 << 14) /*LR*/;
2682  }
2683  }
2684 
2685  reg_names_p = reg_names;
2686  for (i = 0; i <= 15; i++) {
2687  if (reg_list & (1 << i))
2688  reg_names_p += snprintf(reg_names_p,
2689  (reg_names + 40 - reg_names_p),
2690  "r%i, ",
2691  i);
2692  }
2693  if (reg_names_p > reg_names)
2694  reg_names_p[-2] = '\0';
2695  else /* invalid op : no registers */
2696  reg_names[0] = '\0';
2697 
2698  snprintf(instruction->text, 128,
2699  "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%s{%s}",
2700  address, opcode, mnemonic, ptr_name, reg_names);
2701 
2702  instruction->info.load_store_multiple.register_list = reg_list;
2703  instruction->info.load_store_multiple.rn = rn;
2704  instruction->info.load_store_multiple.addressing_mode = addr_mode;
2705 
2706  return ERROR_OK;
2707 }
2708 
2709 static int evaluate_cond_branch_thumb(uint16_t opcode,
2710  uint32_t address, struct arm_instruction *instruction)
2711 {
2712  uint32_t offset = opcode & 0xff;
2713  uint8_t cond = (opcode >> 8) & 0xf;
2714  uint32_t target_address;
2715 
2716  if (cond == 0xf) {
2717  instruction->type = ARM_SWI;
2718  snprintf(instruction->text, 128,
2719  "0x%8.8" PRIx32 " 0x%4.4x \tSVC\t%#2.2" PRIx32,
2720  address, opcode, offset);
2721  return ERROR_OK;
2722  } else if (cond == 0xe) {
2723  instruction->type = ARM_UNDEFINED_INSTRUCTION;
2724  snprintf(instruction->text, 128,
2725  "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION",
2726  address, opcode);
2727  return ERROR_OK;
2728  }
2729 
2730  /* sign extend 8-bit offset */
2731  if (offset & 0x00000080)
2732  offset = 0xffffff00 | offset;
2733 
2734  target_address = address + 4 + (offset << 1);
2735 
2736  snprintf(instruction->text, 128,
2737  "0x%8.8" PRIx32 " 0x%4.4x \tB%s\t%#8.8" PRIx32,
2738  address, opcode,
2739  arm_condition_strings[cond], target_address);
2740 
2741  instruction->type = ARM_B;
2742  instruction->info.b_bl_bx_blx.reg_operand = -1;
2743  instruction->info.b_bl_bx_blx.target_address = target_address;
2744 
2745  return ERROR_OK;
2746 }
2747 
2748 static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
2749  struct arm_instruction *instruction)
2750 {
2751  unsigned offset;
2752 
2753  /* added in Thumb2 */
2754  offset = (opcode >> 3) & 0x1f;
2755  offset |= (opcode & 0x0200) >> 4;
2756 
2757  snprintf(instruction->text, 128,
2758  "0x%8.8" PRIx32 " 0x%4.4x \tCB%sZ\tr%d, %#8.8" PRIx32,
2759  address, opcode,
2760  (opcode & 0x0800) ? "N" : "",
2761  opcode & 0x7, address + 4 + (offset << 1));
2762 
2763  return ERROR_OK;
2764 }
2765 
2766 static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
2767  struct arm_instruction *instruction)
2768 {
2769  /* added in ARMv6 */
2770  snprintf(instruction->text, 128,
2771  "0x%8.8" PRIx32 " 0x%4.4x \t%cXT%c\tr%d, r%d",
2772  address, opcode,
2773  (opcode & 0x0080) ? 'U' : 'S',
2774  (opcode & 0x0040) ? 'B' : 'H',
2775  opcode & 0x7, (opcode >> 3) & 0x7);
2776 
2777  return ERROR_OK;
2778 }
2779 
2780 static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
2781  struct arm_instruction *instruction)
2782 {
2783  /* added in ARMv6 */
2784  if ((opcode & 0x0ff0) == 0x0650)
2785  snprintf(instruction->text, 128,
2786  "0x%8.8" PRIx32 " 0x%4.4x \tSETEND %s",
2787  address, opcode,
2788  (opcode & 0x80) ? "BE" : "LE");
2789  else /* ASSUME (opcode & 0x0fe0) == 0x0660 */
2790  snprintf(instruction->text, 128,
2791  "0x%8.8" PRIx32 " 0x%4.4x \tCPSI%c\t%s%s%s",
2792  address, opcode,
2793  (opcode & 0x0010) ? 'D' : 'E',
2794  (opcode & 0x0004) ? "A" : "",
2795  (opcode & 0x0002) ? "I" : "",
2796  (opcode & 0x0001) ? "F" : "");
2797 
2798  return ERROR_OK;
2799 }
2800 
2801 static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
2802  struct arm_instruction *instruction)
2803 {
2804  char *suffix;
2805 
2806  /* added in ARMv6 */
2807  switch ((opcode >> 6) & 3) {
2808  case 0:
2809  suffix = "";
2810  break;
2811  case 1:
2812  suffix = "16";
2813  break;
2814  default:
2815  suffix = "SH";
2816  break;
2817  }
2818  snprintf(instruction->text, 128,
2819  "0x%8.8" PRIx32 " 0x%4.4x \tREV%s\tr%d, r%d",
2820  address, opcode, suffix,
2821  opcode & 0x7, (opcode >> 3) & 0x7);
2822 
2823  return ERROR_OK;
2824 }
2825 
2826 static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
2827  struct arm_instruction *instruction)
2828 {
2829  char *hint;
2830 
2831  switch ((opcode >> 4) & 0x0f) {
2832  case 0:
2833  hint = "NOP";
2834  break;
2835  case 1:
2836  hint = "YIELD";
2837  break;
2838  case 2:
2839  hint = "WFE";
2840  break;
2841  case 3:
2842  hint = "WFI";
2843  break;
2844  case 4:
2845  hint = "SEV";
2846  break;
2847  default:
2848  hint = "HINT (UNRECOGNIZED)";
2849  break;
2850  }
2851 
2852  snprintf(instruction->text, 128,
2853  "0x%8.8" PRIx32 " 0x%4.4x \t%s",
2854  address, opcode, hint);
2855 
2856  return ERROR_OK;
2857 }
2858 
2859 static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
2860  struct arm_instruction *instruction)
2861 {
2862  unsigned cond = (opcode >> 4) & 0x0f;
2863  char *x = "", *y = "", *z = "";
2864 
2865  if (opcode & 0x01)
2866  z = (opcode & 0x02) ? "T" : "E";
2867  if (opcode & 0x03)
2868  y = (opcode & 0x04) ? "T" : "E";
2869  if (opcode & 0x07)
2870  x = (opcode & 0x08) ? "T" : "E";
2871 
2872  snprintf(instruction->text, 128,
2873  "0x%8.8" PRIx32 " 0x%4.4x \tIT%s%s%s\t%s",
2874  address, opcode,
2875  x, y, z, arm_condition_strings[cond]);
2876 
2877  /* NOTE: strictly speaking, the next 1-4 instructions should
2878  * now be displayed with the relevant conditional suffix...
2879  */
2880 
2881  return ERROR_OK;
2882 }
2883 
2884 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
2885 {
2886  /* clear fields, to avoid confusion */
2887  memset(instruction, 0, sizeof(struct arm_instruction));
2888  instruction->opcode = opcode;
2889  instruction->instruction_size = 2;
2890 
2891  if ((opcode & 0xe000) == 0x0000) {
2892  /* add/subtract register or immediate */
2893  if ((opcode & 0x1800) == 0x1800)
2894  return evaluate_add_sub_thumb(opcode, address, instruction);
2895  /* shift by immediate */
2896  else
2897  return evaluate_shift_imm_thumb(opcode, address, instruction);
2898  }
2899 
2900  /* Add/subtract/compare/move immediate */
2901  if ((opcode & 0xe000) == 0x2000)
2902  return evaluate_data_proc_imm_thumb(opcode, address, instruction);
2903 
2904  /* Data processing instructions */
2905  if ((opcode & 0xf800) == 0x4000)
2906  return evaluate_data_proc_thumb(opcode, address, instruction);
2907 
2908  /* Load from literal pool */
2909  if ((opcode & 0xf800) == 0x4800)
2910  return evaluate_load_literal_thumb(opcode, address, instruction);
2911 
2912  /* Load/Store register offset */
2913  if ((opcode & 0xf000) == 0x5000)
2914  return evaluate_load_store_reg_thumb(opcode, address, instruction);
2915 
2916  /* Load/Store immediate offset */
2917  if (((opcode & 0xe000) == 0x6000)
2918  || ((opcode & 0xf000) == 0x8000))
2919  return evaluate_load_store_imm_thumb(opcode, address, instruction);
2920 
2921  /* Load/Store from/to stack */
2922  if ((opcode & 0xf000) == 0x9000)
2923  return evaluate_load_store_stack_thumb(opcode, address, instruction);
2924 
2925  /* Add to SP/PC */
2926  if ((opcode & 0xf000) == 0xa000)
2927  return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2928 
2929  /* Misc */
2930  if ((opcode & 0xf000) == 0xb000) {
2931  switch ((opcode >> 8) & 0x0f) {
2932  case 0x0:
2933  return evaluate_adjust_stack_thumb(opcode, address, instruction);
2934  case 0x1:
2935  case 0x3:
2936  case 0x9:
2937  case 0xb:
2938  return evaluate_cb_thumb(opcode, address, instruction);
2939  case 0x2:
2940  return evaluate_extend_thumb(opcode, address, instruction);
2941  case 0x4:
2942  case 0x5:
2943  case 0xc:
2944  case 0xd:
2945  return evaluate_load_store_multiple_thumb(opcode, address,
2946  instruction);
2947  case 0x6:
2948  return evaluate_cps_thumb(opcode, address, instruction);
2949  case 0xa:
2950  if ((opcode & 0x00c0) == 0x0080)
2951  break;
2952  return evaluate_byterev_thumb(opcode, address, instruction);
2953  case 0xe:
2954  return evaluate_breakpoint_thumb(opcode, address, instruction);
2955  case 0xf:
2956  if (opcode & 0x000f)
2957  return evaluate_ifthen_thumb(opcode, address,
2958  instruction);
2959  else
2960  return evaluate_hint_thumb(opcode, address,
2961  instruction);
2962  }
2963 
2964  instruction->type = ARM_UNDEFINED_INSTRUCTION;
2965  snprintf(instruction->text, 128,
2966  "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION",
2967  address, opcode);
2968  return ERROR_OK;
2969  }
2970 
2971  /* Load/Store multiple */
2972  if ((opcode & 0xf000) == 0xc000)
2973  return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2974 
2975  /* Conditional branch + SWI */
2976  if ((opcode & 0xf000) == 0xd000)
2977  return evaluate_cond_branch_thumb(opcode, address, instruction);
2978 
2979  if ((opcode & 0xe000) == 0xe000) {
2980  /* Undefined instructions */
2981  if ((opcode & 0xf801) == 0xe801) {
2982  instruction->type = ARM_UNDEFINED_INSTRUCTION;
2983  snprintf(instruction->text, 128,
2984  "0x%8.8" PRIx32 " 0x%8.8x\t"
2985  "UNDEFINED INSTRUCTION",
2986  address, opcode);
2987  return ERROR_OK;
2988  } else /* Branch to offset */
2989  return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2990  }
2991 
2992  LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
2993  return -1;
2994 }
2995 
2996 int arm_access_size(struct arm_instruction *instruction)
2997 {
2998  if ((instruction->type == ARM_LDRB)
2999  || (instruction->type == ARM_LDRBT)
3000  || (instruction->type == ARM_LDRSB)
3001  || (instruction->type == ARM_STRB)
3002  || (instruction->type == ARM_STRBT))
3003  return 1;
3004  else if ((instruction->type == ARM_LDRH)
3005  || (instruction->type == ARM_LDRSH)
3006  || (instruction->type == ARM_STRH))
3007  return 2;
3008  else if ((instruction->type == ARM_LDR)
3009  || (instruction->type == ARM_LDRT)
3010  || (instruction->type == ARM_STR)
3011  || (instruction->type == ARM_STRT))
3012  return 4;
3013  else if ((instruction->type == ARM_LDRD)
3014  || (instruction->type == ARM_STRD))
3015  return 8;
3016  else {
3017  LOG_ERROR("BUG: instruction type %i isn't a load/store instruction",
3018  instruction->type);
3019  return 0;
3020  }
3021 }
3022 
3023 #if HAVE_CAPSTONE
3024 static void print_opcode(struct command_invocation *cmd, const cs_insn *insn)
3025 {
3026  uint32_t opcode = 0;
3027 
3028  memcpy(&opcode, insn->bytes, insn->size);
3029 
3030  if (insn->size == 4) {
3031  uint16_t opcode_high = opcode >> 16;
3032  opcode = opcode & 0xffff;
3033 
3034  command_print(cmd, "0x%08" PRIx64" %04x %04x\t%s%s%s",
3035  insn->address, opcode, opcode_high, insn->mnemonic,
3036  insn->op_str[0] ? "\t" : "", insn->op_str);
3037  } else {
3038  command_print(cmd, "0x%08" PRIx64" %04x\t%s%s%s",
3039  insn->address, opcode, insn->mnemonic,
3040  insn->op_str[0] ? "\t" : "", insn->op_str);
3041  }
3042 }
3043 
3044 int arm_disassemble(struct command_invocation *cmd, struct target *target,
3045  target_addr_t address, size_t count, bool thumb_mode)
3046 {
3047  csh handle;
3048  int ret;
3049  cs_insn *insn;
3050  cs_mode mode;
3051 
3052  if (!cs_support(CS_ARCH_ARM)) {
3053  LOG_ERROR("ARM architecture not supported by capstone");
3054  return ERROR_FAIL;
3055  }
3056 
3057  mode = CS_MODE_LITTLE_ENDIAN;
3058 
3059  if (thumb_mode)
3060  mode |= CS_MODE_THUMB;
3061 
3062  ret = cs_open(CS_ARCH_ARM, mode, &handle);
3063 
3064  if (ret != CS_ERR_OK) {
3065  LOG_ERROR("cs_open() failed: %s", cs_strerror(ret));
3066  return ERROR_FAIL;
3067  }
3068 
3069  ret = cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
3070 
3071  if (ret != CS_ERR_OK) {
3072  LOG_ERROR("cs_option() failed: %s", cs_strerror(ret));
3073  cs_close(&handle);
3074  return ERROR_FAIL;
3075  }
3076 
3077  insn = cs_malloc(handle);
3078 
3079  if (!insn) {
3080  LOG_ERROR("cs_malloc() failed\n");
3081  cs_close(&handle);
3082  return ERROR_FAIL;
3083  }
3084 
3085  while (count > 0) {
3086  uint8_t buffer[4];
3087 
3088  ret = target_read_buffer(target, address, sizeof(buffer), buffer);
3089 
3090  if (ret != ERROR_OK) {
3091  cs_free(insn, 1);
3092  cs_close(&handle);
3093  return ret;
3094  }
3095 
3096  size_t size = sizeof(buffer);
3097  const uint8_t *tmp = buffer;
3098 
3099  ret = cs_disasm_iter(handle, &tmp, &size, &address, insn);
3100 
3101  if (!ret) {
3102  LOG_ERROR("cs_disasm_iter() failed: %s",
3103  cs_strerror(cs_errno(handle)));
3104  cs_free(insn, 1);
3105  cs_close(&handle);
3106  return ERROR_FAIL;
3107  }
3108 
3109  print_opcode(cmd, insn);
3110  count--;
3111  }
3112 
3113  cs_free(insn, 1);
3114  cs_close(&handle);
3115 
3116  return ERROR_OK;
3117 }
3118 #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:481
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:206
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
enum arm_instruction_type type
unsigned instruction_size
struct arm_b_bl_bx_blx_instr b_bl_bx_blx
union arm_instruction::@68 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 register_shift
struct arm_shifter_operand::@64 immediate_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