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