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