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