- keep additional information for decoded instructions
[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 #include "arm_disassembler.h"
21
22 #include "log.h"
23
24 #include <strings.h>
25
26 /* textual represenation of the condition field */
27 /* ALways (default) is ommitted (empty string) */
28 char *arm_condition_strings[] =
29 {
30         "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
31 };
32
33 /* make up for C's missing ROR */
34 u32 ror(u32 value, int places) 
35
36         return (value >> places) | (value << (32 - places)); 
37 }
38
39 int evaluate_pld(u32 opcode, u32 address, arm_instruction_t *instruction)
40 {
41         /* PLD */
42         if ((opcode & 0x0d70f0000) == 0x0550f000)
43         {
44                 instruction->type = ARM_PLD;
45                 
46                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tPLD ...TODO...", address, opcode);
47                 
48                 return ERROR_OK;
49         }
50         else
51         {
52                 instruction->type = ARM_UNDEFINED_INSTRUCTION;
53                 return ERROR_OK;
54         }
55         
56         ERROR("should never reach this point");
57         return -1;
58 }
59
60 int evaluate_swi(u32 opcode, u32 address, arm_instruction_t *instruction)
61 {
62         instruction->type = ARM_SWI;
63         
64         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSWI 0x%6.6x", address, opcode, (opcode & 0xffffff));
65         
66         return ERROR_OK;
67 }
68
69 int evaluate_blx_imm(u32 opcode, u32 address, arm_instruction_t *instruction)
70 {
71         int offset;
72         u32 immediate;
73         u32 target_address;
74         
75         instruction->type = ARM_BLX;
76         immediate = opcode & 0x00ffffff;
77         
78         /* sign extend 24-bit immediate */
79         if (immediate & 0x00800000)
80                 offset = 0xff000000 | immediate;
81         else
82                 offset = immediate;
83         
84         /* shift two bits left */
85         offset <<= 2;
86         
87         /* odd/event halfword */
88         if (opcode & 0x01000000)
89                 offset |= 0x2;
90         
91         target_address = address + 8 + offset;
92         
93         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBLX 0x%8.8x", address, opcode, target_address);
94         
95         instruction->info.b_bl_bx_blx.reg_operand = -1;
96         instruction->info.b_bl_bx_blx.target_address = target_address;
97         
98         return ERROR_OK;
99 }
100
101 int evaluate_b_bl(u32 opcode, u32 address, arm_instruction_t *instruction)
102 {
103         u8 L;
104         u32 immediate;
105         int offset;
106         u32 target_address;
107         
108         immediate = opcode & 0x00ffffff;
109         L = (opcode & 0x01000000) >> 24;
110         
111         /* sign extend 24-bit immediate */
112         if (immediate & 0x00800000)
113                 offset = 0xff000000 | immediate;
114         else
115                 offset = immediate;
116         
117         /* shift two bits left */
118         offset <<= 2;
119         
120         target_address = address + 8 + offset;
121
122         if (L)
123                 instruction->type = ARM_BL;
124         else
125                 instruction->type = ARM_B;
126         
127         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tB%s%s 0x%8.8x", address, opcode,
128                          (L) ? "L" : "", COND(opcode), target_address);
129         
130         instruction->info.b_bl_bx_blx.reg_operand = -1;
131         instruction->info.b_bl_bx_blx.target_address = target_address;
132         
133         return ERROR_OK;
134 }
135
136 /* Coprocessor load/store and double register transfers */
137 /* both normal and extended instruction space (condition field b1111) */
138 int evaluate_ldc_stc_mcrr_mrrc(u32 opcode, u32 address, arm_instruction_t *instruction)
139 {
140         u8 cp_num = (opcode & 0xf00) >> 8;
141         
142         /* MCRR or MRRC */
143         if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000))
144         {
145                 u8 cp_opcode, Rd, Rn, CRm;
146                 char *mnemonic;
147                 
148                 cp_opcode = (opcode & 0xf0) >> 4;
149                 Rd = (opcode & 0xf000) >> 12;
150                 Rn = (opcode & 0xf0000) >> 16;
151                 CRm = (opcode & 0xf);
152                 
153                 /* MCRR */
154                 if ((opcode & 0x0ff00000) == 0x0c400000)
155                 {
156                         instruction->type = ARM_MCRR;
157                         mnemonic = "MCRR";
158                 }
159                 
160                 /* MRRC */
161                 if ((opcode & 0x0ff00000) == 0x0c500000)
162                 {
163                         instruction->type = ARM_MRRC;
164                         mnemonic = "MRRC";
165                 }
166                 
167                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s p%i, %x, r%i, r%i, c%i",
168                                  address, opcode, mnemonic, COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
169         }
170         else /* LDC or STC */
171         {
172                 u8 CRd, Rn, offset;
173                 u8 U, N;
174                 char *mnemonic;
175                 char addressing_mode[32];
176                 
177                 CRd = (opcode & 0xf000) >> 12;
178                 Rn = (opcode & 0xf0000) >> 16;
179                 offset = (opcode & 0xff);
180                 
181                 /* load/store */
182                 if (opcode & 0x00100000)
183                 {
184                         instruction->type = ARM_LDC;
185                         mnemonic = "LDC";
186                 }
187                 else
188                 {
189                         instruction->type = ARM_STC;
190                         mnemonic = "STC";
191                 }
192                 
193                 U = (opcode & 0x00800000) >> 23;
194                 N = (opcode & 0x00400000) >> 22;
195                 
196                 /* addressing modes */
197                 if ((opcode & 0x01200000) == 0x01000000) /* immediate offset */
198                         snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]", Rn, (U) ? "" : "-", offset);
199                 else if ((opcode & 0x01200000) == 0x01200000) /* immediate pre-indexed */
200                         snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]!", Rn, (U) ? "" : "-", offset);
201                 else if ((opcode & 0x01200000) == 0x00200000) /* immediate post-indexed */
202                         snprintf(addressing_mode, 32, "[r%i], #%s0x%2.2x*4", Rn, (U) ? "" : "-", offset);
203                 else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
204                         snprintf(addressing_mode, 32, "[r%i], #0x%2.2x", Rn, offset);
205
206                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s p%i, c%i, %s",
207                                  address, opcode, mnemonic, ((opcode & 0xf0000000) == 0xf0000000) ? COND(opcode) : "2",
208                                  (N) ? "L" : "",
209                                  cp_num, CRd, addressing_mode);
210         }
211         
212         return ERROR_OK;
213 }
214
215 /* Coprocessor data processing instructions */
216 /* Coprocessor register transfer instructions */
217 /* both normal and extended instruction space (condition field b1111) */
218 int evaluate_cdp_mcr_mrc(u32 opcode, u32 address, arm_instruction_t *instruction)
219 {
220         char* cond;
221         char* mnemonic;
222         u8 cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
223         
224         cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
225         cp_num = (opcode & 0xf00) >> 8;
226         CRd_Rd = (opcode & 0xf000) >> 12;
227         CRn = (opcode & 0xf0000) >> 16;
228         CRm = (opcode & 0xf);
229         opcode_2 = (opcode & 0xe0) >> 5;
230         
231         /* CDP or MRC/MCR */
232         if (opcode & 0x00000010) /* bit 4 set -> MRC/MCR */
233         {
234                 if (opcode & 0x00100000) /* bit 20 set -> MRC */
235                 {
236                         instruction->type = ARM_MRC;
237                         mnemonic = "MRC";
238                 }
239                 else /* bit 20 not set -> MCR */
240                 {
241                         instruction->type = ARM_MCR;
242                         mnemonic = "MCR";
243                 }
244                 
245                 opcode_1 = (opcode & 0x00e00000) >> 21;
246                 
247                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x",
248                                  address, opcode, mnemonic, cond,
249                                  cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
250         }
251         else /* bit 4 not set -> CDP */
252         {
253                 instruction->type = ARM_CDP;
254                 mnemonic = "CDP";
255                 
256                 opcode_1 = (opcode & 0x00f00000) >> 20;
257                 
258                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x",
259                                  address, opcode, mnemonic, cond,
260                                  cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
261         }
262         
263         return ERROR_OK;
264 }
265
266 /* Load/store instructions */
267 int evaluate_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
268 {
269         u8 I, P, U, B, W, L;
270         u8 Rn, Rd;
271         char *operation; /* "LDR" or "STR" */
272         char *suffix; /* "", "B", "T", "BT" */
273         char offset[32];
274         
275         /* examine flags */
276         I = (opcode & 0x02000000) >> 25;
277         P = (opcode & 0x01000000) >> 24;
278         U = (opcode & 0x00800000) >> 23;
279         B = (opcode & 0x00400000) >> 22;
280         W = (opcode & 0x00200000) >> 21;
281         L = (opcode & 0x00100000) >> 20;
282         
283         /* target register */
284         Rd = (opcode & 0xf000) >> 12;
285         
286         /* base register */
287         Rn = (opcode & 0xf0000) >> 16;
288         
289         instruction->info.load_store.Rd = Rd;
290         instruction->info.load_store.Rn = Rn;
291         instruction->info.load_store.U = U;
292
293         /* determine operation */
294         if (L)
295                 operation = "LDR";
296         else
297                 operation = "STR";
298         
299         /* determine instruction type and suffix */
300         if (B)
301         {
302                 if ((P == 0) && (W == 1))
303                 {
304                         if (L)
305                                 instruction->type = ARM_LDRBT;
306                         else
307                                 instruction->type = ARM_STRBT;
308                         suffix = "BT";
309                 }
310                 else
311                 {
312                         if (L)
313                                 instruction->type = ARM_LDRB;
314                         else
315                                 instruction->type = ARM_STRB;
316                         suffix = "B";
317                 }
318         }
319         else
320         {
321                 if ((P == 0) && (W == 1))
322                 {
323                         if (L)
324                                 instruction->type = ARM_LDRT;
325                         else
326                                 instruction->type = ARM_STRT;
327                         suffix = "T";
328                 }
329                 else
330                 {
331                         if (L)
332                                 instruction->type = ARM_LDR;
333                         else
334                                 instruction->type = ARM_STR;
335                         suffix = "";
336                 }
337         }
338         
339         if (!I) /* #+-<offset_12> */
340         {
341                 u32 offset_12 = (opcode & 0xfff);
342                 snprintf(offset, 32, "#%s0x%x", (U) ? "" : "-", offset_12);
343                 
344                 instruction->info.load_store.offset_mode = 0;
345                 instruction->info.load_store.offset.offset = offset_12;
346         }
347         else /* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
348         {
349                 u8 shift_imm, shift;
350                 u8 Rm;
351                 
352                 shift_imm = (opcode & 0xf80) >> 7;
353                 shift = (opcode & 0x60) >> 5;
354                 Rm = (opcode & 0xf);
355                 
356                 /* LSR encodes a shift by 32 bit as 0x0 */
357                 if ((shift == 0x1) && (shift_imm == 0x0))
358                         shift_imm = 0x20;
359                 
360                 /* ASR encodes a shift by 32 bit as 0x0 */
361                 if ((shift == 0x2) && (shift_imm == 0x0))
362                         shift_imm = 0x20;
363
364                 /* ROR by 32 bit is actually a RRX */
365                 if ((shift == 0x3) && (shift_imm == 0x0))
366                         shift = 0x4;
367                 
368                 instruction->info.load_store.offset_mode = 1;
369                 instruction->info.load_store.offset.reg.Rm = Rm;
370                 instruction->info.load_store.offset.reg.shift = shift;
371                 instruction->info.load_store.offset.reg.shift_imm = shift_imm;
372
373                 if ((shift_imm == 0x0) && (shift == 0x0)) /* +-<Rm> */
374                 {
375                         snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
376                 }
377                 else /* +-<Rm>, <Shift>, #<shift_imm> */
378                 {
379                         switch (shift)
380                         {
381                                 case 0x0: /* LSL */
382                                         snprintf(offset, 32, "%sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
383                                         break;
384                                 case 0x1: /* LSR */
385                                         snprintf(offset, 32, "%sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
386                                         break;
387                                 case 0x2: /* ASR */
388                                         snprintf(offset, 32, "%sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
389                                         break;
390                                 case 0x3: /* ROR */
391                                         snprintf(offset, 32, "%sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
392                                         break;
393                                 case 0x4: /* RRX */
394                                         snprintf(offset, 32, "%sr%i, RRX", (U) ? "" : "-", Rm);
395                                         break;
396                         }
397                 }
398         }
399         
400         if (P == 1)
401         {
402                 if (W == 0) /* offset */
403                 {
404                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]",
405                                          address, opcode, operation, COND(opcode), suffix,
406                                          Rd, Rn, offset);
407                         
408                         instruction->info.load_store.index_mode = 0;
409                 }
410                 else /* pre-indexed */
411                 {
412                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]!",
413                                          address, opcode, operation, COND(opcode), suffix,
414                                          Rd, Rn, offset);
415                         
416                         instruction->info.load_store.index_mode = 1;
417                 }
418         }
419         else /* post-indexed */
420         {
421                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i], %s",
422                                  address, opcode, operation, COND(opcode), suffix,
423                                  Rd, Rn, offset);
424                 
425                 instruction->info.load_store.index_mode = 2;
426         }
427         
428         return ERROR_OK;
429 }
430
431 /* Miscellaneous load/store instructions */
432 int evaluate_misc_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
433 {
434         u8 P, U, I, W, L, S, H;
435         u8 Rn, Rd;
436         char *operation; /* "LDR" or "STR" */
437         char *suffix; /* "H", "SB", "SH", "D" */
438         char offset[32];
439         
440         /* examine flags */
441         P = (opcode & 0x01000000) >> 24;
442         U = (opcode & 0x00800000) >> 23;
443         I = (opcode & 0x00400000) >> 22;
444         W = (opcode & 0x00200000) >> 21;
445         L = (opcode & 0x00100000) >> 20;
446         S = (opcode & 0x00000040) >> 6;
447         H = (opcode & 0x00000020) >> 5;
448         
449         /* target register */
450         Rd = (opcode & 0xf000) >> 12;
451         
452         /* base register */
453         Rn = (opcode & 0xf0000) >> 16;
454         
455         instruction->info.load_store.Rd = Rd;
456         instruction->info.load_store.Rn = Rn;
457         instruction->info.load_store.U = U;
458         
459         /* determine instruction type and suffix */
460         if (S) /* signed */
461         {
462                 if (L) /* load */
463                 {
464                         if (H)
465                         {
466                                 operation = "LDR";
467                                 instruction->type = ARM_LDRSH;
468                                 suffix = "SH";
469                         }
470                         else
471                         {
472                                 operation = "LDR";
473                                 instruction->type = ARM_LDRSB;
474                                 suffix = "SB";
475                         }
476                 }
477                 else /* there are no signed stores, so this is used to encode double-register load/stores */
478                 {
479                         suffix = "D";
480                         if (H)
481                         {
482                                 operation = "STR";
483                                 instruction->type = ARM_STRD;
484                         }
485                         else
486                         {
487                                 operation = "LDR";
488                                 instruction->type = ARM_LDRD;
489                         }
490                 }
491         }
492         else /* unsigned */
493         {
494                 suffix = "H";
495                 if (L) /* load */
496                 {
497                         operation = "LDR";
498                         instruction->type = ARM_LDRH;
499                 }
500                 else /* store */
501                 {
502                         operation = "STR";
503                         instruction->type = ARM_STRH;
504                 }
505         }
506         
507         if (I) /* Immediate offset/index (#+-<offset_8>)*/
508         {
509                 u32 offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
510                 snprintf(offset, 32, "#%s0x%x", (U) ? "" : "-", offset_8);
511                 
512                 instruction->info.load_store.offset_mode = 0;
513                 instruction->info.load_store.offset.offset = offset_8;
514         }
515         else /* Register offset/index (+-<Rm>) */
516         {
517                 u8 Rm;
518                 Rm = (opcode & 0xf);
519                 snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
520                 
521                 instruction->info.load_store.offset_mode = 1;
522                 instruction->info.load_store.offset.reg.Rm = Rm;
523                 instruction->info.load_store.offset.reg.shift = 0x0;
524                 instruction->info.load_store.offset.reg.shift_imm = 0x0;
525         }
526         
527         if (P == 1)
528         {
529                 if (W == 0) /* offset */
530                 {
531                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]",
532                                          address, opcode, operation, COND(opcode), suffix,
533                                          Rd, Rn, offset);
534                         
535                         instruction->info.load_store.index_mode = 0;
536                 }
537                 else /* pre-indexed */
538                 {
539                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]!",
540                                          address, opcode, operation, COND(opcode), suffix,
541                                          Rd, Rn, offset);
542                 
543                         instruction->info.load_store.index_mode = 1;
544                 }
545         }
546         else /* post-indexed */
547         {
548                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i], %s",
549                                  address, opcode, operation, COND(opcode), suffix,
550                                  Rd, Rn, offset);
551         
552                 instruction->info.load_store.index_mode = 2;
553         }
554         
555         return ERROR_OK;
556 }
557
558 /* Load/store multiples instructions */
559 int evaluate_ldm_stm(u32 opcode, u32 address, arm_instruction_t *instruction)
560 {
561         u8 P, U, S, W, L, Rn;
562         u32 register_list;
563         char *addressing_mode;
564         char *mnemonic;
565         char reg_list[69];
566         char *reg_list_p;
567         int i;
568         int first_reg = 1;
569         
570         P = (opcode & 0x01000000) >> 24;
571         U = (opcode & 0x00800000) >> 23;
572         S = (opcode & 0x00400000) >> 22;
573         W = (opcode & 0x00200000) >> 21;
574         L = (opcode & 0x00100000) >> 20;
575         register_list = (opcode & 0xffff);
576         Rn = (opcode & 0xf0000) >> 16;
577         
578         instruction->info.load_store_multiple.Rn = Rn;
579         instruction->info.load_store_multiple.register_list = register_list;
580         instruction->info.load_store_multiple.S = S;
581         instruction->info.load_store_multiple.W = W;
582         
583         if (L)
584         {
585                 instruction->type = ARM_LDM;
586                 mnemonic = "LDM";
587         }
588         else
589         {
590                 instruction->type = ARM_STM;
591                 mnemonic = "STM";
592         }
593         
594         if (P)
595         {
596                 if (U)
597                 {
598                         instruction->info.load_store_multiple.addressing_mode = 1;
599                         addressing_mode = "IB";
600                 }
601                 else
602                 {
603                         instruction->info.load_store_multiple.addressing_mode = 3;
604                         addressing_mode = "DB";
605                 }
606         }
607         else
608         {
609                 if (U)
610                 {
611                         instruction->info.load_store_multiple.addressing_mode = 0;
612                         addressing_mode = "IA";
613                 }
614                 else
615                 {
616                         instruction->info.load_store_multiple.addressing_mode = 2;
617                         addressing_mode = "DA";
618                 }
619         }
620         
621         reg_list_p = reg_list;
622         for (i = 0; i <= 15; i++)
623         {
624                 if ((register_list >> i) & 1)
625                 {
626                         if (first_reg)
627                         {
628                                 first_reg = 0;
629                                 reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), "r%i", i);
630                         }
631                         else
632                         {
633                                 reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), ", r%i", i);
634                         }
635                 }
636         }
637         
638         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i%s, {%s}%s",
639                          address, opcode, mnemonic, COND(opcode), addressing_mode,
640                          Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
641         
642         return ERROR_OK;
643 }
644
645 /* Multiplies, extra load/stores */
646 int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *instruction)
647 {
648         /* Multiply (accumulate) (long) and Swap/swap byte */
649         if ((opcode & 0x000000f0) == 0x00000090)
650         {
651                 /* Multiply (accumulate) */
652                 if ((opcode & 0x0f800000) == 0x00000000)
653                 {
654                         u8 Rm, Rs, Rn, Rd, S;
655                         Rm = opcode & 0xf;
656                         Rs = (opcode & 0xf00) >> 8;
657                         Rn = (opcode & 0xf000) >> 12;
658                         Rd = (opcode & 0xf0000) >> 16;
659                         S = (opcode & 0x00100000) >> 20;
660                         
661                         /* examine A bit (accumulate) */
662                         if (opcode & 0x00200000)
663                         {
664                                 instruction->type = ARM_MLA;
665                                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMLA%s%s r%i, r%i, r%i, r%i",
666                                                 address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs, Rn);
667                         }
668                         else
669                         {
670                                 instruction->type = ARM_MUL;
671                                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMUL%s%s r%i, r%i, r%i",
672                                                  address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs);
673                         }
674                         
675                         return ERROR_OK;
676                 }
677                 
678                 /* Multiply (accumulate) long */
679                 if ((opcode & 0x0f800000) == 0x00800000)
680                 {
681                         char* mnemonic;
682                         u8 Rm, Rs, RdHi, RdLow, S;
683                         Rm = opcode & 0xf;
684                         Rs = (opcode & 0xf00) >> 8;
685                         RdHi = (opcode & 0xf000) >> 12;
686                         RdLow = (opcode & 0xf0000) >> 16;
687                         S = (opcode & 0x00100000) >> 20;
688                         
689                         switch ((opcode & 0x00600000) >> 21)
690                         {
691                                 case 0x0:
692                                         instruction->type = ARM_UMULL;
693                                         mnemonic = "UMULL";
694                                         break;
695                                 case 0x1:
696                                         instruction->type = ARM_UMLAL;
697                                         mnemonic = "UMLAL";
698                                         break;
699                                 case 0x2:
700                                         instruction->type = ARM_SMULL;
701                                         mnemonic = "SMULL";
702                                         break;
703                                 case 0x3:
704                                         instruction->type = ARM_SMLAL;
705                                         mnemonic = "SMLAL";
706                                         break;
707                         }
708                         
709                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, r%i, r%i, r%i",
710                                                 address, opcode, mnemonic, COND(opcode), (S) ? "S" : "",
711                                                 RdLow, RdHi, Rm, Rs);
712                         
713                         return ERROR_OK;
714                 }
715                 
716                 /* Swap/swap byte */
717                 if ((opcode & 0x0f800000) == 0x01000000)
718                 {
719                         u8 Rm, Rd, Rn;
720                         Rm = opcode & 0xf;
721                         Rd = (opcode & 0xf000) >> 12;
722                         Rn = (opcode & 0xf0000) >> 16;
723                         
724                         /* examine B flag */
725                         instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
726                         
727                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, r%i, [r%i]",
728                                          address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn);
729                         return ERROR_OK;
730                 }
731                 
732         }
733         
734         return evaluate_misc_load_store(opcode, address, instruction);
735 }
736
737 int evaluate_mrs_msr(u32 opcode, u32 address, arm_instruction_t *instruction)
738 {
739         int R = (opcode & 0x00400000) >> 22;
740         char *PSR = (R) ? "SPSR" : "CPSR";
741                 
742         /* Move register to status register (MSR) */
743         if (opcode & 0x00200000)
744         {
745                 instruction->type = ARM_MSR;
746                         
747                 /* immediate variant */
748                 if (opcode & 0x02000000)
749                 {
750                         u8 immediate = (opcode & 0xff);
751                         u8 rotate = (opcode & 0xf00);
752                         
753                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMSR%s %s_%s%s%s%s, 0x%8.8x",
754                                          address, opcode, COND(opcode), PSR,
755                                          (opcode & 0x10000) ? "c" : "",
756                                          (opcode & 0x20000) ? "x" : "",
757                                          (opcode & 0x40000) ? "s" : "",
758                                          (opcode & 0x80000) ? "f" : "",
759                                          ror(immediate, (rotate * 2))
760                                         );
761                 }
762                 else /* register variant */
763                 {
764                         u8 Rm = opcode & 0xf;
765                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMSR%s %s_%s%s%s%s, r%i",
766                                          address, opcode, COND(opcode), PSR,
767                                          (opcode & 0x10000) ? "c" : "",
768                                          (opcode & 0x20000) ? "x" : "",
769                                          (opcode & 0x40000) ? "s" : "",
770                                          (opcode & 0x80000) ? "f" : "",
771                                          Rm
772                                         );
773                 }
774                 
775         }
776         else /* Move status register to register (MRS) */
777         {
778                 u8 Rd;
779                 
780                 instruction->type = ARM_MRS;
781                 Rd = (opcode & 0x0000f000) >> 12;
782                         
783                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMRS%s r%i, %s",
784                                  address, opcode, COND(opcode), Rd, PSR);
785         }
786         
787         return ERROR_OK;
788 }
789
790 /* Miscellaneous instructions */
791 int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
792 {
793         /* MRS/MSR */
794         if ((opcode & 0x000000f0) == 0x00000000)
795         {
796                 evaluate_mrs_msr(opcode, address, instruction);
797         }
798         
799         /* BX */
800         if ((opcode & 0x006000f0) == 0x00200010)
801         {
802                 u8 Rm;
803                 instruction->type = ARM_BX;
804                 Rm = opcode & 0xf;
805                 
806                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBX%s r%i",
807                                  address, opcode, COND(opcode), Rm);
808                 
809                 instruction->info.b_bl_bx_blx.reg_operand = Rm;
810                 instruction->info.b_bl_bx_blx.target_address = -1;
811         }
812         
813         /* CLZ */
814         if ((opcode & 0x0060000f0) == 0x00300010)
815         {
816                 u8 Rm, Rd;
817                 instruction->type = ARM_CLZ;
818                 Rm = opcode & 0xf;
819                 Rd = (opcode & 0xf000) >> 12;
820
821                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tCLZ%s r%i, r%i",
822                                  address, opcode, COND(opcode), Rd, Rm);
823         }
824         
825         /* BLX */
826         if ((opcode & 0x0060000f0) == 0x00200030)
827         {
828                 u8 Rm;
829                 instruction->type = ARM_BLX;
830                 Rm = opcode & 0xf;
831                 
832                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBLX%s r%i",
833                                  address, opcode, COND(opcode), Rm);
834         }
835         
836         /* Enhanced DSP add/subtracts */
837         if ((opcode & 0x0000000f0) == 0x00000050)
838         {
839                 u8 Rm, Rd, Rn;
840                 char *mnemonic;
841                 Rm = opcode & 0xf;
842                 Rd = (opcode & 0xf000) >> 12;
843                 Rn = (opcode & 0xf0000) >> 16;
844                 
845                 switch ((opcode & 0x00600000) >> 21)
846                 {
847                         case 0x0:
848                                 instruction->type = ARM_QADD;
849                                 mnemonic = "QADD";
850                                 break;
851                         case 0x1:
852                                 instruction->type = ARM_QSUB;
853                                 mnemonic = "QSUB";
854                                 break;
855                         case 0x2:
856                                 instruction->type = ARM_QDADD;
857                                 mnemonic = "QDADD";
858                                 break;
859                         case 0x3:
860                                 instruction->type = ARM_QDSUB;
861                                 mnemonic = "QDSUB";
862                                 break;
863                 }
864                 
865                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, r%i, r%i",
866                                  address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn);
867         }
868         
869         /* Software breakpoints */
870         if ((opcode & 0x0000000f0) == 0x00000070)
871         {
872                 u32 immediate;
873                 instruction->type = ARM_BKPT;
874                 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
875                 
876                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBKPT 0x%4.4x",
877                                  address, opcode, immediate);   
878         }
879         
880         /* Enhanced DSP multiplies */
881         if ((opcode & 0x000000090) == 0x00000080)
882         {
883                 int x = (opcode & 0x20) >> 5;
884                 int y = (opcode & 0x40) >> 6;
885                 
886                 /* SMLA<x><y> */
887                 if ((opcode & 0x00600000) == 0x00000000)
888                 {
889                         u8 Rd, Rm, Rs, Rn;
890                         instruction->type = ARM_SMLAxy;
891                         Rd = (opcode & 0xf0000) >> 16;
892                         Rm = (opcode & 0xf);
893                         Rs = (opcode & 0xf00) >> 8;
894                         Rn = (opcode & 0xf000) >> 12;
895                         
896                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLA%s%s%s r%i, r%i, r%i, r%i",
897                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
898                                          Rd, Rm, Rs, Rn);
899                 }
900                 
901                 /* SMLAL<x><y> */
902                 if ((opcode & 0x00600000) == 0x00400000)
903                 {
904                         u8 RdLow, RdHi, Rm, Rs;
905                         instruction->type = ARM_SMLAxy;
906                         RdHi = (opcode & 0xf0000) >> 16;
907                         RdLow = (opcode & 0xf000) >> 12;
908                         Rm = (opcode & 0xf);
909                         Rs = (opcode & 0xf00) >> 8;
910                         
911                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLA%s%s%s r%i, r%i, r%i, r%i",
912                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
913                                          RdLow, RdHi, Rm, Rs);
914                 }
915                 
916                 /* SMLAW<y> */
917                 if (((opcode & 0x00600000) == 0x00100000) && (x == 0))
918                 {
919                         u8 Rd, Rm, Rs, Rn;
920                         instruction->type = ARM_SMLAWy;
921                         Rd = (opcode & 0xf0000) >> 16;
922                         Rm = (opcode & 0xf);
923                         Rs = (opcode & 0xf00) >> 8;
924                         Rn = (opcode & 0xf000) >> 12;
925
926                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLAW%s%s r%i, r%i, r%i, r%i",
927                                          address, opcode, (y) ? "T" : "B", COND(opcode),
928                                          Rd, Rm, Rs, Rn);
929                 }
930                 
931                 /* SMUL<x><y> */
932                 if ((opcode & 0x00600000) == 0x00300000)
933                 {
934                         u8 Rd, Rm, Rs;
935                         instruction->type = ARM_SMULxy;
936                         Rd = (opcode & 0xf0000) >> 16;
937                         Rm = (opcode & 0xf);
938                         Rs = (opcode & 0xf00) >> 8;
939                         
940                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMULW%s%s%s r%i, r%i, r%i",
941                                          address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
942                                          Rd, Rm, Rs);
943                 }
944                 
945                 /* SMULW<y> */
946                 if (((opcode & 0x00600000) == 0x00100000) && (x == 1))
947                 {
948                         u8 Rd, Rm, Rs;
949                         instruction->type = ARM_SMULWy;
950                         Rd = (opcode & 0xf0000) >> 16;
951                         Rm = (opcode & 0xf);
952                         Rs = (opcode & 0xf00) >> 8;
953                         
954                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMULW%s%s r%i, r%i, r%i",
955                                          address, opcode, (y) ? "T" : "B", COND(opcode),
956                                          Rd, Rm, Rs);
957                 }
958         }
959         
960         return ERROR_OK;
961 }
962
963 int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction)
964 {
965         u8 I, op, S, Rn, Rd;
966         char *mnemonic;
967         char shifter_operand[32];
968         
969         I = (opcode & 0x02000000) >> 25;
970         op = (opcode & 0x01e00000) >> 21;
971         S = (opcode & 0x00100000) >> 20;
972         
973         Rd = (opcode & 0xf000) >> 12;
974         Rn = (opcode & 0xf0000) >> 16;
975         
976         instruction->info.data_proc.Rd = Rd;
977         instruction->info.data_proc.Rn = Rn;
978         instruction->info.data_proc.S = S;
979
980         switch (op)
981         {
982                 case 0x0:
983                         instruction->type = ARM_AND;
984                         mnemonic = "AND";
985                         break;
986                 case 0x1:
987                         instruction->type = ARM_EOR;
988                         mnemonic = "EOR";
989                         break;
990                 case 0x2:
991                         instruction->type = ARM_SUB;
992                         mnemonic = "SUB";
993                         break;
994                 case 0x3:
995                         instruction->type = ARM_RSB;
996                         mnemonic = "RSB";
997                         break;
998                 case 0x4:
999                         instruction->type = ARM_ADD;
1000                         mnemonic = "ADD";
1001                         break;
1002                 case 0x5:
1003                         instruction->type = ARM_ADC;
1004                         mnemonic = "ADC";
1005                         break;
1006                 case 0x6:
1007                         instruction->type = ARM_SBC;
1008                         mnemonic = "SBC";
1009                         break;
1010                 case 0x7:
1011                         instruction->type = ARM_RSC;
1012                         mnemonic = "RSC";
1013                         break;
1014                 case 0x8:
1015                         instruction->type = ARM_TST;
1016                         mnemonic = "TST";
1017                         break;
1018                 case 0x9:
1019                         instruction->type = ARM_TEQ;
1020                         mnemonic = "TEQ";
1021                         break;
1022                 case 0xa:
1023                         instruction->type = ARM_CMP;
1024                         mnemonic = "CMP";
1025                         break;
1026                 case 0xb:
1027                         instruction->type = ARM_CMN;
1028                         mnemonic = "CMN";
1029                         break;
1030                 case 0xc:
1031                         instruction->type = ARM_ORR;
1032                         mnemonic = "ORR";
1033                         break;
1034                 case 0xd:
1035                         instruction->type = ARM_MOV;
1036                         mnemonic = "MOV";
1037                         break;
1038                 case 0xe:
1039                         instruction->type = ARM_BIC;
1040                         mnemonic = "BIC";
1041                         break;
1042                 case 0xf:
1043                         instruction->type = ARM_MVN;
1044                         mnemonic = "MVN";
1045                         break;
1046         }
1047         
1048         if (I) /* immediate shifter operand (#<immediate>)*/
1049         {
1050                 u8 immed_8 = opcode & 0xff;
1051                 u8 rotate_imm = (opcode & 0xf00) >> 8;
1052                 u32 immediate;
1053                 
1054                 immediate = ror(immed_8, rotate_imm * 2);
1055                 
1056                 snprintf(shifter_operand, 32, "#0x%x", immediate);
1057                 
1058                 instruction->info.data_proc.variant = 0;
1059                 instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
1060         }
1061         else /* register-based shifter operand */
1062         {
1063                 u8 shift, Rm;
1064                 shift = (opcode & 0x60) >> 5;
1065                 Rm = (opcode & 0xf);
1066                 
1067                 if ((opcode & 0x10) != 0x10) /* Immediate shifts ("<Rm>" or "<Rm>, <shift> #<shift_immediate>") */
1068                 {
1069                         u8 shift_imm;
1070                         shift_imm = (opcode & 0xf80) >> 7;
1071
1072                         instruction->info.data_proc.variant = 1;
1073                         instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1074                         instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm;
1075                         instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
1076                 
1077                         if ((shift_imm == 0x0) && (shift == 0x0))
1078                         {
1079                                 snprintf(shifter_operand, 32, "r%i", Rm);
1080                         }
1081                         else
1082                         {
1083                                 if (shift == 0x0) /* LSL */
1084                                 {
1085                                         snprintf(shifter_operand, 32, "r%i, LSL #0x%x", Rm, shift_imm);
1086                                 }
1087                                 else if (shift == 0x1) /* LSR */
1088                                 {
1089                                         if (shift_imm == 0x0)
1090                                                 shift_imm = 0x32;
1091                                         snprintf(shifter_operand, 32, "r%i, LSR #0x%x", Rm, shift_imm);
1092                                 }
1093                                 else if (shift == 0x2) /* ASR */
1094                                 {
1095                                         if (shift_imm == 0x0)
1096                                                 shift_imm = 0x32;
1097                                         snprintf(shifter_operand, 32, "r%i, ASR #0x%x", Rm, shift_imm);
1098                                 }
1099                                 else if (shift == 0x3) /* ROR or RRX */
1100                                 {
1101                                         if (shift_imm == 0x0) /* RRX */
1102                                                 snprintf(shifter_operand, 32, "r%i, RRX", Rm);
1103                                         else
1104                                                 snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm);
1105                                 }
1106                         }
1107                 }
1108                 else /* Register shifts ("<Rm>, <shift> <Rs>") */
1109                 {
1110                         u8 Rs = (opcode & 0xf00) >> 8;
1111                         
1112                         instruction->info.data_proc.variant = 2;
1113                         instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
1114                         instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
1115                         instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
1116                         
1117                         if (shift == 0x0) /* LSL */
1118                         {
1119                                 snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
1120                         }
1121                         else if (shift == 0x1) /* LSR */
1122                         {
1123                                 snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
1124                         }
1125                         else if (shift == 0x2) /* ASR */
1126                         {
1127                                 snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
1128                         }
1129                         else if (shift == 0x3) /* ROR or RRX */
1130                         {
1131                                 snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
1132                         }
1133                 }
1134         }
1135         
1136         if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand> */
1137         {
1138                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, r%i, %s",
1139                                  address, opcode, mnemonic, COND(opcode),
1140                                  (S) ? "S" : "", Rd, Rn, shifter_operand);
1141         }
1142         else if ((op == 0xd) || (op == 0xf)) /* <opcode1>{<cond>}{S} <Rd>, <shifter_operand> */
1143         {
1144                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, %s",
1145                                  address, opcode, mnemonic, COND(opcode),
1146                                  (S) ? "S" : "", Rd, shifter_operand);
1147         }
1148         else /* <opcode2>{<cond>} <Rn>, <shifter_operand> */
1149         {
1150                 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, %s",
1151                                  address, opcode, mnemonic, COND(opcode),
1152                                  Rn, shifter_operand);
1153         }
1154         
1155         return ERROR_OK;
1156 }
1157                 
1158 int evaluate_opcode(u32 opcode, u32 address, arm_instruction_t *instruction)
1159 {
1160         /* clear fields, to avoid confusion */
1161         bzero(instruction, sizeof(arm_instruction_t));
1162         instruction->opcode = opcode;
1163         
1164         /* catch opcodes with condition field [31:28] = b1111 */
1165         if ((opcode & 0xf0000000) == 0xf0000000)
1166         {
1167                 /* Undefined instruction (or ARMv5E cache preload PLD) */
1168                 if ((opcode & 0x08000000) == 0x00000000)
1169                         return evaluate_pld(opcode, address, instruction);
1170                 
1171                 /* Undefined instruction */
1172                 if ((opcode & 0x0e000000) == 0x08000000)
1173                 {
1174                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1175                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
1176                         return ERROR_OK;
1177                 }
1178                 
1179                 /* Branch and branch with link and change to Thumb */
1180                 if ((opcode & 0x0e000000) == 0x0a000000)
1181                         return evaluate_blx_imm(opcode, address, instruction);
1182                 
1183                 /* Extended coprocessor opcode space (ARMv5 and higher )*/
1184                 /* Coprocessor load/store and double register transfers */
1185                 if ((opcode & 0x0e000000) == 0x0c000000)
1186                         return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1187                 
1188                 /* Coprocessor data processing */
1189                 if ((opcode & 0x0f000100) == 0x0c000000)
1190                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1191                 
1192                 /* Coprocessor register transfers */
1193                 if ((opcode & 0x0f000010) == 0x0c000010)
1194                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1195                 
1196                 /* Undefined instruction */
1197                 if ((opcode & 0x0f000000) == 0x0f000000)
1198                 {
1199                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1200                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
1201                         return ERROR_OK;
1202                 }
1203         }
1204         
1205         /* catch opcodes with [27:25] = b000 */
1206         if ((opcode & 0x0e000000) == 0x00000000)
1207         {
1208                 /* Multiplies, extra load/stores */
1209                 if ((opcode & 0x00000090) == 0x00000090)
1210                         return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
1211                 
1212                 /* Miscellaneous instructions */
1213                 if ((opcode & 0x0f900000) == 0x01000000)
1214                         return evaluate_misc_instr(opcode, address, instruction);
1215                 
1216                 return evaluate_data_proc(opcode, address, instruction);
1217         }
1218         
1219         /* catch opcodes with [27:25] = b001 */
1220         if ((opcode & 0x0e000000) == 0x02000000)
1221         {
1222                 /* Undefined instruction */
1223                 if ((opcode & 0x0fb00000) == 0x03000000)
1224                 {
1225                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1226                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
1227                         return ERROR_OK;
1228                 }
1229                                 
1230                 /* Move immediate to status register */
1231                 if ((opcode & 0x0fb00000) == 0x03200000)
1232                         return evaluate_mrs_msr(opcode, address, instruction);
1233                 
1234                 return evaluate_data_proc(opcode, address, instruction);
1235
1236         }
1237         
1238         /* catch opcodes with [27:25] = b010 */
1239         if ((opcode & 0x0e000000) == 0x04000000)
1240         {
1241                 /* Load/store immediate offset */
1242                 return evaluate_load_store(opcode, address, instruction);
1243         }
1244         
1245         /* catch opcodes with [27:25] = b011 */
1246         if ((opcode & 0x0e000000) == 0x04000000)
1247         {
1248                 /* Undefined instruction */
1249                 if ((opcode & 0x00000010) == 0x00000010)
1250                 {
1251                         instruction->type = ARM_UNDEFINED_INSTRUCTION;
1252                         snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
1253                         return ERROR_OK;
1254                 }
1255                 
1256                 /* Load/store register offset */
1257                 return evaluate_load_store(opcode, address, instruction);
1258
1259         }
1260         
1261         /* catch opcodes with [27:25] = b100 */
1262         if ((opcode & 0x0e000000) == 0x08000000)
1263         {
1264                 /* Load/store multiple */
1265                 return evaluate_ldm_stm(opcode, address, instruction);
1266         }
1267         
1268         /* catch opcodes with [27:25] = b101 */
1269         if ((opcode & 0x0e000000) == 0x0a000000)
1270         {
1271                 /* Branch and branch with link */
1272                 return evaluate_b_bl(opcode, address, instruction);
1273         }
1274         
1275         /* catch opcodes with [27:25] = b110 */
1276         if ((opcode & 0x0e000000) == 0x0a000000)
1277         {
1278                 /* Coprocessor load/store and double register transfers */
1279                 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1280         }
1281         
1282         /* catch opcodes with [27:25] = b111 */
1283         if ((opcode & 0x0e000000) == 0x0e000000)
1284         {
1285                 /* Software interrupt */
1286                 if ((opcode & 0x0f000000) == 0x0f000000)
1287                         return evaluate_swi(opcode, address, instruction);
1288                 
1289                 /* Coprocessor data processing */
1290                 if ((opcode & 0x0f000010) == 0x0e000000)
1291                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1292                 
1293                 /* Coprocessor register transfers */
1294                 if ((opcode & 0x0f000010) == 0x0e000010)
1295                         return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1296         }
1297         
1298         ERROR("should never reach this point");
1299         return -1;
1300 }