Convert to non-recursive make
[openocd.git] / src / target / arm_disassembler.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2009 by David Brownell *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "target.h"
26 #include "arm_disassembler.h"
27 #include <helper/log.h>
28
29 /*
30 * This disassembler supports two main functions for OpenOCD:
31 *
32 * - Various "disassemble" commands. OpenOCD can serve as a
33 * machine-language debugger, without help from GDB.
34 *
35 * - Single stepping. Not all ARM cores support hardware single
36 * stepping. To work without that support, the debugger must
37 * be able to decode instructions to find out where to put a
38 * "next instruction" breakpoint.
39 *
40 * In addition, interpretation of ETM trace data needs some of the
41 * decoding mechanisms.
42 *
43 * At this writing (September 2009) neither function is complete.
44 *
45 * - ARM decoding
46 * * Old-style syntax (not UAL) is generally used
47 * * VFP instructions are not understood (ARMv5 and later)
48 * except as coprocessor 10/11 operations
49 * * Most ARM instructions through ARMv6 are decoded, but some
50 * of the post-ARMv4 opcodes may not be handled yet
51 * CPS, SDIV, UDIV, LDREX*, STREX*, QASX, ...
52 * * NEON instructions are not understood (ARMv7-A)
53 *
54 * - Thumb/Thumb2 decoding
55 * * UAL syntax should be consistently used
56 * * Any Thumb2 instructions used in Cortex-M3 (ARMv7-M) should
57 * be handled properly. Accordingly, so should the subset
58 * used in Cortex-M0/M1; and "original" 16-bit Thumb from
59 * ARMv4T and ARMv5T.
60 * * Conditional effects of Thumb2 "IT" (if-then) instructions
61 * are not handled: the affected instructions are not shown
62 * with their now-conditional suffixes.
63 * * Some ARMv6 and ARMv7-M Thumb2 instructions may not be
64 * handled (minimally for coprocessor access).
65 * * SIMD instructions, and some other Thumb2 instructions
66 * from ARMv7-A, are not understood.
67 *
68 * - ThumbEE decoding
69 * * As a Thumb2 variant, the Thumb2 comments (above) apply.
70 * * Opcodes changed by ThumbEE mode are not handled; these
71 * instructions wrongly decode as LDM and STM.
72 *
73 * - Jazelle decoding ... no support whatsoever for Jazelle mode
74 * or decoding. ARM encourages use of the more generic ThumbEE
75 * mode, instead of Jazelle mode, in current chips.
76 *
77 * - Single-step/emulation ... spotty support, which is only weakly
78 * tested. Thumb2 is not supported. (Arguably a full simulator
79 * is not needed to support just single stepping. Recognizing
80 * branch vs non-branch instructions suffices, except when the
81 * instruction faults and triggers a synchronous exception which
82 * can be intercepted using other means.)
83 *
84 * ARM DDI 0406B "ARM Architecture Reference Manual, ARM v7-A and
85 * ARM v7-R edition" gives the most complete coverage of the various
86 * generations of ARM instructions. At this writing it is publicly
87 * accessible to anyone willing to create an account at the ARM
88 * web site; see http://www.arm.com/documentation/ for information.
89 *
90 * ARM DDI 0403C "ARMv7-M Architecture Reference Manual" provides
91 * more details relevant to the Thumb2-only processors (such as
92 * the Cortex-M implementations).
93 */
94
95 /* textual represenation of the condition field
96 * ALways (default) is ommitted (empty string) */
97 static const char *arm_condition_strings[] = {
98 "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
99 };
100
101 /* make up for C's missing ROR */
102 static uint32_t ror(uint32_t value, int places)
103 {
104 return (value >> places) | (value << (32 - places));
105 }
106
107 static int evaluate_unknown(uint32_t opcode,
108 uint32_t address, struct arm_instruction *instruction)
109 {
110 instruction->type = ARM_UNDEFINED_INSTRUCTION;
111 snprintf(instruction->text, 128,
112 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
113 "\tUNDEFINED INSTRUCTION", address, opcode);
114 return ERROR_OK;
115 }
116
117 static int evaluate_pld(uint32_t opcode,
118 uint32_t address, struct arm_instruction *instruction)
119 {
120 /* PLD */
121 if ((opcode & 0x0d70f000) == 0x0550f000) {
122 instruction->type = ARM_PLD;
123
124 snprintf(instruction->text,
125 128,
126 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...",
127 address,
128 opcode);
129
130 return ERROR_OK;
131 }
132 return evaluate_unknown(opcode, address, instruction);
133 }
134
135 static int evaluate_srs(uint32_t opcode,
136 uint32_t address, struct arm_instruction *instruction)
137 {
138 const char *wback = (opcode & (1 << 21)) ? "!" : "";
139 const char *mode = "";
140
141 switch ((opcode >> 23) & 0x3) {
142 case 0:
143 mode = "DA";
144 break;
145 case 1:
146 /* "IA" is default */
147 break;
148 case 2:
149 mode = "DB";
150 break;
151 case 3:
152 mode = "IB";
153 break;
154 }
155
156 switch (opcode & 0x0e500000) {
157 case 0x08400000:
158 snprintf(instruction->text, 128, "0x%8.8" PRIx32
159 "\t0x%8.8" PRIx32
160 "\tSRS%s\tSP%s, #%d",
161 address, opcode,
162 mode, wback,
163 (unsigned)(opcode & 0x1f));
164 break;
165 case 0x08100000:
166 snprintf(instruction->text, 128, "0x%8.8" PRIx32
167 "\t0x%8.8" PRIx32
168 "\tRFE%s\tr%d%s",
169 address, opcode,
170 mode,
171 (unsigned)((opcode >> 16) & 0xf), wback);
172 break;
173 default:
174 return evaluate_unknown(opcode, address, instruction);
175 }
176 return ERROR_OK;
177 }
178
179 static int evaluate_swi(uint32_t opcode,
180 uint32_t address, struct arm_instruction *instruction)
181 {
182 instruction->type = ARM_SWI;
183
184 snprintf(instruction->text, 128,
185 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSVC %#6.6" PRIx32,
186 address, opcode, (opcode & 0xffffff));
187
188 return ERROR_OK;
189 }
190
191 static int evaluate_blx_imm(uint32_t opcode,
192 uint32_t address, struct arm_instruction *instruction)
193 {
194 int offset;
195 uint32_t immediate;
196 uint32_t target_address;
197
198 instruction->type = ARM_BLX;
199 immediate = opcode & 0x00ffffff;
200
201 /* sign extend 24-bit immediate */
202 if (immediate & 0x00800000)
203 offset = 0xff000000 | immediate;
204 else
205 offset = immediate;
206
207 /* shift two bits left */
208 offset <<= 2;
209
210 /* odd/event halfword */
211 if (opcode & 0x01000000)
212 offset |= 0x2;
213
214 target_address = address + 8 + offset;
215
216 snprintf(instruction->text,
217 128,
218 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "",
219 address,
220 opcode,
221 target_address);
222
223 instruction->info.b_bl_bx_blx.reg_operand = -1;
224 instruction->info.b_bl_bx_blx.target_address = target_address;
225
226 return ERROR_OK;
227 }
228
229 static int evaluate_b_bl(uint32_t opcode,
230 uint32_t address, struct arm_instruction *instruction)
231 {
232 uint8_t L;
233 uint32_t immediate;
234 int offset;
235 uint32_t target_address;
236
237 immediate = opcode & 0x00ffffff;
238 L = (opcode & 0x01000000) >> 24;
239
240 /* sign extend 24-bit immediate */
241 if (immediate & 0x00800000)
242 offset = 0xff000000 | immediate;
243 else
244 offset = immediate;
245
246 /* shift two bits left */
247 offset <<= 2;
248
249 target_address = address + 8 + offset;
250
251 if (L)
252 instruction->type = ARM_BL;
253 else
254 instruction->type = ARM_B;
255
256 snprintf(instruction->text,
257 128,
258 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32,
259 address,
260 opcode,
261 (L) ? "L" : "",
262 COND(opcode),
263 target_address);
264
265 instruction->info.b_bl_bx_blx.reg_operand = -1;
266 instruction->info.b_bl_bx_blx.target_address = target_address;
267
268 return ERROR_OK;
269 }
270
271 /* Coprocessor load/store and double register transfers
272 * both normal and extended instruction space (condition field b1111) */
273 static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
274 uint32_t address, struct arm_instruction *instruction)
275 {
276 uint8_t cp_num = (opcode & 0xf00) >> 8;
277
278 /* MCRR or MRRC */
279 if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c500000)) {
280 uint8_t cp_opcode, Rd, Rn, CRm;
281 char *mnemonic;
282
283 cp_opcode = (opcode & 0xf0) >> 4;
284 Rd = (opcode & 0xf000) >> 12;
285 Rn = (opcode & 0xf0000) >> 16;
286 CRm = (opcode & 0xf);
287
288 /* MCRR */
289 if ((opcode & 0x0ff00000) == 0x0c400000) {
290 instruction->type = ARM_MCRR;
291 mnemonic = "MCRR";
292 } else if ((opcode & 0x0ff00000) == 0x0c500000) {
293 /* MRRC */
294 instruction->type = ARM_MRRC;
295 mnemonic = "MRRC";
296 } else {
297 LOG_ERROR("Unknown instruction");
298 return ERROR_FAIL;
299 }
300
301 snprintf(instruction->text, 128,
302 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
303 "\t%s%s%s p%i, %x, r%i, r%i, c%i",
304 address, opcode, mnemonic,
305 ((opcode & 0xf0000000) == 0xf0000000)
306 ? "2" : COND(opcode),
307 COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
308 } else {/* LDC or STC */
309 uint8_t CRd, Rn, offset;
310 uint8_t U;
311 char *mnemonic;
312 char addressing_mode[32];
313
314 CRd = (opcode & 0xf000) >> 12;
315 Rn = (opcode & 0xf0000) >> 16;
316 offset = (opcode & 0xff) << 2;
317
318 /* load/store */
319 if (opcode & 0x00100000) {
320 instruction->type = ARM_LDC;
321 mnemonic = "LDC";
322 } else {
323 instruction->type = ARM_STC;
324 mnemonic = "STC";
325 }
326
327 U = (opcode & 0x00800000) >> 23;
328
329 /* addressing modes */
330 if ((opcode & 0x01200000) == 0x01000000)/* offset */
331 snprintf(addressing_mode, 32, "[r%i, #%s%d]",
332 Rn, U ? "" : "-", offset);
333 else if ((opcode & 0x01200000) == 0x01200000) /* pre-indexed */
334 snprintf(addressing_mode, 32, "[r%i, #%s%d]!",
335 Rn, U ? "" : "-", offset);
336 else if ((opcode & 0x01200000) == 0x00200000) /* post-indexed */
337 snprintf(addressing_mode, 32, "[r%i], #%s%d",
338 Rn, U ? "" : "-", offset);
339 else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
340 snprintf(addressing_mode, 32, "[r%i], {%d}",
341 Rn, offset >> 2);
342
343 snprintf(instruction->text, 128, "0x%8.8" PRIx32
344 "\t0x%8.8" PRIx32
345 "\t%s%s%s p%i, c%i, %s",
346 address, opcode, mnemonic,
347 ((opcode & 0xf0000000) == 0xf0000000)
348 ? "2" : COND(opcode),
349 (opcode & (1 << 22)) ? "L" : "",
350 cp_num, CRd, addressing_mode);
351 }
352
353 return ERROR_OK;
354 }
355
356 /* Coprocessor data processing instructions
357 * Coprocessor register transfer instructions
358 * both normal and extended instruction space (condition field b1111) */
359 static int evaluate_cdp_mcr_mrc(uint32_t opcode,
360 uint32_t address, struct arm_instruction *instruction)
361 {
362 const char *cond;
363 char *mnemonic;
364 uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
365
366 cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
367 cp_num = (opcode & 0xf00) >> 8;
368 CRd_Rd = (opcode & 0xf000) >> 12;
369 CRn = (opcode & 0xf0000) >> 16;
370 CRm = (opcode & 0xf);
371 opcode_2 = (opcode & 0xe0) >> 5;
372
373 /* CDP or MRC/MCR */
374 if (opcode & 0x00000010) { /* bit 4 set -> MRC/MCR */
375 if (opcode & 0x00100000) { /* bit 20 set -> MRC */
376 instruction->type = ARM_MRC;
377 mnemonic = "MRC";
378 } else {/* bit 20 not set -> MCR */
379 instruction->type = ARM_MCR;
380 mnemonic = "MCR";
381 }
382
383 opcode_1 = (opcode & 0x00e00000) >> 21;
384
385 snprintf(instruction->text,
386 128,
387 "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",
388 address,
389 opcode,
390 mnemonic,
391 cond,
392 cp_num,
393 opcode_1,
394 CRd_Rd,
395 CRn,
396 CRm,
397 opcode_2);
398 } else {/* bit 4 not set -> CDP */
399 instruction->type = ARM_CDP;
400 mnemonic = "CDP";
401
402 opcode_1 = (opcode & 0x00f00000) >> 20;
403
404 snprintf(instruction->text,
405 128,
406 "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",
407 address,
408 opcode,
409 mnemonic,
410 cond,
411 cp_num,
412 opcode_1,
413 CRd_Rd,
414 CRn,
415 CRm,
416 opcode_2);
417 }
418
419 return ERROR_OK;
420 }
421
422 /* Load/store instructions */
423 static int evaluate_load_store(uint32_t opcode,
424 uint32_t address, struct arm_instruction *instruction)
425 {
426 uint8_t I, P, U, B, W, L;
427 uint8_t Rn, Rd;
428 char *operation;/* "LDR" or "STR" */
429 char *suffix; /* "", "B", "T", "BT" */
430 char offset[32];
431
432 /* examine flags */
433 I = (opcode & 0x02000000) >> 25;
434 P = (opcode & 0x01000000) >> 24;
435 U = (opcode & 0x00800000) >> 23;
436 B = (opcode & 0x00400000) >> 22;
437 W = (opcode & 0x00200000) >> 21;
438 L = (opcode & 0x00100000) >> 20;
439
440 /* target register */
441 Rd = (opcode & 0xf000) >> 12;
442
443 /* base register */
444 Rn = (opcode & 0xf0000) >> 16;
445
446 instruction->info.load_store.Rd = Rd;
447 instruction->info.load_store.Rn = Rn;
448 instruction->info.load_store.U = U;
449
450 /* determine operation */
451 if (L)
452 operation = "LDR";
453 else
454 operation = "STR";
455
456 /* determine instruction type and suffix */
457 if (B) {
458 if ((P == 0) && (W == 1)) {
459 if (L)
460 instruction->type = ARM_LDRBT;
461 else
462 instruction->type = ARM_STRBT;
463 suffix = "BT";
464 } else {
465 if (L)
466 instruction->type = ARM_LDRB;
467 else
468 instruction->type = ARM_STRB;
469 suffix = "B";
470 }
471 } else {
472 if ((P == 0) && (W == 1)) {
473 if (L)
474 instruction->type = ARM_LDRT;
475 else
476 instruction->type = ARM_STRT;
477 suffix = "T";
478 } else {
479 if (L)
480 instruction->type = ARM_LDR;
481 else
482 instruction->type = ARM_STR;
483 suffix = "";
484 }
485 }
486
487 if (!I) { /* #+-<offset_12> */
488 uint32_t offset_12 = (opcode & 0xfff);
489 if (offset_12)
490 snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
491 else
492 snprintf(offset, 32, "%s", "");
493
494 instruction->info.load_store.offset_mode = 0;
495 instruction->info.load_store.offset.offset = offset_12;
496 } else {/* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
497 uint8_t shift_imm, shift;
498 uint8_t Rm;
499
500 shift_imm = (opcode & 0xf80) >> 7;
501 shift = (opcode & 0x60) >> 5;
502 Rm = (opcode & 0xf);
503
504 /* LSR encodes a shift by 32 bit as 0x0 */
505 if ((shift == 0x1) && (shift_imm == 0x0))
506 shift_imm = 0x20;
507
508 /* ASR encodes a shift by 32 bit as 0x0 */
509 if ((shift == 0x2) && (shift_imm == 0x0))
510 shift_imm = 0x20;
511
512 /* ROR by 32 bit is actually a RRX */
513 if ((shift == 0x3) && (shift_imm == 0x0))
514 shift = 0x4;
515
516 instruction->info.load_store.offset_mode = 1;
517 instruction->info.load_store.offset.reg.Rm = Rm;
518 instruction->info.load_store.offset.reg.shift = shift;
519 instruction->info.load_store.offset.reg.shift_imm = shift_imm;
520
521 if ((shift_imm == 0x0) && (shift == 0x0)) /* +-<Rm> */
522 snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm);
523 else { /* +-<Rm>, <Shift>, #<shift_imm> */
524 switch (shift) {
525 case 0x0: /* LSL */
526 snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
527 break;
528 case 0x1: /* LSR */
529 snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
530 break;
531 case 0x2: /* ASR */
532 snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
533 break;
534 case 0x3: /* ROR */
535 snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
536 break;
537 case 0x4: /* RRX */
538 snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm);
539 break;
540 }
541 }
542 }
543
544 if (P == 1) {
545 if (W == 0) { /* offset */
546 snprintf(instruction->text,
547 128,
548 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
549 address,
550 opcode,
551 operation,
552 COND(opcode),
553 suffix,
554 Rd,
555 Rn,
556 offset);
557
558 instruction->info.load_store.index_mode = 0;
559 } else {/* pre-indexed */
560 snprintf(instruction->text,
561 128,
562 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
563 address,
564 opcode,
565 operation,
566 COND(opcode),
567 suffix,
568 Rd,
569 Rn,
570 offset);
571
572 instruction->info.load_store.index_mode = 1;
573 }
574 } else {/* post-indexed */
575 snprintf(instruction->text,
576 128,
577 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
578 address,
579 opcode,
580 operation,
581 COND(opcode),
582 suffix,
583 Rd,
584 Rn,
585 offset);
586
587 instruction->info.load_store.index_mode = 2;
588 }
589
590 return ERROR_OK;
591 }
592
593 static int evaluate_extend(uint32_t opcode, uint32_t address, char *cp)
594 {
595 unsigned rm = (opcode >> 0) & 0xf;
596 unsigned rd = (opcode >> 12) & 0xf;
597 unsigned rn = (opcode >> 16) & 0xf;
598 char *type, *rot;
599
600 switch ((opcode >> 24) & 0x3) {
601 case 0:
602 type = "B16";
603 break;
604 case 1:
605 sprintf(cp, "UNDEFINED");
606 return ARM_UNDEFINED_INSTRUCTION;
607 case 2:
608 type = "B";
609 break;
610 default:
611 type = "H";
612 break;
613 }
614
615 switch ((opcode >> 10) & 0x3) {
616 case 0:
617 rot = "";
618 break;
619 case 1:
620 rot = ", ROR #8";
621 break;
622 case 2:
623 rot = ", ROR #16";
624 break;
625 default:
626 rot = ", ROR #24";
627 break;
628 }
629
630 if (rn == 0xf) {
631 sprintf(cp, "%cXT%s%s\tr%d, r%d%s",
632 (opcode & (1 << 22)) ? 'U' : 'S',
633 type, COND(opcode),
634 rd, rm, rot);
635 return ARM_MOV;
636 } else {
637 sprintf(cp, "%cXTA%s%s\tr%d, r%d, r%d%s",
638 (opcode & (1 << 22)) ? 'U' : 'S',
639 type, COND(opcode),
640 rd, rn, rm, rot);
641 return ARM_ADD;
642 }
643 }
644
645 static int evaluate_p_add_sub(uint32_t opcode, uint32_t address, char *cp)
646 {
647 char *prefix;
648 char *op;
649 int type;
650
651 switch ((opcode >> 20) & 0x7) {
652 case 1:
653 prefix = "S";
654 break;
655 case 2:
656 prefix = "Q";
657 break;
658 case 3:
659 prefix = "SH";
660 break;
661 case 5:
662 prefix = "U";
663 break;
664 case 6:
665 prefix = "UQ";
666 break;
667 case 7:
668 prefix = "UH";
669 break;
670 default:
671 goto undef;
672 }
673
674 switch ((opcode >> 5) & 0x7) {
675 case 0:
676 op = "ADD16";
677 type = ARM_ADD;
678 break;
679 case 1:
680 op = "ADDSUBX";
681 type = ARM_ADD;
682 break;
683 case 2:
684 op = "SUBADDX";
685 type = ARM_SUB;
686 break;
687 case 3:
688 op = "SUB16";
689 type = ARM_SUB;
690 break;
691 case 4:
692 op = "ADD8";
693 type = ARM_ADD;
694 break;
695 case 7:
696 op = "SUB8";
697 type = ARM_SUB;
698 break;
699 default:
700 goto undef;
701 }
702
703 sprintf(cp, "%s%s%s\tr%d, r%d, r%d", prefix, op, COND(opcode),
704 (int) (opcode >> 12) & 0xf,
705 (int) (opcode >> 16) & 0xf,
706 (int) (opcode >> 0) & 0xf);
707 return type;
708
709 undef:
710 /* these opcodes might be used someday */
711 sprintf(cp, "UNDEFINED");
712 return ARM_UNDEFINED_INSTRUCTION;
713 }
714
715 /* ARMv6 and later support "media" instructions (includes SIMD) */
716 static int evaluate_media(uint32_t opcode, uint32_t address,
717 struct arm_instruction *instruction)
718 {
719 char *cp = instruction->text;
720 char *mnemonic = NULL;
721
722 sprintf(cp,
723 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t",
724 address, opcode);
725 cp = strchr(cp, 0);
726
727 /* parallel add/subtract */
728 if ((opcode & 0x01800000) == 0x00000000) {
729 instruction->type = evaluate_p_add_sub(opcode, address, cp);
730 return ERROR_OK;
731 }
732
733 /* halfword pack */
734 if ((opcode & 0x01f00020) == 0x00800000) {
735 char *type, *shift;
736 unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
737
738 if (opcode & (1 << 6)) {
739 type = "TB";
740 shift = "ASR";
741 if (imm == 0)
742 imm = 32;
743 } else {
744 type = "BT";
745 shift = "LSL";
746 }
747 sprintf(cp, "PKH%s%s\tr%d, r%d, r%d, %s #%d",
748 type, COND(opcode),
749 (int) (opcode >> 12) & 0xf,
750 (int) (opcode >> 16) & 0xf,
751 (int) (opcode >> 0) & 0xf,
752 shift, imm);
753 return ERROR_OK;
754 }
755
756 /* word saturate */
757 if ((opcode & 0x01a00020) == 0x00a00000) {
758 char *shift;
759 unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
760
761 if (opcode & (1 << 6)) {
762 shift = "ASR";
763 if (imm == 0)
764 imm = 32;
765 } else
766 shift = "LSL";
767
768 sprintf(cp, "%cSAT%s\tr%d, #%d, r%d, %s #%d",
769 (opcode & (1 << 22)) ? 'U' : 'S',
770 COND(opcode),
771 (int) (opcode >> 12) & 0xf,
772 (int) (opcode >> 16) & 0x1f,
773 (int) (opcode >> 0) & 0xf,
774 shift, imm);
775 return ERROR_OK;
776 }
777
778 /* sign extension */
779 if ((opcode & 0x018000f0) == 0x00800070) {
780 instruction->type = evaluate_extend(opcode, address, cp);
781 return ERROR_OK;
782 }
783
784 /* multiplies */
785 if ((opcode & 0x01f00080) == 0x01000000) {
786 unsigned rn = (opcode >> 12) & 0xf;
787
788 if (rn != 0xf)
789 sprintf(cp, "SML%cD%s%s\tr%d, r%d, r%d, r%d",
790 (opcode & (1 << 6)) ? 'S' : 'A',
791 (opcode & (1 << 5)) ? "X" : "",
792 COND(opcode),
793 (int) (opcode >> 16) & 0xf,
794 (int) (opcode >> 0) & 0xf,
795 (int) (opcode >> 8) & 0xf,
796 rn);
797 else
798 sprintf(cp, "SMU%cD%s%s\tr%d, r%d, r%d",
799 (opcode & (1 << 6)) ? 'S' : 'A',
800 (opcode & (1 << 5)) ? "X" : "",
801 COND(opcode),
802 (int) (opcode >> 16) & 0xf,
803 (int) (opcode >> 0) & 0xf,
804 (int) (opcode >> 8) & 0xf);
805 return ERROR_OK;
806 }
807 if ((opcode & 0x01f00000) == 0x01400000) {
808 sprintf(cp, "SML%cLD%s%s\tr%d, r%d, r%d, r%d",
809 (opcode & (1 << 6)) ? 'S' : 'A',
810 (opcode & (1 << 5)) ? "X" : "",
811 COND(opcode),
812 (int) (opcode >> 12) & 0xf,
813 (int) (opcode >> 16) & 0xf,
814 (int) (opcode >> 0) & 0xf,
815 (int) (opcode >> 8) & 0xf);
816 return ERROR_OK;
817 }
818 if ((opcode & 0x01f00000) == 0x01500000) {
819 unsigned rn = (opcode >> 12) & 0xf;
820
821 switch (opcode & 0xc0) {
822 case 3:
823 if (rn == 0xf)
824 goto undef;
825 /* FALL THROUGH */
826 case 0:
827 break;
828 default:
829 goto undef;
830 }
831
832 if (rn != 0xf)
833 sprintf(cp, "SMML%c%s%s\tr%d, r%d, r%d, r%d",
834 (opcode & (1 << 6)) ? 'S' : 'A',
835 (opcode & (1 << 5)) ? "R" : "",
836 COND(opcode),
837 (int) (opcode >> 16) & 0xf,
838 (int) (opcode >> 0) & 0xf,
839 (int) (opcode >> 8) & 0xf,
840 rn);
841 else
842 sprintf(cp, "SMMUL%s%s\tr%d, r%d, r%d",
843 (opcode & (1 << 5)) ? "R" : "",
844 COND(opcode),
845 (int) (opcode >> 16) & 0xf,
846 (int) (opcode >> 0) & 0xf,
847 (int) (opcode >> 8) & 0xf);
848 return ERROR_OK;
849 }
850
851 /* simple matches against the remaining decode bits */
852 switch (opcode & 0x01f000f0) {
853 case 0x00a00030:
854 case 0x00e00030:
855 /* parallel halfword saturate */
856 sprintf(cp, "%cSAT16%s\tr%d, #%d, r%d",
857 (opcode & (1 << 22)) ? 'U' : 'S',
858 COND(opcode),
859 (int) (opcode >> 12) & 0xf,
860 (int) (opcode >> 16) & 0xf,
861 (int) (opcode >> 0) & 0xf);
862 return ERROR_OK;
863 case 0x00b00030:
864 mnemonic = "REV";
865 break;
866 case 0x00b000b0:
867 mnemonic = "REV16";
868 break;
869 case 0x00f000b0:
870 mnemonic = "REVSH";
871 break;
872 case 0x008000b0:
873 /* select bytes */
874 sprintf(cp, "SEL%s\tr%d, r%d, r%d", COND(opcode),
875 (int) (opcode >> 12) & 0xf,
876 (int) (opcode >> 16) & 0xf,
877 (int) (opcode >> 0) & 0xf);
878 return ERROR_OK;
879 case 0x01800010:
880 /* unsigned sum of absolute differences */
881 if (((opcode >> 12) & 0xf) == 0xf)
882 sprintf(cp, "USAD8%s\tr%d, r%d, r%d", COND(opcode),
883 (int) (opcode >> 16) & 0xf,
884 (int) (opcode >> 0) & 0xf,
885 (int) (opcode >> 8) & 0xf);
886 else
887 sprintf(cp, "USADA8%s\tr%d, r%d, r%d, r%d", COND(opcode),
888 (int) (opcode >> 16) & 0xf,
889 (int) (opcode >> 0) & 0xf,
890 (int) (opcode >> 8) & 0xf,
891 (int) (opcode >> 12) & 0xf);
892 return ERROR_OK;
893 }
894 if (mnemonic) {
895 unsigned rm = (opcode >> 0) & 0xf;
896 unsigned rd = (opcode >> 12) & 0xf;
897
898 sprintf(cp, "%s%s\tr%d, r%d", mnemonic, COND(opcode), rm, rd);
899 return ERROR_OK;
900 }
901
902 undef:
903 /* these opcodes might be used someday */
904 sprintf(cp, "UNDEFINED");
905 return ERROR_OK;
906 }
907
908 /* Miscellaneous load/store instructions */
909 static int evaluate_misc_load_store(uint32_t opcode,
910 uint32_t address, struct arm_instruction *instruction)
911 {
912 uint8_t P, U, I, W, L, S, H;
913 uint8_t Rn, Rd;
914 char *operation;/* "LDR" or "STR" */
915 char *suffix; /* "H", "SB", "SH", "D" */
916 char offset[32];
917
918 /* examine flags */
919 P = (opcode & 0x01000000) >> 24;
920 U = (opcode & 0x00800000) >> 23;
921 I = (opcode & 0x00400000) >> 22;
922 W = (opcode & 0x00200000) >> 21;
923 L = (opcode & 0x00100000) >> 20;
924 S = (opcode & 0x00000040) >> 6;
925 H = (opcode & 0x00000020) >> 5;
926
927 /* target register */
928 Rd = (opcode & 0xf000) >> 12;
929
930 /* base register */
931 Rn = (opcode & 0xf0000) >> 16;
932
933 instruction->info.load_store.Rd = Rd;
934 instruction->info.load_store.Rn = Rn;
935 instruction->info.load_store.U = U;
936
937 /* determine instruction type and suffix */
938 if (S) {/* signed */
939 if (L) {/* load */
940 if (H) {
941 operation = "LDR";
942 instruction->type = ARM_LDRSH;
943 suffix = "SH";
944 } else {
945 operation = "LDR";
946 instruction->type = ARM_LDRSB;
947 suffix = "SB";
948 }
949 } else {/* there are no signed stores, so this is used to encode double-register
950 *load/stores */
951 suffix = "D";
952 if (H) {
953 operation = "STR";
954 instruction->type = ARM_STRD;
955 } else {
956 operation = "LDR";
957 instruction->type = ARM_LDRD;
958 }
959 }
960 } else {/* unsigned */
961 suffix = "H";
962 if (L) {/* load */
963 operation = "LDR";
964 instruction->type = ARM_LDRH;
965 } else {/* store */
966 operation = "STR";
967 instruction->type = ARM_STRH;
968 }
969 }
970
971 if (I) {/* Immediate offset/index (#+-<offset_8>)*/
972 uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
973 snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
974
975 instruction->info.load_store.offset_mode = 0;
976 instruction->info.load_store.offset.offset = offset_8;
977 } else {/* Register offset/index (+-<Rm>) */
978 uint8_t Rm;
979 Rm = (opcode & 0xf);
980 snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
981
982 instruction->info.load_store.offset_mode = 1;
983 instruction->info.load_store.offset.reg.Rm = Rm;
984 instruction->info.load_store.offset.reg.shift = 0x0;
985 instruction->info.load_store.offset.reg.shift_imm = 0x0;
986 }
987
988 if (P == 1) {
989 if (W == 0) { /* offset */
990 snprintf(instruction->text,
991 128,
992 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
993 address,
994 opcode,
995 operation,
996 COND(opcode),
997 suffix,
998 Rd,
999 Rn,
1000 offset);
1001
1002 instruction->info.load_store.index_mode = 0;
1003 } else {/* pre-indexed */
1004 snprintf(instruction->text,
1005 128,
1006 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
1007 address,
1008 opcode,
1009 operation,
1010 COND(opcode),
1011 suffix,
1012 Rd,
1013 Rn,
1014 offset);
1015
1016 instruction->info.load_store.index_mode = 1;
1017 }
1018 } else {/* post-indexed */
1019 snprintf(instruction->text,
1020 128,
1021 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
1022 address,
1023 opcode,
1024 operation,
1025 COND(opcode),
1026 suffix,
1027 Rd,
1028 Rn,
1029 offset);
1030
1031 instruction->info.load_store.index_mode = 2;
1032 }
1033
1034 return ERROR_OK;
1035 }
1036
1037 /* Load/store multiples instructions */
1038 static int evaluate_ldm_stm(uint32_t opcode,
1039 uint32_t address, struct arm_instruction *instruction)
1040 {
1041 uint8_t P, U, S, W, L, Rn;
1042 uint32_t register_list;
1043 char *addressing_mode;
1044 char *mnemonic;
1045 char reg_list[69];
1046 char *reg_list_p;
1047 int i;
1048 int first_reg = 1;
1049
1050 P = (opcode & 0x01000000) >> 24;
1051 U = (opcode & 0x00800000) >> 23;
1052 S = (opcode & 0x00400000) >> 22;
1053 W = (opcode & 0x00200000) >> 21;
1054 L = (opcode & 0x00100000) >> 20;
1055 register_list = (opcode & 0xffff);
1056 Rn = (opcode & 0xf0000) >> 16;
1057
1058 instruction->info.load_store_multiple.Rn = Rn;
1059 instruction->info.load_store_multiple.register_list = register_list;
1060 instruction->info.load_store_multiple.S = S;
1061 instruction->info.load_store_multiple.W = W;
1062
1063 if (L) {
1064 instruction->type = ARM_LDM;
1065 mnemonic = "LDM";
1066 } else {
1067 instruction->type = ARM_STM;
1068 mnemonic = "STM";
1069 }
1070
1071 if (P) {
1072 if (U) {
1073 instruction->info.load_store_multiple.addressing_mode = 1;
1074 addressing_mode = "IB";
1075 } else {
1076 instruction->info.load_store_multiple.addressing_mode = 3;
1077 addressing_mode = "DB";
1078 }
1079 } else {
1080 if (U) {
1081 instruction->info.load_store_multiple.addressing_mode = 0;
1082 /* "IA" is the default in UAL syntax */
1083 addressing_mode = "";
1084 } else {
1085 instruction->info.load_store_multiple.addressing_mode = 2;
1086 addressing_mode = "DA";
1087 }
1088 }
1089
1090 reg_list_p = reg_list;
1091 for (i = 0; i <= 15; i++) {
1092 if ((register_list >> i) & 1) {
1093 if (first_reg) {
1094 first_reg = 0;
1095 reg_list_p += snprintf(reg_list_p,
1096 (reg_list + 69 - reg_list_p),
1097 "r%i",
1098 i);
1099 } else
1100 reg_list_p += snprintf(reg_list_p,
1101 (reg_list + 69 - reg_list_p),
1102 ", r%i",
1103 i);
1104 }
1105 }
1106
1107 snprintf(instruction->text, 128,
1108 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
1109 "\t%s%s%s r%i%s, {%s}%s",
1110 address, opcode,
1111 mnemonic, addressing_mode, COND(opcode),
1112 Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
1113
1114 return ERROR_OK;
1115 }
1116
1117 /* Multiplies, extra load/stores */
1118 static int evaluate_mul_and_extra_ld_st(uint32_t opcode,
1119 uint32_t address, struct arm_instruction *instruction)
1120 {
1121 /* Multiply (accumulate) (long) and Swap/swap byte */
1122 if ((opcode & 0x000000f0) == 0x00000090) {
1123 /* Multiply (accumulate) */
1124 if ((opcode & 0x0f800000) == 0x00000000) {
1125 uint8_t Rm, Rs, Rn, Rd, S;
1126 Rm = opcode & 0xf;
1127 Rs = (opcode & 0xf00) >> 8;
1128 Rn = (opcode & 0xf000) >> 12;
1129 Rd = (opcode & 0xf0000) >> 16;
1130 S = (opcode & 0x00100000) >> 20;
1131
1132 /* examine A bit (accumulate) */
1133 if (opcode & 0x00200000) {
1134 instruction->type = ARM_MLA;
1135 snprintf(instruction->text,
1136 128,
1137 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
1138 address,
1139 opcode,
1140 COND(opcode),
1141 (S) ? "S" : "",
1142 Rd,
1143 Rm,
1144 Rs,
1145 Rn);
1146 } else {
1147 instruction->type = ARM_MUL;
1148 snprintf(instruction->text,
1149 128,
1150 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
1151 address,
1152 opcode,
1153 COND(opcode),
1154 (S) ? "S" : "",
1155 Rd,
1156 Rm,
1157 Rs);
1158 }
1159
1160 return ERROR_OK;
1161 }
1162
1163 /* Multiply (accumulate) long */
1164 if ((opcode & 0x0f800000) == 0x00800000) {
1165 char *mnemonic = NULL;
1166 uint8_t Rm, Rs, RdHi, RdLow, S;
1167 Rm = opcode & 0xf;
1168 Rs = (opcode & 0xf00) >> 8;
1169 RdHi = (opcode & 0xf000) >> 12;
1170 RdLow = (opcode & 0xf0000) >> 16;
1171 S = (opcode & 0x00100000) >> 20;
1172
1173 switch ((opcode & 0x00600000) >> 21) {
1174 case 0x0:
1175 instruction->type = ARM_UMULL;
1176 mnemonic = "UMULL";
1177 break;
1178 case 0x1:
1179 instruction->type = ARM_UMLAL;
1180 mnemonic = "UMLAL";
1181 break;
1182 case 0x2:
1183 instruction->type = ARM_SMULL;
1184 mnemonic = "SMULL";
1185 break;
1186 case 0x3:
1187 instruction->type = ARM_SMLAL;
1188 mnemonic = "SMLAL";
1189 break;
1190 }
1191
1192 snprintf(instruction->text,
1193 128,
1194 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
1195 address,
1196 opcode,
1197 mnemonic,
1198 COND(opcode),
1199 (S) ? "S" : "",
1200 RdLow,
1201 RdHi,
1202 Rm,
1203 Rs);
1204
1205 return ERROR_OK;
1206 }
1207
1208 /* Swap/swap byte */
1209 if ((opcode & 0x0f800000) == 0x01000000) {
1210 uint8_t Rm, Rd, Rn;
1211 Rm = opcode & 0xf;
1212 Rd = (opcode & 0xf000) >> 12;
1213 Rn = (opcode & 0xf0000) >> 16;
1214
1215 /* examine B flag */
1216 instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
1217
1218 snprintf(instruction->text,
1219 128,
1220 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
1221 address,
1222 opcode,
1223 (opcode & 0x00400000) ? "SWPB" : "SWP",
1224 COND(opcode),
1225 Rd,
1226 Rm,
1227 Rn);
1228 return ERROR_OK;
1229 }
1230
1231 }
1232
1233 return evaluate_misc_load_store(opcode, address, instruction);
1234 }
1235
1236 static int evaluate_mrs_msr(uint32_t opcode,
1237 uint32_t address, struct arm_instruction *instruction)
1238 {
1239 int R = (opcode & 0x00400000) >> 22;
1240 char *PSR = (R) ? "SPSR" : "CPSR";
1241
1242 /* Move register to status register (MSR) */
1243 if (opcode & 0x00200000) {
1244 instruction->type = ARM_MSR;
1245
1246 /* immediate variant */
1247 if (opcode & 0x02000000) {
1248 uint8_t immediate = (opcode & 0xff);
1249 uint8_t rotate = (opcode & 0xf00);
1250
1251 snprintf(instruction->text,
1252 128,
1253 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32,
1254 address,
1255 opcode,
1256 COND(opcode),
1257 PSR,
1258 (opcode & 0x10000) ? "c" : "",
1259 (opcode & 0x20000) ? "x" : "",
1260 (opcode & 0x40000) ? "s" : "",
1261 (opcode & 0x80000) ? "f" : "",
1262 ror(immediate, (rotate * 2))
1263 );
1264 } else {/* register variant */
1265 uint8_t Rm = opcode & 0xf;
1266 snprintf(instruction->text,
1267 128,
1268 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
1269 address,
1270 opcode,
1271 COND(opcode),
1272 PSR,
1273 (opcode & 0x10000) ? "c" : "",
1274 (opcode & 0x20000) ? "x" : "",
1275 (opcode & 0x40000) ? "s" : "",
1276 (opcode & 0x80000) ? "f" : "",
1277 Rm
1278 );
1279 }
1280
1281 } else {/* Move status register to register (MRS) */
1282 uint8_t Rd;
1283
1284 instruction->type = ARM_MRS;
1285 Rd = (opcode & 0x0000f000) >> 12;
1286
1287 snprintf(instruction->text,
1288 128,
1289 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
1290 address,
1291 opcode,
1292 COND(opcode),
1293 Rd,
1294 PSR);
1295 }
1296
1297 return ERROR_OK;
1298 }
1299
1300 /* Miscellaneous instructions */
1301 static int evaluate_misc_instr(uint32_t opcode,
1302 uint32_t address, struct arm_instruction *instruction)
1303 {
1304 /* MRS/MSR */
1305 if ((opcode & 0x000000f0) == 0x00000000)
1306 evaluate_mrs_msr(opcode, address, instruction);
1307
1308 /* BX */
1309 if ((opcode & 0x006000f0) == 0x00200010) {
1310 uint8_t Rm;
1311 instruction->type = ARM_BX;
1312 Rm = opcode & 0xf;
1313
1314 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
1315 address, opcode, COND(opcode), Rm);
1316
1317 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1318 instruction->info.b_bl_bx_blx.target_address = -1;
1319 }
1320
1321 /* BXJ - "Jazelle" support (ARMv5-J) */
1322 if ((opcode & 0x006000f0) == 0x00200020) {
1323 uint8_t Rm;
1324 instruction->type = ARM_BX;
1325 Rm = opcode & 0xf;
1326
1327 snprintf(instruction->text, 128,
1328 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBXJ%s r%i",
1329 address, opcode, COND(opcode), Rm);
1330
1331 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1332 instruction->info.b_bl_bx_blx.target_address = -1;
1333 }
1334
1335 /* CLZ */
1336 if ((opcode & 0x006000f0) == 0x00600010) {
1337 uint8_t Rm, Rd;
1338 instruction->type = ARM_CLZ;
1339 Rm = opcode & 0xf;
1340 Rd = (opcode & 0xf000) >> 12;
1341
1342 snprintf(instruction->text,
1343 128,
1344 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
1345 address,
1346 opcode,
1347 COND(opcode),
1348 Rd,
1349 Rm);
1350 }
1351
1352 /* BLX(2) */
1353 if ((opcode & 0x006000f0) == 0x00200030) {
1354 uint8_t Rm;
1355 instruction->type = ARM_BLX;
1356 Rm = opcode & 0xf;
1357
1358 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
1359 address, opcode, COND(opcode), Rm);
1360
1361 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1362 instruction->info.b_bl_bx_blx.target_address = -1;
1363 }
1364
1365 /* Enhanced DSP add/subtracts */
1366 if ((opcode & 0x0000000f0) == 0x00000050) {
1367 uint8_t Rm, Rd, Rn;
1368 char *mnemonic = NULL;
1369 Rm = opcode & 0xf;
1370 Rd = (opcode & 0xf000) >> 12;
1371 Rn = (opcode & 0xf0000) >> 16;
1372
1373 switch ((opcode & 0x00600000) >> 21) {
1374 case 0x0:
1375 instruction->type = ARM_QADD;
1376 mnemonic = "QADD";
1377 break;
1378 case 0x1:
1379 instruction->type = ARM_QSUB;
1380 mnemonic = "QSUB";
1381 break;
1382 case 0x2:
1383 instruction->type = ARM_QDADD;
1384 mnemonic = "QDADD";
1385 break;
1386 case 0x3:
1387 instruction->type = ARM_QDSUB;
1388 mnemonic = "QDSUB";
1389 break;
1390 }
1391
1392 snprintf(instruction->text,
1393 128,
1394 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
1395 address,
1396 opcode,
1397 mnemonic,
1398 COND(opcode),
1399 Rd,
1400 Rm,
1401 Rn);
1402 }
1403
1404 /* exception return */
1405 if ((opcode & 0x0000000f0) == 0x00000060) {
1406 if (((opcode & 0x600000) >> 21) == 3)
1407 instruction->type = ARM_ERET;
1408 snprintf(instruction->text,
1409 128,
1410 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tERET",
1411 address,
1412 opcode);
1413 }
1414
1415 /* exception generate instructions */
1416 if ((opcode & 0x0000000f0) == 0x00000070) {
1417 uint32_t immediate = 0;
1418 char *mnemonic = NULL;
1419
1420 switch ((opcode & 0x600000) >> 21) {
1421 case 0x1:
1422 instruction->type = ARM_BKPT;
1423 mnemonic = "BRKT";
1424 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1425 break;
1426 case 0x2:
1427 instruction->type = ARM_HVC;
1428 mnemonic = "HVC";
1429 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1430 break;
1431 case 0x3:
1432 instruction->type = ARM_SMC;
1433 mnemonic = "SMC";
1434 immediate = (opcode & 0xf);
1435 break;
1436 }
1437
1438 snprintf(instruction->text,
1439 128,
1440 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s 0x%4.4" PRIx32 "",
1441 address,
1442 opcode,
1443 mnemonic,
1444 immediate);
1445 }
1446
1447 /* Enhanced DSP multiplies */
1448 if ((opcode & 0x000000090) == 0x00000080) {
1449 int x = (opcode & 0x20) >> 5;
1450 int y = (opcode & 0x40) >> 6;
1451
1452 /* SMLA < x><y> */
1453 if ((opcode & 0x00600000) == 0x00000000) {
1454 uint8_t Rd, Rm, Rs, Rn;
1455 instruction->type = ARM_SMLAxy;
1456 Rd = (opcode & 0xf0000) >> 16;
1457 Rm = (opcode & 0xf);
1458 Rs = (opcode & 0xf00) >> 8;
1459 Rn = (opcode & 0xf000) >> 12;
1460
1461 snprintf(instruction->text,
1462 128,
1463 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1464 address,
1465 opcode,
1466 (x) ? "T" : "B",
1467 (y) ? "T" : "B",
1468 COND(opcode),
1469 Rd,
1470 Rm,
1471 Rs,
1472 Rn);
1473 }
1474
1475 /* SMLAL < x><y> */
1476 if ((opcode & 0x00600000) == 0x00400000) {
1477 uint8_t RdLow, RdHi, Rm, Rs;
1478 instruction->type = ARM_SMLAxy;
1479 RdHi = (opcode & 0xf0000) >> 16;
1480 RdLow = (opcode & 0xf000) >> 12;
1481 Rm = (opcode & 0xf);
1482 Rs = (opcode & 0xf00) >> 8;
1483
1484 snprintf(instruction->text,
1485 128,
1486 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1487 address,
1488 opcode,
1489 (x) ? "T" : "B",
1490 (y) ? "T" : "B",
1491 COND(opcode),
1492 RdLow,
1493 RdHi,
1494 Rm,
1495 Rs);
1496 }
1497
1498 /* SMLAW < y> */
1499 if (((opcode & 0x00600000) == 0x00100000) && (x == 0)) {
1500 uint8_t Rd, Rm, Rs, Rn;
1501 instruction->type = ARM_SMLAWy;
1502 Rd = (opcode & 0xf0000) >> 16;
1503 Rm = (opcode & 0xf);
1504 Rs = (opcode & 0xf00) >> 8;
1505 Rn = (opcode & 0xf000) >> 12;
1506
1507 snprintf(instruction->text,
1508 128,
1509 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
1510 address,
1511 opcode,
1512 (y) ? "T" : "B",
1513 COND(opcode),
1514 Rd,
1515 Rm,
1516 Rs,
1517 Rn);
1518 }
1519
1520 /* SMUL < x><y> */
1521 if ((opcode & 0x00600000) == 0x00300000) {
1522 uint8_t Rd, Rm, Rs;
1523 instruction->type = ARM_SMULxy;
1524 Rd = (opcode & 0xf0000) >> 16;
1525 Rm = (opcode & 0xf);
1526 Rs = (opcode & 0xf00) >> 8;
1527
1528 snprintf(instruction->text,
1529 128,
1530 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
1531 address,
1532 opcode,
1533 (x) ? "T" : "B",
1534 (y) ? "T" : "B",
1535 COND(opcode),
1536 Rd,
1537 Rm,
1538 Rs);
1539 }
1540
1541 /* SMULW < y> */
1542 if (((opcode & 0x00600000) == 0x00100000) && (x == 1)) {
1543 uint8_t Rd, Rm, Rs;
1544 instruction->type = ARM_SMULWy;
1545 Rd = (opcode & 0xf0000) >> 16;
1546 Rm = (opcode & 0xf);
1547 Rs = (opcode & 0xf00) >> 8;
1548
1549 snprintf(instruction->text,
1550 128,
1551 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
1552 address,
1553 opcode,
1554 (y) ? "T" : "B",
1555 COND(opcode),
1556 Rd,
1557 Rm,
1558 Rs);
1559 }
1560 }
1561
1562 return ERROR_OK;
1563 }
1564
1565 static int evaluate_data_proc(uint32_t opcode,
1566 uint32_t address, struct arm_instruction *instruction)
1567 {
1568 uint8_t I, op, S, Rn, Rd;
1569 char *mnemonic = NULL;
1570 char shifter_operand[32];
1571
1572 I = (opcode & 0x02000000) >> 25;
1573 op = (opcode & 0x01e00000) >> 21;
1574 S = (opcode & 0x00100000) >> 20;
1575
1576 Rd = (opcode & 0xf000) >> 12;
1577 Rn = (opcode & 0xf0000) >> 16;
1578
1579 instruction->info.data_proc.Rd = Rd;
1580 instruction->info.data_proc.Rn = Rn;
1581 instruction->info.data_proc.S = S;
1582
1583 switch (op) {
1584 case 0x0:
1585 instruction->type = ARM_AND;
1586 mnemonic = "AND";
1587 break;
1588 case 0x1:
1589 instruction->type = ARM_EOR;
1590 mnemonic = "EOR";
1591 break;
1592 case 0x2:
1593 instruction->type = ARM_SUB;
1594 mnemonic = "SUB";
1595 break;
1596 case 0x3:
1597 instruction->type = ARM_RSB;
1598 mnemonic = "RSB";
1599 break;
1600 case 0x4:
1601 instruction->type = ARM_ADD;
1602 mnemonic = "ADD";
1603 break;
1604 case 0x5:
1605 instruction->type = ARM_ADC;
1606 mnemonic = "ADC";
1607 break;
1608 case 0x6:
1609 instruction->type = ARM_SBC;
1610 mnemonic = "SBC";
1611 break;
1612 case 0x7:
1613 instruction->type = ARM_RSC;
1614 mnemonic = "RSC";
1615 break;
1616 case 0x8:
1617 instruction->type = ARM_TST;
1618 mnemonic = "TST";
1619 break;
1620 case 0x9:
1621 instruction->type = ARM_TEQ;
1622 mnemonic = "TEQ";
1623 break;
1624 case 0xa:
1625 instruction->type = ARM_CMP;
1626 mnemonic = "CMP";
1627 break;
1628 case 0xb:
1629 instruction->type = ARM_CMN;
1630 mnemonic = "CMN";
1631 break;
1632 case 0xc:
1633 instruction->type = ARM_ORR;
1634 mnemonic = "ORR";
1635 break;
1636 case 0xd:
1637 instruction->type = ARM_MOV;
1638 mnemonic = "MOV";
1639 break;
1640 case 0xe:
1641 instruction->type = ARM_BIC;
1642 mnemonic = "BIC";
1643 break;
1644 case 0xf:
1645 instruction->type = ARM_MVN;
1646 mnemonic = "MVN";
1647 break;
1648 }
1649
1650 if (I) {/* immediate shifter operand (#<immediate>)*/
1651 uint8_t immed_8 = opcode & 0xff;
1652 uint8_t rotate_imm = (opcode & 0xf00) >> 8;
1653 uint32_t immediate;
1654
1655 immediate = ror(immed_8, rotate_imm * 2);
1656
1657 snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
1658
1659 instruction->info.data_proc.variant = 0;
1660 instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
1661 } else {/* register-based shifter operand */
1662 uint8_t shift, Rm;
1663 shift = (opcode & 0x60) >> 5;
1664 Rm = (opcode & 0xf);
1665
1666 if ((opcode & 0x10) != 0x10) { /* Immediate shifts ("<Rm>" or "<Rm>, <shift>
1667 *#<shift_immediate>") */
1668 uint8_t shift_imm;
1669 shift_imm = (opcode & 0xf80) >> 7;
1670
1671 instruction->info.data_proc.variant = 1;
1672 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1673 instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm =
1674 shift_imm;
1675 instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
1676
1677 /* LSR encodes a shift by 32 bit as 0x0 */
1678 if ((shift == 0x1) && (shift_imm == 0x0))
1679 shift_imm = 0x20;
1680
1681 /* ASR encodes a shift by 32 bit as 0x0 */
1682 if ((shift == 0x2) && (shift_imm == 0x0))
1683 shift_imm = 0x20;
1684
1685 /* ROR by 32 bit is actually a RRX */
1686 if ((shift == 0x3) && (shift_imm == 0x0))
1687 shift = 0x4;
1688
1689 if ((shift_imm == 0x0) && (shift == 0x0))
1690 snprintf(shifter_operand, 32, "r%i", Rm);
1691 else {
1692 if (shift == 0x0) /* LSL */
1693 snprintf(shifter_operand,
1694 32,
1695 "r%i, LSL #0x%x",
1696 Rm,
1697 shift_imm);
1698 else if (shift == 0x1) /* LSR */
1699 snprintf(shifter_operand,
1700 32,
1701 "r%i, LSR #0x%x",
1702 Rm,
1703 shift_imm);
1704 else if (shift == 0x2) /* ASR */
1705 snprintf(shifter_operand,
1706 32,
1707 "r%i, ASR #0x%x",
1708 Rm,
1709 shift_imm);
1710 else if (shift == 0x3) /* ROR */
1711 snprintf(shifter_operand,
1712 32,
1713 "r%i, ROR #0x%x",
1714 Rm,
1715 shift_imm);
1716 else if (shift == 0x4) /* RRX */
1717 snprintf(shifter_operand, 32, "r%i, RRX", Rm);
1718 }
1719 } else {/* Register shifts ("<Rm>, <shift> <Rs>") */
1720 uint8_t Rs = (opcode & 0xf00) >> 8;
1721
1722 instruction->info.data_proc.variant = 2;
1723 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
1724 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
1725 instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
1726
1727 if (shift == 0x0) /* LSL */
1728 snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
1729 else if (shift == 0x1) /* LSR */
1730 snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
1731 else if (shift == 0x2) /* ASR */
1732 snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
1733 else if (shift == 0x3) /* ROR */
1734 snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
1735 }
1736 }
1737
1738 if ((op < 0x8) || (op == 0xc) || (op == 0xe)) { /* <opcode3>{<cond>}{S} <Rd>, <Rn>,
1739 *<shifter_operand> */
1740 snprintf(instruction->text,
1741 128,
1742 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
1743 address,
1744 opcode,
1745 mnemonic,
1746 COND(opcode),
1747 (S) ? "S" : "",
1748 Rd,
1749 Rn,
1750 shifter_operand);
1751 } else if ((op == 0xd) || (op == 0xf)) { /* <opcode1>{<cond>}{S} <Rd>,
1752 *<shifter_operand> */
1753 if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */
1754 snprintf(instruction->text,
1755 128,
1756 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",
1757 address,
1758 opcode);
1759 else
1760 snprintf(instruction->text,
1761 128,
1762 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
1763 address,
1764 opcode,
1765 mnemonic,
1766 COND(opcode),
1767 (S) ? "S" : "",
1768 Rd,
1769 shifter_operand);
1770 } else {/* <opcode2>{<cond>} <Rn>, <shifter_operand> */
1771 snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
1772 address, opcode, mnemonic, COND(opcode),
1773 Rn, shifter_operand);
1774 }
1775
1776 return ERROR_OK;
1777 }
1778
1779 int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
1780 struct arm_instruction *instruction)
1781 {
1782 /* clear fields, to avoid confusion */
1783 memset(instruction, 0, sizeof(struct arm_instruction));
1784 instruction->opcode = opcode;
1785 instruction->instruction_size = 4;
1786
1787 /* catch opcodes with condition field [31:28] = b1111 */
1788 if ((opcode & 0xf0000000) == 0xf0000000) {
1789 /* Undefined instruction (or ARMv5E cache preload PLD) */
1790 if ((opcode & 0x08000000) == 0x00000000)
1791 return evaluate_pld(opcode, address, instruction);
1792
1793 /* Undefined instruction (or ARMv6+ SRS/RFE) */
1794 if ((opcode & 0x0e000000) == 0x08000000)
1795 return evaluate_srs(opcode, address, instruction);
1796
1797 /* Branch and branch with link and change to Thumb */
1798 if ((opcode & 0x0e000000) == 0x0a000000)
1799 return evaluate_blx_imm(opcode, address, instruction);
1800
1801 /* Extended coprocessor opcode space (ARMv5 and higher)
1802 * Coprocessor load/store and double register transfers */
1803 if ((opcode & 0x0e000000) == 0x0c000000)
1804 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1805
1806 /* Coprocessor data processing */
1807 if ((opcode & 0x0f000100) == 0x0c000000)
1808 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1809
1810 /* Coprocessor register transfers */
1811 if ((opcode & 0x0f000010) == 0x0c000010)
1812 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1813
1814 /* Undefined instruction */
1815 if ((opcode & 0x0f000000) == 0x0f000000) {
1816 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1817 snprintf(instruction->text,
1818 128,
1819 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1820 address,
1821 opcode);
1822 return ERROR_OK;
1823 }
1824 }
1825
1826 /* catch opcodes with [27:25] = b000 */
1827 if ((opcode & 0x0e000000) == 0x00000000) {
1828 /* Multiplies, extra load/stores */
1829 if ((opcode & 0x00000090) == 0x00000090)
1830 return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
1831
1832 /* Miscellaneous instructions */
1833 if ((opcode & 0x0f900000) == 0x01000000)
1834 return evaluate_misc_instr(opcode, address, instruction);
1835
1836 return evaluate_data_proc(opcode, address, instruction);
1837 }
1838
1839 /* catch opcodes with [27:25] = b001 */
1840 if ((opcode & 0x0e000000) == 0x02000000) {
1841 /* Undefined instruction */
1842 if ((opcode & 0x0fb00000) == 0x03000000) {
1843 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1844 snprintf(instruction->text,
1845 128,
1846 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1847 address,
1848 opcode);
1849 return ERROR_OK;
1850 }
1851
1852 /* Move immediate to status register */
1853 if ((opcode & 0x0fb00000) == 0x03200000)
1854 return evaluate_mrs_msr(opcode, address, instruction);
1855
1856 return evaluate_data_proc(opcode, address, instruction);
1857
1858 }
1859
1860 /* catch opcodes with [27:25] = b010 */
1861 if ((opcode & 0x0e000000) == 0x04000000) {
1862 /* Load/store immediate offset */
1863 return evaluate_load_store(opcode, address, instruction);
1864 }
1865
1866 /* catch opcodes with [27:25] = b011 */
1867 if ((opcode & 0x0e000000) == 0x06000000) {
1868 /* Load/store register offset */
1869 if ((opcode & 0x00000010) == 0x00000000)
1870 return evaluate_load_store(opcode, address, instruction);
1871
1872 /* Architecturally Undefined instruction
1873 * ... don't expect these to ever be used
1874 */
1875 if ((opcode & 0x07f000f0) == 0x07f000f0) {
1876 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1877 snprintf(instruction->text, 128,
1878 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF",
1879 address, opcode);
1880 return ERROR_OK;
1881 }
1882
1883 /* "media" instructions */
1884 return evaluate_media(opcode, address, instruction);
1885 }
1886
1887 /* catch opcodes with [27:25] = b100 */
1888 if ((opcode & 0x0e000000) == 0x08000000) {
1889 /* Load/store multiple */
1890 return evaluate_ldm_stm(opcode, address, instruction);
1891 }
1892
1893 /* catch opcodes with [27:25] = b101 */
1894 if ((opcode & 0x0e000000) == 0x0a000000) {
1895 /* Branch and branch with link */
1896 return evaluate_b_bl(opcode, address, instruction);
1897 }
1898
1899 /* catch opcodes with [27:25] = b110 */
1900 if ((opcode & 0x0e000000) == 0x0c000000) {
1901 /* Coprocessor load/store and double register transfers */
1902 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1903 }
1904
1905 /* catch opcodes with [27:25] = b111 */
1906 if ((opcode & 0x0e000000) == 0x0e000000) {
1907 /* Software interrupt */
1908 if ((opcode & 0x0f000000) == 0x0f000000)
1909 return evaluate_swi(opcode, address, instruction);
1910
1911 /* Coprocessor data processing */
1912 if ((opcode & 0x0f000010) == 0x0e000000)
1913 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1914
1915 /* Coprocessor register transfers */
1916 if ((opcode & 0x0f000010) == 0x0e000010)
1917 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1918 }
1919
1920 LOG_ERROR("ARM: should never reach this point (opcode=%08x)",
1921 (unsigned) opcode);
1922 return -1;
1923 }
1924
1925 static int evaluate_b_bl_blx_thumb(uint16_t opcode,
1926 uint32_t address, struct arm_instruction *instruction)
1927 {
1928 uint32_t offset = opcode & 0x7ff;
1929 uint32_t opc = (opcode >> 11) & 0x3;
1930 uint32_t target_address;
1931 char *mnemonic = NULL;
1932
1933 /* sign extend 11-bit offset */
1934 if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
1935 offset = 0xfffff800 | offset;
1936
1937 target_address = address + 4 + (offset << 1);
1938
1939 switch (opc) {
1940 /* unconditional branch */
1941 case 0:
1942 instruction->type = ARM_B;
1943 mnemonic = "B";
1944 break;
1945 /* BLX suffix */
1946 case 1:
1947 instruction->type = ARM_BLX;
1948 mnemonic = "BLX";
1949 target_address &= 0xfffffffc;
1950 break;
1951 /* BL/BLX prefix */
1952 case 2:
1953 instruction->type = ARM_UNKNOWN_INSTUCTION;
1954 mnemonic = "prefix";
1955 target_address = offset << 12;
1956 break;
1957 /* BL suffix */
1958 case 3:
1959 instruction->type = ARM_BL;
1960 mnemonic = "BL";
1961 break;
1962 }
1963
1964 /* TODO: deal correctly with dual opcode (prefixed) BL/BLX;
1965 * these are effectively 32-bit instructions even in Thumb1. For
1966 * disassembly, it's simplest to always use the Thumb2 decoder.
1967 *
1968 * But some cores will evidently handle them as two instructions,
1969 * where exceptions may occur between the two. The ETMv3.2+ ID
1970 * register has a bit which exposes this behavior.
1971 */
1972
1973 snprintf(instruction->text, 128,
1974 "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%#8.8" PRIx32,
1975 address, opcode, mnemonic, target_address);
1976
1977 instruction->info.b_bl_bx_blx.reg_operand = -1;
1978 instruction->info.b_bl_bx_blx.target_address = target_address;
1979
1980 return ERROR_OK;
1981 }
1982
1983 static int evaluate_add_sub_thumb(uint16_t opcode,
1984 uint32_t address, struct arm_instruction *instruction)
1985 {
1986 uint8_t Rd = (opcode >> 0) & 0x7;
1987 uint8_t Rn = (opcode >> 3) & 0x7;
1988 uint8_t Rm_imm = (opcode >> 6) & 0x7;
1989 uint32_t opc = opcode & (1 << 9);
1990 uint32_t reg_imm = opcode & (1 << 10);
1991 char *mnemonic;
1992
1993 if (opc) {
1994 instruction->type = ARM_SUB;
1995 mnemonic = "SUBS";
1996 } else {
1997 /* REVISIT: if reg_imm == 0, display as "MOVS" */
1998 instruction->type = ARM_ADD;
1999 mnemonic = "ADDS";
2000 }
2001
2002 instruction->info.data_proc.Rd = Rd;
2003 instruction->info.data_proc.Rn = Rn;
2004 instruction->info.data_proc.S = 1;
2005
2006 if (reg_imm) {
2007 instruction->info.data_proc.variant = 0;/*immediate*/
2008 instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
2009 snprintf(instruction->text, 128,
2010 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%d",
2011 address, opcode, mnemonic, Rd, Rn, Rm_imm);
2012 } else {
2013 instruction->info.data_proc.variant = 1;/*immediate shift*/
2014 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
2015 snprintf(instruction->text, 128,
2016 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, r%i",
2017 address, opcode, mnemonic, Rd, Rn, Rm_imm);
2018 }
2019
2020 return ERROR_OK;
2021 }
2022
2023 static int evaluate_shift_imm_thumb(uint16_t opcode,
2024 uint32_t address, struct arm_instruction *instruction)
2025 {
2026 uint8_t Rd = (opcode >> 0) & 0x7;
2027 uint8_t Rm = (opcode >> 3) & 0x7;
2028 uint8_t imm = (opcode >> 6) & 0x1f;
2029 uint8_t opc = (opcode >> 11) & 0x3;
2030 char *mnemonic = NULL;
2031
2032 switch (opc) {
2033 case 0:
2034 instruction->type = ARM_MOV;
2035 mnemonic = "LSLS";
2036 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
2037 break;
2038 case 1:
2039 instruction->type = ARM_MOV;
2040 mnemonic = "LSRS";
2041 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
2042 break;
2043 case 2:
2044 instruction->type = ARM_MOV;
2045 mnemonic = "ASRS";
2046 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
2047 break;
2048 }
2049
2050 if ((imm == 0) && (opc != 0))
2051 imm = 32;
2052
2053 instruction->info.data_proc.Rd = Rd;
2054 instruction->info.data_proc.Rn = -1;
2055 instruction->info.data_proc.S = 1;
2056
2057 instruction->info.data_proc.variant = 1;/*immediate_shift*/
2058 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2059 instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
2060
2061 snprintf(instruction->text, 128,
2062 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%#2.2x",
2063 address, opcode, mnemonic, Rd, Rm, imm);
2064
2065 return ERROR_OK;
2066 }
2067
2068 static int evaluate_data_proc_imm_thumb(uint16_t opcode,
2069 uint32_t address, struct arm_instruction *instruction)
2070 {
2071 uint8_t imm = opcode & 0xff;
2072 uint8_t Rd = (opcode >> 8) & 0x7;
2073 uint32_t opc = (opcode >> 11) & 0x3;
2074 char *mnemonic = NULL;
2075
2076 instruction->info.data_proc.Rd = Rd;
2077 instruction->info.data_proc.Rn = Rd;
2078 instruction->info.data_proc.S = 1;
2079 instruction->info.data_proc.variant = 0;/*immediate*/
2080 instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
2081
2082 switch (opc) {
2083 case 0:
2084 instruction->type = ARM_MOV;
2085 mnemonic = "MOVS";
2086 instruction->info.data_proc.Rn = -1;
2087 break;
2088 case 1:
2089 instruction->type = ARM_CMP;
2090 mnemonic = "CMP";
2091 instruction->info.data_proc.Rd = -1;
2092 break;
2093 case 2:
2094 instruction->type = ARM_ADD;
2095 mnemonic = "ADDS";
2096 break;
2097 case 3:
2098 instruction->type = ARM_SUB;
2099 mnemonic = "SUBS";
2100 break;
2101 }
2102
2103 snprintf(instruction->text, 128,
2104 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, #%#2.2x",
2105 address, opcode, mnemonic, Rd, imm);
2106
2107 return ERROR_OK;
2108 }
2109
2110 static int evaluate_data_proc_thumb(uint16_t opcode,
2111 uint32_t address, struct arm_instruction *instruction)
2112 {
2113 uint8_t high_reg, op, Rm, Rd, H1, H2;
2114 char *mnemonic = NULL;
2115 bool nop = false;
2116
2117 high_reg = (opcode & 0x0400) >> 10;
2118 op = (opcode & 0x03C0) >> 6;
2119
2120 Rd = (opcode & 0x0007);
2121 Rm = (opcode & 0x0038) >> 3;
2122 H1 = (opcode & 0x0080) >> 7;
2123 H2 = (opcode & 0x0040) >> 6;
2124
2125 instruction->info.data_proc.Rd = Rd;
2126 instruction->info.data_proc.Rn = Rd;
2127 instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
2128 instruction->info.data_proc.variant = 1 /*immediate shift*/;
2129 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2130
2131 if (high_reg) {
2132 Rd |= H1 << 3;
2133 Rm |= H2 << 3;
2134 op >>= 2;
2135
2136 switch (op) {
2137 case 0x0:
2138 instruction->type = ARM_ADD;
2139 mnemonic = "ADD";
2140 break;
2141 case 0x1:
2142 instruction->type = ARM_CMP;
2143 mnemonic = "CMP";
2144 break;
2145 case 0x2:
2146 instruction->type = ARM_MOV;
2147 mnemonic = "MOV";
2148 if (Rd == Rm)
2149 nop = true;
2150 break;
2151 case 0x3:
2152 if ((opcode & 0x7) == 0x0) {
2153 instruction->info.b_bl_bx_blx.reg_operand = Rm;
2154 if (H1) {
2155 instruction->type = ARM_BLX;
2156 snprintf(instruction->text, 128,
2157 "0x%8.8" PRIx32
2158 " 0x%4.4x \tBLX\tr%i",
2159 address, opcode, Rm);
2160 } else {
2161 instruction->type = ARM_BX;
2162 snprintf(instruction->text, 128,
2163 "0x%8.8" PRIx32
2164 " 0x%4.4x \tBX\tr%i",
2165 address, opcode, Rm);
2166 }
2167 } else {
2168 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2169 snprintf(instruction->text, 128,
2170 "0x%8.8" PRIx32
2171 " 0x%4.4x \t"
2172 "UNDEFINED INSTRUCTION",
2173 address, opcode);
2174 }
2175 return ERROR_OK;
2176 break;
2177 }
2178 } else {
2179 switch (op) {
2180 case 0x0:
2181 instruction->type = ARM_AND;
2182 mnemonic = "ANDS";
2183 break;
2184 case 0x1:
2185 instruction->type = ARM_EOR;
2186 mnemonic = "EORS";
2187 break;
2188 case 0x2:
2189 instruction->type = ARM_MOV;
2190 mnemonic = "LSLS";
2191 instruction->info.data_proc.variant = 2 /*register shift*/;
2192 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
2193 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2194 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2195 break;
2196 case 0x3:
2197 instruction->type = ARM_MOV;
2198 mnemonic = "LSRS";
2199 instruction->info.data_proc.variant = 2 /*register shift*/;
2200 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
2201 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2202 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2203 break;
2204 case 0x4:
2205 instruction->type = ARM_MOV;
2206 mnemonic = "ASRS";
2207 instruction->info.data_proc.variant = 2 /*register shift*/;
2208 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
2209 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2210 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2211 break;
2212 case 0x5:
2213 instruction->type = ARM_ADC;
2214 mnemonic = "ADCS";
2215 break;
2216 case 0x6:
2217 instruction->type = ARM_SBC;
2218 mnemonic = "SBCS";
2219 break;
2220 case 0x7:
2221 instruction->type = ARM_MOV;
2222 mnemonic = "RORS";
2223 instruction->info.data_proc.variant = 2 /*register shift*/;
2224 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
2225 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2226 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2227 break;
2228 case 0x8:
2229 instruction->type = ARM_TST;
2230 mnemonic = "TST";
2231 break;
2232 case 0x9:
2233 instruction->type = ARM_RSB;
2234 mnemonic = "RSBS";
2235 instruction->info.data_proc.variant = 0 /*immediate*/;
2236 instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
2237 instruction->info.data_proc.Rn = Rm;
2238 break;
2239 case 0xA:
2240 instruction->type = ARM_CMP;
2241 mnemonic = "CMP";
2242 break;
2243 case 0xB:
2244 instruction->type = ARM_CMN;
2245 mnemonic = "CMN";
2246 break;
2247 case 0xC:
2248 instruction->type = ARM_ORR;
2249 mnemonic = "ORRS";
2250 break;
2251 case 0xD:
2252 instruction->type = ARM_MUL;
2253 mnemonic = "MULS";
2254 break;
2255 case 0xE:
2256 instruction->type = ARM_BIC;
2257 mnemonic = "BICS";
2258 break;
2259 case 0xF:
2260 instruction->type = ARM_MVN;
2261 mnemonic = "MVNS";
2262 break;
2263 }
2264 }
2265
2266 if (nop)
2267 snprintf(instruction->text, 128,
2268 "0x%8.8" PRIx32 " 0x%4.4x \tNOP\t\t\t"
2269 "; (%s r%i, r%i)",
2270 address, opcode, mnemonic, Rd, Rm);
2271 else
2272 snprintf(instruction->text, 128,
2273 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i",
2274 address, opcode, mnemonic, Rd, Rm);
2275
2276 return ERROR_OK;
2277 }
2278
2279 /* PC-relative data addressing is word-aligned even with Thumb */
2280 static inline uint32_t thumb_alignpc4(uint32_t addr)
2281 {
2282 return (addr + 4) & ~3;
2283 }
2284
2285 static int evaluate_load_literal_thumb(uint16_t opcode,
2286 uint32_t address, struct arm_instruction *instruction)
2287 {
2288 uint32_t immediate;
2289 uint8_t Rd = (opcode >> 8) & 0x7;
2290
2291 instruction->type = ARM_LDR;
2292 immediate = opcode & 0x000000ff;
2293 immediate *= 4;
2294
2295 instruction->info.load_store.Rd = Rd;
2296 instruction->info.load_store.Rn = 15 /*PC*/;
2297 instruction->info.load_store.index_mode = 0; /*offset*/
2298 instruction->info.load_store.offset_mode = 0; /*immediate*/
2299 instruction->info.load_store.offset.offset = immediate;
2300
2301 snprintf(instruction->text, 128,
2302 "0x%8.8" PRIx32 " 0x%4.4x \t"
2303 "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32,
2304 address, opcode, Rd, immediate,
2305 thumb_alignpc4(address) + immediate);
2306
2307 return ERROR_OK;
2308 }
2309
2310 static int evaluate_load_store_reg_thumb(uint16_t opcode,
2311 uint32_t address, struct arm_instruction *instruction)
2312 {
2313 uint8_t Rd = (opcode >> 0) & 0x7;
2314 uint8_t Rn = (opcode >> 3) & 0x7;
2315 uint8_t Rm = (opcode >> 6) & 0x7;
2316 uint8_t opc = (opcode >> 9) & 0x7;
2317 char *mnemonic = NULL;
2318
2319 switch (opc) {
2320 case 0:
2321 instruction->type = ARM_STR;
2322 mnemonic = "STR";
2323 break;
2324 case 1:
2325 instruction->type = ARM_STRH;
2326 mnemonic = "STRH";
2327 break;
2328 case 2:
2329 instruction->type = ARM_STRB;
2330 mnemonic = "STRB";
2331 break;
2332 case 3:
2333 instruction->type = ARM_LDRSB;
2334 mnemonic = "LDRSB";
2335 break;
2336 case 4:
2337 instruction->type = ARM_LDR;
2338 mnemonic = "LDR";
2339 break;
2340 case 5:
2341 instruction->type = ARM_LDRH;
2342 mnemonic = "LDRH";
2343 break;
2344 case 6:
2345 instruction->type = ARM_LDRB;
2346 mnemonic = "LDRB";
2347 break;
2348 case 7:
2349 instruction->type = ARM_LDRSH;
2350 mnemonic = "LDRSH";
2351 break;
2352 }
2353
2354 snprintf(instruction->text, 128,
2355 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [r%i, r%i]",
2356 address, opcode, mnemonic, Rd, Rn, Rm);
2357
2358 instruction->info.load_store.Rd = Rd;
2359 instruction->info.load_store.Rn = Rn;
2360 instruction->info.load_store.index_mode = 0; /*offset*/
2361 instruction->info.load_store.offset_mode = 1; /*register*/
2362 instruction->info.load_store.offset.reg.Rm = Rm;
2363
2364 return ERROR_OK;
2365 }
2366
2367 static int evaluate_load_store_imm_thumb(uint16_t opcode,
2368 uint32_t address, struct arm_instruction *instruction)
2369 {
2370 uint32_t offset = (opcode >> 6) & 0x1f;
2371 uint8_t Rd = (opcode >> 0) & 0x7;
2372 uint8_t Rn = (opcode >> 3) & 0x7;
2373 uint32_t L = opcode & (1 << 11);
2374 uint32_t B = opcode & (1 << 12);
2375 char *mnemonic;
2376 char suffix = ' ';
2377 uint32_t shift = 2;
2378
2379 if (L) {
2380 instruction->type = ARM_LDR;
2381 mnemonic = "LDR";
2382 } else {
2383 instruction->type = ARM_STR;
2384 mnemonic = "STR";
2385 }
2386
2387 if ((opcode&0xF000) == 0x8000) {
2388 suffix = 'H';
2389 shift = 1;
2390 } else if (B) {
2391 suffix = 'B';
2392 shift = 0;
2393 }
2394
2395 snprintf(instruction->text, 128,
2396 "0x%8.8" PRIx32 " 0x%4.4x \t%s%c\tr%i, [r%i, #%#" PRIx32 "]",
2397 address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
2398
2399 instruction->info.load_store.Rd = Rd;
2400 instruction->info.load_store.Rn = Rn;
2401 instruction->info.load_store.index_mode = 0; /*offset*/
2402 instruction->info.load_store.offset_mode = 0; /*immediate*/
2403 instruction->info.load_store.offset.offset = offset << shift;
2404
2405 return ERROR_OK;
2406 }
2407
2408 static int evaluate_load_store_stack_thumb(uint16_t opcode,
2409 uint32_t address, struct arm_instruction *instruction)
2410 {
2411 uint32_t offset = opcode & 0xff;
2412 uint8_t Rd = (opcode >> 8) & 0x7;
2413 uint32_t L = opcode & (1 << 11);
2414 char *mnemonic;
2415
2416 if (L) {
2417 instruction->type = ARM_LDR;
2418 mnemonic = "LDR";
2419 } else {
2420 instruction->type = ARM_STR;
2421 mnemonic = "STR";
2422 }
2423
2424 snprintf(instruction->text, 128,
2425 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [SP, #%#" PRIx32 "]",
2426 address, opcode, mnemonic, Rd, offset*4);
2427
2428 instruction->info.load_store.Rd = Rd;
2429 instruction->info.load_store.Rn = 13 /*SP*/;
2430 instruction->info.load_store.index_mode = 0; /*offset*/
2431 instruction->info.load_store.offset_mode = 0; /*immediate*/
2432 instruction->info.load_store.offset.offset = offset*4;
2433
2434 return ERROR_OK;
2435 }
2436
2437 static int evaluate_add_sp_pc_thumb(uint16_t opcode,
2438 uint32_t address, struct arm_instruction *instruction)
2439 {
2440 uint32_t imm = opcode & 0xff;
2441 uint8_t Rd = (opcode >> 8) & 0x7;
2442 uint8_t Rn;
2443 uint32_t SP = opcode & (1 << 11);
2444 const char *reg_name;
2445
2446 instruction->type = ARM_ADD;
2447
2448 if (SP) {
2449 reg_name = "SP";
2450 Rn = 13;
2451 } else {
2452 reg_name = "PC";
2453 Rn = 15;
2454 }
2455
2456 snprintf(instruction->text, 128,
2457 "0x%8.8" PRIx32 " 0x%4.4x \tADD\tr%i, %s, #%#" PRIx32,
2458 address, opcode, Rd, reg_name, imm * 4);
2459
2460 instruction->info.data_proc.variant = 0 /* immediate */;
2461 instruction->info.data_proc.Rd = Rd;
2462 instruction->info.data_proc.Rn = Rn;
2463 instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2464
2465 return ERROR_OK;
2466 }
2467
2468 static int evaluate_adjust_stack_thumb(uint16_t opcode,
2469 uint32_t address, struct arm_instruction *instruction)
2470 {
2471 uint32_t imm = opcode & 0x7f;
2472 uint8_t opc = opcode & (1 << 7);
2473 char *mnemonic;
2474
2475
2476 if (opc) {
2477 instruction->type = ARM_SUB;
2478 mnemonic = "SUB";
2479 } else {
2480 instruction->type = ARM_ADD;
2481 mnemonic = "ADD";
2482 }
2483
2484 snprintf(instruction->text, 128,
2485 "0x%8.8" PRIx32 " 0x%4.4x \t%s\tSP, #%#" PRIx32,
2486 address, opcode, mnemonic, imm*4);
2487
2488 instruction->info.data_proc.variant = 0 /* immediate */;
2489 instruction->info.data_proc.Rd = 13 /*SP*/;
2490 instruction->info.data_proc.Rn = 13 /*SP*/;
2491 instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2492
2493 return ERROR_OK;
2494 }
2495
2496 static int evaluate_breakpoint_thumb(uint16_t opcode,
2497 uint32_t address, struct arm_instruction *instruction)
2498 {
2499 uint32_t imm = opcode & 0xff;
2500
2501 instruction->type = ARM_BKPT;
2502
2503 snprintf(instruction->text, 128,
2504 "0x%8.8" PRIx32 " 0x%4.4x \tBKPT\t%#2.2" PRIx32 "",
2505 address, opcode, imm);
2506
2507 return ERROR_OK;
2508 }
2509
2510 static int evaluate_load_store_multiple_thumb(uint16_t opcode,
2511 uint32_t address, struct arm_instruction *instruction)
2512 {
2513 uint32_t reg_list = opcode & 0xff;
2514 uint32_t L = opcode & (1 << 11);
2515 uint32_t R = opcode & (1 << 8);
2516 uint8_t Rn = (opcode >> 8) & 7;
2517 uint8_t addr_mode = 0 /* IA */;
2518 char reg_names[40];
2519 char *reg_names_p;
2520 char *mnemonic;
2521 char ptr_name[7] = "";
2522 int i;
2523
2524 /* REVISIT: in ThumbEE mode, there are no LDM or STM instructions.
2525 * The STMIA and LDMIA opcodes are used for other instructions.
2526 */
2527
2528 if ((opcode & 0xf000) == 0xc000) { /* generic load/store multiple */
2529 char *wback = "!";
2530
2531 if (L) {
2532 instruction->type = ARM_LDM;
2533 mnemonic = "LDM";
2534 if (opcode & (1 << Rn))
2535 wback = "";
2536 } else {
2537 instruction->type = ARM_STM;
2538 mnemonic = "STM";
2539 }
2540 snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback);
2541 } else {/* push/pop */
2542 Rn = 13;/* SP */
2543 if (L) {
2544 instruction->type = ARM_LDM;
2545 mnemonic = "POP";
2546 if (R)
2547 reg_list |= (1 << 15) /*PC*/;
2548 } else {
2549 instruction->type = ARM_STM;
2550 mnemonic = "PUSH";
2551 addr_mode = 3; /*DB*/
2552 if (R)
2553 reg_list |= (1 << 14) /*LR*/;
2554 }
2555 }
2556
2557 reg_names_p = reg_names;
2558 for (i = 0; i <= 15; i++) {
2559 if (reg_list & (1 << i))
2560 reg_names_p += snprintf(reg_names_p,
2561 (reg_names + 40 - reg_names_p),
2562 "r%i, ",
2563 i);
2564 }
2565 if (reg_names_p > reg_names)
2566 reg_names_p[-2] = '\0';
2567 else /* invalid op : no registers */
2568 reg_names[0] = '\0';
2569
2570 snprintf(instruction->text, 128,
2571 "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%s{%s}",
2572 address, opcode, mnemonic, ptr_name, reg_names);
2573
2574 instruction->info.load_store_multiple.register_list = reg_list;
2575 instruction->info.load_store_multiple.Rn = Rn;
2576 instruction->info.load_store_multiple.addressing_mode = addr_mode;
2577
2578 return ERROR_OK;
2579 }
2580
2581 static int evaluate_cond_branch_thumb(uint16_t opcode,
2582 uint32_t address, struct arm_instruction *instruction)
2583 {
2584 uint32_t offset = opcode & 0xff;
2585 uint8_t cond = (opcode >> 8) & 0xf;
2586 uint32_t target_address;
2587
2588 if (cond == 0xf) {
2589 instruction->type = ARM_SWI;
2590 snprintf(instruction->text, 128,
2591 "0x%8.8" PRIx32 " 0x%4.4x \tSVC\t%#2.2" PRIx32,
2592 address, opcode, offset);
2593 return ERROR_OK;
2594 } else if (cond == 0xe) {
2595 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2596 snprintf(instruction->text, 128,
2597 "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION",
2598 address, opcode);
2599 return ERROR_OK;
2600 }
2601
2602 /* sign extend 8-bit offset */
2603 if (offset & 0x00000080)
2604 offset = 0xffffff00 | offset;
2605
2606 target_address = address + 4 + (offset << 1);
2607
2608 snprintf(instruction->text, 128,
2609 "0x%8.8" PRIx32 " 0x%4.4x \tB%s\t%#8.8" PRIx32,
2610 address, opcode,
2611 arm_condition_strings[cond], target_address);
2612
2613 instruction->type = ARM_B;
2614 instruction->info.b_bl_bx_blx.reg_operand = -1;
2615 instruction->info.b_bl_bx_blx.target_address = target_address;
2616
2617 return ERROR_OK;
2618 }
2619
2620 static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
2621 struct arm_instruction *instruction)
2622 {
2623 unsigned offset;
2624
2625 /* added in Thumb2 */
2626 offset = (opcode >> 3) & 0x1f;
2627 offset |= (opcode & 0x0200) >> 4;
2628
2629 snprintf(instruction->text, 128,
2630 "0x%8.8" PRIx32 " 0x%4.4x \tCB%sZ\tr%d, %#8.8" PRIx32,
2631 address, opcode,
2632 (opcode & 0x0800) ? "N" : "",
2633 opcode & 0x7, address + 4 + (offset << 1));
2634
2635 return ERROR_OK;
2636 }
2637
2638 static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
2639 struct arm_instruction *instruction)
2640 {
2641 /* added in ARMv6 */
2642 snprintf(instruction->text, 128,
2643 "0x%8.8" PRIx32 " 0x%4.4x \t%cXT%c\tr%d, r%d",
2644 address, opcode,
2645 (opcode & 0x0080) ? 'U' : 'S',
2646 (opcode & 0x0040) ? 'B' : 'H',
2647 opcode & 0x7, (opcode >> 3) & 0x7);
2648
2649 return ERROR_OK;
2650 }
2651
2652 static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
2653 struct arm_instruction *instruction)
2654 {
2655 /* added in ARMv6 */
2656 if ((opcode & 0x0ff0) == 0x0650)
2657 snprintf(instruction->text, 128,
2658 "0x%8.8" PRIx32 " 0x%4.4x \tSETEND %s",
2659 address, opcode,
2660 (opcode & 0x80) ? "BE" : "LE");
2661 else /* ASSUME (opcode & 0x0fe0) == 0x0660 */
2662 snprintf(instruction->text, 128,
2663 "0x%8.8" PRIx32 " 0x%4.4x \tCPSI%c\t%s%s%s",
2664 address, opcode,
2665 (opcode & 0x0010) ? 'D' : 'E',
2666 (opcode & 0x0004) ? "A" : "",
2667 (opcode & 0x0002) ? "I" : "",
2668 (opcode & 0x0001) ? "F" : "");
2669
2670 return ERROR_OK;
2671 }
2672
2673 static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
2674 struct arm_instruction *instruction)
2675 {
2676 char *suffix;
2677
2678 /* added in ARMv6 */
2679 switch ((opcode >> 6) & 3) {
2680 case 0:
2681 suffix = "";
2682 break;
2683 case 1:
2684 suffix = "16";
2685 break;
2686 default:
2687 suffix = "SH";
2688 break;
2689 }
2690 snprintf(instruction->text, 128,
2691 "0x%8.8" PRIx32 " 0x%4.4x \tREV%s\tr%d, r%d",
2692 address, opcode, suffix,
2693 opcode & 0x7, (opcode >> 3) & 0x7);
2694
2695 return ERROR_OK;
2696 }
2697
2698 static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
2699 struct arm_instruction *instruction)
2700 {
2701 char *hint;
2702
2703 switch ((opcode >> 4) & 0x0f) {
2704 case 0:
2705 hint = "NOP";
2706 break;
2707 case 1:
2708 hint = "YIELD";
2709 break;
2710 case 2:
2711 hint = "WFE";
2712 break;
2713 case 3:
2714 hint = "WFI";
2715 break;
2716 case 4:
2717 hint = "SEV";
2718 break;
2719 default:
2720 hint = "HINT (UNRECOGNIZED)";
2721 break;
2722 }
2723
2724 snprintf(instruction->text, 128,
2725 "0x%8.8" PRIx32 " 0x%4.4x \t%s",
2726 address, opcode, hint);
2727
2728 return ERROR_OK;
2729 }
2730
2731 static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
2732 struct arm_instruction *instruction)
2733 {
2734 unsigned cond = (opcode >> 4) & 0x0f;
2735 char *x = "", *y = "", *z = "";
2736
2737 if (opcode & 0x01)
2738 z = (opcode & 0x02) ? "T" : "E";
2739 if (opcode & 0x03)
2740 y = (opcode & 0x04) ? "T" : "E";
2741 if (opcode & 0x07)
2742 x = (opcode & 0x08) ? "T" : "E";
2743
2744 snprintf(instruction->text, 128,
2745 "0x%8.8" PRIx32 " 0x%4.4x \tIT%s%s%s\t%s",
2746 address, opcode,
2747 x, y, z, arm_condition_strings[cond]);
2748
2749 /* NOTE: strictly speaking, the next 1-4 instructions should
2750 * now be displayed with the relevant conditional suffix...
2751 */
2752
2753 return ERROR_OK;
2754 }
2755
2756 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
2757 {
2758 /* clear fields, to avoid confusion */
2759 memset(instruction, 0, sizeof(struct arm_instruction));
2760 instruction->opcode = opcode;
2761 instruction->instruction_size = 2;
2762
2763 if ((opcode & 0xe000) == 0x0000) {
2764 /* add/substract register or immediate */
2765 if ((opcode & 0x1800) == 0x1800)
2766 return evaluate_add_sub_thumb(opcode, address, instruction);
2767 /* shift by immediate */
2768 else
2769 return evaluate_shift_imm_thumb(opcode, address, instruction);
2770 }
2771
2772 /* Add/substract/compare/move immediate */
2773 if ((opcode & 0xe000) == 0x2000)
2774 return evaluate_data_proc_imm_thumb(opcode, address, instruction);
2775
2776 /* Data processing instructions */
2777 if ((opcode & 0xf800) == 0x4000)
2778 return evaluate_data_proc_thumb(opcode, address, instruction);
2779
2780 /* Load from literal pool */
2781 if ((opcode & 0xf800) == 0x4800)
2782 return evaluate_load_literal_thumb(opcode, address, instruction);
2783
2784 /* Load/Store register offset */
2785 if ((opcode & 0xf000) == 0x5000)
2786 return evaluate_load_store_reg_thumb(opcode, address, instruction);
2787
2788 /* Load/Store immediate offset */
2789 if (((opcode & 0xe000) == 0x6000)
2790 || ((opcode & 0xf000) == 0x8000))
2791 return evaluate_load_store_imm_thumb(opcode, address, instruction);
2792
2793 /* Load/Store from/to stack */
2794 if ((opcode & 0xf000) == 0x9000)
2795 return evaluate_load_store_stack_thumb(opcode, address, instruction);
2796
2797 /* Add to SP/PC */
2798 if ((opcode & 0xf000) == 0xa000)
2799 return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2800
2801 /* Misc */
2802 if ((opcode & 0xf000) == 0xb000) {
2803 switch ((opcode >> 8) & 0x0f) {
2804 case 0x0:
2805 return evaluate_adjust_stack_thumb(opcode, address, instruction);
2806 case 0x1:
2807 case 0x3:
2808 case 0x9:
2809 case 0xb:
2810 return evaluate_cb_thumb(opcode, address, instruction);
2811 case 0x2:
2812 return evaluate_extend_thumb(opcode, address, instruction);
2813 case 0x4:
2814 case 0x5:
2815 case 0xc:
2816 case 0xd:
2817 return evaluate_load_store_multiple_thumb(opcode, address,
2818 instruction);
2819 case 0x6:
2820 return evaluate_cps_thumb(opcode, address, instruction);
2821 case 0xa:
2822 if ((opcode & 0x00c0) == 0x0080)
2823 break;
2824 return evaluate_byterev_thumb(opcode, address, instruction);
2825 case 0xe:
2826 return evaluate_breakpoint_thumb(opcode, address, instruction);
2827 case 0xf:
2828 if (opcode & 0x000f)
2829 return evaluate_ifthen_thumb(opcode, address,
2830 instruction);
2831 else
2832 return evaluate_hint_thumb(opcode, address,
2833 instruction);
2834 }
2835
2836 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2837 snprintf(instruction->text, 128,
2838 "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION",
2839 address, opcode);
2840 return ERROR_OK;
2841 }
2842
2843 /* Load/Store multiple */
2844 if ((opcode & 0xf000) == 0xc000)
2845 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2846
2847 /* Conditional branch + SWI */
2848 if ((opcode & 0xf000) == 0xd000)
2849 return evaluate_cond_branch_thumb(opcode, address, instruction);
2850
2851 if ((opcode & 0xe000) == 0xe000) {
2852 /* Undefined instructions */
2853 if ((opcode & 0xf801) == 0xe801) {
2854 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2855 snprintf(instruction->text, 128,
2856 "0x%8.8" PRIx32 " 0x%8.8x\t"
2857 "UNDEFINED INSTRUCTION",
2858 address, opcode);
2859 return ERROR_OK;
2860 } else /* Branch to offset */
2861 return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2862 }
2863
2864 LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
2865 return -1;
2866 }
2867
2868 static int t2ev_b_bl(uint32_t opcode, uint32_t address,
2869 struct arm_instruction *instruction, char *cp)
2870 {
2871 unsigned offset;
2872 unsigned b21 = 1 << 21;
2873 unsigned b22 = 1 << 22;
2874
2875 /* instead of combining two smaller 16-bit branch instructions,
2876 * Thumb2 uses only one larger 32-bit instruction.
2877 */
2878 offset = opcode & 0x7ff;
2879 offset |= (opcode & 0x03ff0000) >> 5;
2880 if (opcode & (1 << 26)) {
2881 offset |= 0xff << 23;
2882 if ((opcode & (1 << 11)) == 0)
2883 b21 = 0;
2884 if ((opcode & (1 << 13)) == 0)
2885 b22 = 0;
2886 } else {
2887 if (opcode & (1 << 11))
2888 b21 = 0;
2889 if (opcode & (1 << 13))
2890 b22 = 0;
2891 }
2892 offset |= b21;
2893 offset |= b22;
2894
2895
2896 address += 4;
2897 address += offset << 1;
2898
2899 instruction->type = (opcode & (1 << 14)) ? ARM_BL : ARM_B;
2900 instruction->info.b_bl_bx_blx.reg_operand = -1;
2901 instruction->info.b_bl_bx_blx.target_address = address;
2902 sprintf(cp, "%s\t%#8.8" PRIx32,
2903 (opcode & (1 << 14)) ? "BL" : "B.W",
2904 address);
2905
2906 return ERROR_OK;
2907 }
2908
2909 static int t2ev_cond_b(uint32_t opcode, uint32_t address,
2910 struct arm_instruction *instruction, char *cp)
2911 {
2912 unsigned offset;
2913 unsigned b17 = 1 << 17;
2914 unsigned b18 = 1 << 18;
2915 unsigned cond = (opcode >> 22) & 0x0f;
2916
2917 offset = opcode & 0x7ff;
2918 offset |= (opcode & 0x003f0000) >> 5;
2919 if (opcode & (1 << 26)) {
2920 offset |= 0x1fff << 19;
2921 if ((opcode & (1 << 11)) == 0)
2922 b17 = 0;
2923 if ((opcode & (1 << 13)) == 0)
2924 b18 = 0;
2925 } else {
2926 if (opcode & (1 << 11))
2927 b17 = 0;
2928 if (opcode & (1 << 13))
2929 b18 = 0;
2930 }
2931 offset |= b17;
2932 offset |= b18;
2933
2934 address += 4;
2935 address += offset << 1;
2936
2937 instruction->type = ARM_B;
2938 instruction->info.b_bl_bx_blx.reg_operand = -1;
2939 instruction->info.b_bl_bx_blx.target_address = address;
2940 sprintf(cp, "B%s.W\t%#8.8" PRIx32,
2941 arm_condition_strings[cond],
2942 address);
2943
2944 return ERROR_OK;
2945 }
2946
2947 static const char *special_name(int number)
2948 {
2949 char *special = "(RESERVED)";
2950
2951 switch (number) {
2952 case 0:
2953 special = "apsr";
2954 break;
2955 case 1:
2956 special = "iapsr";
2957 break;
2958 case 2:
2959 special = "eapsr";
2960 break;
2961 case 3:
2962 special = "xpsr";
2963 break;
2964 case 5:
2965 special = "ipsr";
2966 break;
2967 case 6:
2968 special = "epsr";
2969 break;
2970 case 7:
2971 special = "iepsr";
2972 break;
2973 case 8:
2974 special = "msp";
2975 break;
2976 case 9:
2977 special = "psp";
2978 break;
2979 case 16:
2980 special = "primask";
2981 break;
2982 case 17:
2983 special = "basepri";
2984 break;
2985 case 18:
2986 special = "basepri_max";
2987 break;
2988 case 19:
2989 special = "faultmask";
2990 break;
2991 case 20:
2992 special = "control";
2993 break;
2994 }
2995 return special;
2996 }
2997
2998 static int t2ev_hint(uint32_t opcode, uint32_t address,
2999 struct arm_instruction *instruction, char *cp)
3000 {
3001 const char *mnemonic;
3002
3003 if (opcode & 0x0700) {
3004 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3005 strcpy(cp, "UNDEFINED");
3006 return ERROR_OK;
3007 }
3008
3009 if (opcode & 0x00f0) {
3010 sprintf(cp, "DBG\t#%d", (int) opcode & 0xf);
3011 return ERROR_OK;
3012 }
3013
3014 switch (opcode & 0x0f) {
3015 case 0:
3016 mnemonic = "NOP.W";
3017 break;
3018 case 1:
3019 mnemonic = "YIELD.W";
3020 break;
3021 case 2:
3022 mnemonic = "WFE.W";
3023 break;
3024 case 3:
3025 mnemonic = "WFI.W";
3026 break;
3027 case 4:
3028 mnemonic = "SEV.W";
3029 break;
3030 default:
3031 mnemonic = "HINT.W (UNRECOGNIZED)";
3032 break;
3033 }
3034 strcpy(cp, mnemonic);
3035 return ERROR_OK;
3036 }
3037
3038 static int t2ev_misc(uint32_t opcode, uint32_t address,
3039 struct arm_instruction *instruction, char *cp)
3040 {
3041 const char *mnemonic;
3042
3043 switch ((opcode >> 4) & 0x0f) {
3044 case 0:
3045 mnemonic = "LEAVEX";
3046 break;
3047 case 1:
3048 mnemonic = "ENTERX";
3049 break;
3050 case 2:
3051 mnemonic = "CLREX";
3052 break;
3053 case 4:
3054 mnemonic = "DSB";
3055 break;
3056 case 5:
3057 mnemonic = "DMB";
3058 break;
3059 case 6:
3060 mnemonic = "ISB";
3061 break;
3062 default:
3063 return ERROR_COMMAND_SYNTAX_ERROR;
3064 }
3065 strcpy(cp, mnemonic);
3066 return ERROR_OK;
3067 }
3068
3069 static int t2ev_b_misc(uint32_t opcode, uint32_t address,
3070 struct arm_instruction *instruction, char *cp)
3071 {
3072 /* permanently undefined */
3073 if ((opcode & 0x07f07000) == 0x07f02000) {
3074 instruction->type = ARM_UNDEFINED_INSTRUCTION;
3075 strcpy(cp, "UNDEFINED");
3076 return ERROR_OK;
3077 }
3078
3079 switch ((opcode >> 12) & 0x5) {
3080 case 0x1:
3081 case 0x5:
3082 return t2ev_b_bl(opcode, address, instruction, cp);
3083 case 0x4:
3084 goto undef;
3085 case 0:
3086 if (((opcode >> 23) & 0x07) != 0x07)
3087 return t2ev_cond_b(opcode, address, instruction, cp);
3088 if (opcode & (1 << 26))
3089 goto undef;
3090 break;
3091 }
3092
3093 switch ((opcode >> 20) & 0x7f) {
3094 case 0x38:
3095 case 0x39:
3096 sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff),
3097 (int) (opcode >> 16) & 0x0f);
3098 return ERROR_OK;
3099 case 0x3a:
3100 return t2ev_hint(opcode, address, instruction, cp);
3101 case 0x3b:
3102 return t2ev_misc(opcode, address, instruction, cp);
3103 case 0x3c:
3104 sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f);
3105 return ERROR_OK;
3106 case 0x3e:
3107 case 0x3f:
3108 sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f,
3109 special_name(opcode & 0xff));
3110 return ERROR_OK;
3111 }
3112
3113 undef:
3114 return ERROR_COMMAND_SYNTAX_ERROR;
3115 }
3116
3117 static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
3118 struct arm_instruction *instruction, char *cp)
3119 {
3120 char *mnemonic = NULL;
3121 int rn = (opcode >> 16) & 0xf;
3122 int rd = (opcode >> 8) & 0xf;
3123 unsigned immed = opcode & 0xff;
3124 unsigned func;
3125 bool one = false;
3126 char *suffix = "";
3127 char *suffix2 = "";
3128
3129 /* ARMv7-M: A5.3.2 Modified immediate constants */
3130 func = (opcode >> 11) & 0x0e;
3131 if (immed & 0x80)
3132 func |= 1;
3133 if (opcode & (1 << 26))
3134 func |= 0x10;
3135
3136 /* "Modified" immediates */
3137 switch (func >> 1) {
3138 case 0:
3139 break;
3140 case 2:
3141 immed <<= 8;
3142 /* FALLTHROUGH */
3143 case 1:
3144 immed += immed << 16;
3145 break;
3146 case 3:
3147 immed += immed << 8;
3148 immed += immed << 16;
3149 break;
3150 default:
3151 immed |= 0x80;
3152 immed = ror(immed, func);
3153 }
3154
3155 if (opcode & (1 << 20))
3156 suffix = "S";
3157
3158 switch ((opcode >> 21) & 0xf) {
3159 case 0:
3160 if (rd == 0xf) {
3161 instruction->type = ARM_TST;
3162 mnemonic = "TST";
3163 one = true;
3164 suffix = "";
3165 rd = rn;
3166 } else {
3167 instruction->type = ARM_AND;
3168 mnemonic = "AND";
3169 }
3170 break;
3171 case 1:
3172 instruction->type = ARM_BIC;
3173 mnemonic = "BIC";
3174 break;
3175 case 2:
3176 if (rn == 0xf) {
3177 instruction->type = ARM_MOV;
3178 mnemonic = "MOV";
3179 one = true;
3180 suffix2 = ".W";
3181 } else {
3182 instruction->type = ARM_ORR;
3183 mnemonic = "ORR";
3184 }
3185 break;
3186 case 3:
3187 if (rn == 0xf) {
3188 instruction->type = ARM_MVN;
3189 mnemonic = "MVN";
3190 one = true;
3191 } else {
3192 /* instruction->type = ARM_ORN; */
3193 mnemonic = "ORN";
3194 }
3195 break;
3196 case 4:
3197 if (rd == 0xf) {
3198 instruction->type = ARM_TEQ;
3199 mnemonic = "TEQ";
3200 one = true;
3201 suffix = "";
3202 rd = rn;
3203 } else {
3204 instruction->type = ARM_EOR;
3205 mnemonic = "EOR";
3206 }
3207 break;
3208 case 8:
3209 if (rd == 0xf) {
3210 instruction->type = ARM_CMN;
3211 mnemonic = "CMN";
3212 one = true;
3213 suffix = "";
3214 rd = rn;
3215 } else {
3216 instruction->type = ARM_ADD;
3217 mnemonic = "ADD";
3218 suffix2 = ".W";
3219 }
3220 break;
3221 case 10:
3222 instruction->type = ARM_ADC;
3223 mnemonic = "ADC";
3224 suffix2 = ".W";
3225 break;
3226 case 11:
3227 instruction->type = ARM_SBC;
3228 mnemonic = "SBC";
3229 break;
3230 case 13:
3231 if (rd == 0xf) {
3232 instruction->type = ARM_CMP;
3233 mnemonic = "CMP";
3234 one = true;
3235 suffix = "";
3236 rd = rn;
3237 } else {
3238 instruction->type = ARM_SUB;
3239 mnemonic = "SUB";
3240 }
3241 suffix2 = ".W";
3242 break;
3243 case 14:
3244 instruction->type = ARM_RSB;
3245 mnemonic = "RSB";
3246 suffix2 = ".W";
3247 break;
3248 default:
3249 return ERROR_COMMAND_SYNTAX_ERROR;
3250 }
3251
3252 if (one)
3253 sprintf(cp, "%s%s\tr%d, #%d\t; %#8.8x",
3254 mnemonic, suffix2, rd, immed, immed);
3255 else
3256 sprintf(cp, "%s%s%s\tr%d, r%d, #%d\t; %#8.8x",
3257 mnemonic, suffix, suffix2,
3258 rd, rn, immed, immed);
3259
3260 return ERROR_OK;
3261 }
3262
3263 static int t2ev_data_immed(uint32_t opcode, uint32_t address,
3264 struct arm_instruction *instruction, char *cp)
3265 {
3266 char *mnemonic = NULL;
3267 int rn = (opcode >> 16) & 0xf;
3268 int rd = (opcode >> 8) & 0xf;
3269 unsigned immed;
3270 bool add = false;
3271 bool is_signed = false;
3272
3273 immed = (opcode & 0x0ff) | ((opcode & 0x7000) >> 4);
3274 if (opcode & (1 << 26))
3275 immed |= (1 << 11);
3276
3277 switch ((opcode >> 20) & 0x1f) {
3278 case 0:
3279 if (rn == 0xf) {
3280 add = true;
3281 goto do_adr;
3282 }
3283 mnemonic = "ADDW";
3284 break;
3285 case 4:
3286 immed |= (opcode >> 4) & 0xf000;
3287 sprintf(cp, "MOVW\tr%d, #%d\t; %#3.3x", rd, immed, immed);
3288 return ERROR_OK;
3289 case 0x0a:
3290 if (rn == 0xf)
3291 goto do_adr;
3292 mnemonic = "SUBW";
3293 break;
3294 case 0x0c:
3295 /* move constant to top 16 bits of register */
3296 immed |= (opcode >> 4) & 0xf000;
3297 sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed);
3298 return ERROR_OK;
3299 case 0x10:
3300 case 0x12:
3301 is_signed = true;
3302 case 0x18:
3303 case 0x1a:
3304 /* signed/unsigned saturated add */
3305 immed = (opcode >> 6) & 0x03;
3306 immed |= (opcode >> 10) & 0x1c;
3307 sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t",
3308 is_signed ? "S" : "U",
3309 rd, (int) (opcode & 0x1f) + is_signed, rn,
3310 (opcode & (1 << 21)) ? "ASR" : "LSL",
3311 immed ? immed : 32);
3312 return ERROR_OK;
3313 case 0x14:
3314 is_signed = true;
3315 /* FALLTHROUGH */
3316 case 0x1c:
3317 /* signed/unsigned bitfield extract */
3318 immed = (opcode >> 6) & 0x03;
3319 immed |= (opcode >> 10) & 0x1c;
3320 sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t",
3321 is_signed ? "S" : "U",
3322 rd, rn, immed,
3323 (int) (opcode & 0x1f) + 1);
3324 return ERROR_OK;
3325 case 0x16:
3326 immed = (opcode >> 6) & 0x03;
3327 immed |= (opcode >> 10) & 0x1c;
3328 if (rn == 0xf) /* bitfield clear */
3329 sprintf(cp, "BFC\tr%d, #%d, #%d\t",
3330 rd, immed,
3331 (int) (opcode & 0x1f) + 1 - immed);
3332 else /* bitfield insert */
3333 sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t",
3334 rd, rn, immed,
3335 (int) (opcode & 0x1f) + 1 - immed);
3336 return ERROR_OK;
3337 default:
3338 return ERROR_COMMAND_SYNTAX_ERROR;
3339 }
3340
3341 sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic,
3342 rd, rn, immed, immed);
3343 return ERROR_OK;
3344
3345 do_adr:
3346 address = thumb_alignpc4(address);
3347 if (add)
3348 address += immed;
3349 else
3350 address -= immed;
3351 /* REVISIT "ADD/SUB Rd, PC, #const ; 0x..." might be better;
3352 * not hiding the pc-relative stuff will sometimes be useful.
3353 */
3354 sprintf(cp, "ADR.W\tr%d, %#8.8" PRIx32, rd, address);
3355 return ERROR_OK;
3356 }
3357
3358 static int t2ev_store_single(uint32_t opcode, uint32_t address,
3359 struct arm_instruction *instruction, char *cp)
3360 {
3361 unsigned op = (opcode >> 20) & 0xf;
3362 char *size = "";
3363 char *suffix = "";
3364 char *p1 = "";
3365 char *p2 = "]";
3366 unsigned immed;
3367 unsigned rn = (opcode >> 16) & 0x0f;
3368 unsigned rt = (opcode >> 12) & 0x0f;
3369
3370 if (rn == 0xf)
3371 return ERROR_COMMAND_SYNTAX_ERROR;
3372
3373 if (opcode & 0x0800)
3374 op |= 1;
3375 switch (op) {
3376 /* byte */
3377 case 0x8:
3378 case 0x9:
3379 size = "B";
3380 goto imm12;
3381 case 0x1:
3382 size = "B";
3383 goto imm8;
3384 case 0x0:
3385 size = "B";
3386 break;
3387 /* halfword */
3388 case 0xa:
3389 case 0xb:
3390 size = "H";
3391 goto imm12;
3392 case 0x3:
3393 size = "H";
3394 goto imm8;
3395 case 0x2:
3396 size = "H";
3397 break;
3398 /* word */
3399 case 0xc:
3400 case 0xd:
3401 goto imm12;
3402 case 0x5:
3403 goto imm8;
3404 case 0x4:
3405 break;
3406 /* error */
3407 default:
3408 return ERROR_COMMAND_SYNTAX_ERROR;
3409 }
3410
3411 sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]",
3412 size, rt, rn, (int) opcode & 0x0f,
3413 (int) (opcode >> 4) & 0x03);
3414 return ERROR_OK;
3415
3416 imm12:
3417 immed = opcode & 0x0fff;
3418 sprintf(cp, "STR%s.W\tr%d, [r%d, #%u]\t; %#3.3x",
3419 size, rt, rn, immed, immed);
3420 return ERROR_OK;
3421
3422 imm8:
3423 immed = opcode & 0x00ff;
3424
3425 switch (opcode & 0x700) {
3426 case 0x600:
3427 suffix = "T";
3428 break;
3429 case 0x000:
3430 case 0x200:
3431 return ERROR_COMMAND_SYNTAX_ERROR;
3432 }
3433
3434 /* two indexed modes will write back rn */
3435 if (opcode & 0x100) {
3436 if (opcode & 0x400) /* pre-indexed */
3437 p2 = "]!";
3438 else { /* post-indexed */
3439 p1 = "]";
3440 p2 = "";
3441 }
3442 }
3443
3444 sprintf(cp, "STR%s%s\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
3445 size, suffix, rt, rn, p1,
3446 (opcode & 0x200) ? "" : "-",
3447 immed, p2, immed);
3448 return ERROR_OK;
3449 }
3450
3451 static int t2ev_mul32(uint32_t opcode, uint32_t address,
3452 struct arm_instruction *instruction, char *cp)
3453 {
3454 int ra = (opcode >> 12) & 0xf;
3455
3456 switch (opcode & 0x007000f0) {
3457 case 0:
3458 if (ra == 0xf)
3459 sprintf(cp, "MUL\tr%d, r%d, r%d",
3460 (int) (opcode >> 8) & 0xf,
3461 (int) (opcode >> 16) & 0xf,
3462 (int) (opcode >> 0) & 0xf);
3463 else
3464 sprintf(cp, "MLA\tr%d, r%d, r%d, r%d",
3465 (int) (opcode >> 8) & 0xf,
3466 (int) (opcode >> 16) & 0xf,
3467 (int) (opcode >> 0) & 0xf, ra);
3468 break;
3469 case 0x10:
3470 sprintf(cp, "MLS\tr%d, r%d, r%d, r%d",
3471 (int) (opcode >> 8) & 0xf,
3472 (int) (opcode >> 16) & 0xf,
3473 (int) (opcode >> 0) & 0xf, ra);
3474 break;
3475 default:
3476 return ERROR_COMMAND_SYNTAX_ERROR;
3477 }
3478 return ERROR_OK;
3479 }
3480
3481 static int t2ev_mul64_div(uint32_t opcode, uint32_t address,
3482 struct arm_instruction *instruction, char *cp)
3483 {
3484 int op = (opcode >> 4) & 0xf;
3485 char *infix = "MUL";
3486
3487 op += (opcode >> 16) & 0x70;
3488 switch (op) {
3489 case 0x40:
3490 case 0x60:
3491 infix = "MLA";
3492 /* FALLTHROUGH */
3493 case 0:
3494 case 0x20:
3495 sprintf(cp, "%c%sL\tr%d, r%d, r%d, r%d",
3496 (op & 0x20) ? 'U' : 'S',
3497 infix,
3498 (int) (opcode >> 12) & 0xf,
3499 (int) (opcode >> 8) & 0xf,
3500 (int) (opcode >> 16) & 0xf,
3501 (int) (opcode >> 0) & 0xf);
3502 break;
3503 case 0x1f:
3504 case 0x3f:
3505 sprintf(cp, "%cDIV\tr%d, r%d, r%d",
3506 (op & 0x20) ? 'U' : 'S',
3507 (int) (opcode >> 8) & 0xf,
3508 (int) (opcode >> 16) & 0xf,
3509 (int) (opcode >> 0) & 0xf);
3510 break;
3511 default:
3512 return ERROR_COMMAND_SYNTAX_ERROR;
3513 }
3514
3515 return ERROR_OK;
3516 }
3517
3518 static int t2ev_ldm_stm(uint32_t opcode, uint32_t address,
3519 struct arm_instruction *instruction, char *cp)
3520 {
3521 int rn = (opcode >> 16) & 0xf;
3522 int op = (opcode >> 22) & 0x6;
3523 int t = (opcode >> 21) & 1;
3524 unsigned registers = opcode & 0xffff;
3525 char *mode = "";
3526
3527 if (opcode & (1 << 20))
3528 op |= 1;
3529
3530 switch (op) {
3531 case 0:
3532 mode = "DB";
3533 /* FALL THROUGH */
3534 case 6:
3535 sprintf(cp, "SRS%s\tsp%s, #%d", mode,
3536 t ? "!" : "",
3537 (unsigned) (opcode & 0x1f));
3538 return ERROR_OK;
3539 case 1:
3540 mode = "DB";
3541 /* FALL THROUGH */
3542 case 7:
3543 sprintf(cp, "RFE%s\tr%d%s", mode,
3544 (unsigned) ((opcode >> 16) & 0xf),
3545 t ? "!" : "");
3546 return ERROR_OK;
3547 case 2:
3548 sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : "");
3549 break;
3550 case 3:
3551 if (rn == 13 && t)
3552 sprintf(cp, "POP.W\t");
3553 else
3554 sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : "");
3555 break;
3556 case 4:
3557 if (rn == 13 && t)
3558 sprintf(cp, "PUSH.W\t");
3559 else
3560 sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : "");
3561 break;
3562 case 5:
3563 sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : "");
3564 break;
3565 default:
3566 return ERROR_COMMAND_SYNTAX_ERROR;
3567 }
3568
3569 cp = strchr(cp, 0);
3570 *cp++ = '{';
3571 for (t = 0; registers; t++, registers >>= 1) {
3572 if ((registers & 1) == 0)
3573 continue;
3574 registers &= ~1;
3575 sprintf(cp, "r%d%s", t, registers ? ", " : "");
3576 cp = strchr(cp, 0);
3577 }
3578 *cp++ = '}';
3579 *cp++ = 0;
3580
3581 return ERROR_OK;
3582 }
3583
3584 /* load/store dual or exclusive, table branch */
3585 static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
3586 struct arm_instruction *instruction, char *cp)
3587 {
3588 unsigned op1op2 = (opcode >> 20) & 0x3;
3589 unsigned op3 = (opcode >> 4) & 0xf;
3590 char *mnemonic;
3591 unsigned rn = (opcode >> 16) & 0xf;
3592 unsigned rt = (opcode >> 12) & 0xf;
3593 unsigned rd = (opcode >> 8) & 0xf;
3594 unsigned imm = opcode & 0xff;
3595 char *p1 = "";
3596 char *p2 = "]";
3597
3598 op1op2 |= (opcode >> 21) & 0xc;
3599 switch (op1op2) {
3600 case 0:
3601 mnemonic = "STREX";
3602 goto strex;
3603 case 1:
3604 mnemonic = "LDREX";
3605 goto ldrex;
3606 case 2:
3607 case 6:
3608 case 8:
3609 case 10:
3610 case 12:
3611 case 14:
3612 mnemonic = "STRD";
3613 goto immediate;
3614 case 3:
3615 case 7:
3616 case 9:
3617 case 11:
3618 case 13:
3619 case 15:
3620 mnemonic = "LDRD";
3621 if (rn == 15)
3622 goto literal;
3623 else
3624 goto immediate;
3625 case 4:
3626 switch (op3) {
3627 case 4:
3628 mnemonic = "STREXB";
3629 break;
3630 case 5:
3631 mnemonic = "STREXH";
3632 break;
3633 default:
3634 return ERROR_COMMAND_SYNTAX_ERROR;
3635 }
3636 rd = opcode & 0xf;
3637 imm = 0;
3638 goto strex;
3639 case 5:
3640 switch (op3) {
3641 case 0:
3642 sprintf(cp, "TBB\t[r%u, r%u]", rn, imm & 0xf);
3643 return ERROR_OK;
3644 case 1:
3645 sprintf(cp, "TBH\t[r%u, r%u, LSL #1]", rn, imm & 0xf);
3646 return ERROR_OK;
3647 case 4:
3648 mnemonic = "LDREXB";
3649 break;
3650 case 5:
3651 mnemonic = "LDREXH";
3652 break;
3653 default:
3654 return ERROR_COMMAND_SYNTAX_ERROR;
3655 }
3656 imm = 0;
3657 goto ldrex;
3658 }
3659 return ERROR_COMMAND_SYNTAX_ERROR;
3660
3661 strex:
3662 imm <<= 2;
3663 if (imm)
3664 sprintf(cp, "%s\tr%u, r%u, [r%u, #%u]\t; %#2.2x",
3665 mnemonic, rd, rt, rn, imm, imm);
3666 else
3667 sprintf(cp, "%s\tr%u, r%u, [r%u]",
3668 mnemonic, rd, rt, rn);
3669 return ERROR_OK;
3670
3671 ldrex:
3672 imm <<= 2;
3673 if (imm)
3674 sprintf(cp, "%s\tr%u, [r%u, #%u]\t; %#2.2x",
3675 mnemonic, rt, rn, imm, imm);
3676 else
3677 sprintf(cp, "%s\tr%u, [r%u]",
3678 mnemonic, rt, rn);
3679 return ERROR_OK;
3680
3681 immediate:
3682 /* two indexed modes will write back rn */
3683 if (opcode & (1 << 21)) {
3684 if (opcode & (1 << 24)) /* pre-indexed */
3685 p2 = "]!";
3686 else { /* post-indexed */
3687 p1 = "]";
3688 p2 = "";
3689 }
3690 }
3691
3692 imm <<= 2;
3693 sprintf(cp, "%s\tr%u, r%u, [r%u%s, #%s%u%s\t; %#2.2x",
3694 mnemonic, rt, rd, rn, p1,
3695 (opcode & (1 << 23)) ? "" : "-",
3696 imm, p2, imm);
3697 return ERROR_OK;
3698
3699 literal:
3700 address = thumb_alignpc4(address);
3701 imm <<= 2;
3702 if (opcode & (1 << 23))
3703 address += imm;
3704 else
3705 address -= imm;
3706 sprintf(cp, "%s\tr%u, r%u, %#8.8" PRIx32,
3707 mnemonic, rt, rd, address);
3708 return ERROR_OK;
3709 }
3710
3711 static int t2ev_data_shift(uint32_t opcode, uint32_t address,
3712 struct arm_instruction *instruction, char *cp)
3713 {
3714 int op = (opcode >> 21) & 0xf;
3715 int rd = (opcode >> 8) & 0xf;
3716 int rn = (opcode >> 16) & 0xf;
3717 int type = (opcode >> 4) & 0x3;
3718 int immed = (opcode >> 6) & 0x3;
3719 char *mnemonic;
3720 char *suffix = "";
3721
3722 immed |= (opcode >> 10) & 0x1c;
3723 if (opcode & (1 << 20))
3724 suffix = "S";
3725
3726 switch (op) {
3727 case 0:
3728 if (rd == 0xf) {
3729 if (!(opcode & (1 << 20)))
3730 return ERROR_COMMAND_SYNTAX_ERROR;
3731 instruction->type = ARM_TST;
3732 mnemonic = "TST";
3733 suffix = "";
3734 goto two;
3735 }
3736 instruction->type = ARM_AND;
3737 mnemonic = "AND";
3738 break;
3739 case 1:
3740 instruction->type = ARM_BIC;
3741 mnemonic = "BIC";
3742 break;
3743 case 2:
3744 if (rn == 0xf) {
3745 instruction->type = ARM_MOV;
3746 switch (type) {
3747 case 0:
3748 if (immed == 0) {
3749 sprintf(cp, "MOV%s.W\tr%d, r%d",
3750 suffix, rd,
3751 (int) (opcode & 0xf));
3752 return ERROR_OK;
3753 }
3754 mnemonic = "LSL";
3755 break;
3756 case 1:
3757 mnemonic = "LSR";
3758 break;
3759 case 2:
3760 mnemonic = "ASR";
3761 break;
3762 default:
3763 if (immed == 0) {
3764 sprintf(cp, "RRX%s\tr%d, r%d",
3765 suffix, rd,
3766 (int) (opcode & 0xf));
3767 return ERROR_OK;
3768 }
3769 mnemonic = "ROR";
3770 break;
3771 }
3772 goto immediate;
3773 } else {
3774 instruction->type = ARM_ORR;
3775 mnemonic = "ORR";
3776 }
3777 break;
3778 case 3:
3779 if (rn == 0xf) {
3780 instruction->type = ARM_MVN;
3781 mnemonic = "MVN";
3782 rn = rd;
3783 goto two;
3784 } else {
3785 /* instruction->type = ARM_ORN; */
3786 mnemonic = "ORN";
3787 }
3788 break;
3789 case 4:
3790 if (rd == 0xf) {
3791 if (!(opcode & (1 << 20)))
3792 return ERROR_COMMAND_SYNTAX_ERROR;
3793 instruction->type = ARM_TEQ;
3794 mnemonic = "TEQ";
3795 suffix = "";
3796 goto two;
3797 }
3798 instruction->type = ARM_EOR;
3799 mnemonic = "EOR";
3800 break;
3801 case 8:
3802 if (rd == 0xf) {
3803 if (!(opcode & (1 << 20)))
3804 return ERROR_COMMAND_SYNTAX_ERROR;
3805 instruction->type = ARM_CMN;
3806 mnemonic = "CMN";
3807 suffix = "";
3808 goto two;
3809 }
3810 instruction->type = ARM_ADD;
3811 mnemonic = "ADD";
3812 break;
3813 case 0xa:
3814 instruction->type = ARM_ADC;
3815 mnemonic = "ADC";
3816 break;
3817 case 0xb:
3818 instruction->type = ARM_SBC;
3819 mnemonic = "SBC";
3820 break;
3821 case 0xd:
3822 if (rd == 0xf) {
3823 if (!(opcode & (1 << 21)))
3824 return ERROR_COMMAND_SYNTAX_ERROR;
3825 instruction->type = ARM_CMP;
3826 mnemonic = "CMP";
3827 suffix = "";
3828 goto two;
3829 }
3830 instruction->type = ARM_SUB;
3831 mnemonic = "SUB";
3832 break;
3833 case 0xe:
3834 instruction->type = ARM_RSB;
3835 mnemonic = "RSB";
3836 break;
3837 default:
3838 return ERROR_COMMAND_SYNTAX_ERROR;
3839 }
3840
3841 sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
3842 mnemonic, suffix, rd, rn, (int) (opcode & 0xf));
3843
3844 shift:
3845 cp = strchr(cp, 0);
3846
3847 switch (type) {
3848 case 0:
3849 if (immed == 0)
3850 return ERROR_OK;
3851 suffix = "LSL";
3852 break;
3853 case 1:
3854 suffix = "LSR";
3855 if (immed == 32)
3856 immed = 0;
3857 break;
3858 case 2:
3859 suffix = "ASR";
3860 if (immed == 32)
3861 immed = 0;
3862 break;
3863 case 3:
3864 if (immed == 0) {
3865 strcpy(cp, ", RRX");
3866 return ERROR_OK;
3867 }
3868 suffix = "ROR";
3869 break;
3870 }
3871 sprintf(cp, ", %s #%d", suffix, immed ? immed : 32);
3872 return ERROR_OK;
3873
3874 two:
3875 sprintf(cp, "%s%s.W\tr%d, r%d",
3876 mnemonic, suffix, rn, (int) (opcode & 0xf));
3877 goto shift;
3878
3879 immediate:
3880 sprintf(cp, "%s%s.W\tr%d, r%d, #%d",
3881 mnemonic, suffix, rd,
3882 (int) (opcode & 0xf), immed ? immed : 32);
3883 return ERROR_OK;
3884 }
3885
3886 static int t2ev_data_reg(uint32_t opcode, uint32_t address,
3887 struct arm_instruction *instruction, char *cp)
3888 {
3889 char *mnemonic;
3890 char *suffix = "";
3891
3892 if (((opcode >> 4) & 0xf) == 0) {
3893 switch ((opcode >> 21) & 0x7) {
3894 case 0:
3895 mnemonic = "LSL";
3896 break;
3897 case 1:
3898 mnemonic = "LSR";
3899 break;
3900 case 2:
3901 mnemonic = "ASR";
3902 break;
3903 case 3:
3904 mnemonic = "ROR";
3905 break;
3906 default:
3907 return ERROR_COMMAND_SYNTAX_ERROR;
3908 }
3909
3910 instruction->type = ARM_MOV;
3911 if (opcode & (1 << 20))
3912 suffix = "S";
3913 sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
3914 mnemonic, suffix,
3915 (int) (opcode >> 8) & 0xf,
3916 (int) (opcode >> 16) & 0xf,
3917 (int) (opcode >> 0) & 0xf);
3918
3919 } else if (opcode & (1 << 7)) {
3920 switch ((opcode >> 20) & 0xf) {
3921 case 0:
3922 case 1:
3923 case 4:
3924 case 5:
3925 switch ((opcode >> 4) & 0x3) {
3926 case 1:
3927 suffix = ", ROR #8";
3928 break;
3929 case 2:
3930 suffix = ", ROR #16";
3931 break;
3932 case 3:
3933 suffix = ", ROR #24";
3934 break;
3935 }
3936 sprintf(cp, "%cXT%c.W\tr%d, r%d%s",
3937 (opcode & (1 << 24)) ? 'U' : 'S',
3938 (opcode & (1 << 26)) ? 'B' : 'H',
3939 (int) (opcode >> 8) & 0xf,
3940 (int) (opcode >> 0) & 0xf,
3941 suffix);
3942 break;
3943 case 8:
3944 case 9:
3945 case 0xa:
3946 case 0xb:
3947 if (opcode & (1 << 6))
3948 return ERROR_COMMAND_SYNTAX_ERROR;
3949 if (((opcode >> 12) & 0xf) != 0xf)
3950 return ERROR_COMMAND_SYNTAX_ERROR;
3951 if (!(opcode & (1 << 20)))
3952 return ERROR_COMMAND_SYNTAX_ERROR;
3953
3954 switch (((opcode >> 19) & 0x04)
3955 | ((opcode >> 4) & 0x3)) {
3956 case 0:
3957 mnemonic = "REV.W";
3958 break;
3959 case 1:
3960 mnemonic = "REV16.W";
3961 break;
3962 case 2:
3963 mnemonic = "RBIT";
3964 break;
3965 case 3:
3966 mnemonic = "REVSH.W";
3967 break;
3968 case 4:
3969 mnemonic = "CLZ";
3970 break;
3971 default:
3972 return ERROR_COMMAND_SYNTAX_ERROR;
3973 }
3974 sprintf(cp, "%s\tr%d, r%d",
3975 mnemonic,
3976 (int) (opcode >> 8) & 0xf,
3977 (int) (opcode >> 0) & 0xf);
3978 break;
3979 default:
3980 return ERROR_COMMAND_SYNTAX_ERROR;
3981 }
3982 }
3983
3984 return ERROR_OK;
3985 }
3986
3987 static int t2ev_load_word(uint32_t opcode, uint32_t address,
3988 struct arm_instruction *instruction, char *cp)
3989 {
3990 int rn = (opcode >> 16) & 0xf;
3991 int immed;
3992
3993 instruction->type = ARM_LDR;
3994
3995 if (rn == 0xf) {
3996 immed = opcode & 0x0fff;
3997 if ((opcode & (1 << 23)) == 0)
3998 immed = -immed;
3999 sprintf(cp, "LDR\tr%d, %#8.8" PRIx32,
4000 (int) (opcode >> 12) & 0xf,
4001 thumb_alignpc4(address) + immed);
4002 return ERROR_OK;
4003 }
4004
4005 if (opcode & (1 << 23)) {
4006 immed = opcode & 0x0fff;
4007 sprintf(cp, "LDR.W\tr%d, [r%d, #%d]\t; %#3.3x",
4008 (int) (opcode >> 12) & 0xf,
4009 rn, immed, immed);
4010 return ERROR_OK;
4011 }
4012
4013 if (!(opcode & (0x3f << 6))) {
4014 sprintf(cp, "LDR.W\tr%d, [r%d, r%d, LSL #%d]",
4015 (int) (opcode >> 12) & 0xf,
4016 rn,
4017 (int) (opcode >> 0) & 0xf,
4018 (int) (opcode >> 4) & 0x3);
4019 return ERROR_OK;
4020 }
4021
4022
4023 if (((opcode >> 8) & 0xf) == 0xe) {
4024 immed = opcode & 0x00ff;
4025
4026 sprintf(cp, "LDRT\tr%d, [r%d, #%d]\t; %#2.2x",
4027 (int) (opcode >> 12) & 0xf,
4028 rn, immed, immed);
4029 return ERROR_OK;
4030 }
4031
4032 if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) {
4033 char *p1 = "]", *p2 = "";
4034
4035 if (!(opcode & 0x0500))
4036 return ERROR_COMMAND_SYNTAX_ERROR;
4037
4038 immed = opcode & 0x00ff;
4039
4040 /* two indexed modes will write back rn */
4041 if (opcode & 0x100) {
4042 if (opcode & 0x400) /* pre-indexed */
4043 p2 = "]!";
4044 else { /* post-indexed */
4045 p1 = "]";
4046 p2 = "";
4047 }
4048 }
4049
4050 sprintf(cp, "LDR\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
4051 (int) (opcode >> 12) & 0xf,
4052 rn, p1,
4053 (opcode & 0x200) ? "" : "-",
4054 immed, p2, immed);
4055 return ERROR_OK;
4056 }
4057
4058 return ERROR_COMMAND_SYNTAX_ERROR;
4059 }
4060
4061 static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address,
4062 struct arm_instruction *instruction, char *cp)
4063 {
4064 int rn = (opcode >> 16) & 0xf;
4065 int rt = (opcode >> 12) & 0xf;
4066 int op2 = (opcode >> 6) & 0x3f;
4067 unsigned immed;
4068 char *p1 = "", *p2 = "]";
4069 char *mnemonic;
4070
4071 switch ((opcode >> 23) & 0x3) {
4072 case 0:
4073 if ((rn & rt) == 0xf) {
4074 pld_literal:
4075 immed = opcode & 0xfff;
4076 address = thumb_alignpc4(address);
4077 if (opcode & (1 << 23))
4078 address += immed;
4079 else
4080 address -= immed;
4081 sprintf(cp, "PLD\tr%d, %#8.8" PRIx32,
4082 rt, address);
4083 return ERROR_OK;
4084 }
4085 if (rn == 0x0f && rt != 0x0f) {
4086 ldrb_literal:
4087 immed = opcode & 0xfff;
4088 address = thumb_alignpc4(address);
4089 if (opcode & (1 << 23))
4090 address += immed;
4091 else
4092 address -= immed;
4093 sprintf(cp, "LDRB\tr%d, %#8.8" PRIx32,
4094 rt, address);
4095 return ERROR_OK;
4096 }
4097 if (rn == 0x0f)
4098 break;
4099 if ((op2 & 0x3c) == 0x38) {
4100 immed = opcode & 0xff;
4101 sprintf(cp, "LDRBT\tr%d, [r%d, #%d]\t; %#2.2x",
4102 rt, rn, immed, immed);
4103 return ERROR_OK;
4104 }
4105 if ((op2 & 0x3c) == 0x30) {
4106 if (rt == 0x0f) {
4107 immed = opcode & 0xff;
4108 immed = -immed;
4109 preload_immediate:
4110 p1 = (opcode & (1 << 21)) ? "W" : "";
4111 sprintf(cp, "PLD%s\t[r%d, #%d]\t; %#6.6x",
4112 p1, rn, immed, immed);
4113 return ERROR_OK;
4114 }
4115 mnemonic = "LDRB";
4116 ldrxb_immediate_t3:
4117 immed = opcode & 0xff;
4118 if (!(opcode & 0x200))
4119 immed = -immed;
4120
4121 /* two indexed modes will write back rn */
4122 if (opcode & 0x100) {
4123 if (opcode & 0x400) /* pre-indexed */
4124 p2 = "]!";
4125 else { /* post-indexed */
4126 p1 = "]";
4127 p2 = "";
4128 }
4129 }
4130 ldrxb_immediate_t2:
4131 sprintf(cp, "%s\tr%d, [r%d%s, #%d%s\t; %#8.8x",
4132 mnemonic, rt, rn, p1,
4133 immed, p2, immed);
4134 return ERROR_OK;
4135 }
4136 if ((op2 & 0x24) == 0x24) {
4137 mnemonic = "LDRB";
4138 goto ldrxb_immediate_t3;
4139 }
4140 if (op2 == 0) {
4141 int rm = opcode & 0xf;
4142
4143 if (rt == 0x0f)
4144 sprintf(cp, "PLD\t");
4145 else
4146 sprintf(cp, "LDRB.W\tr%d, ", rt);
4147 immed = (opcode >> 4) & 0x3;
4148 cp = strchr(cp, 0);
4149 sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
4150 return ERROR_OK;
4151 }
4152 break;
4153 case 1:
4154 if ((rn & rt) == 0xf)
4155 goto pld_literal;
4156 if (rt == 0xf) {
4157 immed = opcode & 0xfff;
4158 goto preload_immediate;
4159 }
4160 if (rn == 0x0f)
4161 goto ldrb_literal;
4162 mnemonic = "LDRB.W";
4163 immed = opcode & 0xfff;
4164 goto ldrxb_immediate_t2;
4165 case 2:
4166 if ((rn & rt) == 0xf) {
4167 immed = opcode & 0xfff;
4168 address = thumb_alignpc4(address);
4169 if (opcode & (1 << 23))
4170 address += immed;
4171 else
4172 address -= immed;
4173 sprintf(cp, "PLI\t%#8.8" PRIx32, address);
4174 return ERROR_OK;
4175 }
4176 if (rn == 0xf && rt != 0xf) {
4177 ldrsb_literal:
4178 immed = opcode & 0xfff;
4179 address = thumb_alignpc4(address);
4180 if (opcode & (1 << 23))
4181 address += immed;
4182 else
4183 address -= immed;
4184 sprintf(cp, "LDRSB\t%#8.8" PRIx32, address);
4185 return ERROR_OK;
4186 }
4187 if (rn == 0xf)
4188 break;
4189 if ((op2 & 0x3c) == 0x38) {
4190 immed = opcode & 0xff;
4191 sprintf(cp, "LDRSBT\tr%d, [r%d, #%d]\t; %#2.2x",
4192 rt, rn, immed, immed);
4193 return ERROR_OK;
4194 }
4195 if ((op2 & 0x3c) == 0x30) {
4196 if (rt == 0xf) {
4197 immed = opcode & 0xff;
4198 immed = -immed; /* pli */
4199 sprintf(cp, "PLI\t[r%d, #%d]\t; -%#2.2x",
4200 rn, immed, -immed);
4201 return ERROR_OK;
4202 }
4203 mnemonic = "LDRSB";
4204 goto ldrxb_immediate_t3;
4205 }
4206 if ((op2 & 0x24) == 0x24) {
4207 mnemonic = "LDRSB";
4208 goto ldrxb_immediate_t3;
4209 }
4210 if (op2 == 0) {
4211 int rm = opcode & 0xf;
4212
4213 if (rt == 0x0f)
4214 sprintf(cp, "PLI\t");
4215 else
4216 sprintf(cp, "LDRSB.W\tr%d, ", rt);
4217 immed = (opcode >> 4) & 0x3;
4218 cp = strchr(cp, 0);
4219 sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed);
4220 return ERROR_OK;
4221 }
4222 break;
4223 case 3:
4224 if (rt == 0xf) {
4225 immed = opcode & 0xfff;
4226 sprintf(cp, "PLI\t[r%d, #%d]\t; %#3.3x",
4227 rn, immed, immed);
4228 return ERROR_OK;
4229 }
4230 if (rn == 0xf)
4231 goto ldrsb_literal;
4232 immed = opcode & 0xfff;
4233 mnemonic = "LDRSB";
4234 goto ldrxb_immediate_t2;
4235 }
4236
4237 return ERROR_COMMAND_SYNTAX_ERROR;
4238 }
4239
4240 static int t2ev_load_halfword(uint32_t opcode, uint32_t address,
4241 struct arm_instruction *instruction, char *cp)
4242 {
4243 int rn = (opcode >> 16) & 0xf;
4244 int rt = (opcode >> 12) & 0xf;
4245 int op2 = (opcode >> 6) & 0x3f;
4246 char *sign = "";
4247 unsigned immed;
4248
4249 if (rt == 0xf) {
4250 sprintf(cp, "HINT (UNALLOCATED)");
4251 return ERROR_OK;
4252 }
4253
4254 if (opcode & (1 << 24))
4255 sign = "S";
4256
4257 if ((opcode & (1 << 23)) == 0) {
4258 if (rn == 0xf) {
4259 ldrh_literal:
4260 immed = opcode & 0xfff;
4261 address = thumb_alignpc4(address);
4262 if (opcode & (1 << 23))
4263 address += immed;
4264 else
4265 address -= immed;
4266 sprintf(cp, "LDR%sH\tr%d, %#8.8" PRIx32,
4267 sign, rt, address);
4268 return ERROR_OK;
4269 }
4270 if (op2 == 0) {
4271 int rm = opcode & 0xf;
4272
4273 immed = (opcode >> 4) & 0x3;
4274 sprintf(cp, "LDR%sH.W\tr%d, [r%d, r%d, LSL #%d]",
4275 sign, rt, rn, rm, immed);
4276 return ERROR_OK;
4277 }
4278 if ((op2 & 0x3c) == 0x38) {
4279 immed = opcode & 0xff;
4280 sprintf(cp, "LDR%sHT\tr%d, [r%d, #%d]\t; %#2.2x",
4281 sign, rt, rn, immed, immed);
4282 return ERROR_OK;
4283 }
4284 if ((op2 & 0x3c) == 0x30 || (op2 & 0x24) == 0x24) {
4285 char *p1 = "", *p2 = "]";
4286
4287 immed = opcode & 0xff;
4288 if (!(opcode & 0x200))
4289 immed = -immed;
4290
4291 /* two indexed modes will write back rn */
4292 if (opcode & 0x100) {
4293 if (opcode & 0x400) /* pre-indexed */
4294 p2 = "]!";
4295 else { /* post-indexed */
4296 p1 = "]";
4297 p2 = "";
4298 }
4299 }
4300 sprintf(cp, "LDR%sH\tr%d, [r%d%s, #%d%s\t; %#8.8x",
4301 sign, rt, rn, p1, immed, p2, immed);
4302 return ERROR_OK;
4303 }
4304 } else {
4305 if (rn == 0xf)
4306 goto ldrh_literal;
4307
4308 immed = opcode & 0xfff;
4309 sprintf(cp, "LDR%sH%s\tr%d, [r%d, #%d]\t; %#6.6x",
4310 sign, *sign ? "" : ".W",
4311 rt, rn, immed, immed);
4312 return ERROR_OK;
4313 }
4314
4315 return ERROR_COMMAND_SYNTAX_ERROR;
4316 }
4317
4318 /*
4319 * REVISIT for Thumb2 instructions, instruction->type and friends aren't
4320 * always set. That means eventual arm_simulate_step() support for Thumb2
4321 * will need work in this area.
4322 */
4323 int thumb2_opcode(struct target *target, uint32_t address, struct arm_instruction *instruction)
4324 {
4325 int retval;
4326 uint16_t op;
4327 uint32_t opcode;
4328 char *cp;
4329
4330 /* clear low bit ... it's set on function pointers */
4331 address &= ~1;
4332
4333 /* clear fields, to avoid confusion */
4334 memset(instruction, 0, sizeof(struct arm_instruction));
4335
4336 /* read first halfword, see if this is the only one */
4337 retval = target_read_u16(target, address, &op);
4338 if (retval != ERROR_OK)
4339 return retval;
4340
4341 switch (op & 0xf800) {
4342 case 0xf800:
4343 case 0xf000:
4344 case 0xe800:
4345 /* 32-bit instructions */
4346 instruction->instruction_size = 4;
4347 opcode = op << 16;
4348 retval = target_read_u16(target, address + 2, &op);
4349 if (retval != ERROR_OK)
4350 return retval;
4351 opcode |= op;
4352 instruction->opcode = opcode;
4353 break;
4354 default:
4355 /* 16-bit: Thumb1 + IT + CBZ/CBNZ + ... */
4356 return thumb_evaluate_opcode(op, address, instruction);
4357 }
4358
4359 snprintf(instruction->text, 128,
4360 "0x%8.8" PRIx32 " 0x%8.8" PRIx32 "\t",
4361 address, opcode);
4362 cp = strchr(instruction->text, 0);
4363 retval = ERROR_FAIL;
4364
4365 /* ARMv7-M: A5.3.1 Data processing (modified immediate) */
4366 if ((opcode & 0x1a008000) == 0x10000000)
4367 retval = t2ev_data_mod_immed(opcode, address, instruction, cp);
4368
4369 /* ARMv7-M: A5.3.3 Data processing (plain binary immediate) */
4370 else if ((opcode & 0x1a008000) == 0x12000000)
4371 retval = t2ev_data_immed(opcode, address, instruction, cp);
4372
4373 /* ARMv7-M: A5.3.4 Branches and miscellaneous control */
4374 else if ((opcode & 0x18008000) == 0x10008000)
4375 retval = t2ev_b_misc(opcode, address, instruction, cp);
4376
4377 /* ARMv7-M: A5.3.5 Load/store multiple */
4378 else if ((opcode & 0x1e400000) == 0x08000000)
4379 retval = t2ev_ldm_stm(opcode, address, instruction, cp);
4380
4381 /* ARMv7-M: A5.3.6 Load/store dual or exclusive, table branch */
4382 else if ((opcode & 0x1e400000) == 0x08400000)
4383 retval = t2ev_ldrex_strex(opcode, address, instruction, cp);
4384
4385 /* ARMv7-M: A5.3.7 Load word */
4386 else if ((opcode & 0x1f700000) == 0x18500000)
4387 retval = t2ev_load_word(opcode, address, instruction, cp);
4388
4389 /* ARMv7-M: A5.3.8 Load halfword, unallocated memory hints */
4390 else if ((opcode & 0x1e700000) == 0x18300000)
4391 retval = t2ev_load_halfword(opcode, address, instruction, cp);
4392
4393 /* ARMv7-M: A5.3.9 Load byte, memory hints */
4394 else if ((opcode & 0x1e700000) == 0x18100000)
4395 retval = t2ev_load_byte_hints(opcode, address, instruction, cp);
4396
4397 /* ARMv7-M: A5.3.10 Store single data item */
4398 else if ((opcode & 0x1f100000) == 0x18000000)
4399 retval = t2ev_store_single(opcode, address, instruction, cp);
4400
4401 /* ARMv7-M: A5.3.11 Data processing (shifted register) */
4402 else if ((opcode & 0x1e000000) == 0x0a000000)
4403 retval = t2ev_data_shift(opcode, address, instruction, cp);
4404
4405 /* ARMv7-M: A5.3.12 Data processing (register)
4406 * and A5.3.13 Miscellaneous operations
4407 */
4408 else if ((opcode & 0x1f000000) == 0x1a000000)
4409 retval = t2ev_data_reg(opcode, address, instruction, cp);
4410
4411 /* ARMv7-M: A5.3.14 Multiply, and multiply accumulate */
4412 else if ((opcode & 0x1f800000) == 0x1b000000)
4413 retval = t2ev_mul32(opcode, address, instruction, cp);
4414
4415 /* ARMv7-M: A5.3.15 Long multiply, long multiply accumulate, divide */
4416 else if ((opcode & 0x1f800000) == 0x1b800000)
4417 retval = t2ev_mul64_div(opcode, address, instruction, cp);
4418
4419 if (retval == ERROR_OK)
4420 return retval;
4421
4422 /*
4423 * Thumb2 also supports coprocessor, ThumbEE, and DSP/Media (SIMD)
4424 * instructions; not yet handled here.
4425 */
4426
4427 if (retval == ERROR_COMMAND_SYNTAX_ERROR) {
4428 instruction->type = ARM_UNDEFINED_INSTRUCTION;
4429 strcpy(cp, "UNDEFINED OPCODE");
4430 return ERROR_OK;
4431 }
4432
4433 LOG_DEBUG("Can't decode 32-bit Thumb2 yet (opcode=%08" PRIx32 ")",
4434 opcode);
4435
4436 strcpy(cp, "(32-bit Thumb2 ...)");
4437 return ERROR_OK;
4438 }
4439
4440 int arm_access_size(struct arm_instruction *instruction)
4441 {
4442 if ((instruction->type == ARM_LDRB)
4443 || (instruction->type == ARM_LDRBT)
4444 || (instruction->type == ARM_LDRSB)
4445 || (instruction->type == ARM_STRB)
4446 || (instruction->type == ARM_STRBT))
4447 return 1;
4448 else if ((instruction->type == ARM_LDRH)
4449 || (instruction->type == ARM_LDRSH)
4450 || (instruction->type == ARM_STRH))
4451 return 2;
4452 else if ((instruction->type == ARM_LDR)
4453 || (instruction->type == ARM_LDRT)
4454 || (instruction->type == ARM_STR)
4455 || (instruction->type == ARM_STRT))
4456 return 4;
4457 else if ((instruction->type == ARM_LDRD)
4458 || (instruction->type == ARM_STRD))
4459 return 8;
4460 else {
4461 LOG_ERROR("BUG: instruction type %i isn't a load/store instruction",
4462 instruction->type);
4463 return 0;
4464 }
4465 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)