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