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, "0x%8.8" PRIx32 "\t0x%4.4x\t%s 0x%8.8" PRIx32 , address, opcode,mnemonic, target_address);
1371
1372         instruction->info.b_bl_bx_blx.reg_operand = -1;
1373         instruction->info.b_bl_bx_blx.target_address = target_address;
1374
1375         return ERROR_OK;
1376 }
1377
1378 int evaluate_add_sub_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1379 {
1380         uint8_t Rd = (opcode >> 0) & 0x7;
1381         uint8_t Rn = (opcode >> 3) & 0x7;
1382         uint8_t Rm_imm = (opcode >> 6) & 0x7;
1383         uint32_t opc = opcode & (1 << 9);
1384         uint32_t reg_imm  = opcode & (1 << 10);
1385         char *mnemonic;
1386
1387         if (opc)
1388         {
1389                 instruction->type = ARM_SUB;
1390                 mnemonic = "SUBS";
1391         }
1392         else
1393         {
1394                 instruction->type = ARM_ADD;
1395                 mnemonic = "ADDS";
1396         }
1397
1398         instruction->info.data_proc.Rd = Rd;
1399         instruction->info.data_proc.Rn = Rn;
1400         instruction->info.data_proc.S = 1;
1401
1402         if (reg_imm)
1403         {
1404                 instruction->info.data_proc.variant = 0; /*immediate*/
1405                 instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
1406                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, #%d",
1407                                  address, opcode, mnemonic, Rd, Rn, Rm_imm);
1408         }
1409         else
1410         {
1411                 instruction->info.data_proc.variant = 1; /*immediate shift*/
1412                 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
1413                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, r%i",
1414                                  address, opcode, mnemonic, Rd, Rn, Rm_imm);
1415         }
1416
1417         return ERROR_OK;
1418 }
1419
1420 int evaluate_shift_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1421 {
1422         uint8_t Rd = (opcode >> 0) & 0x7;
1423         uint8_t Rm = (opcode >> 3) & 0x7;
1424         uint8_t imm = (opcode >> 6) & 0x1f;
1425         uint8_t opc = (opcode >> 11) & 0x3;
1426         char *mnemonic = NULL;
1427
1428         switch (opc)
1429         {
1430                 case 0:
1431                         instruction->type = ARM_MOV;
1432                         mnemonic = "LSLS";
1433                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
1434                         break;
1435                 case 1:
1436                         instruction->type = ARM_MOV;
1437                         mnemonic = "LSRS";
1438                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
1439                         break;
1440                 case 2:
1441                         instruction->type = ARM_MOV;
1442                         mnemonic = "ASRS";
1443                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
1444                         break;
1445         }
1446
1447         if ((imm == 0) && (opc != 0))
1448                 imm = 32;
1449
1450         instruction->info.data_proc.Rd = Rd;
1451         instruction->info.data_proc.Rn = -1;
1452         instruction->info.data_proc.S = 1;
1453
1454         instruction->info.data_proc.variant = 1; /*immediate_shift*/
1455         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1456         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
1457
1458         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, #0x%02x" ,
1459                                  address, opcode, mnemonic, Rd, Rm, imm);
1460
1461         return ERROR_OK;
1462 }
1463
1464 int evaluate_data_proc_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1465 {
1466         uint8_t imm = opcode & 0xff;
1467         uint8_t Rd = (opcode >> 8) & 0x7;
1468         uint32_t opc = (opcode >> 11) & 0x3;
1469         char *mnemonic = NULL;
1470
1471         instruction->info.data_proc.Rd = Rd;
1472         instruction->info.data_proc.Rn = Rd;
1473         instruction->info.data_proc.S = 1;
1474         instruction->info.data_proc.variant = 0; /*immediate*/
1475         instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
1476
1477         switch (opc)
1478         {
1479                 case 0:
1480                         instruction->type = ARM_MOV;
1481                         mnemonic = "MOVS";
1482                         instruction->info.data_proc.Rn = -1;
1483                         break;
1484                 case 1:
1485                         instruction->type = ARM_CMP;
1486                         mnemonic = "CMP";
1487                         instruction->info.data_proc.Rd = -1;
1488                         break;
1489                 case 2:
1490                         instruction->type = ARM_ADD;
1491                         mnemonic = "ADDS";
1492                         break;
1493                 case 3:
1494                         instruction->type = ARM_SUB;
1495                         mnemonic = "SUBS";
1496                         break;
1497         }
1498
1499         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, #0x%02x" ,
1500                                  address, opcode, mnemonic, Rd, imm);
1501
1502         return ERROR_OK;
1503 }
1504
1505 int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1506 {
1507         uint8_t high_reg, op, Rm, Rd,H1,H2;
1508         char *mnemonic = NULL;
1509
1510         high_reg = (opcode & 0x0400) >> 10;
1511         op = (opcode & 0x03C0) >> 6;
1512
1513         Rd = (opcode & 0x0007);
1514         Rm = (opcode & 0x0038) >> 3;
1515         H1 = (opcode & 0x0080) >> 7;
1516         H2 = (opcode & 0x0040) >> 6;
1517
1518         instruction->info.data_proc.Rd = Rd;
1519         instruction->info.data_proc.Rn = Rd;
1520         instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
1521         instruction->info.data_proc.variant = 1 /*immediate shift*/;
1522         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1523
1524         if (high_reg)
1525         {
1526                 Rd |= H1 << 3;
1527                 Rm |= H2 << 3;
1528                 op >>= 2;
1529
1530                 switch (op)
1531                 {
1532                         case 0x0:
1533                                 instruction->type = ARM_ADD;
1534                                 mnemonic = "ADD";
1535                                 break;
1536                         case 0x1:
1537                                 instruction->type = ARM_CMP;
1538                                 mnemonic = "CMP";
1539                                 break;
1540                         case 0x2:
1541                                 instruction->type = ARM_MOV;
1542                                 mnemonic = "MOV";
1543                                 break;
1544                         case 0x3:
1545                                 if ((opcode & 0x7) == 0x0)
1546                                 {
1547                                         instruction->info.b_bl_bx_blx.reg_operand = Rm;
1548                                         if (H1)
1549                                         {
1550                                                 instruction->type = ARM_BLX;
1551                                                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBLX r%i", address, opcode, Rm);
1552                                         }
1553                                         else
1554                                         {
1555                                                 instruction->type = ARM_BX;
1556                                                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBX r%i", address, opcode, Rm);
1557                                         }
1558                                 }
1559                                 else
1560                                 {
1561                                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1562                                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
1563                                 }
1564                                 return ERROR_OK;
1565                                 break;
1566                 }
1567         }
1568         else
1569         {
1570                 switch (op)
1571                 {
1572                         case 0x0:
1573                                 instruction->type = ARM_AND;
1574                                 mnemonic = "ANDS";
1575                                 break;
1576                         case 0x1:
1577                                 instruction->type = ARM_EOR;
1578                                 mnemonic = "EORS";
1579                                 break;
1580                         case 0x2:
1581                                 instruction->type = ARM_MOV;
1582                                 mnemonic = "LSLS";
1583                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1584                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
1585                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1586                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1587                                 break;
1588                         case 0x3:
1589                                 instruction->type = ARM_MOV;
1590                                 mnemonic = "LSRS";
1591                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1592                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
1593                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1594                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1595                                 break;
1596                         case 0x4:
1597                                 instruction->type = ARM_MOV;
1598                                 mnemonic = "ASRS";
1599                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1600                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
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 0x5:
1605                                 instruction->type = ARM_ADC;
1606                                 mnemonic = "ADCS";
1607                                 break;
1608                         case 0x6:
1609                                 instruction->type = ARM_SBC;
1610                                 mnemonic = "SBCS";
1611                                 break;
1612                         case 0x7:
1613                                 instruction->type = ARM_MOV;
1614                                 mnemonic = "RORS";
1615                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1616                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
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 0x8:
1621                                 instruction->type = ARM_TST;
1622                                 mnemonic = "TST";
1623                                 break;
1624                         case 0x9:
1625                                 instruction->type = ARM_RSB;
1626                                 mnemonic = "NEGS";
1627                                 instruction->info.data_proc.variant = 0 /*immediate*/;
1628                                 instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
1629                                 instruction->info.data_proc.Rn = Rm;
1630                                 break;
1631                         case 0xA:
1632                                 instruction->type = ARM_CMP;
1633                                 mnemonic = "CMP";
1634                                 break;
1635                         case 0xB:
1636                                 instruction->type = ARM_CMN;
1637                                 mnemonic = "CMN";
1638                                 break;
1639                         case 0xC:
1640                                 instruction->type = ARM_ORR;
1641                                 mnemonic = "ORRS";
1642                                 break;
1643                         case 0xD:
1644                                 instruction->type = ARM_MUL;
1645                                 mnemonic = "MULS";
1646                                 break;
1647                         case 0xE:
1648                                 instruction->type = ARM_BIC;
1649                                 mnemonic = "BICS";
1650                                 break;
1651                         case 0xF:
1652                                 instruction->type = ARM_MVN;
1653                                 mnemonic = "MVNS";
1654                                 break;
1655                 }
1656         }
1657
1658         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i",
1659                                  address, opcode, mnemonic, Rd, Rm);
1660
1661         return ERROR_OK;
1662 }
1663
1664 int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1665 {
1666         uint32_t immediate;
1667         uint8_t Rd = (opcode >> 8) & 0x7;
1668
1669         instruction->type = ARM_LDR;
1670         immediate = opcode & 0x000000ff;
1671
1672         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tLDR r%i, [PC, #0x%" PRIx32 "]", address, opcode, Rd, immediate*4);
1673
1674         instruction->info.load_store.Rd = Rd;
1675         instruction->info.load_store.Rn = 15 /*PC*/;
1676         instruction->info.load_store.index_mode = 0; /*offset*/
1677         instruction->info.load_store.offset_mode = 0; /*immediate*/
1678         instruction->info.load_store.offset.offset = immediate*4;
1679
1680         return ERROR_OK;
1681 }
1682
1683 int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1684 {
1685         uint8_t Rd = (opcode >> 0) & 0x7;
1686         uint8_t Rn = (opcode >> 3) & 0x7;
1687         uint8_t Rm = (opcode >> 6) & 0x7;
1688         uint8_t opc = (opcode >> 9) & 0x7;
1689         char *mnemonic = NULL;
1690
1691         switch (opc)
1692         {
1693                 case 0:
1694                         instruction->type = ARM_STR;
1695                         mnemonic = "STR";
1696                         break;
1697                 case 1:
1698                         instruction->type = ARM_STRH;
1699                         mnemonic = "STRH";
1700                         break;
1701                 case 2:
1702                         instruction->type = ARM_STRB;
1703                         mnemonic = "STRB";
1704                         break;
1705                 case 3:
1706                         instruction->type = ARM_LDRSB;
1707                         mnemonic = "LDRSB";
1708                         break;
1709                 case 4:
1710                         instruction->type = ARM_LDR;
1711                         mnemonic = "LDR";
1712                         break;
1713                 case 5:
1714                         instruction->type = ARM_LDRH;
1715                         mnemonic = "LDRH";
1716                         break;
1717                 case 6:
1718                         instruction->type = ARM_LDRB;
1719                         mnemonic = "LDRB";
1720                         break;
1721                 case 7:
1722                         instruction->type = ARM_LDRSH;
1723                         mnemonic = "LDRSH";
1724                         break;
1725         }
1726
1727         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [r%i, r%i]", address, opcode, mnemonic, Rd, Rn, Rm);
1728
1729         instruction->info.load_store.Rd = Rd;
1730         instruction->info.load_store.Rn = Rn;
1731         instruction->info.load_store.index_mode = 0; /*offset*/
1732         instruction->info.load_store.offset_mode = 1; /*register*/
1733         instruction->info.load_store.offset.reg.Rm = Rm;
1734
1735         return ERROR_OK;
1736 }
1737
1738 int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1739 {
1740         uint32_t offset = (opcode >> 6) & 0x1f;
1741         uint8_t Rd = (opcode >> 0) & 0x7;
1742         uint8_t Rn = (opcode >> 3) & 0x7;
1743         uint32_t L = opcode & (1 << 11);
1744         uint32_t B = opcode & (1 << 12);
1745         char *mnemonic;
1746         char suffix = ' ';
1747         uint32_t shift = 2;
1748
1749         if (L)
1750         {
1751                 instruction->type = ARM_LDR;
1752                 mnemonic = "LDR";
1753         }
1754         else
1755         {
1756                 instruction->type = ARM_STR;
1757                 mnemonic = "STR";
1758         }
1759
1760         if ((opcode&0xF000) == 0x8000)
1761         {
1762                 suffix = 'H';
1763                 shift = 1;
1764         }
1765         else if (B)
1766         {
1767                 suffix = 'B';
1768                 shift = 0;
1769         }
1770
1771         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s%c r%i, [r%i, #0x%" PRIx32 "]", address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
1772
1773         instruction->info.load_store.Rd = Rd;
1774         instruction->info.load_store.Rn = Rn;
1775         instruction->info.load_store.index_mode = 0; /*offset*/
1776         instruction->info.load_store.offset_mode = 0; /*immediate*/
1777         instruction->info.load_store.offset.offset = offset << shift;
1778
1779         return ERROR_OK;
1780 }
1781
1782 int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1783 {
1784         uint32_t offset = opcode  & 0xff;
1785         uint8_t Rd = (opcode >> 8) & 0x7;
1786         uint32_t L = opcode & (1 << 11);
1787         char *mnemonic;
1788
1789         if (L)
1790         {
1791                 instruction->type = ARM_LDR;
1792                 mnemonic = "LDR";
1793         }
1794         else
1795         {
1796                 instruction->type = ARM_STR;
1797                 mnemonic = "STR";
1798         }
1799
1800         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [SP, #0x%" PRIx32 "]", address, opcode, mnemonic, Rd, offset*4);
1801
1802         instruction->info.load_store.Rd = Rd;
1803         instruction->info.load_store.Rn = 13 /*SP*/;
1804         instruction->info.load_store.index_mode = 0; /*offset*/
1805         instruction->info.load_store.offset_mode = 0; /*immediate*/
1806         instruction->info.load_store.offset.offset = offset*4;
1807
1808         return ERROR_OK;
1809 }
1810
1811 int evaluate_add_sp_pc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1812 {
1813         uint32_t imm = opcode  & 0xff;
1814         uint8_t Rd = (opcode >> 8) & 0x7;
1815         uint8_t Rn;
1816         uint32_t SP = opcode & (1 << 11);
1817         char *reg_name;
1818
1819         instruction->type = ARM_ADD;
1820
1821         if (SP)
1822         {
1823                 reg_name = "SP";
1824                 Rn = 13;
1825         }
1826         else
1827         {
1828                 reg_name = "PC";
1829                 Rn = 15;
1830         }
1831
1832         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tADD r%i, %s, #0x%" PRIx32 "", address, opcode, Rd,reg_name, imm*4);
1833
1834         instruction->info.data_proc.variant = 0 /* immediate */;
1835         instruction->info.data_proc.Rd = Rd;
1836         instruction->info.data_proc.Rn = Rn;
1837         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
1838
1839         return ERROR_OK;
1840 }
1841
1842 int evaluate_adjust_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1843 {
1844         uint32_t imm = opcode  & 0x7f;
1845         uint8_t opc = opcode & (1 << 7);
1846         char *mnemonic;
1847
1848
1849         if (opc)
1850         {
1851                 instruction->type = ARM_SUB;
1852                 mnemonic = "SUB";
1853         }
1854         else
1855         {
1856                 instruction->type = ARM_ADD;
1857                 mnemonic = "ADD";
1858         }
1859
1860         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s SP, #0x%" PRIx32 "", address, opcode, mnemonic, imm*4);
1861
1862         instruction->info.data_proc.variant = 0 /* immediate */;
1863         instruction->info.data_proc.Rd = 13 /*SP*/;
1864         instruction->info.data_proc.Rn = 13 /*SP*/;
1865         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
1866
1867         return ERROR_OK;
1868 }
1869
1870 int evaluate_breakpoint_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1871 {
1872         uint32_t imm = opcode  & 0xff;
1873
1874         instruction->type = ARM_BKPT;
1875
1876         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBKPT 0x%02" PRIx32 "", address, opcode, imm);
1877
1878         return ERROR_OK;
1879 }
1880
1881 int evaluate_load_store_multiple_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1882 {
1883         uint32_t reg_list = opcode  & 0xff;
1884         uint32_t L = opcode & (1 << 11);
1885         uint32_t R = opcode & (1 << 8);
1886         uint8_t Rn = (opcode >> 8) & 7;
1887         uint8_t addr_mode = 0 /* IA */;
1888         char reg_names[40];
1889         char *reg_names_p;
1890         char *mnemonic;
1891         char ptr_name[7] = "";
1892         int i;
1893
1894         if ((opcode & 0xf000) == 0xc000)
1895         { /* generic load/store multiple */
1896                 if (L)
1897                 {
1898                         instruction->type = ARM_LDM;
1899                         mnemonic = "LDM";
1900                 }
1901                 else
1902                 {
1903                         instruction->type = ARM_STM;
1904                         mnemonic = "STM";
1905                 }
1906                 snprintf(ptr_name,7,"r%i!, ",Rn);
1907         }
1908         else
1909         { /* push/pop */
1910                 Rn = 13; /* SP */
1911                 if (L)
1912                 {
1913                         instruction->type = ARM_LDM;
1914                         mnemonic = "POP";
1915                         if (R)
1916                                 reg_list |= (1 << 15) /*PC*/;
1917                 }
1918                 else
1919                 {
1920                         instruction->type = ARM_STM;
1921                         mnemonic = "PUSH";
1922                         addr_mode = 3; /*DB*/
1923                         if (R)
1924                                 reg_list |= (1 << 14) /*LR*/;
1925                 }
1926         }
1927
1928         reg_names_p = reg_names;
1929         for (i = 0; i <= 15; i++)
1930         {
1931                 if (reg_list & (1 << i))
1932                         reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i);
1933         }
1934         if (reg_names_p > reg_names)
1935                 reg_names_p[-2] = '\0';
1936         else /* invalid op : no registers */
1937                 reg_names[0] = '\0';
1938
1939         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s %s{%s}", address, opcode, mnemonic, ptr_name,reg_names);
1940
1941         instruction->info.load_store_multiple.register_list = reg_list;
1942         instruction->info.load_store_multiple.Rn = Rn;
1943         instruction->info.load_store_multiple.addressing_mode = addr_mode;
1944
1945         return ERROR_OK;
1946 }
1947
1948 int evaluate_cond_branch_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1949 {
1950         uint32_t offset = opcode  & 0xff;
1951         uint8_t cond = (opcode >> 8) & 0xf;
1952         uint32_t target_address;
1953
1954         if (cond == 0xf)
1955         {
1956                 instruction->type = ARM_SWI;
1957                 snprintf(instruction->text, 128,
1958                                 "0x%8.8" PRIx32 "\t0x%4.4x\tSVC 0x%02" PRIx32,
1959                                 address, opcode, offset);
1960                 return ERROR_OK;
1961         }
1962         else if (cond == 0xe)
1963         {
1964                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1965                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
1966                 return ERROR_OK;
1967         }
1968
1969         /* sign extend 8-bit offset */
1970         if (offset & 0x00000080)
1971                 offset = 0xffffff00 | offset;
1972
1973         target_address = address + 4 + (offset << 1);
1974
1975         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tB%s 0x%8.8" PRIx32 , address, opcode,
1976                          arm_condition_strings[cond], target_address);
1977
1978         instruction->type = ARM_B;
1979         instruction->info.b_bl_bx_blx.reg_operand = -1;
1980         instruction->info.b_bl_bx_blx.target_address = target_address;
1981
1982         return ERROR_OK;
1983 }
1984
1985 static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
1986                 arm_instruction_t *instruction)
1987 {
1988         unsigned offset;
1989
1990         /* added in Thumb2 */
1991         offset = (opcode >> 3) & 0x1f;
1992         offset |= (opcode & 0x0200) >> 4;
1993
1994         snprintf(instruction->text, 128,
1995                         "0x%8.8" PRIx32 "\t0x%4.4x\tCB%sZ r%d, %#8.8" PRIx32,
1996                         address, opcode,
1997                         (opcode & 0x0800) ? "N" : "",
1998                         opcode & 0x7, address + 4 + (offset << 1));
1999
2000         return ERROR_OK;
2001 }
2002
2003 static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
2004                 arm_instruction_t *instruction)
2005 {
2006         /* added in ARMv6 */
2007         snprintf(instruction->text, 128,
2008                         "0x%8.8" PRIx32 "\t0x%4.4x\t%cXT%c r%d, r%d",
2009                         address, opcode,
2010                         (opcode & 0x0080) ? 'U' : 'S',
2011                         (opcode & 0x0040) ? 'B' : 'H',
2012                         opcode & 0x7, (opcode >> 3) & 0x7);
2013
2014         return ERROR_OK;
2015 }
2016
2017 static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
2018                 arm_instruction_t *instruction)
2019 {
2020         /* added in ARMv6 */
2021         if ((opcode & 0x0ff0) == 0x0650)
2022                 snprintf(instruction->text, 128,
2023                                 "0x%8.8" PRIx32 "\t0x%4.4x\tSETEND %s",
2024                                 address, opcode,
2025                                 (opcode & 0x80) ? "BE" : "LE");
2026         else /* ASSUME (opcode & 0x0fe0) == 0x0660 */
2027                 snprintf(instruction->text, 128,
2028                                 "0x%8.8" PRIx32 "\t0x%4.4x\tCPSI%c %s%s%s",
2029                                 address, opcode,
2030                                 (opcode & 0x0010) ? 'D' : 'E',
2031                                 (opcode & 0x0004) ? "A" : "",
2032                                 (opcode & 0x0002) ? "I" : "",
2033                                 (opcode & 0x0001) ? "F" : "");
2034
2035         return ERROR_OK;
2036 }
2037
2038 static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
2039                 arm_instruction_t *instruction)
2040 {
2041         char *suffix;
2042
2043         /* added in ARMv6 */
2044         switch (opcode & 0x00c0) {
2045         case 0:
2046                 suffix = "";
2047                 break;
2048         case 1:
2049                 suffix = "16";
2050                 break;
2051         default:
2052                 suffix = "SH";
2053                 break;
2054         }
2055         snprintf(instruction->text, 128,
2056                         "0x%8.8" PRIx32 "\t0x%4.4x\tREV%s r%d, r%d",
2057                         address, opcode, suffix,
2058                         opcode & 0x7, (opcode >> 3) & 0x7);
2059
2060         return ERROR_OK;
2061 }
2062
2063 static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
2064                 arm_instruction_t *instruction)
2065 {
2066         char *hint;
2067
2068         switch ((opcode >> 4) & 0x0f) {
2069         case 0:
2070                 hint = "NOP";
2071                 break;
2072         case 1:
2073                 hint = "YIELD";
2074                 break;
2075         case 2:
2076                 hint = "WFE";
2077                 break;
2078         case 3:
2079                 hint = "WFI";
2080                 break;
2081         case 4:
2082                 hint = "SEV";
2083                 break;
2084         default:
2085                 hint = "HINT (UNRECOGNIZED)";
2086                 break;
2087         }
2088
2089         snprintf(instruction->text, 128,
2090                         "0x%8.8" PRIx32 "\t0x%4.4x\t%s",
2091                         address, opcode, hint);
2092
2093         return ERROR_OK;
2094 }
2095
2096 static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
2097                 arm_instruction_t *instruction)
2098 {
2099         unsigned cond = (opcode >> 4) & 0x0f;
2100         char *x = "", *y = "", *z = "";
2101
2102         if (opcode & 0x01)
2103                 z = (opcode & 0x02) ? "T" : "E";
2104         if (opcode & 0x03)
2105                 y = (opcode & 0x04) ? "T" : "E";
2106         if (opcode & 0x07)
2107                 x = (opcode & 0x08) ? "T" : "E";
2108
2109         snprintf(instruction->text, 128,
2110                         "0x%8.8" PRIx32 "\t0x%4.4x\tIT%s%s%s %s",
2111                         address, opcode,
2112                         x, y, z, arm_condition_strings[cond]);
2113
2114         /* NOTE:  strictly speaking, the next 1-4 instructions should
2115          * now be displayed with the relevant conditional suffix...
2116          */
2117
2118         return ERROR_OK;
2119 }
2120
2121 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
2122 {
2123         /* clear fields, to avoid confusion */
2124         memset(instruction, 0, sizeof(arm_instruction_t));
2125         instruction->opcode = opcode;
2126         instruction->instruction_size = 2;
2127
2128         if ((opcode & 0xe000) == 0x0000)
2129         {
2130                 /* add/substract register or immediate */
2131                 if ((opcode & 0x1800) == 0x1800)
2132                         return evaluate_add_sub_thumb(opcode, address, instruction);
2133                 /* shift by immediate */
2134                 else
2135                         return evaluate_shift_imm_thumb(opcode, address, instruction);
2136         }
2137
2138         /* Add/substract/compare/move immediate */
2139         if ((opcode & 0xe000) == 0x2000)
2140         {
2141                 return evaluate_data_proc_imm_thumb(opcode, address, instruction);
2142         }
2143
2144         /* Data processing instructions */
2145         if ((opcode & 0xf800) == 0x4000)
2146         {
2147                 return evaluate_data_proc_thumb(opcode, address, instruction);
2148         }
2149
2150         /* Load from literal pool */
2151         if ((opcode & 0xf800) == 0x4800)
2152         {
2153                 return evaluate_load_literal_thumb(opcode, address, instruction);
2154         }
2155
2156         /* Load/Store register offset */
2157         if ((opcode & 0xf000) == 0x5000)
2158         {
2159                 return evaluate_load_store_reg_thumb(opcode, address, instruction);
2160         }
2161
2162         /* Load/Store immediate offset */
2163         if (((opcode & 0xe000) == 0x6000)
2164                 ||((opcode & 0xf000) == 0x8000))
2165         {
2166                 return evaluate_load_store_imm_thumb(opcode, address, instruction);
2167         }
2168
2169         /* Load/Store from/to stack */
2170         if ((opcode & 0xf000) == 0x9000)
2171         {
2172                 return evaluate_load_store_stack_thumb(opcode, address, instruction);
2173         }
2174
2175         /* Add to SP/PC */
2176         if ((opcode & 0xf000) == 0xa000)
2177         {
2178                 return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2179         }
2180
2181         /* Misc */
2182         if ((opcode & 0xf000) == 0xb000)
2183         {
2184                 switch ((opcode >> 8) & 0x0f) {
2185                 case 0x0:
2186                         return evaluate_adjust_stack_thumb(opcode, address, instruction);
2187                 case 0x1:
2188                 case 0x3:
2189                 case 0x9:
2190                 case 0xb:
2191                         return evaluate_cb_thumb(opcode, address, instruction);
2192                 case 0x2:
2193                         return evaluate_extend_thumb(opcode, address, instruction);
2194                 case 0x4:
2195                 case 0x5:
2196                 case 0xc:
2197                 case 0xd:
2198                         return evaluate_load_store_multiple_thumb(opcode, address,
2199                                                 instruction);
2200                 case 0x6:
2201                         return evaluate_cps_thumb(opcode, address, instruction);
2202                 case 0xa:
2203                         if ((opcode & 0x00c0) == 0x0080)
2204                                 break;
2205                         return evaluate_byterev_thumb(opcode, address, instruction);
2206                 case 0xe:
2207                         return evaluate_breakpoint_thumb(opcode, address, instruction);
2208                 case 0xf:
2209                         if (opcode & 0x000f)
2210                                 return evaluate_ifthen_thumb(opcode, address,
2211                                                 instruction);
2212                         else
2213                                 return evaluate_hint_thumb(opcode, address,
2214                                                 instruction);
2215                 }
2216
2217                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2218                 snprintf(instruction->text, 128,
2219                         "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION",
2220                         address, opcode);
2221                 return ERROR_OK;
2222         }
2223
2224         /* Load/Store multiple */
2225         if ((opcode & 0xf000) == 0xc000)
2226         {
2227                 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2228         }
2229
2230         /* Conditional branch + SWI */
2231         if ((opcode & 0xf000) == 0xd000)
2232         {
2233                 return evaluate_cond_branch_thumb(opcode, address, instruction);
2234         }
2235
2236         if ((opcode & 0xe000) == 0xe000)
2237         {
2238                 /* Undefined instructions */
2239                 if ((opcode & 0xf801) == 0xe801)
2240                 {
2241                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
2242                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
2243                         return ERROR_OK;
2244                 }
2245                 else
2246                 { /* Branch to offset */
2247                         return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2248                 }
2249         }
2250
2251         LOG_ERROR("should never reach this point (opcode=%04x)",opcode);
2252         return -1;
2253 }
2254
2255 /*
2256  * REVISIT for Thumb2 instructions, instruction->type and friends aren't
2257  * always set.  That means eventual arm_simulate_step() support for Thumb2
2258  * will need work in this area.
2259  */
2260 int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruction)
2261 {
2262         int retval;
2263         uint16_t op;
2264         uint32_t opcode;
2265
2266         /* clear low bit ... it's set on function pointers */
2267         address &= ~1;
2268
2269         /* clear fields, to avoid confusion */
2270         memset(instruction, 0, sizeof(arm_instruction_t));
2271
2272         /* read first halfword, see if this is the only one */
2273         retval = target_read_u16(target, address, &op);
2274         if (retval != ERROR_OK)
2275                 return retval;
2276
2277         switch (op & 0xf800) {
2278         case 0xf800:
2279         case 0xf000:
2280         case 0xe800:
2281                 /* 32-bit instructions */
2282                 instruction->instruction_size = 4;
2283                 opcode = op << 16;
2284                 retval = target_read_u16(target, address + 2, &op);
2285                 if (retval != ERROR_OK)
2286                         return retval;
2287                 opcode |= op;
2288                 instruction->opcode = opcode;
2289                 break;
2290         default:
2291                 /* 16-bit:  Thumb1 + IT + CBZ/CBNZ + ... */
2292                 return thumb_evaluate_opcode(op, address, instruction);
2293         }
2294
2295         /* FIXME decode the 32-bit instructions */
2296
2297         LOG_DEBUG("Can't decode 32-bit Thumb2 yet (opcode=%08x)", opcode);
2298
2299         snprintf(instruction->text, 128,
2300                         "0x%8.8" PRIx32 "\t0x%8.8x\t... 32-bit Thumb2 ...",
2301                         address, opcode);
2302         return ERROR_OK;
2303 }
2304
2305 int arm_access_size(arm_instruction_t *instruction)
2306 {
2307         if ((instruction->type == ARM_LDRB)
2308                 || (instruction->type == ARM_LDRBT)
2309                 || (instruction->type == ARM_LDRSB)
2310                 || (instruction->type == ARM_STRB)
2311                 || (instruction->type == ARM_STRBT))
2312         {
2313                 return 1;
2314         }
2315         else if ((instruction->type == ARM_LDRH)
2316                 || (instruction->type == ARM_LDRSH)
2317                 || (instruction->type == ARM_STRH))
2318         {
2319                 return 2;
2320         }
2321         else if ((instruction->type == ARM_LDR)
2322                 || (instruction->type == ARM_LDRT)
2323                 || (instruction->type == ARM_STR)
2324                 || (instruction->type == ARM_STRT))
2325         {
2326                 return 4;
2327         }
2328         else if ((instruction->type == ARM_LDRD)
2329                 || (instruction->type == ARM_STRD))
2330         {
2331                 return 8;
2332         }
2333         else
2334         {
2335                 LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type);
2336                 return 0;
2337         }
2338 }