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