target: arm: disassembler: decode v6T2 ARM DSB instruction
[fw/openocd] / src / target / arm_disassembler.c
1 /***************************************************************************
2  *   Copyright (C) 2006 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2009 by David Brownell                                  *
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General Public License as published by  *
9  *   the Free Software Foundation; either version 2 of the License, or     *
10  *   (at your option) any later version.                                   *
11  *                                                                         *
12  *   This program is distributed in the hope that it will be useful,       *
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15  *   GNU General Public License for more details.                          *
16  *                                                                         *
17  *   You should have received a copy of the GNU General Public License     *
18  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
19  ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "target.h"
26 #include "arm_disassembler.h"
27 #include <helper/log.h>
28
29 /*
30  * This disassembler supports two main functions for OpenOCD:
31  *
32  *  - Various "disassemble" commands.  OpenOCD can serve as a
33  *    machine-language debugger, without help from GDB.
34  *
35  *  - Single stepping.  Not all ARM cores support hardware single
36  *    stepping.  To work without that support, the debugger must
37  *    be able to decode instructions to find out where to put a
38  *    "next instruction" breakpoint.
39  *
40  * In addition, interpretation of ETM trace data needs some of the
41  * decoding mechanisms.
42  *
43  * At this writing (September 2009) neither function is complete.
44  *
45  *  - ARM decoding
46  *     * Old-style syntax (not UAL) is generally used
47  *     * VFP instructions are not understood (ARMv5 and later)
48  *       except as coprocessor 10/11 operations
49  *     * Most ARM instructions through ARMv6 are decoded, but some
50  *       of the post-ARMv4 opcodes may not be handled yet
51  *              CPS, SDIV, UDIV, LDREX*, STREX*, QASX, ...
52  *     * NEON instructions are not understood (ARMv7-A)
53  *
54  *  - Thumb/Thumb2 decoding
55  *     * UAL syntax should be consistently used
56  *     * Any Thumb2 instructions used in Cortex-M3 (ARMv7-M) should
57  *       be handled properly.  Accordingly, so should the subset
58  *       used in Cortex-M0/M1; and "original" 16-bit Thumb from
59  *       ARMv4T and ARMv5T.
60  *     * Conditional effects of Thumb2 "IT" (if-then) instructions
61  *       are not handled:  the affected instructions are not shown
62  *       with their now-conditional suffixes.
63  *     * Some ARMv6 and ARMv7-M Thumb2 instructions may not be
64  *       handled (minimally for coprocessor access).
65  *     * SIMD instructions, and some other Thumb2 instructions
66  *       from ARMv7-A, are not understood.
67  *
68  *  - ThumbEE decoding
69  *     * As a Thumb2 variant, the Thumb2 comments (above) apply.
70  *     * Opcodes changed by ThumbEE mode are not handled; these
71  *       instructions wrongly decode as LDM and STM.
72  *
73  *  - Jazelle decoding ...  no support whatsoever for Jazelle mode
74  *    or decoding.  ARM encourages use of the more generic ThumbEE
75  *    mode, instead of Jazelle mode, in current chips.
76  *
77  *  - Single-step/emulation ... spotty support, which is only weakly
78  *    tested.  Thumb2 is not supported.  (Arguably a full simulator
79  *    is not needed to support just single stepping.  Recognizing
80  *    branch vs non-branch instructions suffices, except when the
81  *    instruction faults and triggers a synchronous exception which
82  *    can be intercepted using other means.)
83  *
84  * ARM DDI 0406B "ARM Architecture Reference Manual, ARM v7-A and
85  * ARM v7-R edition" gives the most complete coverage of the various
86  * generations of ARM instructions.  At this writing it is publicly
87  * accessible to anyone willing to create an account at the ARM
88  * web site; see http://www.arm.com/documentation/ for information.
89  *
90  * ARM DDI 0403C "ARMv7-M Architecture Reference Manual" provides
91  * more details relevant to the Thumb2-only processors (such as
92  * the Cortex-M implementations).
93  */
94
95 /* textual represenation of the condition field
96  * ALways (default) is ommitted (empty string) */
97 static const char *arm_condition_strings[] = {
98         "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
99 };
100
101 /* make up for C's missing ROR */
102 static uint32_t ror(uint32_t value, int places)
103 {
104         return (value >> places) | (value << (32 - places));
105 }
106
107 static int evaluate_unknown(uint32_t opcode,
108                             uint32_t address, struct arm_instruction *instruction)
109 {
110         instruction->type = ARM_UNDEFINED_INSTRUCTION;
111         snprintf(instruction->text, 128,
112                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
113                         "\tUNDEFINED INSTRUCTION", address, opcode);
114         return ERROR_OK;
115 }
116
117 static int evaluate_pld(uint32_t opcode,
118                         uint32_t address, struct arm_instruction *instruction)
119 {
120         /* PLD */
121         if ((opcode & 0x0d70f000) == 0x0550f000) {
122                 instruction->type = ARM_PLD;
123
124                 snprintf(instruction->text,
125                                 128,
126                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...",
127                                 address,
128                                 opcode);
129
130                 return ERROR_OK;
131         }
132         /* DSB */
133         if ((opcode & 0x07f000f0) == 0x05700040) {
134                 instruction->type = ARM_DSB;
135
136                 char *opt;
137                 switch (opcode & 0x0000000f) {
138                 case 0xf:
139                         opt = "SY";
140                         break;
141                 case 0xe:
142                         opt = "ST";
143                         break;
144                 case 0xb:
145                         opt = "ISH";
146                         break;
147                 case 0xa:
148                         opt = "ISHST";
149                         break;
150                 case 0x7:
151                         opt = "NSH";
152                         break;
153                 case 0x6:
154                         opt = "NSHST";
155                         break;
156                 case 0x3:
157                         opt = "OSH";
158                         break;
159                 case 0x2:
160                         opt = "OSHST";
161                         break;
162                 default:
163                         opt = "UNK";
164                 }
165
166                 snprintf(instruction->text,
167                                 128,
168                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB %s",
169                                 address, opcode, opt);
170
171                 return ERROR_OK;
172         }
173         return evaluate_unknown(opcode, address, instruction);
174 }
175
176 static int evaluate_srs(uint32_t opcode,
177                         uint32_t address, struct arm_instruction *instruction)
178 {
179         const char *wback = (opcode & (1 << 21)) ? "!" : "";
180         const char *mode = "";
181
182         switch ((opcode >> 23) & 0x3) {
183                 case 0:
184                         mode = "DA";
185                         break;
186                 case 1:
187                         /* "IA" is default */
188                         break;
189                 case 2:
190                         mode = "DB";
191                         break;
192                 case 3:
193                         mode = "IB";
194                         break;
195         }
196
197         switch (opcode & 0x0e500000) {
198                 case 0x08400000:
199                         snprintf(instruction->text, 128, "0x%8.8" PRIx32
200                                 "\t0x%8.8" PRIx32
201                                 "\tSRS%s\tSP%s, #%d",
202                                 address, opcode,
203                                 mode, wback,
204                                 (unsigned)(opcode & 0x1f));
205                         break;
206                 case 0x08100000:
207                         snprintf(instruction->text, 128, "0x%8.8" PRIx32
208                                 "\t0x%8.8" PRIx32
209                                 "\tRFE%s\tr%d%s",
210                                 address, opcode,
211                                 mode,
212                                 (unsigned)((opcode >> 16) & 0xf), wback);
213                         break;
214                 default:
215                         return evaluate_unknown(opcode, address, instruction);
216         }
217         return ERROR_OK;
218 }
219
220 static int evaluate_swi(uint32_t opcode,
221                         uint32_t address, struct arm_instruction *instruction)
222 {
223         instruction->type = ARM_SWI;
224
225         snprintf(instruction->text, 128,
226                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSVC %#6.6" PRIx32,
227                         address, opcode, (opcode & 0xffffff));
228
229         return ERROR_OK;
230 }
231
232 static int evaluate_blx_imm(uint32_t opcode,
233                             uint32_t address, struct arm_instruction *instruction)
234 {
235         int offset;
236         uint32_t immediate;
237         uint32_t target_address;
238
239         instruction->type = ARM_BLX;
240         immediate = opcode & 0x00ffffff;
241
242         /* sign extend 24-bit immediate */
243         if (immediate & 0x00800000)
244                 offset = 0xff000000 | immediate;
245         else
246                 offset = immediate;
247
248         /* shift two bits left */
249         offset <<= 2;
250
251         /* odd/event halfword */
252         if (opcode & 0x01000000)
253                 offset |= 0x2;
254
255         target_address = address + 8 + offset;
256
257         snprintf(instruction->text,
258                         128,
259                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "",
260                         address,
261                         opcode,
262                         target_address);
263
264         instruction->info.b_bl_bx_blx.reg_operand = -1;
265         instruction->info.b_bl_bx_blx.target_address = target_address;
266
267         return ERROR_OK;
268 }
269
270 static int evaluate_b_bl(uint32_t opcode,
271                          uint32_t address, struct arm_instruction *instruction)
272 {
273         uint8_t L;
274         uint32_t immediate;
275         int offset;
276         uint32_t target_address;
277
278         immediate = opcode & 0x00ffffff;
279         L = (opcode & 0x01000000) >> 24;
280
281         /* sign extend 24-bit immediate */
282         if (immediate & 0x00800000)
283                 offset = 0xff000000 | immediate;
284         else
285                 offset = immediate;
286
287         /* shift two bits left */
288         offset <<= 2;
289
290         target_address = address + 8 + offset;
291
292         if (L)
293                 instruction->type = ARM_BL;
294         else
295                 instruction->type = ARM_B;
296
297         snprintf(instruction->text,
298                         128,
299                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32,
300                         address,
301                         opcode,
302                         (L) ? "L" : "",
303                         COND(opcode),
304                         target_address);
305
306         instruction->info.b_bl_bx_blx.reg_operand = -1;
307         instruction->info.b_bl_bx_blx.target_address = target_address;
308
309         return ERROR_OK;
310 }
311
312 /* Coprocessor load/store and double register transfers
313  * both normal and extended instruction space (condition field b1111) */
314 static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
315                                       uint32_t address, struct arm_instruction *instruction)
316 {
317         uint8_t cp_num = (opcode & 0xf00) >> 8;
318
319         /* MCRR or MRRC */
320         if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c500000)) {
321                 uint8_t cp_opcode, Rd, Rn, CRm;
322                 char *mnemonic;
323
324                 cp_opcode = (opcode & 0xf0) >> 4;
325                 Rd = (opcode & 0xf000) >> 12;
326                 Rn = (opcode & 0xf0000) >> 16;
327                 CRm = (opcode & 0xf);
328
329                 /* MCRR */
330                 if ((opcode & 0x0ff00000) == 0x0c400000) {
331                         instruction->type = ARM_MCRR;
332                         mnemonic = "MCRR";
333                 } else if ((opcode & 0x0ff00000) == 0x0c500000) {
334                         /* MRRC */
335                         instruction->type = ARM_MRRC;
336                         mnemonic = "MRRC";
337                 } else {
338                         LOG_ERROR("Unknown instruction");
339                         return ERROR_FAIL;
340                 }
341
342                 snprintf(instruction->text, 128,
343                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
344                                 "\t%s%s%s p%i, %x, r%i, r%i, c%i",
345                                 address, opcode, mnemonic,
346                                 ((opcode & 0xf0000000) == 0xf0000000)
347                                 ? "2" : COND(opcode),
348                                 COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
349         } else {/* LDC or STC */
350                 uint8_t CRd, Rn, offset;
351                 uint8_t U;
352                 char *mnemonic;
353                 char addressing_mode[32];
354
355                 CRd = (opcode & 0xf000) >> 12;
356                 Rn = (opcode & 0xf0000) >> 16;
357                 offset = (opcode & 0xff) << 2;
358
359                 /* load/store */
360                 if (opcode & 0x00100000) {
361                         instruction->type = ARM_LDC;
362                         mnemonic = "LDC";
363                 } else {
364                         instruction->type = ARM_STC;
365                         mnemonic = "STC";
366                 }
367
368                 U = (opcode & 0x00800000) >> 23;
369
370                 /* addressing modes */
371                 if ((opcode & 0x01200000) == 0x01000000)/* offset */
372                         snprintf(addressing_mode, 32, "[r%i, #%s%d]",
373                                         Rn, U ? "" : "-", offset);
374                 else if ((opcode & 0x01200000) == 0x01200000)   /* pre-indexed */
375                         snprintf(addressing_mode, 32, "[r%i, #%s%d]!",
376                                         Rn, U ? "" : "-", offset);
377                 else if ((opcode & 0x01200000) == 0x00200000)   /* post-indexed */
378                         snprintf(addressing_mode, 32, "[r%i], #%s%d",
379                                         Rn, U ? "" : "-", offset);
380                 else if ((opcode & 0x01200000) == 0x00000000)   /* unindexed */
381                         snprintf(addressing_mode, 32, "[r%i], {%d}",
382                                         Rn, offset >> 2);
383
384                 snprintf(instruction->text, 128, "0x%8.8" PRIx32
385                                 "\t0x%8.8" PRIx32
386                                 "\t%s%s%s p%i, c%i, %s",
387                                 address, opcode, mnemonic,
388                                 ((opcode & 0xf0000000) == 0xf0000000)
389                                 ? "2" : COND(opcode),
390                                 (opcode & (1 << 22)) ? "L" : "",
391                                 cp_num, CRd, addressing_mode);
392         }
393
394         return ERROR_OK;
395 }
396
397 /* Coprocessor data processing instructions
398  * Coprocessor register transfer instructions
399  * both normal and extended instruction space (condition field b1111) */
400 static int evaluate_cdp_mcr_mrc(uint32_t opcode,
401                                 uint32_t address, struct arm_instruction *instruction)
402 {
403         const char *cond;
404         char *mnemonic;
405         uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
406
407         cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
408         cp_num = (opcode & 0xf00) >> 8;
409         CRd_Rd = (opcode & 0xf000) >> 12;
410         CRn = (opcode & 0xf0000) >> 16;
411         CRm = (opcode & 0xf);
412         opcode_2 = (opcode & 0xe0) >> 5;
413
414         /* CDP or MRC/MCR */
415         if (opcode & 0x00000010) {      /* bit 4 set -> MRC/MCR */
416                 if (opcode & 0x00100000) {      /* bit 20 set -> MRC */
417                         instruction->type = ARM_MRC;
418                         mnemonic = "MRC";
419                 } else {/* bit 20 not set -> MCR */
420                         instruction->type = ARM_MCR;
421                         mnemonic = "MCR";
422                 }
423
424                 opcode_1 = (opcode & 0x00e00000) >> 21;
425
426                 snprintf(instruction->text,
427                                 128,
428                                 "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",
429                                 address,
430                                 opcode,
431                                 mnemonic,
432                                 cond,
433                                 cp_num,
434                                 opcode_1,
435                                 CRd_Rd,
436                                 CRn,
437                                 CRm,
438                                 opcode_2);
439         } else {/* bit 4 not set -> CDP */
440                 instruction->type = ARM_CDP;
441                 mnemonic = "CDP";
442
443                 opcode_1 = (opcode & 0x00f00000) >> 20;
444
445                 snprintf(instruction->text,
446                                 128,
447                                 "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",
448                                 address,
449                                 opcode,
450                                 mnemonic,
451                                 cond,
452                                 cp_num,
453                                 opcode_1,
454                                 CRd_Rd,
455                                 CRn,
456                                 CRm,
457                                 opcode_2);
458         }
459
460         return ERROR_OK;
461 }
462
463 /* Load/store instructions */
464 static int evaluate_load_store(uint32_t opcode,
465                                uint32_t address, struct arm_instruction *instruction)
466 {
467         uint8_t I, P, U, B, W, L;
468         uint8_t Rn, Rd;
469         char *operation;/* "LDR" or "STR" */
470         char *suffix;   /* "", "B", "T", "BT" */
471         char offset[32];
472
473         /* examine flags */
474         I = (opcode & 0x02000000) >> 25;
475         P = (opcode & 0x01000000) >> 24;
476         U = (opcode & 0x00800000) >> 23;
477         B = (opcode & 0x00400000) >> 22;
478         W = (opcode & 0x00200000) >> 21;
479         L = (opcode & 0x00100000) >> 20;
480
481         /* target register */
482         Rd = (opcode & 0xf000) >> 12;
483
484         /* base register */
485         Rn = (opcode & 0xf0000) >> 16;
486
487         instruction->info.load_store.Rd = Rd;
488         instruction->info.load_store.Rn = Rn;
489         instruction->info.load_store.U = U;
490
491         /* determine operation */
492         if (L)
493                 operation = "LDR";
494         else
495                 operation = "STR";
496
497         /* determine instruction type and suffix */
498         if (B) {
499                 if ((P == 0) && (W == 1)) {
500                         if (L)
501                                 instruction->type = ARM_LDRBT;
502                         else
503                                 instruction->type = ARM_STRBT;
504                         suffix = "BT";
505                 } else {
506                         if (L)
507                                 instruction->type = ARM_LDRB;
508                         else
509                                 instruction->type = ARM_STRB;
510                         suffix = "B";
511                 }
512         } else {
513                 if ((P == 0) && (W == 1)) {
514                         if (L)
515                                 instruction->type = ARM_LDRT;
516                         else
517                                 instruction->type = ARM_STRT;
518                         suffix = "T";
519                 } else {
520                         if (L)
521                                 instruction->type = ARM_LDR;
522                         else
523                                 instruction->type = ARM_STR;
524                         suffix = "";
525                 }
526         }
527
528         if (!I) {       /* #+-<offset_12> */
529                 uint32_t offset_12 = (opcode & 0xfff);
530                 if (offset_12)
531                         snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
532                 else
533                         snprintf(offset, 32, "%s", "");
534
535                 instruction->info.load_store.offset_mode = 0;
536                 instruction->info.load_store.offset.offset = offset_12;
537         } else {/* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
538                 uint8_t shift_imm, shift;
539                 uint8_t Rm;
540
541                 shift_imm = (opcode & 0xf80) >> 7;
542                 shift = (opcode & 0x60) >> 5;
543                 Rm = (opcode & 0xf);
544
545                 /* LSR encodes a shift by 32 bit as 0x0 */
546                 if ((shift == 0x1) && (shift_imm == 0x0))
547                         shift_imm = 0x20;
548
549                 /* ASR encodes a shift by 32 bit as 0x0 */
550                 if ((shift == 0x2) && (shift_imm == 0x0))
551                         shift_imm = 0x20;
552
553                 /* ROR by 32 bit is actually a RRX */
554                 if ((shift == 0x3) && (shift_imm == 0x0))
555                         shift = 0x4;
556
557                 instruction->info.load_store.offset_mode = 1;
558                 instruction->info.load_store.offset.reg.Rm = Rm;
559                 instruction->info.load_store.offset.reg.shift = shift;
560                 instruction->info.load_store.offset.reg.shift_imm = shift_imm;
561
562                 if ((shift_imm == 0x0) && (shift == 0x0))       /* +-<Rm> */
563                         snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm);
564                 else {  /* +-<Rm>, <Shift>, #<shift_imm> */
565                         switch (shift) {
566                                 case 0x0:               /* LSL */
567                                         snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
568                                         break;
569                                 case 0x1:               /* LSR */
570                                         snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
571                                         break;
572                                 case 0x2:               /* ASR */
573                                         snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
574                                         break;
575                                 case 0x3:               /* ROR */
576                                         snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
577                                         break;
578                                 case 0x4:               /* RRX */
579                                         snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm);
580                                         break;
581                         }
582                 }
583         }
584
585         if (P == 1) {
586                 if (W == 0) {   /* offset */
587                         snprintf(instruction->text,
588                                         128,
589                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
590                                         address,
591                                         opcode,
592                                         operation,
593                                         COND(opcode),
594                                         suffix,
595                                         Rd,
596                                         Rn,
597                                         offset);
598
599                         instruction->info.load_store.index_mode = 0;
600                 } else {/* pre-indexed */
601                         snprintf(instruction->text,
602                                         128,
603                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
604                                         address,
605                                         opcode,
606                                         operation,
607                                         COND(opcode),
608                                         suffix,
609                                         Rd,
610                                         Rn,
611                                         offset);
612
613                         instruction->info.load_store.index_mode = 1;
614                 }
615         } else {/* post-indexed */
616                 snprintf(instruction->text,
617                                 128,
618                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
619                                 address,
620                                 opcode,
621                                 operation,
622                                 COND(opcode),
623                                 suffix,
624                                 Rd,
625                                 Rn,
626                                 offset);
627
628                 instruction->info.load_store.index_mode = 2;
629         }
630
631         return ERROR_OK;
632 }
633
634 static int evaluate_extend(uint32_t opcode, uint32_t address, char *cp)
635 {
636         unsigned rm = (opcode >> 0) & 0xf;
637         unsigned rd = (opcode >> 12) & 0xf;
638         unsigned rn = (opcode >> 16) & 0xf;
639         char *type, *rot;
640
641         switch ((opcode >> 24) & 0x3) {
642                 case 0:
643                         type = "B16";
644                         break;
645                 case 1:
646                         sprintf(cp, "UNDEFINED");
647                         return ARM_UNDEFINED_INSTRUCTION;
648                 case 2:
649                         type = "B";
650                         break;
651                 default:
652                         type = "H";
653                         break;
654         }
655
656         switch ((opcode >> 10) & 0x3) {
657                 case 0:
658                         rot = "";
659                         break;
660                 case 1:
661                         rot = ", ROR #8";
662                         break;
663                 case 2:
664                         rot = ", ROR #16";
665                         break;
666                 default:
667                         rot = ", ROR #24";
668                         break;
669         }
670
671         if (rn == 0xf) {
672                 sprintf(cp, "%cXT%s%s\tr%d, r%d%s",
673                                 (opcode & (1 << 22)) ? 'U' : 'S',
674                                 type, COND(opcode),
675                                 rd, rm, rot);
676                 return ARM_MOV;
677         } else {
678                 sprintf(cp, "%cXTA%s%s\tr%d, r%d, r%d%s",
679                                 (opcode & (1 << 22)) ? 'U' : 'S',
680                                 type, COND(opcode),
681                                 rd, rn, rm, rot);
682                 return ARM_ADD;
683         }
684 }
685
686 static int evaluate_p_add_sub(uint32_t opcode, uint32_t address, char *cp)
687 {
688         char *prefix;
689         char *op;
690         int type;
691
692         switch ((opcode >> 20) & 0x7) {
693                 case 1:
694                         prefix = "S";
695                         break;
696                 case 2:
697                         prefix = "Q";
698                         break;
699                 case 3:
700                         prefix = "SH";
701                         break;
702                 case 5:
703                         prefix = "U";
704                         break;
705                 case 6:
706                         prefix = "UQ";
707                         break;
708                 case 7:
709                         prefix = "UH";
710                         break;
711                 default:
712                         goto undef;
713         }
714
715         switch ((opcode >> 5) & 0x7) {
716                 case 0:
717                         op = "ADD16";
718                         type = ARM_ADD;
719                         break;
720                 case 1:
721                         op = "ADDSUBX";
722                         type = ARM_ADD;
723                         break;
724                 case 2:
725                         op = "SUBADDX";
726                         type = ARM_SUB;
727                         break;
728                 case 3:
729                         op = "SUB16";
730                         type = ARM_SUB;
731                         break;
732                 case 4:
733                         op = "ADD8";
734                         type = ARM_ADD;
735                         break;
736                 case 7:
737                         op = "SUB8";
738                         type = ARM_SUB;
739                         break;
740                 default:
741                         goto undef;
742         }
743
744         sprintf(cp, "%s%s%s\tr%d, r%d, r%d", prefix, op, COND(opcode),
745                         (int) (opcode >> 12) & 0xf,
746                         (int) (opcode >> 16) & 0xf,
747                         (int) (opcode >> 0) & 0xf);
748         return type;
749
750 undef:
751         /* these opcodes might be used someday */
752         sprintf(cp, "UNDEFINED");
753         return ARM_UNDEFINED_INSTRUCTION;
754 }
755
756 /* ARMv6 and later support "media" instructions (includes SIMD) */
757 static int evaluate_media(uint32_t opcode, uint32_t address,
758                           struct arm_instruction *instruction)
759 {
760         char *cp = instruction->text;
761         char *mnemonic = NULL;
762
763         sprintf(cp,
764                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t",
765                         address, opcode);
766         cp = strchr(cp, 0);
767
768         /* parallel add/subtract */
769         if ((opcode & 0x01800000) == 0x00000000) {
770                 instruction->type = evaluate_p_add_sub(opcode, address, cp);
771                 return ERROR_OK;
772         }
773
774         /* halfword pack */
775         if ((opcode & 0x01f00020) == 0x00800000) {
776                 char *type, *shift;
777                 unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
778
779                 if (opcode & (1 << 6)) {
780                         type = "TB";
781                         shift = "ASR";
782                         if (imm == 0)
783                                 imm = 32;
784                 } else {
785                         type = "BT";
786                         shift = "LSL";
787                 }
788                 sprintf(cp, "PKH%s%s\tr%d, r%d, r%d, %s #%d",
789                                 type, COND(opcode),
790                                 (int) (opcode >> 12) & 0xf,
791                                 (int) (opcode >> 16) & 0xf,
792                                 (int) (opcode >> 0) & 0xf,
793                                 shift, imm);
794                 return ERROR_OK;
795         }
796
797         /* word saturate */
798         if ((opcode & 0x01a00020) == 0x00a00000) {
799                 char *shift;
800                 unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
801
802                 if (opcode & (1 << 6)) {
803                         shift = "ASR";
804                         if (imm == 0)
805                                 imm = 32;
806                 } else
807                         shift = "LSL";
808
809                 sprintf(cp, "%cSAT%s\tr%d, #%d, r%d, %s #%d",
810                                 (opcode & (1 << 22)) ? 'U' : 'S',
811                                 COND(opcode),
812                                 (int) (opcode >> 12) & 0xf,
813                                 (int) (opcode >> 16) & 0x1f,
814                                 (int) (opcode >> 0) & 0xf,
815                                 shift, imm);
816                 return ERROR_OK;
817         }
818
819         /* sign extension */
820         if ((opcode & 0x018000f0) == 0x00800070) {
821                 instruction->type = evaluate_extend(opcode, address, cp);
822                 return ERROR_OK;
823         }
824
825         /* multiplies */
826         if ((opcode & 0x01f00080) == 0x01000000) {
827                 unsigned rn = (opcode >> 12) & 0xf;
828
829                 if (rn != 0xf)
830                         sprintf(cp, "SML%cD%s%s\tr%d, r%d, r%d, r%d",
831                                         (opcode & (1 << 6)) ? 'S' : 'A',
832                                         (opcode & (1 << 5)) ? "X" : "",
833                                         COND(opcode),
834                                         (int) (opcode >> 16) & 0xf,
835                                         (int) (opcode >> 0) & 0xf,
836                                         (int) (opcode >> 8) & 0xf,
837                                         rn);
838                 else
839                         sprintf(cp, "SMU%cD%s%s\tr%d, r%d, r%d",
840                                         (opcode & (1 << 6)) ? 'S' : 'A',
841                                         (opcode & (1 << 5)) ? "X" : "",
842                                         COND(opcode),
843                                         (int) (opcode >> 16) & 0xf,
844                                         (int) (opcode >> 0) & 0xf,
845                                         (int) (opcode >> 8) & 0xf);
846                 return ERROR_OK;
847         }
848         if ((opcode & 0x01f00000) == 0x01400000) {
849                 sprintf(cp, "SML%cLD%s%s\tr%d, r%d, r%d, r%d",
850                                 (opcode & (1 << 6)) ? 'S' : 'A',
851                                 (opcode & (1 << 5)) ? "X" : "",
852                                 COND(opcode),
853                                 (int) (opcode >> 12) & 0xf,
854                                 (int) (opcode >> 16) & 0xf,
855                                 (int) (opcode >> 0) & 0xf,
856                                 (int) (opcode >> 8) & 0xf);
857                 return ERROR_OK;
858         }
859         if ((opcode & 0x01f00000) == 0x01500000) {
860                 unsigned rn = (opcode >> 12) & 0xf;
861
862                 switch (opcode & 0xc0) {
863                         case 3:
864                                 if (rn == 0xf)
865                                         goto undef;
866                         /* FALL THROUGH */
867                         case 0:
868                                 break;
869                         default:
870                                 goto undef;
871                 }
872
873                 if (rn != 0xf)
874                         sprintf(cp, "SMML%c%s%s\tr%d, r%d, r%d, r%d",
875                                         (opcode & (1 << 6)) ? 'S' : 'A',
876                                         (opcode & (1 << 5)) ? "R" : "",
877                                         COND(opcode),
878                                         (int) (opcode >> 16) & 0xf,
879                                         (int) (opcode >> 0) & 0xf,
880                                         (int) (opcode >> 8) & 0xf,
881                                         rn);
882                 else
883                         sprintf(cp, "SMMUL%s%s\tr%d, r%d, r%d",
884                                         (opcode & (1 << 5)) ? "R" : "",
885                                         COND(opcode),
886                                         (int) (opcode >> 16) & 0xf,
887                                         (int) (opcode >> 0) & 0xf,
888                                         (int) (opcode >> 8) & 0xf);
889                 return ERROR_OK;
890         }
891
892         /* simple matches against the remaining decode bits */
893         switch (opcode & 0x01f000f0) {
894                 case 0x00a00030:
895                 case 0x00e00030:
896                         /* parallel halfword saturate */
897                         sprintf(cp, "%cSAT16%s\tr%d, #%d, r%d",
898                                 (opcode & (1 << 22)) ? 'U' : 'S',
899                                 COND(opcode),
900                                 (int) (opcode >> 12) & 0xf,
901                                 (int) (opcode >> 16) & 0xf,
902                                 (int) (opcode >> 0) & 0xf);
903                         return ERROR_OK;
904                 case 0x00b00030:
905                         mnemonic = "REV";
906                         break;
907                 case 0x00b000b0:
908                         mnemonic = "REV16";
909                         break;
910                 case 0x00f000b0:
911                         mnemonic = "REVSH";
912                         break;
913                 case 0x008000b0:
914                         /* select bytes */
915                         sprintf(cp, "SEL%s\tr%d, r%d, r%d", COND(opcode),
916                                 (int) (opcode >> 12) & 0xf,
917                                 (int) (opcode >> 16) & 0xf,
918                                 (int) (opcode >> 0) & 0xf);
919                         return ERROR_OK;
920                 case 0x01800010:
921                         /* unsigned sum of absolute differences */
922                         if (((opcode >> 12) & 0xf) == 0xf)
923                                 sprintf(cp, "USAD8%s\tr%d, r%d, r%d", COND(opcode),
924                                                 (int) (opcode >> 16) & 0xf,
925                                                 (int) (opcode >> 0) & 0xf,
926                                                 (int) (opcode >> 8) & 0xf);
927                         else
928                                 sprintf(cp, "USADA8%s\tr%d, r%d, r%d, r%d", COND(opcode),
929                                                 (int) (opcode >> 16) & 0xf,
930                                                 (int) (opcode >> 0) & 0xf,
931                                                 (int) (opcode >> 8) & 0xf,
932                                                 (int) (opcode >> 12) & 0xf);
933                         return ERROR_OK;
934         }
935         if (mnemonic) {
936                 unsigned rm = (opcode >> 0) & 0xf;
937                 unsigned rd = (opcode >> 12) & 0xf;
938
939                 sprintf(cp, "%s%s\tr%d, r%d", mnemonic, COND(opcode), rm, rd);
940                 return ERROR_OK;
941         }
942
943 undef:
944         /* these opcodes might be used someday */
945         sprintf(cp, "UNDEFINED");
946         return ERROR_OK;
947 }
948
949 /* Miscellaneous load/store instructions */
950 static int evaluate_misc_load_store(uint32_t opcode,
951                                     uint32_t address, struct arm_instruction *instruction)
952 {
953         uint8_t P, U, I, W, L, S, H;
954         uint8_t Rn, Rd;
955         char *operation;/* "LDR" or "STR" */
956         char *suffix;   /* "H", "SB", "SH", "D" */
957         char offset[32];
958
959         /* examine flags */
960         P = (opcode & 0x01000000) >> 24;
961         U = (opcode & 0x00800000) >> 23;
962         I = (opcode & 0x00400000) >> 22;
963         W = (opcode & 0x00200000) >> 21;
964         L = (opcode & 0x00100000) >> 20;
965         S = (opcode & 0x00000040) >> 6;
966         H = (opcode & 0x00000020) >> 5;
967
968         /* target register */
969         Rd = (opcode & 0xf000) >> 12;
970
971         /* base register */
972         Rn = (opcode & 0xf0000) >> 16;
973
974         instruction->info.load_store.Rd = Rd;
975         instruction->info.load_store.Rn = Rn;
976         instruction->info.load_store.U = U;
977
978         /* determine instruction type and suffix */
979         if (S) {/* signed */
980                 if (L) {/* load */
981                         if (H) {
982                                 operation = "LDR";
983                                 instruction->type = ARM_LDRSH;
984                                 suffix = "SH";
985                         } else {
986                                 operation = "LDR";
987                                 instruction->type = ARM_LDRSB;
988                                 suffix = "SB";
989                         }
990                 } else {/* there are no signed stores, so this is used to encode double-register
991                          *load/stores */
992                         suffix = "D";
993                         if (H) {
994                                 operation = "STR";
995                                 instruction->type = ARM_STRD;
996                         } else {
997                                 operation = "LDR";
998                                 instruction->type = ARM_LDRD;
999                         }
1000                 }
1001         } else {/* unsigned */
1002                 suffix = "H";
1003                 if (L) {/* load */
1004                         operation = "LDR";
1005                         instruction->type = ARM_LDRH;
1006                 } else {/* store */
1007                         operation = "STR";
1008                         instruction->type = ARM_STRH;
1009                 }
1010         }
1011
1012         if (I) {/* Immediate offset/index (#+-<offset_8>)*/
1013                 uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
1014                 snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
1015
1016                 instruction->info.load_store.offset_mode = 0;
1017                 instruction->info.load_store.offset.offset = offset_8;
1018         } else {/* Register offset/index (+-<Rm>) */
1019                 uint8_t Rm;
1020                 Rm = (opcode & 0xf);
1021                 snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
1022
1023                 instruction->info.load_store.offset_mode = 1;
1024                 instruction->info.load_store.offset.reg.Rm = Rm;
1025                 instruction->info.load_store.offset.reg.shift = 0x0;
1026                 instruction->info.load_store.offset.reg.shift_imm = 0x0;
1027         }
1028
1029         if (P == 1) {
1030                 if (W == 0) {   /* offset */
1031                         snprintf(instruction->text,
1032                                         128,
1033                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
1034                                         address,
1035                                         opcode,
1036                                         operation,
1037                                         COND(opcode),
1038                                         suffix,
1039                                         Rd,
1040                                         Rn,
1041                                         offset);
1042
1043                         instruction->info.load_store.index_mode = 0;
1044                 } else {/* pre-indexed */
1045                         snprintf(instruction->text,
1046                                         128,
1047                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
1048                                         address,
1049                                         opcode,
1050                                         operation,
1051                                         COND(opcode),
1052                                         suffix,
1053                                         Rd,
1054                                         Rn,
1055                                         offset);
1056
1057                         instruction->info.load_store.index_mode = 1;
1058                 }
1059         } else {/* post-indexed */
1060                 snprintf(instruction->text,
1061                                 128,
1062                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
1063                                 address,
1064                                 opcode,
1065                                 operation,
1066                                 COND(opcode),
1067                                 suffix,
1068                                 Rd,
1069                                 Rn,
1070                                 offset);
1071
1072                 instruction->info.load_store.index_mode = 2;
1073         }
1074
1075         return ERROR_OK;
1076 }
1077
1078 /* Load/store multiples instructions */
1079 static int evaluate_ldm_stm(uint32_t opcode,
1080                             uint32_t address, struct arm_instruction *instruction)
1081 {
1082         uint8_t P, U, S, W, L, Rn;
1083         uint32_t register_list;
1084         char *addressing_mode;
1085         char *mnemonic;
1086         char reg_list[69];
1087         char *reg_list_p;
1088         int i;
1089         int first_reg = 1;
1090
1091         P = (opcode & 0x01000000) >> 24;
1092         U = (opcode & 0x00800000) >> 23;
1093         S = (opcode & 0x00400000) >> 22;
1094         W = (opcode & 0x00200000) >> 21;
1095         L = (opcode & 0x00100000) >> 20;
1096         register_list = (opcode & 0xffff);
1097         Rn = (opcode & 0xf0000) >> 16;
1098
1099         instruction->info.load_store_multiple.Rn = Rn;
1100         instruction->info.load_store_multiple.register_list = register_list;
1101         instruction->info.load_store_multiple.S = S;
1102         instruction->info.load_store_multiple.W = W;
1103
1104         if (L) {
1105                 instruction->type = ARM_LDM;
1106                 mnemonic = "LDM";
1107         } else {
1108                 instruction->type = ARM_STM;
1109                 mnemonic = "STM";
1110         }
1111
1112         if (P) {
1113                 if (U) {
1114                         instruction->info.load_store_multiple.addressing_mode = 1;
1115                         addressing_mode = "IB";
1116                 } else {
1117                         instruction->info.load_store_multiple.addressing_mode = 3;
1118                         addressing_mode = "DB";
1119                 }
1120         } else {
1121                 if (U) {
1122                         instruction->info.load_store_multiple.addressing_mode = 0;
1123                         /* "IA" is the default in UAL syntax */
1124                         addressing_mode = "";
1125                 } else {
1126                         instruction->info.load_store_multiple.addressing_mode = 2;
1127                         addressing_mode = "DA";
1128                 }
1129         }
1130
1131         reg_list_p = reg_list;
1132         for (i = 0; i <= 15; i++) {
1133                 if ((register_list >> i) & 1) {
1134                         if (first_reg) {
1135                                 first_reg = 0;
1136                                 reg_list_p += snprintf(reg_list_p,
1137                                                         (reg_list + 69 - reg_list_p),
1138                                                         "r%i",
1139                                                         i);
1140                         } else
1141                                 reg_list_p += snprintf(reg_list_p,
1142                                                         (reg_list + 69 - reg_list_p),
1143                                                         ", r%i",
1144                                                         i);
1145                 }
1146         }
1147
1148         snprintf(instruction->text, 128,
1149                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
1150                         "\t%s%s%s r%i%s, {%s}%s",
1151                         address, opcode,
1152                         mnemonic, addressing_mode, COND(opcode),
1153                         Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
1154
1155         return ERROR_OK;
1156 }
1157
1158 /* Multiplies, extra load/stores */
1159 static int evaluate_mul_and_extra_ld_st(uint32_t opcode,
1160                                         uint32_t address, struct arm_instruction *instruction)
1161 {
1162         /* Multiply (accumulate) (long) and Swap/swap byte */
1163         if ((opcode & 0x000000f0) == 0x00000090) {
1164                 /* Multiply (accumulate) */
1165                 if ((opcode & 0x0f800000) == 0x00000000) {
1166                         uint8_t Rm, Rs, Rn, Rd, S;
1167                         Rm = opcode & 0xf;
1168                         Rs = (opcode & 0xf00) >> 8;
1169                         Rn = (opcode & 0xf000) >> 12;
1170                         Rd = (opcode & 0xf0000) >> 16;
1171                         S = (opcode & 0x00100000) >> 20;
1172
1173                         /* examine A bit (accumulate) */
1174                         if (opcode & 0x00200000) {
1175                                 instruction->type = ARM_MLA;
1176                                 snprintf(instruction->text,
1177                                                 128,
1178                                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
1179                                                 address,
1180                                                 opcode,
1181                                                 COND(opcode),
1182                                                 (S) ? "S" : "",
1183                                                 Rd,
1184                                                 Rm,
1185                                                 Rs,
1186                                                 Rn);
1187                         } else {
1188                                 instruction->type = ARM_MUL;
1189                                 snprintf(instruction->text,
1190                                                 128,
1191                                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
1192                                                 address,
1193                                                 opcode,
1194                                                 COND(opcode),
1195                                                 (S) ? "S" : "",
1196                                                 Rd,
1197                                                 Rm,
1198                                                 Rs);
1199                         }
1200
1201                         return ERROR_OK;
1202                 }
1203
1204                 /* Multiply (accumulate) long */
1205                 if ((opcode & 0x0f800000) == 0x00800000) {
1206                         char *mnemonic = NULL;
1207                         uint8_t Rm, Rs, RdHi, RdLow, S;
1208                         Rm = opcode & 0xf;
1209                         Rs = (opcode & 0xf00) >> 8;
1210                         RdHi = (opcode & 0xf000) >> 12;
1211                         RdLow = (opcode & 0xf0000) >> 16;
1212                         S = (opcode & 0x00100000) >> 20;
1213
1214                         switch ((opcode & 0x00600000) >> 21) {
1215                                 case 0x0:
1216                                         instruction->type = ARM_UMULL;
1217                                         mnemonic = "UMULL";
1218                                         break;
1219                                 case 0x1:
1220                                         instruction->type = ARM_UMLAL;
1221                                         mnemonic = "UMLAL";
1222                                         break;
1223                                 case 0x2:
1224                                         instruction->type = ARM_SMULL;
1225                                         mnemonic = "SMULL";
1226                                         break;
1227                                 case 0x3:
1228                                         instruction->type = ARM_SMLAL;
1229                                         mnemonic = "SMLAL";
1230                                         break;
1231                         }
1232
1233                         snprintf(instruction->text,
1234                                         128,
1235                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
1236                                         address,
1237                                         opcode,
1238                                         mnemonic,
1239                                         COND(opcode),
1240                                         (S) ? "S" : "",
1241                                         RdLow,
1242                                         RdHi,
1243                                         Rm,
1244                                         Rs);
1245
1246                         return ERROR_OK;
1247                 }
1248
1249                 /* Swap/swap byte */
1250                 if ((opcode & 0x0f800000) == 0x01000000) {
1251                         uint8_t Rm, Rd, Rn;
1252                         Rm = opcode & 0xf;
1253                         Rd = (opcode & 0xf000) >> 12;
1254                         Rn = (opcode & 0xf0000) >> 16;
1255
1256                         /* examine B flag */
1257                         instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
1258
1259                         snprintf(instruction->text,
1260                                         128,
1261                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
1262                                         address,
1263                                         opcode,
1264                                         (opcode & 0x00400000) ? "SWPB" : "SWP",
1265                                         COND(opcode),
1266                                         Rd,
1267                                         Rm,
1268                                         Rn);
1269                         return ERROR_OK;
1270                 }
1271
1272         }
1273
1274         return evaluate_misc_load_store(opcode, address, instruction);
1275 }
1276
1277 static int evaluate_mrs_msr(uint32_t opcode,
1278                             uint32_t address, struct arm_instruction *instruction)
1279 {
1280         int R = (opcode & 0x00400000) >> 22;
1281         char *PSR = (R) ? "SPSR" : "CPSR";
1282
1283         /* Move register to status register (MSR) */
1284         if (opcode & 0x00200000) {
1285                 instruction->type = ARM_MSR;
1286
1287                 /* immediate variant */
1288                 if (opcode & 0x02000000) {
1289                         uint8_t immediate = (opcode & 0xff);
1290                         uint8_t rotate = (opcode & 0xf00);
1291
1292                         snprintf(instruction->text,
1293                                         128,
1294                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32,
1295                                         address,
1296                                         opcode,
1297                                         COND(opcode),
1298                                         PSR,
1299                                         (opcode & 0x10000) ? "c" : "",
1300                                         (opcode & 0x20000) ? "x" : "",
1301                                         (opcode & 0x40000) ? "s" : "",
1302                                         (opcode & 0x80000) ? "f" : "",
1303                                         ror(immediate, (rotate * 2))
1304                                         );
1305                 } else {/* register variant */
1306                         uint8_t Rm = opcode & 0xf;
1307                         snprintf(instruction->text,
1308                                         128,
1309                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
1310                                         address,
1311                                         opcode,
1312                                         COND(opcode),
1313                                         PSR,
1314                                         (opcode & 0x10000) ? "c" : "",
1315                                         (opcode & 0x20000) ? "x" : "",
1316                                         (opcode & 0x40000) ? "s" : "",
1317                                         (opcode & 0x80000) ? "f" : "",
1318                                         Rm
1319                                         );
1320                 }
1321
1322         } else {/* Move status register to register (MRS) */
1323                 uint8_t Rd;
1324
1325                 instruction->type = ARM_MRS;
1326                 Rd = (opcode & 0x0000f000) >> 12;
1327
1328                 snprintf(instruction->text,
1329                                 128,
1330                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
1331                                 address,
1332                                 opcode,
1333                                 COND(opcode),
1334                                 Rd,
1335                                 PSR);
1336         }
1337
1338         return ERROR_OK;
1339 }
1340
1341 /* Miscellaneous instructions */
1342 static int evaluate_misc_instr(uint32_t opcode,
1343                                uint32_t address, struct arm_instruction *instruction)
1344 {
1345         /* MRS/MSR */
1346         if ((opcode & 0x000000f0) == 0x00000000)
1347                 evaluate_mrs_msr(opcode, address, instruction);
1348
1349         /* BX */
1350         if ((opcode & 0x006000f0) == 0x00200010) {
1351                 uint8_t Rm;
1352                 instruction->type = ARM_BX;
1353                 Rm = opcode & 0xf;
1354
1355                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
1356                                 address, opcode, COND(opcode), Rm);
1357
1358                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1359                 instruction->info.b_bl_bx_blx.target_address = -1;
1360         }
1361
1362         /* BXJ - "Jazelle" support (ARMv5-J) */
1363         if ((opcode & 0x006000f0) == 0x00200020) {
1364                 uint8_t Rm;
1365                 instruction->type = ARM_BX;
1366                 Rm = opcode & 0xf;
1367
1368                 snprintf(instruction->text, 128,
1369                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBXJ%s r%i",
1370                                 address, opcode, COND(opcode), Rm);
1371
1372                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1373                 instruction->info.b_bl_bx_blx.target_address = -1;
1374         }
1375
1376         /* CLZ */
1377         if ((opcode & 0x006000f0) == 0x00600010) {
1378                 uint8_t Rm, Rd;
1379                 instruction->type = ARM_CLZ;
1380                 Rm = opcode & 0xf;
1381                 Rd = (opcode & 0xf000) >> 12;
1382
1383                 snprintf(instruction->text,
1384                                 128,
1385                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
1386                                 address,
1387                                 opcode,
1388                                 COND(opcode),
1389                                 Rd,
1390                                 Rm);
1391         }
1392
1393         /* BLX(2) */
1394         if ((opcode & 0x006000f0) == 0x00200030) {
1395                 uint8_t Rm;
1396                 instruction->type = ARM_BLX;
1397                 Rm = opcode & 0xf;
1398
1399                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
1400                                 address, opcode, COND(opcode), Rm);
1401
1402                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1403                 instruction->info.b_bl_bx_blx.target_address = -1;
1404         }
1405
1406         /* Enhanced DSP add/subtracts */
1407         if ((opcode & 0x0000000f0) == 0x00000050) {
1408                 uint8_t Rm, Rd, Rn;
1409                 char *mnemonic = NULL;
1410                 Rm = opcode & 0xf;
1411                 Rd = (opcode & 0xf000) >> 12;
1412                 Rn = (opcode & 0xf0000) >> 16;
1413
1414                 switch ((opcode & 0x00600000) >> 21) {
1415                         case 0x0:
1416                                 instruction->type = ARM_QADD;
1417                                 mnemonic = "QADD";
1418                                 break;
1419                         case 0x1:
1420                                 instruction->type = ARM_QSUB;
1421                                 mnemonic = "QSUB";
1422                                 break;
1423                         case 0x2:
1424                                 instruction->type = ARM_QDADD;
1425                                 mnemonic = "QDADD";
1426                                 break;
1427                         case 0x3:
1428                                 instruction->type = ARM_QDSUB;
1429                                 mnemonic = "QDSUB";
1430                                 break;
1431                 }
1432
1433                 snprintf(instruction->text,
1434                                 128,
1435                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
1436                                 address,
1437                                 opcode,
1438                                 mnemonic,
1439                                 COND(opcode),
1440                                 Rd,
1441                                 Rm,
1442                                 Rn);
1443         }
1444
1445         /* exception return */
1446         if ((opcode & 0x0000000f0) == 0x00000060) {
1447                 if (((opcode & 0x600000) >> 21) == 3)
1448                         instruction->type = ARM_ERET;
1449                 snprintf(instruction->text,
1450                                 128,
1451                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tERET",
1452                                 address,
1453                                 opcode);
1454         }
1455
1456         /* exception generate instructions */
1457         if ((opcode & 0x0000000f0) == 0x00000070) {
1458                 uint32_t immediate = 0;
1459                 char *mnemonic = NULL;
1460
1461                 switch ((opcode & 0x600000) >> 21) {
1462                         case 0x1:
1463                                 instruction->type = ARM_BKPT;
1464                                 mnemonic = "BRKT";
1465                                 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1466                                 break;
1467                         case 0x2:
1468                                 instruction->type = ARM_HVC;
1469                                 mnemonic = "HVC";
1470                                 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1471                                 break;
1472                         case 0x3:
1473                                 instruction->type = ARM_SMC;
1474                                 mnemonic = "SMC";
1475                                 immediate = (opcode & 0xf);
1476                                 break;
1477                 }
1478
1479                 snprintf(instruction->text,
1480                                 128,
1481                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s 0x%4.4" PRIx32 "",
1482                                 address,
1483                                 opcode,
1484                                 mnemonic,
1485                                 immediate);
1486         }
1487
1488         /* Enhanced DSP multiplies */
1489         if ((opcode & 0x000000090) == 0x00000080) {
1490                 int x = (opcode & 0x20) >> 5;
1491                 int y = (opcode & 0x40) >> 6;
1492
1493                 /* SMLA < x><y> */
1494                 if ((opcode & 0x00600000) == 0x00000000) {
1495                         uint8_t Rd, Rm, Rs, Rn;
1496                         instruction->type = ARM_SMLAxy;
1497                         Rd = (opcode & 0xf0000) >> 16;
1498                         Rm = (opcode & 0xf);
1499                         Rs = (opcode & 0xf00) >> 8;
1500                         Rn = (opcode & 0xf000) >> 12;
1501
1502                         snprintf(instruction->text,
1503                                         128,
1504                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1505                                         address,
1506                                         opcode,
1507                                         (x) ? "T" : "B",
1508                                         (y) ? "T" : "B",
1509                                         COND(opcode),
1510                                         Rd,
1511                                         Rm,
1512                                         Rs,
1513                                         Rn);
1514                 }
1515
1516                 /* SMLAL < x><y> */
1517                 if ((opcode & 0x00600000) == 0x00400000) {
1518                         uint8_t RdLow, RdHi, Rm, Rs;
1519                         instruction->type = ARM_SMLAxy;
1520                         RdHi = (opcode & 0xf0000) >> 16;
1521                         RdLow = (opcode & 0xf000) >> 12;
1522                         Rm = (opcode & 0xf);
1523                         Rs = (opcode & 0xf00) >> 8;
1524
1525                         snprintf(instruction->text,
1526                                         128,
1527                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1528                                         address,
1529                                         opcode,
1530                                         (x) ? "T" : "B",
1531                                         (y) ? "T" : "B",
1532                                         COND(opcode),
1533                                         RdLow,
1534                                         RdHi,
1535                                         Rm,
1536                                         Rs);
1537                 }
1538
1539                 /* SMLAW < y> */
1540                 if (((opcode & 0x00600000) == 0x00100000) && (x == 0)) {
1541                         uint8_t Rd, Rm, Rs, Rn;
1542                         instruction->type = ARM_SMLAWy;
1543                         Rd = (opcode & 0xf0000) >> 16;
1544                         Rm = (opcode & 0xf);
1545                         Rs = (opcode & 0xf00) >> 8;
1546                         Rn = (opcode & 0xf000) >> 12;
1547
1548                         snprintf(instruction->text,
1549                                         128,
1550                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
1551                                         address,
1552                                         opcode,
1553                                         (y) ? "T" : "B",
1554                                         COND(opcode),
1555                                         Rd,
1556                                         Rm,
1557                                         Rs,
1558                                         Rn);
1559                 }
1560
1561                 /* SMUL < x><y> */
1562                 if ((opcode & 0x00600000) == 0x00300000) {
1563                         uint8_t Rd, Rm, Rs;
1564                         instruction->type = ARM_SMULxy;
1565                         Rd = (opcode & 0xf0000) >> 16;
1566                         Rm = (opcode & 0xf);
1567                         Rs = (opcode & 0xf00) >> 8;
1568
1569                         snprintf(instruction->text,
1570                                         128,
1571                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
1572                                         address,
1573                                         opcode,
1574                                         (x) ? "T" : "B",
1575                                         (y) ? "T" : "B",
1576                                         COND(opcode),
1577                                         Rd,
1578                                         Rm,
1579                                         Rs);
1580                 }
1581
1582                 /* SMULW < y> */
1583                 if (((opcode & 0x00600000) == 0x00100000) && (x == 1)) {
1584                         uint8_t Rd, Rm, Rs;
1585                         instruction->type = ARM_SMULWy;
1586                         Rd = (opcode & 0xf0000) >> 16;
1587                         Rm = (opcode & 0xf);
1588                         Rs = (opcode & 0xf00) >> 8;
1589
1590                         snprintf(instruction->text,
1591                                         128,
1592                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
1593                                         address,
1594                                         opcode,
1595                                         (y) ? "T" : "B",
1596                                         COND(opcode),
1597                                         Rd,
1598                                         Rm,
1599                                         Rs);
1600                 }
1601         }
1602
1603         return ERROR_OK;
1604 }
1605
1606 static int evaluate_data_proc(uint32_t opcode,
1607                               uint32_t address, struct arm_instruction *instruction)
1608 {
1609         uint8_t I, op, S, Rn, Rd;
1610         char *mnemonic = NULL;
1611         char shifter_operand[32];
1612
1613         I = (opcode & 0x02000000) >> 25;
1614         op = (opcode & 0x01e00000) >> 21;
1615         S = (opcode & 0x00100000) >> 20;
1616
1617         Rd = (opcode & 0xf000) >> 12;
1618         Rn = (opcode & 0xf0000) >> 16;
1619
1620         instruction->info.data_proc.Rd = Rd;
1621         instruction->info.data_proc.Rn = Rn;
1622         instruction->info.data_proc.S = S;
1623
1624         switch (op) {
1625                 case 0x0:
1626                         instruction->type = ARM_AND;
1627                         mnemonic = "AND";
1628                         break;
1629                 case 0x1:
1630                         instruction->type = ARM_EOR;
1631                         mnemonic = "EOR";
1632                         break;
1633                 case 0x2:
1634                         instruction->type = ARM_SUB;
1635                         mnemonic = "SUB";
1636                         break;
1637                 case 0x3:
1638                         instruction->type = ARM_RSB;
1639                         mnemonic = "RSB";
1640                         break;
1641                 case 0x4:
1642                         instruction->type = ARM_ADD;
1643                         mnemonic = "ADD";
1644                         break;
1645                 case 0x5:
1646                         instruction->type = ARM_ADC;
1647                         mnemonic = "ADC";
1648                         break;
1649                 case 0x6:
1650                         instruction->type = ARM_SBC;
1651                         mnemonic = "SBC";
1652                         break;
1653                 case 0x7:
1654                         instruction->type = ARM_RSC;
1655                         mnemonic = "RSC";
1656                         break;
1657                 case 0x8:
1658                         instruction->type = ARM_TST;
1659                         mnemonic = "TST";
1660                         break;
1661                 case 0x9:
1662                         instruction->type = ARM_TEQ;
1663                         mnemonic = "TEQ";
1664                         break;
1665                 case 0xa:
1666                         instruction->type = ARM_CMP;
1667                         mnemonic = "CMP";
1668                         break;
1669                 case 0xb:
1670                         instruction->type = ARM_CMN;
1671                         mnemonic = "CMN";
1672                         break;
1673                 case 0xc:
1674                         instruction->type = ARM_ORR;
1675                         mnemonic = "ORR";
1676                         break;
1677                 case 0xd:
1678                         instruction->type = ARM_MOV;
1679                         mnemonic = "MOV";
1680                         break;
1681                 case 0xe:
1682                         instruction->type = ARM_BIC;
1683                         mnemonic = "BIC";
1684                         break;
1685                 case 0xf:
1686                         instruction->type = ARM_MVN;
1687                         mnemonic = "MVN";
1688                         break;
1689         }
1690
1691         if (I) {/* immediate shifter operand (#<immediate>)*/
1692                 uint8_t immed_8 = opcode & 0xff;
1693                 uint8_t rotate_imm = (opcode & 0xf00) >> 8;
1694                 uint32_t immediate;
1695
1696                 immediate = ror(immed_8, rotate_imm * 2);
1697
1698                 snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
1699
1700                 instruction->info.data_proc.variant = 0;
1701                 instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
1702         } else {/* register-based shifter operand */
1703                 uint8_t shift, Rm;
1704                 shift = (opcode & 0x60) >> 5;
1705                 Rm = (opcode & 0xf);
1706
1707                 if ((opcode & 0x10) != 0x10) {  /* Immediate shifts ("<Rm>" or "<Rm>, <shift>
1708                                                  *#<shift_immediate>") */
1709                         uint8_t shift_imm;
1710                         shift_imm = (opcode & 0xf80) >> 7;
1711
1712                         instruction->info.data_proc.variant = 1;
1713                         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1714                         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm =
1715                                 shift_imm;
1716                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
1717
1718                         /* LSR encodes a shift by 32 bit as 0x0 */
1719                         if ((shift == 0x1) && (shift_imm == 0x0))
1720                                 shift_imm = 0x20;
1721
1722                         /* ASR encodes a shift by 32 bit as 0x0 */
1723                         if ((shift == 0x2) && (shift_imm == 0x0))
1724                                 shift_imm = 0x20;
1725
1726                         /* ROR by 32 bit is actually a RRX */
1727                         if ((shift == 0x3) && (shift_imm == 0x0))
1728                                 shift = 0x4;
1729
1730                         if ((shift_imm == 0x0) && (shift == 0x0))
1731                                 snprintf(shifter_operand, 32, "r%i", Rm);
1732                         else {
1733                                 if (shift == 0x0)       /* LSL */
1734                                         snprintf(shifter_operand,
1735                                                         32,
1736                                                         "r%i, LSL #0x%x",
1737                                                         Rm,
1738                                                         shift_imm);
1739                                 else if (shift == 0x1)  /* LSR */
1740                                         snprintf(shifter_operand,
1741                                                         32,
1742                                                         "r%i, LSR #0x%x",
1743                                                         Rm,
1744                                                         shift_imm);
1745                                 else if (shift == 0x2)  /* ASR */
1746                                         snprintf(shifter_operand,
1747                                                         32,
1748                                                         "r%i, ASR #0x%x",
1749                                                         Rm,
1750                                                         shift_imm);
1751                                 else if (shift == 0x3)  /* ROR */
1752                                         snprintf(shifter_operand,
1753                                                         32,
1754                                                         "r%i, ROR #0x%x",
1755                                                         Rm,
1756                                                         shift_imm);
1757                                 else if (shift == 0x4)  /* RRX */
1758                                         snprintf(shifter_operand, 32, "r%i, RRX", Rm);
1759                         }
1760                 } else {/* Register shifts ("<Rm>, <shift> <Rs>") */
1761                         uint8_t Rs = (opcode & 0xf00) >> 8;
1762
1763                         instruction->info.data_proc.variant = 2;
1764                         instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
1765                         instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
1766                         instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
1767
1768                         if (shift == 0x0)       /* LSL */
1769                                 snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
1770                         else if (shift == 0x1)  /* LSR */
1771                                 snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
1772                         else if (shift == 0x2)  /* ASR */
1773                                 snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
1774                         else if (shift == 0x3)  /* ROR */
1775                                 snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
1776                 }
1777         }
1778
1779         if ((op < 0x8) || (op == 0xc) || (op == 0xe)) { /* <opcode3>{<cond>}{S} <Rd>, <Rn>,
1780                                                          *<shifter_operand> */
1781                 snprintf(instruction->text,
1782                                 128,
1783                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
1784                                 address,
1785                                 opcode,
1786                                 mnemonic,
1787                                 COND(opcode),
1788                                 (S) ? "S" : "",
1789                                 Rd,
1790                                 Rn,
1791                                 shifter_operand);
1792         } else if ((op == 0xd) || (op == 0xf)) {        /* <opcode1>{<cond>}{S} <Rd>,
1793                                                          *<shifter_operand> */
1794                 if (opcode == 0xe1a00000)       /* print MOV r0,r0 as NOP */
1795                         snprintf(instruction->text,
1796                                         128,
1797                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",
1798                                         address,
1799                                         opcode);
1800                 else
1801                         snprintf(instruction->text,
1802                                         128,
1803                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
1804                                         address,
1805                                         opcode,
1806                                         mnemonic,
1807                                         COND(opcode),
1808                                         (S) ? "S" : "",
1809                                         Rd,
1810                                         shifter_operand);
1811         } else {/* <opcode2>{<cond>} <Rn>, <shifter_operand> */
1812                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
1813                                 address, opcode, mnemonic, COND(opcode),
1814                                 Rn, shifter_operand);
1815         }
1816
1817         return ERROR_OK;
1818 }
1819
1820 int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
1821                         struct arm_instruction *instruction)
1822 {
1823         /* clear fields, to avoid confusion */
1824         memset(instruction, 0, sizeof(struct arm_instruction));
1825         instruction->opcode = opcode;
1826         instruction->instruction_size = 4;
1827
1828         /* catch opcodes with condition field [31:28] = b1111 */
1829         if ((opcode & 0xf0000000) == 0xf0000000) {
1830                 /* Undefined instruction (or ARMv5E cache preload PLD) */
1831                 if ((opcode & 0x08000000) == 0x00000000)
1832                         return evaluate_pld(opcode, address, instruction);
1833
1834                 /* Undefined instruction (or ARMv6+ SRS/RFE) */
1835                 if ((opcode & 0x0e000000) == 0x08000000)
1836                         return evaluate_srs(opcode, address, instruction);
1837
1838                 /* Branch and branch with link and change to Thumb */
1839                 if ((opcode & 0x0e000000) == 0x0a000000)
1840                         return evaluate_blx_imm(opcode, address, instruction);
1841
1842                 /* Extended coprocessor opcode space (ARMv5 and higher)
1843                  * Coprocessor load/store and double register transfers */
1844                 if ((opcode & 0x0e000000) == 0x0c000000)
1845                         return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1846
1847                 /* Coprocessor data processing */
1848                 if ((opcode & 0x0f000100) == 0x0c000000)
1849                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1850
1851                 /* Coprocessor register transfers */
1852                 if ((opcode & 0x0f000010) == 0x0c000010)
1853                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1854
1855                 /* Undefined instruction */
1856                 if ((opcode & 0x0f000000) == 0x0f000000) {
1857                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1858                         snprintf(instruction->text,
1859                                         128,
1860                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1861                                         address,
1862                                         opcode);
1863                         return ERROR_OK;
1864                 }
1865         }
1866
1867         /* catch opcodes with [27:25] = b000 */
1868         if ((opcode & 0x0e000000) == 0x00000000) {
1869                 /* Multiplies, extra load/stores */
1870                 if ((opcode & 0x00000090) == 0x00000090)
1871                         return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
1872
1873                 /* Miscellaneous instructions */
1874                 if ((opcode & 0x0f900000) == 0x01000000)
1875                         return evaluate_misc_instr(opcode, address, instruction);
1876
1877                 return evaluate_data_proc(opcode, address, instruction);
1878         }
1879
1880         /* catch opcodes with [27:25] = b001 */
1881         if ((opcode & 0x0e000000) == 0x02000000) {
1882                 /* Undefined instruction */
1883                 if ((opcode & 0x0fb00000) == 0x03000000) {
1884                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1885                         snprintf(instruction->text,
1886                                         128,
1887                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1888                                         address,
1889                                         opcode);
1890                         return ERROR_OK;
1891                 }
1892
1893                 /* Move immediate to status register */
1894                 if ((opcode & 0x0fb00000) == 0x03200000)
1895                         return evaluate_mrs_msr(opcode, address, instruction);
1896
1897                 return evaluate_data_proc(opcode, address, instruction);
1898
1899         }
1900
1901         /* catch opcodes with [27:25] = b010 */
1902         if ((opcode & 0x0e000000) == 0x04000000) {
1903                 /* Load/store immediate offset */
1904                 return evaluate_load_store(opcode, address, instruction);
1905         }
1906
1907         /* catch opcodes with [27:25] = b011 */
1908         if ((opcode & 0x0e000000) == 0x06000000) {
1909                 /* Load/store register offset */
1910                 if ((opcode & 0x00000010) == 0x00000000)
1911                         return evaluate_load_store(opcode, address, instruction);
1912
1913                 /* Architecturally Undefined instruction
1914                  * ... don't expect these to ever be used
1915                  */
1916                 if ((opcode & 0x07f000f0) == 0x07f000f0) {
1917                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1918                         snprintf(instruction->text, 128,
1919                                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF",
1920                                         address, opcode);
1921                         return ERROR_OK;
1922                 }
1923
1924                 /* "media" instructions */
1925                 return evaluate_media(opcode, address, instruction);
1926         }
1927
1928         /* catch opcodes with [27:25] = b100 */
1929         if ((opcode & 0x0e000000) == 0x08000000) {
1930                 /* Load/store multiple */
1931                 return evaluate_ldm_stm(opcode, address, instruction);
1932         }
1933
1934         /* catch opcodes with [27:25] = b101 */
1935         if ((opcode & 0x0e000000) == 0x0a000000) {
1936                 /* Branch and branch with link */
1937                 return evaluate_b_bl(opcode, address, instruction);
1938         }
1939
1940         /* catch opcodes with [27:25] = b110 */
1941         if ((opcode & 0x0e000000) == 0x0c000000) {
1942                 /* Coprocessor load/store and double register transfers */
1943                 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1944         }
1945
1946         /* catch opcodes with [27:25] = b111 */
1947         if ((opcode & 0x0e000000) == 0x0e000000) {
1948                 /* Software interrupt */
1949                 if ((opcode & 0x0f000000) == 0x0f000000)
1950                         return evaluate_swi(opcode, address, instruction);
1951
1952                 /* Coprocessor data processing */
1953                 if ((opcode & 0x0f000010) == 0x0e000000)
1954                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1955
1956                 /* Coprocessor register transfers */
1957                 if ((opcode & 0x0f000010) == 0x0e000010)
1958                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1959         }
1960
1961         LOG_ERROR("ARM: should never reach this point (opcode=%08x)",
1962                         (unsigned) opcode);
1963         return -1;
1964 }
1965
1966 static int evaluate_b_bl_blx_thumb(uint16_t opcode,
1967                                    uint32_t address, struct arm_instruction *instruction)
1968 {
1969         uint32_t offset = opcode & 0x7ff;
1970         uint32_t opc = (opcode >> 11) & 0x3;
1971         uint32_t target_address;
1972         char *mnemonic = NULL;
1973
1974         /* sign extend 11-bit offset */
1975         if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
1976                 offset = 0xfffff800 | offset;
1977
1978         target_address = address + 4 + (offset << 1);
1979
1980         switch (opc) {
1981                 /* unconditional branch */
1982                 case 0:
1983                         instruction->type = ARM_B;
1984                         mnemonic = "B";
1985                         break;
1986                 /* BLX suffix */
1987                 case 1:
1988                         instruction->type = ARM_BLX;
1989                         mnemonic = "BLX";
1990                         target_address &= 0xfffffffc;
1991                         break;
1992                 /* BL/BLX prefix */
1993                 case 2:
1994                         instruction->type = ARM_UNKNOWN_INSTUCTION;
1995                         mnemonic = "prefix";
1996                         target_address = offset << 12;
1997                         break;
1998                 /* BL suffix */
1999                 case 3:
2000                         instruction->type = ARM_BL;
2001                         mnemonic = "BL";
2002                         break;
2003         }
2004
2005         /* TODO: deal correctly with dual opcode (prefixed) BL/BLX;
2006          * these are effectively 32-bit instructions even in Thumb1.  For
2007          * disassembly, it's simplest to always use the Thumb2 decoder.
2008          *
2009          * But some cores will evidently handle them as two instructions,
2010          * where exceptions may occur between the two.  The ETMv3.2+ ID
2011          * register has a bit which exposes this behavior.
2012          */
2013
2014         snprintf(instruction->text, 128,
2015                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\t%#8.8" PRIx32,
2016                         address, opcode, mnemonic, target_address);
2017
2018         instruction->info.b_bl_bx_blx.reg_operand = -1;
2019         instruction->info.b_bl_bx_blx.target_address = target_address;
2020
2021         return ERROR_OK;
2022 }
2023
2024 static int evaluate_add_sub_thumb(uint16_t opcode,
2025                                   uint32_t address, struct arm_instruction *instruction)
2026 {
2027         uint8_t Rd = (opcode >> 0) & 0x7;
2028         uint8_t Rn = (opcode >> 3) & 0x7;
2029         uint8_t Rm_imm = (opcode >> 6) & 0x7;
2030         uint32_t opc = opcode & (1 << 9);
2031         uint32_t reg_imm  = opcode & (1 << 10);
2032         char *mnemonic;
2033
2034         if (opc) {
2035                 instruction->type = ARM_SUB;
2036                 mnemonic = "SUBS";
2037         } else {
2038                 /* REVISIT:  if reg_imm == 0, display as "MOVS" */
2039                 instruction->type = ARM_ADD;
2040                 mnemonic = "ADDS";
2041         }
2042
2043         instruction->info.data_proc.Rd = Rd;
2044         instruction->info.data_proc.Rn = Rn;
2045         instruction->info.data_proc.S = 1;
2046
2047         if (reg_imm) {
2048                 instruction->info.data_proc.variant = 0;/*immediate*/
2049                 instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
2050                 snprintf(instruction->text, 128,
2051                                 "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, #%d",
2052                                 address, opcode, mnemonic, Rd, Rn, Rm_imm);
2053         } else {
2054                 instruction->info.data_proc.variant = 1;/*immediate shift*/
2055                 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
2056                 snprintf(instruction->text, 128,
2057                                 "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, r%i",
2058                                 address, opcode, mnemonic, Rd, Rn, Rm_imm);
2059         }
2060
2061         return ERROR_OK;
2062 }
2063
2064 static int evaluate_shift_imm_thumb(uint16_t opcode,
2065                                     uint32_t address, struct arm_instruction *instruction)
2066 {
2067         uint8_t Rd = (opcode >> 0) & 0x7;
2068         uint8_t Rm = (opcode >> 3) & 0x7;
2069         uint8_t imm = (opcode >> 6) & 0x1f;
2070         uint8_t opc = (opcode >> 11) & 0x3;
2071         char *mnemonic = NULL;
2072
2073         switch (opc) {
2074                 case 0:
2075                         instruction->type = ARM_MOV;
2076                         mnemonic = "LSLS";
2077                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
2078                         break;
2079                 case 1:
2080                         instruction->type = ARM_MOV;
2081                         mnemonic = "LSRS";
2082                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
2083                         break;
2084                 case 2:
2085                         instruction->type = ARM_MOV;
2086                         mnemonic = "ASRS";
2087                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
2088                         break;
2089         }
2090
2091         if ((imm == 0) && (opc != 0))
2092                 imm = 32;
2093
2094         instruction->info.data_proc.Rd = Rd;
2095         instruction->info.data_proc.Rn = -1;
2096         instruction->info.data_proc.S = 1;
2097
2098         instruction->info.data_proc.variant = 1;/*immediate_shift*/
2099         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2100         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
2101
2102         snprintf(instruction->text, 128,
2103                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, #%#2.2x",
2104                         address, opcode, mnemonic, Rd, Rm, imm);
2105
2106         return ERROR_OK;
2107 }
2108
2109 static int evaluate_data_proc_imm_thumb(uint16_t opcode,
2110                                         uint32_t address, struct arm_instruction *instruction)
2111 {
2112         uint8_t imm = opcode & 0xff;
2113         uint8_t Rd = (opcode >> 8) & 0x7;
2114         uint32_t opc = (opcode >> 11) & 0x3;
2115         char *mnemonic = NULL;
2116
2117         instruction->info.data_proc.Rd = Rd;
2118         instruction->info.data_proc.Rn = Rd;
2119         instruction->info.data_proc.S = 1;
2120         instruction->info.data_proc.variant = 0;/*immediate*/
2121         instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
2122
2123         switch (opc) {
2124                 case 0:
2125                         instruction->type = ARM_MOV;
2126                         mnemonic = "MOVS";
2127                         instruction->info.data_proc.Rn = -1;
2128                         break;
2129                 case 1:
2130                         instruction->type = ARM_CMP;
2131                         mnemonic = "CMP";
2132                         instruction->info.data_proc.Rd = -1;
2133                         break;
2134                 case 2:
2135                         instruction->type = ARM_ADD;
2136                         mnemonic = "ADDS";
2137                         break;
2138                 case 3:
2139                         instruction->type = ARM_SUB;
2140                         mnemonic = "SUBS";
2141                         break;
2142         }
2143
2144         snprintf(instruction->text, 128,
2145                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, #%#2.2x",
2146                         address, opcode, mnemonic, Rd, imm);
2147
2148         return ERROR_OK;
2149 }
2150
2151 static int evaluate_data_proc_thumb(uint16_t opcode,
2152                                     uint32_t address, struct arm_instruction *instruction)
2153 {
2154         uint8_t high_reg, op, Rm, Rd, H1, H2;
2155         char *mnemonic = NULL;
2156         bool nop = false;
2157
2158         high_reg = (opcode & 0x0400) >> 10;
2159         op = (opcode & 0x03C0) >> 6;
2160
2161         Rd = (opcode & 0x0007);
2162         Rm = (opcode & 0x0038) >> 3;
2163         H1 = (opcode & 0x0080) >> 7;
2164         H2 = (opcode & 0x0040) >> 6;
2165
2166         instruction->info.data_proc.Rd = Rd;
2167         instruction->info.data_proc.Rn = Rd;
2168         instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
2169         instruction->info.data_proc.variant = 1 /*immediate shift*/;
2170         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2171
2172         if (high_reg) {
2173                 Rd |= H1 << 3;
2174                 Rm |= H2 << 3;
2175                 op >>= 2;
2176
2177                 switch (op) {
2178                         case 0x0:
2179                                 instruction->type = ARM_ADD;
2180                                 mnemonic = "ADD";
2181                                 break;
2182                         case 0x1:
2183                                 instruction->type = ARM_CMP;
2184                                 mnemonic = "CMP";
2185                                 break;
2186                         case 0x2:
2187                                 instruction->type = ARM_MOV;
2188                                 mnemonic = "MOV";
2189                                 if (Rd == Rm)
2190                                         nop = true;
2191                                 break;
2192                         case 0x3:
2193                                 if ((opcode & 0x7) == 0x0) {
2194                                         instruction->info.b_bl_bx_blx.reg_operand = Rm;
2195                                         if (H1) {
2196                                                 instruction->type = ARM_BLX;
2197                                                 snprintf(instruction->text, 128,
2198                                                                 "0x%8.8" PRIx32
2199                                                                 "  0x%4.4x    \tBLX\tr%i",
2200                                                                 address, opcode, Rm);
2201                                         } else {
2202                                                 instruction->type = ARM_BX;
2203                                                 snprintf(instruction->text, 128,
2204                                                                 "0x%8.8" PRIx32
2205                                                                 "  0x%4.4x    \tBX\tr%i",
2206                                                                 address, opcode, Rm);
2207                                         }
2208                                 } else {
2209                                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
2210                                         snprintf(instruction->text, 128,
2211                                                         "0x%8.8" PRIx32
2212                                                         "  0x%4.4x    \t"
2213                                                         "UNDEFINED INSTRUCTION",
2214                                                         address, opcode);
2215                                 }
2216                                 return ERROR_OK;
2217                                 break;
2218                 }
2219         } else {
2220                 switch (op) {
2221                         case 0x0:
2222                                 instruction->type = ARM_AND;
2223                                 mnemonic = "ANDS";
2224                                 break;
2225                         case 0x1:
2226                                 instruction->type = ARM_EOR;
2227                                 mnemonic = "EORS";
2228                                 break;
2229                         case 0x2:
2230                                 instruction->type = ARM_MOV;
2231                                 mnemonic = "LSLS";
2232                                 instruction->info.data_proc.variant = 2 /*register shift*/;
2233                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
2234                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2235                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2236                                 break;
2237                         case 0x3:
2238                                 instruction->type = ARM_MOV;
2239                                 mnemonic = "LSRS";
2240                                 instruction->info.data_proc.variant = 2 /*register shift*/;
2241                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
2242                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2243                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2244                                 break;
2245                         case 0x4:
2246                                 instruction->type = ARM_MOV;
2247                                 mnemonic = "ASRS";
2248                                 instruction->info.data_proc.variant = 2 /*register shift*/;
2249                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
2250                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2251                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2252                                 break;
2253                         case 0x5:
2254                                 instruction->type = ARM_ADC;
2255                                 mnemonic = "ADCS";
2256                                 break;
2257                         case 0x6:
2258                                 instruction->type = ARM_SBC;
2259                                 mnemonic = "SBCS";
2260                                 break;
2261                         case 0x7:
2262                                 instruction->type = ARM_MOV;
2263                                 mnemonic = "RORS";
2264                                 instruction->info.data_proc.variant = 2 /*register shift*/;
2265                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
2266                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2267                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2268                                 break;
2269                         case 0x8:
2270                                 instruction->type = ARM_TST;
2271                                 mnemonic = "TST";
2272                                 break;
2273                         case 0x9:
2274                                 instruction->type = ARM_RSB;
2275                                 mnemonic = "RSBS";
2276                                 instruction->info.data_proc.variant = 0 /*immediate*/;
2277                                 instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
2278                                 instruction->info.data_proc.Rn = Rm;
2279                                 break;
2280                         case 0xA:
2281                                 instruction->type = ARM_CMP;
2282                                 mnemonic = "CMP";
2283                                 break;
2284                         case 0xB:
2285                                 instruction->type = ARM_CMN;
2286                                 mnemonic = "CMN";
2287                                 break;
2288                         case 0xC:
2289                                 instruction->type = ARM_ORR;
2290                                 mnemonic = "ORRS";
2291                                 break;
2292                         case 0xD:
2293                                 instruction->type = ARM_MUL;
2294                                 mnemonic = "MULS";
2295                                 break;
2296                         case 0xE:
2297                                 instruction->type = ARM_BIC;
2298                                 mnemonic = "BICS";
2299                                 break;
2300                         case 0xF:
2301                                 instruction->type = ARM_MVN;
2302                                 mnemonic = "MVNS";
2303                                 break;
2304                 }
2305         }
2306
2307         if (nop)
2308                 snprintf(instruction->text, 128,
2309                                 "0x%8.8" PRIx32 "  0x%4.4x    \tNOP\t\t\t"
2310                                 "; (%s r%i, r%i)",
2311                                 address, opcode, mnemonic, Rd, Rm);
2312         else
2313                 snprintf(instruction->text, 128,
2314                                 "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i",
2315                                 address, opcode, mnemonic, Rd, Rm);
2316
2317         return ERROR_OK;
2318 }
2319
2320 /* PC-relative data addressing is word-aligned even with Thumb */
2321 static inline uint32_t thumb_alignpc4(uint32_t addr)
2322 {
2323         return (addr + 4) & ~3;
2324 }
2325
2326 static int evaluate_load_literal_thumb(uint16_t opcode,
2327                                        uint32_t address, struct arm_instruction *instruction)
2328 {
2329         uint32_t immediate;
2330         uint8_t Rd = (opcode >> 8) & 0x7;
2331
2332         instruction->type = ARM_LDR;
2333         immediate = opcode & 0x000000ff;
2334         immediate *= 4;
2335
2336         instruction->info.load_store.Rd = Rd;
2337         instruction->info.load_store.Rn = 15 /*PC*/;
2338         instruction->info.load_store.index_mode = 0;    /*offset*/
2339         instruction->info.load_store.offset_mode = 0;   /*immediate*/
2340         instruction->info.load_store.offset.offset = immediate;
2341
2342         snprintf(instruction->text, 128,
2343                         "0x%8.8" PRIx32 "  0x%4.4x    \t"
2344                         "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32,
2345                         address, opcode, Rd, immediate,
2346                         thumb_alignpc4(address) + immediate);
2347
2348         return ERROR_OK;
2349 }
2350
2351 static int evaluate_load_store_reg_thumb(uint16_t opcode,
2352                                          uint32_t address, struct arm_instruction *instruction)
2353 {
2354         uint8_t Rd = (opcode >> 0) & 0x7;
2355         uint8_t Rn = (opcode >> 3) & 0x7;
2356         uint8_t Rm = (opcode >> 6) & 0x7;
2357         uint8_t opc = (opcode >> 9) & 0x7;
2358         char *mnemonic = NULL;
2359
2360         switch (opc) {
2361                 case 0:
2362                         instruction->type = ARM_STR;
2363                         mnemonic = "STR";
2364                         break;
2365                 case 1:
2366                         instruction->type = ARM_STRH;
2367                         mnemonic = "STRH";
2368                         break;
2369                 case 2:
2370                         instruction->type = ARM_STRB;
2371                         mnemonic = "STRB";
2372                         break;
2373                 case 3:
2374                         instruction->type = ARM_LDRSB;
2375                         mnemonic = "LDRSB";
2376                         break;
2377                 case 4:
2378                         instruction->type = ARM_LDR;
2379                         mnemonic = "LDR";
2380                         break;
2381                 case 5:
2382                         instruction->type = ARM_LDRH;
2383                         mnemonic = "LDRH";
2384                         break;
2385                 case 6:
2386                         instruction->type = ARM_LDRB;
2387                         mnemonic = "LDRB";
2388                         break;
2389                 case 7:
2390                         instruction->type = ARM_LDRSH;
2391                         mnemonic = "LDRSH";
2392                         break;
2393         }
2394
2395         snprintf(instruction->text, 128,
2396                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, [r%i, r%i]",
2397                         address, opcode, mnemonic, Rd, Rn, Rm);
2398
2399         instruction->info.load_store.Rd = Rd;
2400         instruction->info.load_store.Rn = Rn;
2401         instruction->info.load_store.index_mode = 0;    /*offset*/
2402         instruction->info.load_store.offset_mode = 1;   /*register*/
2403         instruction->info.load_store.offset.reg.Rm = Rm;
2404
2405         return ERROR_OK;
2406 }
2407
2408 static int evaluate_load_store_imm_thumb(uint16_t opcode,
2409                                          uint32_t address, struct arm_instruction *instruction)
2410 {
2411         uint32_t offset = (opcode >> 6) & 0x1f;
2412         uint8_t Rd = (opcode >> 0) & 0x7;
2413         uint8_t Rn = (opcode >> 3) & 0x7;
2414         uint32_t L = opcode & (1 << 11);
2415         uint32_t B = opcode & (1 << 12);
2416         char *mnemonic;
2417         char suffix = ' ';
2418         uint32_t shift = 2;
2419
2420         if (L) {
2421                 instruction->type = ARM_LDR;
2422                 mnemonic = "LDR";
2423         } else {
2424                 instruction->type = ARM_STR;
2425                 mnemonic = "STR";
2426         }
2427
2428         if ((opcode&0xF000) == 0x8000) {
2429                 suffix = 'H';
2430                 shift = 1;
2431         } else if (B) {
2432                 suffix = 'B';
2433                 shift = 0;
2434         }
2435
2436         snprintf(instruction->text, 128,
2437                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s%c\tr%i, [r%i, #%#" PRIx32 "]",
2438                         address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
2439
2440         instruction->info.load_store.Rd = Rd;
2441         instruction->info.load_store.Rn = Rn;
2442         instruction->info.load_store.index_mode = 0;    /*offset*/
2443         instruction->info.load_store.offset_mode = 0;   /*immediate*/
2444         instruction->info.load_store.offset.offset = offset << shift;
2445
2446         return ERROR_OK;
2447 }
2448
2449 static int evaluate_load_store_stack_thumb(uint16_t opcode,
2450                                            uint32_t address, struct arm_instruction *instruction)
2451 {
2452         uint32_t offset = opcode  & 0xff;
2453         uint8_t Rd = (opcode >> 8) & 0x7;
2454         uint32_t L = opcode & (1 << 11);
2455         char *mnemonic;
2456
2457         if (L) {
2458                 instruction->type = ARM_LDR;
2459                 mnemonic = "LDR";
2460         } else {
2461                 instruction->type = ARM_STR;
2462                 mnemonic = "STR";
2463         }
2464
2465         snprintf(instruction->text, 128,
2466                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, [SP, #%#" PRIx32 "]",
2467                         address, opcode, mnemonic, Rd, offset*4);
2468
2469         instruction->info.load_store.Rd = Rd;
2470         instruction->info.load_store.Rn = 13 /*SP*/;
2471         instruction->info.load_store.index_mode = 0;    /*offset*/
2472         instruction->info.load_store.offset_mode = 0;   /*immediate*/
2473         instruction->info.load_store.offset.offset = offset*4;
2474
2475         return ERROR_OK;
2476 }
2477
2478 static int evaluate_add_sp_pc_thumb(uint16_t opcode,
2479                                     uint32_t address, struct arm_instruction *instruction)
2480 {
2481         uint32_t imm = opcode  & 0xff;
2482         uint8_t Rd = (opcode >> 8) & 0x7;
2483         uint8_t Rn;
2484         uint32_t SP = opcode & (1 << 11);
2485         const char *reg_name;
2486
2487         instruction->type = ARM_ADD;
2488
2489         if (SP) {
2490                 reg_name = "SP";
2491                 Rn = 13;
2492         } else {
2493                 reg_name = "PC";
2494                 Rn = 15;
2495         }
2496
2497         snprintf(instruction->text, 128,
2498                         "0x%8.8" PRIx32 "  0x%4.4x  \tADD\tr%i, %s, #%#" PRIx32,
2499                         address, opcode, Rd, reg_name, imm * 4);
2500
2501         instruction->info.data_proc.variant = 0 /* immediate */;
2502         instruction->info.data_proc.Rd = Rd;
2503         instruction->info.data_proc.Rn = Rn;
2504         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2505
2506         return ERROR_OK;
2507 }
2508
2509 static int evaluate_adjust_stack_thumb(uint16_t opcode,
2510                                        uint32_t address, struct arm_instruction *instruction)
2511 {
2512         uint32_t imm = opcode  & 0x7f;
2513         uint8_t opc = opcode & (1 << 7);
2514         char *mnemonic;
2515
2516
2517         if (opc) {
2518                 instruction->type = ARM_SUB;
2519                 mnemonic = "SUB";
2520         } else {
2521                 instruction->type = ARM_ADD;
2522                 mnemonic = "ADD";
2523         }
2524
2525         snprintf(instruction->text, 128,
2526                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tSP, #%#" PRIx32,
2527                         address, opcode, mnemonic, imm*4);
2528
2529         instruction->info.data_proc.variant = 0 /* immediate */;
2530         instruction->info.data_proc.Rd = 13 /*SP*/;
2531         instruction->info.data_proc.Rn = 13 /*SP*/;
2532         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2533
2534         return ERROR_OK;
2535 }
2536
2537 static int evaluate_breakpoint_thumb(uint16_t opcode,
2538                                      uint32_t address, struct arm_instruction *instruction)
2539 {
2540         uint32_t imm = opcode  & 0xff;
2541
2542         instruction->type = ARM_BKPT;
2543
2544         snprintf(instruction->text, 128,
2545                         "0x%8.8" PRIx32 "  0x%4.4x  \tBKPT\t%#2.2" PRIx32 "",
2546                         address, opcode, imm);
2547
2548         return ERROR_OK;
2549 }
2550
2551 static int evaluate_load_store_multiple_thumb(uint16_t opcode,
2552                                               uint32_t address, struct arm_instruction *instruction)
2553 {
2554         uint32_t reg_list = opcode  & 0xff;
2555         uint32_t L = opcode & (1 << 11);
2556         uint32_t R = opcode & (1 << 8);
2557         uint8_t Rn = (opcode >> 8) & 7;
2558         uint8_t addr_mode = 0 /* IA */;
2559         char reg_names[40];
2560         char *reg_names_p;
2561         char *mnemonic;
2562         char ptr_name[7] = "";
2563         int i;
2564
2565         /* REVISIT:  in ThumbEE mode, there are no LDM or STM instructions.
2566          * The STMIA and LDMIA opcodes are used for other instructions.
2567          */
2568
2569         if ((opcode & 0xf000) == 0xc000) {      /* generic load/store multiple */
2570                 char *wback = "!";
2571
2572                 if (L) {
2573                         instruction->type = ARM_LDM;
2574                         mnemonic = "LDM";
2575                         if (opcode & (1 << Rn))
2576                                 wback = "";
2577                 } else {
2578                         instruction->type = ARM_STM;
2579                         mnemonic = "STM";
2580                 }
2581                 snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback);
2582         } else {/* push/pop */
2583                 Rn = 13;/* SP */
2584                 if (L) {
2585                         instruction->type = ARM_LDM;
2586                         mnemonic = "POP";
2587                         if (R)
2588                                 reg_list |= (1 << 15) /*PC*/;
2589                 } else {
2590                         instruction->type = ARM_STM;
2591                         mnemonic = "PUSH";
2592                         addr_mode = 3;  /*DB*/
2593                         if (R)
2594                                 reg_list |= (1 << 14) /*LR*/;
2595                 }
2596         }
2597
2598         reg_names_p = reg_names;
2599         for (i = 0; i <= 15; i++) {
2600                 if (reg_list & (1 << i))
2601                         reg_names_p += snprintf(reg_names_p,
2602                                                 (reg_names + 40 - reg_names_p),
2603                                                 "r%i, ",
2604                                                 i);
2605         }
2606         if (reg_names_p > reg_names)
2607                 reg_names_p[-2] = '\0';
2608         else    /* invalid op : no registers */
2609                 reg_names[0] = '\0';
2610
2611         snprintf(instruction->text, 128,
2612                         "0x%8.8" PRIx32 "  0x%4.4x  \t%s\t%s{%s}",
2613                         address, opcode, mnemonic, ptr_name, reg_names);
2614
2615         instruction->info.load_store_multiple.register_list = reg_list;
2616         instruction->info.load_store_multiple.Rn = Rn;
2617         instruction->info.load_store_multiple.addressing_mode = addr_mode;
2618
2619         return ERROR_OK;
2620 }
2621
2622 static int evaluate_cond_branch_thumb(uint16_t opcode,
2623                                       uint32_t address, struct arm_instruction *instruction)
2624 {
2625         uint32_t offset = opcode  & 0xff;
2626         uint8_t cond = (opcode >> 8) & 0xf;
2627         uint32_t target_address;
2628
2629         if (cond == 0xf) {
2630                 instruction->type = ARM_SWI;
2631                 snprintf(instruction->text, 128,
2632                                 "0x%8.8" PRIx32 "  0x%4.4x    \tSVC\t%#2.2" PRIx32,
2633                                 address, opcode, offset);
2634                 return ERROR_OK;
2635         } else if (cond == 0xe) {
2636                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2637                 snprintf(instruction->text, 128,
2638                                 "0x%8.8" PRIx32 "  0x%4.4x    \tUNDEFINED INSTRUCTION",
2639                                 address, opcode);
2640                 return ERROR_OK;
2641         }
2642
2643         /* sign extend 8-bit offset */
2644         if (offset & 0x00000080)
2645                 offset = 0xffffff00 | offset;
2646
2647         target_address = address + 4 + (offset << 1);
2648
2649         snprintf(instruction->text, 128,
2650                         "0x%8.8" PRIx32 "  0x%4.4x    \tB%s\t%#8.8" PRIx32,
2651                         address, opcode,
2652                         arm_condition_strings[cond], target_address);
2653
2654         instruction->type = ARM_B;
2655         instruction->info.b_bl_bx_blx.reg_operand = -1;
2656         instruction->info.b_bl_bx_blx.target_address = target_address;
2657
2658         return ERROR_OK;
2659 }
2660
2661 static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
2662                              struct arm_instruction *instruction)
2663 {
2664         unsigned offset;
2665
2666         /* added in Thumb2 */
2667         offset = (opcode >> 3) & 0x1f;
2668         offset |= (opcode & 0x0200) >> 4;
2669
2670         snprintf(instruction->text, 128,
2671                         "0x%8.8" PRIx32 "  0x%4.4x    \tCB%sZ\tr%d, %#8.8" PRIx32,
2672                         address, opcode,
2673                         (opcode & 0x0800) ? "N" : "",
2674                         opcode & 0x7, address + 4 + (offset << 1));
2675
2676         return ERROR_OK;
2677 }
2678
2679 static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
2680                                  struct arm_instruction *instruction)
2681 {
2682         /* added in ARMv6 */
2683         snprintf(instruction->text, 128,
2684                         "0x%8.8" PRIx32 "  0x%4.4x    \t%cXT%c\tr%d, r%d",
2685                         address, opcode,
2686                         (opcode & 0x0080) ? 'U' : 'S',
2687                         (opcode & 0x0040) ? 'B' : 'H',
2688                         opcode & 0x7, (opcode >> 3) & 0x7);
2689
2690         return ERROR_OK;
2691 }
2692
2693 static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
2694                               struct arm_instruction *instruction)
2695 {
2696         /* added in ARMv6 */
2697         if ((opcode & 0x0ff0) == 0x0650)
2698                 snprintf(instruction->text, 128,
2699                                 "0x%8.8" PRIx32 "  0x%4.4x    \tSETEND %s",
2700                                 address, opcode,
2701                                 (opcode & 0x80) ? "BE" : "LE");
2702         else    /* ASSUME (opcode & 0x0fe0) == 0x0660 */
2703                 snprintf(instruction->text, 128,
2704                                 "0x%8.8" PRIx32 "  0x%4.4x    \tCPSI%c\t%s%s%s",
2705                                 address, opcode,
2706                                 (opcode & 0x0010) ? 'D' : 'E',
2707                                 (opcode & 0x0004) ? "A" : "",
2708                                 (opcode & 0x0002) ? "I" : "",
2709                                 (opcode & 0x0001) ? "F" : "");
2710
2711         return ERROR_OK;
2712 }
2713
2714 static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
2715                                   struct arm_instruction *instruction)
2716 {
2717         char *suffix;
2718
2719         /* added in ARMv6 */
2720         switch ((opcode >> 6) & 3) {
2721                 case 0:
2722                         suffix = "";
2723                         break;
2724                 case 1:
2725                         suffix = "16";
2726                         break;
2727                 default:
2728                         suffix = "SH";
2729                         break;
2730         }
2731         snprintf(instruction->text, 128,
2732                         "0x%8.8" PRIx32 "  0x%4.4x    \tREV%s\tr%d, r%d",
2733                         address, opcode, suffix,
2734                         opcode & 0x7, (opcode >> 3) & 0x7);
2735
2736         return ERROR_OK;
2737 }
2738
2739 static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
2740                                struct arm_instruction *instruction)
2741 {
2742         char *hint;
2743
2744         switch ((opcode >> 4) & 0x0f) {
2745                 case 0:
2746                         hint = "NOP";
2747                         break;
2748                 case 1:
2749                         hint = "YIELD";
2750                         break;
2751                 case 2:
2752                         hint = "WFE";
2753                         break;
2754                 case 3:
2755                         hint = "WFI";
2756                         break;
2757                 case 4:
2758                         hint = "SEV";
2759                         break;
2760                 default:
2761                         hint = "HINT (UNRECOGNIZED)";
2762                         break;
2763         }
2764
2765         snprintf(instruction->text, 128,
2766                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s",
2767                         address, opcode, hint);
2768
2769         return ERROR_OK;
2770 }
2771
2772 static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
2773                                  struct arm_instruction *instruction)
2774 {
2775         unsigned cond = (opcode >> 4) & 0x0f;
2776         char *x = "", *y = "", *z = "";
2777
2778         if (opcode & 0x01)
2779                 z = (opcode & 0x02) ? "T" : "E";
2780         if (opcode & 0x03)
2781                 y = (opcode & 0x04) ? "T" : "E";
2782         if (opcode & 0x07)
2783                 x = (opcode & 0x08) ? "T" : "E";
2784
2785         snprintf(instruction->text, 128,
2786                         "0x%8.8" PRIx32 "  0x%4.4x    \tIT%s%s%s\t%s",
2787                         address, opcode,
2788                         x, y, z, arm_condition_strings[cond]);
2789
2790         /* NOTE:  strictly speaking, the next 1-4 instructions should
2791          * now be displayed with the relevant conditional suffix...
2792          */
2793
2794         return ERROR_OK;
2795 }
2796
2797 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
2798 {
2799         /* clear fields, to avoid confusion */
2800         memset(instruction, 0, sizeof(struct arm_instruction));
2801         instruction->opcode = opcode;
2802         instruction->instruction_size = 2;
2803
2804         if ((opcode & 0xe000) == 0x0000) {
2805                 /* add/substract register or immediate */
2806                 if ((opcode & 0x1800) == 0x1800)
2807                         return evaluate_add_sub_thumb(opcode, address, instruction);
2808                 /* shift by immediate */
2809                 else
2810                         return evaluate_shift_imm_thumb(opcode, address, instruction);
2811         }
2812
2813         /* Add/substract/compare/move immediate */
2814         if ((opcode & 0xe000) == 0x2000)
2815                 return evaluate_data_proc_imm_thumb(opcode, address, instruction);
2816
2817         /* Data processing instructions */
2818         if ((opcode & 0xf800) == 0x4000)
2819                 return evaluate_data_proc_thumb(opcode, address, instruction);
2820
2821         /* Load from literal pool */
2822         if ((opcode & 0xf800) == 0x4800)
2823                 return evaluate_load_literal_thumb(opcode, address, instruction);
2824
2825         /* Load/Store register offset */
2826         if ((opcode & 0xf000) == 0x5000)
2827                 return evaluate_load_store_reg_thumb(opcode, address, instruction);
2828
2829         /* Load/Store immediate offset */
2830         if (((opcode & 0xe000) == 0x6000)
2831                         || ((opcode & 0xf000) == 0x8000))
2832                 return evaluate_load_store_imm_thumb(opcode, address, instruction);
2833
2834         /* Load/Store from/to stack */
2835         if ((opcode & 0xf000) == 0x9000)
2836                 return evaluate_load_store_stack_thumb(opcode, address, instruction);
2837
2838         /* Add to SP/PC */
2839         if ((opcode & 0xf000) == 0xa000)
2840                 return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2841
2842         /* Misc */
2843         if ((opcode & 0xf000) == 0xb000) {
2844                 switch ((opcode >> 8) & 0x0f) {
2845                         case 0x0:
2846                                 return evaluate_adjust_stack_thumb(opcode, address, instruction);
2847                         case 0x1:
2848                         case 0x3:
2849                         case 0x9:
2850                         case 0xb:
2851                                 return evaluate_cb_thumb(opcode, address, instruction);
2852                         case 0x2:
2853                                 return evaluate_extend_thumb(opcode, address, instruction);
2854                         case 0x4:
2855                         case 0x5:
2856                         case 0xc:
2857                         case 0xd:
2858                                 return evaluate_load_store_multiple_thumb(opcode, address,
2859                                         instruction);
2860                         case 0x6:
2861                                 return evaluate_cps_thumb(opcode, address, instruction);
2862                         case 0xa:
2863                                 if ((opcode & 0x00c0) == 0x0080)
2864                                         break;
2865                                 return evaluate_byterev_thumb(opcode, address, instruction);
2866                         case 0xe:
2867                                 return evaluate_breakpoint_thumb(opcode, address, instruction);
2868                         case 0xf:
2869                                 if (opcode & 0x000f)
2870                                         return evaluate_ifthen_thumb(opcode, address,
2871                                                         instruction);
2872                                 else
2873                                         return evaluate_hint_thumb(opcode, address,
2874                                                         instruction);
2875                 }
2876
2877                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2878                 snprintf(instruction->text, 128,
2879                                 "0x%8.8" PRIx32 "  0x%4.4x    \tUNDEFINED INSTRUCTION",
2880                                 address, opcode);
2881                 return ERROR_OK;
2882         }
2883
2884         /* Load/Store multiple */
2885         if ((opcode & 0xf000) == 0xc000)
2886                 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2887
2888         /* Conditional branch + SWI */
2889         if ((opcode & 0xf000) == 0xd000)
2890                 return evaluate_cond_branch_thumb(opcode, address, instruction);
2891
2892         if ((opcode & 0xe000) == 0xe000) {
2893                 /* Undefined instructions */
2894                 if ((opcode & 0xf801) == 0xe801) {
2895                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
2896                         snprintf(instruction->text, 128,
2897                                         "0x%8.8" PRIx32 "  0x%8.8x\t"
2898                                         "UNDEFINED INSTRUCTION",
2899                                         address, opcode);
2900                         return ERROR_OK;
2901                 } else  /* Branch to offset */
2902                         return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2903         }
2904
2905         LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
2906         return -1;
2907 }
2908
2909 static int t2ev_b_bl(uint32_t opcode, uint32_t address,
2910                      struct arm_instruction *instruction, char *cp)
2911 {
2912         unsigned offset;
2913         unsigned b21 = 1 << 21;
2914         unsigned b22 = 1 << 22;
2915
2916         /* instead of combining two smaller 16-bit branch instructions,
2917          * Thumb2 uses only one larger 32-bit instruction.
2918          */
2919         offset = opcode & 0x7ff;
2920         offset |= (opcode & 0x03ff0000) >> 5;
2921         if (opcode & (1 << 26)) {
2922                 offset |= 0xff << 23;
2923                 if ((opcode & (1 << 11)) == 0)
2924                         b21 = 0;
2925                 if ((opcode & (1 << 13)) == 0)
2926                         b22 = 0;
2927         } else {
2928                 if (opcode & (1 << 11))
2929                         b21 = 0;
2930                 if (opcode & (1 << 13))
2931                         b22 = 0;
2932         }
2933         offset |= b21;
2934         offset |= b22;
2935
2936
2937         address += 4;
2938         address += offset << 1;
2939
2940         char *inst;
2941         switch ((opcode >> 12) & 0x5) {
2942         case 0x1:
2943                 inst = "B.W";
2944                 instruction->type = ARM_B;
2945                 break;
2946         case 0x4:
2947                 inst = "BLX";
2948                 instruction->type = ARM_BLX;
2949                 break;
2950         case 0x5:
2951                 inst = "BL";
2952                 instruction->type = ARM_BL;
2953                 break;
2954         default:
2955                 return ERROR_COMMAND_SYNTAX_ERROR;
2956         }
2957         instruction->info.b_bl_bx_blx.reg_operand = -1;
2958         instruction->info.b_bl_bx_blx.target_address = address;
2959         sprintf(cp, "%s\t%#8.8" PRIx32, inst, address);
2960
2961         return ERROR_OK;
2962 }
2963
2964 static int t2ev_cond_b(uint32_t opcode, uint32_t address,
2965                        struct arm_instruction *instruction, char *cp)
2966 {
2967         unsigned offset;
2968         unsigned b17 = 1 << 17;
2969         unsigned b18 = 1 << 18;
2970         unsigned cond = (opcode >> 22) & 0x0f;
2971
2972         offset = opcode & 0x7ff;
2973         offset |= (opcode & 0x003f0000) >> 5;
2974         if (opcode & (1 << 26)) {
2975                 offset |= 0x1fff << 19;
2976                 if ((opcode & (1 << 11)) == 0)
2977                         b17 = 0;
2978                 if ((opcode & (1 << 13)) == 0)
2979                         b18 = 0;
2980         } else {
2981                 if (opcode & (1 << 11))
2982                         b17 = 0;
2983                 if (opcode & (1 << 13))
2984                         b18 = 0;
2985         }
2986         offset |= b17;
2987         offset |= b18;
2988
2989         address += 4;
2990         address += offset << 1;
2991
2992         instruction->type = ARM_B;
2993         instruction->info.b_bl_bx_blx.reg_operand = -1;
2994         instruction->info.b_bl_bx_blx.target_address = address;
2995         sprintf(cp, "B%s.W\t%#8.8" PRIx32,
2996                         arm_condition_strings[cond],
2997                         address);
2998
2999         return ERROR_OK;
3000 }
3001
3002 static const char *special_name(int number)
3003 {
3004         char *special = "(RESERVED)";
3005
3006         switch (number) {
3007                 case 0:
3008                         special = "apsr";
3009                         break;
3010                 case 1:
3011                         special = "iapsr";
3012                         break;
3013                 case 2:
3014                         special = "eapsr";
3015                         break;
3016                 case 3:
3017                         special = "xpsr";
3018                         break;
3019                 case 5:
3020                         special = "ipsr";
3021                         break;
3022                 case 6:
3023                         special = "epsr";
3024                         break;
3025                 case 7:
3026                         special = "iepsr";
3027                         break;
3028                 case 8:
3029                         special = "msp";
3030                         break;
3031                 case 9:
3032                         special = "psp";
3033                         break;
3034                 case 16:
3035                         special = "primask";
3036                         break;
3037                 case 17:
3038                         special = "basepri";
3039                         break;
3040                 case 18:
3041                         special = "basepri_max";
3042                         break;
3043                 case 19:
3044                         special = "faultmask";
3045                         break;
3046                 case 20:
3047                         special = "control";
3048                         break;
3049         }
3050         return special;
3051 }
3052
3053 static int t2ev_hint(uint32_t opcode, uint32_t address,
3054                      struct arm_instruction *instruction, char *cp)
3055 {
3056         const char *mnemonic;
3057
3058         if (opcode & 0x0700) {
3059                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3060                 strcpy(cp, "UNDEFINED");
3061                 return ERROR_OK;
3062         }
3063
3064         if (opcode & 0x00f0) {
3065                 sprintf(cp, "DBG\t#%d", (int) opcode & 0xf);
3066                 return ERROR_OK;
3067         }
3068
3069         switch (opcode & 0x0f) {
3070                 case 0:
3071                         mnemonic = "NOP.W";
3072                         break;
3073                 case 1:
3074                         mnemonic = "YIELD.W";
3075                         break;
3076                 case 2:
3077                         mnemonic = "WFE.W";
3078                         break;
3079                 case 3:
3080                         mnemonic = "WFI.W";
3081                         break;
3082                 case 4:
3083                         mnemonic = "SEV.W";
3084                         break;
3085                 default:
3086                         mnemonic = "HINT.W (UNRECOGNIZED)";
3087                         break;
3088         }
3089         strcpy(cp, mnemonic);
3090         return ERROR_OK;
3091 }
3092
3093 static int t2ev_misc(uint32_t opcode, uint32_t address,
3094                      struct arm_instruction *instruction, char *cp)
3095 {
3096         const char *mnemonic;
3097
3098         switch ((opcode >> 4) & 0x0f) {
3099                 case 0:
3100                         mnemonic = "LEAVEX";
3101                         break;
3102                 case 1:
3103                         mnemonic = "ENTERX";
3104                         break;
3105                 case 2:
3106                         mnemonic = "CLREX";
3107                         break;
3108                 case 4:
3109                         mnemonic = "DSB";
3110                         break;
3111                 case 5:
3112                         mnemonic = "DMB";
3113                         break;
3114                 case 6:
3115                         mnemonic = "ISB";
3116                         break;
3117                 default:
3118                         return ERROR_COMMAND_SYNTAX_ERROR;
3119         }
3120         strcpy(cp, mnemonic);
3121         return ERROR_OK;
3122 }
3123
3124 static int t2ev_b_misc(uint32_t opcode, uint32_t address,
3125                        struct arm_instruction *instruction, char *cp)
3126 {
3127         /* permanently undefined */
3128         if ((opcode & 0x07f07000) == 0x07f02000) {
3129                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3130                 strcpy(cp, "UNDEFINED");
3131                 return ERROR_OK;
3132         }
3133
3134         switch ((opcode >> 12) & 0x5) {
3135                 case 0x1:
3136                 case 0x4:
3137                 case 0x5:
3138                         return t2ev_b_bl(opcode, address, instruction, cp);
3139                 case 0:
3140                         if (((opcode >> 23) & 0x07) != 0x07)
3141                                 return t2ev_cond_b(opcode, address, instruction, cp);
3142                         if (opcode & (1 << 26))
3143                                 goto undef;
3144                         break;
3145         }
3146
3147         switch ((opcode >> 20) & 0x7f) {
3148                 case 0x38:
3149                 case 0x39:
3150                         sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff),
3151                                 (int) (opcode >> 16) & 0x0f);
3152                         return ERROR_OK;
3153                 case 0x3a:
3154                         return t2ev_hint(opcode, address, instruction, cp);
3155                 case 0x3b:
3156                         return t2ev_misc(opcode, address, instruction, cp);
3157                 case 0x3c:
3158                         sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f);
3159                         return ERROR_OK;
3160                 case 0x3e:
3161                 case 0x3f:
3162                         sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f,
3163                                 special_name(opcode & 0xff));
3164                         return ERROR_OK;
3165         }
3166
3167 undef:
3168         return ERROR_COMMAND_SYNTAX_ERROR;
3169 }
3170
3171 static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
3172                                struct arm_instruction *instruction, char *cp)
3173 {
3174         char *mnemonic = NULL;
3175         int rn = (opcode >> 16) & 0xf;
3176         int rd = (opcode >> 8) & 0xf;
3177         unsigned immed = opcode & 0xff;
3178         unsigned func;
3179         bool one = false;
3180         char *suffix = "";
3181         char *suffix2 = "";
3182
3183         /* ARMv7-M: A5.3.2 Modified immediate constants */
3184         func = (opcode >> 11) & 0x0e;
3185         if (immed & 0x80)
3186                 func |= 1;
3187         if (opcode & (1 << 26))
3188                 func |= 0x10;
3189
3190         /* "Modified" immediates */
3191         switch (func >> 1) {
3192                 case 0:
3193                         break;
3194                 case 2:
3195                         immed <<= 8;
3196                 /* FALLTHROUGH */
3197                 case 1:
3198                         immed += immed << 16;
3199                         break;
3200                 case 3:
3201                         immed += immed << 8;
3202                         immed += immed << 16;
3203                         break;
3204                 default:
3205                         immed |= 0x80;
3206                         immed = ror(immed, func);
3207         }
3208
3209         if (opcode & (1 << 20))
3210                 suffix = "S";
3211
3212         switch ((opcode >> 21) & 0xf) {
3213                 case 0:
3214                         if (rd == 0xf) {
3215                                 instruction->type = ARM_TST;
3216                                 mnemonic = "TST";
3217                                 one = true;
3218                                 suffix = "";
3219                                 rd = rn;
3220                         } else {
3221                                 instruction->type = ARM_AND;
3222                                 mnemonic = "AND";
3223                         }
3224                         break;
3225                 case 1:
3226                         instruction->type = ARM_BIC;
3227                         mnemonic = "BIC";
3228                         break;
3229                 case 2:
3230                         if (rn == 0xf) {
3231                                 instruction->type = ARM_MOV;
3232                                 mnemonic = "MOV";
3233                                 one = true;
3234                                 suffix2 = ".W";
3235                         } else {
3236                                 instruction->type = ARM_ORR;
3237                                 mnemonic = "ORR";
3238                         }
3239                         break;
3240                 case 3:
3241                         if (rn == 0xf) {
3242                                 instruction->type = ARM_MVN;
3243                                 mnemonic = "MVN";
3244                                 one = true;
3245                         } else {
3246                                 /* instruction->type = ARM_ORN; */
3247                                 mnemonic = "ORN";
3248                         }
3249                         break;
3250                 case 4:
3251                         if (rd == 0xf) {
3252                                 instruction->type = ARM_TEQ;
3253                                 mnemonic = "TEQ";
3254                                 one = true;
3255                                 suffix = "";
3256                                 rd = rn;
3257                         } else {
3258                                 instruction->type = ARM_EOR;
3259                                 mnemonic = "EOR";
3260                         }
3261                         break;
3262                 case 8:
3263                         if (rd == 0xf) {
3264                                 instruction->type = ARM_CMN;
3265                                 mnemonic = "CMN";
3266                                 one = true;
3267                                 suffix = "";
3268                                 rd = rn;
3269                         } else {
3270                                 instruction->type = ARM_ADD;
3271                                 mnemonic = "ADD";
3272                                 suffix2 = ".W";
3273                         }
3274                         break;
3275                 case 10:
3276                         instruction->type = ARM_ADC;
3277                         mnemonic = "ADC";
3278                         suffix2 = ".W";
3279                         break;
3280                 case 11:
3281                         instruction->type = ARM_SBC;
3282                         mnemonic = "SBC";
3283                         break;
3284                 case 13:
3285                         if (rd == 0xf) {
3286                                 instruction->type = ARM_CMP;
3287                                 mnemonic = "CMP";
3288                                 one = true;
3289                                 suffix = "";
3290                                 rd = rn;
3291                         } else {
3292                                 instruction->type = ARM_SUB;
3293                                 mnemonic = "SUB";
3294                         }
3295                         suffix2 = ".W";
3296                         break;
3297                 case 14:
3298                         instruction->type = ARM_RSB;
3299                         mnemonic = "RSB";
3300                         suffix2 = ".W";
3301                         break;
3302                 default:
3303                         return ERROR_COMMAND_SYNTAX_ERROR;
3304         }
3305
3306         if (one)
3307                 sprintf(cp, "%s%s\tr%d, #%d\t; %#8.8x",
3308                                 mnemonic, suffix2, rd, immed, immed);
3309         else
3310                 sprintf(cp, "%s%s%s\tr%d, r%d, #%d\t; %#8.8x",
3311                                 mnemonic, suffix, suffix2,
3312                                 rd, rn, immed, immed);
3313
3314         return ERROR_OK;
3315 }
3316
3317 static int t2ev_data_immed(uint32_t opcode, uint32_t address,
3318                            struct arm_instruction *instruction, char *cp)
3319 {
3320         char *mnemonic = NULL;
3321         int rn = (opcode >> 16) & 0xf;
3322         int rd = (opcode >> 8) & 0xf;
3323         unsigned immed;
3324         bool add = false;
3325         bool is_signed = false;
3326
3327         immed = (opcode & 0x0ff) | ((opcode & 0x7000) >> 4);
3328         if (opcode & (1 << 26))
3329                 immed |= (1 << 11);
3330
3331         switch ((opcode >> 20) & 0x1f) {
3332                 case 0:
3333                         if (rn == 0xf) {
3334                                 add = true;
3335                                 goto do_adr;
3336                         }
3337                         mnemonic = "ADDW";
3338                         break;
3339                 case 4:
3340                         immed |= (opcode >> 4) & 0xf000;
3341                         sprintf(cp, "MOVW\tr%d, #%d\t; %#3.3x", rd, immed, immed);
3342                         return ERROR_OK;
3343                 case 0x0a:
3344                         if (rn == 0xf)
3345                                 goto do_adr;
3346                         mnemonic = "SUBW";
3347                         break;
3348                 case 0x0c:
3349                         /* move constant to top 16 bits of register */
3350                         immed |= (opcode >> 4) & 0xf000;
3351                         sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed);
3352                         return ERROR_OK;
3353                 case 0x10:
3354                 case 0x12:
3355                         is_signed = true;
3356                         /* fallthrough */
3357                 case 0x18:
3358                 case 0x1a:
3359                         /* signed/unsigned saturated add */
3360                         immed = (opcode >> 6) & 0x03;
3361                         immed |= (opcode >> 10) & 0x1c;
3362                         sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t",
3363                                 is_signed ? "S" : "U",
3364                                 rd, (int) (opcode & 0x1f) + is_signed, rn,
3365                                 (opcode & (1 << 21)) ? "ASR" : "LSL",
3366                                 immed ? immed : 32);
3367                         return ERROR_OK;
3368                 case 0x14:
3369                         is_signed = true;
3370                 /* FALLTHROUGH */
3371                 case 0x1c:
3372                         /* signed/unsigned bitfield extract */
3373                         immed = (opcode >> 6) & 0x03;
3374                         immed |= (opcode >> 10) & 0x1c;
3375                         sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t",
3376                                 is_signed ? "S" : "U",
3377                                 rd, rn, immed,
3378                                 (int) (opcode & 0x1f) + 1);
3379                         return ERROR_OK;
3380                 case 0x16:
3381                         immed = (opcode >> 6) & 0x03;
3382                         immed |= (opcode >> 10) & 0x1c;
3383                         if (rn == 0xf)  /* bitfield clear */
3384                                 sprintf(cp, "BFC\tr%d, #%d, #%d\t",
3385                                                 rd, immed,
3386                                                 (int) (opcode & 0x1f) + 1 - immed);
3387                         else            /* bitfield insert */
3388                                 sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t",
3389                                                 rd, rn, immed,
3390                                                 (int) (opcode & 0x1f) + 1 - immed);
3391                         return ERROR_OK;
3392                 default:
3393                         return ERROR_COMMAND_SYNTAX_ERROR;
3394         }
3395
3396         sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic,
3397                         rd, rn, immed, immed);
3398         return ERROR_OK;
3399
3400 do_adr:
3401         address = thumb_alignpc4(address);
3402         if (add)
3403                 address += immed;
3404         else
3405                 address -= immed;
3406         /* REVISIT "ADD/SUB Rd, PC, #const ; 0x..." might be better;
3407          * not hiding the pc-relative stuff will sometimes be useful.
3408          */
3409         sprintf(cp, "ADR.W\tr%d, %#8.8" PRIx32, rd, address);
3410         return ERROR_OK;
3411 }
3412
3413 static int t2ev_store_single(uint32_t opcode, uint32_t address,
3414                              struct arm_instruction *instruction, char *cp)
3415 {
3416         unsigned op = (opcode >> 20) & 0xf;
3417         char *size = "";
3418         char *suffix = "";
3419         char *p1 = "";
3420         char *p2 = "]";
3421         unsigned immed;
3422         unsigned rn = (opcode >> 16) & 0x0f;
3423         unsigned rt = (opcode >> 12) & 0x0f;
3424
3425         if (rn == 0xf)
3426                 return ERROR_COMMAND_SYNTAX_ERROR;
3427
3428         if (opcode & 0x0800)
3429                 op |= 1;
3430         switch (op) {
3431                 /* byte */
3432                 case 0x8:
3433                 case 0x9:
3434                         size = "B";
3435                         goto imm12;
3436                 case 0x1:
3437                         size = "B";
3438                         goto imm8;
3439                 case 0x0:
3440                         size = "B";
3441                         break;
3442                 /* halfword */
3443                 case 0xa:
3444                 case 0xb:
3445                         size = "H";
3446                         goto imm12;
3447                 case 0x3:
3448                         size = "H";
3449                         goto imm8;
3450                 case 0x2:
3451                         size = "H";
3452                         break;
3453                 /* word */
3454                 case 0xc:
3455                 case 0xd:
3456                         goto imm12;
3457                 case 0x5:
3458                         goto imm8;
3459                 case 0x4:
3460                         break;
3461                 /* error */
3462                 default:
3463                         return ERROR_COMMAND_SYNTAX_ERROR;
3464         }
3465
3466         sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]",
3467                         size, rt, rn, (int) opcode & 0x0f,
3468                         (int) (opcode >> 4) & 0x03);
3469         return ERROR_OK;
3470
3471 imm12:
3472         immed = opcode & 0x0fff;
3473         sprintf(cp, "STR%s.W\tr%d, [r%d, #%u]\t; %#3.3x",
3474                         size, rt, rn, immed, immed);
3475         return ERROR_OK;
3476
3477 imm8:
3478         immed = opcode & 0x00ff;
3479
3480         switch (opcode & 0x700) {
3481                 case 0x600:
3482                         suffix = "T";
3483                         break;
3484                 case 0x000:
3485                 case 0x200:
3486                         return ERROR_COMMAND_SYNTAX_ERROR;
3487         }
3488
3489         /* two indexed modes will write back rn */
3490         if (opcode & 0x100) {
3491                 if (opcode & 0x400)     /* pre-indexed */
3492                         p2 = "]!";
3493                 else {                  /* post-indexed */
3494                         p1 = "]";
3495                         p2 = "";
3496                 }
3497         }
3498
3499         sprintf(cp, "STR%s%s\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
3500                         size, suffix, rt, rn, p1,
3501                         (opcode & 0x200) ? "" : "-",
3502                         immed, p2, immed);
3503         return ERROR_OK;
3504 }
3505
3506 static int t2ev_mul32(uint32_t opcode, uint32_t address,
3507                       struct arm_instruction *instruction, char *cp)
3508 {
3509         int ra = (opcode >> 12) & 0xf;
3510
3511         switch (opcode & 0x007000f0) {
3512                 case 0:
3513                         if (ra == 0xf)
3514                                 sprintf(cp, "MUL\tr%d, r%d, r%d",
3515                                                 (int) (opcode >> 8) & 0xf,
3516                                                 (int) (opcode >> 16) & 0xf,
3517                                                 (int) (opcode >> 0) & 0xf);
3518                         else
3519                                 sprintf(cp, "MLA\tr%d, r%d, r%d, r%d",
3520                                                 (int) (opcode >> 8) & 0xf,
3521                                                 (int) (opcode >> 16) & 0xf,
3522                                                 (int) (opcode >> 0) & 0xf, ra);
3523                         break;
3524                 case 0x10:
3525                         sprintf(cp, "MLS\tr%d, r%d, r%d, r%d",
3526                                 (int) (opcode >> 8) & 0xf,
3527                                 (int) (opcode >> 16) & 0xf,
3528                                 (int) (opcode >> 0) & 0xf, ra);
3529                         break;
3530                 default:
3531                         return ERROR_COMMAND_SYNTAX_ERROR;
3532         }
3533         return ERROR_OK;
3534 }
3535
3536 static int t2ev_mul64_div(uint32_t opcode, uint32_t address,
3537                           struct arm_instruction *instruction, char *cp)
3538 {
3539         int op = (opcode >> 4) & 0xf;
3540         char *infix = "MUL";
3541
3542         op += (opcode >> 16) & 0x70;
3543         switch (op) {
3544                 case 0x40:
3545                 case 0x60:
3546                         infix = "MLA";
3547                 /* FALLTHROUGH */
3548                 case 0:
3549                 case 0x20:
3550                         sprintf(cp, "%c%sL\tr%d, r%d, r%d, r%d",
3551                                 (op & 0x20) ? 'U' : 'S',
3552                                 infix,
3553                                 (int) (opcode >> 12) & 0xf,
3554                                 (int) (opcode >> 8) & 0xf,
3555                                 (int) (opcode >> 16) & 0xf,
3556                                 (int) (opcode >> 0) & 0xf);
3557                         break;
3558                 case 0x1f:
3559                 case 0x3f:
3560                         sprintf(cp, "%cDIV\tr%d, r%d, r%d",
3561                                 (op & 0x20) ? 'U' : 'S',
3562                                 (int) (opcode >> 8) & 0xf,
3563                                 (int) (opcode >> 16) & 0xf,
3564                                 (int) (opcode >> 0) & 0xf);
3565                         break;
3566                 default:
3567                         return ERROR_COMMAND_SYNTAX_ERROR;
3568         }
3569
3570         return ERROR_OK;
3571 }
3572
3573 static int t2ev_ldm_stm(uint32_t opcode, uint32_t address,
3574                         struct arm_instruction *instruction, char *cp)
3575 {
3576         int rn = (opcode >> 16) & 0xf;
3577         int op = (opcode >> 22) & 0x6;
3578         int t = (opcode >> 21) & 1;
3579         unsigned registers = opcode & 0xffff;
3580         char *mode = "";
3581
3582         if (opcode & (1 << 20))
3583                 op |= 1;
3584
3585         switch (op) {
3586                 case 0:
3587                         mode = "DB";
3588                 /* FALL THROUGH */
3589                 case 6:
3590                         sprintf(cp, "SRS%s\tsp%s, #%d", mode,
3591                                 t ? "!" : "",
3592                                 (unsigned) (opcode & 0x1f));
3593                         return ERROR_OK;
3594                 case 1:
3595                         mode = "DB";
3596                 /* FALL THROUGH */
3597                 case 7:
3598                         sprintf(cp, "RFE%s\tr%d%s", mode,
3599                                 (unsigned) ((opcode >> 16) & 0xf),
3600                                 t ? "!" : "");
3601                         return ERROR_OK;
3602                 case 2:
3603                         sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : "");
3604                         break;
3605                 case 3:
3606                         if (rn == 13 && t)
3607                                 sprintf(cp, "POP.W\t");
3608                         else
3609                                 sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : "");
3610                         break;
3611                 case 4:
3612                         if (rn == 13 && t)
3613                                 sprintf(cp, "PUSH.W\t");
3614                         else
3615                                 sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : "");
3616                         break;
3617                 case 5:
3618                         sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : "");
3619                         break;
3620                 default:
3621                         return ERROR_COMMAND_SYNTAX_ERROR;
3622         }
3623
3624         cp = strchr(cp, 0);
3625         *cp++ = '{';
3626         for (t = 0; registers; t++, registers >>= 1) {
3627                 if ((registers & 1) == 0)
3628                         continue;
3629                 registers &= ~1;
3630                 sprintf(cp, "r%d%s", t, registers ? ", " : "");
3631                 cp = strchr(cp, 0);
3632         }
3633         *cp++ = '}';
3634         *cp++ = 0;
3635
3636         return ERROR_OK;
3637 }
3638
3639 /* load/store dual or exclusive, table branch */
3640 static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
3641                             struct arm_instruction *instruction, char *cp)
3642 {
3643         unsigned op1op2 = (opcode >> 20) & 0x3;
3644         unsigned op3 = (opcode >> 4) & 0xf;
3645         char *mnemonic;
3646         unsigned rn = (opcode >> 16) & 0xf;
3647         unsigned rt = (opcode >> 12) & 0xf;
3648         unsigned rd = (opcode >> 8) & 0xf;
3649         unsigned imm = opcode & 0xff;
3650         char *p1 = "";
3651         char *p2 = "]";
3652
3653         op1op2 |= (opcode >> 21) & 0xc;
3654         switch (op1op2) {
3655                 case 0:
3656                         mnemonic = "STREX";
3657                         goto strex;
3658                 case 1:
3659                         mnemonic = "LDREX";
3660                         goto ldrex;
3661                 case 2:
3662                 case 6:
3663                 case 8:
3664                 case 10:
3665                 case 12:
3666                 case 14:
3667                         mnemonic = "STRD";
3668                         goto immediate;
3669                 case 3:
3670                 case 7:
3671                 case 9:
3672                 case 11:
3673                 case 13:
3674                 case 15:
3675                         mnemonic = "LDRD";
3676                         if (rn == 15)
3677                                 goto literal;
3678                         else
3679                                 goto immediate;
3680                 case 4:
3681                         switch (op3) {
3682                                 case 4:
3683                                         mnemonic = "STREXB";
3684                                         break;
3685                                 case 5:
3686                                         mnemonic = "STREXH";
3687                                         break;
3688                                 default:
3689                                         return ERROR_COMMAND_SYNTAX_ERROR;
3690                         }
3691                         rd = opcode & 0xf;
3692                         imm = 0;
3693                         goto strex;
3694                 case 5:
3695                         switch (op3) {
3696                                 case 0:
3697                                         sprintf(cp, "TBB\t[r%u, r%u]", rn, imm & 0xf);
3698                                         return ERROR_OK;
3699                                 case 1:
3700                                         sprintf(cp, "TBH\t[r%u, r%u, LSL #1]", rn, imm & 0xf);
3701                                         return ERROR_OK;
3702                                 case 4:
3703                                         mnemonic = "LDREXB";
3704                                         break;
3705                                 case 5:
3706                                         mnemonic = "LDREXH";
3707                                         break;
3708                                 default:
3709                                         return ERROR_COMMAND_SYNTAX_ERROR;
3710                         }
3711                         imm = 0;
3712                         goto ldrex;
3713         }
3714         return ERROR_COMMAND_SYNTAX_ERROR;
3715
3716 strex:
3717         imm <<= 2;
3718         if (imm)
3719                 sprintf(cp, "%s\tr%u, r%u, [r%u, #%u]\t; %#2.2x",
3720                                 mnemonic, rd, rt, rn, imm, imm);
3721         else
3722                 sprintf(cp, "%s\tr%u, r%u, [r%u]",
3723                                 mnemonic, rd, rt, rn);
3724         return ERROR_OK;
3725
3726 ldrex:
3727         imm <<= 2;
3728         if (imm)
3729                 sprintf(cp, "%s\tr%u, [r%u, #%u]\t; %#2.2x",
3730                                 mnemonic, rt, rn, imm, imm);
3731         else
3732                 sprintf(cp, "%s\tr%u, [r%u]",
3733                                 mnemonic, rt, rn);
3734         return ERROR_OK;
3735
3736 immediate:
3737         /* two indexed modes will write back rn */
3738         if (opcode & (1 << 21)) {
3739                 if (opcode & (1 << 24)) /* pre-indexed */
3740                         p2 = "]!";
3741                 else {                  /* post-indexed */
3742                         p1 = "]";
3743                         p2 = "";
3744                 }
3745         }
3746
3747         imm <<= 2;
3748         sprintf(cp, "%s\tr%u, r%u, [r%u%s, #%s%u%s\t; %#2.2x",
3749                         mnemonic, rt, rd, rn, p1,
3750                         (opcode & (1 << 23)) ? "" : "-",
3751                         imm, p2, imm);
3752         return ERROR_OK;
3753
3754 literal:
3755         address = thumb_alignpc4(address);
3756         imm <<= 2;
3757         if (opcode & (1 << 23))
3758                 address += imm;
3759         else
3760                 address -= imm;
3761         sprintf(cp, "%s\tr%u, r%u, %#8.8" PRIx32,
3762                         mnemonic, rt, rd, address);
3763         return ERROR_OK;
3764 }
3765
3766 static int t2ev_data_shift(uint32_t opcode, uint32_t address,
3767                            struct arm_instruction *instruction, char *cp)
3768 {
3769         int op = (opcode >> 21) & 0xf;
3770         int rd = (opcode >> 8) & 0xf;
3771         int rn = (opcode >> 16) & 0xf;
3772         int type = (opcode >> 4) & 0x3;
3773         int immed = (opcode >> 6) & 0x3;
3774         char *mnemonic;
3775         char *suffix = "";
3776
3777         immed |= (opcode >> 10) & 0x1c;
3778         if (opcode & (1 << 20))
3779                 suffix = "S";
3780
3781         switch (op) {
3782                 case 0:
3783                         if (rd == 0xf) {
3784                                 if (!(opcode & (1 << 20)))
3785                                         return ERROR_COMMAND_SYNTAX_ERROR;
3786                                 instruction->type = ARM_TST;
3787                                 mnemonic = "TST";
3788                                 suffix = "";
3789                                 goto two;
3790                         }
3791                         instruction->type = ARM_AND;
3792                         mnemonic = "AND";
3793                         break;
3794                 case 1:
3795                         instruction->type = ARM_BIC;
3796                         mnemonic = "BIC";
3797                         break;
3798                 case 2:
3799                         if (rn == 0xf) {
3800                                 instruction->type = ARM_MOV;
3801                                 switch (type) {
3802                                         case 0:
3803                                                 if (immed == 0) {
3804                                                         sprintf(cp, "MOV%s.W\tr%d, r%d",
3805                                                                         suffix, rd,
3806                                                                         (int) (opcode & 0xf));
3807                                                         return ERROR_OK;
3808                                                 }
3809                                                 mnemonic = "LSL";
3810                                                 break;
3811                                         case 1:
3812                                                 mnemonic = "LSR";
3813                                                 break;
3814                                         case 2:
3815                                                 mnemonic = "ASR";
3816                                                 break;
3817                                         default:
3818                                                 if (immed == 0) {
3819                                                         sprintf(cp, "RRX%s\tr%d, r%d",
3820                                                                         suffix, rd,
3821                                                                         (int) (opcode & 0xf));
3822                                                         return ERROR_OK;
3823                                                 }
3824                                                 mnemonic = "ROR";
3825                                                 break;
3826                                 }
3827                                 goto immediate;
3828                         } else {
3829                                 instruction->type = ARM_ORR;
3830                                 mnemonic = "ORR";
3831                         }
3832                         break;
3833                 case 3:
3834                         if (rn == 0xf) {
3835                                 instruction->type = ARM_MVN;
3836                                 mnemonic = "MVN";
3837                                 rn = rd;
3838                                 goto two;
3839                         } else {
3840                                 /* instruction->type = ARM_ORN; */
3841                                 mnemonic = "ORN";
3842                         }
3843                         break;
3844                 case 4:
3845                         if (rd == 0xf) {
3846                                 if (!(opcode & (1 << 20)))
3847                                         return ERROR_COMMAND_SYNTAX_ERROR;
3848                                 instruction->type = ARM_TEQ;
3849                                 mnemonic = "TEQ";
3850                                 suffix = "";
3851                                 goto two;
3852                         }
3853                         instruction->type = ARM_EOR;
3854                         mnemonic = "EOR";
3855                         break;
3856                 case 8:
3857                         if (rd == 0xf) {
3858                                 if (!(opcode & (1 << 20)))
3859                                         return ERROR_COMMAND_SYNTAX_ERROR;
3860                                 instruction->type = ARM_CMN;
3861                                 mnemonic = "CMN";
3862                                 suffix = "";
3863                                 goto two;
3864                         }
3865                         instruction->type = ARM_ADD;
3866                         mnemonic = "ADD";
3867                         break;
3868                 case 0xa:
3869                         instruction->type = ARM_ADC;
3870                         mnemonic = "ADC";
3871                         break;
3872                 case 0xb:
3873                         instruction->type = ARM_SBC;
3874                         mnemonic = "SBC";
3875                         break;
3876                 case 0xd:
3877                         if (rd == 0xf) {
3878                                 if (!(opcode & (1 << 21)))
3879                                         return ERROR_COMMAND_SYNTAX_ERROR;
3880                                 instruction->type = ARM_CMP;
3881                                 mnemonic = "CMP";
3882                                 suffix = "";
3883                                 goto two;
3884                         }
3885                         instruction->type = ARM_SUB;
3886                         mnemonic = "SUB";
3887                         break;
3888                 case 0xe:
3889                         instruction->type = ARM_RSB;
3890                         mnemonic = "RSB";
3891                         break;
3892                 default:
3893                         return ERROR_COMMAND_SYNTAX_ERROR;
3894         }
3895
3896         sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
3897                         mnemonic, suffix, rd, rn, (int) (opcode & 0xf));
3898
3899 shift:
3900         cp = strchr(cp, 0);
3901
3902         switch (type) {
3903                 case 0:
3904                         if (immed == 0)
3905                                 return ERROR_OK;
3906                         suffix = "LSL";
3907                         break;
3908                 case 1:
3909                         suffix = "LSR";
3910                         if (immed == 32)
3911                                 immed = 0;
3912                         break;
3913                 case 2:
3914                         suffix = "ASR";
3915                         if (immed == 32)
3916                                 immed = 0;
3917                         break;
3918                 case 3:
3919                         if (immed == 0) {
3920                                 strcpy(cp, ", RRX");
3921                                 return ERROR_OK;
3922                         }
3923                         suffix = "ROR";
3924                         break;
3925         }
3926         sprintf(cp, ", %s #%d", suffix, immed ? immed : 32);
3927         return ERROR_OK;
3928
3929 two:
3930         sprintf(cp, "%s%s.W\tr%d, r%d",
3931                         mnemonic, suffix, rn, (int) (opcode & 0xf));
3932         goto shift;
3933
3934 immediate:
3935         sprintf(cp, "%s%s.W\tr%d, r%d, #%d",
3936                         mnemonic, suffix, rd,
3937                         (int) (opcode & 0xf), immed ? immed : 32);
3938         return ERROR_OK;
3939 }
3940
3941 static int t2ev_data_reg(uint32_t opcode, uint32_t address,
3942                          struct arm_instruction *instruction, char *cp)
3943 {
3944         char *mnemonic;
3945         char *suffix = "";
3946
3947         if (((opcode >> 4) & 0xf) == 0) {
3948                 switch ((opcode >> 21) & 0x7) {
3949                         case 0:
3950                                 mnemonic = "LSL";
3951                                 break;
3952                         case 1:
3953                                 mnemonic = "LSR";
3954                                 break;
3955                         case 2:
3956                                 mnemonic = "ASR";
3957                                 break;
3958                         case 3:
3959                                 mnemonic = "ROR";
3960                                 break;
3961                         default:
3962                                 return ERROR_COMMAND_SYNTAX_ERROR;
3963                 }
3964
3965                 instruction->type = ARM_MOV;
3966                 if (opcode & (1 << 20))
3967                         suffix = "S";
3968                 sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
3969                                 mnemonic, suffix,
3970                                 (int) (opcode >> 8) & 0xf,
3971                                 (int) (opcode >> 16) & 0xf,
3972                                 (int) (opcode >> 0) & 0xf);
3973
3974         } else if (opcode & (1 << 7)) {
3975                 switch ((opcode >> 20) & 0xf) {
3976                         case 0:
3977                         case 1:
3978                         case 4:
3979                         case 5:
3980                                 switch ((opcode >> 4) & 0x3) {
3981                                         case 1:
3982                                                 suffix = ", ROR #8";
3983                                                 break;
3984                                         case 2:
3985                                                 suffix = ", ROR #16";
3986                                                 break;
3987                                         case 3:
3988                                                 suffix = ", ROR #24";
3989                                                 break;
3990                                 }
3991                                 sprintf(cp, "%cXT%c.W\tr%d, r%d%s",
3992                                         (opcode & (1 << 24)) ? 'U' : 'S',
3993                                         (opcode & (1 << 26)) ? 'B' : 'H',
3994                                         (int) (opcode >> 8) & 0xf,
3995                                         (int) (opcode >> 0) & 0xf,
3996                                         suffix);
3997                                 break;
3998                         case 8:
3999                         case 9:
4000                         case 0xa:
4001                         case 0xb:
4002                                 if (opcode & (1 << 6))
4003                                         return ERROR_COMMAND_SYNTAX_ERROR;
4004                                 if (((opcode >> 12) & 0xf) != 0xf)
4005                                         return ERROR_COMMAND_SYNTAX_ERROR;
4006                                 if (!(opcode & (1 << 20)))
4007                                         return ERROR_COMMAND_SYNTAX_ERROR;
4008
4009                                 switch (((opcode >> 19) & 0x04)
4010                                         | ((opcode >> 4) & 0x3)) {
4011                                         case 0:
4012                                                 mnemonic = "REV.W";
4013                                                 break;
4014                                         case 1:
4015                                                 mnemonic = "REV16.W";
4016                                                 break;
4017                                         case 2:
4018                                                 mnemonic = "RBIT";
4019                                                 break;
4020                                         case 3:
4021                                                 mnemonic = "REVSH.W";
4022                                                 break;
4023                                         case 4:
4024                                                 mnemonic = "CLZ";
4025                                                 break;
4026                                         default:
4027                                                 return ERROR_COMMAND_SYNTAX_ERROR;
4028                                 }
4029                                 sprintf(cp, "%s\tr%d, r%d",
4030                                         mnemonic,
4031                                         (int) (opcode >> 8) & 0xf,
4032                                         (int) (opcode >> 0) & 0xf);
4033                                 break;
4034                         default:
4035                                 return ERROR_COMMAND_SYNTAX_ERROR;
4036                 }
4037         }
4038
4039         return ERROR_OK;
4040 }
4041
4042 static int t2ev_load_word(uint32_t opcode, uint32_t address,
4043                           struct arm_instruction *instruction, char *cp)
4044 {
4045         int rn = (opcode >> 16) & 0xf;
4046         int immed;
4047
4048         instruction->type = ARM_LDR;
4049
4050         if (rn == 0xf) {
4051                 immed = opcode & 0x0fff;
4052                 if ((opcode & (1 << 23)) == 0)
4053                         immed = -immed;
4054                 sprintf(cp, "LDR\tr%d, %#8.8" PRIx32,
4055                                 (int) (opcode >> 12) & 0xf,
4056                                 thumb_alignpc4(address) + immed);
4057                 return ERROR_OK;
4058         }
4059
4060         if (opcode & (1 << 23)) {
4061                 immed = opcode & 0x0fff;
4062                 sprintf(cp, "LDR.W\tr%d, [r%d, #%d]\t; %#3.3x",
4063                                 (int) (opcode >> 12) & 0xf,
4064                                 rn, immed, immed);
4065                 return ERROR_OK;
4066         }
4067
4068         if (!(opcode & (0x3f << 6))) {
4069                 sprintf(cp, "LDR.W\tr%d, [r%d, r%d, LSL #%d]",
4070                                 (int) (opcode >> 12) & 0xf,
4071                                 rn,
4072                                 (int) (opcode >> 0) & 0xf,
4073                                 (int) (opcode >> 4) & 0x3);
4074                 return ERROR_OK;
4075         }
4076
4077
4078         if (((opcode >> 8) & 0xf) == 0xe) {
4079                 immed = opcode & 0x00ff;
4080
4081                 sprintf(cp, "LDRT\tr%d, [r%d, #%d]\t; %#2.2x",
4082                                 (int) (opcode >> 12) & 0xf,
4083                                 rn, immed, immed);
4084                 return ERROR_OK;
4085         }
4086
4087         if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) {
4088                 char *p1 = "]", *p2 = "";
4089
4090                 if (!(opcode & 0x0500))
4091                         return ERROR_COMMAND_SYNTAX_ERROR;
4092
4093                 immed = opcode & 0x00ff;
4094
4095                 /* two indexed modes will write back rn */
4096                 if (opcode & 0x100) {
4097                         if (opcode & 0x400)     /* pre-indexed */
4098                                 p2 = "]!";
4099                         else {                  /* post-indexed */
4100                                 p1 = "]";
4101                                 p2 = "";
4102                         }
4103                 }
4104
4105                 sprintf(cp, "LDR\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
4106                                 (int) (opcode >> 12) & 0xf,
4107                                 rn, p1,
4108                                 (opcode & 0x200) ? "" : "-",
4109                                 immed, p2, immed);
4110                 return ERROR_OK;
4111         }
4112
4113         return ERROR_COMMAND_SYNTAX_ERROR;
4114 }
4115
4116 static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address,
4117                                 struct arm_instruction *instruction, char *cp)
4118 {
4119         int rn = (opcode >> 16) & 0xf;
4120         int rt = (opcode >> 12) & 0xf;
4121         int op2 = (opcode >> 6) & 0x3f;
4122         unsigned immed;
4123         char *p1 = "", *p2 = "]";
4124         char *mnemonic;
4125
4126         switch ((opcode >> 23) & 0x3) {
4127                 case 0:
4128                         if ((rn & rt) == 0xf) {
4129 pld_literal:
4130                                 immed = opcode & 0xfff;
4131                                 address = thumb_alignpc4(address);
4132                                 if (opcode & (1 << 23))
4133                                         address += immed;
4134                                 else
4135                                         address -= immed;
4136                                 sprintf(cp, "PLD\tr%d, %#8.8" PRIx32,
4137                                                 rt, address);
4138                                 return ERROR_OK;
4139                         }
4140                         if (rn == 0x0f && rt != 0x0f) {
4141 ldrb_literal:
4142                                 immed = opcode & 0xfff;
4143                                 address = thumb_alignpc4(address);
4144                                 if (opcode & (1 << 23))
4145                                         address += immed;
4146                                 else
4147                                         address -= immed;
4148                                 sprintf(cp, "LDRB\tr%d, %#8.8" PRIx32,
4149                                                 rt, address);
4150                                 return ERROR_OK;
4151                         }
4152                         if (rn == 0x0f)
4153                                 break;
4154                         if ((op2 & 0x3c) == 0x38) {
4155                                 immed = opcode & 0xff;
4156                                 sprintf(cp, "LDRBT\tr%d, [r%d, #%d]\t; %#2.2x",
4157                                                 rt, rn, immed, immed);
4158                                 return ERROR_OK;
4159                         }
4160                         if ((op2 & 0x3c) == 0x30) {
4161                                 if (rt == 0x0f) {
4162                                         immed = opcode & 0xff;
4163                                         immed = -immed;
4164 preload_immediate:
4165                                         p1 = (opcode & (1 << 21)) ? "W" : "";
4166                                         sprintf(cp, "PLD%s\t[r%d, #%d]\t; %#6.6x",
4167                                                         p1, rn, immed, immed);
4168                                         return ERROR_OK;
4169                                 }
4170                                 mnemonic = "LDRB";
4171 ldrxb_immediate_t3:
4172                                 immed = opcode & 0xff;
4173                                 if (!(opcode & 0x200))
4174                                         immed = -immed;
4175
4176                                 /* two indexed modes will write back rn */
4177                                 if (opcode & 0x100) {
4178                                         if (opcode & 0x400)     /* pre-indexed */
4179                                                 p2 = "]!";
4180                                         else {          /* post-indexed */
4181                                                 p1 = "]";
4182                                                 p2 = "";
4183                                         }
4184                                 }
4185 ldrxb_immediate_t2:
4186                                 sprintf(cp, "%s\tr%d, [r%d%s, #%d%s\t; %#8.8x",
4187                                                 mnemonic, rt, rn, p1,
4188                                                 immed, p2, immed);
4189                                 return ERROR_OK;
4190                         }
4191                         if ((op2 & 0x24) == 0x24) {
4192                                 mnemonic = "LDRB";
4193                                 goto ldrxb_immediate_t3;
4194                         }
4195                         if (op2 == 0) {
4196                                 int rm = opcode & 0xf;
4197
4198                                 if (rt == 0x0f)
4199                                         sprintf(cp, "PLD\t");
4200                                 else
4201                                         sprintf(cp, "LDRB.W\tr%d, ", rt);
4202                                 immed = (opcode >> 4) & 0x3;
4203                                 cp = strchr(cp, 0);
4204                                 sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
4205                                 return ERROR_OK;
4206                         }
4207                         break;
4208                 case 1:
4209                         if ((rn & rt) == 0xf)
4210                                 goto pld_literal;
4211                         if (rt == 0xf) {
4212                                 immed = opcode & 0xfff;
4213                                 goto preload_immediate;
4214                         }
4215                         if (rn == 0x0f)
4216                                 goto ldrb_literal;
4217                         mnemonic = "LDRB.W";
4218                         immed = opcode & 0xfff;
4219                         goto ldrxb_immediate_t2;
4220                 case 2:
4221                         if ((rn & rt) == 0xf) {
4222                                 immed = opcode & 0xfff;
4223                                 address = thumb_alignpc4(address);
4224                                 if (opcode & (1 << 23))
4225                                         address += immed;
4226                                 else
4227                                         address -= immed;
4228                                 sprintf(cp, "PLI\t%#8.8" PRIx32, address);
4229                                 return ERROR_OK;
4230                         }
4231                         if (rn == 0xf && rt != 0xf) {
4232 ldrsb_literal:
4233                                 immed = opcode & 0xfff;
4234                                 address = thumb_alignpc4(address);
4235                                 if (opcode & (1 << 23))
4236                                         address += immed;
4237                                 else
4238                                         address -= immed;
4239                                 sprintf(cp, "LDRSB\t%#8.8" PRIx32, address);
4240                                 return ERROR_OK;
4241                         }
4242                         if (rn == 0xf)
4243                                 break;
4244                         if ((op2 & 0x3c) == 0x38) {
4245                                 immed = opcode & 0xff;
4246                                 sprintf(cp, "LDRSBT\tr%d, [r%d, #%d]\t; %#2.2x",
4247                                                 rt, rn, immed, immed);
4248                                 return ERROR_OK;
4249                         }
4250                         if ((op2 & 0x3c) == 0x30) {
4251                                 if (rt == 0xf) {
4252                                         immed = opcode & 0xff;
4253                                         immed = -immed; /* pli */
4254                                         sprintf(cp, "PLI\t[r%d, #%d]\t; -%#2.2x",
4255                                                         rn, immed, -immed);
4256                                         return ERROR_OK;
4257                                 }
4258                                 mnemonic = "LDRSB";
4259                                 goto ldrxb_immediate_t3;
4260                         }
4261                         if ((op2 & 0x24) == 0x24) {
4262                                 mnemonic = "LDRSB";
4263                                 goto ldrxb_immediate_t3;
4264                         }
4265                         if (op2 == 0) {
4266                                 int rm = opcode & 0xf;
4267
4268                                 if (rt == 0x0f)
4269                                         sprintf(cp, "PLI\t");
4270                                 else
4271                                         sprintf(cp, "LDRSB.W\tr%d, ", rt);
4272                                 immed = (opcode >> 4) & 0x3;
4273                                 cp = strchr(cp, 0);
4274                                 sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
4275                                 return ERROR_OK;
4276                         }
4277                         break;
4278                 case 3:
4279                         if (rt == 0xf) {
4280                                 immed = opcode & 0xfff;
4281                                 sprintf(cp, "PLI\t[r%d, #%d]\t; %#3.3x",
4282                                                 rn, immed, immed);
4283                                 return ERROR_OK;
4284                         }
4285                         if (rn == 0xf)
4286                                 goto ldrsb_literal;
4287                         immed = opcode & 0xfff;
4288                         mnemonic = "LDRSB";
4289                         goto ldrxb_immediate_t2;
4290         }
4291
4292         return ERROR_COMMAND_SYNTAX_ERROR;
4293 }
4294
4295 static int t2ev_load_halfword(uint32_t opcode, uint32_t address,
4296                               struct arm_instruction *instruction, char *cp)
4297 {
4298         int rn = (opcode >> 16) & 0xf;
4299         int rt = (opcode >> 12) & 0xf;
4300         int op2 = (opcode >> 6) & 0x3f;
4301         char *sign = "";
4302         unsigned immed;
4303
4304         if (rt == 0xf) {
4305                 sprintf(cp, "HINT (UNALLOCATED)");
4306                 return ERROR_OK;
4307         }
4308
4309         if (opcode & (1 << 24))
4310                 sign = "S";
4311
4312         if ((opcode & (1 << 23)) == 0) {
4313                 if (rn == 0xf) {
4314 ldrh_literal:
4315                         immed = opcode & 0xfff;
4316                         address = thumb_alignpc4(address);
4317                         if (opcode & (1 << 23))
4318                                 address += immed;
4319                         else
4320                                 address -= immed;
4321                         sprintf(cp, "LDR%sH\tr%d, %#8.8" PRIx32,
4322                                         sign, rt, address);
4323                         return ERROR_OK;
4324                 }
4325                 if (op2 == 0) {
4326                         int rm = opcode & 0xf;
4327
4328                         immed = (opcode >> 4) & 0x3;
4329                         sprintf(cp, "LDR%sH.W\tr%d, [r%d, r%d, LSL #%d]",
4330                                         sign, rt, rn, rm, immed);
4331                         return ERROR_OK;
4332                 }
4333                 if ((op2 & 0x3c) == 0x38) {
4334                         immed = opcode & 0xff;
4335                         sprintf(cp, "LDR%sHT\tr%d, [r%d, #%d]\t; %#2.2x",
4336                                         sign, rt, rn, immed, immed);
4337                         return ERROR_OK;
4338                 }
4339                 if ((op2 & 0x3c) == 0x30 || (op2 & 0x24) == 0x24) {
4340                         char *p1 = "", *p2 = "]";
4341
4342                         immed = opcode & 0xff;
4343                         if (!(opcode & 0x200))
4344                                 immed = -immed;
4345
4346                         /* two indexed modes will write back rn */
4347                         if (opcode & 0x100) {
4348                                 if (opcode & 0x400)     /* pre-indexed */
4349                                         p2 = "]!";
4350                                 else {                  /* post-indexed */
4351                                         p1 = "]";
4352                                         p2 = "";
4353                                 }
4354                         }
4355                         sprintf(cp, "LDR%sH\tr%d, [r%d%s, #%d%s\t; %#8.8x",
4356                                         sign, rt, rn, p1, immed, p2, immed);
4357                         return ERROR_OK;
4358                 }
4359         } else {
4360                 if (rn == 0xf)
4361                         goto ldrh_literal;
4362
4363                 immed = opcode & 0xfff;
4364                 sprintf(cp, "LDR%sH%s\tr%d, [r%d, #%d]\t; %#6.6x",
4365                                 sign, *sign ? "" : ".W",
4366                                 rt, rn, immed, immed);
4367                 return ERROR_OK;
4368         }
4369
4370         return ERROR_COMMAND_SYNTAX_ERROR;
4371 }
4372
4373 /*
4374  * REVISIT for Thumb2 instructions, instruction->type and friends aren't
4375  * always set.  That means eventual arm_simulate_step() support for Thumb2
4376  * will need work in this area.
4377  */
4378 int thumb2_opcode(struct target *target, uint32_t address, struct arm_instruction *instruction)
4379 {
4380         int retval;
4381         uint16_t op;
4382         uint32_t opcode;
4383         char *cp;
4384
4385         /* clear low bit ... it's set on function pointers */
4386         address &= ~1;
4387
4388         /* clear fields, to avoid confusion */
4389         memset(instruction, 0, sizeof(struct arm_instruction));
4390
4391         /* read first halfword, see if this is the only one */
4392         retval = target_read_u16(target, address, &op);
4393         if (retval != ERROR_OK)
4394                 return retval;
4395
4396         switch (op & 0xf800) {
4397                 case 0xf800:
4398                 case 0xf000:
4399                 case 0xe800:
4400                         /* 32-bit instructions */
4401                         instruction->instruction_size = 4;
4402                         opcode = op << 16;
4403                         retval = target_read_u16(target, address + 2, &op);
4404                         if (retval != ERROR_OK)
4405                                 return retval;
4406                         opcode |= op;
4407                         instruction->opcode = opcode;
4408                         break;
4409                 default:
4410                         /* 16-bit:  Thumb1 + IT + CBZ/CBNZ + ... */
4411                         return thumb_evaluate_opcode(op, address, instruction);
4412         }
4413
4414         snprintf(instruction->text, 128,
4415                         "0x%8.8" PRIx32 "  0x%8.8" PRIx32 "\t",
4416                         address, opcode);
4417         cp = strchr(instruction->text, 0);
4418         retval = ERROR_FAIL;
4419
4420         /* ARMv7-M: A5.3.1 Data processing (modified immediate) */
4421         if ((opcode & 0x1a008000) == 0x10000000)
4422                 retval = t2ev_data_mod_immed(opcode, address, instruction, cp);
4423
4424         /* ARMv7-M: A5.3.3 Data processing (plain binary immediate) */
4425         else if ((opcode & 0x1a008000) == 0x12000000)
4426                 retval = t2ev_data_immed(opcode, address, instruction, cp);
4427
4428         /* ARMv7-M: A5.3.4 Branches and miscellaneous control */
4429         else if ((opcode & 0x18008000) == 0x10008000)
4430                 retval = t2ev_b_misc(opcode, address, instruction, cp);
4431
4432         /* ARMv7-M: A5.3.5 Load/store multiple */
4433         else if ((opcode & 0x1e400000) == 0x08000000)
4434                 retval = t2ev_ldm_stm(opcode, address, instruction, cp);
4435
4436         /* ARMv7-M: A5.3.6 Load/store dual or exclusive, table branch */
4437         else if ((opcode & 0x1e400000) == 0x08400000)
4438                 retval = t2ev_ldrex_strex(opcode, address, instruction, cp);
4439
4440         /* ARMv7-M: A5.3.7 Load word */
4441         else if ((opcode & 0x1f700000) == 0x18500000)
4442                 retval = t2ev_load_word(opcode, address, instruction, cp);
4443
4444         /* ARMv7-M: A5.3.8 Load halfword, unallocated memory hints */
4445         else if ((opcode & 0x1e700000) == 0x18300000)
4446                 retval = t2ev_load_halfword(opcode, address, instruction, cp);
4447
4448         /* ARMv7-M: A5.3.9 Load byte, memory hints */
4449         else if ((opcode & 0x1e700000) == 0x18100000)
4450                 retval = t2ev_load_byte_hints(opcode, address, instruction, cp);
4451
4452         /* ARMv7-M: A5.3.10 Store single data item */
4453         else if ((opcode & 0x1f100000) == 0x18000000)
4454                 retval = t2ev_store_single(opcode, address, instruction, cp);
4455
4456         /* ARMv7-M: A5.3.11 Data processing (shifted register) */
4457         else if ((opcode & 0x1e000000) == 0x0a000000)
4458                 retval = t2ev_data_shift(opcode, address, instruction, cp);
4459
4460         /* ARMv7-M: A5.3.12 Data processing (register)
4461          * and A5.3.13 Miscellaneous operations
4462          */
4463         else if ((opcode & 0x1f000000) == 0x1a000000)
4464                 retval = t2ev_data_reg(opcode, address, instruction, cp);
4465
4466         /* ARMv7-M: A5.3.14 Multiply, and multiply accumulate */
4467         else if ((opcode & 0x1f800000) == 0x1b000000)
4468                 retval = t2ev_mul32(opcode, address, instruction, cp);
4469
4470         /* ARMv7-M: A5.3.15 Long multiply, long multiply accumulate, divide */
4471         else if ((opcode & 0x1f800000) == 0x1b800000)
4472                 retval = t2ev_mul64_div(opcode, address, instruction, cp);
4473
4474         if (retval == ERROR_OK)
4475                 return retval;
4476
4477         /*
4478          * Thumb2 also supports coprocessor, ThumbEE, and DSP/Media (SIMD)
4479          * instructions; not yet handled here.
4480          */
4481
4482         if (retval == ERROR_COMMAND_SYNTAX_ERROR) {
4483                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
4484                 strcpy(cp, "UNDEFINED OPCODE");
4485                 return ERROR_OK;
4486         }
4487
4488         LOG_DEBUG("Can't decode 32-bit Thumb2 yet (opcode=%08" PRIx32 ")",
4489                         opcode);
4490
4491         strcpy(cp, "(32-bit Thumb2 ...)");
4492         return ERROR_OK;
4493 }
4494
4495 int arm_access_size(struct arm_instruction *instruction)
4496 {
4497         if ((instruction->type == ARM_LDRB)
4498             || (instruction->type == ARM_LDRBT)
4499             || (instruction->type == ARM_LDRSB)
4500             || (instruction->type == ARM_STRB)
4501             || (instruction->type == ARM_STRBT))
4502                 return 1;
4503         else if ((instruction->type == ARM_LDRH)
4504                  || (instruction->type == ARM_LDRSH)
4505                  || (instruction->type == ARM_STRH))
4506                 return 2;
4507         else if ((instruction->type == ARM_LDR)
4508                  || (instruction->type == ARM_LDRT)
4509                  || (instruction->type == ARM_STR)
4510                  || (instruction->type == ARM_STRT))
4511                 return 4;
4512         else if ((instruction->type == ARM_LDRD)
4513                  || (instruction->type == ARM_STRD))
4514                 return 8;
4515         else {
4516                 LOG_ERROR("BUG: instruction type %i isn't a load/store instruction",
4517                                 instruction->type);
4518                 return 0;
4519         }
4520 }