Tomato 1.28
[tomato/tomato-null.git] / tools-src / gnu / binutils / opcodes / arm-dis.c
blobf3785f2ed9bc8475f5b1cf5bae5dfe3e33c1e6de
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 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 ()
106 return NUM_ARM_REGNAMES;
110 set_arm_regname_option (option)
111 int option;
113 int old = regname_selected;
114 regname_selected = option;
115 return old;
119 get_arm_regnames (option, setname, setdescription, register_names)
120 int option;
121 const char **setname;
122 const char **setdescription;
123 const char ***register_names;
125 *setname = regnames[option].name;
126 *setdescription = regnames[option].description;
127 *register_names = regnames[option].reg_names;
128 return 16;
131 static void
132 arm_decode_shift (given, func, stream)
133 long given;
134 fprintf_ftype func;
135 void * stream;
137 func (stream, "%s", arm_regnames[given & 0xf]);
139 if ((given & 0xff0) != 0)
141 if ((given & 0x10) == 0)
143 int amount = (given & 0xf80) >> 7;
144 int shift = (given & 0x60) >> 5;
146 if (amount == 0)
148 if (shift == 3)
150 func (stream, ", rrx");
151 return;
154 amount = 32;
157 func (stream, ", %s #%d", arm_shift[shift], amount);
159 else
160 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
161 arm_regnames[(given & 0xf00) >> 8]);
165 /* Print one instruction from PC on INFO->STREAM.
166 Return the size of the instruction (always 4 on ARM). */
168 static int
169 print_insn_arm (pc, info, given)
170 bfd_vma pc;
171 struct disassemble_info * info;
172 long given;
174 struct arm_opcode * insn;
175 void * stream = info->stream;
176 fprintf_ftype func = info->fprintf_func;
178 for (insn = arm_opcodes; insn->assembler; insn++)
180 if ((given & insn->mask) == insn->value)
182 char * c;
184 for (c = insn->assembler; *c; c++)
186 if (*c == '%')
188 switch (*++c)
190 case '%':
191 func (stream, "%%");
192 break;
194 case 'a':
195 if (((given & 0x000f0000) == 0x000f0000)
196 && ((given & 0x02000000) == 0))
198 int offset = given & 0xfff;
200 func (stream, "[pc");
202 if (given & 0x01000000)
204 if ((given & 0x00800000) == 0)
205 offset = - offset;
207 /* Pre-indexed. */
208 func (stream, ", #%d]", offset);
210 offset += pc + 8;
212 /* Cope with the possibility of write-back
213 being used. Probably a very dangerous thing
214 for the programmer to do, but who are we to
215 argue ? */
216 if (given & 0x00200000)
217 func (stream, "!");
219 else
221 /* Post indexed. */
222 func (stream, "], #%d", offset);
224 /* ie ignore the offset. */
225 offset = pc + 8;
228 func (stream, "\t; ");
229 info->print_address_func (offset, info);
231 else
233 func (stream, "[%s",
234 arm_regnames[(given >> 16) & 0xf]);
235 if ((given & 0x01000000) != 0)
237 if ((given & 0x02000000) == 0)
239 int offset = given & 0xfff;
240 if (offset)
241 func (stream, ", %s#%d",
242 (((given & 0x00800000) == 0)
243 ? "-" : ""), offset);
245 else
247 func (stream, ", %s",
248 (((given & 0x00800000) == 0)
249 ? "-" : ""));
250 arm_decode_shift (given, func, stream);
253 func (stream, "]%s",
254 ((given & 0x00200000) != 0) ? "!" : "");
256 else
258 if ((given & 0x02000000) == 0)
260 int offset = given & 0xfff;
261 if (offset)
262 func (stream, "], %s#%d",
263 (((given & 0x00800000) == 0)
264 ? "-" : ""), offset);
265 else
266 func (stream, "]");
268 else
270 func (stream, "], %s",
271 (((given & 0x00800000) == 0)
272 ? "-" : ""));
273 arm_decode_shift (given, func, stream);
277 break;
279 case 's':
280 if ((given & 0x004f0000) == 0x004f0000)
282 /* PC relative with immediate offset. */
283 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
285 if ((given & 0x00800000) == 0)
286 offset = -offset;
288 func (stream, "[pc, #%d]\t; ", offset);
290 (*info->print_address_func)
291 (offset + pc + 8, info);
293 else
295 func (stream, "[%s",
296 arm_regnames[(given >> 16) & 0xf]);
297 if ((given & 0x01000000) != 0)
299 /* Pre-indexed. */
300 if ((given & 0x00400000) == 0x00400000)
302 /* Immediate. */
303 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
304 if (offset)
305 func (stream, ", %s#%d",
306 (((given & 0x00800000) == 0)
307 ? "-" : ""), offset);
309 else
311 /* Register. */
312 func (stream, ", %s%s",
313 (((given & 0x00800000) == 0)
314 ? "-" : ""),
315 arm_regnames[given & 0xf]);
318 func (stream, "]%s",
319 ((given & 0x00200000) != 0) ? "!" : "");
321 else
323 /* Post-indexed. */
324 if ((given & 0x00400000) == 0x00400000)
326 /* Immediate. */
327 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
328 if (offset)
329 func (stream, "], %s#%d",
330 (((given & 0x00800000) == 0)
331 ? "-" : ""), offset);
332 else
333 func (stream, "]");
335 else
337 /* Register. */
338 func (stream, "], %s%s",
339 (((given & 0x00800000) == 0)
340 ? "-" : ""),
341 arm_regnames[given & 0xf]);
345 break;
347 case 'b':
348 (*info->print_address_func)
349 (BDISP (given) * 4 + pc + 8, info);
350 break;
352 case 'c':
353 func (stream, "%s",
354 arm_conditional [(given >> 28) & 0xf]);
355 break;
357 case 'm':
359 int started = 0;
360 int reg;
362 func (stream, "{");
363 for (reg = 0; reg < 16; reg++)
364 if ((given & (1 << reg)) != 0)
366 if (started)
367 func (stream, ", ");
368 started = 1;
369 func (stream, "%s", arm_regnames[reg]);
371 func (stream, "}");
373 break;
375 case 'o':
376 if ((given & 0x02000000) != 0)
378 int rotate = (given & 0xf00) >> 7;
379 int immed = (given & 0xff);
380 immed = (((immed << (32 - rotate))
381 | (immed >> rotate)) & 0xffffffff);
382 func (stream, "#%d\t; 0x%x", immed, immed);
384 else
385 arm_decode_shift (given, func, stream);
386 break;
388 case 'p':
389 if ((given & 0x0000f000) == 0x0000f000)
390 func (stream, "p");
391 break;
393 case 't':
394 if ((given & 0x01200000) == 0x00200000)
395 func (stream, "t");
396 break;
398 case 'A':
399 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
400 if ((given & 0x01000000) != 0)
402 int offset = given & 0xff;
403 if (offset)
404 func (stream, ", %s#%d]%s",
405 ((given & 0x00800000) == 0 ? "-" : ""),
406 offset * 4,
407 ((given & 0x00200000) != 0 ? "!" : ""));
408 else
409 func (stream, "]");
411 else
413 int offset = given & 0xff;
414 if (offset)
415 func (stream, "], %s#%d",
416 ((given & 0x00800000) == 0 ? "-" : ""),
417 offset * 4);
418 else
419 func (stream, "]");
421 break;
423 case 'B':
424 /* Print ARM V5 BLX(1) address: pc+25 bits. */
426 bfd_vma address;
427 bfd_vma offset = 0;
429 if (given & 0x00800000)
430 /* Is signed, hi bits should be ones. */
431 offset = (-1) ^ 0x00ffffff;
433 /* Offset is (SignExtend(offset field)<<2). */
434 offset += given & 0x00ffffff;
435 offset <<= 2;
436 address = offset + pc + 8;
438 if (given & 0x01000000)
439 /* H bit allows addressing to 2-byte boundaries. */
440 address += 2;
442 info->print_address_func (address, info);
444 break;
446 case 'I':
447 /* Print a Cirrus/DSP shift immediate. */
448 /* Immediates are 7bit signed ints with bits 0..3 in
449 bits 0..3 of opcode and bits 4..6 in bits 5..7
450 of opcode. */
452 int imm;
454 imm = (given & 0xf) | ((given & 0xe0) >> 1);
456 /* Is ``imm'' a negative number? */
457 if (imm & 0x40)
458 imm |= (-1 << 7);
460 func (stream, "%d", imm);
463 break;
465 case 'C':
466 func (stream, "_");
467 if (given & 0x80000)
468 func (stream, "f");
469 if (given & 0x40000)
470 func (stream, "s");
471 if (given & 0x20000)
472 func (stream, "x");
473 if (given & 0x10000)
474 func (stream, "c");
475 break;
477 case 'F':
478 switch (given & 0x00408000)
480 case 0:
481 func (stream, "4");
482 break;
483 case 0x8000:
484 func (stream, "1");
485 break;
486 case 0x00400000:
487 func (stream, "2");
488 break;
489 default:
490 func (stream, "3");
492 break;
494 case 'P':
495 switch (given & 0x00080080)
497 case 0:
498 func (stream, "s");
499 break;
500 case 0x80:
501 func (stream, "d");
502 break;
503 case 0x00080000:
504 func (stream, "e");
505 break;
506 default:
507 func (stream, _("<illegal precision>"));
508 break;
510 break;
511 case 'Q':
512 switch (given & 0x00408000)
514 case 0:
515 func (stream, "s");
516 break;
517 case 0x8000:
518 func (stream, "d");
519 break;
520 case 0x00400000:
521 func (stream, "e");
522 break;
523 default:
524 func (stream, "p");
525 break;
527 break;
528 case 'R':
529 switch (given & 0x60)
531 case 0:
532 break;
533 case 0x20:
534 func (stream, "p");
535 break;
536 case 0x40:
537 func (stream, "m");
538 break;
539 default:
540 func (stream, "z");
541 break;
543 break;
545 case '0': case '1': case '2': case '3': case '4':
546 case '5': case '6': case '7': case '8': case '9':
548 int bitstart = *c++ - '0';
549 int bitend = 0;
550 while (*c >= '0' && *c <= '9')
551 bitstart = (bitstart * 10) + *c++ - '0';
553 switch (*c)
555 case '-':
556 c++;
558 while (*c >= '0' && *c <= '9')
559 bitend = (bitend * 10) + *c++ - '0';
561 if (!bitend)
562 abort ();
564 switch (*c)
566 case 'r':
568 long reg;
570 reg = given >> bitstart;
571 reg &= (2 << (bitend - bitstart)) - 1;
573 func (stream, "%s", arm_regnames[reg]);
575 break;
576 case 'd':
578 long reg;
580 reg = given >> bitstart;
581 reg &= (2 << (bitend - bitstart)) - 1;
583 func (stream, "%d", reg);
585 break;
586 case 'x':
588 long reg;
590 reg = given >> bitstart;
591 reg &= (2 << (bitend - bitstart)) - 1;
593 func (stream, "0x%08x", reg);
595 /* Some SWI instructions have special
596 meanings. */
597 if ((given & 0x0fffffff) == 0x0FF00000)
598 func (stream, "\t; IMB");
599 else if ((given & 0x0fffffff) == 0x0FF00001)
600 func (stream, "\t; IMBRange");
602 break;
603 case 'X':
605 long reg;
607 reg = given >> bitstart;
608 reg &= (2 << (bitend - bitstart)) - 1;
610 func (stream, "%01x", reg & 0xf);
612 break;
613 case 'f':
615 long reg;
617 reg = given >> bitstart;
618 reg &= (2 << (bitend - bitstart)) - 1;
620 if (reg > 7)
621 func (stream, "#%s",
622 arm_fp_const[reg & 7]);
623 else
624 func (stream, "f%d", reg);
626 break;
627 default:
628 abort ();
630 break;
632 case 'y':
633 case 'z':
635 int single = *c == 'y';
636 int regno;
638 switch (bitstart)
640 case 4: /* Sm pair */
641 func (stream, "{");
642 /* Fall through. */
643 case 0: /* Sm, Dm */
644 regno = given & 0x0000000f;
645 if (single)
647 regno <<= 1;
648 regno += (given >> 5) & 1;
650 break;
652 case 1: /* Sd, Dd */
653 regno = (given >> 12) & 0x0000000f;
654 if (single)
656 regno <<= 1;
657 regno += (given >> 22) & 1;
659 break;
661 case 2: /* Sn, Dn */
662 regno = (given >> 16) & 0x0000000f;
663 if (single)
665 regno <<= 1;
666 regno += (given >> 7) & 1;
668 break;
670 case 3: /* List */
671 func (stream, "{");
672 regno = (given >> 12) & 0x0000000f;
673 if (single)
675 regno <<= 1;
676 regno += (given >> 22) & 1;
678 break;
681 default:
682 abort ();
685 func (stream, "%c%d", single ? 's' : 'd', regno);
687 if (bitstart == 3)
689 int count = given & 0xff;
691 if (single == 0)
692 count >>= 1;
694 if (--count)
696 func (stream, "-%c%d",
697 single ? 's' : 'd',
698 regno + count);
701 func (stream, "}");
703 else if (bitstart == 4)
704 func (stream, ", %c%d}", single ? 's' : 'd',
705 regno + 1);
707 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 break;
720 case '?':
721 ++c;
722 if ((given & (1 << bitstart)) != 0)
723 func (stream, "%c", *c++);
724 else
725 func (stream, "%c", *++c);
726 break;
727 default:
728 abort ();
730 break;
732 default:
733 abort ();
737 else
738 func (stream, "%c", *c);
740 return 4;
743 abort ();
746 /* Print one instruction from PC on INFO->STREAM.
747 Return the size of the instruction. */
749 static int
750 print_insn_thumb (pc, info, given)
751 bfd_vma pc;
752 struct disassemble_info * info;
753 long given;
755 struct thumb_opcode * insn;
756 void * stream = info->stream;
757 fprintf_ftype func = info->fprintf_func;
759 for (insn = thumb_opcodes; insn->assembler; insn++)
761 if ((given & insn->mask) == insn->value)
763 char * c = insn->assembler;
765 /* Special processing for Thumb 2 instruction BL sequence: */
766 if (!*c) /* Check for empty (not NULL) assembler string. */
768 long offset;
770 info->bytes_per_chunk = 4;
771 info->bytes_per_line = 4;
773 offset = BDISP23 (given);
774 offset = offset * 2 + pc + 4;
776 if ((given & 0x10000000) == 0)
778 func (stream, "blx\t");
779 offset &= 0xfffffffc;
781 else
782 func (stream, "bl\t");
784 info->print_address_func (offset, info);
785 return 4;
787 else
789 info->bytes_per_chunk = 2;
790 info->bytes_per_line = 4;
792 given &= 0xffff;
794 for (; *c; c++)
796 if (*c == '%')
798 int domaskpc = 0;
799 int domasklr = 0;
801 switch (*++c)
803 case '%':
804 func (stream, "%%");
805 break;
807 case 'S':
809 long reg;
811 reg = (given >> 3) & 0x7;
812 if (given & (1 << 6))
813 reg += 8;
815 func (stream, "%s", arm_regnames[reg]);
817 break;
819 case 'D':
821 long reg;
823 reg = given & 0x7;
824 if (given & (1 << 7))
825 reg += 8;
827 func (stream, "%s", arm_regnames[reg]);
829 break;
831 case 'T':
832 func (stream, "%s",
833 arm_conditional [(given >> 8) & 0xf]);
834 break;
836 case 'N':
837 if (given & (1 << 8))
838 domasklr = 1;
839 /* Fall through. */
840 case 'O':
841 if (*c == 'O' && (given & (1 << 8)))
842 domaskpc = 1;
843 /* Fall through. */
844 case 'M':
846 int started = 0;
847 int reg;
849 func (stream, "{");
851 /* It would be nice if we could spot
852 ranges, and generate the rS-rE format: */
853 for (reg = 0; (reg < 8); reg++)
854 if ((given & (1 << reg)) != 0)
856 if (started)
857 func (stream, ", ");
858 started = 1;
859 func (stream, "%s", arm_regnames[reg]);
862 if (domasklr)
864 if (started)
865 func (stream, ", ");
866 started = 1;
867 func (stream, arm_regnames[14] /* "lr" */);
870 if (domaskpc)
872 if (started)
873 func (stream, ", ");
874 func (stream, arm_regnames[15] /* "pc" */);
877 func (stream, "}");
879 break;
882 case '0': case '1': case '2': case '3': case '4':
883 case '5': case '6': case '7': case '8': case '9':
885 int bitstart = *c++ - '0';
886 int bitend = 0;
888 while (*c >= '0' && *c <= '9')
889 bitstart = (bitstart * 10) + *c++ - '0';
891 switch (*c)
893 case '-':
895 long reg;
897 c++;
898 while (*c >= '0' && *c <= '9')
899 bitend = (bitend * 10) + *c++ - '0';
900 if (!bitend)
901 abort ();
902 reg = given >> bitstart;
903 reg &= (2 << (bitend - bitstart)) - 1;
904 switch (*c)
906 case 'r':
907 func (stream, "%s", arm_regnames[reg]);
908 break;
910 case 'd':
911 func (stream, "%d", reg);
912 break;
914 case 'H':
915 func (stream, "%d", reg << 1);
916 break;
918 case 'W':
919 func (stream, "%d", reg << 2);
920 break;
922 case 'a':
923 /* PC-relative address -- the bottom two
924 bits of the address are dropped
925 before the calculation. */
926 info->print_address_func
927 (((pc + 4) & ~3) + (reg << 2), info);
928 break;
930 case 'x':
931 func (stream, "0x%04x", reg);
932 break;
934 case 'I':
935 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
936 func (stream, "%d", reg);
937 break;
939 case 'B':
940 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
941 (*info->print_address_func)
942 (reg * 2 + pc + 4, info);
943 break;
945 default:
946 abort ();
949 break;
951 case '\'':
952 c++;
953 if ((given & (1 << bitstart)) != 0)
954 func (stream, "%c", *c);
955 break;
957 case '?':
958 ++c;
959 if ((given & (1 << bitstart)) != 0)
960 func (stream, "%c", *c++);
961 else
962 func (stream, "%c", *++c);
963 break;
965 default:
966 abort ();
969 break;
971 default:
972 abort ();
975 else
976 func (stream, "%c", *c);
979 return 2;
983 /* No match. */
984 abort ();
987 /* Parse an individual disassembler option. */
989 void
990 parse_arm_disassembler_option (option)
991 char * option;
993 if (option == NULL)
994 return;
996 if (strneq (option, "reg-names-", 10))
998 int i;
1000 option += 10;
1002 for (i = NUM_ARM_REGNAMES; i--;)
1003 if (streq (option, regnames[i].name))
1005 regname_selected = i;
1006 break;
1009 if (i < 0)
1010 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1012 else if (streq (option, "force-thumb"))
1013 force_thumb = 1;
1014 else if (streq (option, "no-force-thumb"))
1015 force_thumb = 0;
1016 else
1017 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1019 return;
1022 /* Parse the string of disassembler options, spliting it at whitespaces. */
1024 static void
1025 parse_disassembler_options (options)
1026 char * options;
1028 char * space;
1030 if (options == NULL)
1031 return;
1035 space = strchr (options, ' ');
1037 if (space)
1039 * space = '\0';
1040 parse_arm_disassembler_option (options);
1041 * space = ' ';
1042 options = space + 1;
1044 else
1045 parse_arm_disassembler_option (options);
1047 while (space);
1050 /* NOTE: There are no checks in these routines that
1051 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");