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