openocd: fix SPDX tag format for files .c
[fw/openocd] / src / target / arm_disassembler.c
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");
715                         return ARM_UNDEFINED_INSTRUCTION;
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");
821         return ARM_UNDEFINED_INSTRUCTION;
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;
1809                         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm =
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;
1860                         instruction->info.data_proc.shifter_operand.register_shift.rs = rs;
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";
2165                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
2166                         break;
2167                 case 1:
2168                         instruction->type = ARM_MOV;
2169                         mnemonic = "LSRS";
2170                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
2171                         break;
2172                 case 2:
2173                         instruction->type = ARM_MOV;
2174                         mnemonic = "ASRS";
2175                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
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;
2188         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
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*/;
2320                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
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*/;
2328                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
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*/;
2336                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
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*/;
2352                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
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 */