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