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