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