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