- Fixes '[<>]' whitespace
[openocd.git] / 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 }