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