ARM: bugfix for "movt" disassembly
[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,
1101                         "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
1102                         "\t%s%s%s r%i%s, {%s}%s",
1103                          address, opcode,
1104                          mnemonic, addressing_mode, COND(opcode),
1105                          Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
1106
1107         return ERROR_OK;
1108 }
1109
1110 /* Multiplies, extra load/stores */
1111 static int evaluate_mul_and_extra_ld_st(uint32_t opcode,
1112                 uint32_t address, struct arm_instruction *instruction)
1113 {
1114         /* Multiply (accumulate) (long) and Swap/swap byte */
1115         if ((opcode & 0x000000f0) == 0x00000090)
1116         {
1117                 /* Multiply (accumulate) */
1118                 if ((opcode & 0x0f800000) == 0x00000000)
1119                 {
1120                         uint8_t Rm, Rs, Rn, Rd, S;
1121                         Rm = opcode & 0xf;
1122                         Rs = (opcode & 0xf00) >> 8;
1123                         Rn = (opcode & 0xf000) >> 12;
1124                         Rd = (opcode & 0xf0000) >> 16;
1125                         S = (opcode & 0x00100000) >> 20;
1126
1127                         /* examine A bit (accumulate) */
1128                         if (opcode & 0x00200000)
1129                         {
1130                                 instruction->type = ARM_MLA;
1131                                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
1132                                                 address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs, Rn);
1133                         }
1134                         else
1135                         {
1136                                 instruction->type = ARM_MUL;
1137                                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
1138                                                  address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs);
1139                         }
1140
1141                         return ERROR_OK;
1142                 }
1143
1144                 /* Multiply (accumulate) long */
1145                 if ((opcode & 0x0f800000) == 0x00800000)
1146                 {
1147                         char* mnemonic = NULL;
1148                         uint8_t Rm, Rs, RdHi, RdLow, S;
1149                         Rm = opcode & 0xf;
1150                         Rs = (opcode & 0xf00) >> 8;
1151                         RdHi = (opcode & 0xf000) >> 12;
1152                         RdLow = (opcode & 0xf0000) >> 16;
1153                         S = (opcode & 0x00100000) >> 20;
1154
1155                         switch ((opcode & 0x00600000) >> 21)
1156                         {
1157                                 case 0x0:
1158                                         instruction->type = ARM_UMULL;
1159                                         mnemonic = "UMULL";
1160                                         break;
1161                                 case 0x1:
1162                                         instruction->type = ARM_UMLAL;
1163                                         mnemonic = "UMLAL";
1164                                         break;
1165                                 case 0x2:
1166                                         instruction->type = ARM_SMULL;
1167                                         mnemonic = "SMULL";
1168                                         break;
1169                                 case 0x3:
1170                                         instruction->type = ARM_SMLAL;
1171                                         mnemonic = "SMLAL";
1172                                         break;
1173                         }
1174
1175                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
1176                                                 address, opcode, mnemonic, COND(opcode), (S) ? "S" : "",
1177                                                 RdLow, RdHi, Rm, Rs);
1178
1179                         return ERROR_OK;
1180                 }
1181
1182                 /* Swap/swap byte */
1183                 if ((opcode & 0x0f800000) == 0x01000000)
1184                 {
1185                         uint8_t Rm, Rd, Rn;
1186                         Rm = opcode & 0xf;
1187                         Rd = (opcode & 0xf000) >> 12;
1188                         Rn = (opcode & 0xf0000) >> 16;
1189
1190                         /* examine B flag */
1191                         instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
1192
1193                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
1194                                          address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn);
1195                         return ERROR_OK;
1196                 }
1197
1198         }
1199
1200         return evaluate_misc_load_store(opcode, address, instruction);
1201 }
1202
1203 static int evaluate_mrs_msr(uint32_t opcode,
1204                 uint32_t address, struct arm_instruction *instruction)
1205 {
1206         int R = (opcode & 0x00400000) >> 22;
1207         char *PSR = (R) ? "SPSR" : "CPSR";
1208
1209         /* Move register to status register (MSR) */
1210         if (opcode & 0x00200000)
1211         {
1212                 instruction->type = ARM_MSR;
1213
1214                 /* immediate variant */
1215                 if (opcode & 0x02000000)
1216                 {
1217                         uint8_t immediate = (opcode & 0xff);
1218                         uint8_t rotate = (opcode & 0xf00);
1219
1220                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32 ,
1221                                          address, opcode, COND(opcode), PSR,
1222                                          (opcode & 0x10000) ? "c" : "",
1223                                          (opcode & 0x20000) ? "x" : "",
1224                                          (opcode & 0x40000) ? "s" : "",
1225                                          (opcode & 0x80000) ? "f" : "",
1226                                          ror(immediate, (rotate * 2))
1227 );
1228                 }
1229                 else /* register variant */
1230                 {
1231                         uint8_t Rm = opcode & 0xf;
1232                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
1233                                          address, opcode, COND(opcode), PSR,
1234                                          (opcode & 0x10000) ? "c" : "",
1235                                          (opcode & 0x20000) ? "x" : "",
1236                                          (opcode & 0x40000) ? "s" : "",
1237                                          (opcode & 0x80000) ? "f" : "",
1238                                          Rm
1239 );
1240                 }
1241
1242         }
1243         else /* Move status register to register (MRS) */
1244         {
1245                 uint8_t Rd;
1246
1247                 instruction->type = ARM_MRS;
1248                 Rd = (opcode & 0x0000f000) >> 12;
1249
1250                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
1251                                  address, opcode, COND(opcode), Rd, PSR);
1252         }
1253
1254         return ERROR_OK;
1255 }
1256
1257 /* Miscellaneous instructions */
1258 static int evaluate_misc_instr(uint32_t opcode,
1259                 uint32_t address, struct arm_instruction *instruction)
1260 {
1261         /* MRS/MSR */
1262         if ((opcode & 0x000000f0) == 0x00000000)
1263         {
1264                 evaluate_mrs_msr(opcode, address, instruction);
1265         }
1266
1267         /* BX */
1268         if ((opcode & 0x006000f0) == 0x00200010)
1269         {
1270                 uint8_t Rm;
1271                 instruction->type = ARM_BX;
1272                 Rm = opcode & 0xf;
1273
1274                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
1275                                  address, opcode, COND(opcode), Rm);
1276
1277                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1278                 instruction->info.b_bl_bx_blx.target_address = -1;
1279         }
1280
1281         /* BXJ - "Jazelle" support (ARMv5-J) */
1282         if ((opcode & 0x006000f0) == 0x00200020)
1283         {
1284                 uint8_t Rm;
1285                 instruction->type = ARM_BX;
1286                 Rm = opcode & 0xf;
1287
1288                 snprintf(instruction->text, 128,
1289                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBXJ%s r%i",
1290                                  address, opcode, COND(opcode), Rm);
1291
1292                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1293                 instruction->info.b_bl_bx_blx.target_address = -1;
1294         }
1295
1296         /* CLZ */
1297         if ((opcode & 0x006000f0) == 0x00600010)
1298         {
1299                 uint8_t Rm, Rd;
1300                 instruction->type = ARM_CLZ;
1301                 Rm = opcode & 0xf;
1302                 Rd = (opcode & 0xf000) >> 12;
1303
1304                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
1305                                  address, opcode, COND(opcode), Rd, Rm);
1306         }
1307
1308         /* BLX(2) */
1309         if ((opcode & 0x006000f0) == 0x00200030)
1310         {
1311                 uint8_t Rm;
1312                 instruction->type = ARM_BLX;
1313                 Rm = opcode & 0xf;
1314
1315                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
1316                                  address, opcode, COND(opcode), Rm);
1317
1318                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1319                 instruction->info.b_bl_bx_blx.target_address = -1;
1320         }
1321
1322         /* Enhanced DSP add/subtracts */
1323         if ((opcode & 0x0000000f0) == 0x00000050)
1324         {
1325                 uint8_t Rm, Rd, Rn;
1326                 char *mnemonic = NULL;
1327                 Rm = opcode & 0xf;
1328                 Rd = (opcode & 0xf000) >> 12;
1329                 Rn = (opcode & 0xf0000) >> 16;
1330
1331                 switch ((opcode & 0x00600000) >> 21)
1332                 {
1333                         case 0x0:
1334                                 instruction->type = ARM_QADD;
1335                                 mnemonic = "QADD";
1336                                 break;
1337                         case 0x1:
1338                                 instruction->type = ARM_QSUB;
1339                                 mnemonic = "QSUB";
1340                                 break;
1341                         case 0x2:
1342                                 instruction->type = ARM_QDADD;
1343                                 mnemonic = "QDADD";
1344                                 break;
1345                         case 0x3:
1346                                 instruction->type = ARM_QDSUB;
1347                                 mnemonic = "QDSUB";
1348                                 break;
1349                 }
1350
1351                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
1352                                  address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn);
1353         }
1354
1355         /* Software breakpoints */
1356         if ((opcode & 0x0000000f0) == 0x00000070)
1357         {
1358                 uint32_t immediate;
1359                 instruction->type = ARM_BKPT;
1360                 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1361
1362                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "",
1363                                  address, opcode, immediate);
1364         }
1365
1366         /* Enhanced DSP multiplies */
1367         if ((opcode & 0x000000090) == 0x00000080)
1368         {
1369                 int x = (opcode & 0x20) >> 5;
1370                 int y = (opcode & 0x40) >> 6;
1371
1372                 /* SMLA < x><y> */
1373                 if ((opcode & 0x00600000) == 0x00000000)
1374                 {
1375                         uint8_t Rd, Rm, Rs, Rn;
1376                         instruction->type = ARM_SMLAxy;
1377                         Rd = (opcode & 0xf0000) >> 16;
1378                         Rm = (opcode & 0xf);
1379                         Rs = (opcode & 0xf00) >> 8;
1380                         Rn = (opcode & 0xf000) >> 12;
1381
1382                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1383                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
1384                                          Rd, Rm, Rs, Rn);
1385                 }
1386
1387                 /* SMLAL < x><y> */
1388                 if ((opcode & 0x00600000) == 0x00400000)
1389                 {
1390                         uint8_t RdLow, RdHi, Rm, Rs;
1391                         instruction->type = ARM_SMLAxy;
1392                         RdHi = (opcode & 0xf0000) >> 16;
1393                         RdLow = (opcode & 0xf000) >> 12;
1394                         Rm = (opcode & 0xf);
1395                         Rs = (opcode & 0xf00) >> 8;
1396
1397                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1398                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
1399                                          RdLow, RdHi, Rm, Rs);
1400                 }
1401
1402                 /* SMLAW < y> */
1403                 if (((opcode & 0x00600000) == 0x00100000) && (x == 0))
1404                 {
1405                         uint8_t Rd, Rm, Rs, Rn;
1406                         instruction->type = ARM_SMLAWy;
1407                         Rd = (opcode & 0xf0000) >> 16;
1408                         Rm = (opcode & 0xf);
1409                         Rs = (opcode & 0xf00) >> 8;
1410                         Rn = (opcode & 0xf000) >> 12;
1411
1412                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
1413                                          address, opcode, (y) ? "T" : "B", COND(opcode),
1414                                          Rd, Rm, Rs, Rn);
1415                 }
1416
1417                 /* SMUL < x><y> */
1418                 if ((opcode & 0x00600000) == 0x00300000)
1419                 {
1420                         uint8_t Rd, Rm, Rs;
1421                         instruction->type = ARM_SMULxy;
1422                         Rd = (opcode & 0xf0000) >> 16;
1423                         Rm = (opcode & 0xf);
1424                         Rs = (opcode & 0xf00) >> 8;
1425
1426                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
1427                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
1428                                          Rd, Rm, Rs);
1429                 }
1430
1431                 /* SMULW < y> */
1432                 if (((opcode & 0x00600000) == 0x00100000) && (x == 1))
1433                 {
1434                         uint8_t Rd, Rm, Rs;
1435                         instruction->type = ARM_SMULWy;
1436                         Rd = (opcode & 0xf0000) >> 16;
1437                         Rm = (opcode & 0xf);
1438                         Rs = (opcode & 0xf00) >> 8;
1439
1440                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
1441                                          address, opcode, (y) ? "T" : "B", COND(opcode),
1442                                          Rd, Rm, Rs);
1443                 }
1444         }
1445
1446         return ERROR_OK;
1447 }
1448
1449 static int evaluate_data_proc(uint32_t opcode,
1450                 uint32_t address, struct arm_instruction *instruction)
1451 {
1452         uint8_t I, op, S, Rn, Rd;
1453         char *mnemonic = NULL;
1454         char shifter_operand[32];
1455
1456         I = (opcode & 0x02000000) >> 25;
1457         op = (opcode & 0x01e00000) >> 21;
1458         S = (opcode & 0x00100000) >> 20;
1459
1460         Rd = (opcode & 0xf000) >> 12;
1461         Rn = (opcode & 0xf0000) >> 16;
1462
1463         instruction->info.data_proc.Rd = Rd;
1464         instruction->info.data_proc.Rn = Rn;
1465         instruction->info.data_proc.S = S;
1466
1467         switch (op)
1468         {
1469                 case 0x0:
1470                         instruction->type = ARM_AND;
1471                         mnemonic = "AND";
1472                         break;
1473                 case 0x1:
1474                         instruction->type = ARM_EOR;
1475                         mnemonic = "EOR";
1476                         break;
1477                 case 0x2:
1478                         instruction->type = ARM_SUB;
1479                         mnemonic = "SUB";
1480                         break;
1481                 case 0x3:
1482                         instruction->type = ARM_RSB;
1483                         mnemonic = "RSB";
1484                         break;
1485                 case 0x4:
1486                         instruction->type = ARM_ADD;
1487                         mnemonic = "ADD";
1488                         break;
1489                 case 0x5:
1490                         instruction->type = ARM_ADC;
1491                         mnemonic = "ADC";
1492                         break;
1493                 case 0x6:
1494                         instruction->type = ARM_SBC;
1495                         mnemonic = "SBC";
1496                         break;
1497                 case 0x7:
1498                         instruction->type = ARM_RSC;
1499                         mnemonic = "RSC";
1500                         break;
1501                 case 0x8:
1502                         instruction->type = ARM_TST;
1503                         mnemonic = "TST";
1504                         break;
1505                 case 0x9:
1506                         instruction->type = ARM_TEQ;
1507                         mnemonic = "TEQ";
1508                         break;
1509                 case 0xa:
1510                         instruction->type = ARM_CMP;
1511                         mnemonic = "CMP";
1512                         break;
1513                 case 0xb:
1514                         instruction->type = ARM_CMN;
1515                         mnemonic = "CMN";
1516                         break;
1517                 case 0xc:
1518                         instruction->type = ARM_ORR;
1519                         mnemonic = "ORR";
1520                         break;
1521                 case 0xd:
1522                         instruction->type = ARM_MOV;
1523                         mnemonic = "MOV";
1524                         break;
1525                 case 0xe:
1526                         instruction->type = ARM_BIC;
1527                         mnemonic = "BIC";
1528                         break;
1529                 case 0xf:
1530                         instruction->type = ARM_MVN;
1531                         mnemonic = "MVN";
1532                         break;
1533         }
1534
1535         if (I) /* immediate shifter operand (#<immediate>)*/
1536         {
1537                 uint8_t immed_8 = opcode & 0xff;
1538                 uint8_t rotate_imm = (opcode & 0xf00) >> 8;
1539                 uint32_t immediate;
1540
1541                 immediate = ror(immed_8, rotate_imm * 2);
1542
1543                 snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
1544
1545                 instruction->info.data_proc.variant = 0;
1546                 instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
1547         }
1548         else /* register-based shifter operand */
1549         {
1550                 uint8_t shift, Rm;
1551                 shift = (opcode & 0x60) >> 5;
1552                 Rm = (opcode & 0xf);
1553
1554                 if ((opcode & 0x10) != 0x10) /* Immediate shifts ("<Rm>" or "<Rm>, <shift> #<shift_immediate>") */
1555                 {
1556                         uint8_t shift_imm;
1557                         shift_imm = (opcode & 0xf80) >> 7;
1558
1559                         instruction->info.data_proc.variant = 1;
1560                         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1561                         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm;
1562                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
1563
1564                         /* LSR encodes a shift by 32 bit as 0x0 */
1565                         if ((shift == 0x1) && (shift_imm == 0x0))
1566                                 shift_imm = 0x20;
1567
1568                         /* ASR encodes a shift by 32 bit as 0x0 */
1569                         if ((shift == 0x2) && (shift_imm == 0x0))
1570                                 shift_imm = 0x20;
1571
1572                         /* ROR by 32 bit is actually a RRX */
1573                         if ((shift == 0x3) && (shift_imm == 0x0))
1574                                 shift = 0x4;
1575
1576                         if ((shift_imm == 0x0) && (shift == 0x0))
1577                         {
1578                                 snprintf(shifter_operand, 32, "r%i", Rm);
1579                         }
1580                         else
1581                         {
1582                                 if (shift == 0x0) /* LSL */
1583                                 {
1584                                         snprintf(shifter_operand, 32, "r%i, LSL #0x%x", Rm, shift_imm);
1585                                 }
1586                                 else if (shift == 0x1) /* LSR */
1587                                 {
1588                                         snprintf(shifter_operand, 32, "r%i, LSR #0x%x", Rm, shift_imm);
1589                                 }
1590                                 else if (shift == 0x2) /* ASR */
1591                                 {
1592                                         snprintf(shifter_operand, 32, "r%i, ASR #0x%x", Rm, shift_imm);
1593                                 }
1594                                 else if (shift == 0x3) /* ROR */
1595                                 {
1596                                         snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm);
1597                                 }
1598                                 else if (shift == 0x4) /* RRX */
1599                                 {
1600                                         snprintf(shifter_operand, 32, "r%i, RRX", Rm);
1601                                 }
1602                         }
1603                 }
1604                 else /* Register shifts ("<Rm>, <shift> <Rs>") */
1605                 {
1606                         uint8_t Rs = (opcode & 0xf00) >> 8;
1607
1608                         instruction->info.data_proc.variant = 2;
1609                         instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
1610                         instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
1611                         instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
1612
1613                         if (shift == 0x0) /* LSL */
1614                         {
1615                                 snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
1616                         }
1617                         else if (shift == 0x1) /* LSR */
1618                         {
1619                                 snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
1620                         }
1621                         else if (shift == 0x2) /* ASR */
1622                         {
1623                                 snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
1624                         }
1625                         else if (shift == 0x3) /* ROR */
1626                         {
1627                                 snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
1628                         }
1629                 }
1630         }
1631
1632         if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand> */
1633         {
1634                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
1635                                  address, opcode, mnemonic, COND(opcode),
1636                                  (S) ? "S" : "", Rd, Rn, shifter_operand);
1637         }
1638         else if ((op == 0xd) || (op == 0xf)) /* <opcode1>{<cond>}{S} <Rd>, <shifter_operand> */
1639         {
1640                 if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */
1641                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",address, opcode);
1642                 else
1643                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
1644                                  address, opcode, mnemonic, COND(opcode),
1645                                  (S) ? "S" : "", Rd, shifter_operand);
1646         }
1647         else /* <opcode2>{<cond>} <Rn>, <shifter_operand> */
1648         {
1649                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
1650                                  address, opcode, mnemonic, COND(opcode),
1651                                  Rn, shifter_operand);
1652         }
1653
1654         return ERROR_OK;
1655 }
1656
1657 int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
1658                 struct arm_instruction *instruction)
1659 {
1660         /* clear fields, to avoid confusion */
1661         memset(instruction, 0, sizeof(struct arm_instruction));
1662         instruction->opcode = opcode;
1663         instruction->instruction_size = 4;
1664
1665         /* catch opcodes with condition field [31:28] = b1111 */
1666         if ((opcode & 0xf0000000) == 0xf0000000)
1667         {
1668                 /* Undefined instruction (or ARMv5E cache preload PLD) */
1669                 if ((opcode & 0x08000000) == 0x00000000)
1670                         return evaluate_pld(opcode, address, instruction);
1671
1672                 /* Undefined instruction (or ARMv6+ SRS/RFE) */
1673                 if ((opcode & 0x0e000000) == 0x08000000)
1674                         return evaluate_srs(opcode, address, instruction);
1675
1676                 /* Branch and branch with link and change to Thumb */
1677                 if ((opcode & 0x0e000000) == 0x0a000000)
1678                         return evaluate_blx_imm(opcode, address, instruction);
1679
1680                 /* Extended coprocessor opcode space (ARMv5 and higher)*/
1681                 /* Coprocessor load/store and double register transfers */
1682                 if ((opcode & 0x0e000000) == 0x0c000000)
1683                         return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1684
1685                 /* Coprocessor data processing */
1686                 if ((opcode & 0x0f000100) == 0x0c000000)
1687                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1688
1689                 /* Coprocessor register transfers */
1690                 if ((opcode & 0x0f000010) == 0x0c000010)
1691                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1692
1693                 /* Undefined instruction */
1694                 if ((opcode & 0x0f000000) == 0x0f000000)
1695                 {
1696                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1697                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
1698                         return ERROR_OK;
1699                 }
1700         }
1701
1702         /* catch opcodes with [27:25] = b000 */
1703         if ((opcode & 0x0e000000) == 0x00000000)
1704         {
1705                 /* Multiplies, extra load/stores */
1706                 if ((opcode & 0x00000090) == 0x00000090)
1707                         return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
1708
1709                 /* Miscellaneous instructions */
1710                 if ((opcode & 0x0f900000) == 0x01000000)
1711                         return evaluate_misc_instr(opcode, address, instruction);
1712
1713                 return evaluate_data_proc(opcode, address, instruction);
1714         }
1715
1716         /* catch opcodes with [27:25] = b001 */
1717         if ((opcode & 0x0e000000) == 0x02000000)
1718         {
1719                 /* Undefined instruction */
1720                 if ((opcode & 0x0fb00000) == 0x03000000)
1721                 {
1722                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1723                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
1724                         return ERROR_OK;
1725                 }
1726
1727                 /* Move immediate to status register */
1728                 if ((opcode & 0x0fb00000) == 0x03200000)
1729                         return evaluate_mrs_msr(opcode, address, instruction);
1730
1731                 return evaluate_data_proc(opcode, address, instruction);
1732
1733         }
1734
1735         /* catch opcodes with [27:25] = b010 */
1736         if ((opcode & 0x0e000000) == 0x04000000)
1737         {
1738                 /* Load/store immediate offset */
1739                 return evaluate_load_store(opcode, address, instruction);
1740         }
1741
1742         /* catch opcodes with [27:25] = b011 */
1743         if ((opcode & 0x0e000000) == 0x06000000)
1744         {
1745                 /* Load/store register offset */
1746                 if ((opcode & 0x00000010) == 0x00000000)
1747                         return evaluate_load_store(opcode, address, instruction);
1748
1749                 /* Architecturally Undefined instruction
1750                  * ... don't expect these to ever be used
1751                  */
1752                 if ((opcode & 0x07f000f0) == 0x07f000f0)
1753                 {
1754                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1755                         snprintf(instruction->text, 128,
1756                                 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF",
1757                                 address, opcode);
1758                         return ERROR_OK;
1759                 }
1760
1761                 /* "media" instructions */
1762                 return evaluate_media(opcode, address, instruction);
1763         }
1764
1765         /* catch opcodes with [27:25] = b100 */
1766         if ((opcode & 0x0e000000) == 0x08000000)
1767         {
1768                 /* Load/store multiple */
1769                 return evaluate_ldm_stm(opcode, address, instruction);
1770         }
1771
1772         /* catch opcodes with [27:25] = b101 */
1773         if ((opcode & 0x0e000000) == 0x0a000000)
1774         {
1775                 /* Branch and branch with link */
1776                 return evaluate_b_bl(opcode, address, instruction);
1777         }
1778
1779         /* catch opcodes with [27:25] = b110 */
1780         if ((opcode & 0x0e000000) == 0x0c000000)
1781         {
1782                 /* Coprocessor load/store and double register transfers */
1783                 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1784         }
1785
1786         /* catch opcodes with [27:25] = b111 */
1787         if ((opcode & 0x0e000000) == 0x0e000000)
1788         {
1789                 /* Software interrupt */
1790                 if ((opcode & 0x0f000000) == 0x0f000000)
1791                         return evaluate_swi(opcode, address, instruction);
1792
1793                 /* Coprocessor data processing */
1794                 if ((opcode & 0x0f000010) == 0x0e000000)
1795                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1796
1797                 /* Coprocessor register transfers */
1798                 if ((opcode & 0x0f000010) == 0x0e000010)
1799                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1800         }
1801
1802         LOG_ERROR("ARM: should never reach this point (opcode=%08x)",
1803                         (unsigned) opcode);
1804         return -1;
1805 }
1806
1807 static int evaluate_b_bl_blx_thumb(uint16_t opcode,
1808                 uint32_t address, struct arm_instruction *instruction)
1809 {
1810         uint32_t offset = opcode & 0x7ff;
1811         uint32_t opc = (opcode >> 11) & 0x3;
1812         uint32_t target_address;
1813         char *mnemonic = NULL;
1814
1815         /* sign extend 11-bit offset */
1816         if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
1817                 offset = 0xfffff800 | offset;
1818
1819         target_address = address + 4 + (offset << 1);
1820
1821         switch (opc)
1822         {
1823                 /* unconditional branch */
1824                 case 0:
1825                         instruction->type = ARM_B;
1826                         mnemonic = "B";
1827                         break;
1828                 /* BLX suffix */
1829                 case 1:
1830                         instruction->type = ARM_BLX;
1831                         mnemonic = "BLX";
1832                         target_address &= 0xfffffffc;
1833                         break;
1834                 /* BL/BLX prefix */
1835                 case 2:
1836                         instruction->type = ARM_UNKNOWN_INSTUCTION;
1837                         mnemonic = "prefix";
1838                         target_address = offset << 12;
1839                         break;
1840                 /* BL suffix */
1841                 case 3:
1842                         instruction->type = ARM_BL;
1843                         mnemonic = "BL";
1844                         break;
1845         }
1846
1847         /* TODO: deal correctly with dual opcode (prefixed) BL/BLX;
1848          * these are effectively 32-bit instructions even in Thumb1.  For
1849          * disassembly, it's simplest to always use the Thumb2 decoder.
1850          *
1851          * But some cores will evidently handle them as two instructions,
1852          * where exceptions may occur between the two.  The ETMv3.2+ ID
1853          * register has a bit which exposes this behavior.
1854          */
1855
1856         snprintf(instruction->text, 128,
1857                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\t%#8.8" PRIx32,
1858                         address, opcode, mnemonic, target_address);
1859
1860         instruction->info.b_bl_bx_blx.reg_operand = -1;
1861         instruction->info.b_bl_bx_blx.target_address = target_address;
1862
1863         return ERROR_OK;
1864 }
1865
1866 static int evaluate_add_sub_thumb(uint16_t opcode,
1867                 uint32_t address, struct arm_instruction *instruction)
1868 {
1869         uint8_t Rd = (opcode >> 0) & 0x7;
1870         uint8_t Rn = (opcode >> 3) & 0x7;
1871         uint8_t Rm_imm = (opcode >> 6) & 0x7;
1872         uint32_t opc = opcode & (1 << 9);
1873         uint32_t reg_imm  = opcode & (1 << 10);
1874         char *mnemonic;
1875
1876         if (opc)
1877         {
1878                 instruction->type = ARM_SUB;
1879                 mnemonic = "SUBS";
1880         }
1881         else
1882         {
1883                 /* REVISIT:  if reg_imm == 0, display as "MOVS" */
1884                 instruction->type = ARM_ADD;
1885                 mnemonic = "ADDS";
1886         }
1887
1888         instruction->info.data_proc.Rd = Rd;
1889         instruction->info.data_proc.Rn = Rn;
1890         instruction->info.data_proc.S = 1;
1891
1892         if (reg_imm)
1893         {
1894                 instruction->info.data_proc.variant = 0; /*immediate*/
1895                 instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
1896                 snprintf(instruction->text, 128,
1897                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, #%d",
1898                         address, opcode, mnemonic, Rd, Rn, Rm_imm);
1899         }
1900         else
1901         {
1902                 instruction->info.data_proc.variant = 1; /*immediate shift*/
1903                 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
1904                 snprintf(instruction->text, 128,
1905                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, r%i",
1906                         address, opcode, mnemonic, Rd, Rn, Rm_imm);
1907         }
1908
1909         return ERROR_OK;
1910 }
1911
1912 static int evaluate_shift_imm_thumb(uint16_t opcode,
1913                 uint32_t address, struct arm_instruction *instruction)
1914 {
1915         uint8_t Rd = (opcode >> 0) & 0x7;
1916         uint8_t Rm = (opcode >> 3) & 0x7;
1917         uint8_t imm = (opcode >> 6) & 0x1f;
1918         uint8_t opc = (opcode >> 11) & 0x3;
1919         char *mnemonic = NULL;
1920
1921         switch (opc)
1922         {
1923                 case 0:
1924                         instruction->type = ARM_MOV;
1925                         mnemonic = "LSLS";
1926                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
1927                         break;
1928                 case 1:
1929                         instruction->type = ARM_MOV;
1930                         mnemonic = "LSRS";
1931                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
1932                         break;
1933                 case 2:
1934                         instruction->type = ARM_MOV;
1935                         mnemonic = "ASRS";
1936                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
1937                         break;
1938         }
1939
1940         if ((imm == 0) && (opc != 0))
1941                 imm = 32;
1942
1943         instruction->info.data_proc.Rd = Rd;
1944         instruction->info.data_proc.Rn = -1;
1945         instruction->info.data_proc.S = 1;
1946
1947         instruction->info.data_proc.variant = 1; /*immediate_shift*/
1948         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1949         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
1950
1951         snprintf(instruction->text, 128,
1952                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, #%#2.2x" ,
1953                         address, opcode, mnemonic, Rd, Rm, imm);
1954
1955         return ERROR_OK;
1956 }
1957
1958 static int evaluate_data_proc_imm_thumb(uint16_t opcode,
1959                 uint32_t address, struct arm_instruction *instruction)
1960 {
1961         uint8_t imm = opcode & 0xff;
1962         uint8_t Rd = (opcode >> 8) & 0x7;
1963         uint32_t opc = (opcode >> 11) & 0x3;
1964         char *mnemonic = NULL;
1965
1966         instruction->info.data_proc.Rd = Rd;
1967         instruction->info.data_proc.Rn = Rd;
1968         instruction->info.data_proc.S = 1;
1969         instruction->info.data_proc.variant = 0; /*immediate*/
1970         instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
1971
1972         switch (opc)
1973         {
1974                 case 0:
1975                         instruction->type = ARM_MOV;
1976                         mnemonic = "MOVS";
1977                         instruction->info.data_proc.Rn = -1;
1978                         break;
1979                 case 1:
1980                         instruction->type = ARM_CMP;
1981                         mnemonic = "CMP";
1982                         instruction->info.data_proc.Rd = -1;
1983                         break;
1984                 case 2:
1985                         instruction->type = ARM_ADD;
1986                         mnemonic = "ADDS";
1987                         break;
1988                 case 3:
1989                         instruction->type = ARM_SUB;
1990                         mnemonic = "SUBS";
1991                         break;
1992         }
1993
1994         snprintf(instruction->text, 128,
1995                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, #%#2.2x",
1996                         address, opcode, mnemonic, Rd, imm);
1997
1998         return ERROR_OK;
1999 }
2000
2001 static int evaluate_data_proc_thumb(uint16_t opcode,
2002                 uint32_t address, struct arm_instruction *instruction)
2003 {
2004         uint8_t high_reg, op, Rm, Rd,H1,H2;
2005         char *mnemonic = NULL;
2006         bool nop = false;
2007
2008         high_reg = (opcode & 0x0400) >> 10;
2009         op = (opcode & 0x03C0) >> 6;
2010
2011         Rd = (opcode & 0x0007);
2012         Rm = (opcode & 0x0038) >> 3;
2013         H1 = (opcode & 0x0080) >> 7;
2014         H2 = (opcode & 0x0040) >> 6;
2015
2016         instruction->info.data_proc.Rd = Rd;
2017         instruction->info.data_proc.Rn = Rd;
2018         instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
2019         instruction->info.data_proc.variant = 1 /*immediate shift*/;
2020         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2021
2022         if (high_reg)
2023         {
2024                 Rd |= H1 << 3;
2025                 Rm |= H2 << 3;
2026                 op >>= 2;
2027
2028                 switch (op)
2029                 {
2030                         case 0x0:
2031                                 instruction->type = ARM_ADD;
2032                                 mnemonic = "ADD";
2033                                 break;
2034                         case 0x1:
2035                                 instruction->type = ARM_CMP;
2036                                 mnemonic = "CMP";
2037                                 break;
2038                         case 0x2:
2039                                 instruction->type = ARM_MOV;
2040                                 mnemonic = "MOV";
2041                                 if (Rd == Rm)
2042                                         nop = true;
2043                                 break;
2044                         case 0x3:
2045                                 if ((opcode & 0x7) == 0x0)
2046                                 {
2047                                         instruction->info.b_bl_bx_blx.reg_operand = Rm;
2048                                         if (H1)
2049                                         {
2050                                                 instruction->type = ARM_BLX;
2051                                                 snprintf(instruction->text, 128,
2052                                                         "0x%8.8" PRIx32
2053                                                         "  0x%4.4x    \tBLX\tr%i",
2054                                                         address, opcode, Rm);
2055                                         }
2056                                         else
2057                                         {
2058                                                 instruction->type = ARM_BX;
2059                                                 snprintf(instruction->text, 128,
2060                                                         "0x%8.8" PRIx32
2061                                                         "  0x%4.4x    \tBX\tr%i",
2062                                                         address, opcode, Rm);
2063                                         }
2064                                 }
2065                                 else
2066                                 {
2067                                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
2068                                         snprintf(instruction->text, 128,
2069                                                 "0x%8.8" PRIx32
2070                                                 "  0x%4.4x    \t"
2071                                                 "UNDEFINED INSTRUCTION",
2072                                                 address, opcode);
2073                                 }
2074                                 return ERROR_OK;
2075                                 break;
2076                 }
2077         }
2078         else
2079         {
2080                 switch (op)
2081                 {
2082                         case 0x0:
2083                                 instruction->type = ARM_AND;
2084                                 mnemonic = "ANDS";
2085                                 break;
2086                         case 0x1:
2087                                 instruction->type = ARM_EOR;
2088                                 mnemonic = "EORS";
2089                                 break;
2090                         case 0x2:
2091                                 instruction->type = ARM_MOV;
2092                                 mnemonic = "LSLS";
2093                                 instruction->info.data_proc.variant = 2 /*register shift*/;
2094                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
2095                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2096                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2097                                 break;
2098                         case 0x3:
2099                                 instruction->type = ARM_MOV;
2100                                 mnemonic = "LSRS";
2101                                 instruction->info.data_proc.variant = 2 /*register shift*/;
2102                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
2103                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2104                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2105                                 break;
2106                         case 0x4:
2107                                 instruction->type = ARM_MOV;
2108                                 mnemonic = "ASRS";
2109                                 instruction->info.data_proc.variant = 2 /*register shift*/;
2110                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
2111                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2112                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2113                                 break;
2114                         case 0x5:
2115                                 instruction->type = ARM_ADC;
2116                                 mnemonic = "ADCS";
2117                                 break;
2118                         case 0x6:
2119                                 instruction->type = ARM_SBC;
2120                                 mnemonic = "SBCS";
2121                                 break;
2122                         case 0x7:
2123                                 instruction->type = ARM_MOV;
2124                                 mnemonic = "RORS";
2125                                 instruction->info.data_proc.variant = 2 /*register shift*/;
2126                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
2127                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2128                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2129                                 break;
2130                         case 0x8:
2131                                 instruction->type = ARM_TST;
2132                                 mnemonic = "TST";
2133                                 break;
2134                         case 0x9:
2135                                 instruction->type = ARM_RSB;
2136                                 mnemonic = "RSBS";
2137                                 instruction->info.data_proc.variant = 0 /*immediate*/;
2138                                 instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
2139                                 instruction->info.data_proc.Rn = Rm;
2140                                 break;
2141                         case 0xA:
2142                                 instruction->type = ARM_CMP;
2143                                 mnemonic = "CMP";
2144                                 break;
2145                         case 0xB:
2146                                 instruction->type = ARM_CMN;
2147                                 mnemonic = "CMN";
2148                                 break;
2149                         case 0xC:
2150                                 instruction->type = ARM_ORR;
2151                                 mnemonic = "ORRS";
2152                                 break;
2153                         case 0xD:
2154                                 instruction->type = ARM_MUL;
2155                                 mnemonic = "MULS";
2156                                 break;
2157                         case 0xE:
2158                                 instruction->type = ARM_BIC;
2159                                 mnemonic = "BICS";
2160                                 break;
2161                         case 0xF:
2162                                 instruction->type = ARM_MVN;
2163                                 mnemonic = "MVNS";
2164                                 break;
2165                 }
2166         }
2167
2168         if (nop)
2169                 snprintf(instruction->text, 128,
2170                                 "0x%8.8" PRIx32 "  0x%4.4x    \tNOP\t\t\t"
2171                                 "; (%s r%i, r%i)",
2172                                  address, opcode, mnemonic, Rd, Rm);
2173         else
2174                 snprintf(instruction->text, 128,
2175                                 "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i",
2176                                  address, opcode, mnemonic, Rd, Rm);
2177
2178         return ERROR_OK;
2179 }
2180
2181 /* PC-relative data addressing is word-aligned even with Thumb */
2182 static inline uint32_t thumb_alignpc4(uint32_t addr)
2183 {
2184         return (addr + 4) & ~3;
2185 }
2186
2187 static int evaluate_load_literal_thumb(uint16_t opcode,
2188                 uint32_t address, struct arm_instruction *instruction)
2189 {
2190         uint32_t immediate;
2191         uint8_t Rd = (opcode >> 8) & 0x7;
2192
2193         instruction->type = ARM_LDR;
2194         immediate = opcode & 0x000000ff;
2195         immediate *= 4;
2196
2197         instruction->info.load_store.Rd = Rd;
2198         instruction->info.load_store.Rn = 15 /*PC*/;
2199         instruction->info.load_store.index_mode = 0; /*offset*/
2200         instruction->info.load_store.offset_mode = 0; /*immediate*/
2201         instruction->info.load_store.offset.offset = immediate;
2202
2203         snprintf(instruction->text, 128,
2204                 "0x%8.8" PRIx32 "  0x%4.4x    \t"
2205                 "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32,
2206                 address, opcode, Rd, immediate,
2207                 thumb_alignpc4(address) + immediate);
2208
2209         return ERROR_OK;
2210 }
2211
2212 static int evaluate_load_store_reg_thumb(uint16_t opcode,
2213                 uint32_t address, struct arm_instruction *instruction)
2214 {
2215         uint8_t Rd = (opcode >> 0) & 0x7;
2216         uint8_t Rn = (opcode >> 3) & 0x7;
2217         uint8_t Rm = (opcode >> 6) & 0x7;
2218         uint8_t opc = (opcode >> 9) & 0x7;
2219         char *mnemonic = NULL;
2220
2221         switch (opc)
2222         {
2223                 case 0:
2224                         instruction->type = ARM_STR;
2225                         mnemonic = "STR";
2226                         break;
2227                 case 1:
2228                         instruction->type = ARM_STRH;
2229                         mnemonic = "STRH";
2230                         break;
2231                 case 2:
2232                         instruction->type = ARM_STRB;
2233                         mnemonic = "STRB";
2234                         break;
2235                 case 3:
2236                         instruction->type = ARM_LDRSB;
2237                         mnemonic = "LDRSB";
2238                         break;
2239                 case 4:
2240                         instruction->type = ARM_LDR;
2241                         mnemonic = "LDR";
2242                         break;
2243                 case 5:
2244                         instruction->type = ARM_LDRH;
2245                         mnemonic = "LDRH";
2246                         break;
2247                 case 6:
2248                         instruction->type = ARM_LDRB;
2249                         mnemonic = "LDRB";
2250                         break;
2251                 case 7:
2252                         instruction->type = ARM_LDRSH;
2253                         mnemonic = "LDRSH";
2254                         break;
2255         }
2256
2257         snprintf(instruction->text, 128,
2258                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, [r%i, r%i]",
2259                         address, opcode, mnemonic, Rd, Rn, Rm);
2260
2261         instruction->info.load_store.Rd = Rd;
2262         instruction->info.load_store.Rn = Rn;
2263         instruction->info.load_store.index_mode = 0; /*offset*/
2264         instruction->info.load_store.offset_mode = 1; /*register*/
2265         instruction->info.load_store.offset.reg.Rm = Rm;
2266
2267         return ERROR_OK;
2268 }
2269
2270 static int evaluate_load_store_imm_thumb(uint16_t opcode,
2271                 uint32_t address, struct arm_instruction *instruction)
2272 {
2273         uint32_t offset = (opcode >> 6) & 0x1f;
2274         uint8_t Rd = (opcode >> 0) & 0x7;
2275         uint8_t Rn = (opcode >> 3) & 0x7;
2276         uint32_t L = opcode & (1 << 11);
2277         uint32_t B = opcode & (1 << 12);
2278         char *mnemonic;
2279         char suffix = ' ';
2280         uint32_t shift = 2;
2281
2282         if (L)
2283         {
2284                 instruction->type = ARM_LDR;
2285                 mnemonic = "LDR";
2286         }
2287         else
2288         {
2289                 instruction->type = ARM_STR;
2290                 mnemonic = "STR";
2291         }
2292
2293         if ((opcode&0xF000) == 0x8000)
2294         {
2295                 suffix = 'H';
2296                 shift = 1;
2297         }
2298         else if (B)
2299         {
2300                 suffix = 'B';
2301                 shift = 0;
2302         }
2303
2304         snprintf(instruction->text, 128,
2305                 "0x%8.8" PRIx32 "  0x%4.4x    \t%s%c\tr%i, [r%i, #%#" PRIx32 "]",
2306                 address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
2307
2308         instruction->info.load_store.Rd = Rd;
2309         instruction->info.load_store.Rn = Rn;
2310         instruction->info.load_store.index_mode = 0; /*offset*/
2311         instruction->info.load_store.offset_mode = 0; /*immediate*/
2312         instruction->info.load_store.offset.offset = offset << shift;
2313
2314         return ERROR_OK;
2315 }
2316
2317 static int evaluate_load_store_stack_thumb(uint16_t opcode,
2318                 uint32_t address, struct arm_instruction *instruction)
2319 {
2320         uint32_t offset = opcode  & 0xff;
2321         uint8_t Rd = (opcode >> 8) & 0x7;
2322         uint32_t L = opcode & (1 << 11);
2323         char *mnemonic;
2324
2325         if (L)
2326         {
2327                 instruction->type = ARM_LDR;
2328                 mnemonic = "LDR";
2329         }
2330         else
2331         {
2332                 instruction->type = ARM_STR;
2333                 mnemonic = "STR";
2334         }
2335
2336         snprintf(instruction->text, 128,
2337                 "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, [SP, #%#" PRIx32 "]",
2338                 address, opcode, mnemonic, Rd, offset*4);
2339
2340         instruction->info.load_store.Rd = Rd;
2341         instruction->info.load_store.Rn = 13 /*SP*/;
2342         instruction->info.load_store.index_mode = 0; /*offset*/
2343         instruction->info.load_store.offset_mode = 0; /*immediate*/
2344         instruction->info.load_store.offset.offset = offset*4;
2345
2346         return ERROR_OK;
2347 }
2348
2349 static int evaluate_add_sp_pc_thumb(uint16_t opcode,
2350                 uint32_t address, struct arm_instruction *instruction)
2351 {
2352         uint32_t imm = opcode  & 0xff;
2353         uint8_t Rd = (opcode >> 8) & 0x7;
2354         uint8_t Rn;
2355         uint32_t SP = opcode & (1 << 11);
2356         char *reg_name;
2357
2358         instruction->type = ARM_ADD;
2359
2360         if (SP)
2361         {
2362                 reg_name = "SP";
2363                 Rn = 13;
2364         }
2365         else
2366         {
2367                 reg_name = "PC";
2368                 Rn = 15;
2369         }
2370
2371         snprintf(instruction->text, 128,
2372                 "0x%8.8" PRIx32 "  0x%4.4x  \tADD\tr%i, %s, #%#" PRIx32,
2373                 address, opcode, Rd, reg_name, imm * 4);
2374
2375         instruction->info.data_proc.variant = 0 /* immediate */;
2376         instruction->info.data_proc.Rd = Rd;
2377         instruction->info.data_proc.Rn = Rn;
2378         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2379
2380         return ERROR_OK;
2381 }
2382
2383 static int evaluate_adjust_stack_thumb(uint16_t opcode,
2384                 uint32_t address, struct arm_instruction *instruction)
2385 {
2386         uint32_t imm = opcode  & 0x7f;
2387         uint8_t opc = opcode & (1 << 7);
2388         char *mnemonic;
2389
2390
2391         if (opc)
2392         {
2393                 instruction->type = ARM_SUB;
2394                 mnemonic = "SUB";
2395         }
2396         else
2397         {
2398                 instruction->type = ARM_ADD;
2399                 mnemonic = "ADD";
2400         }
2401
2402         snprintf(instruction->text, 128,
2403                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tSP, #%#" PRIx32,
2404                         address, opcode, mnemonic, imm*4);
2405
2406         instruction->info.data_proc.variant = 0 /* immediate */;
2407         instruction->info.data_proc.Rd = 13 /*SP*/;
2408         instruction->info.data_proc.Rn = 13 /*SP*/;
2409         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2410
2411         return ERROR_OK;
2412 }
2413
2414 static int evaluate_breakpoint_thumb(uint16_t opcode,
2415                 uint32_t address, struct arm_instruction *instruction)
2416 {
2417         uint32_t imm = opcode  & 0xff;
2418
2419         instruction->type = ARM_BKPT;
2420
2421         snprintf(instruction->text, 128,
2422                         "0x%8.8" PRIx32 "  0x%4.4x  \tBKPT\t%#2.2" PRIx32 "",
2423                         address, opcode, imm);
2424
2425         return ERROR_OK;
2426 }
2427
2428 static int evaluate_load_store_multiple_thumb(uint16_t opcode,
2429                 uint32_t address, struct arm_instruction *instruction)
2430 {
2431         uint32_t reg_list = opcode  & 0xff;
2432         uint32_t L = opcode & (1 << 11);
2433         uint32_t R = opcode & (1 << 8);
2434         uint8_t Rn = (opcode >> 8) & 7;
2435         uint8_t addr_mode = 0 /* IA */;
2436         char reg_names[40];
2437         char *reg_names_p;
2438         char *mnemonic;
2439         char ptr_name[7] = "";
2440         int i;
2441
2442         /* REVISIT:  in ThumbEE mode, there are no LDM or STM instructions.
2443          * The STMIA and LDMIA opcodes are used for other instructions.
2444          */
2445
2446         if ((opcode & 0xf000) == 0xc000)
2447         { /* generic load/store multiple */
2448                 char *wback = "!";
2449
2450                 if (L)
2451                 {
2452                         instruction->type = ARM_LDM;
2453                         mnemonic = "LDM";
2454                         if (opcode & (1 << Rn))
2455                                 wback = "";
2456                 }
2457                 else
2458                 {
2459                         instruction->type = ARM_STM;
2460                         mnemonic = "STM";
2461                 }
2462                 snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback);
2463         }
2464         else
2465         { /* push/pop */
2466                 Rn = 13; /* SP */
2467                 if (L)
2468                 {
2469                         instruction->type = ARM_LDM;
2470                         mnemonic = "POP";
2471                         if (R)
2472                                 reg_list |= (1 << 15) /*PC*/;
2473                 }
2474                 else
2475                 {
2476                         instruction->type = ARM_STM;
2477                         mnemonic = "PUSH";
2478                         addr_mode = 3; /*DB*/
2479                         if (R)
2480                                 reg_list |= (1 << 14) /*LR*/;
2481                 }
2482         }
2483
2484         reg_names_p = reg_names;
2485         for (i = 0; i <= 15; i++)
2486         {
2487                 if (reg_list & (1 << i))
2488                         reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i);
2489         }
2490         if (reg_names_p > reg_names)
2491                 reg_names_p[-2] = '\0';
2492         else /* invalid op : no registers */
2493                 reg_names[0] = '\0';
2494
2495         snprintf(instruction->text, 128,
2496                         "0x%8.8" PRIx32 "  0x%4.4x  \t%s\t%s{%s}",
2497                         address, opcode, mnemonic, ptr_name, reg_names);
2498
2499         instruction->info.load_store_multiple.register_list = reg_list;
2500         instruction->info.load_store_multiple.Rn = Rn;
2501         instruction->info.load_store_multiple.addressing_mode = addr_mode;
2502
2503         return ERROR_OK;
2504 }
2505
2506 static int evaluate_cond_branch_thumb(uint16_t opcode,
2507                 uint32_t address, struct arm_instruction *instruction)
2508 {
2509         uint32_t offset = opcode  & 0xff;
2510         uint8_t cond = (opcode >> 8) & 0xf;
2511         uint32_t target_address;
2512
2513         if (cond == 0xf)
2514         {
2515                 instruction->type = ARM_SWI;
2516                 snprintf(instruction->text, 128,
2517                                 "0x%8.8" PRIx32 "  0x%4.4x    \tSVC\t%#2.2" PRIx32,
2518                                 address, opcode, offset);
2519                 return ERROR_OK;
2520         }
2521         else if (cond == 0xe)
2522         {
2523                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2524                 snprintf(instruction->text, 128,
2525                         "0x%8.8" PRIx32 "  0x%4.4x    \tUNDEFINED INSTRUCTION",
2526                         address, opcode);
2527                 return ERROR_OK;
2528         }
2529
2530         /* sign extend 8-bit offset */
2531         if (offset & 0x00000080)
2532                 offset = 0xffffff00 | offset;
2533
2534         target_address = address + 4 + (offset << 1);
2535
2536         snprintf(instruction->text, 128,
2537                         "0x%8.8" PRIx32 "  0x%4.4x    \tB%s\t%#8.8" PRIx32,
2538                         address, opcode,
2539                         arm_condition_strings[cond], target_address);
2540
2541         instruction->type = ARM_B;
2542         instruction->info.b_bl_bx_blx.reg_operand = -1;
2543         instruction->info.b_bl_bx_blx.target_address = target_address;
2544
2545         return ERROR_OK;
2546 }
2547
2548 static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
2549                 struct arm_instruction *instruction)
2550 {
2551         unsigned offset;
2552
2553         /* added in Thumb2 */
2554         offset = (opcode >> 3) & 0x1f;
2555         offset |= (opcode & 0x0200) >> 4;
2556
2557         snprintf(instruction->text, 128,
2558                         "0x%8.8" PRIx32 "  0x%4.4x    \tCB%sZ\tr%d, %#8.8" PRIx32,
2559                         address, opcode,
2560                         (opcode & 0x0800) ? "N" : "",
2561                         opcode & 0x7, address + 4 + (offset << 1));
2562
2563         return ERROR_OK;
2564 }
2565
2566 static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
2567                 struct arm_instruction *instruction)
2568 {
2569         /* added in ARMv6 */
2570         snprintf(instruction->text, 128,
2571                         "0x%8.8" PRIx32 "  0x%4.4x    \t%cXT%c\tr%d, r%d",
2572                         address, opcode,
2573                         (opcode & 0x0080) ? 'U' : 'S',
2574                         (opcode & 0x0040) ? 'B' : 'H',
2575                         opcode & 0x7, (opcode >> 3) & 0x7);
2576
2577         return ERROR_OK;
2578 }
2579
2580 static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
2581                 struct arm_instruction *instruction)
2582 {
2583         /* added in ARMv6 */
2584         if ((opcode & 0x0ff0) == 0x0650)
2585                 snprintf(instruction->text, 128,
2586                                 "0x%8.8" PRIx32 "  0x%4.4x    \tSETEND %s",
2587                                 address, opcode,
2588                                 (opcode & 0x80) ? "BE" : "LE");
2589         else /* ASSUME (opcode & 0x0fe0) == 0x0660 */
2590                 snprintf(instruction->text, 128,
2591                                 "0x%8.8" PRIx32 "  0x%4.4x    \tCPSI%c\t%s%s%s",
2592                                 address, opcode,
2593                                 (opcode & 0x0010) ? 'D' : 'E',
2594                                 (opcode & 0x0004) ? "A" : "",
2595                                 (opcode & 0x0002) ? "I" : "",
2596                                 (opcode & 0x0001) ? "F" : "");
2597
2598         return ERROR_OK;
2599 }
2600
2601 static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
2602                 struct arm_instruction *instruction)
2603 {
2604         char *suffix;
2605
2606         /* added in ARMv6 */
2607         switch ((opcode >> 6) & 3) {
2608         case 0:
2609                 suffix = "";
2610                 break;
2611         case 1:
2612                 suffix = "16";
2613                 break;
2614         default:
2615                 suffix = "SH";
2616                 break;
2617         }
2618         snprintf(instruction->text, 128,
2619                         "0x%8.8" PRIx32 "  0x%4.4x    \tREV%s\tr%d, r%d",
2620                         address, opcode, suffix,
2621                         opcode & 0x7, (opcode >> 3) & 0x7);
2622
2623         return ERROR_OK;
2624 }
2625
2626 static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
2627                 struct arm_instruction *instruction)
2628 {
2629         char *hint;
2630
2631         switch ((opcode >> 4) & 0x0f) {
2632         case 0:
2633                 hint = "NOP";
2634                 break;
2635         case 1:
2636                 hint = "YIELD";
2637                 break;
2638         case 2:
2639                 hint = "WFE";
2640                 break;
2641         case 3:
2642                 hint = "WFI";
2643                 break;
2644         case 4:
2645                 hint = "SEV";
2646                 break;
2647         default:
2648                 hint = "HINT (UNRECOGNIZED)";
2649                 break;
2650         }
2651
2652         snprintf(instruction->text, 128,
2653                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s",
2654                         address, opcode, hint);
2655
2656         return ERROR_OK;
2657 }
2658
2659 static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
2660                 struct arm_instruction *instruction)
2661 {
2662         unsigned cond = (opcode >> 4) & 0x0f;
2663         char *x = "", *y = "", *z = "";
2664
2665         if (opcode & 0x01)
2666                 z = (opcode & 0x02) ? "T" : "E";
2667         if (opcode & 0x03)
2668                 y = (opcode & 0x04) ? "T" : "E";
2669         if (opcode & 0x07)
2670                 x = (opcode & 0x08) ? "T" : "E";
2671
2672         snprintf(instruction->text, 128,
2673                         "0x%8.8" PRIx32 "  0x%4.4x    \tIT%s%s%s\t%s",
2674                         address, opcode,
2675                         x, y, z, arm_condition_strings[cond]);
2676
2677         /* NOTE:  strictly speaking, the next 1-4 instructions should
2678          * now be displayed with the relevant conditional suffix...
2679          */
2680
2681         return ERROR_OK;
2682 }
2683
2684 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
2685 {
2686         /* clear fields, to avoid confusion */
2687         memset(instruction, 0, sizeof(struct arm_instruction));
2688         instruction->opcode = opcode;
2689         instruction->instruction_size = 2;
2690
2691         if ((opcode & 0xe000) == 0x0000)
2692         {
2693                 /* add/substract register or immediate */
2694                 if ((opcode & 0x1800) == 0x1800)
2695                         return evaluate_add_sub_thumb(opcode, address, instruction);
2696                 /* shift by immediate */
2697                 else
2698                         return evaluate_shift_imm_thumb(opcode, address, instruction);
2699         }
2700
2701         /* Add/substract/compare/move immediate */
2702         if ((opcode & 0xe000) == 0x2000)
2703         {
2704                 return evaluate_data_proc_imm_thumb(opcode, address, instruction);
2705         }
2706
2707         /* Data processing instructions */
2708         if ((opcode & 0xf800) == 0x4000)
2709         {
2710                 return evaluate_data_proc_thumb(opcode, address, instruction);
2711         }
2712
2713         /* Load from literal pool */
2714         if ((opcode & 0xf800) == 0x4800)
2715         {
2716                 return evaluate_load_literal_thumb(opcode, address, instruction);
2717         }
2718
2719         /* Load/Store register offset */
2720         if ((opcode & 0xf000) == 0x5000)
2721         {
2722                 return evaluate_load_store_reg_thumb(opcode, address, instruction);
2723         }
2724
2725         /* Load/Store immediate offset */
2726         if (((opcode & 0xe000) == 0x6000)
2727                 ||((opcode & 0xf000) == 0x8000))
2728         {
2729                 return evaluate_load_store_imm_thumb(opcode, address, instruction);
2730         }
2731
2732         /* Load/Store from/to stack */
2733         if ((opcode & 0xf000) == 0x9000)
2734         {
2735                 return evaluate_load_store_stack_thumb(opcode, address, instruction);
2736         }
2737
2738         /* Add to SP/PC */
2739         if ((opcode & 0xf000) == 0xa000)
2740         {
2741                 return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2742         }
2743
2744         /* Misc */
2745         if ((opcode & 0xf000) == 0xb000)
2746         {
2747                 switch ((opcode >> 8) & 0x0f) {
2748                 case 0x0:
2749                         return evaluate_adjust_stack_thumb(opcode, address, instruction);
2750                 case 0x1:
2751                 case 0x3:
2752                 case 0x9:
2753                 case 0xb:
2754                         return evaluate_cb_thumb(opcode, address, instruction);
2755                 case 0x2:
2756                         return evaluate_extend_thumb(opcode, address, instruction);
2757                 case 0x4:
2758                 case 0x5:
2759                 case 0xc:
2760                 case 0xd:
2761                         return evaluate_load_store_multiple_thumb(opcode, address,
2762                                                 instruction);
2763                 case 0x6:
2764                         return evaluate_cps_thumb(opcode, address, instruction);
2765                 case 0xa:
2766                         if ((opcode & 0x00c0) == 0x0080)
2767                                 break;
2768                         return evaluate_byterev_thumb(opcode, address, instruction);
2769                 case 0xe:
2770                         return evaluate_breakpoint_thumb(opcode, address, instruction);
2771                 case 0xf:
2772                         if (opcode & 0x000f)
2773                                 return evaluate_ifthen_thumb(opcode, address,
2774                                                 instruction);
2775                         else
2776                                 return evaluate_hint_thumb(opcode, address,
2777                                                 instruction);
2778                 }
2779
2780                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2781                 snprintf(instruction->text, 128,
2782                         "0x%8.8" PRIx32 "  0x%4.4x    \tUNDEFINED INSTRUCTION",
2783                         address, opcode);
2784                 return ERROR_OK;
2785         }
2786
2787         /* Load/Store multiple */
2788         if ((opcode & 0xf000) == 0xc000)
2789         {
2790                 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2791         }
2792
2793         /* Conditional branch + SWI */
2794         if ((opcode & 0xf000) == 0xd000)
2795         {
2796                 return evaluate_cond_branch_thumb(opcode, address, instruction);
2797         }
2798
2799         if ((opcode & 0xe000) == 0xe000)
2800         {
2801                 /* Undefined instructions */
2802                 if ((opcode & 0xf801) == 0xe801)
2803                 {
2804                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
2805                         snprintf(instruction->text, 128,
2806                                         "0x%8.8" PRIx32 "  0x%8.8x\t"
2807                                         "UNDEFINED INSTRUCTION",
2808                                         address, opcode);
2809                         return ERROR_OK;
2810                 }
2811                 else
2812                 { /* Branch to offset */
2813                         return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2814                 }
2815         }
2816
2817         LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
2818         return -1;
2819 }
2820
2821 static int t2ev_b_bl(uint32_t opcode, uint32_t address,
2822                 struct arm_instruction *instruction, char *cp)
2823 {
2824         unsigned offset;
2825         unsigned b21 = 1 << 21;
2826         unsigned b22 = 1 << 22;
2827
2828         /* instead of combining two smaller 16-bit branch instructions,
2829          * Thumb2 uses only one larger 32-bit instruction.
2830          */
2831         offset = opcode & 0x7ff;
2832         offset |= (opcode & 0x03ff0000) >> 5;
2833         if (opcode & (1 << 26)) {
2834                 offset |= 0xff << 23;
2835                 if ((opcode & (1 << 11)) == 0)
2836                         b21 = 0;
2837                 if ((opcode & (1 << 13)) == 0)
2838                         b22 = 0;
2839         } else {
2840                 if (opcode & (1 << 11))
2841                         b21 = 0;
2842                 if (opcode & (1 << 13))
2843                         b22 = 0;
2844         }
2845         offset |= b21;
2846         offset |= b22;
2847
2848
2849         address += 4;
2850         address += offset << 1;
2851
2852         instruction->type = (opcode & (1 << 14)) ? ARM_BL : ARM_B;
2853         instruction->info.b_bl_bx_blx.reg_operand = -1;
2854         instruction->info.b_bl_bx_blx.target_address = address;
2855         sprintf(cp, "%s\t%#8.8" PRIx32,
2856                         (opcode & (1 << 14)) ? "BL" : "B.W",
2857                         address);
2858
2859         return ERROR_OK;
2860 }
2861
2862 static int t2ev_cond_b(uint32_t opcode, uint32_t address,
2863                 struct arm_instruction *instruction, char *cp)
2864 {
2865         unsigned offset;
2866         unsigned b17 = 1 << 17;
2867         unsigned b18 = 1 << 18;
2868         unsigned cond = (opcode >> 22) & 0x0f;
2869
2870         offset = opcode & 0x7ff;
2871         offset |= (opcode & 0x003f0000) >> 5;
2872         if (opcode & (1 << 26)) {
2873                 offset |= 0xffff << 19;
2874                 if ((opcode & (1 << 11)) == 0)
2875                         b17 = 0;
2876                 if ((opcode & (1 << 13)) == 0)
2877                         b18 = 0;
2878         } else {
2879                 if (opcode & (1 << 11))
2880                         b17 = 0;
2881                 if (opcode & (1 << 13))
2882                         b18 = 0;
2883         }
2884         offset |= b17;
2885         offset |= b18;
2886
2887         address += 4;
2888         address += offset << 1;
2889
2890         instruction->type = ARM_B;
2891         instruction->info.b_bl_bx_blx.reg_operand = -1;
2892         instruction->info.b_bl_bx_blx.target_address = address;
2893         sprintf(cp, "B%s.W\t%#8.8" PRIx32,
2894                         arm_condition_strings[cond],
2895                         address);
2896
2897         return ERROR_OK;
2898 }
2899
2900 static const char *special_name(int number)
2901 {
2902         char *special = "(RESERVED)";
2903
2904         switch (number) {
2905         case 0:
2906                 special = "apsr";
2907                 break;
2908         case 1:
2909                 special = "iapsr";
2910                 break;
2911         case 2:
2912                 special = "eapsr";
2913                 break;
2914         case 3:
2915                 special = "xpsr";
2916                 break;
2917         case 5:
2918                 special = "ipsr";
2919                 break;
2920         case 6:
2921                 special = "epsr";
2922                 break;
2923         case 7:
2924                 special = "iepsr";
2925                 break;
2926         case 8:
2927                 special = "msp";
2928                 break;
2929         case 9:
2930                 special = "psp";
2931                 break;
2932         case 16:
2933                 special = "primask";
2934                 break;
2935         case 17:
2936                 special = "basepri";
2937                 break;
2938         case 18:
2939                 special = "basepri_max";
2940                 break;
2941         case 19:
2942                 special = "faultmask";
2943                 break;
2944         case 20:
2945                 special = "control";
2946                 break;
2947         }
2948         return special;
2949 }
2950
2951 static int t2ev_hint(uint32_t opcode, uint32_t address,
2952                 struct arm_instruction *instruction, char *cp)
2953 {
2954         const char *mnemonic;
2955
2956         if (opcode & 0x0700) {
2957                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2958                 strcpy(cp, "UNDEFINED");
2959                 return ERROR_OK;
2960         }
2961
2962         if (opcode & 0x00f0) {
2963                 sprintf(cp, "DBG\t#%d", (int) opcode & 0xf);
2964                 return ERROR_OK;
2965         }
2966
2967         switch (opcode & 0x0f) {
2968         case 0:
2969                 mnemonic = "NOP.W";
2970                 break;
2971         case 1:
2972                 mnemonic = "YIELD.W";
2973                 break;
2974         case 2:
2975                 mnemonic = "WFE.W";
2976                 break;
2977         case 3:
2978                 mnemonic = "WFI.W";
2979                 break;
2980         case 4:
2981                 mnemonic = "SEV.W";
2982                 break;
2983         default:
2984                 mnemonic = "HINT.W (UNRECOGNIZED)";
2985                 break;
2986         }
2987         strcpy(cp, mnemonic);
2988         return ERROR_OK;
2989 }
2990
2991 static int t2ev_misc(uint32_t opcode, uint32_t address,
2992                 struct arm_instruction *instruction, char *cp)
2993 {
2994         const char *mnemonic;
2995
2996         switch ((opcode >> 4) & 0x0f) {
2997         case 0:
2998                 mnemonic = "LEAVEX";
2999                 break;
3000         case 1:
3001                 mnemonic = "ENTERX";
3002                 break;
3003         case 2:
3004                 mnemonic = "CLREX";
3005                 break;
3006         case 4:
3007                 mnemonic = "DSB";
3008                 break;
3009         case 5:
3010                 mnemonic = "DMB";
3011                 break;
3012         case 6:
3013                 mnemonic = "ISB";
3014                 break;
3015         default:
3016                 return ERROR_INVALID_ARGUMENTS;
3017         }
3018         strcpy(cp, mnemonic);
3019         return ERROR_OK;
3020 }
3021
3022 static int t2ev_b_misc(uint32_t opcode, uint32_t address,
3023                 struct arm_instruction *instruction, char *cp)
3024 {
3025         /* permanently undefined */
3026         if ((opcode & 0x07f07000) == 0x07f02000) {
3027                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3028                 strcpy(cp, "UNDEFINED");
3029                 return ERROR_OK;
3030         }
3031
3032         switch ((opcode >> 12) & 0x5) {
3033         case 0x1:
3034         case 0x5:
3035                 return t2ev_b_bl(opcode, address, instruction, cp);
3036         case 0x4:
3037                 goto undef;
3038         case 0:
3039                 if (((opcode >> 23) & 0x07) != 0x07)
3040                         return t2ev_cond_b(opcode, address, instruction, cp);
3041                 if (opcode & (1 << 26))
3042                         goto undef;
3043                 break;
3044         }
3045
3046         switch ((opcode >> 20) & 0x7f) {
3047         case 0x38:
3048         case 0x39:
3049                 sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff),
3050                                 (int) (opcode >> 16) & 0x0f);
3051                 return ERROR_OK;
3052         case 0x3a:
3053                 return t2ev_hint(opcode, address, instruction, cp);
3054         case 0x3b:
3055                 return t2ev_misc(opcode, address, instruction, cp);
3056         case 0x3c:
3057                 sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f);
3058                 return ERROR_OK;
3059         case 0x3e:
3060         case 0x3f:
3061                 sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f,
3062                                 special_name(opcode & 0xff));
3063                 return ERROR_OK;
3064         }
3065
3066 undef:
3067         return ERROR_INVALID_ARGUMENTS;
3068 }
3069
3070 static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
3071                 struct arm_instruction *instruction, char *cp)
3072 {
3073         char *mnemonic = NULL;
3074         int rn = (opcode >> 16) & 0xf;
3075         int rd = (opcode >> 8) & 0xf;
3076         unsigned immed = opcode & 0xff;
3077         unsigned func;
3078         bool one = false;
3079         char *suffix = "";
3080         char *suffix2 = "";
3081
3082         /* ARMv7-M: A5.3.2 Modified immediate constants */
3083         func = (opcode >> 11) & 0x0e;
3084         if (immed & 0x80)
3085                 func |= 1;
3086         if (opcode & (1 << 26))
3087                 func |= 0x10;
3088
3089         /* "Modified" immediates */
3090         switch (func >> 1) {
3091         case 0:
3092                 break;
3093         case 2:
3094                 immed <<= 8;
3095                 /* FALLTHROUGH */
3096         case 1:
3097                 immed += immed << 16;
3098                 break;
3099         case 3:
3100                 immed += immed << 8;
3101                 immed += immed << 16;
3102                 break;
3103         default:
3104                 immed |= 0x80;
3105                 immed = ror(immed, func);
3106         }
3107
3108         if (opcode & (1 << 20))
3109                 suffix = "S";
3110
3111         switch ((opcode >> 21) & 0xf) {
3112         case 0:
3113                 if (rd == 0xf) {
3114                         instruction->type = ARM_TST;
3115                         mnemonic = "TST";
3116                         one = true;
3117                         suffix = "";
3118                         rd = rn;
3119                 } else {
3120                         instruction->type = ARM_AND;
3121                         mnemonic = "AND";
3122                 }
3123                 break;
3124         case 1:
3125                 instruction->type = ARM_BIC;
3126                 mnemonic = "BIC";
3127                 break;
3128         case 2:
3129                 if (rn == 0xf) {
3130                         instruction->type = ARM_MOV;
3131                         mnemonic = "MOV";
3132                         one = true;
3133                         suffix2 = ".W";
3134                 } else {
3135                         instruction->type = ARM_ORR;
3136                         mnemonic = "ORR";
3137                 }
3138                 break;
3139         case 3:
3140                 if (rn == 0xf) {
3141                         instruction->type = ARM_MVN;
3142                         mnemonic = "MVN";
3143                         one = true;
3144                 } else {
3145                         // instruction->type = ARM_ORN;
3146                         mnemonic = "ORN";
3147                 }
3148                 break;
3149         case 4:
3150                 if (rd == 0xf) {
3151                         instruction->type = ARM_TEQ;
3152                         mnemonic = "TEQ";
3153                         one = true;
3154                         suffix = "";
3155                         rd = rn;
3156                 } else {
3157                         instruction->type = ARM_EOR;
3158                         mnemonic = "EOR";
3159                 }
3160                 break;
3161         case 8:
3162                 if (rd == 0xf) {
3163                         instruction->type = ARM_CMN;
3164                         mnemonic = "CMN";
3165                         one = true;
3166                         suffix = "";
3167                         rd = rn;
3168                 } else {
3169                         instruction->type = ARM_ADD;
3170                         mnemonic = "ADD";
3171                         suffix2 = ".W";
3172                 }
3173                 break;
3174         case 10:
3175                 instruction->type = ARM_ADC;
3176                 mnemonic = "ADC";
3177                 suffix2 = ".W";
3178                 break;
3179         case 11:
3180                 instruction->type = ARM_SBC;
3181                 mnemonic = "SBC";
3182                 break;
3183         case 13:
3184                 if (rd == 0xf) {
3185                         instruction->type = ARM_CMP;
3186                         mnemonic = "CMP";
3187                         one = true;
3188                         suffix = "";
3189                         rd = rn;
3190                 } else {
3191                         instruction->type = ARM_SUB;
3192                         mnemonic = "SUB";
3193                 }
3194                 suffix2 = ".W";
3195                 break;
3196         case 14:
3197                 instruction->type = ARM_RSB;
3198                 mnemonic = "RSB";
3199                 suffix2 = ".W";
3200                 break;
3201         default:
3202                 return ERROR_INVALID_ARGUMENTS;
3203         }
3204
3205         if (one)
3206                 sprintf(cp, "%s%s\tr%d, #%d\t; %#8.8x",
3207                                 mnemonic, suffix2 ,rd, immed, immed);
3208         else
3209                 sprintf(cp, "%s%s%s\tr%d, r%d, #%d\t; %#8.8x",
3210                                 mnemonic, suffix, suffix2,
3211                                 rd, rn, immed, immed);
3212
3213         return ERROR_OK;
3214 }
3215
3216 static int t2ev_data_immed(uint32_t opcode, uint32_t address,
3217                 struct arm_instruction *instruction, char *cp)
3218 {
3219         char *mnemonic = NULL;
3220         int rn = (opcode >> 16) & 0xf;
3221         int rd = (opcode >> 8) & 0xf;
3222         unsigned immed;
3223         bool add = false;
3224         bool is_signed = false;
3225
3226         immed = (opcode & 0x0ff) | ((opcode & 0x7000) >> 4);
3227         if (opcode & (1 << 26))
3228                 immed |= (1 << 11);
3229
3230         switch ((opcode >> 20) & 0x1f) {
3231         case 0:
3232                 if (rn == 0xf) {
3233                         add = true;
3234                         goto do_adr;
3235                 }
3236                 mnemonic = "ADDW";
3237                 break;
3238         case 4:
3239                 immed |= (opcode >> 4) & 0xf000;
3240                 sprintf(cp, "MOVW\tr%d, #%d\t; %#3.3x", rd, immed, immed);
3241                 return ERROR_OK;
3242         case 0x0a:
3243                 if (rn == 0xf)
3244                         goto do_adr;
3245                 mnemonic = "SUBW";
3246                 break;
3247         case 0x0c:
3248                 /* move constant to top 16 bits of register */
3249                 immed |= (opcode >> 4) & 0xf000;
3250                 sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed);
3251                 return ERROR_OK;
3252         case 0x10:
3253         case 0x12:
3254                 is_signed = true;
3255         case 0x18:
3256         case 0x1a:
3257                 /* signed/unsigned saturated add */
3258                 immed = (opcode >> 6) & 0x03;
3259                 immed |= (opcode >> 10) & 0x1c;
3260                 sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t",
3261                                 is_signed ? "S" : "U",
3262                                 rd, (int) (opcode & 0x1f) + is_signed, rn,
3263                                 (opcode & (1 << 21)) ? "ASR" : "LSL",
3264                                 immed ? immed : 32);
3265                 return ERROR_OK;
3266         case 0x14:
3267                 is_signed = true;
3268                 /* FALLTHROUGH */
3269         case 0x1c:
3270                 /* signed/unsigned bitfield extract */
3271                 immed = (opcode >> 6) & 0x03;
3272                 immed |= (opcode >> 10) & 0x1c;
3273                 sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t",
3274                                 is_signed ? "S" : "U",
3275                                 rd, rn, immed,
3276                                 (int) (opcode & 0x1f) + 1);
3277                 return ERROR_OK;
3278         case 0x16:
3279                 immed = (opcode >> 6) & 0x03;
3280                 immed |= (opcode >> 10) & 0x1c;
3281                 if (rn == 0xf)          /* bitfield clear */
3282                         sprintf(cp, "BFC\tr%d, #%d, #%d\t",
3283                                         rd, immed,
3284                                         (int) (opcode & 0x1f) + 1 - immed);
3285                 else                    /* bitfield insert */
3286                         sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t",
3287                                         rd, rn, immed,
3288                                         (int) (opcode & 0x1f) + 1 - immed);
3289                 return ERROR_OK;
3290         default:
3291                 return ERROR_INVALID_ARGUMENTS;
3292         }
3293
3294         sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic,
3295                         rd, rn, immed, immed);
3296         return ERROR_OK;
3297
3298 do_adr:
3299         address = thumb_alignpc4(address);
3300         if (add)
3301                 address += immed;
3302         else
3303                 address -= immed;
3304         /* REVISIT "ADD/SUB Rd, PC, #const ; 0x..." might be better;
3305          * not hiding the pc-relative stuff will sometimes be useful.
3306          */
3307         sprintf(cp, "ADR.W\tr%d, %#8.8" PRIx32, rd, address);
3308         return ERROR_OK;
3309 }
3310
3311 static int t2ev_store_single(uint32_t opcode, uint32_t address,
3312                 struct arm_instruction *instruction, char *cp)
3313 {
3314         unsigned op = (opcode >> 20) & 0xf;
3315         char *size = "";
3316         char *suffix = "";
3317         char *p1 = "";
3318         char *p2 = "]";
3319         unsigned immed;
3320         unsigned rn = (opcode >> 16) & 0x0f;
3321         unsigned rt = (opcode >> 12) & 0x0f;
3322
3323         if (rn == 0xf)
3324                 return ERROR_INVALID_ARGUMENTS;
3325
3326         if (opcode & 0x0800)
3327                 op |= 1;
3328         switch (op) {
3329         /* byte */
3330         case 0x8:
3331         case 0x9:
3332                 size = "B";
3333                 goto imm12;
3334         case 0x1:
3335                 size = "B";
3336                 goto imm8;
3337         case 0x0:
3338                 size = "B";
3339                 break;
3340         /* halfword */
3341         case 0xa:
3342         case 0xb:
3343                 size = "H";
3344                 goto imm12;
3345         case 0x3:
3346                 size = "H";
3347                 goto imm8;
3348         case 0x2:
3349                 size = "H";
3350                 break;
3351         /* word */
3352         case 0xc:
3353         case 0xd:
3354                 goto imm12;
3355         case 0x5:
3356                 goto imm8;
3357         case 0x4:
3358                 break;
3359         /* error */
3360         default:
3361                 return ERROR_INVALID_ARGUMENTS;
3362         }
3363
3364         sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]",
3365                         size, rt, rn, (int) opcode & 0x0f,
3366                         (int) (opcode >> 4) & 0x03);
3367         return ERROR_OK;
3368
3369 imm12:
3370         immed = opcode & 0x0fff;
3371         sprintf(cp, "STR%s.W\tr%d, [r%d, #%u]\t; %#3.3x",
3372                         size, rt, rn, immed, immed);
3373         return ERROR_OK;
3374
3375 imm8:
3376         immed = opcode & 0x00ff;
3377
3378         switch (opcode & 0x700) {
3379         case 0x600:
3380                 suffix = "T";
3381                 break;
3382         case 0x000:
3383         case 0x200:
3384                 return ERROR_INVALID_ARGUMENTS;
3385         }
3386
3387         /* two indexed modes will write back rn */
3388         if (opcode & 0x100) {
3389                 if (opcode & 0x400)     /* pre-indexed */
3390                         p2 = "]!";
3391                 else {                  /* post-indexed */
3392                         p1 = "]";
3393                         p2 = "";
3394                 }
3395         }
3396
3397         sprintf(cp, "STR%s%s\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
3398                         size, suffix, rt, rn, p1,
3399                         (opcode & 0x200) ? "" : "-",
3400                         immed, p2, immed);
3401         return ERROR_OK;
3402 }
3403
3404 static int t2ev_mul32(uint32_t opcode, uint32_t address,
3405                 struct arm_instruction *instruction, char *cp)
3406 {
3407         int ra = (opcode >> 12) & 0xf;
3408
3409         switch (opcode & 0x007000f0) {
3410         case 0:
3411                 if (ra == 0xf)
3412                         sprintf(cp, "MUL\tr%d, r%d, r%d",
3413                                 (int) (opcode >> 8) & 0xf,
3414                                 (int) (opcode >> 16) & 0xf,
3415                                 (int) (opcode >> 0) & 0xf);
3416                 else
3417                         sprintf(cp, "MLA\tr%d, r%d, r%d, r%d",
3418                                 (int) (opcode >> 8) & 0xf,
3419                                 (int) (opcode >> 16) & 0xf,
3420                                 (int) (opcode >> 0) & 0xf, ra);
3421                 break;
3422         case 0x10:
3423                 sprintf(cp, "MLS\tr%d, r%d, r%d, r%d",
3424                         (int) (opcode >> 8) & 0xf,
3425                         (int) (opcode >> 16) & 0xf,
3426                         (int) (opcode >> 0) & 0xf, ra);
3427                 break;
3428         default:
3429                 return ERROR_INVALID_ARGUMENTS;
3430         }
3431         return ERROR_OK;
3432 }
3433
3434 static int t2ev_mul64_div(uint32_t opcode, uint32_t address,
3435                 struct arm_instruction *instruction, char *cp)
3436 {
3437         int op = (opcode >> 4) & 0xf;
3438         char *infix = "MUL";
3439
3440         op += (opcode >> 16) & 0x70;
3441         switch (op) {
3442         case 0x40:
3443         case 0x60:
3444                 infix = "MLA";
3445                 /* FALLTHROUGH */
3446         case 0:
3447         case 0x20:
3448                 sprintf(cp, "%c%sL\tr%d, r%d, r%d, r%d",
3449                                 (op & 0x20) ? 'U' : 'S',
3450                                 infix,
3451                                 (int) (opcode >> 12) & 0xf,
3452                                 (int) (opcode >> 8) & 0xf,
3453                                 (int) (opcode >> 16) & 0xf,
3454                                 (int) (opcode >> 0) & 0xf);
3455                 break;
3456         case 0x1f:
3457         case 0x3f:
3458                 sprintf(cp, "%cDIV\tr%d, r%d, r%d",
3459                                 (op & 0x20) ? 'U' : 'S',
3460                                 (int) (opcode >> 8) & 0xf,
3461                                 (int) (opcode >> 16) & 0xf,
3462                                 (int) (opcode >> 0) & 0xf);
3463                 break;
3464         default:
3465                 return ERROR_INVALID_ARGUMENTS;
3466         }
3467
3468         return ERROR_OK;
3469 }
3470
3471 static int t2ev_ldm_stm(uint32_t opcode, uint32_t address,
3472                 struct arm_instruction *instruction, char *cp)
3473 {
3474         int rn = (opcode >> 16) & 0xf;
3475         int op = (opcode >> 22) & 0x6;
3476         int t = (opcode >> 21) & 1;
3477         unsigned registers = opcode & 0xffff;
3478         char *mode = "";
3479
3480         if (opcode & (1 << 20))
3481                 op |= 1;
3482
3483         switch (op) {
3484         case 0:
3485                 mode = "DB";
3486                 /* FALL THROUGH */
3487         case 6:
3488                 sprintf(cp, "SRS%s\tsp%s, #%d", mode,
3489                                 t ? "!" : "",
3490                                 (unsigned) (opcode & 0x1f));
3491                 return ERROR_OK;
3492         case 1:
3493                 mode = "DB";
3494                 /* FALL THROUGH */
3495         case 7:
3496                 sprintf(cp, "RFE%s\tr%d%s", mode,
3497                                 (unsigned) ((opcode >> 16) & 0xf),
3498                                 t ? "!" : "");
3499                 return ERROR_OK;
3500         case 2:
3501                 sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : "");
3502                 break;
3503         case 3:
3504                 if (rn == 13 && t)
3505                         sprintf(cp, "POP.W\t");
3506                 else
3507                         sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : "");
3508                 break;
3509         case 4:
3510                 if (rn == 13 && t)
3511                         sprintf(cp, "PUSH.W\t");
3512                 else
3513                         sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : "");
3514                 break;
3515         case 5:
3516                 sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : "");
3517                 break;
3518         default:
3519                 return ERROR_INVALID_ARGUMENTS;
3520         }
3521
3522         cp = strchr(cp, 0);
3523         *cp++ = '{';
3524         for (t = 0; registers; t++, registers >>= 1) {
3525                 if ((registers & 1) == 0)
3526                         continue;
3527                 registers &= ~1;
3528                 sprintf(cp, "r%d%s", t, registers ? ", " : "");
3529                 cp = strchr(cp, 0);
3530         }
3531         *cp++ = '}';
3532         *cp++ = 0;
3533
3534         return ERROR_OK;
3535 }
3536
3537 /* load/store dual or exclusive, table branch */
3538 static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
3539                 struct arm_instruction *instruction, char *cp)
3540 {
3541         unsigned op1op2 = (opcode >> 20) & 0x3;
3542         unsigned op3 = (opcode >> 4) & 0xf;
3543         char *mnemonic;
3544         unsigned rn = (opcode >> 16) & 0xf;
3545         unsigned rt = (opcode >> 12) & 0xf;
3546         unsigned rd = (opcode >> 8) & 0xf;
3547         unsigned imm = opcode & 0xff;
3548         char *p1 = "";
3549         char *p2 = "]";
3550
3551         op1op2 |= (opcode >> 21) & 0xc;
3552         switch (op1op2) {
3553         case 0:
3554                 mnemonic = "STREX";
3555                 goto strex;
3556         case 1:
3557                 mnemonic = "LDREX";
3558                 goto ldrex;
3559         case 2:
3560         case 6:
3561         case 8:
3562         case 10:
3563         case 12:
3564         case 14:
3565                 mnemonic = "STRD";
3566                 goto immediate;
3567         case 3:
3568         case 7:
3569         case 9:
3570         case 11:
3571         case 13:
3572         case 15:
3573                 mnemonic = "LDRD";
3574                 if (rn == 15)
3575                         goto literal;
3576                 else
3577                         goto immediate;
3578         case 4:
3579                 switch (op3) {
3580                 case 4:
3581                         mnemonic = "STREXB";
3582                         break;
3583                 case 5:
3584                         mnemonic = "STREXH";
3585                         break;
3586                 default:
3587                         return ERROR_INVALID_ARGUMENTS;
3588                 }
3589                 rd = opcode & 0xf;
3590                 imm = 0;
3591                 goto strex;
3592         case 5:
3593                 switch (op3) {
3594                 case 0:
3595                         sprintf(cp, "TBB\t[r%u, r%u]", rn, imm & 0xf);
3596                         return ERROR_OK;
3597                 case 1:
3598                         sprintf(cp, "TBH\t[r%u, r%u, LSL #1]", rn, imm & 0xf);
3599                         return ERROR_OK;
3600                 case 4:
3601                         mnemonic = "LDREXB";
3602                         break;
3603                 case 5:
3604                         mnemonic = "LDREXH";
3605                         break;
3606                 default:
3607                         return ERROR_INVALID_ARGUMENTS;
3608                 }
3609                 imm = 0;
3610                 goto ldrex;
3611         }
3612         return ERROR_INVALID_ARGUMENTS;
3613
3614 strex:
3615         imm <<= 2;
3616         if (imm)
3617                 sprintf(cp, "%s\tr%u, r%u, [r%u, #%u]\t; %#2.2x",
3618                                 mnemonic, rd, rt, rn, imm, imm);
3619         else
3620                 sprintf(cp, "%s\tr%u, r%u, [r%u]",
3621                                 mnemonic, rd, rt, rn);
3622         return ERROR_OK;
3623
3624 ldrex:
3625         imm <<= 2;
3626         if (imm)
3627                 sprintf(cp, "%s\tr%u, [r%u, #%u]\t; %#2.2x",
3628                                 mnemonic, rt, rn, imm, imm);
3629         else
3630                 sprintf(cp, "%s\tr%u, [r%u]",
3631                                 mnemonic, rt, rn);
3632         return ERROR_OK;
3633
3634 immediate:
3635         /* two indexed modes will write back rn */
3636         if (opcode & (1 << 21)) {
3637                 if (opcode & (1 << 24)) /* pre-indexed */
3638                         p2 = "]!";
3639                 else {                  /* post-indexed */
3640                         p1 = "]";
3641                         p2 = "";
3642                 }
3643         }
3644
3645         imm <<= 2;
3646         sprintf(cp, "%s\tr%u, r%u, [r%u%s, #%s%u%s\t; %#2.2x",
3647                         mnemonic, rt, rd, rn, p1,
3648                         (opcode & (1 << 23)) ? "" : "-",
3649                         imm, p2, imm);
3650         return ERROR_OK;
3651
3652 literal:
3653         address = thumb_alignpc4(address);
3654         imm <<= 2;
3655         if (opcode & (1 << 23))
3656                 address += imm;
3657         else
3658                 address -= imm;
3659         sprintf(cp, "%s\tr%u, r%u, %#8.8" PRIx32,
3660                         mnemonic, rt, rd, address);
3661         return ERROR_OK;
3662 }
3663
3664 static int t2ev_data_shift(uint32_t opcode, uint32_t address,
3665                 struct arm_instruction *instruction, char *cp)
3666 {
3667         int op = (opcode >> 21) & 0xf;
3668         int rd = (opcode >> 8) & 0xf;
3669         int rn = (opcode >> 16) & 0xf;
3670         int type = (opcode >> 4) & 0x3;
3671         int immed = (opcode >> 6) & 0x3;
3672         char *mnemonic;
3673         char *suffix = "";
3674
3675         immed |= (opcode >> 10) & 0x1c;
3676         if (opcode & (1 << 20))
3677                 suffix = "S";
3678
3679         switch (op) {
3680         case 0:
3681                 if (rd == 0xf) {
3682                         if (!(opcode & (1 << 20)))
3683                                 return ERROR_INVALID_ARGUMENTS;
3684                         instruction->type = ARM_TST;
3685                         mnemonic = "TST";
3686                         suffix = "";
3687                         goto two;
3688                 }
3689                 instruction->type = ARM_AND;
3690                 mnemonic = "AND";
3691                 break;
3692         case 1:
3693                 instruction->type = ARM_BIC;
3694                 mnemonic = "BIC";
3695                 break;
3696         case 2:
3697                 if (rn == 0xf) {
3698                         instruction->type = ARM_MOV;
3699                         switch (type) {
3700                         case 0:
3701                                 if (immed == 0) {
3702                                         sprintf(cp, "MOV%s.W\tr%d, r%d",
3703                                                 suffix, rd,
3704                                                 (int) (opcode & 0xf));
3705                                         return ERROR_OK;
3706                                 }
3707                                 mnemonic = "LSL";
3708                                 break;
3709                         case 1:
3710                                 mnemonic = "LSR";
3711                                 break;
3712                         case 2:
3713                                 mnemonic = "ASR";
3714                                 break;
3715                         default:
3716                                 if (immed == 0) {
3717                                         sprintf(cp, "RRX%s\tr%d, r%d",
3718                                                 suffix, rd,
3719                                                 (int) (opcode & 0xf));
3720                                         return ERROR_OK;
3721                                 }
3722                                 mnemonic = "ROR";
3723                                 break;
3724                         }
3725                         goto immediate;
3726                 } else {
3727                         instruction->type = ARM_ORR;
3728                         mnemonic = "ORR";
3729                 }
3730                 break;
3731         case 3:
3732                 if (rn == 0xf) {
3733                         instruction->type = ARM_MVN;
3734                         mnemonic = "MVN";
3735                         rn = rd;
3736                         goto two;
3737                 } else {
3738                         // instruction->type = ARM_ORN;
3739                         mnemonic = "ORN";
3740                 }
3741                 break;
3742         case 4:
3743                 if (rd == 0xf) {
3744                         if (!(opcode & (1 << 20)))
3745                                 return ERROR_INVALID_ARGUMENTS;
3746                         instruction->type = ARM_TEQ;
3747                         mnemonic = "TEQ";
3748                         suffix = "";
3749                         goto two;
3750                 }
3751                 instruction->type = ARM_EOR;
3752                 mnemonic = "EOR";
3753                 break;
3754         case 8:
3755                 if (rd == 0xf) {
3756                         if (!(opcode & (1 << 20)))
3757                                 return ERROR_INVALID_ARGUMENTS;
3758                         instruction->type = ARM_CMN;
3759                         mnemonic = "CMN";
3760                         suffix = "";
3761                         goto two;
3762                 }
3763                 instruction->type = ARM_ADD;
3764                 mnemonic = "ADD";
3765                 break;
3766         case 0xa:
3767                 instruction->type = ARM_ADC;
3768                 mnemonic = "ADC";
3769                 break;
3770         case 0xb:
3771                 instruction->type = ARM_SBC;
3772                 mnemonic = "SBC";
3773                 break;
3774         case 0xd:
3775                 if (rd == 0xf) {
3776                         if (!(opcode & (1 << 21)))
3777                                 return ERROR_INVALID_ARGUMENTS;
3778                         instruction->type = ARM_CMP;
3779                         mnemonic = "CMP";
3780                         suffix = "";
3781                         goto two;
3782                 }
3783                 instruction->type = ARM_SUB;
3784                 mnemonic = "SUB";
3785                 break;
3786         case 0xe:
3787                 instruction->type = ARM_RSB;
3788                 mnemonic = "RSB";
3789                 break;
3790         default:
3791                 return ERROR_INVALID_ARGUMENTS;
3792         }
3793
3794         sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
3795                 mnemonic, suffix, rd, rn, (int) (opcode & 0xf));
3796
3797 shift:
3798         cp = strchr(cp, 0);
3799
3800         switch (type) {
3801         case 0:
3802                 if (immed == 0)
3803                         return ERROR_OK;
3804                 suffix = "LSL";
3805                 break;
3806         case 1:
3807                 suffix = "LSR";
3808                 if (immed == 32)
3809                         immed = 0;
3810                 break;
3811         case 2:
3812                 suffix = "ASR";
3813                 if (immed == 32)
3814                         immed = 0;
3815                 break;
3816         case 3:
3817                 if (immed == 0) {
3818                         strcpy(cp, ", RRX");
3819                         return ERROR_OK;
3820                 }
3821                 suffix = "ROR";
3822                 break;
3823         }
3824         sprintf(cp, ", %s #%d", suffix, immed ? immed : 32);
3825         return ERROR_OK;
3826
3827 two:
3828         sprintf(cp, "%s%s.W\tr%d, r%d",
3829                 mnemonic, suffix, rn, (int) (opcode & 0xf));
3830         goto shift;
3831
3832 immediate:
3833         sprintf(cp, "%s%s.W\tr%d, r%d, #%d",
3834                 mnemonic, suffix, rd,
3835                 (int) (opcode & 0xf), immed ? immed : 32);
3836         return ERROR_OK;
3837 }
3838
3839 static int t2ev_data_reg(uint32_t opcode, uint32_t address,
3840                 struct arm_instruction *instruction, char *cp)
3841 {
3842         char *mnemonic;
3843         char * suffix = "";
3844
3845         if (((opcode >> 4) & 0xf) == 0) {
3846                 switch ((opcode >> 21) & 0x7) {
3847                 case 0:
3848                         mnemonic = "LSL";
3849                         break;
3850                 case 1:
3851                         mnemonic = "LSR";
3852                         break;
3853                 case 2:
3854                         mnemonic = "ASR";
3855                         break;
3856                 case 3:
3857                         mnemonic = "ROR";
3858                         break;
3859                 default:
3860                         return ERROR_INVALID_ARGUMENTS;
3861                 }
3862
3863                 instruction->type = ARM_MOV;
3864                 if (opcode & (1 << 20))
3865                         suffix = "S";
3866                 sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
3867                                 mnemonic, suffix,
3868                                 (int) (opcode >> 8) & 0xf,
3869                                 (int) (opcode >> 16) & 0xf,
3870                                 (int) (opcode >> 0) & 0xf);
3871
3872         } else if (opcode & (1 << 7)) {
3873                 switch ((opcode >> 20) & 0xf) {
3874                 case 0:
3875                 case 1:
3876                 case 4:
3877                 case 5:
3878                         switch ((opcode >> 4) & 0x3) {
3879                         case 1:
3880                                 suffix = ", ROR #8";
3881                                 break;
3882                         case 2:
3883                                 suffix = ", ROR #16";
3884                                 break;
3885                         case 3:
3886                                 suffix = ", ROR #24";
3887                                 break;
3888                         }
3889                         sprintf(cp, "%cXT%c.W\tr%d, r%d%s",
3890                                         (opcode & (1 << 24)) ? 'U' : 'S',
3891                                         (opcode & (1 << 26)) ? 'B' : 'H',
3892                                         (int) (opcode >> 8) & 0xf,
3893                                         (int) (opcode >> 0) & 0xf,
3894                                         suffix);
3895                         break;
3896                 case 8:
3897                 case 9:
3898                 case 0xa:
3899                 case 0xb:
3900                         if (opcode & (1 << 6))
3901                                 return ERROR_INVALID_ARGUMENTS;
3902                         if (((opcode >> 12) & 0xf) != 0xf)
3903                                 return ERROR_INVALID_ARGUMENTS;
3904                         if (!(opcode & (1 << 20)))
3905                                 return ERROR_INVALID_ARGUMENTS;
3906
3907                         switch (((opcode >> 19) & 0x04)
3908                                 | ((opcode >> 4) & 0x3)) {
3909                         case 0:
3910                                 mnemonic = "REV.W";
3911                                 break;
3912                         case 1:
3913                                 mnemonic = "REV16.W";
3914                                 break;
3915                         case 2:
3916                                 mnemonic = "RBIT";
3917                                 break;
3918                         case 3:
3919                                 mnemonic = "REVSH.W";
3920                                 break;
3921                         case 4:
3922                                 mnemonic = "CLZ";
3923                                 break;
3924                         default:
3925                                 return ERROR_INVALID_ARGUMENTS;
3926                         }
3927                         sprintf(cp, "%s\tr%d, r%d",
3928                                         mnemonic,
3929                                         (int) (opcode >> 8) & 0xf,
3930                                         (int) (opcode >> 0) & 0xf);
3931                         break;
3932                 default:
3933                         return ERROR_INVALID_ARGUMENTS;
3934                 }
3935         }
3936
3937         return ERROR_OK;
3938 }
3939
3940 static int t2ev_load_word(uint32_t opcode, uint32_t address,
3941                 struct arm_instruction *instruction, char *cp)
3942 {
3943         int rn = (opcode >> 16) & 0xf;
3944         int immed;
3945
3946         instruction->type = ARM_LDR;
3947
3948         if (rn == 0xf) {
3949                 immed = opcode & 0x0fff;
3950                 if ((opcode & (1 << 23)) == 0)
3951                         immed = -immed;
3952                 sprintf(cp, "LDR\tr%d, %#8.8" PRIx32,
3953                                 (int) (opcode >> 12) & 0xf,
3954                                 thumb_alignpc4(address) + immed);
3955                 return ERROR_OK;
3956         }
3957
3958         if (opcode & (1 << 23)) {
3959                 immed = opcode & 0x0fff;
3960                 sprintf(cp, "LDR.W\tr%d, [r%d, #%d]\t; %#3.3x",
3961                                 (int) (opcode >> 12) & 0xf,
3962                                 rn, immed, immed);
3963                 return ERROR_OK;
3964         }
3965
3966         if (!(opcode & (0x3f << 6))) {
3967                 sprintf(cp, "LDR.W\tr%d, [r%d, r%d, LSL #%d]",
3968                                 (int) (opcode >> 12) & 0xf,
3969                                 rn,
3970                                 (int) (opcode >> 0) & 0xf,
3971                                 (int) (opcode >> 4) & 0x3);
3972                 return ERROR_OK;
3973         }
3974
3975
3976         if (((opcode >> 8) & 0xf) == 0xe) {
3977                 immed = opcode & 0x00ff;
3978
3979                 sprintf(cp, "LDRT\tr%d, [r%d, #%d]\t; %#2.2x",
3980                                 (int) (opcode >> 12) & 0xf,
3981                                 rn, immed, immed);
3982                 return ERROR_OK;
3983         }
3984
3985         if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) {
3986                 char *p1 = "]", *p2 = "";
3987
3988                 if (!(opcode & 0x0500))
3989                         return ERROR_INVALID_ARGUMENTS;
3990
3991                 immed = opcode & 0x00ff;
3992
3993                 /* two indexed modes will write back rn */
3994                 if (opcode & 0x100) {
3995                         if (opcode & 0x400)     /* pre-indexed */
3996                                 p2 = "]!";
3997                         else {                  /* post-indexed */
3998                                 p1 = "]";
3999                                 p2 = "";
4000                         }
4001                 }
4002
4003                 sprintf(cp, "LDR\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
4004                                 (int) (opcode >> 12) & 0xf,
4005                                 rn, p1,
4006                                 (opcode & 0x200) ? "" : "-",
4007                                 immed, p2, immed);
4008                 return ERROR_OK;
4009         }
4010
4011         return ERROR_INVALID_ARGUMENTS;
4012 }
4013
4014 static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address,
4015                 struct arm_instruction *instruction, char *cp)
4016 {
4017         int rn = (opcode >> 16) & 0xf;
4018         int rt = (opcode >> 12) & 0xf;
4019         int op2 = (opcode >> 6) & 0x3f;
4020         unsigned immed;
4021         char *p1 = "", *p2 = "]";
4022         char *mnemonic;
4023
4024         switch ((opcode >> 23) & 0x3) {
4025         case 0:
4026                 if ((rn & rt) == 0xf) {
4027 pld_literal:
4028                         immed = opcode & 0xfff;
4029                         address = thumb_alignpc4(address);
4030                         if (opcode & (1 << 23))
4031                                 address += immed;
4032                         else
4033                                 address -= immed;
4034                         sprintf(cp, "PLD\tr%d, %#8.8" PRIx32,
4035                                         rt, address);
4036                         return ERROR_OK;
4037                 }
4038                 if (rn == 0x0f && rt != 0x0f) {
4039 ldrb_literal:
4040                         immed = opcode & 0xfff;
4041                         address = thumb_alignpc4(address);
4042                         if (opcode & (1 << 23))
4043                                 address += immed;
4044                         else
4045                                 address -= immed;
4046                         sprintf(cp, "LDRB\tr%d, %#8.8" PRIx32,
4047                                         rt, address);
4048                         return ERROR_OK;
4049                 }
4050                 if (rn == 0x0f)
4051                         break;
4052                 if ((op2 & 0x3c) == 0x38) {
4053                         immed = opcode & 0xff;
4054                         sprintf(cp, "LDRBT\tr%d, [r%d, #%d]\t; %#2.2x",
4055                                         rt, rn, immed, immed);
4056                         return ERROR_OK;
4057                 }
4058                 if ((op2 & 0x3c) == 0x30) {
4059                         if (rt == 0x0f) {
4060                                 immed = opcode & 0xff;
4061                                 immed = -immed;
4062 preload_immediate:
4063                                 p1 = (opcode & (1 << 21)) ? "W" : "";
4064                                 sprintf(cp, "PLD%s\t[r%d, #%d]\t; %#6.6x",
4065                                                 p1, rn, immed, immed);
4066                                 return ERROR_OK;
4067                         }
4068                         mnemonic = "LDRB";
4069 ldrxb_immediate_t3:
4070                         immed = opcode & 0xff;
4071                         if (!(opcode & 0x200))
4072                                 immed = -immed;
4073
4074                         /* two indexed modes will write back rn */
4075                         if (opcode & 0x100) {
4076                                 if (opcode & 0x400)     /* pre-indexed */
4077                                         p2 = "]!";
4078                                 else {                  /* post-indexed */
4079                                         p1 = "]";
4080                                         p2 = "";
4081                                 }
4082                         }
4083 ldrxb_immediate_t2:
4084                         sprintf(cp, "%s\tr%d, [r%d%s, #%d%s\t; %#8.8x",
4085                                         mnemonic, rt, rn, p1,
4086                                         immed, p2, immed);
4087                         return ERROR_OK;
4088                 }
4089                 if ((op2 & 0x24) == 0x24) {
4090                         mnemonic = "LDRB";
4091                         goto ldrxb_immediate_t3;
4092                 }
4093                 if (op2 == 0) {
4094                         int rm = opcode & 0xf;
4095
4096                         if (rt == 0x0f)
4097                                 sprintf(cp, "PLD\t");
4098                         else
4099                                 sprintf(cp, "LDRB.W\tr%d, ", rt);
4100                         immed = (opcode >> 4) & 0x3;
4101                         cp = strchr(cp, 0);
4102                         sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
4103                         return ERROR_OK;
4104                 }
4105                 break;
4106         case 1:
4107                 if ((rn & rt) == 0xf)
4108                         goto pld_literal;
4109                 if (rt == 0xf) {
4110                         immed = opcode & 0xfff;
4111                         goto preload_immediate;
4112                 }
4113                 if (rn == 0x0f)
4114                         goto ldrb_literal;
4115                 mnemonic = "LDRB.W";
4116                 immed = opcode & 0xfff;
4117                 goto ldrxb_immediate_t2;
4118         case 2:
4119                 if ((rn & rt) == 0xf) {
4120                         immed = opcode & 0xfff;
4121                         address = thumb_alignpc4(address);
4122                         if (opcode & (1 << 23))
4123                                 address += immed;
4124                         else
4125                                 address -= immed;
4126                         sprintf(cp, "PLI\t%#8.8" PRIx32, address);
4127                         return ERROR_OK;
4128                 }
4129                 if (rn == 0xf && rt != 0xf) {
4130 ldrsb_literal:
4131                         immed = opcode & 0xfff;
4132                         address = thumb_alignpc4(address);
4133                         if (opcode & (1 << 23))
4134                                 address += immed;
4135                         else
4136                                 address -= immed;
4137                         sprintf(cp, "LDRSB\t%#8.8" PRIx32, address);
4138                         return ERROR_OK;
4139                 }
4140                 if (rn == 0xf)
4141                         break;
4142                 if ((op2 & 0x3c) == 0x38) {
4143                         immed = opcode & 0xff;
4144                         sprintf(cp, "LDRSBT\tr%d, [r%d, #%d]\t; %#2.2x",
4145                                         rt, rn, immed, immed);
4146                         return ERROR_OK;
4147                 }
4148                 if ((op2 & 0x3c) == 0x30) {
4149                         if (rt == 0xf) {
4150                                 immed = opcode & 0xff;
4151                                 immed = -immed; // pli
4152                                 sprintf(cp, "PLI\t[r%d, #%d]\t; -%#2.2x",
4153                                                 rn, immed, -immed);
4154                                 return ERROR_OK;
4155                         }
4156                         mnemonic = "LDRSB";
4157                         goto ldrxb_immediate_t3;
4158                 }
4159                 if ((op2 & 0x24) == 0x24) {
4160                         mnemonic = "LDRSB";
4161                         goto ldrxb_immediate_t3;
4162                 }
4163                 if (op2 == 0) {
4164                         int rm = opcode & 0xf;
4165
4166                         if (rt == 0x0f)
4167                                 sprintf(cp, "PLI\t");
4168                         else
4169                                 sprintf(cp, "LDRSB.W\tr%d, ", rt);
4170                         immed = (opcode >> 4) & 0x3;
4171                         cp = strchr(cp, 0);
4172                         sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
4173                         return ERROR_OK;
4174                 }
4175                 break;
4176         case 3:
4177                 if (rt == 0xf) {
4178                         immed = opcode & 0xfff;
4179                         sprintf(cp, "PLI\t[r%d, #%d]\t; %#3.3x",
4180                                         rn, immed, immed);
4181                         return ERROR_OK;
4182                 }
4183                 if (rn == 0xf)
4184                         goto ldrsb_literal;
4185                 immed = opcode & 0xfff;
4186                 mnemonic = "LDRSB";
4187                 goto ldrxb_immediate_t2;
4188         }
4189
4190         return ERROR_INVALID_ARGUMENTS;
4191 }
4192
4193 static int t2ev_load_halfword(uint32_t opcode, uint32_t address,
4194                 struct arm_instruction *instruction, char *cp)
4195 {
4196         int rn = (opcode >> 16) & 0xf;
4197         int rt = (opcode >> 12) & 0xf;
4198         int op2 = (opcode >> 6) & 0x3f;
4199         char *sign = "";
4200         unsigned immed;
4201
4202         if (rt == 0xf) {
4203                 sprintf(cp, "HINT (UNALLOCATED)");
4204                 return ERROR_OK;
4205         }
4206
4207         if (opcode & (1 << 24))
4208                 sign = "S";
4209
4210         if ((opcode & (1 << 23)) == 0) {
4211                 if (rn == 0xf) {
4212 ldrh_literal:
4213                         immed = opcode & 0xfff;
4214                         address = thumb_alignpc4(address);
4215                         if (opcode & (1 << 23))
4216                                 address += immed;
4217                         else
4218                                 address -= immed;
4219                         sprintf(cp, "LDR%sH\tr%d, %#8.8" PRIx32,
4220                                         sign, rt, address);
4221                         return ERROR_OK;
4222                 }
4223                 if (op2 == 0) {
4224                         int rm = opcode & 0xf;
4225
4226                         immed = (opcode >> 4) & 0x3;
4227                         sprintf(cp, "LDR%sH.W\tr%d, [r%d, r%d, LSL #%d]",
4228                                         sign, rt, rn, rm, immed);
4229                         return ERROR_OK;
4230                 }
4231                 if ((op2 & 0x3c) == 0x38) {
4232                         immed = opcode & 0xff;
4233                         sprintf(cp, "LDR%sHT\tr%d, [r%d, #%d]\t; %#2.2x",
4234                                         sign, rt, rn, immed, immed);
4235                         return ERROR_OK;
4236                 }
4237                 if ((op2 & 0x3c) == 0x30 || (op2 & 0x24) == 0x24) {
4238                         char *p1 = "", *p2 = "]";
4239
4240                         immed = opcode & 0xff;
4241                         if (!(opcode & 0x200))
4242                                 immed = -immed;
4243
4244                         /* two indexed modes will write back rn */
4245                         if (opcode & 0x100) {
4246                                 if (opcode & 0x400)     /* pre-indexed */
4247                                         p2 = "]!";
4248                                 else {                  /* post-indexed */
4249                                         p1 = "]";
4250                                         p2 = "";
4251                                 }
4252                         }
4253                         sprintf(cp, "LDR%sH\tr%d, [r%d%s, #%d%s\t; %#8.8x",
4254                                         sign, rt, rn, p1, immed, p2, immed);
4255                         return ERROR_OK;
4256                 }
4257         } else {
4258                 if (rn == 0xf)
4259                         goto ldrh_literal;
4260
4261                 immed = opcode & 0xfff;
4262                 sprintf(cp, "LDR%sH%s\tr%d, [r%d, #%d]\t; %#6.6x",
4263                                 sign, *sign ? "" : ".W",
4264                                 rt, rn, immed, immed);
4265                 return ERROR_OK;
4266         }
4267
4268         return ERROR_INVALID_ARGUMENTS;
4269 }
4270
4271 /*
4272  * REVISIT for Thumb2 instructions, instruction->type and friends aren't
4273  * always set.  That means eventual arm_simulate_step() support for Thumb2
4274  * will need work in this area.
4275  */
4276 int thumb2_opcode(struct target *target, uint32_t address, struct arm_instruction *instruction)
4277 {
4278         int retval;
4279         uint16_t op;
4280         uint32_t opcode;
4281         char *cp;
4282
4283         /* clear low bit ... it's set on function pointers */
4284         address &= ~1;
4285
4286         /* clear fields, to avoid confusion */
4287         memset(instruction, 0, sizeof(struct arm_instruction));
4288
4289         /* read first halfword, see if this is the only one */
4290         retval = target_read_u16(target, address, &op);
4291         if (retval != ERROR_OK)
4292                 return retval;
4293
4294         switch (op & 0xf800) {
4295         case 0xf800:
4296         case 0xf000:
4297         case 0xe800:
4298                 /* 32-bit instructions */
4299                 instruction->instruction_size = 4;
4300                 opcode = op << 16;
4301                 retval = target_read_u16(target, address + 2, &op);
4302                 if (retval != ERROR_OK)
4303                         return retval;
4304                 opcode |= op;
4305                 instruction->opcode = opcode;
4306                 break;
4307         default:
4308                 /* 16-bit:  Thumb1 + IT + CBZ/CBNZ + ... */
4309                 return thumb_evaluate_opcode(op, address, instruction);
4310         }
4311
4312         snprintf(instruction->text, 128,
4313                         "0x%8.8" PRIx32 "  0x%8.8" PRIx32 "\t",
4314                         address, opcode);
4315         cp = strchr(instruction->text, 0);
4316         retval = ERROR_FAIL;
4317
4318         /* ARMv7-M: A5.3.1 Data processing (modified immediate) */
4319         if ((opcode & 0x1a008000) == 0x10000000)
4320                 retval = t2ev_data_mod_immed(opcode, address, instruction, cp);
4321
4322         /* ARMv7-M: A5.3.3 Data processing (plain binary immediate) */
4323         else if ((opcode & 0x1a008000) == 0x12000000)
4324                 retval = t2ev_data_immed(opcode, address, instruction, cp);
4325
4326         /* ARMv7-M: A5.3.4 Branches and miscellaneous control */
4327         else if ((opcode & 0x18008000) == 0x10008000)
4328                 retval = t2ev_b_misc(opcode, address, instruction, cp);
4329
4330         /* ARMv7-M: A5.3.5 Load/store multiple */
4331         else if ((opcode & 0x1e400000) == 0x08000000)
4332                 retval = t2ev_ldm_stm(opcode, address, instruction, cp);
4333
4334         /* ARMv7-M: A5.3.6 Load/store dual or exclusive, table branch */
4335         else if ((opcode & 0x1e400000) == 0x08400000)
4336                 retval = t2ev_ldrex_strex(opcode, address, instruction, cp);
4337
4338         /* ARMv7-M: A5.3.7 Load word */
4339         else if ((opcode & 0x1f700000) == 0x18500000)
4340                 retval = t2ev_load_word(opcode, address, instruction, cp);
4341
4342         /* ARMv7-M: A5.3.8 Load halfword, unallocated memory hints */
4343         else if ((opcode & 0x1e700000) == 0x18300000)
4344                 retval = t2ev_load_halfword(opcode, address, instruction, cp);
4345
4346         /* ARMv7-M: A5.3.9 Load byte, memory hints */
4347         else if ((opcode & 0x1e700000) == 0x18100000)
4348                 retval = t2ev_load_byte_hints(opcode, address, instruction, cp);
4349
4350         /* ARMv7-M: A5.3.10 Store single data item */
4351         else if ((opcode & 0x1f100000) == 0x18000000)
4352                 retval = t2ev_store_single(opcode, address, instruction, cp);
4353
4354         /* ARMv7-M: A5.3.11 Data processing (shifted register) */
4355         else if ((opcode & 0x1e000000) == 0x0a000000)
4356                 retval = t2ev_data_shift(opcode, address, instruction, cp);
4357
4358         /* ARMv7-M: A5.3.12 Data processing (register)
4359          * and      A5.3.13 Miscellaneous operations
4360          */
4361         else if ((opcode & 0x1f000000) == 0x1a000000)
4362                 retval = t2ev_data_reg(opcode, address, instruction, cp);
4363
4364         /* ARMv7-M: A5.3.14 Multiply, and multiply accumulate */
4365         else if ((opcode & 0x1f800000) == 0x1b000000)
4366                 retval = t2ev_mul32(opcode, address, instruction, cp);
4367
4368         /* ARMv7-M: A5.3.15 Long multiply, long multiply accumulate, divide */
4369         else if ((opcode & 0x1f800000) == 0x1b800000)
4370                 retval = t2ev_mul64_div(opcode, address, instruction, cp);
4371
4372         if (retval == ERROR_OK)
4373                 return retval;
4374
4375         /*
4376          * Thumb2 also supports coprocessor, ThumbEE, and DSP/Media (SIMD)
4377          * instructions; not yet handled here.
4378          */
4379
4380         if (retval == ERROR_INVALID_ARGUMENTS) {
4381                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
4382                 strcpy(cp, "UNDEFINED OPCODE");
4383                 return ERROR_OK;
4384         }
4385
4386         LOG_DEBUG("Can't decode 32-bit Thumb2 yet (opcode=%08" PRIx32 ")",
4387                         opcode);
4388
4389         strcpy(cp, "(32-bit Thumb2 ...)");
4390         return ERROR_OK;
4391 }
4392
4393 int arm_access_size(struct arm_instruction *instruction)
4394 {
4395         if ((instruction->type == ARM_LDRB)
4396                 || (instruction->type == ARM_LDRBT)
4397                 || (instruction->type == ARM_LDRSB)
4398                 || (instruction->type == ARM_STRB)
4399                 || (instruction->type == ARM_STRBT))
4400         {
4401                 return 1;
4402         }
4403         else if ((instruction->type == ARM_LDRH)
4404                 || (instruction->type == ARM_LDRSH)
4405                 || (instruction->type == ARM_STRH))
4406         {
4407                 return 2;
4408         }
4409         else if ((instruction->type == ARM_LDR)
4410                 || (instruction->type == ARM_LDRT)
4411                 || (instruction->type == ARM_STR)
4412                 || (instruction->type == ARM_STRT))
4413         {
4414                 return 4;
4415         }
4416         else if ((instruction->type == ARM_LDRD)
4417                 || (instruction->type == ARM_STRD))
4418         {
4419                 return 8;
4420         }
4421         else
4422         {
4423                 LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type);
4424                 return 0;
4425         }
4426 }