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