* arm-opc.h (arm_opcodes): Use generic rule %5?hb instead of %h.
[binutils.git] / opcodes / arm-dis.c
blob7e9b3309008473243ffab5e54c110a40183185a0
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)
7 This file is part of libopcodes.
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.
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.
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. */
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"
31 /* FIXME: This shouldn't be done here */
32 #include "elf-bfd.h"
33 #include "elf/internal.h"
34 #include "elf/arm.h"
36 #ifndef streq
37 #define streq(a,b) (strcmp ((a), (b)) == 0)
38 #endif
40 #ifndef strneq
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
42 #endif
44 #ifndef NUM_ELEM
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
46 #endif
48 static char * arm_conditional[] =
49 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
50 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
52 typedef struct
54 const char * name;
55 const char * description;
56 const char * reg_names[16];
58 arm_regname;
60 static arm_regname regnames[] =
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" }}
76 /* Default to GCC register name set. */
77 static unsigned int regname_selected = 1;
79 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
80 #define arm_regnames regnames[regname_selected].reg_names
82 static boolean force_thumb = false;
84 static char * arm_fp_const[] =
85 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
87 static char * arm_shift[] =
88 {"lsl", "lsr", "asr", "ror"};
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);
102 /* Functions. */
104 get_arm_regname_num_options (void)
106 return NUM_ARM_REGNAMES;
110 set_arm_regname_option (int option)
112 int old = regname_selected;
113 regname_selected = option;
114 return old;
118 get_arm_regnames (int option, const char **setname,
119 const char **setdescription,
120 const char ***register_names)
122 *setname = regnames[option].name;
123 *setdescription = regnames[option].description;
124 *register_names = regnames[option].reg_names;
125 return 16;
128 static void
129 arm_decode_shift (given, func, stream)
130 long given;
131 fprintf_ftype func;
132 void * stream;
134 func (stream, "%s", arm_regnames[given & 0xf]);
136 if ((given & 0xff0) != 0)
138 if ((given & 0x10) == 0)
140 int amount = (given & 0xf80) >> 7;
141 int shift = (given & 0x60) >> 5;
143 if (amount == 0)
145 if (shift == 3)
147 func (stream, ", rrx");
148 return;
151 amount = 32;
154 func (stream, ", %s #%d", arm_shift[shift], amount);
156 else
157 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
158 arm_regnames[(given & 0xf00) >> 8]);
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;
170 struct arm_opcode * insn;
171 void * stream = info->stream;
172 fprintf_ftype func = info->fprintf_func;
174 for (insn = arm_opcodes; insn->assembler; insn++)
176 if ((given & insn->mask) == insn->value)
178 char * c;
180 for (c = insn->assembler; *c; c++)
182 if (*c == '%')
184 switch (*++c)
186 case '%':
187 func (stream, "%%");
188 break;
190 case 'a':
191 if (((given & 0x000f0000) == 0x000f0000)
192 && ((given & 0x02000000) == 0))
194 int offset = given & 0xfff;
196 func (stream, "[pc");
198 if (given & 0x01000000)
200 if ((given & 0x00800000) == 0)
201 offset = - offset;
203 /* pre-indexed */
204 func (stream, ", #%d]", offset);
206 offset += pc + 8;
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, "!");
215 else
217 /* Post indexed. */
218 func (stream, "], #%d", offset);
220 offset = pc + 8; /* ie ignore the offset. */
223 func (stream, "\t; ");
224 info->print_address_func (offset, info);
226 else
228 func (stream, "[%s",
229 arm_regnames[(given >> 16) & 0xf]);
230 if ((given & 0x01000000) != 0)
232 if ((given & 0x02000000) == 0)
234 int offset = given & 0xfff;
235 if (offset)
236 func (stream, ", %s#%d",
237 (((given & 0x00800000) == 0)
238 ? "-" : ""), offset);
240 else
242 func (stream, ", %s",
243 (((given & 0x00800000) == 0)
244 ? "-" : ""));
245 arm_decode_shift (given, func, stream);
248 func (stream, "]%s",
249 ((given & 0x00200000) != 0) ? "!" : "");
251 else
253 if ((given & 0x02000000) == 0)
255 int offset = given & 0xfff;
256 if (offset)
257 func (stream, "], %s#%d",
258 (((given & 0x00800000) == 0)
259 ? "-" : ""), offset);
260 else
261 func (stream, "]");
263 else
265 func (stream, "], %s",
266 (((given & 0x00800000) == 0)
267 ? "-" : ""));
268 arm_decode_shift (given, func, stream);
272 break;
274 case 's':
275 if ((given & 0x004f0000) == 0x004f0000)
277 /* PC relative with immediate offset. */
278 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
280 if ((given & 0x00800000) == 0)
281 offset = -offset;
283 func (stream, "[pc, #%d]\t; ", offset);
285 (*info->print_address_func)
286 (offset + pc + 8, info);
288 else
290 func (stream, "[%s",
291 arm_regnames[(given >> 16) & 0xf]);
292 if ((given & 0x01000000) != 0)
294 /* Pre-indexed. */
295 if ((given & 0x00400000) == 0x00400000)
297 /* Immediate. */
298 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
299 if (offset)
300 func (stream, ", %s#%d",
301 (((given & 0x00800000) == 0)
302 ? "-" : ""), offset);
304 else
306 /* Register. */
307 func (stream, ", %s%s",
308 (((given & 0x00800000) == 0)
309 ? "-" : ""),
310 arm_regnames[given & 0xf]);
313 func (stream, "]%s",
314 ((given & 0x00200000) != 0) ? "!" : "");
316 else
318 /* Post-indexed. */
319 if ((given & 0x00400000) == 0x00400000)
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, "]");
330 else
332 /* Register. */
333 func (stream, "], %s%s",
334 (((given & 0x00800000) == 0)
335 ? "-" : ""),
336 arm_regnames[given & 0xf]);
340 break;
342 case 'b':
343 (*info->print_address_func)
344 (BDISP (given) * 4 + pc + 8, info);
345 break;
347 case 'c':
348 func (stream, "%s",
349 arm_conditional [(given >> 28) & 0xf]);
350 break;
352 case 'm':
354 int started = 0;
355 int reg;
357 func (stream, "{");
358 for (reg = 0; reg < 16; reg++)
359 if ((given & (1 << reg)) != 0)
361 if (started)
362 func (stream, ", ");
363 started = 1;
364 func (stream, "%s", arm_regnames[reg]);
366 func (stream, "}");
368 break;
370 case 'o':
371 if ((given & 0x02000000) != 0)
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);
379 else
380 arm_decode_shift (given, func, stream);
381 break;
383 case 'p':
384 if ((given & 0x0000f000) == 0x0000f000)
385 func (stream, "p");
386 break;
388 case 't':
389 if ((given & 0x01200000) == 0x00200000)
390 func (stream, "t");
391 break;
393 case 'A':
394 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
395 if ((given & 0x01000000) != 0)
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, "]");
406 else
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, "]");
416 break;
418 case 'B':
419 /* Print ARM V5 BLX(1) address: pc+25 bits. */
421 bfd_vma address;
422 bfd_vma offset = 0;
424 if (given & 0x00800000)
425 /* Is signed, hi bits should be ones. */
426 offset = (-1) ^ 0x00ffffff;
428 /* Offset is (SignExtend(offset field)<<2). */
429 offset += given & 0x00ffffff;
430 offset <<= 2;
431 address = offset + pc + 8;
433 if (given & 0x01000000)
434 /* H bit allows addressing to 2-byte boundaries. */
435 address += 2;
437 info->print_address_func (address, info);
439 break;
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. */
447 int imm;
449 imm = (given & 0xf) | ((given & 0xe0) >> 1);
451 /* Is ``imm'' a negative number? */
452 if (imm & 0x40)
453 imm |= (-1 << 7);
455 func (stream, "%d", imm);
458 break;
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;
472 case 'F':
473 switch (given & 0x00408000)
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");
487 break;
489 case 'P':
490 switch (given & 0x00080080)
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;
505 break;
506 case 'Q':
507 switch (given & 0x00408000)
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;
522 break;
523 case 'R':
524 switch (given & 0x60)
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;
538 break;
540 case '0': case '1': case '2': case '3': case '4':
541 case '5': case '6': case '7': case '8': case '9':
543 int bitstart = *c++ - '0';
544 int bitend = 0;
545 while (*c >= '0' && *c <= '9')
546 bitstart = (bitstart * 10) + *c++ - '0';
548 switch (*c)
550 case '-':
551 c++;
553 while (*c >= '0' && *c <= '9')
554 bitend = (bitend * 10) + *c++ - '0';
556 if (!bitend)
557 abort ();
559 switch (*c)
561 case 'r':
563 long reg;
565 reg = given >> bitstart;
566 reg &= (2 << (bitend - bitstart)) - 1;
568 func (stream, "%s", arm_regnames[reg]);
570 break;
571 case 'd':
573 long reg;
575 reg = given >> bitstart;
576 reg &= (2 << (bitend - bitstart)) - 1;
578 func (stream, "%d", reg);
580 break;
581 case 'x':
583 long reg;
585 reg = given >> bitstart;
586 reg &= (2 << (bitend - bitstart)) - 1;
588 func (stream, "0x%08x", reg);
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");
597 break;
598 case 'X':
600 long reg;
602 reg = given >> bitstart;
603 reg &= (2 << (bitend - bitstart)) - 1;
605 func (stream, "%01x", reg & 0xf);
607 break;
608 case 'f':
610 long reg;
612 reg = given >> bitstart;
613 reg &= (2 << (bitend - bitstart)) - 1;
615 if (reg > 7)
616 func (stream, "#%s",
617 arm_fp_const[reg & 7]);
618 else
619 func (stream, "f%d", reg);
621 break;
622 default:
623 abort ();
625 break;
627 case 'y':
628 case 'z':
630 int single = *c == 'y';
631 int regno;
633 switch (bitstart)
635 case 4: /* Sm pair */
636 func (stream, "{");
637 /* Fall through. */
638 case 0: /* Sm, Dm */
639 regno = given & 0x0000000f;
640 if (single)
642 regno <<= 1;
643 regno += (given >> 5) & 1;
645 break;
647 case 1: /* Sd, Dd */
648 regno = (given >> 12) & 0x0000000f;
649 if (single)
651 regno <<= 1;
652 regno += (given >> 22) & 1;
654 break;
656 case 2: /* Sn, Dn */
657 regno = (given >> 16) & 0x0000000f;
658 if (single)
660 regno <<= 1;
661 regno += (given >> 7) & 1;
663 break;
665 case 3: /* List */
666 func (stream, "{");
667 regno = (given >> 12) & 0x0000000f;
668 if (single)
670 regno <<= 1;
671 regno += (given >> 22) & 1;
673 break;
676 default:
677 abort ();
680 func (stream, "%c%d", single ? 's' : 'd', regno);
682 if (bitstart == 3)
684 int count = given & 0xff;
686 if (single == 0)
687 count >>= 1;
689 if (--count)
691 func (stream, "-%c%d",
692 single ? 's' : 'd',
693 regno + count);
696 func (stream, "}");
698 else if (bitstart == 4)
699 func (stream, ", %c%d}", single ? 's' : 'd',
700 regno + 1);
702 break;
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 ();
725 break;
727 default:
728 abort ();
732 else
733 func (stream, "%c", *c);
735 return 4;
738 abort ();
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;
749 struct thumb_opcode * insn;
750 void * stream = info->stream;
751 fprintf_ftype func = info->fprintf_func;
753 for (insn = thumb_opcodes; insn->assembler; insn++)
755 if ((given & insn->mask) == insn->value)
757 char * c = insn->assembler;
759 /* Special processing for Thumb 2 instruction BL sequence: */
760 if (!*c) /* Check for empty (not NULL) assembler string. */
762 long offset;
764 info->bytes_per_chunk = 4;
765 info->bytes_per_line = 4;
767 offset = BDISP23 (given);
769 if ((given & 0x10000000) == 0)
771 func (stream, "blx\t");
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)
778 /* func (stream, "*malformed!* "); */
779 offset &= ~ 0x1;
782 offset |= ((pc & 0x2) >> 1);
784 else
785 func (stream, "bl\t");
787 info->print_address_func (offset * 2 + pc + 4, info);
788 return 4;
790 else
792 info->bytes_per_chunk = 2;
793 info->bytes_per_line = 4;
795 given &= 0xffff;
797 for (; *c; c++)
799 if (*c == '%')
801 int domaskpc = 0;
802 int domasklr = 0;
804 switch (*++c)
806 case '%':
807 func (stream, "%%");
808 break;
810 case 'S':
812 long reg;
814 reg = (given >> 3) & 0x7;
815 if (given & (1 << 6))
816 reg += 8;
818 func (stream, "%s", arm_regnames[reg]);
820 break;
822 case 'D':
824 long reg;
826 reg = given & 0x7;
827 if (given & (1 << 7))
828 reg += 8;
830 func (stream, "%s", arm_regnames[reg]);
832 break;
834 case 'T':
835 func (stream, "%s",
836 arm_conditional [(given >> 8) & 0xf]);
837 break;
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':
849 int started = 0;
850 int reg;
852 func (stream, "{");
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)
859 if (started)
860 func (stream, ", ");
861 started = 1;
862 func (stream, "%s", arm_regnames[reg]);
865 if (domasklr)
867 if (started)
868 func (stream, ", ");
869 started = 1;
870 func (stream, arm_regnames[14] /* "lr" */);
873 if (domaskpc)
875 if (started)
876 func (stream, ", ");
877 func (stream, arm_regnames[15] /* "pc" */);
880 func (stream, "}");
882 break;
885 case '0': case '1': case '2': case '3': case '4':
886 case '5': case '6': case '7': case '8': case '9':
888 int bitstart = *c++ - '0';
889 int bitend = 0;
891 while (*c >= '0' && *c <= '9')
892 bitstart = (bitstart * 10) + *c++ - '0';
894 switch (*c)
896 case '-':
898 long reg;
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)
909 case 'r':
910 func (stream, "%s", arm_regnames[reg]);
911 break;
913 case 'd':
914 func (stream, "%d", reg);
915 break;
917 case 'H':
918 func (stream, "%d", reg << 1);
919 break;
921 case 'W':
922 func (stream, "%d", reg << 2);
923 break;
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;
933 case 'x':
934 func (stream, "0x%04x", reg);
935 break;
937 case 'I':
938 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
939 func (stream, "%d", reg);
940 break;
942 case 'B':
943 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
944 (*info->print_address_func)
945 (reg * 2 + pc + 4, info);
946 break;
948 default:
949 abort ();
952 break;
954 case '\'':
955 c++;
956 if ((given & (1 << bitstart)) != 0)
957 func (stream, "%c", *c);
958 break;
960 case '?':
961 ++c;
962 if ((given & (1 << bitstart)) != 0)
963 func (stream, "%c", *c++);
964 else
965 func (stream, "%c", *++c);
966 break;
968 default:
969 abort ();
972 break;
974 default:
975 abort ();
978 else
979 func (stream, "%c", *c);
982 return 2;
986 /* No match. */
987 abort ();
990 /* Parse an individual disassembler option. */
991 void
992 parse_arm_disassembler_option (option)
993 char * option;
995 if (option == NULL)
996 return;
998 if (strneq (option, "reg-names-", 10))
1000 int i;
1002 option += 10;
1004 for (i = NUM_ARM_REGNAMES; i--;)
1005 if (streq (option, regnames[i].name))
1007 regname_selected = i;
1008 break;
1011 if (i < 0)
1012 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
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);
1021 return;
1024 /* Parse the string of disassembler options, spliting it at whitespaces. */
1025 static void
1026 parse_disassembler_options (options)
1027 char * options;
1029 char * space;
1031 if (options == NULL)
1032 return;
1036 space = strchr (options, ' ');
1038 if (space)
1040 * space = '\0';
1041 parse_arm_disassembler_option (options);
1042 * space = ' ';
1043 options = space + 1;
1045 else
1046 parse_arm_disassembler_option (options);
1048 while (space);
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;
1059 unsigned char b[4];
1060 long given;
1061 int status;
1062 int is_thumb;
1064 if (info->disassembler_options)
1066 parse_disassembler_options (info->disassembler_options);
1068 /* To avoid repeated parsing of these options, we remove them here. */
1069 info->disassembler_options = NULL;
1072 is_thumb = force_thumb;
1074 if (!is_thumb && info->symbols != NULL)
1076 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1078 coff_symbol_type * cs;
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);
1087 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1089 elf_symbol_type * es;
1090 unsigned int type;
1092 es = *(elf_symbol_type **)(info->symbols);
1093 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1095 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1099 info->bytes_per_chunk = 4;
1100 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1102 if (little)
1104 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1105 if (status != 0 && is_thumb)
1107 info->bytes_per_chunk = 2;
1109 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1110 b[3] = b[2] = 0;
1113 if (status != 0)
1115 info->memory_error_func (status, pc, info);
1116 return -1;
1119 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1121 else
1123 status = info->read_memory_func
1124 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1125 if (status != 0)
1127 info->memory_error_func (status, pc, info);
1128 return -1;
1131 if (is_thumb)
1133 if (pc & 0x2)
1135 given = (b[2] << 8) | b[3];
1137 status = info->read_memory_func
1138 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1139 if (status != 0)
1141 info->memory_error_func (status, pc + 4, info);
1142 return -1;
1145 given |= (b[0] << 24) | (b[1] << 16);
1147 else
1148 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1150 else
1151 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
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;
1162 if (is_thumb)
1163 status = print_insn_thumb (pc, info, given);
1164 else
1165 status = print_insn_arm (pc, info, given);
1167 return status;
1171 print_insn_big_arm (pc, info)
1172 bfd_vma pc;
1173 struct disassemble_info * info;
1175 return print_insn (pc, info, false);
1179 print_insn_little_arm (pc, info)
1180 bfd_vma pc;
1181 struct disassemble_info * info;
1183 return print_insn (pc, info, true);
1186 void
1187 print_arm_disassembler_options (FILE * stream)
1189 int i;
1191 fprintf (stream, _("\n\
1192 The following ARM specific disassembler options are supported for use with\n\
1193 the -M switch:\n"));
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);
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");