- Fixes '[<>]' whitespace
[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 "arm_disassembler.h"
25 #include "log.h"
26
27
28 /* textual represenation of the condition field */
29 /* ALways (default) is ommitted (empty string) */
30 char *arm_condition_strings[] =
31 {
32         "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
33 };
34
35 /* make up for C's missing ROR */
36 uint32_t ror(uint32_t value, int places) 
37
38         return (value >> places) | (value << (32 - places)); 
39 }
40
41 int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
42 {
43         /* PLD */
44         if ((opcode & 0x0d70f0000) == 0x0550f000)
45         {
46                 instruction->type = ARM_PLD;
47                 
48                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", address, opcode);
49                 
50                 return ERROR_OK;
51         }
52         else
53         {
54                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
55                 return ERROR_OK;
56         }
57         
58         LOG_ERROR("should never reach this point");
59         return -1;
60 }
61
62 int evaluate_swi(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
63 {
64         instruction->type = ARM_SWI;
65         
66         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWI 0x%6.6" PRIx32 "", address, opcode, (opcode & 0xffffff));
67         
68         return ERROR_OK;
69 }
70
71 int evaluate_blx_imm(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
72 {
73         int offset;
74         uint32_t immediate;
75         uint32_t target_address;
76         
77         instruction->type = ARM_BLX;
78         immediate = opcode & 0x00ffffff;
79         
80         /* sign extend 24-bit immediate */
81         if (immediate & 0x00800000)
82                 offset = 0xff000000 | immediate;
83         else
84                 offset = immediate;
85         
86         /* shift two bits left */
87         offset <<= 2;
88         
89         /* odd/event halfword */
90         if (opcode & 0x01000000)
91                 offset |= 0x2;
92         
93         target_address = address + 8 + offset;
94         
95         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "", address, opcode, target_address);
96         
97         instruction->info.b_bl_bx_blx.reg_operand = -1;
98         instruction->info.b_bl_bx_blx.target_address = target_address;
99         
100         return ERROR_OK;
101 }
102
103 int evaluate_b_bl(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
104 {
105         uint8_t L;
106         uint32_t immediate;
107         int offset;
108         uint32_t target_address;
109         
110         immediate = opcode & 0x00ffffff;
111         L = (opcode & 0x01000000) >> 24;
112         
113         /* sign extend 24-bit immediate */
114         if (immediate & 0x00800000)
115                 offset = 0xff000000 | immediate;
116         else
117                 offset = immediate;
118         
119         /* shift two bits left */
120         offset <<= 2;
121         
122         target_address = address + 8 + offset;
123
124         if (L)
125                 instruction->type = ARM_BL;
126         else
127                 instruction->type = ARM_B;
128         
129         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32 , address, opcode,
130                          (L) ? "L" : "", COND(opcode), target_address);
131         
132         instruction->info.b_bl_bx_blx.reg_operand = -1;
133         instruction->info.b_bl_bx_blx.target_address = target_address;
134         
135         return ERROR_OK;
136 }
137
138 /* Coprocessor load/store and double register transfers */
139 /* both normal and extended instruction space (condition field b1111) */
140 int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
141 {
142         uint8_t cp_num = (opcode & 0xf00) >> 8;
143         
144         /* MCRR or MRRC */
145         if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000))
146         {
147                 uint8_t cp_opcode, Rd, Rn, CRm;
148                 char *mnemonic;
149                 
150                 cp_opcode = (opcode & 0xf0) >> 4;
151                 Rd = (opcode & 0xf000) >> 12;
152                 Rn = (opcode & 0xf0000) >> 16;
153                 CRm = (opcode & 0xf);
154                 
155                 /* MCRR */
156                 if ((opcode & 0x0ff00000) == 0x0c400000)
157                 {
158                         instruction->type = ARM_MCRR;
159                         mnemonic = "MCRR";
160                 }
161                 
162                 /* MRRC */
163                 if ((opcode & 0x0ff00000) == 0x0c500000)
164                 {
165                         instruction->type = ARM_MRRC;
166                         mnemonic = "MRRC";
167                 }
168                 
169                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, %x, r%i, r%i, c%i",
170                                  address, opcode, mnemonic, COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
171         }
172         else /* LDC or STC */
173         {
174                 uint8_t CRd, Rn, offset;
175                 uint8_t U, N;
176                 char *mnemonic;
177                 char addressing_mode[32];
178                 
179                 CRd = (opcode & 0xf000) >> 12;
180                 Rn = (opcode & 0xf0000) >> 16;
181                 offset = (opcode & 0xff);
182                 
183                 /* load/store */
184                 if (opcode & 0x00100000)
185                 {
186                         instruction->type = ARM_LDC;
187                         mnemonic = "LDC";
188                 }
189                 else
190                 {
191                         instruction->type = ARM_STC;
192                         mnemonic = "STC";
193                 }
194                 
195                 U = (opcode & 0x00800000) >> 23;
196                 N = (opcode & 0x00400000) >> 22;
197                 
198                 /* addressing modes */
199                 if ((opcode & 0x01200000) == 0x01000000) /* immediate offset */
200                         snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]", Rn, (U) ? "" : "-", offset);
201                 else if ((opcode & 0x01200000) == 0x01200000) /* immediate pre-indexed */
202                         snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]!", Rn, (U) ? "" : "-", offset);
203                 else if ((opcode & 0x01200000) == 0x00200000) /* immediate post-indexed */
204                         snprintf(addressing_mode, 32, "[r%i], #%s0x%2.2x*4", Rn, (U) ? "" : "-", offset);
205                 else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
206                         snprintf(addressing_mode, 32, "[r%i], #0x%2.2x", Rn, offset);
207
208                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s p%i, c%i, %s",
209                                  address, opcode, mnemonic, ((opcode & 0xf0000000) == 0xf0000000) ? COND(opcode) : "2",
210                                  (N) ? "L" : "",
211                                  cp_num, CRd, addressing_mode);
212         }
213         
214         return ERROR_OK;
215 }
216
217 /* Coprocessor data processing instructions */
218 /* Coprocessor register transfer instructions */
219 /* both normal and extended instruction space (condition field b1111) */
220 int evaluate_cdp_mcr_mrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
221 {
222         char* cond;
223         char* mnemonic;
224         uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
225         
226         cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
227         cp_num = (opcode & 0xf00) >> 8;
228         CRd_Rd = (opcode & 0xf000) >> 12;
229         CRn = (opcode & 0xf0000) >> 16;
230         CRm = (opcode & 0xf);
231         opcode_2 = (opcode & 0xe0) >> 5;
232         
233         /* CDP or MRC/MCR */
234         if (opcode & 0x00000010) /* bit 4 set -> MRC/MCR */
235         {
236                 if (opcode & 0x00100000) /* bit 20 set -> MRC */
237                 {
238                         instruction->type = ARM_MRC;
239                         mnemonic = "MRC";
240                 }
241                 else /* bit 20 not set -> MCR */
242                 {
243                         instruction->type = ARM_MCR;
244                         mnemonic = "MCR";
245                 }
246                 
247                 opcode_1 = (opcode & 0x00e00000) >> 21;
248                 
249                 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",
250                                  address, opcode, mnemonic, cond,
251                                  cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
252         }
253         else /* bit 4 not set -> CDP */
254         {
255                 instruction->type = ARM_CDP;
256                 mnemonic = "CDP";
257                 
258                 opcode_1 = (opcode & 0x00f00000) >> 20;
259                 
260                 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",
261                                  address, opcode, mnemonic, cond,
262                                  cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
263         }
264         
265         return ERROR_OK;
266 }
267
268 /* Load/store instructions */
269 int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
270 {
271         uint8_t I, P, U, B, W, L;
272         uint8_t Rn, Rd;
273         char *operation; /* "LDR" or "STR" */
274         char *suffix; /* "", "B", "T", "BT" */
275         char offset[32];
276         
277         /* examine flags */
278         I = (opcode & 0x02000000) >> 25;
279         P = (opcode & 0x01000000) >> 24;
280         U = (opcode & 0x00800000) >> 23;
281         B = (opcode & 0x00400000) >> 22;
282         W = (opcode & 0x00200000) >> 21;
283         L = (opcode & 0x00100000) >> 20;
284         
285         /* target register */
286         Rd = (opcode & 0xf000) >> 12;
287         
288         /* base register */
289         Rn = (opcode & 0xf0000) >> 16;
290         
291         instruction->info.load_store.Rd = Rd;
292         instruction->info.load_store.Rn = Rn;
293         instruction->info.load_store.U = U;
294
295         /* determine operation */
296         if (L)
297                 operation = "LDR";
298         else
299                 operation = "STR";
300         
301         /* determine instruction type and suffix */
302         if (B)
303         {
304                 if ((P == 0) && (W == 1))
305                 {
306                         if (L)
307                                 instruction->type = ARM_LDRBT;
308                         else
309                                 instruction->type = ARM_STRBT;
310                         suffix = "BT";
311                 }
312                 else
313                 {
314                         if (L)
315                                 instruction->type = ARM_LDRB;
316                         else
317                                 instruction->type = ARM_STRB;
318                         suffix = "B";
319                 }
320         }
321         else
322         {
323                 if ((P == 0) && (W == 1))
324                 {
325                         if (L)
326                                 instruction->type = ARM_LDRT;
327                         else
328                                 instruction->type = ARM_STRT;
329                         suffix = "T";
330                 }
331                 else
332                 {
333                         if (L)
334                                 instruction->type = ARM_LDR;
335                         else
336                                 instruction->type = ARM_STR;
337                         suffix = "";
338                 }
339         }
340         
341         if (!I) /* #+-<offset_12> */
342         {
343                 uint32_t offset_12 = (opcode & 0xfff);
344                 if (offset_12)
345                         snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
346                 else
347                         snprintf(offset, 32, "%s", "");
348                 
349                 instruction->info.load_store.offset_mode = 0;
350                 instruction->info.load_store.offset.offset = offset_12;
351         }
352         else /* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
353         {
354                 uint8_t shift_imm, shift;
355                 uint8_t Rm;
356                 
357                 shift_imm = (opcode & 0xf80) >> 7;
358                 shift = (opcode & 0x60) >> 5;
359                 Rm = (opcode & 0xf);
360                 
361                 /* LSR encodes a shift by 32 bit as 0x0 */
362                 if ((shift == 0x1) && (shift_imm == 0x0))
363                         shift_imm = 0x20;
364                 
365                 /* ASR encodes a shift by 32 bit as 0x0 */
366                 if ((shift == 0x2) && (shift_imm == 0x0))
367                         shift_imm = 0x20;
368
369                 /* ROR by 32 bit is actually a RRX */
370                 if ((shift == 0x3) && (shift_imm == 0x0))
371                         shift = 0x4;
372                 
373                 instruction->info.load_store.offset_mode = 1;
374                 instruction->info.load_store.offset.reg.Rm = Rm;
375                 instruction->info.load_store.offset.reg.shift = shift;
376                 instruction->info.load_store.offset.reg.shift_imm = shift_imm;
377
378                 if ((shift_imm == 0x0) && (shift == 0x0)) /* +-<Rm> */
379                 {
380                         snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm);
381                 }
382                 else /* +-<Rm>, <Shift>, #<shift_imm> */
383                 {
384                         switch (shift)
385                         {
386                                 case 0x0: /* LSL */
387                                         snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
388                                         break;
389                                 case 0x1: /* LSR */
390                                         snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
391                                         break;
392                                 case 0x2: /* ASR */
393                                         snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
394                                         break;
395                                 case 0x3: /* ROR */
396                                         snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
397                                         break;
398                                 case 0x4: /* RRX */
399                                         snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm);
400                                         break;
401                         }
402                 }
403         }
404         
405         if (P == 1)
406         {
407                 if (W == 0) /* offset */
408                 {
409                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
410                                          address, opcode, operation, COND(opcode), suffix,
411                                          Rd, Rn, offset);
412                         
413                         instruction->info.load_store.index_mode = 0;
414                 }
415                 else /* pre-indexed */
416                 {
417                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
418                                          address, opcode, operation, COND(opcode), suffix,
419                                          Rd, Rn, offset);
420                         
421                         instruction->info.load_store.index_mode = 1;
422                 }
423         }
424         else /* post-indexed */
425         {
426                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
427                                  address, opcode, operation, COND(opcode), suffix,
428                                  Rd, Rn, offset);
429                 
430                 instruction->info.load_store.index_mode = 2;
431         }
432         
433         return ERROR_OK;
434 }
435
436 /* Miscellaneous load/store instructions */
437 int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
438 {
439         uint8_t P, U, I, W, L, S, H;
440         uint8_t Rn, Rd;
441         char *operation; /* "LDR" or "STR" */
442         char *suffix; /* "H", "SB", "SH", "D" */
443         char offset[32];
444         
445         /* examine flags */
446         P = (opcode & 0x01000000) >> 24;
447         U = (opcode & 0x00800000) >> 23;
448         I = (opcode & 0x00400000) >> 22;
449         W = (opcode & 0x00200000) >> 21;
450         L = (opcode & 0x00100000) >> 20;
451         S = (opcode & 0x00000040) >> 6;
452         H = (opcode & 0x00000020) >> 5;
453         
454         /* target register */
455         Rd = (opcode & 0xf000) >> 12;
456         
457         /* base register */
458         Rn = (opcode & 0xf0000) >> 16;
459         
460         instruction->info.load_store.Rd = Rd;
461         instruction->info.load_store.Rn = Rn;
462         instruction->info.load_store.U = U;
463         
464         /* determine instruction type and suffix */
465         if (S) /* signed */
466         {
467                 if (L) /* load */
468                 {
469                         if (H)
470                         {
471                                 operation = "LDR";
472                                 instruction->type = ARM_LDRSH;
473                                 suffix = "SH";
474                         }
475                         else
476                         {
477                                 operation = "LDR";
478                                 instruction->type = ARM_LDRSB;
479                                 suffix = "SB";
480                         }
481                 }
482                 else /* there are no signed stores, so this is used to encode double-register load/stores */
483                 {
484                         suffix = "D";
485                         if (H)
486                         {
487                                 operation = "STR";
488                                 instruction->type = ARM_STRD;
489                         }
490                         else
491                         {
492                                 operation = "LDR";
493                                 instruction->type = ARM_LDRD;
494                         }
495                 }
496         }
497         else /* unsigned */
498         {
499                 suffix = "H";
500                 if (L) /* load */
501                 {
502                         operation = "LDR";
503                         instruction->type = ARM_LDRH;
504                 }
505                 else /* store */
506                 {
507                         operation = "STR";
508                         instruction->type = ARM_STRH;
509                 }
510         }
511         
512         if (I) /* Immediate offset/index (#+-<offset_8>)*/
513         {
514                 uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
515                 snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
516                 
517                 instruction->info.load_store.offset_mode = 0;
518                 instruction->info.load_store.offset.offset = offset_8;
519         }
520         else /* Register offset/index (+-<Rm>) */
521         {
522                 uint8_t Rm;
523                 Rm = (opcode & 0xf);
524                 snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
525                 
526                 instruction->info.load_store.offset_mode = 1;
527                 instruction->info.load_store.offset.reg.Rm = Rm;
528                 instruction->info.load_store.offset.reg.shift = 0x0;
529                 instruction->info.load_store.offset.reg.shift_imm = 0x0;
530         }
531         
532         if (P == 1)
533         {
534                 if (W == 0) /* offset */
535                 {
536                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
537                                          address, opcode, operation, COND(opcode), suffix,
538                                          Rd, Rn, offset);
539                         
540                         instruction->info.load_store.index_mode = 0;
541                 }
542                 else /* pre-indexed */
543                 {
544                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
545                                          address, opcode, operation, COND(opcode), suffix,
546                                          Rd, Rn, offset);
547                 
548                         instruction->info.load_store.index_mode = 1;
549                 }
550         }
551         else /* post-indexed */
552         {
553                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
554                                  address, opcode, operation, COND(opcode), suffix,
555                                  Rd, Rn, offset);
556         
557                 instruction->info.load_store.index_mode = 2;
558         }
559         
560         return ERROR_OK;
561 }
562
563 /* Load/store multiples instructions */
564 int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
565 {
566         uint8_t P, U, S, W, L, Rn;
567         uint32_t register_list;
568         char *addressing_mode;
569         char *mnemonic;
570         char reg_list[69];
571         char *reg_list_p;
572         int i;
573         int first_reg = 1;
574         
575         P = (opcode & 0x01000000) >> 24;
576         U = (opcode & 0x00800000) >> 23;
577         S = (opcode & 0x00400000) >> 22;
578         W = (opcode & 0x00200000) >> 21;
579         L = (opcode & 0x00100000) >> 20;
580         register_list = (opcode & 0xffff);
581         Rn = (opcode & 0xf0000) >> 16;
582         
583         instruction->info.load_store_multiple.Rn = Rn;
584         instruction->info.load_store_multiple.register_list = register_list;
585         instruction->info.load_store_multiple.S = S;
586         instruction->info.load_store_multiple.W = W;
587         
588         if (L)
589         {
590                 instruction->type = ARM_LDM;
591                 mnemonic = "LDM";
592         }
593         else
594         {
595                 instruction->type = ARM_STM;
596                 mnemonic = "STM";
597         }
598         
599         if (P)
600         {
601                 if (U)
602                 {
603                         instruction->info.load_store_multiple.addressing_mode = 1;
604                         addressing_mode = "IB";
605                 }
606                 else
607                 {
608                         instruction->info.load_store_multiple.addressing_mode = 3;
609                         addressing_mode = "DB";
610                 }
611         }
612         else
613         {
614                 if (U)
615                 {
616                         instruction->info.load_store_multiple.addressing_mode = 0;
617                         addressing_mode = "IA";
618                 }
619                 else
620                 {
621                         instruction->info.load_store_multiple.addressing_mode = 2;
622                         addressing_mode = "DA";
623                 }
624         }
625         
626         reg_list_p = reg_list;
627         for (i = 0; i <= 15; i++)
628         {
629                 if ((register_list >> i) & 1)
630                 {
631                         if (first_reg)
632                         {
633                                 first_reg = 0;
634                                 reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), "r%i", i);
635                         }
636                         else
637                         {
638                                 reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), ", r%i", i);
639                         }
640                 }
641         }
642         
643         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i%s, {%s}%s",
644                          address, opcode, mnemonic, COND(opcode), addressing_mode,
645                          Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
646         
647         return ERROR_OK;
648 }
649
650 /* Multiplies, extra load/stores */
651 int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
652 {
653         /* Multiply (accumulate) (long) and Swap/swap byte */
654         if ((opcode & 0x000000f0) == 0x00000090)
655         {
656                 /* Multiply (accumulate) */
657                 if ((opcode & 0x0f800000) == 0x00000000)
658                 {
659                         uint8_t Rm, Rs, Rn, Rd, S;
660                         Rm = opcode & 0xf;
661                         Rs = (opcode & 0xf00) >> 8;
662                         Rn = (opcode & 0xf000) >> 12;
663                         Rd = (opcode & 0xf0000) >> 16;
664                         S = (opcode & 0x00100000) >> 20;
665                         
666                         /* examine A bit (accumulate) */
667                         if (opcode & 0x00200000)
668                         {
669                                 instruction->type = ARM_MLA;
670                                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
671                                                 address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs, Rn);
672                         }
673                         else
674                         {
675                                 instruction->type = ARM_MUL;
676                                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
677                                                  address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs);
678                         }
679                         
680                         return ERROR_OK;
681                 }
682                 
683                 /* Multiply (accumulate) long */
684                 if ((opcode & 0x0f800000) == 0x00800000)
685                 {
686                         char* mnemonic = NULL;
687                         uint8_t Rm, Rs, RdHi, RdLow, S;
688                         Rm = opcode & 0xf;
689                         Rs = (opcode & 0xf00) >> 8;
690                         RdHi = (opcode & 0xf000) >> 12;
691                         RdLow = (opcode & 0xf0000) >> 16;
692                         S = (opcode & 0x00100000) >> 20;
693                         
694                         switch ((opcode & 0x00600000) >> 21)
695                         {
696                                 case 0x0:
697                                         instruction->type = ARM_UMULL;
698                                         mnemonic = "UMULL";
699                                         break;
700                                 case 0x1:
701                                         instruction->type = ARM_UMLAL;
702                                         mnemonic = "UMLAL";
703                                         break;
704                                 case 0x2:
705                                         instruction->type = ARM_SMULL;
706                                         mnemonic = "SMULL";
707                                         break;
708                                 case 0x3:
709                                         instruction->type = ARM_SMLAL;
710                                         mnemonic = "SMLAL";
711                                         break;
712                         }
713                         
714                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
715                                                 address, opcode, mnemonic, COND(opcode), (S) ? "S" : "",
716                                                 RdLow, RdHi, Rm, Rs);
717                         
718                         return ERROR_OK;
719                 }
720                 
721                 /* Swap/swap byte */
722                 if ((opcode & 0x0f800000) == 0x01000000)
723                 {
724                         uint8_t Rm, Rd, Rn;
725                         Rm = opcode & 0xf;
726                         Rd = (opcode & 0xf000) >> 12;
727                         Rn = (opcode & 0xf0000) >> 16;
728                         
729                         /* examine B flag */
730                         instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
731                         
732                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
733                                          address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn);
734                         return ERROR_OK;
735                 }
736                 
737         }
738         
739         return evaluate_misc_load_store(opcode, address, instruction);
740 }
741
742 int evaluate_mrs_msr(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
743 {
744         int R = (opcode & 0x00400000) >> 22;
745         char *PSR = (R) ? "SPSR" : "CPSR";
746                 
747         /* Move register to status register (MSR) */
748         if (opcode & 0x00200000)
749         {
750                 instruction->type = ARM_MSR;
751                         
752                 /* immediate variant */
753                 if (opcode & 0x02000000)
754                 {
755                         uint8_t immediate = (opcode & 0xff);
756                         uint8_t rotate = (opcode & 0xf00);
757                         
758                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32 ,
759                                          address, opcode, COND(opcode), PSR,
760                                          (opcode & 0x10000) ? "c" : "",
761                                          (opcode & 0x20000) ? "x" : "",
762                                          (opcode & 0x40000) ? "s" : "",
763                                          (opcode & 0x80000) ? "f" : "",
764                                          ror(immediate, (rotate * 2))
765                                         );
766                 }
767                 else /* register variant */
768                 {
769                         uint8_t Rm = opcode & 0xf;
770                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
771                                          address, opcode, COND(opcode), PSR,
772                                          (opcode & 0x10000) ? "c" : "",
773                                          (opcode & 0x20000) ? "x" : "",
774                                          (opcode & 0x40000) ? "s" : "",
775                                          (opcode & 0x80000) ? "f" : "",
776                                          Rm
777                                         );
778                 }
779                 
780         }
781         else /* Move status register to register (MRS) */
782         {
783                 uint8_t Rd;
784                 
785                 instruction->type = ARM_MRS;
786                 Rd = (opcode & 0x0000f000) >> 12;
787                         
788                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
789                                  address, opcode, COND(opcode), Rd, PSR);
790         }
791         
792         return ERROR_OK;
793 }
794
795 /* Miscellaneous instructions */
796 int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
797 {
798         /* MRS/MSR */
799         if ((opcode & 0x000000f0) == 0x00000000)
800         {
801                 evaluate_mrs_msr(opcode, address, instruction);
802         }
803         
804         /* BX */
805         if ((opcode & 0x006000f0) == 0x00200010)
806         {
807                 uint8_t Rm;
808                 instruction->type = ARM_BX;
809                 Rm = opcode & 0xf;
810                 
811                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
812                                  address, opcode, COND(opcode), Rm);
813                 
814                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
815                 instruction->info.b_bl_bx_blx.target_address = -1;
816         }
817         
818         /* CLZ */
819         if ((opcode & 0x006000f0) == 0x00600010)
820         {
821                 uint8_t Rm, Rd;
822                 instruction->type = ARM_CLZ;
823                 Rm = opcode & 0xf;
824                 Rd = (opcode & 0xf000) >> 12;
825
826                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
827                                  address, opcode, COND(opcode), Rd, Rm);
828         }
829         
830         /* BLX(2) */
831         if ((opcode & 0x006000f0) == 0x00200030)
832         {
833                 uint8_t Rm;
834                 instruction->type = ARM_BLX;
835                 Rm = opcode & 0xf;
836                 
837                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
838                                  address, opcode, COND(opcode), Rm);
839                                  
840                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
841                 instruction->info.b_bl_bx_blx.target_address = -1;
842         }
843         
844         /* Enhanced DSP add/subtracts */
845         if ((opcode & 0x0000000f0) == 0x00000050)
846         {
847                 uint8_t Rm, Rd, Rn;
848                 char *mnemonic = NULL;
849                 Rm = opcode & 0xf;
850                 Rd = (opcode & 0xf000) >> 12;
851                 Rn = (opcode & 0xf0000) >> 16;
852                 
853                 switch ((opcode & 0x00600000) >> 21)
854                 {
855                         case 0x0:
856                                 instruction->type = ARM_QADD;
857                                 mnemonic = "QADD";
858                                 break;
859                         case 0x1:
860                                 instruction->type = ARM_QSUB;
861                                 mnemonic = "QSUB";
862                                 break;
863                         case 0x2:
864                                 instruction->type = ARM_QDADD;
865                                 mnemonic = "QDADD";
866                                 break;
867                         case 0x3:
868                                 instruction->type = ARM_QDSUB;
869                                 mnemonic = "QDSUB";
870                                 break;
871                 }
872                 
873                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
874                                  address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn);
875         }
876         
877         /* Software breakpoints */
878         if ((opcode & 0x0000000f0) == 0x00000070)
879         {
880                 uint32_t immediate;
881                 instruction->type = ARM_BKPT;
882                 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
883                 
884                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "",
885                                  address, opcode, immediate);   
886         }
887         
888         /* Enhanced DSP multiplies */
889         if ((opcode & 0x000000090) == 0x00000080)
890         {
891                 int x = (opcode & 0x20) >> 5;
892                 int y = (opcode & 0x40) >> 6;
893                 
894                 /* SMLA < x><y> */
895                 if ((opcode & 0x00600000) == 0x00000000)
896                 {
897                         uint8_t Rd, Rm, Rs, Rn;
898                         instruction->type = ARM_SMLAxy;
899                         Rd = (opcode & 0xf0000) >> 16;
900                         Rm = (opcode & 0xf);
901                         Rs = (opcode & 0xf00) >> 8;
902                         Rn = (opcode & 0xf000) >> 12;
903                         
904                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
905                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
906                                          Rd, Rm, Rs, Rn);
907                 }
908                 
909                 /* SMLAL < x><y> */
910                 if ((opcode & 0x00600000) == 0x00400000)
911                 {
912                         uint8_t RdLow, RdHi, Rm, Rs;
913                         instruction->type = ARM_SMLAxy;
914                         RdHi = (opcode & 0xf0000) >> 16;
915                         RdLow = (opcode & 0xf000) >> 12;
916                         Rm = (opcode & 0xf);
917                         Rs = (opcode & 0xf00) >> 8;
918                         
919                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
920                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
921                                          RdLow, RdHi, Rm, Rs);
922                 }
923                 
924                 /* SMLAW < y> */
925                 if (((opcode & 0x00600000) == 0x00100000) && (x == 0))
926                 {
927                         uint8_t Rd, Rm, Rs, Rn;
928                         instruction->type = ARM_SMLAWy;
929                         Rd = (opcode & 0xf0000) >> 16;
930                         Rm = (opcode & 0xf);
931                         Rs = (opcode & 0xf00) >> 8;
932                         Rn = (opcode & 0xf000) >> 12;
933
934                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
935                                          address, opcode, (y) ? "T" : "B", COND(opcode),
936                                          Rd, Rm, Rs, Rn);
937                 }
938                 
939                 /* SMUL < x><y> */
940                 if ((opcode & 0x00600000) == 0x00300000)
941                 {
942                         uint8_t Rd, Rm, Rs;
943                         instruction->type = ARM_SMULxy;
944                         Rd = (opcode & 0xf0000) >> 16;
945                         Rm = (opcode & 0xf);
946                         Rs = (opcode & 0xf00) >> 8;
947                         
948                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
949                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
950                                          Rd, Rm, Rs);
951                 }
952                 
953                 /* SMULW < y> */
954                 if (((opcode & 0x00600000) == 0x00100000) && (x == 1))
955                 {
956                         uint8_t Rd, Rm, Rs;
957                         instruction->type = ARM_SMULWy;
958                         Rd = (opcode & 0xf0000) >> 16;
959                         Rm = (opcode & 0xf);
960                         Rs = (opcode & 0xf00) >> 8;
961                         
962                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
963                                          address, opcode, (y) ? "T" : "B", COND(opcode),
964                                          Rd, Rm, Rs);
965                 }
966         }
967         
968         return ERROR_OK;
969 }
970
971 int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
972 {
973         uint8_t I, op, S, Rn, Rd;
974         char *mnemonic = NULL;
975         char shifter_operand[32];
976         
977         I = (opcode & 0x02000000) >> 25;
978         op = (opcode & 0x01e00000) >> 21;
979         S = (opcode & 0x00100000) >> 20;
980         
981         Rd = (opcode & 0xf000) >> 12;
982         Rn = (opcode & 0xf0000) >> 16;
983         
984         instruction->info.data_proc.Rd = Rd;
985         instruction->info.data_proc.Rn = Rn;
986         instruction->info.data_proc.S = S;
987
988         switch (op)
989         {
990                 case 0x0:
991                         instruction->type = ARM_AND;
992                         mnemonic = "AND";
993                         break;
994                 case 0x1:
995                         instruction->type = ARM_EOR;
996                         mnemonic = "EOR";
997                         break;
998                 case 0x2:
999                         instruction->type = ARM_SUB;
1000                         mnemonic = "SUB";
1001                         break;
1002                 case 0x3:
1003                         instruction->type = ARM_RSB;
1004                         mnemonic = "RSB";
1005                         break;
1006                 case 0x4:
1007                         instruction->type = ARM_ADD;
1008                         mnemonic = "ADD";
1009                         break;
1010                 case 0x5:
1011                         instruction->type = ARM_ADC;
1012                         mnemonic = "ADC";
1013                         break;
1014                 case 0x6:
1015                         instruction->type = ARM_SBC;
1016                         mnemonic = "SBC";
1017                         break;
1018                 case 0x7:
1019                         instruction->type = ARM_RSC;
1020                         mnemonic = "RSC";
1021                         break;
1022                 case 0x8:
1023                         instruction->type = ARM_TST;
1024                         mnemonic = "TST";
1025                         break;
1026                 case 0x9:
1027                         instruction->type = ARM_TEQ;
1028                         mnemonic = "TEQ";
1029                         break;
1030                 case 0xa:
1031                         instruction->type = ARM_CMP;
1032                         mnemonic = "CMP";
1033                         break;
1034                 case 0xb:
1035                         instruction->type = ARM_CMN;
1036                         mnemonic = "CMN";
1037                         break;
1038                 case 0xc:
1039                         instruction->type = ARM_ORR;
1040                         mnemonic = "ORR";
1041                         break;
1042                 case 0xd:
1043                         instruction->type = ARM_MOV;
1044                         mnemonic = "MOV";
1045                         break;
1046                 case 0xe:
1047                         instruction->type = ARM_BIC;
1048                         mnemonic = "BIC";
1049                         break;
1050                 case 0xf:
1051                         instruction->type = ARM_MVN;
1052                         mnemonic = "MVN";
1053                         break;
1054         }
1055         
1056         if (I) /* immediate shifter operand (#<immediate>)*/
1057         {
1058                 uint8_t immed_8 = opcode & 0xff;
1059                 uint8_t rotate_imm = (opcode & 0xf00) >> 8;
1060                 uint32_t immediate;
1061                 
1062                 immediate = ror(immed_8, rotate_imm * 2);
1063                 
1064                 snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
1065                 
1066                 instruction->info.data_proc.variant = 0;
1067                 instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
1068         }
1069         else /* register-based shifter operand */
1070         {
1071                 uint8_t shift, Rm;
1072                 shift = (opcode & 0x60) >> 5;
1073                 Rm = (opcode & 0xf);
1074                 
1075                 if ((opcode & 0x10) != 0x10) /* Immediate shifts ("<Rm>" or "<Rm>, <shift> #<shift_immediate>") */
1076                 {
1077                         uint8_t shift_imm;
1078                         shift_imm = (opcode & 0xf80) >> 7;
1079
1080                         instruction->info.data_proc.variant = 1;
1081                         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1082                         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm;
1083                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
1084                 
1085                         /* LSR encodes a shift by 32 bit as 0x0 */
1086                         if ((shift == 0x1) && (shift_imm == 0x0))
1087                                 shift_imm = 0x20;
1088                 
1089                         /* ASR encodes a shift by 32 bit as 0x0 */
1090                         if ((shift == 0x2) && (shift_imm == 0x0))
1091                                 shift_imm = 0x20;
1092
1093                         /* ROR by 32 bit is actually a RRX */
1094                         if ((shift == 0x3) && (shift_imm == 0x0))
1095                                 shift = 0x4;
1096                         
1097                         if ((shift_imm == 0x0) && (shift == 0x0))
1098                         {
1099                                 snprintf(shifter_operand, 32, "r%i", Rm);
1100                         }
1101                         else
1102                         {
1103                                 if (shift == 0x0) /* LSL */
1104                                 {
1105                                         snprintf(shifter_operand, 32, "r%i, LSL #0x%x", Rm, shift_imm);
1106                                 }
1107                                 else if (shift == 0x1) /* LSR */
1108                                 {
1109                                         snprintf(shifter_operand, 32, "r%i, LSR #0x%x", Rm, shift_imm);
1110                                 }
1111                                 else if (shift == 0x2) /* ASR */
1112                                 {
1113                                         snprintf(shifter_operand, 32, "r%i, ASR #0x%x", Rm, shift_imm);
1114                                 }
1115                                 else if (shift == 0x3) /* ROR */
1116                                 {
1117                                         snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm);
1118                                 }
1119                                 else if (shift == 0x4) /* RRX */
1120                                 {
1121                                         snprintf(shifter_operand, 32, "r%i, RRX", Rm);
1122                                 }
1123                         }
1124                 }
1125                 else /* Register shifts ("<Rm>, <shift> <Rs>") */
1126                 {
1127                         uint8_t Rs = (opcode & 0xf00) >> 8;
1128                         
1129                         instruction->info.data_proc.variant = 2;
1130                         instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
1131                         instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
1132                         instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
1133                         
1134                         if (shift == 0x0) /* LSL */
1135                         {
1136                                 snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
1137                         }
1138                         else if (shift == 0x1) /* LSR */
1139                         {
1140                                 snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
1141                         }
1142                         else if (shift == 0x2) /* ASR */
1143                         {
1144                                 snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
1145                         }
1146                         else if (shift == 0x3) /* ROR */
1147                         {
1148                                 snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
1149                         }
1150                 }
1151         }
1152         
1153         if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand> */
1154         {
1155                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
1156                                  address, opcode, mnemonic, COND(opcode),
1157                                  (S) ? "S" : "", Rd, Rn, shifter_operand);
1158         }
1159         else if ((op == 0xd) || (op == 0xf)) /* <opcode1>{<cond>}{S} <Rd>, <shifter_operand> */
1160         {
1161                 if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */
1162                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",address, opcode);
1163                 else
1164                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
1165                                  address, opcode, mnemonic, COND(opcode),
1166                                  (S) ? "S" : "", Rd, shifter_operand);
1167         }
1168         else /* <opcode2>{<cond>} <Rn>, <shifter_operand> */
1169         {
1170                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
1171                                  address, opcode, mnemonic, COND(opcode),
1172                                  Rn, shifter_operand);
1173         }
1174         
1175         return ERROR_OK;
1176 }
1177                 
1178 int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
1179 {
1180         /* clear fields, to avoid confusion */
1181         memset(instruction, 0, sizeof(arm_instruction_t));
1182         instruction->opcode = opcode;
1183         
1184         /* catch opcodes with condition field [31:28] = b1111 */
1185         if ((opcode & 0xf0000000) == 0xf0000000)
1186         {
1187                 /* Undefined instruction (or ARMv5E cache preload PLD) */
1188                 if ((opcode & 0x08000000) == 0x00000000)
1189                         return evaluate_pld(opcode, address, instruction);
1190                 
1191                 /* Undefined instruction */
1192                 if ((opcode & 0x0e000000) == 0x08000000)
1193                 {
1194                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1195                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
1196                         return ERROR_OK;
1197                 }
1198                 
1199                 /* Branch and branch with link and change to Thumb */
1200                 if ((opcode & 0x0e000000) == 0x0a000000)
1201                         return evaluate_blx_imm(opcode, address, instruction);
1202                 
1203                 /* Extended coprocessor opcode space (ARMv5 and higher )*/
1204                 /* Coprocessor load/store and double register transfers */
1205                 if ((opcode & 0x0e000000) == 0x0c000000)
1206                         return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1207                 
1208                 /* Coprocessor data processing */
1209                 if ((opcode & 0x0f000100) == 0x0c000000)
1210                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1211                 
1212                 /* Coprocessor register transfers */
1213                 if ((opcode & 0x0f000010) == 0x0c000010)
1214                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1215                 
1216                 /* Undefined instruction */
1217                 if ((opcode & 0x0f000000) == 0x0f000000)
1218                 {
1219                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1220                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
1221                         return ERROR_OK;
1222                 }
1223         }
1224         
1225         /* catch opcodes with [27:25] = b000 */
1226         if ((opcode & 0x0e000000) == 0x00000000)
1227         {
1228                 /* Multiplies, extra load/stores */
1229                 if ((opcode & 0x00000090) == 0x00000090)
1230                         return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
1231                 
1232                 /* Miscellaneous instructions */
1233                 if ((opcode & 0x0f900000) == 0x01000000)
1234                         return evaluate_misc_instr(opcode, address, instruction);
1235                 
1236                 return evaluate_data_proc(opcode, address, instruction);
1237         }
1238         
1239         /* catch opcodes with [27:25] = b001 */
1240         if ((opcode & 0x0e000000) == 0x02000000)
1241         {
1242                 /* Undefined instruction */
1243                 if ((opcode & 0x0fb00000) == 0x03000000)
1244                 {
1245                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1246                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
1247                         return ERROR_OK;
1248                 }
1249                                 
1250                 /* Move immediate to status register */
1251                 if ((opcode & 0x0fb00000) == 0x03200000)
1252                         return evaluate_mrs_msr(opcode, address, instruction);
1253                 
1254                 return evaluate_data_proc(opcode, address, instruction);
1255
1256         }
1257         
1258         /* catch opcodes with [27:25] = b010 */
1259         if ((opcode & 0x0e000000) == 0x04000000)
1260         {
1261                 /* Load/store immediate offset */
1262                 return evaluate_load_store(opcode, address, instruction);
1263         }
1264         
1265         /* catch opcodes with [27:25] = b011 */
1266         if ((opcode & 0x0e000000) == 0x06000000)
1267         {
1268                 /* Undefined instruction */
1269                 if ((opcode & 0x00000010) == 0x00000010)
1270                 {
1271                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1272                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
1273                         return ERROR_OK;
1274                 }
1275                 
1276                 /* Load/store register offset */
1277                 return evaluate_load_store(opcode, address, instruction);
1278
1279         }
1280         
1281         /* catch opcodes with [27:25] = b100 */
1282         if ((opcode & 0x0e000000) == 0x08000000)
1283         {
1284                 /* Load/store multiple */
1285                 return evaluate_ldm_stm(opcode, address, instruction);
1286         }
1287         
1288         /* catch opcodes with [27:25] = b101 */
1289         if ((opcode & 0x0e000000) == 0x0a000000)
1290         {
1291                 /* Branch and branch with link */
1292                 return evaluate_b_bl(opcode, address, instruction);
1293         }
1294         
1295         /* catch opcodes with [27:25] = b110 */
1296         if ((opcode & 0x0e000000) == 0x0a000000)
1297         {
1298                 /* Coprocessor load/store and double register transfers */
1299                 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1300         }
1301         
1302         /* catch opcodes with [27:25] = b111 */
1303         if ((opcode & 0x0e000000) == 0x0e000000)
1304         {
1305                 /* Software interrupt */
1306                 if ((opcode & 0x0f000000) == 0x0f000000)
1307                         return evaluate_swi(opcode, address, instruction);
1308                 
1309                 /* Coprocessor data processing */
1310                 if ((opcode & 0x0f000010) == 0x0e000000)
1311                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1312                 
1313                 /* Coprocessor register transfers */
1314                 if ((opcode & 0x0f000010) == 0x0e000010)
1315                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1316         }
1317         
1318         LOG_ERROR("should never reach this point");
1319         return -1;
1320 }
1321
1322 int evaluate_b_bl_blx_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1323 {
1324         uint32_t offset = opcode & 0x7ff;
1325         uint32_t opc = (opcode >> 11) & 0x3;
1326         uint32_t target_address;
1327         char *mnemonic = NULL;
1328         
1329         /* sign extend 11-bit offset */
1330         if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
1331                 offset = 0xfffff800 | offset;
1332         
1333         target_address = address + 4 + (offset << 1);
1334
1335         switch (opc)
1336         {
1337                 /* unconditional branch */
1338                 case 0:
1339                         instruction->type = ARM_B;
1340                         mnemonic = "B";
1341                         break;
1342                 /* BLX suffix */
1343                 case 1:
1344                         instruction->type = ARM_BLX;
1345                         mnemonic = "BLX";
1346                         break;
1347                 /* BL/BLX prefix */
1348                 case 2:
1349                         instruction->type = ARM_UNKNOWN_INSTUCTION;
1350                         mnemonic = "prefix";
1351                         target_address = offset << 12;
1352                         break;
1353                 /* BL suffix */
1354                 case 3:
1355                         instruction->type = ARM_BL;
1356                         mnemonic = "BL";
1357                         break;
1358         }
1359         /* TODO: deals correctly with dual opcodes BL/BLX ... */
1360
1361         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s 0x%8.8" PRIx32 , address, opcode,mnemonic, target_address);
1362         
1363         instruction->info.b_bl_bx_blx.reg_operand = -1;
1364         instruction->info.b_bl_bx_blx.target_address = target_address;
1365
1366         return ERROR_OK;
1367 }
1368
1369 int evaluate_add_sub_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1370 {
1371         uint8_t Rd = (opcode >> 0) & 0x7;
1372         uint8_t Rn = (opcode >> 3) & 0x7;
1373         uint8_t Rm_imm = (opcode >> 6) & 0x7;
1374         uint32_t opc = opcode & (1 << 9);
1375         uint32_t reg_imm  = opcode & (1 << 10);
1376         char *mnemonic;
1377         
1378         if (opc)
1379         {
1380                 instruction->type = ARM_SUB;
1381                 mnemonic = "SUBS";
1382         }
1383         else
1384         {
1385                 instruction->type = ARM_ADD;
1386                 mnemonic = "ADDS";
1387         }
1388         
1389         instruction->info.data_proc.Rd = Rd;
1390         instruction->info.data_proc.Rn = Rn;
1391         instruction->info.data_proc.S = 1;
1392
1393         if (reg_imm)
1394         {
1395                 instruction->info.data_proc.variant = 0; /*immediate*/
1396                 instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
1397                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, #%d",
1398                                  address, opcode, mnemonic, Rd, Rn, Rm_imm);
1399         }
1400         else
1401         {
1402                 instruction->info.data_proc.variant = 1; /*immediate shift*/
1403                 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
1404                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, r%i",
1405                                  address, opcode, mnemonic, Rd, Rn, Rm_imm);
1406         }
1407
1408         return ERROR_OK;
1409 }
1410
1411 int evaluate_shift_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1412 {
1413         uint8_t Rd = (opcode >> 0) & 0x7;
1414         uint8_t Rm = (opcode >> 3) & 0x7;
1415         uint8_t imm = (opcode >> 6) & 0x1f;
1416         uint8_t opc = (opcode >> 11) & 0x3;
1417         char *mnemonic = NULL;
1418         
1419         switch (opc)
1420         {
1421                 case 0:
1422                         instruction->type = ARM_MOV;
1423                         mnemonic = "LSLS";
1424                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
1425                         break;
1426                 case 1:
1427                         instruction->type = ARM_MOV;
1428                         mnemonic = "LSRS";
1429                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
1430                         break;
1431                 case 2:
1432                         instruction->type = ARM_MOV;
1433                         mnemonic = "ASRS";
1434                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
1435                         break;
1436         }
1437
1438         if ((imm == 0) && (opc != 0))
1439                 imm = 32;
1440
1441         instruction->info.data_proc.Rd = Rd;
1442         instruction->info.data_proc.Rn = -1;
1443         instruction->info.data_proc.S = 1;
1444
1445         instruction->info.data_proc.variant = 1; /*immediate_shift*/
1446         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1447         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
1448
1449         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, #0x%02x" ,
1450                                  address, opcode, mnemonic, Rd, Rm, imm);
1451
1452         return ERROR_OK;
1453 }
1454
1455 int evaluate_data_proc_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1456 {
1457         uint8_t imm = opcode & 0xff;
1458         uint8_t Rd = (opcode >> 8) & 0x7;
1459         uint32_t opc = (opcode >> 11) & 0x3;
1460         char *mnemonic = NULL;
1461         
1462         instruction->info.data_proc.Rd = Rd;
1463         instruction->info.data_proc.Rn = Rd;
1464         instruction->info.data_proc.S = 1;
1465         instruction->info.data_proc.variant = 0; /*immediate*/
1466         instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
1467         
1468         switch (opc)
1469         {
1470                 case 0:
1471                         instruction->type = ARM_MOV;
1472                         mnemonic = "MOVS";
1473                         instruction->info.data_proc.Rn = -1;
1474                         break;
1475                 case 1:
1476                         instruction->type = ARM_CMP;
1477                         mnemonic = "CMP";
1478                         instruction->info.data_proc.Rd = -1;
1479                         break;
1480                 case 2:
1481                         instruction->type = ARM_ADD;
1482                         mnemonic = "ADDS";
1483                         break;
1484                 case 3:
1485                         instruction->type = ARM_SUB;
1486                         mnemonic = "SUBS";
1487                         break;
1488         }
1489         
1490         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, #0x%02x" ,
1491                                  address, opcode, mnemonic, Rd, imm);
1492
1493         return ERROR_OK;
1494 }
1495
1496 int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1497 {
1498         uint8_t high_reg, op, Rm, Rd,H1,H2;
1499         char *mnemonic = NULL;
1500         
1501         high_reg = (opcode & 0x0400) >> 10;
1502         op = (opcode & 0x03C0) >> 6;
1503         
1504         Rd = (opcode & 0x0007);
1505         Rm = (opcode & 0x0038) >> 3;
1506         H1 = (opcode & 0x0080) >> 7;
1507         H2 = (opcode & 0x0040) >> 6;
1508         
1509         instruction->info.data_proc.Rd = Rd;
1510         instruction->info.data_proc.Rn = Rd;
1511         instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
1512         instruction->info.data_proc.variant = 1 /*immediate shift*/;
1513         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1514
1515         if (high_reg)
1516         {
1517                 Rd |= H1 << 3;
1518                 Rm |= H2 << 3;
1519                 op >>= 2;
1520         
1521                 switch (op)
1522                 {
1523                         case 0x0:
1524                                 instruction->type = ARM_ADD;
1525                                 mnemonic = "ADD";
1526                                 break;
1527                         case 0x1:
1528                                 instruction->type = ARM_CMP;
1529                                 mnemonic = "CMP";
1530                                 break;
1531                         case 0x2:
1532                                 instruction->type = ARM_MOV;
1533                                 mnemonic = "MOV";
1534                                 break;
1535                         case 0x3:
1536                                 if ((opcode & 0x7) == 0x0)
1537                                 {
1538                                         instruction->info.b_bl_bx_blx.reg_operand = Rm;
1539                                         if (H1)
1540                                         {
1541                                                 instruction->type = ARM_BLX;
1542                                                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBLX r%i", address, opcode, Rm);
1543                                         }
1544                                         else
1545                                         {
1546                                                 instruction->type = ARM_BX;
1547                                                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBX r%i", address, opcode, Rm);
1548                                         }
1549                                 }
1550                                 else
1551                                 {
1552                                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1553                                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
1554                                 }
1555                                 return ERROR_OK;        
1556                                 break;
1557                 }
1558         }
1559         else
1560         {
1561                 switch (op)
1562                 {
1563                         case 0x0:
1564                                 instruction->type = ARM_AND;
1565                                 mnemonic = "ANDS";
1566                                 break;
1567                         case 0x1:
1568                                 instruction->type = ARM_EOR;
1569                                 mnemonic = "EORS";
1570                                 break;
1571                         case 0x2:
1572                                 instruction->type = ARM_MOV;
1573                                 mnemonic = "LSLS";
1574                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1575                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
1576                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1577                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1578                                 break;
1579                         case 0x3:
1580                                 instruction->type = ARM_MOV;
1581                                 mnemonic = "LSRS";
1582                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1583                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
1584                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1585                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1586                                 break;
1587                         case 0x4:
1588                                 instruction->type = ARM_MOV;
1589                                 mnemonic = "ASRS";
1590                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1591                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
1592                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1593                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1594                                 break;
1595                         case 0x5:
1596                                 instruction->type = ARM_ADC;
1597                                 mnemonic = "ADCS";
1598                                 break;
1599                         case 0x6:
1600                                 instruction->type = ARM_SBC;
1601                                 mnemonic = "SBCS";
1602                                 break;
1603                         case 0x7:
1604                                 instruction->type = ARM_MOV;
1605                                 mnemonic = "RORS";
1606                                 instruction->info.data_proc.variant = 2 /*register shift*/;
1607                                 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
1608                                 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1609                                 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1610                                 break;
1611                         case 0x8:
1612                                 instruction->type = ARM_TST;
1613                                 mnemonic = "TST";
1614                                 break;
1615                         case 0x9:
1616                                 instruction->type = ARM_RSB;
1617                                 mnemonic = "NEGS";
1618                                 instruction->info.data_proc.variant = 0 /*immediate*/;
1619                                 instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
1620                                 instruction->info.data_proc.Rn = Rm;
1621                                 break;
1622                         case 0xA:
1623                                 instruction->type = ARM_CMP;
1624                                 mnemonic = "CMP";
1625                                 break;
1626                         case 0xB:
1627                                 instruction->type = ARM_CMN;
1628                                 mnemonic = "CMN";
1629                                 break;
1630                         case 0xC:
1631                                 instruction->type = ARM_ORR;
1632                                 mnemonic = "ORRS";
1633                                 break;
1634                         case 0xD:
1635                                 instruction->type = ARM_MUL;
1636                                 mnemonic = "MULS";
1637                                 break;
1638                         case 0xE:
1639                                 instruction->type = ARM_BIC;
1640                                 mnemonic = "BICS";
1641                                 break;
1642                         case 0xF:
1643                                 instruction->type = ARM_MVN;
1644                                 mnemonic = "MVNS";
1645                                 break;
1646                 }
1647         }
1648
1649         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i",
1650                                  address, opcode, mnemonic, Rd, Rm);
1651
1652         return ERROR_OK;
1653 }
1654
1655 int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1656 {
1657         uint32_t immediate;
1658         uint8_t Rd = (opcode >> 8) & 0x7; 
1659
1660         instruction->type = ARM_LDR;
1661         immediate = opcode & 0x000000ff;
1662
1663         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tLDR r%i, [PC, #0x%" PRIx32 "]", address, opcode, Rd, immediate*4);
1664
1665         instruction->info.load_store.Rd = Rd;
1666         instruction->info.load_store.Rn = 15 /*PC*/;
1667         instruction->info.load_store.index_mode = 0; /*offset*/
1668         instruction->info.load_store.offset_mode = 0; /*immediate*/
1669         instruction->info.load_store.offset.offset = immediate*4;
1670
1671         return ERROR_OK;
1672 }
1673
1674 int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1675 {
1676         uint8_t Rd = (opcode >> 0) & 0x7; 
1677         uint8_t Rn = (opcode >> 3) & 0x7; 
1678         uint8_t Rm = (opcode >> 6) & 0x7; 
1679         uint8_t opc = (opcode >> 9) & 0x7; 
1680         char *mnemonic = NULL;
1681
1682         switch (opc)
1683         {
1684                 case 0:
1685                         instruction->type = ARM_STR;
1686                         mnemonic = "STR";
1687                         break;
1688                 case 1:
1689                         instruction->type = ARM_STRH;
1690                         mnemonic = "STRH";
1691                         break;
1692                 case 2:
1693                         instruction->type = ARM_STRB;
1694                         mnemonic = "STRB";
1695                         break;
1696                 case 3:
1697                         instruction->type = ARM_LDRSB;
1698                         mnemonic = "LDRSB";
1699                         break;
1700                 case 4:
1701                         instruction->type = ARM_LDR;
1702                         mnemonic = "LDR";
1703                         break;
1704                 case 5:
1705                         instruction->type = ARM_LDRH;
1706                         mnemonic = "LDRH";
1707                         break;
1708                 case 6:
1709                         instruction->type = ARM_LDRB;
1710                         mnemonic = "LDRB";
1711                         break;
1712                 case 7:
1713                         instruction->type = ARM_LDRSH;
1714                         mnemonic = "LDRSH";
1715                         break;
1716         }
1717
1718         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);
1719         
1720         instruction->info.load_store.Rd = Rd;
1721         instruction->info.load_store.Rn = Rn;
1722         instruction->info.load_store.index_mode = 0; /*offset*/
1723         instruction->info.load_store.offset_mode = 1; /*register*/
1724         instruction->info.load_store.offset.reg.Rm = Rm;
1725
1726         return ERROR_OK;
1727 }
1728
1729 int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1730 {
1731         uint32_t offset = (opcode >> 6) & 0x1f;
1732         uint8_t Rd = (opcode >> 0) & 0x7; 
1733         uint8_t Rn = (opcode >> 3) & 0x7; 
1734         uint32_t L = opcode & (1 << 11);
1735         uint32_t B = opcode & (1 << 12);
1736         char *mnemonic;
1737         char suffix = ' ';
1738         uint32_t shift = 2;
1739
1740         if (L)
1741         {
1742                 instruction->type = ARM_LDR;
1743                 mnemonic = "LDR";
1744         }
1745         else
1746         {
1747                 instruction->type = ARM_STR;
1748                 mnemonic = "STR";
1749         }
1750
1751         if ((opcode&0xF000) == 0x8000)
1752         {
1753                 suffix = 'H';
1754                 shift = 1;
1755         }
1756         else if (B)
1757         {
1758                 suffix = 'B';
1759                 shift = 0;
1760         }
1761
1762         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);
1763         
1764         instruction->info.load_store.Rd = Rd;
1765         instruction->info.load_store.Rn = Rn;
1766         instruction->info.load_store.index_mode = 0; /*offset*/
1767         instruction->info.load_store.offset_mode = 0; /*immediate*/
1768         instruction->info.load_store.offset.offset = offset << shift;
1769
1770         return ERROR_OK;
1771 }
1772
1773 int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1774 {
1775         uint32_t offset = opcode  & 0xff;
1776         uint8_t Rd = (opcode >> 8) & 0x7; 
1777         uint32_t L = opcode & (1 << 11);
1778         char *mnemonic;
1779
1780         if (L)
1781         {
1782                 instruction->type = ARM_LDR;
1783                 mnemonic = "LDR";
1784         }
1785         else
1786         {
1787                 instruction->type = ARM_STR;
1788                 mnemonic = "STR";
1789         }
1790
1791         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [SP, #0x%" PRIx32 "]", address, opcode, mnemonic, Rd, offset*4);
1792         
1793         instruction->info.load_store.Rd = Rd;
1794         instruction->info.load_store.Rn = 13 /*SP*/;
1795         instruction->info.load_store.index_mode = 0; /*offset*/
1796         instruction->info.load_store.offset_mode = 0; /*immediate*/
1797         instruction->info.load_store.offset.offset = offset*4;
1798
1799         return ERROR_OK;
1800 }
1801
1802 int evaluate_add_sp_pc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1803 {
1804         uint32_t imm = opcode  & 0xff;
1805         uint8_t Rd = (opcode >> 8) & 0x7; 
1806         uint8_t Rn;
1807         uint32_t SP = opcode & (1 << 11);
1808         char *reg_name;
1809
1810         instruction->type = ARM_ADD;
1811         
1812         if (SP)
1813         {
1814                 reg_name = "SP";
1815                 Rn = 13;
1816         }
1817         else
1818         {
1819                 reg_name = "PC";
1820                 Rn = 15;
1821         }
1822
1823         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tADD r%i, %s, #0x%" PRIx32 "", address, opcode, Rd,reg_name, imm*4);
1824
1825         instruction->info.data_proc.variant = 0 /* immediate */;
1826         instruction->info.data_proc.Rd = Rd;
1827         instruction->info.data_proc.Rn = Rn;
1828         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
1829
1830         return ERROR_OK;
1831 }
1832
1833 int evaluate_adjust_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1834 {
1835         uint32_t imm = opcode  & 0x7f;
1836         uint8_t opc = opcode & (1 << 7);
1837         char *mnemonic;
1838
1839         
1840         if (opc)
1841         {
1842                 instruction->type = ARM_SUB;
1843                 mnemonic = "SUB";
1844         }
1845         else
1846         {
1847                 instruction->type = ARM_ADD;
1848                 mnemonic = "ADD";
1849         }
1850
1851         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s SP, #0x%" PRIx32 "", address, opcode, mnemonic, imm*4);
1852
1853         instruction->info.data_proc.variant = 0 /* immediate */;
1854         instruction->info.data_proc.Rd = 13 /*SP*/;
1855         instruction->info.data_proc.Rn = 13 /*SP*/;
1856         instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
1857
1858         return ERROR_OK;
1859 }
1860
1861 int evaluate_breakpoint_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1862 {
1863         uint32_t imm = opcode  & 0xff;
1864         
1865         instruction->type = ARM_BKPT;
1866
1867         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBKPT 0x%02" PRIx32 "", address, opcode, imm);
1868
1869         return ERROR_OK;
1870 }
1871
1872 int evaluate_load_store_multiple_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1873 {
1874         uint32_t reg_list = opcode  & 0xff;
1875         uint32_t L = opcode & (1 << 11);
1876         uint32_t R = opcode & (1 << 8);
1877         uint8_t Rn = (opcode >> 8) & 7;
1878         uint8_t addr_mode = 0 /* IA */;
1879         char reg_names[40];
1880         char *reg_names_p;
1881         char *mnemonic;
1882         char ptr_name[7] = "";
1883         int i;  
1884
1885         if ((opcode & 0xf000) == 0xc000)
1886         { /* generic load/store multiple */
1887                 if (L)
1888                 {
1889                         instruction->type = ARM_LDM;
1890                         mnemonic = "LDMIA";
1891                 }
1892                 else
1893                 {
1894                         instruction->type = ARM_STM;
1895                         mnemonic = "STMIA";
1896                 }
1897                 snprintf(ptr_name,7,"r%i!, ",Rn);
1898         }
1899         else
1900         { /* push/pop */
1901                 Rn = 13; /* SP */
1902                 if (L)
1903                 {
1904                         instruction->type = ARM_LDM;
1905                         mnemonic = "POP";
1906                         if (R)
1907                                 reg_list |= (1 << 15) /*PC*/;
1908                 }
1909                 else
1910                 {
1911                         instruction->type = ARM_STM;
1912                         mnemonic = "PUSH";
1913                         addr_mode = 3; /*DB*/
1914                         if (R)
1915                                 reg_list |= (1 << 14) /*LR*/;
1916                 }
1917         }
1918
1919         reg_names_p = reg_names;
1920         for (i = 0; i <= 15; i++)
1921         {
1922                 if (reg_list & (1 << i))
1923                         reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i);
1924         }
1925         if (reg_names_p > reg_names)
1926                 reg_names_p[-2] = '\0';
1927         else /* invalid op : no registers */
1928                 reg_names[0] = '\0';
1929
1930         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s %s{%s}", address, opcode, mnemonic, ptr_name,reg_names);
1931
1932         instruction->info.load_store_multiple.register_list = reg_list;
1933         instruction->info.load_store_multiple.Rn = Rn;
1934         instruction->info.load_store_multiple.addressing_mode = addr_mode;
1935
1936         return ERROR_OK;
1937 }
1938
1939 int evaluate_cond_branch_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1940 {
1941         uint32_t offset = opcode  & 0xff;
1942         uint8_t cond = (opcode >> 8) & 0xf;
1943         uint32_t target_address;
1944
1945         if (cond == 0xf)
1946         {
1947                 instruction->type = ARM_SWI;
1948                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tSWI 0x%02" PRIx32 , address, opcode, offset);
1949                 return ERROR_OK;
1950         }
1951         else if (cond == 0xe)
1952         {
1953                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1954                 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
1955                 return ERROR_OK;
1956         }
1957
1958         /* sign extend 8-bit offset */
1959         if (offset & 0x00000080)
1960                 offset = 0xffffff00 | offset;
1961         
1962         target_address = address + 4 + (offset << 1);
1963
1964         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tB%s 0x%8.8" PRIx32 , address, opcode,
1965                          arm_condition_strings[cond], target_address);
1966         
1967         instruction->type = ARM_B;
1968         instruction->info.b_bl_bx_blx.reg_operand = -1;
1969         instruction->info.b_bl_bx_blx.target_address = target_address;
1970
1971         return ERROR_OK;
1972 }
1973
1974 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1975 {
1976         /* clear fields, to avoid confusion */
1977         memset(instruction, 0, sizeof(arm_instruction_t));
1978         instruction->opcode = opcode;
1979         
1980         if ((opcode & 0xe000) == 0x0000)
1981         {
1982                 /* add/substract register or immediate */
1983                 if ((opcode & 0x1800) == 0x1800)
1984                         return evaluate_add_sub_thumb(opcode, address, instruction);
1985                 /* shift by immediate */
1986                 else
1987                         return evaluate_shift_imm_thumb(opcode, address, instruction);
1988         }
1989         
1990         /* Add/substract/compare/move immediate */
1991         if ((opcode & 0xe000) == 0x2000)
1992         {
1993                 return evaluate_data_proc_imm_thumb(opcode, address, instruction);
1994         }
1995         
1996         /* Data processing instructions */
1997         if ((opcode & 0xf800) == 0x4000)
1998         {
1999                 return evaluate_data_proc_thumb(opcode, address, instruction);
2000         }
2001         
2002         /* Load from literal pool */
2003         if ((opcode & 0xf800) == 0x4800)
2004         {
2005                 return evaluate_load_literal_thumb(opcode, address, instruction);
2006         }
2007
2008         /* Load/Store register offset */
2009         if ((opcode & 0xf000) == 0x5000)
2010         {
2011                 return evaluate_load_store_reg_thumb(opcode, address, instruction);
2012         }
2013
2014         /* Load/Store immediate offset */
2015         if (((opcode & 0xe000) == 0x6000)
2016                 ||((opcode & 0xf000) == 0x8000))
2017         {
2018                 return evaluate_load_store_imm_thumb(opcode, address, instruction);
2019         }
2020         
2021         /* Load/Store from/to stack */
2022         if ((opcode & 0xf000) == 0x9000)
2023         {
2024                 return evaluate_load_store_stack_thumb(opcode, address, instruction);
2025         }
2026
2027         /* Add to SP/PC */
2028         if ((opcode & 0xf000) == 0xa000)
2029         {
2030                 return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2031         }
2032
2033         /* Misc */
2034         if ((opcode & 0xf000) == 0xb000)
2035         {
2036                 if ((opcode & 0x0f00) == 0x0000)
2037                         return evaluate_adjust_stack_thumb(opcode, address, instruction);
2038                 else if ((opcode & 0x0f00) == 0x0e00)
2039                         return evaluate_breakpoint_thumb(opcode, address, instruction);
2040                 else if ((opcode & 0x0600) == 0x0400) /* push pop */
2041                         return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2042                 else
2043                 {
2044                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
2045                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
2046                         return ERROR_OK;
2047                 }
2048         }
2049
2050         /* Load/Store multiple */
2051         if ((opcode & 0xf000) == 0xc000)
2052         {
2053                 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2054         }
2055
2056         /* Conditional branch + SWI */
2057         if ((opcode & 0xf000) == 0xd000)
2058         {
2059                 return evaluate_cond_branch_thumb(opcode, address, instruction);
2060         }
2061         
2062         if ((opcode & 0xe000) == 0xe000)
2063         {
2064                 /* Undefined instructions */
2065                 if ((opcode & 0xf801) == 0xe801)
2066                 {
2067                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
2068                         snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
2069                         return ERROR_OK;
2070                 }
2071                 else
2072                 { /* Branch to offset */
2073                         return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2074                 }
2075         }
2076
2077         LOG_ERROR("should never reach this point (opcode=%04x)",opcode);
2078         return -1;
2079 }
2080
2081 int arm_access_size(arm_instruction_t *instruction)
2082 {
2083         if ((instruction->type == ARM_LDRB)
2084                 || (instruction->type == ARM_LDRBT)
2085                 || (instruction->type == ARM_LDRSB)
2086                 || (instruction->type == ARM_STRB)
2087                 || (instruction->type == ARM_STRBT))
2088         {
2089                 return 1;
2090         }
2091         else if ((instruction->type == ARM_LDRH)
2092                 || (instruction->type == ARM_LDRSH)
2093                 || (instruction->type == ARM_STRH))
2094         {
2095                 return 2;
2096         }
2097         else if ((instruction->type == ARM_LDR)
2098                 || (instruction->type == ARM_LDRT)
2099                 || (instruction->type == ARM_STR)
2100                 || (instruction->type == ARM_STRT))
2101         {
2102                 return 4;
2103         }
2104         else if ((instruction->type == ARM_LDRD)
2105                 || (instruction->type == ARM_STRD))
2106         {
2107                 return 8;
2108         }
2109         else
2110         {
2111                 LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type);
2112                 return 0;
2113         }
2114 }