* arm-opc.h (arm_opcodes): Use generic rule %5?hb instead of %h.
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7 This file is part of libopcodes.
8
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
12 any later version.
13
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23 #include "sysdep.h"
24 #include "dis-asm.h"
25 #define DEFINE_TABLE
26 #include "arm-opc.h"
27 #include "coff/internal.h"
28 #include "libcoff.h"
29 #include "opintl.h"
30
31 /* FIXME: This shouldn't be done here */
32 #include "elf-bfd.h"
33 #include "elf/internal.h"
34 #include "elf/arm.h"
35
36 #ifndef streq
37 #define streq(a,b) (strcmp ((a), (b)) == 0)
38 #endif
39
40 #ifndef strneq
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
42 #endif
43
44 #ifndef NUM_ELEM
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
46 #endif
47
48 static char * arm_conditional[] =
49 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
50 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
51
52 typedef struct
53 {
54 const char * name;
55 const char * description;
56 const char * reg_names[16];
57 }
58 arm_regname;
59
60 static arm_regname regnames[] =
61 {
62 { "raw" , "Select raw register names",
63 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
64 { "gcc", "Select register names used by GCC",
65 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
66 { "std", "Select register names used in ARM's ISA documentation",
67 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
68 { "apcs", "Select register names used in the APCS",
69 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
70 { "atpcs", "Select register names used in the ATPCS",
71 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
72 { "special-atpcs", "Select special register names used in the ATPCS",
73 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}
74 };
75
76 /* Default to GCC register name set. */
77 static unsigned int regname_selected = 1;
78
79 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
80 #define arm_regnames regnames[regname_selected].reg_names
81
82 static boolean force_thumb = false;
83
84 static char * arm_fp_const[] =
85 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
86
87 static char * arm_shift[] =
88 {"lsl", "lsr", "asr", "ror"};
89 \f
90 /* Forward declarations. */
91 static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *));
92 static int print_insn_arm PARAMS ((bfd_vma, struct disassemble_info *, long));
93 static int print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long));
94 static void parse_disassembler_options PARAMS ((char *));
95 static int print_insn PARAMS ((bfd_vma, struct disassemble_info *, boolean));
96 int get_arm_regname_num_options (void);
97 int set_arm_regname_option (int option);
98 int get_arm_regnames (int option, const char **setname,
99 const char **setdescription,
100 const char ***register_names);
101 \f
102 /* Functions. */
103 int
104 get_arm_regname_num_options (void)
105 {
106 return NUM_ARM_REGNAMES;
107 }
108
109 int
110 set_arm_regname_option (int option)
111 {
112 int old = regname_selected;
113 regname_selected = option;
114 return old;
115 }
116
117 int
118 get_arm_regnames (int option, const char **setname,
119 const char **setdescription,
120 const char ***register_names)
121 {
122 *setname = regnames[option].name;
123 *setdescription = regnames[option].description;
124 *register_names = regnames[option].reg_names;
125 return 16;
126 }
127
128 static void
129 arm_decode_shift (given, func, stream)
130 long given;
131 fprintf_ftype func;
132 void * stream;
133 {
134 func (stream, "%s", arm_regnames[given & 0xf]);
135
136 if ((given & 0xff0) != 0)
137 {
138 if ((given & 0x10) == 0)
139 {
140 int amount = (given & 0xf80) >> 7;
141 int shift = (given & 0x60) >> 5;
142
143 if (amount == 0)
144 {
145 if (shift == 3)
146 {
147 func (stream, ", rrx");
148 return;
149 }
150
151 amount = 32;
152 }
153
154 func (stream, ", %s #%d", arm_shift[shift], amount);
155 }
156 else
157 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
158 arm_regnames[(given & 0xf00) >> 8]);
159 }
160 }
161
162 /* Print one instruction from PC on INFO->STREAM.
163 Return the size of the instruction (always 4 on ARM). */
164 static int
165 print_insn_arm (pc, info, given)
166 bfd_vma pc;
167 struct disassemble_info * info;
168 long given;
169 {
170 struct arm_opcode * insn;
171 void * stream = info->stream;
172 fprintf_ftype func = info->fprintf_func;
173
174 for (insn = arm_opcodes; insn->assembler; insn++)
175 {
176 if ((given & insn->mask) == insn->value)
177 {
178 char * c;
179
180 for (c = insn->assembler; *c; c++)
181 {
182 if (*c == '%')
183 {
184 switch (*++c)
185 {
186 case '%':
187 func (stream, "%%");
188 break;
189
190 case 'a':
191 if (((given & 0x000f0000) == 0x000f0000)
192 && ((given & 0x02000000) == 0))
193 {
194 int offset = given & 0xfff;
195
196 func (stream, "[pc");
197
198 if (given & 0x01000000)
199 {
200 if ((given & 0x00800000) == 0)
201 offset = - offset;
202
203 /* pre-indexed */
204 func (stream, ", #%d]", offset);
205
206 offset += pc + 8;
207
208 /* Cope with the possibility of write-back
209 being used. Probably a very dangerous thing
210 for the programmer to do, but who are we to
211 argue ? */
212 if (given & 0x00200000)
213 func (stream, "!");
214 }
215 else
216 {
217 /* Post indexed. */
218 func (stream, "], #%d", offset);
219
220 offset = pc + 8; /* ie ignore the offset. */
221 }
222
223 func (stream, "\t; ");
224 info->print_address_func (offset, info);
225 }
226 else
227 {
228 func (stream, "[%s",
229 arm_regnames[(given >> 16) & 0xf]);
230 if ((given & 0x01000000) != 0)
231 {
232 if ((given & 0x02000000) == 0)
233 {
234 int offset = given & 0xfff;
235 if (offset)
236 func (stream, ", %s#%d",
237 (((given & 0x00800000) == 0)
238 ? "-" : ""), offset);
239 }
240 else
241 {
242 func (stream, ", %s",
243 (((given & 0x00800000) == 0)
244 ? "-" : ""));
245 arm_decode_shift (given, func, stream);
246 }
247
248 func (stream, "]%s",
249 ((given & 0x00200000) != 0) ? "!" : "");
250 }
251 else
252 {
253 if ((given & 0x02000000) == 0)
254 {
255 int offset = given & 0xfff;
256 if (offset)
257 func (stream, "], %s#%d",
258 (((given & 0x00800000) == 0)
259 ? "-" : ""), offset);
260 else
261 func (stream, "]");
262 }
263 else
264 {
265 func (stream, "], %s",
266 (((given & 0x00800000) == 0)
267 ? "-" : ""));
268 arm_decode_shift (given, func, stream);
269 }
270 }
271 }
272 break;
273
274 case 's':
275 if ((given & 0x004f0000) == 0x004f0000)
276 {
277 /* PC relative with immediate offset. */
278 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
279
280 if ((given & 0x00800000) == 0)
281 offset = -offset;
282
283 func (stream, "[pc, #%d]\t; ", offset);
284
285 (*info->print_address_func)
286 (offset + pc + 8, info);
287 }
288 else
289 {
290 func (stream, "[%s",
291 arm_regnames[(given >> 16) & 0xf]);
292 if ((given & 0x01000000) != 0)
293 {
294 /* Pre-indexed. */
295 if ((given & 0x00400000) == 0x00400000)
296 {
297 /* Immediate. */
298 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
299 if (offset)
300 func (stream, ", %s#%d",
301 (((given & 0x00800000) == 0)
302 ? "-" : ""), offset);
303 }
304 else
305 {
306 /* Register. */
307 func (stream, ", %s%s",
308 (((given & 0x00800000) == 0)
309 ? "-" : ""),
310 arm_regnames[given & 0xf]);
311 }
312
313 func (stream, "]%s",
314 ((given & 0x00200000) != 0) ? "!" : "");
315 }
316 else
317 {
318 /* Post-indexed. */
319 if ((given & 0x00400000) == 0x00400000)
320 {
321 /* Immediate. */
322 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
323 if (offset)
324 func (stream, "], %s#%d",
325 (((given & 0x00800000) == 0)
326 ? "-" : ""), offset);
327 else
328 func (stream, "]");
329 }
330 else
331 {
332 /* Register. */
333 func (stream, "], %s%s",
334 (((given & 0x00800000) == 0)
335 ? "-" : ""),
336 arm_regnames[given & 0xf]);
337 }
338 }
339 }
340 break;
341
342 case 'b':
343 (*info->print_address_func)
344 (BDISP (given) * 4 + pc + 8, info);
345 break;
346
347 case 'c':
348 func (stream, "%s",
349 arm_conditional [(given >> 28) & 0xf]);
350 break;
351
352 case 'm':
353 {
354 int started = 0;
355 int reg;
356
357 func (stream, "{");
358 for (reg = 0; reg < 16; reg++)
359 if ((given & (1 << reg)) != 0)
360 {
361 if (started)
362 func (stream, ", ");
363 started = 1;
364 func (stream, "%s", arm_regnames[reg]);
365 }
366 func (stream, "}");
367 }
368 break;
369
370 case 'o':
371 if ((given & 0x02000000) != 0)
372 {
373 int rotate = (given & 0xf00) >> 7;
374 int immed = (given & 0xff);
375 immed = (((immed << (32 - rotate))
376 | (immed >> rotate)) & 0xffffffff);
377 func (stream, "#%d\t; 0x%x", immed, immed);
378 }
379 else
380 arm_decode_shift (given, func, stream);
381 break;
382
383 case 'p':
384 if ((given & 0x0000f000) == 0x0000f000)
385 func (stream, "p");
386 break;
387
388 case 't':
389 if ((given & 0x01200000) == 0x00200000)
390 func (stream, "t");
391 break;
392
393 case 'A':
394 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
395 if ((given & 0x01000000) != 0)
396 {
397 int offset = given & 0xff;
398 if (offset)
399 func (stream, ", %s#%d]%s",
400 ((given & 0x00800000) == 0 ? "-" : ""),
401 offset * 4,
402 ((given & 0x00200000) != 0 ? "!" : ""));
403 else
404 func (stream, "]");
405 }
406 else
407 {
408 int offset = given & 0xff;
409 if (offset)
410 func (stream, "], %s#%d",
411 ((given & 0x00800000) == 0 ? "-" : ""),
412 offset * 4);
413 else
414 func (stream, "]");
415 }
416 break;
417
418 case 'B':
419 /* Print ARM V5 BLX(1) address: pc+25 bits. */
420 {
421 bfd_vma address;
422 bfd_vma offset = 0;
423
424 if (given & 0x00800000)
425 /* Is signed, hi bits should be ones. */
426 offset = (-1) ^ 0x00ffffff;
427
428 /* Offset is (SignExtend(offset field)<<2). */
429 offset += given & 0x00ffffff;
430 offset <<= 2;
431 address = offset + pc + 8;
432
433 if (given & 0x01000000)
434 /* H bit allows addressing to 2-byte boundaries. */
435 address += 2;
436
437 info->print_address_func (address, info);
438 }
439 break;
440
441 case 'I':
442 /* Print a Cirrus/DSP shift immediate. */
443 /* Immediates are 7bit signed ints with bits 0..3 in
444 bits 0..3 of opcode and bits 4..6 in bits 5..7
445 of opcode. */
446 {
447 int imm;
448
449 imm = (given & 0xf) | ((given & 0xe0) >> 1);
450
451 /* Is ``imm'' a negative number? */
452 if (imm & 0x40)
453 imm |= (-1 << 7);
454
455 func (stream, "%d", imm);
456 }
457
458 break;
459
460 case 'C':
461 func (stream, "_");
462 if (given & 0x80000)
463 func (stream, "f");
464 if (given & 0x40000)
465 func (stream, "s");
466 if (given & 0x20000)
467 func (stream, "x");
468 if (given & 0x10000)
469 func (stream, "c");
470 break;
471
472 case 'F':
473 switch (given & 0x00408000)
474 {
475 case 0:
476 func (stream, "4");
477 break;
478 case 0x8000:
479 func (stream, "1");
480 break;
481 case 0x00400000:
482 func (stream, "2");
483 break;
484 default:
485 func (stream, "3");
486 }
487 break;
488
489 case 'P':
490 switch (given & 0x00080080)
491 {
492 case 0:
493 func (stream, "s");
494 break;
495 case 0x80:
496 func (stream, "d");
497 break;
498 case 0x00080000:
499 func (stream, "e");
500 break;
501 default:
502 func (stream, _("<illegal precision>"));
503 break;
504 }
505 break;
506 case 'Q':
507 switch (given & 0x00408000)
508 {
509 case 0:
510 func (stream, "s");
511 break;
512 case 0x8000:
513 func (stream, "d");
514 break;
515 case 0x00400000:
516 func (stream, "e");
517 break;
518 default:
519 func (stream, "p");
520 break;
521 }
522 break;
523 case 'R':
524 switch (given & 0x60)
525 {
526 case 0:
527 break;
528 case 0x20:
529 func (stream, "p");
530 break;
531 case 0x40:
532 func (stream, "m");
533 break;
534 default:
535 func (stream, "z");
536 break;
537 }
538 break;
539
540 case '0': case '1': case '2': case '3': case '4':
541 case '5': case '6': case '7': case '8': case '9':
542 {
543 int bitstart = *c++ - '0';
544 int bitend = 0;
545 while (*c >= '0' && *c <= '9')
546 bitstart = (bitstart * 10) + *c++ - '0';
547
548 switch (*c)
549 {
550 case '-':
551 c++;
552
553 while (*c >= '0' && *c <= '9')
554 bitend = (bitend * 10) + *c++ - '0';
555
556 if (!bitend)
557 abort ();
558
559 switch (*c)
560 {
561 case 'r':
562 {
563 long reg;
564
565 reg = given >> bitstart;
566 reg &= (2 << (bitend - bitstart)) - 1;
567
568 func (stream, "%s", arm_regnames[reg]);
569 }
570 break;
571 case 'd':
572 {
573 long reg;
574
575 reg = given >> bitstart;
576 reg &= (2 << (bitend - bitstart)) - 1;
577
578 func (stream, "%d", reg);
579 }
580 break;
581 case 'x':
582 {
583 long reg;
584
585 reg = given >> bitstart;
586 reg &= (2 << (bitend - bitstart)) - 1;
587
588 func (stream, "0x%08x", reg);
589
590 /* Some SWI instructions have special
591 meanings. */
592 if ((given & 0x0fffffff) == 0x0FF00000)
593 func (stream, "\t; IMB");
594 else if ((given & 0x0fffffff) == 0x0FF00001)
595 func (stream, "\t; IMBRange");
596 }
597 break;
598 case 'X':
599 {
600 long reg;
601
602 reg = given >> bitstart;
603 reg &= (2 << (bitend - bitstart)) - 1;
604
605 func (stream, "%01x", reg & 0xf);
606 }
607 break;
608 case 'f':
609 {
610 long reg;
611
612 reg = given >> bitstart;
613 reg &= (2 << (bitend - bitstart)) - 1;
614
615 if (reg > 7)
616 func (stream, "#%s",
617 arm_fp_const[reg & 7]);
618 else
619 func (stream, "f%d", reg);
620 }
621 break;
622 default:
623 abort ();
624 }
625 break;
626
627 case 'y':
628 case 'z':
629 {
630 int single = *c == 'y';
631 int regno;
632
633 switch (bitstart)
634 {
635 case 4: /* Sm pair */
636 func (stream, "{");
637 /* Fall through. */
638 case 0: /* Sm, Dm */
639 regno = given & 0x0000000f;
640 if (single)
641 {
642 regno <<= 1;
643 regno += (given >> 5) & 1;
644 }
645 break;
646
647 case 1: /* Sd, Dd */
648 regno = (given >> 12) & 0x0000000f;
649 if (single)
650 {
651 regno <<= 1;
652 regno += (given >> 22) & 1;
653 }
654 break;
655
656 case 2: /* Sn, Dn */
657 regno = (given >> 16) & 0x0000000f;
658 if (single)
659 {
660 regno <<= 1;
661 regno += (given >> 7) & 1;
662 }
663 break;
664
665 case 3: /* List */
666 func (stream, "{");
667 regno = (given >> 12) & 0x0000000f;
668 if (single)
669 {
670 regno <<= 1;
671 regno += (given >> 22) & 1;
672 }
673 break;
674
675
676 default:
677 abort ();
678 }
679
680 func (stream, "%c%d", single ? 's' : 'd', regno);
681
682 if (bitstart == 3)
683 {
684 int count = given & 0xff;
685
686 if (single == 0)
687 count >>= 1;
688
689 if (--count)
690 {
691 func (stream, "-%c%d",
692 single ? 's' : 'd',
693 regno + count);
694 }
695
696 func (stream, "}");
697 }
698 else if (bitstart == 4)
699 func (stream, ", %c%d}", single ? 's' : 'd',
700 regno + 1);
701
702 break;
703 }
704
705 case '`':
706 c++;
707 if ((given & (1 << bitstart)) == 0)
708 func (stream, "%c", *c);
709 break;
710 case '\'':
711 c++;
712 if ((given & (1 << bitstart)) != 0)
713 func (stream, "%c", *c);
714 break;
715 case '?':
716 ++c;
717 if ((given & (1 << bitstart)) != 0)
718 func (stream, "%c", *c++);
719 else
720 func (stream, "%c", *++c);
721 break;
722 default:
723 abort ();
724 }
725 break;
726
727 default:
728 abort ();
729 }
730 }
731 }
732 else
733 func (stream, "%c", *c);
734 }
735 return 4;
736 }
737 }
738 abort ();
739 }
740
741 /* Print one instruction from PC on INFO->STREAM.
742 Return the size of the instruction. */
743 static int
744 print_insn_thumb (pc, info, given)
745 bfd_vma pc;
746 struct disassemble_info * info;
747 long given;
748 {
749 struct thumb_opcode * insn;
750 void * stream = info->stream;
751 fprintf_ftype func = info->fprintf_func;
752
753 for (insn = thumb_opcodes; insn->assembler; insn++)
754 {
755 if ((given & insn->mask) == insn->value)
756 {
757 char * c = insn->assembler;
758
759 /* Special processing for Thumb 2 instruction BL sequence: */
760 if (!*c) /* Check for empty (not NULL) assembler string. */
761 {
762 long offset;
763
764 info->bytes_per_chunk = 4;
765 info->bytes_per_line = 4;
766
767 offset = BDISP23 (given);
768
769 if ((given & 0x10000000) == 0)
770 {
771 func (stream, "blx\t");
772
773 /* The spec says that bit 1 of the branch's destination
774 address comes from bit 1 of the instruction's
775 address and not from the offset in the instruction. */
776 if (offset & 0x1)
777 {
778 /* func (stream, "*malformed!* "); */
779 offset &= ~ 0x1;
780 }
781
782 offset |= ((pc & 0x2) >> 1);
783 }
784 else
785 func (stream, "bl\t");
786
787 info->print_address_func (offset * 2 + pc + 4, info);
788 return 4;
789 }
790 else
791 {
792 info->bytes_per_chunk = 2;
793 info->bytes_per_line = 4;
794
795 given &= 0xffff;
796
797 for (; *c; c++)
798 {
799 if (*c == '%')
800 {
801 int domaskpc = 0;
802 int domasklr = 0;
803
804 switch (*++c)
805 {
806 case '%':
807 func (stream, "%%");
808 break;
809
810 case 'S':
811 {
812 long reg;
813
814 reg = (given >> 3) & 0x7;
815 if (given & (1 << 6))
816 reg += 8;
817
818 func (stream, "%s", arm_regnames[reg]);
819 }
820 break;
821
822 case 'D':
823 {
824 long reg;
825
826 reg = given & 0x7;
827 if (given & (1 << 7))
828 reg += 8;
829
830 func (stream, "%s", arm_regnames[reg]);
831 }
832 break;
833
834 case 'T':
835 func (stream, "%s",
836 arm_conditional [(given >> 8) & 0xf]);
837 break;
838
839 case 'N':
840 if (given & (1 << 8))
841 domasklr = 1;
842 /* Fall through. */
843 case 'O':
844 if (*c == 'O' && (given & (1 << 8)))
845 domaskpc = 1;
846 /* Fall through. */
847 case 'M':
848 {
849 int started = 0;
850 int reg;
851
852 func (stream, "{");
853
854 /* It would be nice if we could spot
855 ranges, and generate the rS-rE format: */
856 for (reg = 0; (reg < 8); reg++)
857 if ((given & (1 << reg)) != 0)
858 {
859 if (started)
860 func (stream, ", ");
861 started = 1;
862 func (stream, "%s", arm_regnames[reg]);
863 }
864
865 if (domasklr)
866 {
867 if (started)
868 func (stream, ", ");
869 started = 1;
870 func (stream, arm_regnames[14] /* "lr" */);
871 }
872
873 if (domaskpc)
874 {
875 if (started)
876 func (stream, ", ");
877 func (stream, arm_regnames[15] /* "pc" */);
878 }
879
880 func (stream, "}");
881 }
882 break;
883
884
885 case '0': case '1': case '2': case '3': case '4':
886 case '5': case '6': case '7': case '8': case '9':
887 {
888 int bitstart = *c++ - '0';
889 int bitend = 0;
890
891 while (*c >= '0' && *c <= '9')
892 bitstart = (bitstart * 10) + *c++ - '0';
893
894 switch (*c)
895 {
896 case '-':
897 {
898 long reg;
899
900 c++;
901 while (*c >= '0' && *c <= '9')
902 bitend = (bitend * 10) + *c++ - '0';
903 if (!bitend)
904 abort ();
905 reg = given >> bitstart;
906 reg &= (2 << (bitend - bitstart)) - 1;
907 switch (*c)
908 {
909 case 'r':
910 func (stream, "%s", arm_regnames[reg]);
911 break;
912
913 case 'd':
914 func (stream, "%d", reg);
915 break;
916
917 case 'H':
918 func (stream, "%d", reg << 1);
919 break;
920
921 case 'W':
922 func (stream, "%d", reg << 2);
923 break;
924
925 case 'a':
926 /* PC-relative address -- the bottom two
927 bits of the address are dropped
928 before the calculation. */
929 info->print_address_func
930 (((pc + 4) & ~3) + (reg << 2), info);
931 break;
932
933 case 'x':
934 func (stream, "0x%04x", reg);
935 break;
936
937 case 'I':
938 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
939 func (stream, "%d", reg);
940 break;
941
942 case 'B':
943 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
944 (*info->print_address_func)
945 (reg * 2 + pc + 4, info);
946 break;
947
948 default:
949 abort ();
950 }
951 }
952 break;
953
954 case '\'':
955 c++;
956 if ((given & (1 << bitstart)) != 0)
957 func (stream, "%c", *c);
958 break;
959
960 case '?':
961 ++c;
962 if ((given & (1 << bitstart)) != 0)
963 func (stream, "%c", *c++);
964 else
965 func (stream, "%c", *++c);
966 break;
967
968 default:
969 abort ();
970 }
971 }
972 break;
973
974 default:
975 abort ();
976 }
977 }
978 else
979 func (stream, "%c", *c);
980 }
981 }
982 return 2;
983 }
984 }
985
986 /* No match. */
987 abort ();
988 }
989
990 /* Parse an individual disassembler option. */
991 void
992 parse_arm_disassembler_option (option)
993 char * option;
994 {
995 if (option == NULL)
996 return;
997
998 if (strneq (option, "reg-names-", 10))
999 {
1000 int i;
1001
1002 option += 10;
1003
1004 for (i = NUM_ARM_REGNAMES; i--;)
1005 if (streq (option, regnames[i].name))
1006 {
1007 regname_selected = i;
1008 break;
1009 }
1010
1011 if (i < 0)
1012 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1013 }
1014 else if (streq (option, "force-thumb"))
1015 force_thumb = 1;
1016 else if (streq (option, "no-force-thumb"))
1017 force_thumb = 0;
1018 else
1019 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1020
1021 return;
1022 }
1023
1024 /* Parse the string of disassembler options, spliting it at whitespaces. */
1025 static void
1026 parse_disassembler_options (options)
1027 char * options;
1028 {
1029 char * space;
1030
1031 if (options == NULL)
1032 return;
1033
1034 do
1035 {
1036 space = strchr (options, ' ');
1037
1038 if (space)
1039 {
1040 * space = '\0';
1041 parse_arm_disassembler_option (options);
1042 * space = ' ';
1043 options = space + 1;
1044 }
1045 else
1046 parse_arm_disassembler_option (options);
1047 }
1048 while (space);
1049 }
1050
1051 /* NOTE: There are no checks in these routines that
1052 the relevant number of data bytes exist. */
1053 static int
1054 print_insn (pc, info, little)
1055 bfd_vma pc;
1056 struct disassemble_info * info;
1057 boolean little;
1058 {
1059 unsigned char b[4];
1060 long given;
1061 int status;
1062 int is_thumb;
1063
1064 if (info->disassembler_options)
1065 {
1066 parse_disassembler_options (info->disassembler_options);
1067
1068 /* To avoid repeated parsing of these options, we remove them here. */
1069 info->disassembler_options = NULL;
1070 }
1071
1072 is_thumb = force_thumb;
1073
1074 if (!is_thumb && info->symbols != NULL)
1075 {
1076 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1077 {
1078 coff_symbol_type * cs;
1079
1080 cs = coffsymbol (*info->symbols);
1081 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1082 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1083 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1084 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1085 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1086 }
1087 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1088 {
1089 elf_symbol_type * es;
1090 unsigned int type;
1091
1092 es = *(elf_symbol_type **)(info->symbols);
1093 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1094
1095 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1096 }
1097 }
1098
1099 info->bytes_per_chunk = 4;
1100 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1101
1102 if (little)
1103 {
1104 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1105 if (status != 0 && is_thumb)
1106 {
1107 info->bytes_per_chunk = 2;
1108
1109 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1110 b[3] = b[2] = 0;
1111 }
1112
1113 if (status != 0)
1114 {
1115 info->memory_error_func (status, pc, info);
1116 return -1;
1117 }
1118
1119 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1120 }
1121 else
1122 {
1123 status = info->read_memory_func
1124 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1125 if (status != 0)
1126 {
1127 info->memory_error_func (status, pc, info);
1128 return -1;
1129 }
1130
1131 if (is_thumb)
1132 {
1133 if (pc & 0x2)
1134 {
1135 given = (b[2] << 8) | b[3];
1136
1137 status = info->read_memory_func
1138 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1139 if (status != 0)
1140 {
1141 info->memory_error_func (status, pc + 4, info);
1142 return -1;
1143 }
1144
1145 given |= (b[0] << 24) | (b[1] << 16);
1146 }
1147 else
1148 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1149 }
1150 else
1151 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1152 }
1153
1154 if (info->flags & INSN_HAS_RELOC)
1155 /* If the instruction has a reloc associated with it, then
1156 the offset field in the instruction will actually be the
1157 addend for the reloc. (We are using REL type relocs).
1158 In such cases, we can ignore the pc when computing
1159 addresses, since the addend is not currently pc-relative. */
1160 pc = 0;
1161
1162 if (is_thumb)
1163 status = print_insn_thumb (pc, info, given);
1164 else
1165 status = print_insn_arm (pc, info, given);
1166
1167 return status;
1168 }
1169
1170 int
1171 print_insn_big_arm (pc, info)
1172 bfd_vma pc;
1173 struct disassemble_info * info;
1174 {
1175 return print_insn (pc, info, false);
1176 }
1177
1178 int
1179 print_insn_little_arm (pc, info)
1180 bfd_vma pc;
1181 struct disassemble_info * info;
1182 {
1183 return print_insn (pc, info, true);
1184 }
1185
1186 void
1187 print_arm_disassembler_options (FILE * stream)
1188 {
1189 int i;
1190
1191 fprintf (stream, _("\n\
1192 The following ARM specific disassembler options are supported for use with\n\
1193 the -M switch:\n"));
1194
1195 for (i = NUM_ARM_REGNAMES; i--;)
1196 fprintf (stream, " reg-names-%s %*c%s\n",
1197 regnames[i].name,
1198 (int)(14 - strlen (regnames[i].name)), ' ',
1199 regnames[i].description);
1200
1201 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
1202 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
1203 }
This page took 0.057288 seconds and 5 git commands to generate.