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