* config/tc-arm.c (arm_elf_change_section): Not static.
[binutils.git] / opcodes / arm-dis.c
blob5f8fc4cfd12ce126a09c08392c23269f59cf3514
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
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 'x':
644 long reg;
646 reg = given >> bitstart;
647 reg &= (2 << (bitend - bitstart)) - 1;
649 func (stream, "0x%08x", reg);
651 /* Some SWI instructions have special
652 meanings. */
653 if ((given & 0x0fffffff) == 0x0FF00000)
654 func (stream, "\t; IMB");
655 else if ((given & 0x0fffffff) == 0x0FF00001)
656 func (stream, "\t; IMBRange");
658 break;
659 case 'X':
661 long reg;
663 reg = given >> bitstart;
664 reg &= (2 << (bitend - bitstart)) - 1;
666 func (stream, "%01x", reg & 0xf);
668 break;
669 case 'f':
671 long reg;
673 reg = given >> bitstart;
674 reg &= (2 << (bitend - bitstart)) - 1;
676 if (reg > 7)
677 func (stream, "#%s",
678 arm_fp_const[reg & 7]);
679 else
680 func (stream, "f%d", reg);
682 break;
684 case 'w':
686 long reg;
688 if (bitstart != bitend)
690 reg = given >> bitstart;
691 reg &= (2 << (bitend - bitstart)) - 1;
692 if (bitend - bitstart == 1)
693 func (stream, "%s", iwmmxt_wwnames[reg]);
694 else
695 func (stream, "%s", iwmmxt_wwssnames[reg]);
697 else
699 reg = (((given >> 8) & 0x1) |
700 ((given >> 22) & 0x1));
701 func (stream, "%s", iwmmxt_wwnames[reg]);
704 break;
706 case 'g':
708 long reg;
709 int current_regnames;
711 if (! iwmmxt_regnames)
712 iwmmxt_regnames = set_iwmmxt_regnames ();
713 current_regnames = set_arm_regname_option
714 (iwmmxt_regnames);
716 reg = given >> bitstart;
717 reg &= (2 << (bitend - bitstart)) - 1;
718 func (stream, "%s", arm_regnames[reg]);
719 set_arm_regname_option (current_regnames);
721 break;
723 case 'G':
725 long reg;
726 int current_regnames;
728 if (! iwmmxt_regnames)
729 iwmmxt_regnames = set_iwmmxt_regnames ();
730 current_regnames = set_arm_regname_option
731 (iwmmxt_regnames + 1);
733 reg = given >> bitstart;
734 reg &= (2 << (bitend - bitstart)) - 1;
735 func (stream, "%s", arm_regnames[reg]);
736 set_arm_regname_option (current_regnames);
738 break;
740 default:
741 abort ();
743 break;
745 case 'y':
746 case 'z':
748 int single = *c == 'y';
749 int regno;
751 switch (bitstart)
753 case 4: /* Sm pair */
754 func (stream, "{");
755 /* Fall through. */
756 case 0: /* Sm, Dm */
757 regno = given & 0x0000000f;
758 if (single)
760 regno <<= 1;
761 regno += (given >> 5) & 1;
763 break;
765 case 1: /* Sd, Dd */
766 regno = (given >> 12) & 0x0000000f;
767 if (single)
769 regno <<= 1;
770 regno += (given >> 22) & 1;
772 break;
774 case 2: /* Sn, Dn */
775 regno = (given >> 16) & 0x0000000f;
776 if (single)
778 regno <<= 1;
779 regno += (given >> 7) & 1;
781 break;
783 case 3: /* List */
784 func (stream, "{");
785 regno = (given >> 12) & 0x0000000f;
786 if (single)
788 regno <<= 1;
789 regno += (given >> 22) & 1;
791 break;
794 default:
795 abort ();
798 func (stream, "%c%d", single ? 's' : 'd', regno);
800 if (bitstart == 3)
802 int count = given & 0xff;
804 if (single == 0)
805 count >>= 1;
807 if (--count)
809 func (stream, "-%c%d",
810 single ? 's' : 'd',
811 regno + count);
814 func (stream, "}");
816 else if (bitstart == 4)
817 func (stream, ", %c%d}", single ? 's' : 'd',
818 regno + 1);
820 break;
823 case '`':
824 c++;
825 if ((given & (1 << bitstart)) == 0)
826 func (stream, "%c", *c);
827 break;
828 case '\'':
829 c++;
830 if ((given & (1 << bitstart)) != 0)
831 func (stream, "%c", *c);
832 break;
833 case '?':
834 ++c;
835 if ((given & (1 << bitstart)) != 0)
836 func (stream, "%c", *c++);
837 else
838 func (stream, "%c", *++c);
839 break;
840 default:
841 abort ();
843 break;
845 case 'L':
846 switch (given & 0x00400100)
848 case 0x00000000: func (stream, "b"); break;
849 case 0x00400000: func (stream, "h"); break;
850 case 0x00000100: func (stream, "w"); break;
851 case 0x00400100: func (stream, "d"); break;
852 default:
853 break;
855 break;
857 case 'Z':
859 int value;
860 /* given (20, 23) | given (0, 3) */
861 value = ((given >> 16) & 0xf0) | (given & 0xf);
862 func (stream, "%d", value);
864 break;
866 case 'l':
867 /* This is like the 'A' operator, except that if
868 the width field "M" is zero, then the offset is
869 *not* multiplied by four. */
871 int offset = given & 0xff;
872 int multiplier = (given & 0x00000100) ? 4 : 1;
874 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
876 if (offset)
878 if ((given & 0x01000000) != 0)
879 func (stream, ", #%s%d]%s",
880 ((given & 0x00800000) == 0 ? "-" : ""),
881 offset * multiplier,
882 ((given & 0x00200000) != 0 ? "!" : ""));
883 else
884 func (stream, "], #%s%d",
885 ((given & 0x00800000) == 0 ? "-" : ""),
886 offset * multiplier);
888 else
889 func (stream, "]");
891 break;
893 default:
894 abort ();
898 else
899 func (stream, "%c", *c);
901 return 4;
904 abort ();
907 /* Print one instruction from PC on INFO->STREAM.
908 Return the size of the instruction. */
910 static int
911 print_insn_thumb (pc, info, given)
912 bfd_vma pc;
913 struct disassemble_info *info;
914 long given;
916 const struct thumb_opcode *insn;
917 void *stream = info->stream;
918 fprintf_ftype func = info->fprintf_func;
920 for (insn = thumb_opcodes; insn->assembler; insn++)
922 if ((given & insn->mask) == insn->value)
924 char * c = insn->assembler;
926 /* Special processing for Thumb 2 instruction BL sequence: */
927 if (!*c) /* Check for empty (not NULL) assembler string. */
929 long offset;
931 info->bytes_per_chunk = 4;
932 info->bytes_per_line = 4;
934 offset = BDISP23 (given);
935 offset = offset * 2 + pc + 4;
937 if ((given & 0x10000000) == 0)
939 func (stream, "blx\t");
940 offset &= 0xfffffffc;
942 else
943 func (stream, "bl\t");
945 info->print_address_func (offset, info);
946 return 4;
948 else
950 info->bytes_per_chunk = 2;
951 info->bytes_per_line = 4;
953 given &= 0xffff;
955 for (; *c; c++)
957 if (*c == '%')
959 int domaskpc = 0;
960 int domasklr = 0;
962 switch (*++c)
964 case '%':
965 func (stream, "%%");
966 break;
968 case 'S':
970 long reg;
972 reg = (given >> 3) & 0x7;
973 if (given & (1 << 6))
974 reg += 8;
976 func (stream, "%s", arm_regnames[reg]);
978 break;
980 case 'D':
982 long reg;
984 reg = given & 0x7;
985 if (given & (1 << 7))
986 reg += 8;
988 func (stream, "%s", arm_regnames[reg]);
990 break;
992 case 'T':
993 func (stream, "%s",
994 arm_conditional [(given >> 8) & 0xf]);
995 break;
997 case 'N':
998 if (given & (1 << 8))
999 domasklr = 1;
1000 /* Fall through. */
1001 case 'O':
1002 if (*c == 'O' && (given & (1 << 8)))
1003 domaskpc = 1;
1004 /* Fall through. */
1005 case 'M':
1007 int started = 0;
1008 int reg;
1010 func (stream, "{");
1012 /* It would be nice if we could spot
1013 ranges, and generate the rS-rE format: */
1014 for (reg = 0; (reg < 8); reg++)
1015 if ((given & (1 << reg)) != 0)
1017 if (started)
1018 func (stream, ", ");
1019 started = 1;
1020 func (stream, "%s", arm_regnames[reg]);
1023 if (domasklr)
1025 if (started)
1026 func (stream, ", ");
1027 started = 1;
1028 func (stream, arm_regnames[14] /* "lr" */);
1031 if (domaskpc)
1033 if (started)
1034 func (stream, ", ");
1035 func (stream, arm_regnames[15] /* "pc" */);
1038 func (stream, "}");
1040 break;
1043 case '0': case '1': case '2': case '3': case '4':
1044 case '5': case '6': case '7': case '8': case '9':
1046 int bitstart = *c++ - '0';
1047 int bitend = 0;
1049 while (*c >= '0' && *c <= '9')
1050 bitstart = (bitstart * 10) + *c++ - '0';
1052 switch (*c)
1054 case '-':
1056 long reg;
1058 c++;
1059 while (*c >= '0' && *c <= '9')
1060 bitend = (bitend * 10) + *c++ - '0';
1061 if (!bitend)
1062 abort ();
1063 reg = given >> bitstart;
1064 reg &= (2 << (bitend - bitstart)) - 1;
1065 switch (*c)
1067 case 'r':
1068 func (stream, "%s", arm_regnames[reg]);
1069 break;
1071 case 'd':
1072 func (stream, "%d", reg);
1073 break;
1075 case 'H':
1076 func (stream, "%d", reg << 1);
1077 break;
1079 case 'W':
1080 func (stream, "%d", reg << 2);
1081 break;
1083 case 'a':
1084 /* PC-relative address -- the bottom two
1085 bits of the address are dropped
1086 before the calculation. */
1087 info->print_address_func
1088 (((pc + 4) & ~3) + (reg << 2), info);
1089 break;
1091 case 'x':
1092 func (stream, "0x%04x", reg);
1093 break;
1095 case 'I':
1096 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1097 func (stream, "%d", reg);
1098 break;
1100 case 'B':
1101 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1102 (*info->print_address_func)
1103 (reg * 2 + pc + 4, info);
1104 break;
1106 default:
1107 abort ();
1110 break;
1112 case '\'':
1113 c++;
1114 if ((given & (1 << bitstart)) != 0)
1115 func (stream, "%c", *c);
1116 break;
1118 case '?':
1119 ++c;
1120 if ((given & (1 << bitstart)) != 0)
1121 func (stream, "%c", *c++);
1122 else
1123 func (stream, "%c", *++c);
1124 break;
1126 default:
1127 abort ();
1130 break;
1132 default:
1133 abort ();
1136 else
1137 func (stream, "%c", *c);
1140 return 2;
1144 /* No match. */
1145 abort ();
1148 /* Parse an individual disassembler option. */
1150 void
1151 parse_arm_disassembler_option (option)
1152 char * option;
1154 if (option == NULL)
1155 return;
1157 if (strneq (option, "reg-names-", 10))
1159 int i;
1161 option += 10;
1163 for (i = NUM_ARM_REGNAMES; i--;)
1164 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1166 regname_selected = i;
1167 break;
1170 if (i < 0)
1171 /* XXX - should break 'option' at following delimiter. */
1172 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1174 else if (strneq (option, "force-thumb", 11))
1175 force_thumb = 1;
1176 else if (strneq (option, "no-force-thumb", 14))
1177 force_thumb = 0;
1178 else
1179 /* XXX - should break 'option' at following delimiter. */
1180 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1182 return;
1185 /* Parse the string of disassembler options, spliting it at whitespaces
1186 or commas. (Whitespace separators supported for backwards compatibility). */
1188 static void
1189 parse_disassembler_options (options)
1190 char * options;
1192 if (options == NULL)
1193 return;
1195 while (*options)
1197 parse_arm_disassembler_option (options);
1199 /* Skip forward to next seperator. */
1200 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1201 ++ options;
1202 /* Skip forward past seperators. */
1203 while (ISSPACE (*options) || (*options == ','))
1204 ++ options;
1208 /* NOTE: There are no checks in these routines that
1209 the relevant number of data bytes exist. */
1211 static int
1212 print_insn (pc, info, little)
1213 bfd_vma pc;
1214 struct disassemble_info * info;
1215 bfd_boolean little;
1217 unsigned char b[4];
1218 long given;
1219 int status;
1220 int is_thumb;
1222 if (info->disassembler_options)
1224 parse_disassembler_options (info->disassembler_options);
1226 /* To avoid repeated parsing of these options, we remove them here. */
1227 info->disassembler_options = NULL;
1230 is_thumb = force_thumb;
1232 if (!is_thumb && info->symbols != NULL)
1234 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1236 coff_symbol_type * cs;
1238 cs = coffsymbol (*info->symbols);
1239 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1240 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1241 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1242 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1243 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1245 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1247 elf_symbol_type * es;
1248 unsigned int type;
1250 es = *(elf_symbol_type **)(info->symbols);
1251 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1253 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1257 info->bytes_per_chunk = 4;
1258 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1260 if (little)
1262 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1263 if (status != 0 && is_thumb)
1265 info->bytes_per_chunk = 2;
1267 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1268 b[3] = b[2] = 0;
1271 if (status != 0)
1273 info->memory_error_func (status, pc, info);
1274 return -1;
1277 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1279 else
1281 status = info->read_memory_func
1282 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1283 if (status != 0)
1285 info->memory_error_func (status, pc, info);
1286 return -1;
1289 if (is_thumb)
1291 if (pc & 0x2)
1293 given = (b[2] << 8) | b[3];
1295 status = info->read_memory_func
1296 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1297 if (status != 0)
1299 info->memory_error_func (status, pc + 4, info);
1300 return -1;
1303 given |= (b[0] << 24) | (b[1] << 16);
1305 else
1306 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1308 else
1309 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1312 if (info->flags & INSN_HAS_RELOC)
1313 /* If the instruction has a reloc associated with it, then
1314 the offset field in the instruction will actually be the
1315 addend for the reloc. (We are using REL type relocs).
1316 In such cases, we can ignore the pc when computing
1317 addresses, since the addend is not currently pc-relative. */
1318 pc = 0;
1320 if (is_thumb)
1321 status = print_insn_thumb (pc, info, given);
1322 else
1323 status = print_insn_arm (pc, info, given);
1325 return status;
1329 print_insn_big_arm (pc, info)
1330 bfd_vma pc;
1331 struct disassemble_info * info;
1333 return print_insn (pc, info, FALSE);
1337 print_insn_little_arm (pc, info)
1338 bfd_vma pc;
1339 struct disassemble_info * info;
1341 return print_insn (pc, info, TRUE);
1344 void
1345 print_arm_disassembler_options (FILE * stream)
1347 int i;
1349 fprintf (stream, _("\n\
1350 The following ARM specific disassembler options are supported for use with\n\
1351 the -M switch:\n"));
1353 for (i = NUM_ARM_REGNAMES; i--;)
1354 fprintf (stream, " reg-names-%s %*c%s\n",
1355 regnames[i].name,
1356 (int)(14 - strlen (regnames[i].name)), ' ',
1357 regnames[i].description);
1359 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
1360 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");