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