David Brownell <david-b@pacbell.net>:
[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
1516         high_reg = (opcode & 0x0400) >> 10;
1517         op = (opcode & 0x03C0) >> 6;
1518
1519         Rd = (opcode & 0x0007);
1520         Rm = (opcode & 0x0038) >> 3;
1521         H1 = (opcode & 0x0080) >> 7;
1522         H2 = (opcode & 0x0040) >> 6;
1523
1524         instruction->info.data_proc.Rd = Rd;
1525         instruction->info.data_proc.Rn = Rd;
1526         instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
1527         instruction->info.data_proc.variant = 1 /*immediate shift*/;
1528         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1529
1530         if (high_reg)
1531         {
1532                 Rd |= H1 << 3;
1533                 Rm |= H2 << 3;
1534                 op >>= 2;
1535
1536                 switch (op)
1537                 {
1538                         case 0x0:
1539                                 instruction->type = ARM_ADD;
1540                                 mnemonic = "ADD";
1541                                 break;
1542                         case 0x1:
1543                                 instruction->type = ARM_CMP;
1544                                 mnemonic = "CMP";
1545                                 break;
1546                         case 0x2:
1547                                 instruction->type = ARM_MOV;
1548                                 mnemonic = "MOV";
1549                                 break;
1550                         case 0x3:
1551                                 if ((opcode & 0x7) == 0x0)
1552                                 {
1553                                         instruction->info.b_bl_bx_blx.reg_operand = Rm;
1554                                         if (H1)
1555                                         {
1556                                                 instruction->type = ARM_BLX;
1557                                                 snprintf(instruction->text, 128,
1558                                                         "0x%8.8" PRIx32
1559                                                         "  0x%4.4x    \tBLX\tr%i",
1560                                                         address, opcode, Rm);
1561                                         }
1562                                         else
1563                                         {
1564                                                 instruction->type = ARM_BX;
1565                                                 snprintf(instruction->text, 128,
1566                                                         "0x%8.8" PRIx32
1567                                                         "  0x%4.4x    \tBX\tr%i",
1568                                                         address, opcode, Rm);
1569                                         }
1570                                 }
1571                                 else
1572                                 {
1573                                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1574                                         snprintf(instruction->text, 128,
1575                                                 "0x%8.8" PRIx32
1576                                                 "  0x%4.4x    \t"
1577                                                 "UNDEFINED INSTRUCTION",
1578                                                 address, opcode);
1579                                 }
1580                                 return ERROR_OK;
1581                                 break;
1582                 }
1583         }
1584         else
1585         {
1586                 switch (op)
1587                 {
1588                         case 0x0:
1589                                 instruction->type = ARM_AND;
1590                                 mnemonic = "ANDS";
1591                                 break;
1592                         case 0x1:
1593                                 instruction->type = ARM_EOR;
1594                                 mnemonic = "EORS";
1595                                 break;
1596                         case 0x2:
1597                                 instruction->type = ARM_MOV;
1598                                 mnemonic = "LSLS";
1599                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1600                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
1601                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1602                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1603                                 break;
1604                         case 0x3:
1605                                 instruction->type = ARM_MOV;
1606                                 mnemonic = "LSRS";
1607                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1608                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
1609                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1610                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1611                                 break;
1612                         case 0x4:
1613                                 instruction->type = ARM_MOV;
1614                                 mnemonic = "ASRS";
1615                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1616                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
1617                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1618                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1619                                 break;
1620                         case 0x5:
1621                                 instruction->type = ARM_ADC;
1622                                 mnemonic = "ADCS";
1623                                 break;
1624                         case 0x6:
1625                                 instruction->type = ARM_SBC;
1626                                 mnemonic = "SBCS";
1627                                 break;
1628                         case 0x7:
1629                                 instruction->type = ARM_MOV;
1630                                 mnemonic = "RORS";
1631                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1632                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
1633                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1634                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1635                                 break;
1636                         case 0x8:
1637                                 instruction->type = ARM_TST;
1638                                 mnemonic = "TST";
1639                                 break;
1640                         case 0x9:
1641                                 instruction->type = ARM_RSB;
1642                                 mnemonic = "NEGS";
1643                                 instruction->info.data_proc.variant = 0 /*immediate*/;
1644                                 instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
1645                                 instruction->info.data_proc.Rn = Rm;
1646                                 break;
1647                         case 0xA:
1648                                 instruction->type = ARM_CMP;
1649                                 mnemonic = "CMP";
1650                                 break;
1651                         case 0xB:
1652                                 instruction->type = ARM_CMN;
1653                                 mnemonic = "CMN";
1654                                 break;
1655                         case 0xC:
1656                                 instruction->type = ARM_ORR;
1657                                 mnemonic = "ORRS";
1658                                 break;
1659                         case 0xD:
1660                                 instruction->type = ARM_MUL;
1661                                 mnemonic = "MULS";
1662                                 break;
1663                         case 0xE:
1664                                 instruction->type = ARM_BIC;
1665                                 mnemonic = "BICS";
1666                                 break;
1667                         case 0xF:
1668                                 instruction->type = ARM_MVN;
1669                                 mnemonic = "MVNS";
1670                                 break;
1671                 }
1672         }
1673
1674         snprintf(instruction->text, 128,
1675                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i",
1676                          address, opcode, mnemonic, Rd, Rm);
1677
1678         return ERROR_OK;
1679 }
1680
1681 /* PC-relative data addressing is word-aligned even with Thumb */
1682 static inline uint32_t thumb_alignpc4(uint32_t addr)
1683 {
1684         return (addr + 4) & ~3;
1685 }
1686
1687 int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1688 {
1689         uint32_t immediate;
1690         uint8_t Rd = (opcode >> 8) & 0x7;
1691
1692         instruction->type = ARM_LDR;
1693         immediate = opcode & 0x000000ff;
1694         immediate *= 4;
1695
1696         instruction->info.load_store.Rd = Rd;
1697         instruction->info.load_store.Rn = 15 /*PC*/;
1698         instruction->info.load_store.index_mode = 0; /*offset*/
1699         instruction->info.load_store.offset_mode = 0; /*immediate*/
1700         instruction->info.load_store.offset.offset = immediate;
1701
1702         snprintf(instruction->text, 128,
1703                 "0x%8.8" PRIx32 "  0x%4.4x    \t"
1704                 "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8x",
1705                 address, opcode, Rd, immediate,
1706                 thumb_alignpc4(address) + immediate);
1707
1708         return ERROR_OK;
1709 }
1710
1711 int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1712 {
1713         uint8_t Rd = (opcode >> 0) & 0x7;
1714         uint8_t Rn = (opcode >> 3) & 0x7;
1715         uint8_t Rm = (opcode >> 6) & 0x7;
1716         uint8_t opc = (opcode >> 9) & 0x7;
1717         char *mnemonic = NULL;
1718
1719         switch (opc)
1720         {
1721                 case 0:
1722                         instruction->type = ARM_STR;
1723                         mnemonic = "STR";
1724                         break;
1725                 case 1:
1726                         instruction->type = ARM_STRH;
1727                         mnemonic = "STRH";
1728                         break;
1729                 case 2:
1730                         instruction->type = ARM_STRB;
1731                         mnemonic = "STRB";
1732                         break;
1733                 case 3:
1734                         instruction->type = ARM_LDRSB;
1735                         mnemonic = "LDRSB";
1736                         break;
1737                 case 4:
1738                         instruction->type = ARM_LDR;
1739                         mnemonic = "LDR";
1740                         break;
1741                 case 5:
1742                         instruction->type = ARM_LDRH;
1743                         mnemonic = "LDRH";
1744                         break;
1745                 case 6:
1746                         instruction->type = ARM_LDRB;
1747                         mnemonic = "LDRB";
1748                         break;
1749                 case 7:
1750                         instruction->type = ARM_LDRSH;
1751                         mnemonic = "LDRSH";
1752                         break;
1753         }
1754
1755         snprintf(instruction->text, 128,
1756                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, [r%i, r%i]",
1757                         address, opcode, mnemonic, Rd, Rn, Rm);
1758
1759         instruction->info.load_store.Rd = Rd;
1760         instruction->info.load_store.Rn = Rn;
1761         instruction->info.load_store.index_mode = 0; /*offset*/
1762         instruction->info.load_store.offset_mode = 1; /*register*/
1763         instruction->info.load_store.offset.reg.Rm = Rm;
1764
1765         return ERROR_OK;
1766 }
1767
1768 int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1769 {
1770         uint32_t offset = (opcode >> 6) & 0x1f;
1771         uint8_t Rd = (opcode >> 0) & 0x7;
1772         uint8_t Rn = (opcode >> 3) & 0x7;
1773         uint32_t L = opcode & (1 << 11);
1774         uint32_t B = opcode & (1 << 12);
1775         char *mnemonic;
1776         char suffix = ' ';
1777         uint32_t shift = 2;
1778
1779         if (L)
1780         {
1781                 instruction->type = ARM_LDR;
1782                 mnemonic = "LDR";
1783         }
1784         else
1785         {
1786                 instruction->type = ARM_STR;
1787                 mnemonic = "STR";
1788         }
1789
1790         if ((opcode&0xF000) == 0x8000)
1791         {
1792                 suffix = 'H';
1793                 shift = 1;
1794         }
1795         else if (B)
1796         {
1797                 suffix = 'B';
1798                 shift = 0;
1799         }
1800
1801         snprintf(instruction->text, 128,
1802                 "0x%8.8" PRIx32 "  0x%4.4x    \t%s%c\tr%i, [r%i, #%#" PRIx32 "]",
1803                 address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
1804
1805         instruction->info.load_store.Rd = Rd;
1806         instruction->info.load_store.Rn = Rn;
1807         instruction->info.load_store.index_mode = 0; /*offset*/
1808         instruction->info.load_store.offset_mode = 0; /*immediate*/
1809         instruction->info.load_store.offset.offset = offset << shift;
1810
1811         return ERROR_OK;
1812 }
1813
1814 int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1815 {
1816         uint32_t offset = opcode  & 0xff;
1817         uint8_t Rd = (opcode >> 8) & 0x7;
1818         uint32_t L = opcode & (1 << 11);
1819         char *mnemonic;
1820
1821         if (L)
1822         {
1823                 instruction->type = ARM_LDR;
1824                 mnemonic = "LDR";
1825         }
1826         else
1827         {
1828                 instruction->type = ARM_STR;
1829                 mnemonic = "STR";
1830         }
1831
1832         snprintf(instruction->text, 128,
1833                 "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, [SP, #%#" PRIx32 "]",
1834                 address, opcode, mnemonic, Rd, offset*4);
1835
1836         instruction->info.load_store.Rd = Rd;
1837         instruction->info.load_store.Rn = 13 /*SP*/;
1838         instruction->info.load_store.index_mode = 0; /*offset*/
1839         instruction->info.load_store.offset_mode = 0; /*immediate*/
1840         instruction->info.load_store.offset.offset = offset*4;
1841
1842         return ERROR_OK;
1843 }
1844
1845 int evaluate_add_sp_pc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1846 {
1847         uint32_t imm = opcode  & 0xff;
1848         uint8_t Rd = (opcode >> 8) & 0x7;
1849         uint8_t Rn;
1850         uint32_t SP = opcode & (1 << 11);
1851         char *reg_name;
1852
1853         instruction->type = ARM_ADD;
1854
1855         if (SP)
1856         {
1857                 reg_name = "SP";
1858                 Rn = 13;
1859         }
1860         else
1861         {
1862                 reg_name = "PC";
1863                 Rn = 15;
1864         }
1865
1866         snprintf(instruction->text, 128,
1867                 "0x%8.8" PRIx32 "  0x%4.4x  \tADD\tr%i, %s, #%#" PRIx32,
1868                 address, opcode, Rd, reg_name, imm * 4);
1869
1870         instruction->info.data_proc.variant = 0 /* immediate */;
1871         instruction->info.data_proc.Rd = Rd;
1872         instruction->info.data_proc.Rn = Rn;
1873         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
1874
1875         return ERROR_OK;
1876 }
1877
1878 int evaluate_adjust_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1879 {
1880         uint32_t imm = opcode  & 0x7f;
1881         uint8_t opc = opcode & (1 << 7);
1882         char *mnemonic;
1883
1884
1885         if (opc)
1886         {
1887                 instruction->type = ARM_SUB;
1888                 mnemonic = "SUB";
1889         }
1890         else
1891         {
1892                 instruction->type = ARM_ADD;
1893                 mnemonic = "ADD";
1894         }
1895
1896         snprintf(instruction->text, 128,
1897                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s\tSP, #%#" PRIx32,
1898                         address, opcode, mnemonic, imm*4);
1899
1900         instruction->info.data_proc.variant = 0 /* immediate */;
1901         instruction->info.data_proc.Rd = 13 /*SP*/;
1902         instruction->info.data_proc.Rn = 13 /*SP*/;
1903         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
1904
1905         return ERROR_OK;
1906 }
1907
1908 int evaluate_breakpoint_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1909 {
1910         uint32_t imm = opcode  & 0xff;
1911
1912         instruction->type = ARM_BKPT;
1913
1914         snprintf(instruction->text, 128,
1915                         "0x%8.8" PRIx32 "  0x%4.4x  \tBKPT\t%#2.2" PRIx32 "",
1916                         address, opcode, imm);
1917
1918         return ERROR_OK;
1919 }
1920
1921 int evaluate_load_store_multiple_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1922 {
1923         uint32_t reg_list = opcode  & 0xff;
1924         uint32_t L = opcode & (1 << 11);
1925         uint32_t R = opcode & (1 << 8);
1926         uint8_t Rn = (opcode >> 8) & 7;
1927         uint8_t addr_mode = 0 /* IA */;
1928         char reg_names[40];
1929         char *reg_names_p;
1930         char *mnemonic;
1931         char ptr_name[7] = "";
1932         int i;
1933
1934         if ((opcode & 0xf000) == 0xc000)
1935         { /* generic load/store multiple */
1936                 if (L)
1937                 {
1938                         instruction->type = ARM_LDM;
1939                         mnemonic = "LDM";
1940                 }
1941                 else
1942                 {
1943                         instruction->type = ARM_STM;
1944                         mnemonic = "STM";
1945                 }
1946                 snprintf(ptr_name,7,"r%i!, ",Rn);
1947         }
1948         else
1949         { /* push/pop */
1950                 Rn = 13; /* SP */
1951                 if (L)
1952                 {
1953                         instruction->type = ARM_LDM;
1954                         mnemonic = "POP";
1955                         if (R)
1956                                 reg_list |= (1 << 15) /*PC*/;
1957                 }
1958                 else
1959                 {
1960                         instruction->type = ARM_STM;
1961                         mnemonic = "PUSH";
1962                         addr_mode = 3; /*DB*/
1963                         if (R)
1964                                 reg_list |= (1 << 14) /*LR*/;
1965                 }
1966         }
1967
1968         reg_names_p = reg_names;
1969         for (i = 0; i <= 15; i++)
1970         {
1971                 if (reg_list & (1 << i))
1972                         reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i);
1973         }
1974         if (reg_names_p > reg_names)
1975                 reg_names_p[-2] = '\0';
1976         else /* invalid op : no registers */
1977                 reg_names[0] = '\0';
1978
1979         snprintf(instruction->text, 128,
1980                         "0x%8.8" PRIx32 "  0x%4.4x  \t%s\t%s{%s}",
1981                         address, opcode, mnemonic, ptr_name, reg_names);
1982
1983         instruction->info.load_store_multiple.register_list = reg_list;
1984         instruction->info.load_store_multiple.Rn = Rn;
1985         instruction->info.load_store_multiple.addressing_mode = addr_mode;
1986
1987         return ERROR_OK;
1988 }
1989
1990 int evaluate_cond_branch_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1991 {
1992         uint32_t offset = opcode  & 0xff;
1993         uint8_t cond = (opcode >> 8) & 0xf;
1994         uint32_t target_address;
1995
1996         if (cond == 0xf)
1997         {
1998                 instruction->type = ARM_SWI;
1999                 snprintf(instruction->text, 128,
2000                                 "0x%8.8" PRIx32 "  0x%4.4x    \tSVC\t%#2.2" PRIx32,
2001                                 address, opcode, offset);
2002                 return ERROR_OK;
2003         }
2004         else if (cond == 0xe)
2005         {
2006                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2007                 snprintf(instruction->text, 128,
2008                         "0x%8.8" PRIx32 "  0x%4.4x    \tUNDEFINED INSTRUCTION",
2009                         address, opcode);
2010                 return ERROR_OK;
2011         }
2012
2013         /* sign extend 8-bit offset */
2014         if (offset & 0x00000080)
2015                 offset = 0xffffff00 | offset;
2016
2017         target_address = address + 4 + (offset << 1);
2018
2019         snprintf(instruction->text, 128,
2020                         "0x%8.8" PRIx32 "  0x%4.4x    \tB%s\t%#8.8" PRIx32,
2021                         address, opcode,
2022                         arm_condition_strings[cond], target_address);
2023
2024         instruction->type = ARM_B;
2025         instruction->info.b_bl_bx_blx.reg_operand = -1;
2026         instruction->info.b_bl_bx_blx.target_address = target_address;
2027
2028         return ERROR_OK;
2029 }
2030
2031 static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
2032                 arm_instruction_t *instruction)
2033 {
2034         unsigned offset;
2035
2036         /* added in Thumb2 */
2037         offset = (opcode >> 3) & 0x1f;
2038         offset |= (opcode & 0x0200) >> 4;
2039
2040         snprintf(instruction->text, 128,
2041                         "0x%8.8" PRIx32 "  0x%4.4x    \tCB%sZ\tr%d, %#8.8" PRIx32,
2042                         address, opcode,
2043                         (opcode & 0x0800) ? "N" : "",
2044                         opcode & 0x7, address + 4 + (offset << 1));
2045
2046         return ERROR_OK;
2047 }
2048
2049 static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
2050                 arm_instruction_t *instruction)
2051 {
2052         /* added in ARMv6 */
2053         snprintf(instruction->text, 128,
2054                         "0x%8.8" PRIx32 "  0x%4.4x    \t%cXT%c\tr%d, r%d",
2055                         address, opcode,
2056                         (opcode & 0x0080) ? 'U' : 'S',
2057                         (opcode & 0x0040) ? 'B' : 'H',
2058                         opcode & 0x7, (opcode >> 3) & 0x7);
2059
2060         return ERROR_OK;
2061 }
2062
2063 static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
2064                 arm_instruction_t *instruction)
2065 {
2066         /* added in ARMv6 */
2067         if ((opcode & 0x0ff0) == 0x0650)
2068                 snprintf(instruction->text, 128,
2069                                 "0x%8.8" PRIx32 "  0x%4.4x    \tSETEND %s",
2070                                 address, opcode,
2071                                 (opcode & 0x80) ? "BE" : "LE");
2072         else /* ASSUME (opcode & 0x0fe0) == 0x0660 */
2073                 snprintf(instruction->text, 128,
2074                                 "0x%8.8" PRIx32 "  0x%4.4x    \tCPSI%c %s%s%s",
2075                                 address, opcode,
2076                                 (opcode & 0x0010) ? 'D' : 'E',
2077                                 (opcode & 0x0004) ? "A" : "",
2078                                 (opcode & 0x0002) ? "I" : "",
2079                                 (opcode & 0x0001) ? "F" : "");
2080
2081         return ERROR_OK;
2082 }
2083
2084 static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
2085                 arm_instruction_t *instruction)
2086 {
2087         char *suffix;
2088
2089         /* added in ARMv6 */
2090         switch (opcode & 0x00c0) {
2091         case 0:
2092                 suffix = "";
2093                 break;
2094         case 1:
2095                 suffix = "16";
2096                 break;
2097         default:
2098                 suffix = "SH";
2099                 break;
2100         }
2101         snprintf(instruction->text, 128,
2102                         "0x%8.8" PRIx32 "  0x%4.4x    \tREV%s\tr%d, r%d",
2103                         address, opcode, suffix,
2104                         opcode & 0x7, (opcode >> 3) & 0x7);
2105
2106         return ERROR_OK;
2107 }
2108
2109 static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
2110                 arm_instruction_t *instruction)
2111 {
2112         char *hint;
2113
2114         switch ((opcode >> 4) & 0x0f) {
2115         case 0:
2116                 hint = "NOP";
2117                 break;
2118         case 1:
2119                 hint = "YIELD";
2120                 break;
2121         case 2:
2122                 hint = "WFE";
2123                 break;
2124         case 3:
2125                 hint = "WFI";
2126                 break;
2127         case 4:
2128                 hint = "SEV";
2129                 break;
2130         default:
2131                 hint = "HINT (UNRECOGNIZED)";
2132                 break;
2133         }
2134
2135         snprintf(instruction->text, 128,
2136                         "0x%8.8" PRIx32 "  0x%4.4x    \t%s",
2137                         address, opcode, hint);
2138
2139         return ERROR_OK;
2140 }
2141
2142 static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
2143                 arm_instruction_t *instruction)
2144 {
2145         unsigned cond = (opcode >> 4) & 0x0f;
2146         char *x = "", *y = "", *z = "";
2147
2148         if (opcode & 0x01)
2149                 z = (opcode & 0x02) ? "T" : "E";
2150         if (opcode & 0x03)
2151                 y = (opcode & 0x04) ? "T" : "E";
2152         if (opcode & 0x07)
2153                 x = (opcode & 0x08) ? "T" : "E";
2154
2155         snprintf(instruction->text, 128,
2156                         "0x%8.8" PRIx32 "  0x%4.4x    \tIT%s%s%s\t%s",
2157                         address, opcode,
2158                         x, y, z, arm_condition_strings[cond]);
2159
2160         /* NOTE:  strictly speaking, the next 1-4 instructions should
2161          * now be displayed with the relevant conditional suffix...
2162          */
2163
2164         return ERROR_OK;
2165 }
2166
2167 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
2168 {
2169         /* clear fields, to avoid confusion */
2170         memset(instruction, 0, sizeof(arm_instruction_t));
2171         instruction->opcode = opcode;
2172         instruction->instruction_size = 2;
2173
2174         if ((opcode & 0xe000) == 0x0000)
2175         {
2176                 /* add/substract register or immediate */
2177                 if ((opcode & 0x1800) == 0x1800)
2178                         return evaluate_add_sub_thumb(opcode, address, instruction);
2179                 /* shift by immediate */
2180                 else
2181                         return evaluate_shift_imm_thumb(opcode, address, instruction);
2182         }
2183
2184         /* Add/substract/compare/move immediate */
2185         if ((opcode & 0xe000) == 0x2000)
2186         {
2187                 return evaluate_data_proc_imm_thumb(opcode, address, instruction);
2188         }
2189
2190         /* Data processing instructions */
2191         if ((opcode & 0xf800) == 0x4000)
2192         {
2193                 return evaluate_data_proc_thumb(opcode, address, instruction);
2194         }
2195
2196         /* Load from literal pool */
2197         if ((opcode & 0xf800) == 0x4800)
2198         {
2199                 return evaluate_load_literal_thumb(opcode, address, instruction);
2200         }
2201
2202         /* Load/Store register offset */
2203         if ((opcode & 0xf000) == 0x5000)
2204         {
2205                 return evaluate_load_store_reg_thumb(opcode, address, instruction);
2206         }
2207
2208         /* Load/Store immediate offset */
2209         if (((opcode & 0xe000) == 0x6000)
2210                 ||((opcode & 0xf000) == 0x8000))
2211         {
2212                 return evaluate_load_store_imm_thumb(opcode, address, instruction);
2213         }
2214
2215         /* Load/Store from/to stack */
2216         if ((opcode & 0xf000) == 0x9000)
2217         {
2218                 return evaluate_load_store_stack_thumb(opcode, address, instruction);
2219         }
2220
2221         /* Add to SP/PC */
2222         if ((opcode & 0xf000) == 0xa000)
2223         {
2224                 return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2225         }
2226
2227         /* Misc */
2228         if ((opcode & 0xf000) == 0xb000)
2229         {
2230                 switch ((opcode >> 8) & 0x0f) {
2231                 case 0x0:
2232                         return evaluate_adjust_stack_thumb(opcode, address, instruction);
2233                 case 0x1:
2234                 case 0x3:
2235                 case 0x9:
2236                 case 0xb:
2237                         return evaluate_cb_thumb(opcode, address, instruction);
2238                 case 0x2:
2239                         return evaluate_extend_thumb(opcode, address, instruction);
2240                 case 0x4:
2241                 case 0x5:
2242                 case 0xc:
2243                 case 0xd:
2244                         return evaluate_load_store_multiple_thumb(opcode, address,
2245                                                 instruction);
2246                 case 0x6:
2247                         return evaluate_cps_thumb(opcode, address, instruction);
2248                 case 0xa:
2249                         if ((opcode & 0x00c0) == 0x0080)
2250                                 break;
2251                         return evaluate_byterev_thumb(opcode, address, instruction);
2252                 case 0xe:
2253                         return evaluate_breakpoint_thumb(opcode, address, instruction);
2254                 case 0xf:
2255                         if (opcode & 0x000f)
2256                                 return evaluate_ifthen_thumb(opcode, address,
2257                                                 instruction);
2258                         else
2259                                 return evaluate_hint_thumb(opcode, address,
2260                                                 instruction);
2261                 }
2262
2263                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2264                 snprintf(instruction->text, 128,
2265                         "0x%8.8" PRIx32 "  0x%4.4x    \tUNDEFINED INSTRUCTION",
2266                         address, opcode);
2267                 return ERROR_OK;
2268         }
2269
2270         /* Load/Store multiple */
2271         if ((opcode & 0xf000) == 0xc000)
2272         {
2273                 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2274         }
2275
2276         /* Conditional branch + SWI */
2277         if ((opcode & 0xf000) == 0xd000)
2278         {
2279                 return evaluate_cond_branch_thumb(opcode, address, instruction);
2280         }
2281
2282         if ((opcode & 0xe000) == 0xe000)
2283         {
2284                 /* Undefined instructions */
2285                 if ((opcode & 0xf801) == 0xe801)
2286                 {
2287                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
2288                         snprintf(instruction->text, 128,
2289                                         "0x%8.8" PRIx32 "  0x%8.8x\t"
2290                                         "UNDEFINED INSTRUCTION",
2291                                         address, opcode);
2292                         return ERROR_OK;
2293                 }
2294                 else
2295                 { /* Branch to offset */
2296                         return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2297                 }
2298         }
2299
2300         LOG_ERROR("should never reach this point (opcode=%04x)",opcode);
2301         return -1;
2302 }
2303
2304 static int t2ev_b_bl(uint32_t opcode, uint32_t address,
2305                 arm_instruction_t *instruction, char *cp)
2306 {
2307         unsigned offset;
2308         unsigned b21 = 1 << 21;
2309         unsigned b22 = 1 << 22;
2310
2311         /* instead of combining two smaller 16-bit branch instructions,
2312          * Thumb2 uses only one larger 32-bit instruction.
2313          */
2314         offset = opcode & 0x7ff;
2315         offset |= (opcode & 0x03ff0000) >> 5;
2316         if (opcode & (1 << 26)) {
2317                 offset |= 0xff << 23;
2318                 if ((opcode & (1 << 11)) == 0)
2319                         b21 = 0;
2320                 if ((opcode & (1 << 13)) == 0)
2321                         b22 = 0;
2322         } else {
2323                 if (opcode & (1 << 11))
2324                         b21 = 0;
2325                 if (opcode & (1 << 13))
2326                         b22 = 0;
2327         }
2328         offset |= b21;
2329         offset |= b22;
2330
2331
2332         address += 4;
2333         address += offset << 1;
2334
2335         instruction->type = (opcode & (1 << 14)) ? ARM_BL : ARM_B;
2336         instruction->info.b_bl_bx_blx.reg_operand = -1;
2337         instruction->info.b_bl_bx_blx.target_address = address;
2338         sprintf(cp, "%s\t%#8.8" PRIx32,
2339                         (opcode & (1 << 14)) ? "BL" : "B.W",
2340                         address);
2341
2342         return ERROR_OK;
2343 }
2344
2345 static int t2ev_cond_b(uint32_t opcode, uint32_t address,
2346                 arm_instruction_t *instruction, char *cp)
2347 {
2348         unsigned offset;
2349         unsigned b17 = 1 << 17;
2350         unsigned b18 = 1 << 18;
2351         unsigned cond = (opcode >> 22) & 0x0f;
2352
2353         offset = opcode & 0x7ff;
2354         offset |= (opcode & 0x003f0000) >> 5;
2355         if (opcode & (1 << 26)) {
2356                 offset |= 0xffff << 19;
2357                 if ((opcode & (1 << 11)) == 0)
2358                         b17 = 0;
2359                 if ((opcode & (1 << 13)) == 0)
2360                         b18 = 0;
2361         } else {
2362                 if (opcode & (1 << 11))
2363                         b17 = 0;
2364                 if (opcode & (1 << 13))
2365                         b18 = 0;
2366         }
2367         offset |= b17;
2368         offset |= b18;
2369
2370         address += 4;
2371         address += offset << 1;
2372
2373         instruction->type = ARM_B;
2374         instruction->info.b_bl_bx_blx.reg_operand = -1;
2375         instruction->info.b_bl_bx_blx.target_address = address;
2376         sprintf(cp, "B%s.W\t%#8.8" PRIx32,
2377                         arm_condition_strings[cond],
2378                         address);
2379
2380         return ERROR_OK;
2381 }
2382
2383 static const char *special_name(int number)
2384 {
2385         char *special = "(RESERVED)";
2386
2387         switch (number) {
2388         case 0:
2389                 special = "apsr";
2390                 break;
2391         case 1:
2392                 special = "iapsr";
2393                 break;
2394         case 2:
2395                 special = "eapsr";
2396                 break;
2397         case 3:
2398                 special = "xpsr";
2399                 break;
2400         case 5:
2401                 special = "ipsr";
2402                 break;
2403         case 6:
2404                 special = "epsr";
2405                 break;
2406         case 7:
2407                 special = "iepsr";
2408                 break;
2409         case 8:
2410                 special = "msp";
2411                 break;
2412         case 9:
2413                 special = "psp";
2414                 break;
2415         case 16:
2416                 special = "primask";
2417                 break;
2418         case 17:
2419                 special = "basepri";
2420                 break;
2421         case 18:
2422                 special = "basepri_max";
2423                 break;
2424         case 19:
2425                 special = "faultmask";
2426                 break;
2427         case 20:
2428                 special = "control";
2429                 break;
2430         }
2431         return special;
2432 }
2433
2434 static int t2ev_hint(uint32_t opcode, uint32_t address,
2435                 arm_instruction_t *instruction, char *cp)
2436 {
2437         const char *mnemonic;
2438
2439         if (opcode & 0x0700) {
2440                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2441                 strcpy(cp, "UNDEFINED");
2442                 return ERROR_OK;
2443         }
2444
2445         if (opcode & 0x00f0) {
2446                 sprintf(cp, "DBG\t#%d", opcode & 0xf);
2447                 return ERROR_OK;
2448         }
2449
2450         switch (opcode & 0x0f) {
2451         case 0:
2452                 mnemonic = "NOP.W";
2453                 break;
2454         case 1:
2455                 mnemonic = "YIELD.W";
2456                 break;
2457         case 2:
2458                 mnemonic = "WFE.W";
2459                 break;
2460         case 3:
2461                 mnemonic = "WFI.W";
2462                 break;
2463         case 4:
2464                 mnemonic = "SEV.W";
2465                 break;
2466         default:
2467                 mnemonic = "HINT.W (UNRECOGNIZED)";
2468                 break;
2469         }
2470         strcpy(cp, mnemonic);
2471         return ERROR_OK;
2472 }
2473
2474 static int t2ev_misc(uint32_t opcode, uint32_t address,
2475                 arm_instruction_t *instruction, char *cp)
2476 {
2477         const char *mnemonic;
2478
2479         switch ((opcode >> 4) & 0x0f) {
2480         case 2:
2481                 mnemonic = "CLREX";
2482                 break;
2483         case 4:
2484                 mnemonic = "DSB";
2485                 break;
2486         case 5:
2487                 mnemonic = "DMB";
2488                 break;
2489         case 6:
2490                 mnemonic = "ISB";
2491                 break;
2492         default:
2493                 return ERROR_INVALID_ARGUMENTS;
2494         }
2495         strcpy(cp, mnemonic);
2496         return ERROR_OK;
2497 }
2498
2499 static int t2ev_b_misc(uint32_t opcode, uint32_t address,
2500                 arm_instruction_t *instruction, char *cp)
2501 {
2502         /* permanently undefined */
2503         if ((opcode & 0x07f07000) == 0x07f02000) {
2504                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2505                 strcpy(cp, "UNDEFINED");
2506                 return ERROR_OK;
2507         }
2508
2509         switch ((opcode >> 12) & 0x5) {
2510         case 0x1:
2511         case 0x5:
2512                 return t2ev_b_bl(opcode, address, instruction, cp);
2513         case 0x4:
2514                 goto undef;
2515         case 0:
2516                 if (((opcode >> 23) & 0x07) == 0x07)
2517                         return t2ev_cond_b(opcode, address, instruction, cp);
2518                 if (opcode & (1 << 26))
2519                         goto undef;
2520                 break;
2521         }
2522
2523         switch ((opcode >> 20) & 0x7f) {
2524         case 0x38:
2525         case 0x39:
2526                 sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff),
2527                                 (opcode >> 16) & 0x0f);
2528                 return ERROR_OK;
2529         case 0x3a:
2530                 return t2ev_hint(opcode, address, instruction, cp);
2531         case 0x3b:
2532                 return t2ev_misc(opcode, address, instruction, cp);
2533         case 0x3e:
2534         case 0x3f:
2535                 sprintf(cp, "MRS\tr%d, %s", (opcode >> 16) & 0x0f,
2536                                 special_name(opcode & 0xff));
2537                 return ERROR_OK;
2538         }
2539
2540 undef:
2541         return ERROR_INVALID_ARGUMENTS;
2542 }
2543
2544 static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
2545                 arm_instruction_t *instruction, char *cp)
2546 {
2547         char *mnemonic = NULL;
2548         int rn = (opcode >> 16) & 0xf;
2549         int rd = (opcode >> 8) & 0xf;
2550         unsigned immed = opcode & 0xff;
2551         unsigned func;
2552         bool one = false;
2553         char *suffix = "";
2554
2555         /* ARMv7-M: A5.3.2 Modified immediate constants */
2556         func = (opcode >> 11) & 0x0e;
2557         if (immed & 0x80)
2558                 func |= 1;
2559         if (opcode & (1 << 26))
2560                 func |= 0x10;
2561
2562         /* "Modified" immediates */
2563         switch (func >> 1) {
2564         case 0:
2565                 break;
2566         case 2:
2567                 immed <<= 8;
2568                 /* FALLTHROUGH */
2569         case 1:
2570                 immed += immed << 16;
2571                 break;
2572         case 3:
2573                 immed += immed << 8;
2574                 immed += immed << 16;
2575                 break;
2576         default:
2577                 immed |= 0x80;
2578                 immed = ror(immed, func);
2579         }
2580
2581         if (opcode & (1 << 20))
2582                 suffix = "S";
2583
2584         switch ((opcode >> 21) & 0xf) {
2585         case 0:
2586                 if (rd == 0xf) {
2587                         instruction->type = ARM_TST;
2588                         mnemonic = "TST";
2589                         one = true;
2590                         suffix = "";
2591                         rd = rn;
2592                 } else {
2593                         instruction->type = ARM_AND;
2594                         mnemonic = "AND";
2595                 }
2596                 break;
2597         case 1:
2598                 instruction->type = ARM_BIC;
2599                 mnemonic = "BIC";
2600                 break;
2601         case 2:
2602                 if (rn == 0xf) {
2603                         instruction->type = ARM_MOV;
2604                         mnemonic = "MOV";
2605                         one = true;
2606                 } else {
2607                         instruction->type = ARM_ORR;
2608                         mnemonic = "ORR";
2609                 }
2610                 break;
2611         case 3:
2612                 if (rn == 0xf) {
2613                         instruction->type = ARM_MVN;
2614                         mnemonic = "MVN";
2615                         one = true;
2616                 } else {
2617                         // instruction->type = ARM_ORN;
2618                         mnemonic = "ORN";
2619                 }
2620                 break;
2621         case 4:
2622                 if (rd == 0xf) {
2623                         instruction->type = ARM_TEQ;
2624                         mnemonic = "TEQ";
2625                         one = true;
2626                         suffix = "";
2627                         rd = rn;
2628                 } else {
2629                         instruction->type = ARM_EOR;
2630                         mnemonic = "EOR";
2631                 }
2632                 break;
2633         case 8:
2634                 if (rd == 0xf) {
2635                         instruction->type = ARM_CMN;
2636                         mnemonic = "CMN";
2637                         one = true;
2638                         suffix = "";
2639                         rd = rn;
2640                 } else {
2641                         instruction->type = ARM_ADD;
2642                         mnemonic = "ADD";
2643                 }
2644                 break;
2645         case 10:
2646                 instruction->type = ARM_ADC;
2647                 mnemonic = "ADC";
2648                 break;
2649         case 11:
2650                 instruction->type = ARM_SBC;
2651                 mnemonic = "SBC";
2652                 break;
2653         case 13:
2654                 if (rd == 0xf) {
2655                         instruction->type = ARM_CMP;
2656                         mnemonic = "CMP";
2657                         one = true;
2658                         suffix = "";
2659                         rd = rn;
2660                 } else {
2661                         instruction->type = ARM_SUB;
2662                         mnemonic = "SUB";
2663                 }
2664                 break;
2665         case 14:
2666                 instruction->type = ARM_RSB;
2667                 mnemonic = "RSB";
2668                 break;
2669         default:
2670                 return ERROR_INVALID_ARGUMENTS;
2671         }
2672
2673         if (one)
2674                 sprintf(cp, "%s\tr%d, #%d\t; %#8.8x",
2675                                 mnemonic, rd, immed, immed);
2676         else
2677                 sprintf(cp, "%s%s\tr%d, r%d, #%d\t; %#8.8x",
2678                                 mnemonic, suffix, rd, rn, immed, immed);
2679
2680         return ERROR_OK;
2681 }
2682
2683 static int t2ev_data_immed(uint32_t opcode, uint32_t address,
2684                 arm_instruction_t *instruction, char *cp)
2685 {
2686         char *mnemonic = NULL;
2687         int rn = (opcode >> 16) & 0xf;
2688         int rd = (opcode >> 8) & 0xf;
2689         unsigned immed;
2690         bool add = false;
2691         bool is_signed = false;
2692
2693         immed = (opcode & 0x0ff) | ((opcode & 0x7000) >> 12);
2694         if (opcode & (1 << 27))
2695                 immed |= (1 << 11);
2696
2697         switch ((opcode >> 20) & 0x1f) {
2698         case 0:
2699                 if (rn == 0xf) {
2700                         add = true;
2701                         goto do_adr;
2702                 }
2703                 mnemonic = "ADD.W";
2704                 break;
2705         case 4:
2706                 mnemonic = "MOV.W";
2707                 break;
2708         case 0x0a:
2709                 if (rn == 0xf)
2710                         goto do_adr;
2711                 mnemonic = "SUB.W";
2712                 break;
2713         case 0x0c:
2714                 /* move constant to top 16 bits of register */
2715                 immed |= (opcode >> 4) & 0xf000;
2716                 sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rn, immed, immed);
2717                 return ERROR_OK;
2718         case 0x10:
2719         case 0x12:
2720                 is_signed = true;
2721         case 0x18:
2722         case 0x1a:
2723                 /* signed/unsigned saturated add */
2724                 immed = (opcode >> 6) & 0x03;
2725                 immed |= (opcode >> 10) & 0x1c;
2726                 sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t",
2727                                 is_signed ? "S" : "U",
2728                                 rd, (opcode & 0x1f) + 1, rn,
2729                                 (opcode & (1 << 21)) ? "ASR" : "LSL",
2730                                 immed ? immed : 32);
2731                 return ERROR_OK;
2732         case 0x14:
2733                 is_signed = true;
2734                 /* FALLTHROUGH */
2735         case 0x1c:
2736                 /* signed/unsigned bitfield extract */
2737                 immed = (opcode >> 6) & 0x03;
2738                 immed |= (opcode >> 10) & 0x1c;
2739                 sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t",
2740                                 is_signed ? "S" : "U",
2741                                 rd, rn, immed,
2742                                 (opcode & 0x1f) + 1);
2743                 return ERROR_OK;
2744         case 0x16:
2745                 immed = (opcode >> 6) & 0x03;
2746                 immed |= (opcode >> 10) & 0x1c;
2747                 if (rn == 0xf)          /* bitfield clear */
2748                         sprintf(cp, "BFC\tr%d, #%d, #%d\t",
2749                                         rd, immed,
2750                                         (opcode & 0x1f) + 1 - immed);
2751                 else                    /* bitfield insert */
2752                         sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t",
2753                                         rd, rn, immed,
2754                                         (opcode & 0x1f) + 1 - immed);
2755                 return ERROR_OK;
2756         default:
2757                 return ERROR_INVALID_ARGUMENTS;
2758         }
2759
2760         sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic,
2761                         rd, rn, immed, immed);
2762         return ERROR_OK;
2763
2764 do_adr:
2765         address = thumb_alignpc4(address);
2766         if (add)
2767                 address += immed;
2768         else
2769                 address -= immed;
2770         /* REVISIT "ADD/SUB Rd, PC, #const ; 0x..." might be better;
2771          * not hiding the pc-relative stuff will sometimes be useful.
2772          */
2773         sprintf(cp, "ADR.W\tr%d, %#8.8" PRIx32, rd, address);
2774         return ERROR_OK;
2775 }
2776
2777 /*
2778  * REVISIT for Thumb2 instructions, instruction->type and friends aren't
2779  * always set.  That means eventual arm_simulate_step() support for Thumb2
2780  * will need work in this area.
2781  */
2782 int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruction)
2783 {
2784         int retval;
2785         uint16_t op;
2786         uint32_t opcode;
2787         char *cp;
2788
2789         /* clear low bit ... it's set on function pointers */
2790         address &= ~1;
2791
2792         /* clear fields, to avoid confusion */
2793         memset(instruction, 0, sizeof(arm_instruction_t));
2794
2795         /* read first halfword, see if this is the only one */
2796         retval = target_read_u16(target, address, &op);
2797         if (retval != ERROR_OK)
2798                 return retval;
2799
2800         switch (op & 0xf800) {
2801         case 0xf800:
2802         case 0xf000:
2803         case 0xe800:
2804                 /* 32-bit instructions */
2805                 instruction->instruction_size = 4;
2806                 opcode = op << 16;
2807                 retval = target_read_u16(target, address + 2, &op);
2808                 if (retval != ERROR_OK)
2809                         return retval;
2810                 opcode |= op;
2811                 instruction->opcode = opcode;
2812                 break;
2813         default:
2814                 /* 16-bit:  Thumb1 + IT + CBZ/CBNZ + ... */
2815                 return thumb_evaluate_opcode(op, address, instruction);
2816         }
2817
2818         snprintf(instruction->text, 128,
2819                         "0x%8.8" PRIx32 "  0x%8.8" PRIx32 "\t",
2820                         address, opcode);
2821         cp = strchr(instruction->text, 0);
2822         retval = ERROR_FAIL;
2823
2824         /* ARMv7-M: A5.3.1 Data processing (modified immediate) */
2825         if ((opcode & 0x1a008000) == 0x10000000)
2826                 retval = t2ev_data_mod_immed(opcode, address, instruction, cp);
2827
2828         /* ARMv7-M: A5.3.3 Data processing (plain binary immediate) */
2829         else if ((opcode & 0x1a008000) == 0x12000000)
2830                 retval = t2ev_data_immed(opcode, address, instruction, cp);
2831
2832         /* ARMv7-M: A5.3.4 Branches and miscellaneous control */
2833         else if ((opcode & 0x18008000) == 0x10008000)
2834                 retval = t2ev_b_misc(opcode, address, instruction, cp);
2835
2836         /* FIXME decode more 32-bit instructions */
2837
2838         if (retval == ERROR_OK)
2839                 return retval;
2840
2841         if (retval == ERROR_INVALID_ARGUMENTS) {
2842                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2843                 strcpy(cp, "UNDEFINED OPCODE");
2844                 return ERROR_OK;
2845         }
2846
2847         LOG_DEBUG("Can't decode 32-bit Thumb2 yet (opcode=%08x)", opcode);
2848
2849         strcpy(cp, "(32-bit Thumb2 ...)");
2850         return ERROR_OK;
2851 }
2852
2853 int arm_access_size(arm_instruction_t *instruction)
2854 {
2855         if ((instruction->type == ARM_LDRB)
2856                 || (instruction->type == ARM_LDRBT)
2857                 || (instruction->type == ARM_LDRSB)
2858                 || (instruction->type == ARM_STRB)
2859                 || (instruction->type == ARM_STRBT))
2860         {
2861                 return 1;
2862         }
2863         else if ((instruction->type == ARM_LDRH)
2864                 || (instruction->type == ARM_LDRSH)
2865                 || (instruction->type == ARM_STRH))
2866         {
2867                 return 2;
2868         }
2869         else if ((instruction->type == ARM_LDR)
2870                 || (instruction->type == ARM_LDRT)
2871                 || (instruction->type == ARM_STR)
2872                 || (instruction->type == ARM_STRT))
2873         {
2874                 return 4;
2875         }
2876         else if ((instruction->type == ARM_LDRD)
2877                 || (instruction->type == ARM_STRD))
2878         {
2879                 return 8;
2880         }
2881         else
2882         {
2883                 LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type);
2884                 return 0;
2885         }
2886 }