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