gas/
[binutils.git] / opcodes / arm-dis.c
blob44cdeac344925a4d369426498b2b1ffe4306244d
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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"
30 #include "safe-ctype.h"
32 /* FIXME: This shouldn't be done here. */
33 #include "elf-bfd.h"
34 #include "elf/internal.h"
35 #include "elf/arm.h"
37 #ifndef streq
38 #define streq(a,b) (strcmp ((a), (b)) == 0)
39 #endif
41 #ifndef strneq
42 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
43 #endif
45 #ifndef NUM_ELEM
46 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
47 #endif
49 static char * arm_conditional[] =
50 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
51 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
53 typedef struct
55 const char * name;
56 const char * description;
57 const char * reg_names[16];
59 arm_regname;
61 static arm_regname regnames[] =
63 { "raw" , "Select raw register names",
64 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
65 { "gcc", "Select register names used by GCC",
66 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
67 { "std", "Select register names used in ARM's ISA documentation",
68 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
69 { "apcs", "Select register names used in the APCS",
70 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
71 { "atpcs", "Select register names used in the ATPCS",
72 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
73 { "special-atpcs", "Select special register names used in the ATPCS",
74 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
75 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
76 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
77 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
78 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
81 static char * iwmmxt_wwnames[] =
82 {"b", "h", "w", "d"};
84 static char * iwmmxt_wwssnames[] =
85 {"b", "bus", "b", "bss",
86 "h", "hus", "h", "hss",
87 "w", "wus", "w", "wss",
88 "d", "dus", "d", "dss"
91 /* Default to GCC register name set. */
92 static unsigned int regname_selected = 1;
94 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
95 #define arm_regnames regnames[regname_selected].reg_names
97 static bfd_boolean force_thumb = FALSE;
99 static char * arm_fp_const[] =
100 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
102 static char * arm_shift[] =
103 {"lsl", "lsr", "asr", "ror"};
105 /* Forward declarations. */
106 static void arm_decode_shift
107 PARAMS ((long, fprintf_ftype, void *));
108 static int print_insn_arm
109 PARAMS ((bfd_vma, struct disassemble_info *, long));
110 static int print_insn_thumb
111 PARAMS ((bfd_vma, struct disassemble_info *, long));
112 static void parse_disassembler_options
113 PARAMS ((char *));
114 static int print_insn
115 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
116 static int set_iwmmxt_regnames
117 PARAMS ((void));
119 int get_arm_regname_num_options
120 PARAMS ((void));
121 int set_arm_regname_option
122 PARAMS ((int));
123 int get_arm_regnames
124 PARAMS ((int, const char **, const char **, const char ***));
126 /* Functions. */
128 get_arm_regname_num_options ()
130 return NUM_ARM_REGNAMES;
134 set_arm_regname_option (option)
135 int option;
137 int old = regname_selected;
138 regname_selected = option;
139 return old;
143 get_arm_regnames (option, setname, setdescription, register_names)
144 int option;
145 const char **setname;
146 const char **setdescription;
147 const char ***register_names;
149 *setname = regnames[option].name;
150 *setdescription = regnames[option].description;
151 *register_names = regnames[option].reg_names;
152 return 16;
155 static void
156 arm_decode_shift (given, func, stream)
157 long given;
158 fprintf_ftype func;
159 void * stream;
161 func (stream, "%s", arm_regnames[given & 0xf]);
163 if ((given & 0xff0) != 0)
165 if ((given & 0x10) == 0)
167 int amount = (given & 0xf80) >> 7;
168 int shift = (given & 0x60) >> 5;
170 if (amount == 0)
172 if (shift == 3)
174 func (stream, ", rrx");
175 return;
178 amount = 32;
181 func (stream, ", %s #%d", arm_shift[shift], amount);
183 else
184 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
185 arm_regnames[(given & 0xf00) >> 8]);
189 static int
190 set_iwmmxt_regnames ()
192 const char * setname;
193 const char * setdesc;
194 const char ** regnames;
195 int iwmmxt_regnames = 0;
196 int num_regnames = get_arm_regname_num_options ();
198 get_arm_regnames (iwmmxt_regnames, &setname,
199 &setdesc, &regnames);
200 while ((strcmp ("iwmmxt_regnames", setname))
201 && (iwmmxt_regnames < num_regnames))
202 get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
204 return iwmmxt_regnames;
207 /* Print one instruction from PC on INFO->STREAM.
208 Return the size of the instruction (always 4 on ARM). */
210 static int
211 print_insn_arm (pc, info, given)
212 bfd_vma pc;
213 struct disassemble_info *info;
214 long given;
216 const struct arm_opcode *insn;
217 void *stream = info->stream;
218 fprintf_ftype func = info->fprintf_func;
219 static int iwmmxt_regnames = 0;
221 for (insn = arm_opcodes; insn->assembler; insn++)
223 if (insn->value == FIRST_IWMMXT_INSN
224 && info->mach != bfd_mach_arm_XScale
225 && info->mach != bfd_mach_arm_iWMMXt)
226 insn = insn + IWMMXT_INSN_COUNT;
228 if ((given & insn->mask) == insn->value)
230 char * c;
232 for (c = insn->assembler; *c; c++)
234 if (*c == '%')
236 switch (*++c)
238 case '%':
239 func (stream, "%%");
240 break;
242 case 'a':
243 if (((given & 0x000f0000) == 0x000f0000)
244 && ((given & 0x02000000) == 0))
246 int offset = given & 0xfff;
248 func (stream, "[pc");
250 if (given & 0x01000000)
252 if ((given & 0x00800000) == 0)
253 offset = - offset;
255 /* Pre-indexed. */
256 func (stream, ", #%d]", offset);
258 offset += pc + 8;
260 /* Cope with the possibility of write-back
261 being used. Probably a very dangerous thing
262 for the programmer to do, but who are we to
263 argue ? */
264 if (given & 0x00200000)
265 func (stream, "!");
267 else
269 /* Post indexed. */
270 func (stream, "], #%d", offset);
272 /* ie ignore the offset. */
273 offset = pc + 8;
276 func (stream, "\t; ");
277 info->print_address_func (offset, info);
279 else
281 func (stream, "[%s",
282 arm_regnames[(given >> 16) & 0xf]);
283 if ((given & 0x01000000) != 0)
285 if ((given & 0x02000000) == 0)
287 int offset = given & 0xfff;
288 if (offset)
289 func (stream, ", #%s%d",
290 (((given & 0x00800000) == 0)
291 ? "-" : ""), offset);
293 else
295 func (stream, ", %s",
296 (((given & 0x00800000) == 0)
297 ? "-" : ""));
298 arm_decode_shift (given, func, stream);
301 func (stream, "]%s",
302 ((given & 0x00200000) != 0) ? "!" : "");
304 else
306 if ((given & 0x02000000) == 0)
308 int offset = given & 0xfff;
309 if (offset)
310 func (stream, "], #%s%d",
311 (((given & 0x00800000) == 0)
312 ? "-" : ""), offset);
313 else
314 func (stream, "]");
316 else
318 func (stream, "], %s",
319 (((given & 0x00800000) == 0)
320 ? "-" : ""));
321 arm_decode_shift (given, func, stream);
325 break;
327 case 's':
328 if ((given & 0x004f0000) == 0x004f0000)
330 /* PC relative with immediate offset. */
331 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
333 if ((given & 0x00800000) == 0)
334 offset = -offset;
336 func (stream, "[pc, #%d]\t; ", offset);
338 (*info->print_address_func)
339 (offset + pc + 8, info);
341 else
343 func (stream, "[%s",
344 arm_regnames[(given >> 16) & 0xf]);
345 if ((given & 0x01000000) != 0)
347 /* Pre-indexed. */
348 if ((given & 0x00400000) == 0x00400000)
350 /* Immediate. */
351 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
352 if (offset)
353 func (stream, ", #%s%d",
354 (((given & 0x00800000) == 0)
355 ? "-" : ""), offset);
357 else
359 /* Register. */
360 func (stream, ", %s%s",
361 (((given & 0x00800000) == 0)
362 ? "-" : ""),
363 arm_regnames[given & 0xf]);
366 func (stream, "]%s",
367 ((given & 0x00200000) != 0) ? "!" : "");
369 else
371 /* Post-indexed. */
372 if ((given & 0x00400000) == 0x00400000)
374 /* Immediate. */
375 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
376 if (offset)
377 func (stream, "], #%s%d",
378 (((given & 0x00800000) == 0)
379 ? "-" : ""), offset);
380 else
381 func (stream, "]");
383 else
385 /* Register. */
386 func (stream, "], %s%s",
387 (((given & 0x00800000) == 0)
388 ? "-" : ""),
389 arm_regnames[given & 0xf]);
393 break;
395 case 'b':
396 (*info->print_address_func)
397 (BDISP (given) * 4 + pc + 8, info);
398 break;
400 case 'c':
401 func (stream, "%s",
402 arm_conditional [(given >> 28) & 0xf]);
403 break;
405 case 'm':
407 int started = 0;
408 int reg;
410 func (stream, "{");
411 for (reg = 0; reg < 16; reg++)
412 if ((given & (1 << reg)) != 0)
414 if (started)
415 func (stream, ", ");
416 started = 1;
417 func (stream, "%s", arm_regnames[reg]);
419 func (stream, "}");
421 break;
423 case 'o':
424 if ((given & 0x02000000) != 0)
426 int rotate = (given & 0xf00) >> 7;
427 int immed = (given & 0xff);
428 immed = (((immed << (32 - rotate))
429 | (immed >> rotate)) & 0xffffffff);
430 func (stream, "#%d\t; 0x%x", immed, immed);
432 else
433 arm_decode_shift (given, func, stream);
434 break;
436 case 'p':
437 if ((given & 0x0000f000) == 0x0000f000)
438 func (stream, "p");
439 break;
441 case 't':
442 if ((given & 0x01200000) == 0x00200000)
443 func (stream, "t");
444 break;
446 case 'A':
447 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
449 if ((given & (1 << 24)) != 0)
451 int offset = given & 0xff;
453 if (offset)
454 func (stream, ", #%s%d]%s",
455 ((given & 0x00800000) == 0 ? "-" : ""),
456 offset * 4,
457 ((given & 0x00200000) != 0 ? "!" : ""));
458 else
459 func (stream, "]");
461 else
463 int offset = given & 0xff;
465 func (stream, "]");
467 if (given & (1 << 21))
469 if (offset)
470 func (stream, ", #%s%d",
471 ((given & 0x00800000) == 0 ? "-" : ""),
472 offset * 4);
474 else
475 func (stream, ", {%d}", offset);
477 break;
479 case 'B':
480 /* Print ARM V5 BLX(1) address: pc+25 bits. */
482 bfd_vma address;
483 bfd_vma offset = 0;
485 if (given & 0x00800000)
486 /* Is signed, hi bits should be ones. */
487 offset = (-1) ^ 0x00ffffff;
489 /* Offset is (SignExtend(offset field)<<2). */
490 offset += given & 0x00ffffff;
491 offset <<= 2;
492 address = offset + pc + 8;
494 if (given & 0x01000000)
495 /* H bit allows addressing to 2-byte boundaries. */
496 address += 2;
498 info->print_address_func (address, info);
500 break;
502 case 'I':
503 /* Print a Cirrus/DSP shift immediate. */
504 /* Immediates are 7bit signed ints with bits 0..3 in
505 bits 0..3 of opcode and bits 4..6 in bits 5..7
506 of opcode. */
508 int imm;
510 imm = (given & 0xf) | ((given & 0xe0) >> 1);
512 /* Is ``imm'' a negative number? */
513 if (imm & 0x40)
514 imm |= (-1 << 7);
516 func (stream, "%d", imm);
519 break;
521 case 'C':
522 func (stream, "_");
523 if (given & 0x80000)
524 func (stream, "f");
525 if (given & 0x40000)
526 func (stream, "s");
527 if (given & 0x20000)
528 func (stream, "x");
529 if (given & 0x10000)
530 func (stream, "c");
531 break;
533 case 'F':
534 switch (given & 0x00408000)
536 case 0:
537 func (stream, "4");
538 break;
539 case 0x8000:
540 func (stream, "1");
541 break;
542 case 0x00400000:
543 func (stream, "2");
544 break;
545 default:
546 func (stream, "3");
548 break;
550 case 'P':
551 switch (given & 0x00080080)
553 case 0:
554 func (stream, "s");
555 break;
556 case 0x80:
557 func (stream, "d");
558 break;
559 case 0x00080000:
560 func (stream, "e");
561 break;
562 default:
563 func (stream, _("<illegal precision>"));
564 break;
566 break;
567 case 'Q':
568 switch (given & 0x00408000)
570 case 0:
571 func (stream, "s");
572 break;
573 case 0x8000:
574 func (stream, "d");
575 break;
576 case 0x00400000:
577 func (stream, "e");
578 break;
579 default:
580 func (stream, "p");
581 break;
583 break;
584 case 'R':
585 switch (given & 0x60)
587 case 0:
588 break;
589 case 0x20:
590 func (stream, "p");
591 break;
592 case 0x40:
593 func (stream, "m");
594 break;
595 default:
596 func (stream, "z");
597 break;
599 break;
601 case '0': case '1': case '2': case '3': case '4':
602 case '5': case '6': case '7': case '8': case '9':
604 int bitstart = *c++ - '0';
605 int bitend = 0;
606 while (*c >= '0' && *c <= '9')
607 bitstart = (bitstart * 10) + *c++ - '0';
609 switch (*c)
611 case '-':
612 c++;
614 while (*c >= '0' && *c <= '9')
615 bitend = (bitend * 10) + *c++ - '0';
617 if (!bitend)
618 abort ();
620 switch (*c)
622 case 'r':
624 long reg;
626 reg = given >> bitstart;
627 reg &= (2 << (bitend - bitstart)) - 1;
629 func (stream, "%s", arm_regnames[reg]);
631 break;
632 case 'd':
634 long reg;
636 reg = given >> bitstart;
637 reg &= (2 << (bitend - bitstart)) - 1;
639 func (stream, "%d", reg);
641 break;
642 case 'W':
644 long reg;
646 reg = given >> bitstart;
647 reg &= (2 << (bitend - bitstart)) - 1;
649 func (stream, "%d", reg + 1);
651 break;
652 case 'x':
654 long reg;
656 reg = given >> bitstart;
657 reg &= (2 << (bitend - bitstart)) - 1;
659 func (stream, "0x%08x", reg);
661 /* Some SWI instructions have special
662 meanings. */
663 if ((given & 0x0fffffff) == 0x0FF00000)
664 func (stream, "\t; IMB");
665 else if ((given & 0x0fffffff) == 0x0FF00001)
666 func (stream, "\t; IMBRange");
668 break;
669 case 'X':
671 long reg;
673 reg = given >> bitstart;
674 reg &= (2 << (bitend - bitstart)) - 1;
676 func (stream, "%01x", reg & 0xf);
678 break;
679 case 'f':
681 long reg;
683 reg = given >> bitstart;
684 reg &= (2 << (bitend - bitstart)) - 1;
686 if (reg > 7)
687 func (stream, "#%s",
688 arm_fp_const[reg & 7]);
689 else
690 func (stream, "f%d", reg);
692 break;
694 case 'w':
696 long reg;
698 if (bitstart != bitend)
700 reg = given >> bitstart;
701 reg &= (2 << (bitend - bitstart)) - 1;
702 if (bitend - bitstart == 1)
703 func (stream, "%s", iwmmxt_wwnames[reg]);
704 else
705 func (stream, "%s", iwmmxt_wwssnames[reg]);
707 else
709 reg = (((given >> 8) & 0x1) |
710 ((given >> 22) & 0x1));
711 func (stream, "%s", iwmmxt_wwnames[reg]);
714 break;
716 case 'g':
718 long reg;
719 int current_regnames;
721 if (! iwmmxt_regnames)
722 iwmmxt_regnames = set_iwmmxt_regnames ();
723 current_regnames = set_arm_regname_option
724 (iwmmxt_regnames);
726 reg = given >> bitstart;
727 reg &= (2 << (bitend - bitstart)) - 1;
728 func (stream, "%s", arm_regnames[reg]);
729 set_arm_regname_option (current_regnames);
731 break;
733 case 'G':
735 long reg;
736 int current_regnames;
738 if (! iwmmxt_regnames)
739 iwmmxt_regnames = set_iwmmxt_regnames ();
740 current_regnames = set_arm_regname_option
741 (iwmmxt_regnames + 1);
743 reg = given >> bitstart;
744 reg &= (2 << (bitend - bitstart)) - 1;
745 func (stream, "%s", arm_regnames[reg]);
746 set_arm_regname_option (current_regnames);
748 break;
750 default:
751 abort ();
753 break;
755 case 'y':
756 case 'z':
758 int single = *c == 'y';
759 int regno;
761 switch (bitstart)
763 case 4: /* Sm pair */
764 func (stream, "{");
765 /* Fall through. */
766 case 0: /* Sm, Dm */
767 regno = given & 0x0000000f;
768 if (single)
770 regno <<= 1;
771 regno += (given >> 5) & 1;
773 break;
775 case 1: /* Sd, Dd */
776 regno = (given >> 12) & 0x0000000f;
777 if (single)
779 regno <<= 1;
780 regno += (given >> 22) & 1;
782 break;
784 case 2: /* Sn, Dn */
785 regno = (given >> 16) & 0x0000000f;
786 if (single)
788 regno <<= 1;
789 regno += (given >> 7) & 1;
791 break;
793 case 3: /* List */
794 func (stream, "{");
795 regno = (given >> 12) & 0x0000000f;
796 if (single)
798 regno <<= 1;
799 regno += (given >> 22) & 1;
801 break;
804 default:
805 abort ();
808 func (stream, "%c%d", single ? 's' : 'd', regno);
810 if (bitstart == 3)
812 int count = given & 0xff;
814 if (single == 0)
815 count >>= 1;
817 if (--count)
819 func (stream, "-%c%d",
820 single ? 's' : 'd',
821 regno + count);
824 func (stream, "}");
826 else if (bitstart == 4)
827 func (stream, ", %c%d}", single ? 's' : 'd',
828 regno + 1);
830 break;
833 case '`':
834 c++;
835 if ((given & (1 << bitstart)) == 0)
836 func (stream, "%c", *c);
837 break;
838 case '\'':
839 c++;
840 if ((given & (1 << bitstart)) != 0)
841 func (stream, "%c", *c);
842 break;
843 case '?':
844 ++c;
845 if ((given & (1 << bitstart)) != 0)
846 func (stream, "%c", *c++);
847 else
848 func (stream, "%c", *++c);
849 break;
850 default:
851 abort ();
853 break;
855 case 'L':
856 switch (given & 0x00400100)
858 case 0x00000000: func (stream, "b"); break;
859 case 0x00400000: func (stream, "h"); break;
860 case 0x00000100: func (stream, "w"); break;
861 case 0x00400100: func (stream, "d"); break;
862 default:
863 break;
865 break;
867 case 'Z':
869 int value;
870 /* given (20, 23) | given (0, 3) */
871 value = ((given >> 16) & 0xf0) | (given & 0xf);
872 func (stream, "%d", value);
874 break;
876 case 'l':
877 /* This is like the 'A' operator, except that if
878 the width field "M" is zero, then the offset is
879 *not* multiplied by four. */
881 int offset = given & 0xff;
882 int multiplier = (given & 0x00000100) ? 4 : 1;
884 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
886 if (offset)
888 if ((given & 0x01000000) != 0)
889 func (stream, ", #%s%d]%s",
890 ((given & 0x00800000) == 0 ? "-" : ""),
891 offset * multiplier,
892 ((given & 0x00200000) != 0 ? "!" : ""));
893 else
894 func (stream, "], #%s%d",
895 ((given & 0x00800000) == 0 ? "-" : ""),
896 offset * multiplier);
898 else
899 func (stream, "]");
901 break;
903 case 'e':
905 int imm;
907 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
908 func (stream, "%d", imm);
910 break;
912 default:
913 abort ();
917 else
918 func (stream, "%c", *c);
920 return 4;
923 abort ();
926 /* Print one instruction from PC on INFO->STREAM.
927 Return the size of the instruction. */
929 static int
930 print_insn_thumb (pc, info, given)
931 bfd_vma pc;
932 struct disassemble_info *info;
933 long given;
935 const struct thumb_opcode *insn;
936 void *stream = info->stream;
937 fprintf_ftype func = info->fprintf_func;
939 for (insn = thumb_opcodes; insn->assembler; insn++)
941 if ((given & insn->mask) == insn->value)
943 char * c = insn->assembler;
945 /* Special processing for Thumb 2 instruction BL sequence: */
946 if (!*c) /* Check for empty (not NULL) assembler string. */
948 long offset;
950 info->bytes_per_chunk = 4;
951 info->bytes_per_line = 4;
953 offset = BDISP23 (given);
954 offset = offset * 2 + pc + 4;
956 if ((given & 0x10000000) == 0)
958 func (stream, "blx\t");
959 offset &= 0xfffffffc;
961 else
962 func (stream, "bl\t");
964 info->print_address_func (offset, info);
965 return 4;
967 else
969 info->bytes_per_chunk = 2;
970 info->bytes_per_line = 4;
972 given &= 0xffff;
974 for (; *c; c++)
976 if (*c == '%')
978 int domaskpc = 0;
979 int domasklr = 0;
981 switch (*++c)
983 case '%':
984 func (stream, "%%");
985 break;
987 case 'S':
989 long reg;
991 reg = (given >> 3) & 0x7;
992 if (given & (1 << 6))
993 reg += 8;
995 func (stream, "%s", arm_regnames[reg]);
997 break;
999 case 'D':
1001 long reg;
1003 reg = given & 0x7;
1004 if (given & (1 << 7))
1005 reg += 8;
1007 func (stream, "%s", arm_regnames[reg]);
1009 break;
1011 case 'T':
1012 func (stream, "%s",
1013 arm_conditional [(given >> 8) & 0xf]);
1014 break;
1016 case 'N':
1017 if (given & (1 << 8))
1018 domasklr = 1;
1019 /* Fall through. */
1020 case 'O':
1021 if (*c == 'O' && (given & (1 << 8)))
1022 domaskpc = 1;
1023 /* Fall through. */
1024 case 'M':
1026 int started = 0;
1027 int reg;
1029 func (stream, "{");
1031 /* It would be nice if we could spot
1032 ranges, and generate the rS-rE format: */
1033 for (reg = 0; (reg < 8); reg++)
1034 if ((given & (1 << reg)) != 0)
1036 if (started)
1037 func (stream, ", ");
1038 started = 1;
1039 func (stream, "%s", arm_regnames[reg]);
1042 if (domasklr)
1044 if (started)
1045 func (stream, ", ");
1046 started = 1;
1047 func (stream, arm_regnames[14] /* "lr" */);
1050 if (domaskpc)
1052 if (started)
1053 func (stream, ", ");
1054 func (stream, arm_regnames[15] /* "pc" */);
1057 func (stream, "}");
1059 break;
1062 case '0': case '1': case '2': case '3': case '4':
1063 case '5': case '6': case '7': case '8': case '9':
1065 int bitstart = *c++ - '0';
1066 int bitend = 0;
1068 while (*c >= '0' && *c <= '9')
1069 bitstart = (bitstart * 10) + *c++ - '0';
1071 switch (*c)
1073 case '-':
1075 long reg;
1077 c++;
1078 while (*c >= '0' && *c <= '9')
1079 bitend = (bitend * 10) + *c++ - '0';
1080 if (!bitend)
1081 abort ();
1082 reg = given >> bitstart;
1083 reg &= (2 << (bitend - bitstart)) - 1;
1084 switch (*c)
1086 case 'r':
1087 func (stream, "%s", arm_regnames[reg]);
1088 break;
1090 case 'd':
1091 func (stream, "%d", reg);
1092 break;
1094 case 'H':
1095 func (stream, "%d", reg << 1);
1096 break;
1098 case 'W':
1099 func (stream, "%d", reg << 2);
1100 break;
1102 case 'a':
1103 /* PC-relative address -- the bottom two
1104 bits of the address are dropped
1105 before the calculation. */
1106 info->print_address_func
1107 (((pc + 4) & ~3) + (reg << 2), info);
1108 break;
1110 case 'x':
1111 func (stream, "0x%04x", reg);
1112 break;
1114 case 'I':
1115 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1116 func (stream, "%d", reg);
1117 break;
1119 case 'B':
1120 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1121 (*info->print_address_func)
1122 (reg * 2 + pc + 4, info);
1123 break;
1125 default:
1126 abort ();
1129 break;
1131 case '\'':
1132 c++;
1133 if ((given & (1 << bitstart)) != 0)
1134 func (stream, "%c", *c);
1135 break;
1137 case '?':
1138 ++c;
1139 if ((given & (1 << bitstart)) != 0)
1140 func (stream, "%c", *c++);
1141 else
1142 func (stream, "%c", *++c);
1143 break;
1145 default:
1146 abort ();
1149 break;
1151 default:
1152 abort ();
1155 else
1156 func (stream, "%c", *c);
1159 return 2;
1163 /* No match. */
1164 abort ();
1167 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
1168 being displayed in symbol relative addresses. */
1170 bfd_boolean
1171 arm_symbol_is_valid (asymbol * sym,
1172 struct disassemble_info * info ATTRIBUTE_UNUSED)
1174 const char * name;
1176 if (sym == NULL)
1177 return FALSE;
1179 name = bfd_asymbol_name (sym);
1181 return (name && *name != '$');
1184 /* Parse an individual disassembler option. */
1186 void
1187 parse_arm_disassembler_option (option)
1188 char * option;
1190 if (option == NULL)
1191 return;
1193 if (strneq (option, "reg-names-", 10))
1195 int i;
1197 option += 10;
1199 for (i = NUM_ARM_REGNAMES; i--;)
1200 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1202 regname_selected = i;
1203 break;
1206 if (i < 0)
1207 /* XXX - should break 'option' at following delimiter. */
1208 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1210 else if (strneq (option, "force-thumb", 11))
1211 force_thumb = 1;
1212 else if (strneq (option, "no-force-thumb", 14))
1213 force_thumb = 0;
1214 else
1215 /* XXX - should break 'option' at following delimiter. */
1216 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1218 return;
1221 /* Parse the string of disassembler options, spliting it at whitespaces
1222 or commas. (Whitespace separators supported for backwards compatibility). */
1224 static void
1225 parse_disassembler_options (options)
1226 char * options;
1228 if (options == NULL)
1229 return;
1231 while (*options)
1233 parse_arm_disassembler_option (options);
1235 /* Skip forward to next seperator. */
1236 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1237 ++ options;
1238 /* Skip forward past seperators. */
1239 while (ISSPACE (*options) || (*options == ','))
1240 ++ options;
1244 /* NOTE: There are no checks in these routines that
1245 the relevant number of data bytes exist. */
1247 static int
1248 print_insn (pc, info, little)
1249 bfd_vma pc;
1250 struct disassemble_info * info;
1251 bfd_boolean little;
1253 unsigned char b[4];
1254 long given;
1255 int status;
1256 int is_thumb;
1258 if (info->disassembler_options)
1260 parse_disassembler_options (info->disassembler_options);
1262 /* To avoid repeated parsing of these options, we remove them here. */
1263 info->disassembler_options = NULL;
1266 is_thumb = force_thumb;
1268 if (!is_thumb && info->symbols != NULL)
1270 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1272 coff_symbol_type * cs;
1274 cs = coffsymbol (*info->symbols);
1275 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1276 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1277 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1278 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1279 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1281 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1283 elf_symbol_type * es;
1284 unsigned int type;
1286 es = *(elf_symbol_type **)(info->symbols);
1287 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1289 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1293 info->bytes_per_chunk = 4;
1294 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1296 if (little)
1298 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1299 if (status != 0 && is_thumb)
1301 info->bytes_per_chunk = 2;
1303 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1304 b[3] = b[2] = 0;
1307 if (status != 0)
1309 info->memory_error_func (status, pc, info);
1310 return -1;
1313 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1315 else
1317 status = info->read_memory_func
1318 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1319 if (status != 0)
1321 info->memory_error_func (status, pc, info);
1322 return -1;
1325 if (is_thumb)
1327 if (pc & 0x2)
1329 given = (b[2] << 8) | b[3];
1331 status = info->read_memory_func
1332 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1333 if (status != 0)
1335 info->memory_error_func (status, pc + 4, info);
1336 return -1;
1339 given |= (b[0] << 24) | (b[1] << 16);
1341 else
1342 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1344 else
1345 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1348 if (info->flags & INSN_HAS_RELOC)
1349 /* If the instruction has a reloc associated with it, then
1350 the offset field in the instruction will actually be the
1351 addend for the reloc. (We are using REL type relocs).
1352 In such cases, we can ignore the pc when computing
1353 addresses, since the addend is not currently pc-relative. */
1354 pc = 0;
1356 if (is_thumb)
1357 status = print_insn_thumb (pc, info, given);
1358 else
1359 status = print_insn_arm (pc, info, given);
1361 return status;
1365 print_insn_big_arm (pc, info)
1366 bfd_vma pc;
1367 struct disassemble_info * info;
1369 return print_insn (pc, info, FALSE);
1373 print_insn_little_arm (pc, info)
1374 bfd_vma pc;
1375 struct disassemble_info * info;
1377 return print_insn (pc, info, TRUE);
1380 void
1381 print_arm_disassembler_options (FILE * stream)
1383 int i;
1385 fprintf (stream, _("\n\
1386 The following ARM specific disassembler options are supported for use with\n\
1387 the -M switch:\n"));
1389 for (i = NUM_ARM_REGNAMES; i--;)
1390 fprintf (stream, " reg-names-%s %*c%s\n",
1391 regnames[i].name,
1392 (int)(14 - strlen (regnames[i].name)), ' ',
1393 regnames[i].description);
1395 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
1396 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");