Fix warnings exposed by GCC8
[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) == 0x00200000) && (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) == 0x00600000) {
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) == 0x00200000) && (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                 address &= 0xfffffffc;
2982                 break;
2983         case 0x5:
2984                 inst = "BL";
2985                 instruction->type = ARM_BL;
2986                 break;
2987         default:
2988                 return ERROR_COMMAND_SYNTAX_ERROR;
2989         }
2990         instruction->info.b_bl_bx_blx.reg_operand = -1;
2991         instruction->info.b_bl_bx_blx.target_address = address;
2992         sprintf(cp, "%s\t%#8.8" PRIx32, inst, address);
2993
2994         return ERROR_OK;
2995 }
2996
2997 static int t2ev_cond_b(uint32_t opcode, uint32_t address,
2998                        struct arm_instruction *instruction, char *cp)
2999 {
3000         unsigned offset;
3001         unsigned b17 = 1 << 17;
3002         unsigned b18 = 1 << 18;
3003         unsigned cond = (opcode >> 22) & 0x0f;
3004
3005         offset = opcode & 0x7ff;
3006         offset |= (opcode & 0x003f0000) >> 5;
3007         if (opcode & (1 << 26)) {
3008                 offset |= 0x1fff << 19;
3009                 if ((opcode & (1 << 11)) == 0)
3010                         b17 = 0;
3011                 if ((opcode & (1 << 13)) == 0)
3012                         b18 = 0;
3013         } else {
3014                 if (opcode & (1 << 11))
3015                         b17 = 0;
3016                 if (opcode & (1 << 13))
3017                         b18 = 0;
3018         }
3019         offset |= b17;
3020         offset |= b18;
3021
3022         address += 4;
3023         address += offset << 1;
3024
3025         instruction->type = ARM_B;
3026         instruction->info.b_bl_bx_blx.reg_operand = -1;
3027         instruction->info.b_bl_bx_blx.target_address = address;
3028         sprintf(cp, "B%s.W\t%#8.8" PRIx32,
3029                         arm_condition_strings[cond],
3030                         address);
3031
3032         return ERROR_OK;
3033 }
3034
3035 static const char *special_name(int number)
3036 {
3037         char *special = "(RESERVED)";
3038
3039         switch (number) {
3040                 case 0:
3041                         special = "apsr";
3042                         break;
3043                 case 1:
3044                         special = "iapsr";
3045                         break;
3046                 case 2:
3047                         special = "eapsr";
3048                         break;
3049                 case 3:
3050                         special = "xpsr";
3051                         break;
3052                 case 5:
3053                         special = "ipsr";
3054                         break;
3055                 case 6:
3056                         special = "epsr";
3057                         break;
3058                 case 7:
3059                         special = "iepsr";
3060                         break;
3061                 case 8:
3062                         special = "msp";
3063                         break;
3064                 case 9:
3065                         special = "psp";
3066                         break;
3067                 case 16:
3068                         special = "primask";
3069                         break;
3070                 case 17:
3071                         special = "basepri";
3072                         break;
3073                 case 18:
3074                         special = "basepri_max";
3075                         break;
3076                 case 19:
3077                         special = "faultmask";
3078                         break;
3079                 case 20:
3080                         special = "control";
3081                         break;
3082         }
3083         return special;
3084 }
3085
3086 static int t2ev_hint(uint32_t opcode, uint32_t address,
3087                      struct arm_instruction *instruction, char *cp)
3088 {
3089         const char *mnemonic;
3090
3091         if (opcode & 0x0700) {
3092                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3093                 strcpy(cp, "UNDEFINED");
3094                 return ERROR_OK;
3095         }
3096
3097         if (opcode & 0x00f0) {
3098                 sprintf(cp, "DBG\t#%d", (int) opcode & 0xf);
3099                 return ERROR_OK;
3100         }
3101
3102         switch (opcode & 0x0f) {
3103                 case 0:
3104                         mnemonic = "NOP.W";
3105                         break;
3106                 case 1:
3107                         mnemonic = "YIELD.W";
3108                         break;
3109                 case 2:
3110                         mnemonic = "WFE.W";
3111                         break;
3112                 case 3:
3113                         mnemonic = "WFI.W";
3114                         break;
3115                 case 4:
3116                         mnemonic = "SEV.W";
3117                         break;
3118                 default:
3119                         mnemonic = "HINT.W (UNRECOGNIZED)";
3120                         break;
3121         }
3122         strcpy(cp, mnemonic);
3123         return ERROR_OK;
3124 }
3125
3126 static int t2ev_misc(uint32_t opcode, uint32_t address,
3127                      struct arm_instruction *instruction, char *cp)
3128 {
3129         const char *mnemonic;
3130
3131         switch ((opcode >> 4) & 0x0f) {
3132                 case 0:
3133                         mnemonic = "LEAVEX";
3134                         break;
3135                 case 1:
3136                         mnemonic = "ENTERX";
3137                         break;
3138                 case 2:
3139                         mnemonic = "CLREX";
3140                         break;
3141                 case 4:
3142                         mnemonic = "DSB";
3143                         break;
3144                 case 5:
3145                         mnemonic = "DMB";
3146                         break;
3147                 case 6:
3148                         mnemonic = "ISB";
3149                         break;
3150                 default:
3151                         return ERROR_COMMAND_SYNTAX_ERROR;
3152         }
3153         strcpy(cp, mnemonic);
3154         return ERROR_OK;
3155 }
3156
3157 static int t2ev_b_misc(uint32_t opcode, uint32_t address,
3158                        struct arm_instruction *instruction, char *cp)
3159 {
3160         /* permanently undefined */
3161         if ((opcode & 0x07f07000) == 0x07f02000) {
3162                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3163                 strcpy(cp, "UNDEFINED");
3164                 return ERROR_OK;
3165         }
3166
3167         switch ((opcode >> 12) & 0x5) {
3168                 case 0x1:
3169                 case 0x4:
3170                 case 0x5:
3171                         return t2ev_b_bl(opcode, address, instruction, cp);
3172                 case 0:
3173                         if (((opcode >> 23) & 0x07) != 0x07)
3174                                 return t2ev_cond_b(opcode, address, instruction, cp);
3175                         if (opcode & (1 << 26))
3176                                 goto undef;
3177                         break;
3178         }
3179
3180         switch ((opcode >> 20) & 0x7f) {
3181                 case 0x38:
3182                 case 0x39:
3183                         sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff),
3184                                 (int) (opcode >> 16) & 0x0f);
3185                         return ERROR_OK;
3186                 case 0x3a:
3187                         return t2ev_hint(opcode, address, instruction, cp);
3188                 case 0x3b:
3189                         return t2ev_misc(opcode, address, instruction, cp);
3190                 case 0x3c:
3191                         sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f);
3192                         return ERROR_OK;
3193                 case 0x3e:
3194                 case 0x3f:
3195                         sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f,
3196                                 special_name(opcode & 0xff));
3197                         return ERROR_OK;
3198         }
3199
3200 undef:
3201         return ERROR_COMMAND_SYNTAX_ERROR;
3202 }
3203
3204 static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
3205                                struct arm_instruction *instruction, char *cp)
3206 {
3207         char *mnemonic = NULL;
3208         int rn = (opcode >> 16) & 0xf;
3209         int rd = (opcode >> 8) & 0xf;
3210         unsigned immed = opcode & 0xff;
3211         unsigned func;
3212         bool one = false;
3213         char *suffix = "";
3214         char *suffix2 = "";
3215
3216         /* ARMv7-M: A5.3.2 Modified immediate constants */
3217         func = (opcode >> 11) & 0x0e;
3218         if (immed & 0x80)
3219                 func |= 1;
3220         if (opcode & (1 << 26))
3221                 func |= 0x10;
3222
3223         /* "Modified" immediates */
3224         switch (func >> 1) {
3225                 case 0:
3226                         break;
3227                 case 2:
3228                         immed <<= 8;
3229                 /* FALLTHROUGH */
3230                 case 1:
3231                         immed += immed << 16;
3232                         break;
3233                 case 3:
3234                         immed += immed << 8;
3235                         immed += immed << 16;
3236                         break;
3237                 default:
3238                         immed |= 0x80;
3239                         immed = ror(immed, func);
3240         }
3241
3242         if (opcode & (1 << 20))
3243                 suffix = "S";
3244
3245         switch ((opcode >> 21) & 0xf) {
3246                 case 0:
3247                         if (rd == 0xf) {
3248                                 instruction->type = ARM_TST;
3249                                 mnemonic = "TST";
3250                                 one = true;
3251                                 suffix = "";
3252                                 rd = rn;
3253                         } else {
3254                                 instruction->type = ARM_AND;
3255                                 mnemonic = "AND";
3256                         }
3257                         break;
3258                 case 1:
3259                         instruction->type = ARM_BIC;
3260                         mnemonic = "BIC";
3261                         break;
3262                 case 2:
3263                         if (rn == 0xf) {
3264                                 instruction->type = ARM_MOV;
3265                                 mnemonic = "MOV";
3266                                 one = true;
3267                                 suffix2 = ".W";
3268                         } else {
3269                                 instruction->type = ARM_ORR;
3270                                 mnemonic = "ORR";
3271                         }
3272                         break;
3273                 case 3:
3274                         if (rn == 0xf) {
3275                                 instruction->type = ARM_MVN;
3276                                 mnemonic = "MVN";
3277                                 one = true;
3278                         } else {
3279                                 /* instruction->type = ARM_ORN; */
3280                                 mnemonic = "ORN";
3281                         }
3282                         break;
3283                 case 4:
3284                         if (rd == 0xf) {
3285                                 instruction->type = ARM_TEQ;
3286                                 mnemonic = "TEQ";
3287                                 one = true;
3288                                 suffix = "";
3289                                 rd = rn;
3290                         } else {
3291                                 instruction->type = ARM_EOR;
3292                                 mnemonic = "EOR";
3293                         }
3294                         break;
3295                 case 8:
3296                         if (rd == 0xf) {
3297                                 instruction->type = ARM_CMN;
3298                                 mnemonic = "CMN";
3299                                 one = true;
3300                                 suffix = "";
3301                                 rd = rn;
3302                         } else {
3303                                 instruction->type = ARM_ADD;
3304                                 mnemonic = "ADD";
3305                                 suffix2 = ".W";
3306                         }
3307                         break;
3308                 case 10:
3309                         instruction->type = ARM_ADC;
3310                         mnemonic = "ADC";
3311                         suffix2 = ".W";
3312                         break;
3313                 case 11:
3314                         instruction->type = ARM_SBC;
3315                         mnemonic = "SBC";
3316                         break;
3317                 case 13:
3318                         if (rd == 0xf) {
3319                                 instruction->type = ARM_CMP;
3320                                 mnemonic = "CMP";
3321                                 one = true;
3322                                 suffix = "";
3323                                 rd = rn;
3324                         } else {
3325                                 instruction->type = ARM_SUB;
3326                                 mnemonic = "SUB";
3327                         }
3328                         suffix2 = ".W";
3329                         break;
3330                 case 14:
3331                         instruction->type = ARM_RSB;
3332                         mnemonic = "RSB";
3333                         suffix2 = ".W";
3334                         break;
3335                 default:
3336                         return ERROR_COMMAND_SYNTAX_ERROR;
3337         }
3338
3339         if (one)
3340                 sprintf(cp, "%s%s\tr%d, #%d\t; %#8.8x",
3341                                 mnemonic, suffix2, rd, immed, immed);
3342         else
3343                 sprintf(cp, "%s%s%s\tr%d, r%d, #%d\t; %#8.8x",
3344                                 mnemonic, suffix, suffix2,
3345                                 rd, rn, immed, immed);
3346
3347         return ERROR_OK;
3348 }
3349
3350 static int t2ev_data_immed(uint32_t opcode, uint32_t address,
3351                            struct arm_instruction *instruction, char *cp)
3352 {
3353         char *mnemonic = NULL;
3354         int rn = (opcode >> 16) & 0xf;
3355         int rd = (opcode >> 8) & 0xf;
3356         unsigned immed;
3357         bool add = false;
3358         bool is_signed = false;
3359
3360         immed = (opcode & 0x0ff) | ((opcode & 0x7000) >> 4);
3361         if (opcode & (1 << 26))
3362                 immed |= (1 << 11);
3363
3364         switch ((opcode >> 20) & 0x1f) {
3365                 case 0:
3366                         if (rn == 0xf) {
3367                                 add = true;
3368                                 goto do_adr;
3369                         }
3370                         mnemonic = "ADDW";
3371                         break;
3372                 case 4:
3373                         immed |= (opcode >> 4) & 0xf000;
3374                         sprintf(cp, "MOVW\tr%d, #%d\t; %#3.3x", rd, immed, immed);
3375                         return ERROR_OK;
3376                 case 0x0a:
3377                         if (rn == 0xf)
3378                                 goto do_adr;
3379                         mnemonic = "SUBW";
3380                         break;
3381                 case 0x0c:
3382                         /* move constant to top 16 bits of register */
3383                         immed |= (opcode >> 4) & 0xf000;
3384                         sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed);
3385                         return ERROR_OK;
3386                 case 0x10:
3387                 case 0x12:
3388                         is_signed = true;
3389                         /* fallthrough */
3390                 case 0x18:
3391                 case 0x1a:
3392                         /* signed/unsigned saturated add */
3393                         immed = (opcode >> 6) & 0x03;
3394                         immed |= (opcode >> 10) & 0x1c;
3395                         sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t",
3396                                 is_signed ? "S" : "U",
3397                                 rd, (int) (opcode & 0x1f) + is_signed, rn,
3398                                 (opcode & (1 << 21)) ? "ASR" : "LSL",
3399                                 immed ? immed : 32);
3400                         return ERROR_OK;
3401                 case 0x14:
3402                         is_signed = true;
3403                 /* FALLTHROUGH */
3404                 case 0x1c:
3405                         /* signed/unsigned bitfield extract */
3406                         immed = (opcode >> 6) & 0x03;
3407                         immed |= (opcode >> 10) & 0x1c;
3408                         sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t",
3409                                 is_signed ? "S" : "U",
3410                                 rd, rn, immed,
3411                                 (int) (opcode & 0x1f) + 1);
3412                         return ERROR_OK;
3413                 case 0x16:
3414                         immed = (opcode >> 6) & 0x03;
3415                         immed |= (opcode >> 10) & 0x1c;
3416                         if (rn == 0xf)  /* bitfield clear */
3417                                 sprintf(cp, "BFC\tr%d, #%d, #%d\t",
3418                                                 rd, immed,
3419                                                 (int) (opcode & 0x1f) + 1 - immed);
3420                         else            /* bitfield insert */
3421                                 sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t",
3422                                                 rd, rn, immed,
3423                                                 (int) (opcode & 0x1f) + 1 - immed);
3424                         return ERROR_OK;
3425                 default:
3426                         return ERROR_COMMAND_SYNTAX_ERROR;
3427         }
3428
3429         sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic,
3430                         rd, rn, immed, immed);
3431         return ERROR_OK;
3432
3433 do_adr:
3434         address = thumb_alignpc4(address);
3435         if (add)
3436                 address += immed;
3437         else
3438                 address -= immed;
3439         /* REVISIT "ADD/SUB Rd, PC, #const ; 0x..." might be better;
3440          * not hiding the pc-relative stuff will sometimes be useful.
3441          */
3442         sprintf(cp, "ADR.W\tr%d, %#8.8" PRIx32, rd, address);
3443         return ERROR_OK;
3444 }
3445
3446 static int t2ev_store_single(uint32_t opcode, uint32_t address,
3447                              struct arm_instruction *instruction, char *cp)
3448 {
3449         unsigned op = (opcode >> 20) & 0xf;
3450         char *size = "";
3451         char *suffix = "";
3452         char *p1 = "";
3453         char *p2 = "]";
3454         unsigned immed;
3455         unsigned rn = (opcode >> 16) & 0x0f;
3456         unsigned rt = (opcode >> 12) & 0x0f;
3457
3458         if (rn == 0xf)
3459                 return ERROR_COMMAND_SYNTAX_ERROR;
3460
3461         if (opcode & 0x0800)
3462                 op |= 1;
3463         switch (op) {
3464                 /* byte */
3465                 case 0x8:
3466                 case 0x9:
3467                         size = "B";
3468                         goto imm12;
3469                 case 0x1:
3470                         size = "B";
3471                         goto imm8;
3472                 case 0x0:
3473                         size = "B";
3474                         break;
3475                 /* halfword */
3476                 case 0xa:
3477                 case 0xb:
3478                         size = "H";
3479                         goto imm12;
3480                 case 0x3:
3481                         size = "H";
3482                         goto imm8;
3483                 case 0x2:
3484                         size = "H";
3485                         break;
3486                 /* word */
3487                 case 0xc:
3488                 case 0xd:
3489                         goto imm12;
3490                 case 0x5:
3491                         goto imm8;
3492                 case 0x4:
3493                         break;
3494                 /* error */
3495                 default:
3496                         return ERROR_COMMAND_SYNTAX_ERROR;
3497         }
3498
3499         sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]",
3500                         size, rt, rn, (int) opcode & 0x0f,
3501                         (int) (opcode >> 4) & 0x03);
3502         return ERROR_OK;
3503
3504 imm12:
3505         immed = opcode & 0x0fff;
3506         sprintf(cp, "STR%s.W\tr%d, [r%d, #%u]\t; %#3.3x",
3507                         size, rt, rn, immed, immed);
3508         return ERROR_OK;
3509
3510 imm8:
3511         immed = opcode & 0x00ff;
3512
3513         switch (opcode & 0x700) {
3514                 case 0x600:
3515                         suffix = "T";
3516                         break;
3517                 case 0x000:
3518                 case 0x200:
3519                         return ERROR_COMMAND_SYNTAX_ERROR;
3520         }
3521
3522         /* two indexed modes will write back rn */
3523         if (opcode & 0x100) {
3524                 if (opcode & 0x400)     /* pre-indexed */
3525                         p2 = "]!";
3526                 else {                  /* post-indexed */
3527                         p1 = "]";
3528                         p2 = "";
3529                 }
3530         }
3531
3532         sprintf(cp, "STR%s%s\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
3533                         size, suffix, rt, rn, p1,
3534                         (opcode & 0x200) ? "" : "-",
3535                         immed, p2, immed);
3536         return ERROR_OK;
3537 }
3538
3539 static int t2ev_mul32(uint32_t opcode, uint32_t address,
3540                       struct arm_instruction *instruction, char *cp)
3541 {
3542         int ra = (opcode >> 12) & 0xf;
3543
3544         switch (opcode & 0x007000f0) {
3545                 case 0:
3546                         if (ra == 0xf)
3547                                 sprintf(cp, "MUL\tr%d, r%d, r%d",
3548                                                 (int) (opcode >> 8) & 0xf,
3549                                                 (int) (opcode >> 16) & 0xf,
3550                                                 (int) (opcode >> 0) & 0xf);
3551                         else
3552                                 sprintf(cp, "MLA\tr%d, r%d, r%d, r%d",
3553                                                 (int) (opcode >> 8) & 0xf,
3554                                                 (int) (opcode >> 16) & 0xf,
3555                                                 (int) (opcode >> 0) & 0xf, ra);
3556                         break;
3557                 case 0x10:
3558                         sprintf(cp, "MLS\tr%d, r%d, r%d, r%d",
3559                                 (int) (opcode >> 8) & 0xf,
3560                                 (int) (opcode >> 16) & 0xf,
3561                                 (int) (opcode >> 0) & 0xf, ra);
3562                         break;
3563                 default:
3564                         return ERROR_COMMAND_SYNTAX_ERROR;
3565         }
3566         return ERROR_OK;
3567 }
3568
3569 static int t2ev_mul64_div(uint32_t opcode, uint32_t address,
3570                           struct arm_instruction *instruction, char *cp)
3571 {
3572         int op = (opcode >> 4) & 0xf;
3573         char *infix = "MUL";
3574
3575         op += (opcode >> 16) & 0x70;
3576         switch (op) {
3577                 case 0x40:
3578                 case 0x60:
3579                         infix = "MLA";
3580                 /* FALLTHROUGH */
3581                 case 0:
3582                 case 0x20:
3583                         sprintf(cp, "%c%sL\tr%d, r%d, r%d, r%d",
3584                                 (op & 0x20) ? 'U' : 'S',
3585                                 infix,
3586                                 (int) (opcode >> 12) & 0xf,
3587                                 (int) (opcode >> 8) & 0xf,
3588                                 (int) (opcode >> 16) & 0xf,
3589                                 (int) (opcode >> 0) & 0xf);
3590                         break;
3591                 case 0x1f:
3592                 case 0x3f:
3593                         sprintf(cp, "%cDIV\tr%d, r%d, r%d",
3594                                 (op & 0x20) ? 'U' : 'S',
3595                                 (int) (opcode >> 8) & 0xf,
3596                                 (int) (opcode >> 16) & 0xf,
3597                                 (int) (opcode >> 0) & 0xf);
3598                         break;
3599                 default:
3600                         return ERROR_COMMAND_SYNTAX_ERROR;
3601         }
3602
3603         return ERROR_OK;
3604 }
3605
3606 static int t2ev_ldm_stm(uint32_t opcode, uint32_t address,
3607                         struct arm_instruction *instruction, char *cp)
3608 {
3609         int rn = (opcode >> 16) & 0xf;
3610         int op = (opcode >> 22) & 0x6;
3611         int t = (opcode >> 21) & 1;
3612         unsigned registers = opcode & 0xffff;
3613         char *mode = "";
3614
3615         if (opcode & (1 << 20))
3616                 op |= 1;
3617
3618         switch (op) {
3619                 case 0:
3620                         mode = "DB";
3621                 /* FALL THROUGH */
3622                 case 6:
3623                         sprintf(cp, "SRS%s\tsp%s, #%d", mode,
3624                                 t ? "!" : "",
3625                                 (unsigned) (opcode & 0x1f));
3626                         return ERROR_OK;
3627                 case 1:
3628                         mode = "DB";
3629                 /* FALL THROUGH */
3630                 case 7:
3631                         sprintf(cp, "RFE%s\tr%d%s", mode,
3632                                 (unsigned) ((opcode >> 16) & 0xf),
3633                                 t ? "!" : "");
3634                         return ERROR_OK;
3635                 case 2:
3636                         sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : "");
3637                         break;
3638                 case 3:
3639                         if (rn == 13 && t)
3640                                 sprintf(cp, "POP.W\t");
3641                         else
3642                                 sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : "");
3643                         break;
3644                 case 4:
3645                         if (rn == 13 && t)
3646                                 sprintf(cp, "PUSH.W\t");
3647                         else
3648                                 sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : "");
3649                         break;
3650                 case 5:
3651                         sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : "");
3652                         break;
3653                 default:
3654                         return ERROR_COMMAND_SYNTAX_ERROR;
3655         }
3656
3657         cp = strchr(cp, 0);
3658         *cp++ = '{';
3659         for (t = 0; registers; t++, registers >>= 1) {
3660                 if ((registers & 1) == 0)
3661                         continue;
3662                 registers &= ~1;
3663                 sprintf(cp, "r%d%s", t, registers ? ", " : "");
3664                 cp = strchr(cp, 0);
3665         }
3666         *cp++ = '}';
3667         *cp++ = 0;
3668
3669         return ERROR_OK;
3670 }
3671
3672 /* load/store dual or exclusive, table branch */
3673 static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
3674                             struct arm_instruction *instruction, char *cp)
3675 {
3676         unsigned op1op2 = (opcode >> 20) & 0x3;
3677         unsigned op3 = (opcode >> 4) & 0xf;
3678         char *mnemonic;
3679         unsigned rn = (opcode >> 16) & 0xf;
3680         unsigned rt = (opcode >> 12) & 0xf;
3681         unsigned rd = (opcode >> 8) & 0xf;
3682         unsigned imm = opcode & 0xff;
3683         char *p1 = "";
3684         char *p2 = "]";
3685
3686         op1op2 |= (opcode >> 21) & 0xc;
3687         switch (op1op2) {
3688                 case 0:
3689                         mnemonic = "STREX";
3690                         goto strex;
3691                 case 1:
3692                         mnemonic = "LDREX";
3693                         goto ldrex;
3694                 case 2:
3695                 case 6:
3696                 case 8:
3697                 case 10:
3698                 case 12:
3699                 case 14:
3700                         mnemonic = "STRD";
3701                         goto immediate;
3702                 case 3:
3703                 case 7:
3704                 case 9:
3705                 case 11:
3706                 case 13:
3707                 case 15:
3708                         mnemonic = "LDRD";
3709                         if (rn == 15)
3710                                 goto literal;
3711                         else
3712                                 goto immediate;
3713                 case 4:
3714                         switch (op3) {
3715                                 case 4:
3716                                         mnemonic = "STREXB";
3717                                         break;
3718                                 case 5:
3719                                         mnemonic = "STREXH";
3720                                         break;
3721                                 default:
3722                                         return ERROR_COMMAND_SYNTAX_ERROR;
3723                         }
3724                         rd = opcode & 0xf;
3725                         imm = 0;
3726                         goto strex;
3727                 case 5:
3728                         switch (op3) {
3729                                 case 0:
3730                                         sprintf(cp, "TBB\t[r%u, r%u]", rn, imm & 0xf);
3731                                         return ERROR_OK;
3732                                 case 1:
3733                                         sprintf(cp, "TBH\t[r%u, r%u, LSL #1]", rn, imm & 0xf);
3734                                         return ERROR_OK;
3735                                 case 4:
3736                                         mnemonic = "LDREXB";
3737                                         break;
3738                                 case 5:
3739                                         mnemonic = "LDREXH";
3740                                         break;
3741                                 default:
3742                                         return ERROR_COMMAND_SYNTAX_ERROR;
3743                         }
3744                         imm = 0;
3745                         goto ldrex;
3746         }
3747         return ERROR_COMMAND_SYNTAX_ERROR;
3748
3749 strex:
3750         imm <<= 2;
3751         if (imm)
3752                 sprintf(cp, "%s\tr%u, r%u, [r%u, #%u]\t; %#2.2x",
3753                                 mnemonic, rd, rt, rn, imm, imm);
3754         else
3755                 sprintf(cp, "%s\tr%u, r%u, [r%u]",
3756                                 mnemonic, rd, rt, rn);
3757         return ERROR_OK;
3758
3759 ldrex:
3760         imm <<= 2;
3761         if (imm)
3762                 sprintf(cp, "%s\tr%u, [r%u, #%u]\t; %#2.2x",
3763                                 mnemonic, rt, rn, imm, imm);
3764         else
3765                 sprintf(cp, "%s\tr%u, [r%u]",
3766                                 mnemonic, rt, rn);
3767         return ERROR_OK;
3768
3769 immediate:
3770         /* two indexed modes will write back rn */
3771         if (opcode & (1 << 21)) {
3772                 if (opcode & (1 << 24)) /* pre-indexed */
3773                         p2 = "]!";
3774                 else {                  /* post-indexed */
3775                         p1 = "]";
3776                         p2 = "";
3777                 }
3778         }
3779
3780         imm <<= 2;
3781         sprintf(cp, "%s\tr%u, r%u, [r%u%s, #%s%u%s\t; %#2.2x",
3782                         mnemonic, rt, rd, rn, p1,
3783                         (opcode & (1 << 23)) ? "" : "-",
3784                         imm, p2, imm);
3785         return ERROR_OK;
3786
3787 literal:
3788         address = thumb_alignpc4(address);
3789         imm <<= 2;
3790         if (opcode & (1 << 23))
3791                 address += imm;
3792         else
3793                 address -= imm;
3794         sprintf(cp, "%s\tr%u, r%u, %#8.8" PRIx32,
3795                         mnemonic, rt, rd, address);
3796         return ERROR_OK;
3797 }
3798
3799 static int t2ev_data_shift(uint32_t opcode, uint32_t address,
3800                            struct arm_instruction *instruction, char *cp)
3801 {
3802         int op = (opcode >> 21) & 0xf;
3803         int rd = (opcode >> 8) & 0xf;
3804         int rn = (opcode >> 16) & 0xf;
3805         int type = (opcode >> 4) & 0x3;
3806         int immed = (opcode >> 6) & 0x3;
3807         char *mnemonic;
3808         char *suffix = "";
3809
3810         immed |= (opcode >> 10) & 0x1c;
3811         if (opcode & (1 << 20))
3812                 suffix = "S";
3813
3814         switch (op) {
3815                 case 0:
3816                         if (rd == 0xf) {
3817                                 if (!(opcode & (1 << 20)))
3818                                         return ERROR_COMMAND_SYNTAX_ERROR;
3819                                 instruction->type = ARM_TST;
3820                                 mnemonic = "TST";
3821                                 suffix = "";
3822                                 goto two;
3823                         }
3824                         instruction->type = ARM_AND;
3825                         mnemonic = "AND";
3826                         break;
3827                 case 1:
3828                         instruction->type = ARM_BIC;
3829                         mnemonic = "BIC";
3830                         break;
3831                 case 2:
3832                         if (rn == 0xf) {
3833                                 instruction->type = ARM_MOV;
3834                                 switch (type) {
3835                                         case 0:
3836                                                 if (immed == 0) {
3837                                                         sprintf(cp, "MOV%s.W\tr%d, r%d",
3838                                                                         suffix, rd,
3839                                                                         (int) (opcode & 0xf));
3840                                                         return ERROR_OK;
3841                                                 }
3842                                                 mnemonic = "LSL";
3843                                                 break;
3844                                         case 1:
3845                                                 mnemonic = "LSR";
3846                                                 break;
3847                                         case 2:
3848                                                 mnemonic = "ASR";
3849                                                 break;
3850                                         default:
3851                                                 if (immed == 0) {
3852                                                         sprintf(cp, "RRX%s\tr%d, r%d",
3853                                                                         suffix, rd,
3854                                                                         (int) (opcode & 0xf));
3855                                                         return ERROR_OK;
3856                                                 }
3857                                                 mnemonic = "ROR";
3858                                                 break;
3859                                 }
3860                                 goto immediate;
3861                         } else {
3862                                 instruction->type = ARM_ORR;
3863                                 mnemonic = "ORR";
3864                         }
3865                         break;
3866                 case 3:
3867                         if (rn == 0xf) {
3868                                 instruction->type = ARM_MVN;
3869                                 mnemonic = "MVN";
3870                                 rn = rd;
3871                                 goto two;
3872                         } else {
3873                                 /* instruction->type = ARM_ORN; */
3874                                 mnemonic = "ORN";
3875                         }
3876                         break;
3877                 case 4:
3878                         if (rd == 0xf) {
3879                                 if (!(opcode & (1 << 20)))
3880                                         return ERROR_COMMAND_SYNTAX_ERROR;
3881                                 instruction->type = ARM_TEQ;
3882                                 mnemonic = "TEQ";
3883                                 suffix = "";
3884                                 goto two;
3885                         }
3886                         instruction->type = ARM_EOR;
3887                         mnemonic = "EOR";
3888                         break;
3889                 case 8:
3890                         if (rd == 0xf) {
3891                                 if (!(opcode & (1 << 20)))
3892                                         return ERROR_COMMAND_SYNTAX_ERROR;
3893                                 instruction->type = ARM_CMN;
3894                                 mnemonic = "CMN";
3895                                 suffix = "";
3896                                 goto two;
3897                         }
3898                         instruction->type = ARM_ADD;
3899                         mnemonic = "ADD";
3900                         break;
3901                 case 0xa:
3902                         instruction->type = ARM_ADC;
3903                         mnemonic = "ADC";
3904                         break;
3905                 case 0xb:
3906                         instruction->type = ARM_SBC;
3907                         mnemonic = "SBC";
3908                         break;
3909                 case 0xd:
3910                         if (rd == 0xf) {
3911                                 if (!(opcode & (1 << 21)))
3912                                         return ERROR_COMMAND_SYNTAX_ERROR;
3913                                 instruction->type = ARM_CMP;
3914                                 mnemonic = "CMP";
3915                                 suffix = "";
3916                                 goto two;
3917                         }
3918                         instruction->type = ARM_SUB;
3919                         mnemonic = "SUB";
3920                         break;
3921                 case 0xe:
3922                         instruction->type = ARM_RSB;
3923                         mnemonic = "RSB";
3924                         break;
3925                 default:
3926                         return ERROR_COMMAND_SYNTAX_ERROR;
3927         }
3928
3929         sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
3930                         mnemonic, suffix, rd, rn, (int) (opcode & 0xf));
3931
3932 shift:
3933         cp = strchr(cp, 0);
3934
3935         switch (type) {
3936                 case 0:
3937                         if (immed == 0)
3938                                 return ERROR_OK;
3939                         suffix = "LSL";
3940                         break;
3941                 case 1:
3942                         suffix = "LSR";
3943                         if (immed == 32)
3944                                 immed = 0;
3945                         break;
3946                 case 2:
3947                         suffix = "ASR";
3948                         if (immed == 32)
3949                                 immed = 0;
3950                         break;
3951                 case 3:
3952                         if (immed == 0) {
3953                                 strcpy(cp, ", RRX");
3954                                 return ERROR_OK;
3955                         }
3956                         suffix = "ROR";
3957                         break;
3958         }
3959         sprintf(cp, ", %s #%d", suffix, immed ? immed : 32);
3960         return ERROR_OK;
3961
3962 two:
3963         sprintf(cp, "%s%s.W\tr%d, r%d",
3964                         mnemonic, suffix, rn, (int) (opcode & 0xf));
3965         goto shift;
3966
3967 immediate:
3968         sprintf(cp, "%s%s.W\tr%d, r%d, #%d",
3969                         mnemonic, suffix, rd,
3970                         (int) (opcode & 0xf), immed ? immed : 32);
3971         return ERROR_OK;
3972 }
3973
3974 static int t2ev_data_reg(uint32_t opcode, uint32_t address,
3975                          struct arm_instruction *instruction, char *cp)
3976 {
3977         char *mnemonic;
3978         char *suffix = "";
3979
3980         if (((opcode >> 4) & 0xf) == 0) {
3981                 switch ((opcode >> 21) & 0x7) {
3982                         case 0:
3983                                 mnemonic = "LSL";
3984                                 break;
3985                         case 1:
3986                                 mnemonic = "LSR";
3987                                 break;
3988                         case 2:
3989                                 mnemonic = "ASR";
3990                                 break;
3991                         case 3:
3992                                 mnemonic = "ROR";
3993                                 break;
3994                         default:
3995                                 return ERROR_COMMAND_SYNTAX_ERROR;
3996                 }
3997
3998                 instruction->type = ARM_MOV;
3999                 if (opcode & (1 << 20))
4000                         suffix = "S";
4001                 sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
4002                                 mnemonic, suffix,
4003                                 (int) (opcode >> 8) & 0xf,
4004                                 (int) (opcode >> 16) & 0xf,
4005                                 (int) (opcode >> 0) & 0xf);
4006
4007         } else if (opcode & (1 << 7)) {
4008                 switch ((opcode >> 20) & 0xf) {
4009                         case 0:
4010                         case 1:
4011                         case 4:
4012                         case 5:
4013                                 switch ((opcode >> 4) & 0x3) {
4014                                         case 1:
4015                                                 suffix = ", ROR #8";
4016                                                 break;
4017                                         case 2:
4018                                                 suffix = ", ROR #16";
4019                                                 break;
4020                                         case 3:
4021                                                 suffix = ", ROR #24";
4022                                                 break;
4023                                 }
4024                                 sprintf(cp, "%cXT%c.W\tr%d, r%d%s",
4025                                         (opcode & (1 << 24)) ? 'U' : 'S',
4026                                         (opcode & (1 << 26)) ? 'B' : 'H',
4027                                         (int) (opcode >> 8) & 0xf,
4028                                         (int) (opcode >> 0) & 0xf,
4029                                         suffix);
4030                                 break;
4031                         case 8:
4032                         case 9:
4033                         case 0xa:
4034                         case 0xb:
4035                                 if (opcode & (1 << 6))
4036                                         return ERROR_COMMAND_SYNTAX_ERROR;
4037                                 if (((opcode >> 12) & 0xf) != 0xf)
4038                                         return ERROR_COMMAND_SYNTAX_ERROR;
4039                                 if (!(opcode & (1 << 20)))
4040                                         return ERROR_COMMAND_SYNTAX_ERROR;
4041
4042                                 switch (((opcode >> 19) & 0x04)
4043                                         | ((opcode >> 4) & 0x3)) {
4044                                         case 0:
4045                                                 mnemonic = "REV.W";
4046                                                 break;
4047                                         case 1:
4048                                                 mnemonic = "REV16.W";
4049                                                 break;
4050                                         case 2:
4051                                                 mnemonic = "RBIT";
4052                                                 break;
4053                                         case 3:
4054                                                 mnemonic = "REVSH.W";
4055                                                 break;
4056                                         case 4:
4057                                                 mnemonic = "CLZ";
4058                                                 break;
4059                                         default:
4060                                                 return ERROR_COMMAND_SYNTAX_ERROR;
4061                                 }
4062                                 sprintf(cp, "%s\tr%d, r%d",
4063                                         mnemonic,
4064                                         (int) (opcode >> 8) & 0xf,
4065                                         (int) (opcode >> 0) & 0xf);
4066                                 break;
4067                         default:
4068                                 return ERROR_COMMAND_SYNTAX_ERROR;
4069                 }
4070         }
4071
4072         return ERROR_OK;
4073 }
4074
4075 static int t2ev_load_word(uint32_t opcode, uint32_t address,
4076                           struct arm_instruction *instruction, char *cp)
4077 {
4078         int rn = (opcode >> 16) & 0xf;
4079         int immed;
4080
4081         instruction->type = ARM_LDR;
4082
4083         if (rn == 0xf) {
4084                 immed = opcode & 0x0fff;
4085                 if ((opcode & (1 << 23)) == 0)
4086                         immed = -immed;
4087                 sprintf(cp, "LDR\tr%d, %#8.8" PRIx32,
4088                                 (int) (opcode >> 12) & 0xf,
4089                                 thumb_alignpc4(address) + immed);
4090                 return ERROR_OK;
4091         }
4092
4093         if (opcode & (1 << 23)) {
4094                 immed = opcode & 0x0fff;
4095                 sprintf(cp, "LDR.W\tr%d, [r%d, #%d]\t; %#3.3x",
4096                                 (int) (opcode >> 12) & 0xf,
4097                                 rn, immed, immed);
4098                 return ERROR_OK;
4099         }
4100
4101         if (!(opcode & (0x3f << 6))) {
4102                 sprintf(cp, "LDR.W\tr%d, [r%d, r%d, LSL #%d]",
4103                                 (int) (opcode >> 12) & 0xf,
4104                                 rn,
4105                                 (int) (opcode >> 0) & 0xf,
4106                                 (int) (opcode >> 4) & 0x3);
4107                 return ERROR_OK;
4108         }
4109
4110
4111         if (((opcode >> 8) & 0xf) == 0xe) {
4112                 immed = opcode & 0x00ff;
4113
4114                 sprintf(cp, "LDRT\tr%d, [r%d, #%d]\t; %#2.2x",
4115                                 (int) (opcode >> 12) & 0xf,
4116                                 rn, immed, immed);
4117                 return ERROR_OK;
4118         }
4119
4120         if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) {
4121                 char *p1 = "]", *p2 = "";
4122
4123                 if (!(opcode & 0x0500))
4124                         return ERROR_COMMAND_SYNTAX_ERROR;
4125
4126                 immed = opcode & 0x00ff;
4127
4128                 /* two indexed modes will write back rn */
4129                 if (opcode & 0x100) {
4130                         if (opcode & 0x400)     /* pre-indexed */
4131                                 p2 = "]!";
4132                         else {                  /* post-indexed */
4133                                 p1 = "]";
4134                                 p2 = "";
4135                         }
4136                 }
4137
4138                 sprintf(cp, "LDR\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
4139                                 (int) (opcode >> 12) & 0xf,
4140                                 rn, p1,
4141                                 (opcode & 0x200) ? "" : "-",
4142                                 immed, p2, immed);
4143                 return ERROR_OK;
4144         }
4145
4146         return ERROR_COMMAND_SYNTAX_ERROR;
4147 }
4148
4149 static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address,
4150                                 struct arm_instruction *instruction, char *cp)
4151 {
4152         int rn = (opcode >> 16) & 0xf;
4153         int rt = (opcode >> 12) & 0xf;
4154         int op2 = (opcode >> 6) & 0x3f;
4155         unsigned immed;
4156         char *p1 = "", *p2 = "]";
4157         char *mnemonic;
4158
4159         switch ((opcode >> 23) & 0x3) {
4160                 case 0:
4161                         if ((rn & rt) == 0xf) {
4162 pld_literal:
4163                                 immed = opcode & 0xfff;
4164                                 address = thumb_alignpc4(address);
4165                                 if (opcode & (1 << 23))
4166                                         address += immed;
4167                                 else
4168                                         address -= immed;
4169                                 sprintf(cp, "PLD\tr%d, %#8.8" PRIx32,
4170                                                 rt, address);
4171                                 return ERROR_OK;
4172                         }
4173                         if (rn == 0x0f && rt != 0x0f) {
4174 ldrb_literal:
4175                                 immed = opcode & 0xfff;
4176                                 address = thumb_alignpc4(address);
4177                                 if (opcode & (1 << 23))
4178                                         address += immed;
4179                                 else
4180                                         address -= immed;
4181                                 sprintf(cp, "LDRB\tr%d, %#8.8" PRIx32,
4182                                                 rt, address);
4183                                 return ERROR_OK;
4184                         }
4185                         if (rn == 0x0f)
4186                                 break;
4187                         if ((op2 & 0x3c) == 0x38) {
4188                                 immed = opcode & 0xff;
4189                                 sprintf(cp, "LDRBT\tr%d, [r%d, #%d]\t; %#2.2x",
4190                                                 rt, rn, immed, immed);
4191                                 return ERROR_OK;
4192                         }
4193                         if ((op2 & 0x3c) == 0x30) {
4194                                 if (rt == 0x0f) {
4195                                         immed = opcode & 0xff;
4196                                         immed = -immed;
4197 preload_immediate:
4198                                         p1 = (opcode & (1 << 21)) ? "W" : "";
4199                                         sprintf(cp, "PLD%s\t[r%d, #%d]\t; %#6.6x",
4200                                                         p1, rn, immed, immed);
4201                                         return ERROR_OK;
4202                                 }
4203                                 mnemonic = "LDRB";
4204 ldrxb_immediate_t3:
4205                                 immed = opcode & 0xff;
4206                                 if (!(opcode & 0x200))
4207                                         immed = -immed;
4208
4209                                 /* two indexed modes will write back rn */
4210                                 if (opcode & 0x100) {
4211                                         if (opcode & 0x400)     /* pre-indexed */
4212                                                 p2 = "]!";
4213                                         else {          /* post-indexed */
4214                                                 p1 = "]";
4215                                                 p2 = "";
4216                                         }
4217                                 }
4218 ldrxb_immediate_t2:
4219                                 sprintf(cp, "%s\tr%d, [r%d%s, #%d%s\t; %#8.8x",
4220                                                 mnemonic, rt, rn, p1,
4221                                                 immed, p2, immed);
4222                                 return ERROR_OK;
4223                         }
4224                         if ((op2 & 0x24) == 0x24) {
4225                                 mnemonic = "LDRB";
4226                                 goto ldrxb_immediate_t3;
4227                         }
4228                         if (op2 == 0) {
4229                                 int rm = opcode & 0xf;
4230
4231                                 if (rt == 0x0f)
4232                                         sprintf(cp, "PLD\t");
4233                                 else
4234                                         sprintf(cp, "LDRB.W\tr%d, ", rt);
4235                                 immed = (opcode >> 4) & 0x3;
4236                                 cp = strchr(cp, 0);
4237                                 sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
4238                                 return ERROR_OK;
4239                         }
4240                         break;
4241                 case 1:
4242                         if ((rn & rt) == 0xf)
4243                                 goto pld_literal;
4244                         if (rt == 0xf) {
4245                                 immed = opcode & 0xfff;
4246                                 goto preload_immediate;
4247                         }
4248                         if (rn == 0x0f)
4249                                 goto ldrb_literal;
4250                         mnemonic = "LDRB.W";
4251                         immed = opcode & 0xfff;
4252                         goto ldrxb_immediate_t2;
4253                 case 2:
4254                         if ((rn & rt) == 0xf) {
4255                                 immed = opcode & 0xfff;
4256                                 address = thumb_alignpc4(address);
4257                                 if (opcode & (1 << 23))
4258                                         address += immed;
4259                                 else
4260                                         address -= immed;
4261                                 sprintf(cp, "PLI\t%#8.8" PRIx32, address);
4262                                 return ERROR_OK;
4263                         }
4264                         if (rn == 0xf && rt != 0xf) {
4265 ldrsb_literal:
4266                                 immed = opcode & 0xfff;
4267                                 address = thumb_alignpc4(address);
4268                                 if (opcode & (1 << 23))
4269                                         address += immed;
4270                                 else
4271                                         address -= immed;
4272                                 sprintf(cp, "LDRSB\t%#8.8" PRIx32, address);
4273                                 return ERROR_OK;
4274                         }
4275                         if (rn == 0xf)
4276                                 break;
4277                         if ((op2 & 0x3c) == 0x38) {
4278                                 immed = opcode & 0xff;
4279                                 sprintf(cp, "LDRSBT\tr%d, [r%d, #%d]\t; %#2.2x",
4280                                                 rt, rn, immed, immed);
4281                                 return ERROR_OK;
4282                         }
4283                         if ((op2 & 0x3c) == 0x30) {
4284                                 if (rt == 0xf) {
4285                                         immed = opcode & 0xff;
4286                                         immed = -immed; /* pli */
4287                                         sprintf(cp, "PLI\t[r%d, #%d]\t; -%#2.2x",
4288                                                         rn, immed, -immed);
4289                                         return ERROR_OK;
4290                                 }
4291                                 mnemonic = "LDRSB";
4292                                 goto ldrxb_immediate_t3;
4293                         }
4294                         if ((op2 & 0x24) == 0x24) {
4295                                 mnemonic = "LDRSB";
4296                                 goto ldrxb_immediate_t3;
4297                         }
4298                         if (op2 == 0) {
4299                                 int rm = opcode & 0xf;
4300
4301                                 if (rt == 0x0f)
4302                                         sprintf(cp, "PLI\t");
4303                                 else
4304                                         sprintf(cp, "LDRSB.W\tr%d, ", rt);
4305                                 immed = (opcode >> 4) & 0x3;
4306                                 cp = strchr(cp, 0);
4307                                 sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
4308                                 return ERROR_OK;
4309                         }
4310                         break;
4311                 case 3:
4312                         if (rt == 0xf) {
4313                                 immed = opcode & 0xfff;
4314                                 sprintf(cp, "PLI\t[r%d, #%d]\t; %#3.3x",
4315                                                 rn, immed, immed);
4316                                 return ERROR_OK;
4317                         }
4318                         if (rn == 0xf)
4319                                 goto ldrsb_literal;
4320                         immed = opcode & 0xfff;
4321                         mnemonic = "LDRSB";
4322                         goto ldrxb_immediate_t2;
4323         }
4324
4325         return ERROR_COMMAND_SYNTAX_ERROR;
4326 }
4327
4328 static int t2ev_load_halfword(uint32_t opcode, uint32_t address,
4329                               struct arm_instruction *instruction, char *cp)
4330 {
4331         int rn = (opcode >> 16) & 0xf;
4332         int rt = (opcode >> 12) & 0xf;
4333         int op2 = (opcode >> 6) & 0x3f;
4334         char *sign = "";
4335         unsigned immed;
4336
4337         if (rt == 0xf) {
4338                 sprintf(cp, "HINT (UNALLOCATED)");
4339                 return ERROR_OK;
4340         }
4341
4342         if (opcode & (1 << 24))
4343                 sign = "S";
4344
4345         if ((opcode & (1 << 23)) == 0) {
4346                 if (rn == 0xf) {
4347 ldrh_literal:
4348                         immed = opcode & 0xfff;
4349                         address = thumb_alignpc4(address);
4350                         if (opcode & (1 << 23))
4351                                 address += immed;
4352                         else
4353                                 address -= immed;
4354                         sprintf(cp, "LDR%sH\tr%d, %#8.8" PRIx32,
4355                                         sign, rt, address);
4356                         return ERROR_OK;
4357                 }
4358                 if (op2 == 0) {
4359                         int rm = opcode & 0xf;
4360
4361                         immed = (opcode >> 4) & 0x3;
4362                         sprintf(cp, "LDR%sH.W\tr%d, [r%d, r%d, LSL #%d]",
4363                                         sign, rt, rn, rm, immed);
4364                         return ERROR_OK;
4365                 }
4366                 if ((op2 & 0x3c) == 0x38) {
4367                         immed = opcode & 0xff;
4368                         sprintf(cp, "LDR%sHT\tr%d, [r%d, #%d]\t; %#2.2x",
4369                                         sign, rt, rn, immed, immed);
4370                         return ERROR_OK;
4371                 }
4372                 if ((op2 & 0x3c) == 0x30 || (op2 & 0x24) == 0x24) {
4373                         char *p1 = "", *p2 = "]";
4374
4375                         immed = opcode & 0xff;
4376                         if (!(opcode & 0x200))
4377                                 immed = -immed;
4378
4379                         /* two indexed modes will write back rn */
4380                         if (opcode & 0x100) {
4381                                 if (opcode & 0x400)     /* pre-indexed */
4382                                         p2 = "]!";
4383                                 else {                  /* post-indexed */
4384                                         p1 = "]";
4385                                         p2 = "";
4386                                 }
4387                         }
4388                         sprintf(cp, "LDR%sH\tr%d, [r%d%s, #%d%s\t; %#8.8x",
4389                                         sign, rt, rn, p1, immed, p2, immed);
4390                         return ERROR_OK;
4391                 }
4392         } else {
4393                 if (rn == 0xf)
4394                         goto ldrh_literal;
4395
4396                 immed = opcode & 0xfff;
4397                 sprintf(cp, "LDR%sH%s\tr%d, [r%d, #%d]\t; %#6.6x",
4398                                 sign, *sign ? "" : ".W",
4399                                 rt, rn, immed, immed);
4400                 return ERROR_OK;
4401         }
4402
4403         return ERROR_COMMAND_SYNTAX_ERROR;
4404 }
4405
4406 /*
4407  * REVISIT for Thumb2 instructions, instruction->type and friends aren't
4408  * always set.  That means eventual arm_simulate_step() support for Thumb2
4409  * will need work in this area.
4410  */
4411 int thumb2_opcode(struct target *target, uint32_t address, struct arm_instruction *instruction)
4412 {
4413         int retval;
4414         uint16_t op;
4415         uint32_t opcode;
4416         char *cp;
4417
4418         /* clear low bit ... it's set on function pointers */
4419         address &= ~1;
4420
4421         /* clear fields, to avoid confusion */
4422         memset(instruction, 0, sizeof(struct arm_instruction));
4423
4424         /* read first halfword, see if this is the only one */
4425         retval = target_read_u16(target, address, &op);
4426         if (retval != ERROR_OK)
4427                 return retval;
4428
4429         switch (op & 0xf800) {
4430                 case 0xf800:
4431                 case 0xf000:
4432                 case 0xe800:
4433                         /* 32-bit instructions */
4434                         instruction->instruction_size = 4;
4435                         opcode = op << 16;
4436                         retval = target_read_u16(target, address + 2, &op);
4437                         if (retval != ERROR_OK)
4438                                 return retval;
4439                         opcode |= op;
4440                         instruction->opcode = opcode;
4441                         break;
4442                 default:
4443                         /* 16-bit:  Thumb1 + IT + CBZ/CBNZ + ... */
4444                         return thumb_evaluate_opcode(op, address, instruction);
4445         }
4446
4447         snprintf(instruction->text, 128,
4448                         "0x%8.8" PRIx32 "  0x%8.8" PRIx32 "\t",
4449                         address, opcode);
4450         cp = strchr(instruction->text, 0);
4451         retval = ERROR_FAIL;
4452
4453         /* ARMv7-M: A5.3.1 Data processing (modified immediate) */
4454         if ((opcode & 0x1a008000) == 0x10000000)
4455                 retval = t2ev_data_mod_immed(opcode, address, instruction, cp);
4456
4457         /* ARMv7-M: A5.3.3 Data processing (plain binary immediate) */
4458         else if ((opcode & 0x1a008000) == 0x12000000)
4459                 retval = t2ev_data_immed(opcode, address, instruction, cp);
4460
4461         /* ARMv7-M: A5.3.4 Branches and miscellaneous control */
4462         else if ((opcode & 0x18008000) == 0x10008000)
4463                 retval = t2ev_b_misc(opcode, address, instruction, cp);
4464
4465         /* ARMv7-M: A5.3.5 Load/store multiple */
4466         else if ((opcode & 0x1e400000) == 0x08000000)
4467                 retval = t2ev_ldm_stm(opcode, address, instruction, cp);
4468
4469         /* ARMv7-M: A5.3.6 Load/store dual or exclusive, table branch */
4470         else if ((opcode & 0x1e400000) == 0x08400000)
4471                 retval = t2ev_ldrex_strex(opcode, address, instruction, cp);
4472
4473         /* ARMv7-M: A5.3.7 Load word */
4474         else if ((opcode & 0x1f700000) == 0x18500000)
4475                 retval = t2ev_load_word(opcode, address, instruction, cp);
4476
4477         /* ARMv7-M: A5.3.8 Load halfword, unallocated memory hints */
4478         else if ((opcode & 0x1e700000) == 0x18300000)
4479                 retval = t2ev_load_halfword(opcode, address, instruction, cp);
4480
4481         /* ARMv7-M: A5.3.9 Load byte, memory hints */
4482         else if ((opcode & 0x1e700000) == 0x18100000)
4483                 retval = t2ev_load_byte_hints(opcode, address, instruction, cp);
4484
4485         /* ARMv7-M: A5.3.10 Store single data item */
4486         else if ((opcode & 0x1f100000) == 0x18000000)
4487                 retval = t2ev_store_single(opcode, address, instruction, cp);
4488
4489         /* ARMv7-M: A5.3.11 Data processing (shifted register) */
4490         else if ((opcode & 0x1e000000) == 0x0a000000)
4491                 retval = t2ev_data_shift(opcode, address, instruction, cp);
4492
4493         /* ARMv7-M: A5.3.12 Data processing (register)
4494          * and A5.3.13 Miscellaneous operations
4495          */
4496         else if ((opcode & 0x1f000000) == 0x1a000000)
4497                 retval = t2ev_data_reg(opcode, address, instruction, cp);
4498
4499         /* ARMv7-M: A5.3.14 Multiply, and multiply accumulate */
4500         else if ((opcode & 0x1f800000) == 0x1b000000)
4501                 retval = t2ev_mul32(opcode, address, instruction, cp);
4502
4503         /* ARMv7-M: A5.3.15 Long multiply, long multiply accumulate, divide */
4504         else if ((opcode & 0x1f800000) == 0x1b800000)
4505                 retval = t2ev_mul64_div(opcode, address, instruction, cp);
4506
4507         if (retval == ERROR_OK)
4508                 return retval;
4509
4510         /*
4511          * Thumb2 also supports coprocessor, ThumbEE, and DSP/Media (SIMD)
4512          * instructions; not yet handled here.
4513          */
4514
4515         if (retval == ERROR_COMMAND_SYNTAX_ERROR) {
4516                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
4517                 strcpy(cp, "UNDEFINED OPCODE");
4518                 return ERROR_OK;
4519         }
4520
4521         LOG_DEBUG("Can't decode 32-bit Thumb2 yet (opcode=%08" PRIx32 ")",
4522                         opcode);
4523
4524         strcpy(cp, "(32-bit Thumb2 ...)");
4525         return ERROR_OK;
4526 }
4527
4528 int arm_access_size(struct arm_instruction *instruction)
4529 {
4530         if ((instruction->type == ARM_LDRB)
4531             || (instruction->type == ARM_LDRBT)
4532             || (instruction->type == ARM_LDRSB)
4533             || (instruction->type == ARM_STRB)
4534             || (instruction->type == ARM_STRBT))
4535                 return 1;
4536         else if ((instruction->type == ARM_LDRH)
4537                  || (instruction->type == ARM_LDRSH)
4538                  || (instruction->type == ARM_STRH))
4539                 return 2;
4540         else if ((instruction->type == ARM_LDR)
4541                  || (instruction->type == ARM_LDRT)
4542                  || (instruction->type == ARM_STR)
4543                  || (instruction->type == ARM_STRT))
4544                 return 4;
4545         else if ((instruction->type == ARM_LDRD)
4546                  || (instruction->type == ARM_STRD))
4547                 return 8;
4548         else {
4549                 LOG_ERROR("BUG: instruction type %i isn't a load/store instruction",
4550                                 instruction->type);
4551                 return 0;
4552         }
4553 }