bfd/
[binutils.git] / opcodes / arm-dis.c
blob62a2a39ab62df8ef659ad71d8ffc58c31166eac9
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
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 bfd_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
92 PARAMS ((long, fprintf_ftype, void *));
93 static int print_insn_arm
94 PARAMS ((bfd_vma, struct disassemble_info *, long));
95 static int print_insn_thumb
96 PARAMS ((bfd_vma, struct disassemble_info *, long));
97 static void parse_disassembler_options
98 PARAMS ((char *));
99 static int print_insn
100 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
101 int get_arm_regname_num_options (void);
102 int set_arm_regname_option (int option);
103 int get_arm_regnames (int option, const char **setname,
104 const char **setdescription,
105 const char ***register_names);
107 /* Functions. */
109 get_arm_regname_num_options ()
111 return NUM_ARM_REGNAMES;
115 set_arm_regname_option (option)
116 int option;
118 int old = regname_selected;
119 regname_selected = option;
120 return old;
124 get_arm_regnames (option, setname, setdescription, register_names)
125 int option;
126 const char **setname;
127 const char **setdescription;
128 const char ***register_names;
130 *setname = regnames[option].name;
131 *setdescription = regnames[option].description;
132 *register_names = regnames[option].reg_names;
133 return 16;
136 static void
137 arm_decode_shift (given, func, stream)
138 long given;
139 fprintf_ftype func;
140 void * stream;
142 func (stream, "%s", arm_regnames[given & 0xf]);
144 if ((given & 0xff0) != 0)
146 if ((given & 0x10) == 0)
148 int amount = (given & 0xf80) >> 7;
149 int shift = (given & 0x60) >> 5;
151 if (amount == 0)
153 if (shift == 3)
155 func (stream, ", rrx");
156 return;
159 amount = 32;
162 func (stream, ", %s #%d", arm_shift[shift], amount);
164 else
165 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
166 arm_regnames[(given & 0xf00) >> 8]);
170 /* Print one instruction from PC on INFO->STREAM.
171 Return the size of the instruction (always 4 on ARM). */
173 static int
174 print_insn_arm (pc, info, given)
175 bfd_vma pc;
176 struct disassemble_info *info;
177 long given;
179 const struct arm_opcode *insn;
180 void *stream = info->stream;
181 fprintf_ftype func = info->fprintf_func;
183 for (insn = arm_opcodes; insn->assembler; insn++)
185 if ((given & insn->mask) == insn->value)
187 char * c;
189 for (c = insn->assembler; *c; c++)
191 if (*c == '%')
193 switch (*++c)
195 case '%':
196 func (stream, "%%");
197 break;
199 case 'a':
200 if (((given & 0x000f0000) == 0x000f0000)
201 && ((given & 0x02000000) == 0))
203 int offset = given & 0xfff;
205 func (stream, "[pc");
207 if (given & 0x01000000)
209 if ((given & 0x00800000) == 0)
210 offset = - offset;
212 /* Pre-indexed. */
213 func (stream, ", #%d]", offset);
215 offset += pc + 8;
217 /* Cope with the possibility of write-back
218 being used. Probably a very dangerous thing
219 for the programmer to do, but who are we to
220 argue ? */
221 if (given & 0x00200000)
222 func (stream, "!");
224 else
226 /* Post indexed. */
227 func (stream, "], #%d", offset);
229 /* ie ignore the offset. */
230 offset = pc + 8;
233 func (stream, "\t; ");
234 info->print_address_func (offset, info);
236 else
238 func (stream, "[%s",
239 arm_regnames[(given >> 16) & 0xf]);
240 if ((given & 0x01000000) != 0)
242 if ((given & 0x02000000) == 0)
244 int offset = given & 0xfff;
245 if (offset)
246 func (stream, ", %s#%d",
247 (((given & 0x00800000) == 0)
248 ? "-" : ""), offset);
250 else
252 func (stream, ", %s",
253 (((given & 0x00800000) == 0)
254 ? "-" : ""));
255 arm_decode_shift (given, func, stream);
258 func (stream, "]%s",
259 ((given & 0x00200000) != 0) ? "!" : "");
261 else
263 if ((given & 0x02000000) == 0)
265 int offset = given & 0xfff;
266 if (offset)
267 func (stream, "], %s#%d",
268 (((given & 0x00800000) == 0)
269 ? "-" : ""), offset);
270 else
271 func (stream, "]");
273 else
275 func (stream, "], %s",
276 (((given & 0x00800000) == 0)
277 ? "-" : ""));
278 arm_decode_shift (given, func, stream);
282 break;
284 case 's':
285 if ((given & 0x004f0000) == 0x004f0000)
287 /* PC relative with immediate offset. */
288 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
290 if ((given & 0x00800000) == 0)
291 offset = -offset;
293 func (stream, "[pc, #%d]\t; ", offset);
295 (*info->print_address_func)
296 (offset + pc + 8, info);
298 else
300 func (stream, "[%s",
301 arm_regnames[(given >> 16) & 0xf]);
302 if ((given & 0x01000000) != 0)
304 /* Pre-indexed. */
305 if ((given & 0x00400000) == 0x00400000)
307 /* Immediate. */
308 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
309 if (offset)
310 func (stream, ", %s#%d",
311 (((given & 0x00800000) == 0)
312 ? "-" : ""), offset);
314 else
316 /* Register. */
317 func (stream, ", %s%s",
318 (((given & 0x00800000) == 0)
319 ? "-" : ""),
320 arm_regnames[given & 0xf]);
323 func (stream, "]%s",
324 ((given & 0x00200000) != 0) ? "!" : "");
326 else
328 /* Post-indexed. */
329 if ((given & 0x00400000) == 0x00400000)
331 /* Immediate. */
332 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
333 if (offset)
334 func (stream, "], %s#%d",
335 (((given & 0x00800000) == 0)
336 ? "-" : ""), offset);
337 else
338 func (stream, "]");
340 else
342 /* Register. */
343 func (stream, "], %s%s",
344 (((given & 0x00800000) == 0)
345 ? "-" : ""),
346 arm_regnames[given & 0xf]);
350 break;
352 case 'b':
353 (*info->print_address_func)
354 (BDISP (given) * 4 + pc + 8, info);
355 break;
357 case 'c':
358 func (stream, "%s",
359 arm_conditional [(given >> 28) & 0xf]);
360 break;
362 case 'm':
364 int started = 0;
365 int reg;
367 func (stream, "{");
368 for (reg = 0; reg < 16; reg++)
369 if ((given & (1 << reg)) != 0)
371 if (started)
372 func (stream, ", ");
373 started = 1;
374 func (stream, "%s", arm_regnames[reg]);
376 func (stream, "}");
378 break;
380 case 'o':
381 if ((given & 0x02000000) != 0)
383 int rotate = (given & 0xf00) >> 7;
384 int immed = (given & 0xff);
385 immed = (((immed << (32 - rotate))
386 | (immed >> rotate)) & 0xffffffff);
387 func (stream, "#%d\t; 0x%x", immed, immed);
389 else
390 arm_decode_shift (given, func, stream);
391 break;
393 case 'p':
394 if ((given & 0x0000f000) == 0x0000f000)
395 func (stream, "p");
396 break;
398 case 't':
399 if ((given & 0x01200000) == 0x00200000)
400 func (stream, "t");
401 break;
403 case 'A':
404 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
405 if ((given & 0x01000000) != 0)
407 int offset = given & 0xff;
408 if (offset)
409 func (stream, ", %s#%d]%s",
410 ((given & 0x00800000) == 0 ? "-" : ""),
411 offset * 4,
412 ((given & 0x00200000) != 0 ? "!" : ""));
413 else
414 func (stream, "]");
416 else
418 int offset = given & 0xff;
419 if (offset)
420 func (stream, "], %s#%d",
421 ((given & 0x00800000) == 0 ? "-" : ""),
422 offset * 4);
423 else
424 func (stream, "]");
426 break;
428 case 'B':
429 /* Print ARM V5 BLX(1) address: pc+25 bits. */
431 bfd_vma address;
432 bfd_vma offset = 0;
434 if (given & 0x00800000)
435 /* Is signed, hi bits should be ones. */
436 offset = (-1) ^ 0x00ffffff;
438 /* Offset is (SignExtend(offset field)<<2). */
439 offset += given & 0x00ffffff;
440 offset <<= 2;
441 address = offset + pc + 8;
443 if (given & 0x01000000)
444 /* H bit allows addressing to 2-byte boundaries. */
445 address += 2;
447 info->print_address_func (address, info);
449 break;
451 case 'I':
452 /* Print a Cirrus/DSP shift immediate. */
453 /* Immediates are 7bit signed ints with bits 0..3 in
454 bits 0..3 of opcode and bits 4..6 in bits 5..7
455 of opcode. */
457 int imm;
459 imm = (given & 0xf) | ((given & 0xe0) >> 1);
461 /* Is ``imm'' a negative number? */
462 if (imm & 0x40)
463 imm |= (-1 << 7);
465 func (stream, "%d", imm);
468 break;
470 case 'C':
471 func (stream, "_");
472 if (given & 0x80000)
473 func (stream, "f");
474 if (given & 0x40000)
475 func (stream, "s");
476 if (given & 0x20000)
477 func (stream, "x");
478 if (given & 0x10000)
479 func (stream, "c");
480 break;
482 case 'F':
483 switch (given & 0x00408000)
485 case 0:
486 func (stream, "4");
487 break;
488 case 0x8000:
489 func (stream, "1");
490 break;
491 case 0x00400000:
492 func (stream, "2");
493 break;
494 default:
495 func (stream, "3");
497 break;
499 case 'P':
500 switch (given & 0x00080080)
502 case 0:
503 func (stream, "s");
504 break;
505 case 0x80:
506 func (stream, "d");
507 break;
508 case 0x00080000:
509 func (stream, "e");
510 break;
511 default:
512 func (stream, _("<illegal precision>"));
513 break;
515 break;
516 case 'Q':
517 switch (given & 0x00408000)
519 case 0:
520 func (stream, "s");
521 break;
522 case 0x8000:
523 func (stream, "d");
524 break;
525 case 0x00400000:
526 func (stream, "e");
527 break;
528 default:
529 func (stream, "p");
530 break;
532 break;
533 case 'R':
534 switch (given & 0x60)
536 case 0:
537 break;
538 case 0x20:
539 func (stream, "p");
540 break;
541 case 0x40:
542 func (stream, "m");
543 break;
544 default:
545 func (stream, "z");
546 break;
548 break;
550 case '0': case '1': case '2': case '3': case '4':
551 case '5': case '6': case '7': case '8': case '9':
553 int bitstart = *c++ - '0';
554 int bitend = 0;
555 while (*c >= '0' && *c <= '9')
556 bitstart = (bitstart * 10) + *c++ - '0';
558 switch (*c)
560 case '-':
561 c++;
563 while (*c >= '0' && *c <= '9')
564 bitend = (bitend * 10) + *c++ - '0';
566 if (!bitend)
567 abort ();
569 switch (*c)
571 case 'r':
573 long reg;
575 reg = given >> bitstart;
576 reg &= (2 << (bitend - bitstart)) - 1;
578 func (stream, "%s", arm_regnames[reg]);
580 break;
581 case 'd':
583 long reg;
585 reg = given >> bitstart;
586 reg &= (2 << (bitend - bitstart)) - 1;
588 func (stream, "%d", reg);
590 break;
591 case 'x':
593 long reg;
595 reg = given >> bitstart;
596 reg &= (2 << (bitend - bitstart)) - 1;
598 func (stream, "0x%08x", reg);
600 /* Some SWI instructions have special
601 meanings. */
602 if ((given & 0x0fffffff) == 0x0FF00000)
603 func (stream, "\t; IMB");
604 else if ((given & 0x0fffffff) == 0x0FF00001)
605 func (stream, "\t; IMBRange");
607 break;
608 case 'X':
610 long reg;
612 reg = given >> bitstart;
613 reg &= (2 << (bitend - bitstart)) - 1;
615 func (stream, "%01x", reg & 0xf);
617 break;
618 case 'f':
620 long reg;
622 reg = given >> bitstart;
623 reg &= (2 << (bitend - bitstart)) - 1;
625 if (reg > 7)
626 func (stream, "#%s",
627 arm_fp_const[reg & 7]);
628 else
629 func (stream, "f%d", reg);
631 break;
632 default:
633 abort ();
635 break;
637 case 'y':
638 case 'z':
640 int single = *c == 'y';
641 int regno;
643 switch (bitstart)
645 case 4: /* Sm pair */
646 func (stream, "{");
647 /* Fall through. */
648 case 0: /* Sm, Dm */
649 regno = given & 0x0000000f;
650 if (single)
652 regno <<= 1;
653 regno += (given >> 5) & 1;
655 break;
657 case 1: /* Sd, Dd */
658 regno = (given >> 12) & 0x0000000f;
659 if (single)
661 regno <<= 1;
662 regno += (given >> 22) & 1;
664 break;
666 case 2: /* Sn, Dn */
667 regno = (given >> 16) & 0x0000000f;
668 if (single)
670 regno <<= 1;
671 regno += (given >> 7) & 1;
673 break;
675 case 3: /* List */
676 func (stream, "{");
677 regno = (given >> 12) & 0x0000000f;
678 if (single)
680 regno <<= 1;
681 regno += (given >> 22) & 1;
683 break;
686 default:
687 abort ();
690 func (stream, "%c%d", single ? 's' : 'd', regno);
692 if (bitstart == 3)
694 int count = given & 0xff;
696 if (single == 0)
697 count >>= 1;
699 if (--count)
701 func (stream, "-%c%d",
702 single ? 's' : 'd',
703 regno + count);
706 func (stream, "}");
708 else if (bitstart == 4)
709 func (stream, ", %c%d}", single ? 's' : 'd',
710 regno + 1);
712 break;
715 case '`':
716 c++;
717 if ((given & (1 << bitstart)) == 0)
718 func (stream, "%c", *c);
719 break;
720 case '\'':
721 c++;
722 if ((given & (1 << bitstart)) != 0)
723 func (stream, "%c", *c);
724 break;
725 case '?':
726 ++c;
727 if ((given & (1 << bitstart)) != 0)
728 func (stream, "%c", *c++);
729 else
730 func (stream, "%c", *++c);
731 break;
732 default:
733 abort ();
735 break;
737 default:
738 abort ();
742 else
743 func (stream, "%c", *c);
745 return 4;
748 abort ();
751 /* Print one instruction from PC on INFO->STREAM.
752 Return the size of the instruction. */
754 static int
755 print_insn_thumb (pc, info, given)
756 bfd_vma pc;
757 struct disassemble_info *info;
758 long given;
760 const struct thumb_opcode *insn;
761 void *stream = info->stream;
762 fprintf_ftype func = info->fprintf_func;
764 for (insn = thumb_opcodes; insn->assembler; insn++)
766 if ((given & insn->mask) == insn->value)
768 char * c = insn->assembler;
770 /* Special processing for Thumb 2 instruction BL sequence: */
771 if (!*c) /* Check for empty (not NULL) assembler string. */
773 long offset;
775 info->bytes_per_chunk = 4;
776 info->bytes_per_line = 4;
778 offset = BDISP23 (given);
779 offset = offset * 2 + pc + 4;
781 if ((given & 0x10000000) == 0)
783 func (stream, "blx\t");
784 offset &= 0xfffffffc;
786 else
787 func (stream, "bl\t");
789 info->print_address_func (offset, info);
790 return 4;
792 else
794 info->bytes_per_chunk = 2;
795 info->bytes_per_line = 4;
797 given &= 0xffff;
799 for (; *c; c++)
801 if (*c == '%')
803 int domaskpc = 0;
804 int domasklr = 0;
806 switch (*++c)
808 case '%':
809 func (stream, "%%");
810 break;
812 case 'S':
814 long reg;
816 reg = (given >> 3) & 0x7;
817 if (given & (1 << 6))
818 reg += 8;
820 func (stream, "%s", arm_regnames[reg]);
822 break;
824 case 'D':
826 long reg;
828 reg = given & 0x7;
829 if (given & (1 << 7))
830 reg += 8;
832 func (stream, "%s", arm_regnames[reg]);
834 break;
836 case 'T':
837 func (stream, "%s",
838 arm_conditional [(given >> 8) & 0xf]);
839 break;
841 case 'N':
842 if (given & (1 << 8))
843 domasklr = 1;
844 /* Fall through. */
845 case 'O':
846 if (*c == 'O' && (given & (1 << 8)))
847 domaskpc = 1;
848 /* Fall through. */
849 case 'M':
851 int started = 0;
852 int reg;
854 func (stream, "{");
856 /* It would be nice if we could spot
857 ranges, and generate the rS-rE format: */
858 for (reg = 0; (reg < 8); reg++)
859 if ((given & (1 << reg)) != 0)
861 if (started)
862 func (stream, ", ");
863 started = 1;
864 func (stream, "%s", arm_regnames[reg]);
867 if (domasklr)
869 if (started)
870 func (stream, ", ");
871 started = 1;
872 func (stream, arm_regnames[14] /* "lr" */);
875 if (domaskpc)
877 if (started)
878 func (stream, ", ");
879 func (stream, arm_regnames[15] /* "pc" */);
882 func (stream, "}");
884 break;
887 case '0': case '1': case '2': case '3': case '4':
888 case '5': case '6': case '7': case '8': case '9':
890 int bitstart = *c++ - '0';
891 int bitend = 0;
893 while (*c >= '0' && *c <= '9')
894 bitstart = (bitstart * 10) + *c++ - '0';
896 switch (*c)
898 case '-':
900 long reg;
902 c++;
903 while (*c >= '0' && *c <= '9')
904 bitend = (bitend * 10) + *c++ - '0';
905 if (!bitend)
906 abort ();
907 reg = given >> bitstart;
908 reg &= (2 << (bitend - bitstart)) - 1;
909 switch (*c)
911 case 'r':
912 func (stream, "%s", arm_regnames[reg]);
913 break;
915 case 'd':
916 func (stream, "%d", reg);
917 break;
919 case 'H':
920 func (stream, "%d", reg << 1);
921 break;
923 case 'W':
924 func (stream, "%d", reg << 2);
925 break;
927 case 'a':
928 /* PC-relative address -- the bottom two
929 bits of the address are dropped
930 before the calculation. */
931 info->print_address_func
932 (((pc + 4) & ~3) + (reg << 2), info);
933 break;
935 case 'x':
936 func (stream, "0x%04x", reg);
937 break;
939 case 'I':
940 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
941 func (stream, "%d", reg);
942 break;
944 case 'B':
945 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
946 (*info->print_address_func)
947 (reg * 2 + pc + 4, info);
948 break;
950 default:
951 abort ();
954 break;
956 case '\'':
957 c++;
958 if ((given & (1 << bitstart)) != 0)
959 func (stream, "%c", *c);
960 break;
962 case '?':
963 ++c;
964 if ((given & (1 << bitstart)) != 0)
965 func (stream, "%c", *c++);
966 else
967 func (stream, "%c", *++c);
968 break;
970 default:
971 abort ();
974 break;
976 default:
977 abort ();
980 else
981 func (stream, "%c", *c);
984 return 2;
988 /* No match. */
989 abort ();
992 /* Parse an individual disassembler option. */
994 void
995 parse_arm_disassembler_option (option)
996 char * option;
998 if (option == NULL)
999 return;
1001 if (strneq (option, "reg-names-", 10))
1003 int i;
1005 option += 10;
1007 for (i = NUM_ARM_REGNAMES; i--;)
1008 if (streq (option, regnames[i].name))
1010 regname_selected = i;
1011 break;
1014 if (i < 0)
1015 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1017 else if (streq (option, "force-thumb"))
1018 force_thumb = 1;
1019 else if (streq (option, "no-force-thumb"))
1020 force_thumb = 0;
1021 else
1022 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1024 return;
1027 /* Parse the string of disassembler options, spliting it at whitespaces. */
1029 static void
1030 parse_disassembler_options (options)
1031 char * options;
1033 char * space;
1035 if (options == NULL)
1036 return;
1040 space = strchr (options, ' ');
1042 if (space)
1044 * space = '\0';
1045 parse_arm_disassembler_option (options);
1046 * space = ' ';
1047 options = space + 1;
1049 else
1050 parse_arm_disassembler_option (options);
1052 while (space);
1055 /* NOTE: There are no checks in these routines that
1056 the relevant number of data bytes exist. */
1058 static int
1059 print_insn (pc, info, little)
1060 bfd_vma pc;
1061 struct disassemble_info * info;
1062 bfd_boolean little;
1064 unsigned char b[4];
1065 long given;
1066 int status;
1067 int is_thumb;
1069 if (info->disassembler_options)
1071 parse_disassembler_options (info->disassembler_options);
1073 /* To avoid repeated parsing of these options, we remove them here. */
1074 info->disassembler_options = NULL;
1077 is_thumb = force_thumb;
1079 if (!is_thumb && info->symbols != NULL)
1081 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1083 coff_symbol_type * cs;
1085 cs = coffsymbol (*info->symbols);
1086 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1087 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1088 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1089 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1090 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1092 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1094 elf_symbol_type * es;
1095 unsigned int type;
1097 es = *(elf_symbol_type **)(info->symbols);
1098 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1100 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1104 info->bytes_per_chunk = 4;
1105 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1107 if (little)
1109 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1110 if (status != 0 && is_thumb)
1112 info->bytes_per_chunk = 2;
1114 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1115 b[3] = b[2] = 0;
1118 if (status != 0)
1120 info->memory_error_func (status, pc, info);
1121 return -1;
1124 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1126 else
1128 status = info->read_memory_func
1129 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1130 if (status != 0)
1132 info->memory_error_func (status, pc, info);
1133 return -1;
1136 if (is_thumb)
1138 if (pc & 0x2)
1140 given = (b[2] << 8) | b[3];
1142 status = info->read_memory_func
1143 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1144 if (status != 0)
1146 info->memory_error_func (status, pc + 4, info);
1147 return -1;
1150 given |= (b[0] << 24) | (b[1] << 16);
1152 else
1153 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1155 else
1156 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1159 if (info->flags & INSN_HAS_RELOC)
1160 /* If the instruction has a reloc associated with it, then
1161 the offset field in the instruction will actually be the
1162 addend for the reloc. (We are using REL type relocs).
1163 In such cases, we can ignore the pc when computing
1164 addresses, since the addend is not currently pc-relative. */
1165 pc = 0;
1167 if (is_thumb)
1168 status = print_insn_thumb (pc, info, given);
1169 else
1170 status = print_insn_arm (pc, info, given);
1172 return status;
1176 print_insn_big_arm (pc, info)
1177 bfd_vma pc;
1178 struct disassemble_info * info;
1180 return print_insn (pc, info, FALSE);
1184 print_insn_little_arm (pc, info)
1185 bfd_vma pc;
1186 struct disassemble_info * info;
1188 return print_insn (pc, info, TRUE);
1191 void
1192 print_arm_disassembler_options (FILE * stream)
1194 int i;
1196 fprintf (stream, _("\n\
1197 The following ARM specific disassembler options are supported for use with\n\
1198 the -M switch:\n"));
1200 for (i = NUM_ARM_REGNAMES; i--;)
1201 fprintf (stream, " reg-names-%s %*c%s\n",
1202 regnames[i].name,
1203 (int)(14 - strlen (regnames[i].name)), ' ',
1204 regnames[i].description);
1206 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
1207 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");