Tidy up code. Switch to ISO C
[binutils.git] / opcodes / arm-dis.c
blob97ec8423485fd32767efdbea30aad4504f5f2a34
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]);
448 if ((given & 0x01000000) != 0)
450 int offset = given & 0xff;
451 if (offset)
452 func (stream, ", %s#%d]%s",
453 ((given & 0x00800000) == 0 ? "-" : ""),
454 offset * 4,
455 ((given & 0x00200000) != 0 ? "!" : ""));
456 else
457 func (stream, "]");
459 else
461 int offset = given & 0xff;
462 if (offset)
463 func (stream, "], %s#%d",
464 ((given & 0x00800000) == 0 ? "-" : ""),
465 offset * 4);
466 else
467 func (stream, "]");
469 break;
471 case 'B':
472 /* Print ARM V5 BLX(1) address: pc+25 bits. */
474 bfd_vma address;
475 bfd_vma offset = 0;
477 if (given & 0x00800000)
478 /* Is signed, hi bits should be ones. */
479 offset = (-1) ^ 0x00ffffff;
481 /* Offset is (SignExtend(offset field)<<2). */
482 offset += given & 0x00ffffff;
483 offset <<= 2;
484 address = offset + pc + 8;
486 if (given & 0x01000000)
487 /* H bit allows addressing to 2-byte boundaries. */
488 address += 2;
490 info->print_address_func (address, info);
492 break;
494 case 'I':
495 /* Print a Cirrus/DSP shift immediate. */
496 /* Immediates are 7bit signed ints with bits 0..3 in
497 bits 0..3 of opcode and bits 4..6 in bits 5..7
498 of opcode. */
500 int imm;
502 imm = (given & 0xf) | ((given & 0xe0) >> 1);
504 /* Is ``imm'' a negative number? */
505 if (imm & 0x40)
506 imm |= (-1 << 7);
508 func (stream, "%d", imm);
511 break;
513 case 'C':
514 func (stream, "_");
515 if (given & 0x80000)
516 func (stream, "f");
517 if (given & 0x40000)
518 func (stream, "s");
519 if (given & 0x20000)
520 func (stream, "x");
521 if (given & 0x10000)
522 func (stream, "c");
523 break;
525 case 'F':
526 switch (given & 0x00408000)
528 case 0:
529 func (stream, "4");
530 break;
531 case 0x8000:
532 func (stream, "1");
533 break;
534 case 0x00400000:
535 func (stream, "2");
536 break;
537 default:
538 func (stream, "3");
540 break;
542 case 'P':
543 switch (given & 0x00080080)
545 case 0:
546 func (stream, "s");
547 break;
548 case 0x80:
549 func (stream, "d");
550 break;
551 case 0x00080000:
552 func (stream, "e");
553 break;
554 default:
555 func (stream, _("<illegal precision>"));
556 break;
558 break;
559 case 'Q':
560 switch (given & 0x00408000)
562 case 0:
563 func (stream, "s");
564 break;
565 case 0x8000:
566 func (stream, "d");
567 break;
568 case 0x00400000:
569 func (stream, "e");
570 break;
571 default:
572 func (stream, "p");
573 break;
575 break;
576 case 'R':
577 switch (given & 0x60)
579 case 0:
580 break;
581 case 0x20:
582 func (stream, "p");
583 break;
584 case 0x40:
585 func (stream, "m");
586 break;
587 default:
588 func (stream, "z");
589 break;
591 break;
593 case '0': case '1': case '2': case '3': case '4':
594 case '5': case '6': case '7': case '8': case '9':
596 int bitstart = *c++ - '0';
597 int bitend = 0;
598 while (*c >= '0' && *c <= '9')
599 bitstart = (bitstart * 10) + *c++ - '0';
601 switch (*c)
603 case '-':
604 c++;
606 while (*c >= '0' && *c <= '9')
607 bitend = (bitend * 10) + *c++ - '0';
609 if (!bitend)
610 abort ();
612 switch (*c)
614 case 'r':
616 long reg;
618 reg = given >> bitstart;
619 reg &= (2 << (bitend - bitstart)) - 1;
621 func (stream, "%s", arm_regnames[reg]);
623 break;
624 case 'd':
626 long reg;
628 reg = given >> bitstart;
629 reg &= (2 << (bitend - bitstart)) - 1;
631 func (stream, "%d", reg);
633 break;
634 case 'x':
636 long reg;
638 reg = given >> bitstart;
639 reg &= (2 << (bitend - bitstart)) - 1;
641 func (stream, "0x%08x", reg);
643 /* Some SWI instructions have special
644 meanings. */
645 if ((given & 0x0fffffff) == 0x0FF00000)
646 func (stream, "\t; IMB");
647 else if ((given & 0x0fffffff) == 0x0FF00001)
648 func (stream, "\t; IMBRange");
650 break;
651 case 'X':
653 long reg;
655 reg = given >> bitstart;
656 reg &= (2 << (bitend - bitstart)) - 1;
658 func (stream, "%01x", reg & 0xf);
660 break;
661 case 'f':
663 long reg;
665 reg = given >> bitstart;
666 reg &= (2 << (bitend - bitstart)) - 1;
668 if (reg > 7)
669 func (stream, "#%s",
670 arm_fp_const[reg & 7]);
671 else
672 func (stream, "f%d", reg);
674 break;
676 case 'w':
678 long reg;
680 if (bitstart != bitend)
682 reg = given >> bitstart;
683 reg &= (2 << (bitend - bitstart)) - 1;
684 if (bitend - bitstart == 1)
685 func (stream, "%s", iwmmxt_wwnames[reg]);
686 else
687 func (stream, "%s", iwmmxt_wwssnames[reg]);
689 else
691 reg = (((given >> 8) & 0x1) |
692 ((given >> 22) & 0x1));
693 func (stream, "%s", iwmmxt_wwnames[reg]);
696 break;
698 case 'g':
700 long reg;
701 int current_regnames;
703 if (! iwmmxt_regnames)
704 iwmmxt_regnames = set_iwmmxt_regnames ();
705 current_regnames = set_arm_regname_option
706 (iwmmxt_regnames);
708 reg = given >> bitstart;
709 reg &= (2 << (bitend - bitstart)) - 1;
710 func (stream, "%s", arm_regnames[reg]);
711 set_arm_regname_option (current_regnames);
713 break;
715 case 'G':
717 long reg;
718 int current_regnames;
720 if (! iwmmxt_regnames)
721 iwmmxt_regnames = set_iwmmxt_regnames ();
722 current_regnames = set_arm_regname_option
723 (iwmmxt_regnames + 1);
725 reg = given >> bitstart;
726 reg &= (2 << (bitend - bitstart)) - 1;
727 func (stream, "%s", arm_regnames[reg]);
728 set_arm_regname_option (current_regnames);
730 break;
732 default:
733 abort ();
735 break;
737 case 'y':
738 case 'z':
740 int single = *c == 'y';
741 int regno;
743 switch (bitstart)
745 case 4: /* Sm pair */
746 func (stream, "{");
747 /* Fall through. */
748 case 0: /* Sm, Dm */
749 regno = given & 0x0000000f;
750 if (single)
752 regno <<= 1;
753 regno += (given >> 5) & 1;
755 break;
757 case 1: /* Sd, Dd */
758 regno = (given >> 12) & 0x0000000f;
759 if (single)
761 regno <<= 1;
762 regno += (given >> 22) & 1;
764 break;
766 case 2: /* Sn, Dn */
767 regno = (given >> 16) & 0x0000000f;
768 if (single)
770 regno <<= 1;
771 regno += (given >> 7) & 1;
773 break;
775 case 3: /* List */
776 func (stream, "{");
777 regno = (given >> 12) & 0x0000000f;
778 if (single)
780 regno <<= 1;
781 regno += (given >> 22) & 1;
783 break;
786 default:
787 abort ();
790 func (stream, "%c%d", single ? 's' : 'd', regno);
792 if (bitstart == 3)
794 int count = given & 0xff;
796 if (single == 0)
797 count >>= 1;
799 if (--count)
801 func (stream, "-%c%d",
802 single ? 's' : 'd',
803 regno + count);
806 func (stream, "}");
808 else if (bitstart == 4)
809 func (stream, ", %c%d}", single ? 's' : 'd',
810 regno + 1);
812 break;
815 case '`':
816 c++;
817 if ((given & (1 << bitstart)) == 0)
818 func (stream, "%c", *c);
819 break;
820 case '\'':
821 c++;
822 if ((given & (1 << bitstart)) != 0)
823 func (stream, "%c", *c);
824 break;
825 case '?':
826 ++c;
827 if ((given & (1 << bitstart)) != 0)
828 func (stream, "%c", *c++);
829 else
830 func (stream, "%c", *++c);
831 break;
832 default:
833 abort ();
835 break;
837 case 'L':
838 switch (given & 0x00400100)
840 case 0x00000000: func (stream, "b"); break;
841 case 0x00400000: func (stream, "h"); break;
842 case 0x00000100: func (stream, "w"); break;
843 case 0x00400100: func (stream, "d"); break;
844 default:
845 break;
847 break;
849 case 'Z':
851 int value;
852 /* given (20, 23) | given (0, 3) */
853 value = ((given >> 16) & 0xf0) | (given & 0xf);
854 func (stream, "%d", value);
856 break;
858 case 'l':
859 /* This is like the 'A' operator, except that if
860 the width field "M" is zero, then the offset is
861 *not* multiplied by four. */
863 int offset = given & 0xff;
864 int multiplier = (given & 0x00000100) ? 4 : 1;
866 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
868 if (offset)
870 if ((given & 0x01000000) != 0)
871 func (stream, ", %s#%d]%s",
872 ((given & 0x00800000) == 0 ? "-" : ""),
873 offset * multiplier,
874 ((given & 0x00200000) != 0 ? "!" : ""));
875 else
876 func (stream, "], %s#%d",
877 ((given & 0x00800000) == 0 ? "-" : ""),
878 offset * multiplier);
880 else
881 func (stream, "]");
883 break;
885 default:
886 abort ();
890 else
891 func (stream, "%c", *c);
893 return 4;
896 abort ();
899 /* Print one instruction from PC on INFO->STREAM.
900 Return the size of the instruction. */
902 static int
903 print_insn_thumb (pc, info, given)
904 bfd_vma pc;
905 struct disassemble_info *info;
906 long given;
908 const struct thumb_opcode *insn;
909 void *stream = info->stream;
910 fprintf_ftype func = info->fprintf_func;
912 for (insn = thumb_opcodes; insn->assembler; insn++)
914 if ((given & insn->mask) == insn->value)
916 char * c = insn->assembler;
918 /* Special processing for Thumb 2 instruction BL sequence: */
919 if (!*c) /* Check for empty (not NULL) assembler string. */
921 long offset;
923 info->bytes_per_chunk = 4;
924 info->bytes_per_line = 4;
926 offset = BDISP23 (given);
927 offset = offset * 2 + pc + 4;
929 if ((given & 0x10000000) == 0)
931 func (stream, "blx\t");
932 offset &= 0xfffffffc;
934 else
935 func (stream, "bl\t");
937 info->print_address_func (offset, info);
938 return 4;
940 else
942 info->bytes_per_chunk = 2;
943 info->bytes_per_line = 4;
945 given &= 0xffff;
947 for (; *c; c++)
949 if (*c == '%')
951 int domaskpc = 0;
952 int domasklr = 0;
954 switch (*++c)
956 case '%':
957 func (stream, "%%");
958 break;
960 case 'S':
962 long reg;
964 reg = (given >> 3) & 0x7;
965 if (given & (1 << 6))
966 reg += 8;
968 func (stream, "%s", arm_regnames[reg]);
970 break;
972 case 'D':
974 long reg;
976 reg = given & 0x7;
977 if (given & (1 << 7))
978 reg += 8;
980 func (stream, "%s", arm_regnames[reg]);
982 break;
984 case 'T':
985 func (stream, "%s",
986 arm_conditional [(given >> 8) & 0xf]);
987 break;
989 case 'N':
990 if (given & (1 << 8))
991 domasklr = 1;
992 /* Fall through. */
993 case 'O':
994 if (*c == 'O' && (given & (1 << 8)))
995 domaskpc = 1;
996 /* Fall through. */
997 case 'M':
999 int started = 0;
1000 int reg;
1002 func (stream, "{");
1004 /* It would be nice if we could spot
1005 ranges, and generate the rS-rE format: */
1006 for (reg = 0; (reg < 8); reg++)
1007 if ((given & (1 << reg)) != 0)
1009 if (started)
1010 func (stream, ", ");
1011 started = 1;
1012 func (stream, "%s", arm_regnames[reg]);
1015 if (domasklr)
1017 if (started)
1018 func (stream, ", ");
1019 started = 1;
1020 func (stream, arm_regnames[14] /* "lr" */);
1023 if (domaskpc)
1025 if (started)
1026 func (stream, ", ");
1027 func (stream, arm_regnames[15] /* "pc" */);
1030 func (stream, "}");
1032 break;
1035 case '0': case '1': case '2': case '3': case '4':
1036 case '5': case '6': case '7': case '8': case '9':
1038 int bitstart = *c++ - '0';
1039 int bitend = 0;
1041 while (*c >= '0' && *c <= '9')
1042 bitstart = (bitstart * 10) + *c++ - '0';
1044 switch (*c)
1046 case '-':
1048 long reg;
1050 c++;
1051 while (*c >= '0' && *c <= '9')
1052 bitend = (bitend * 10) + *c++ - '0';
1053 if (!bitend)
1054 abort ();
1055 reg = given >> bitstart;
1056 reg &= (2 << (bitend - bitstart)) - 1;
1057 switch (*c)
1059 case 'r':
1060 func (stream, "%s", arm_regnames[reg]);
1061 break;
1063 case 'd':
1064 func (stream, "%d", reg);
1065 break;
1067 case 'H':
1068 func (stream, "%d", reg << 1);
1069 break;
1071 case 'W':
1072 func (stream, "%d", reg << 2);
1073 break;
1075 case 'a':
1076 /* PC-relative address -- the bottom two
1077 bits of the address are dropped
1078 before the calculation. */
1079 info->print_address_func
1080 (((pc + 4) & ~3) + (reg << 2), info);
1081 break;
1083 case 'x':
1084 func (stream, "0x%04x", reg);
1085 break;
1087 case 'I':
1088 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1089 func (stream, "%d", reg);
1090 break;
1092 case 'B':
1093 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1094 (*info->print_address_func)
1095 (reg * 2 + pc + 4, info);
1096 break;
1098 default:
1099 abort ();
1102 break;
1104 case '\'':
1105 c++;
1106 if ((given & (1 << bitstart)) != 0)
1107 func (stream, "%c", *c);
1108 break;
1110 case '?':
1111 ++c;
1112 if ((given & (1 << bitstart)) != 0)
1113 func (stream, "%c", *c++);
1114 else
1115 func (stream, "%c", *++c);
1116 break;
1118 default:
1119 abort ();
1122 break;
1124 default:
1125 abort ();
1128 else
1129 func (stream, "%c", *c);
1132 return 2;
1136 /* No match. */
1137 abort ();
1140 /* Parse an individual disassembler option. */
1142 void
1143 parse_arm_disassembler_option (option)
1144 char * option;
1146 if (option == NULL)
1147 return;
1149 if (strneq (option, "reg-names-", 10))
1151 int i;
1153 option += 10;
1155 for (i = NUM_ARM_REGNAMES; i--;)
1156 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1158 regname_selected = i;
1159 break;
1162 if (i < 0)
1163 /* XXX - should break 'option' at following delimiter. */
1164 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1166 else if (strneq (option, "force-thumb", 11))
1167 force_thumb = 1;
1168 else if (strneq (option, "no-force-thumb", 14))
1169 force_thumb = 0;
1170 else
1171 /* XXX - should break 'option' at following delimiter. */
1172 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1174 return;
1177 /* Parse the string of disassembler options, spliting it at whitespaces
1178 or commas. (Whitespace separators supported for backwards compatibility). */
1180 static void
1181 parse_disassembler_options (options)
1182 char * options;
1184 if (options == NULL)
1185 return;
1187 while (*options)
1189 parse_arm_disassembler_option (options);
1191 /* Skip forward to next seperator. */
1192 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1193 ++ options;
1194 /* Skip forward past seperators. */
1195 while (ISSPACE (*options) || (*options == ','))
1196 ++ options;
1200 /* NOTE: There are no checks in these routines that
1201 the relevant number of data bytes exist. */
1203 static int
1204 print_insn (pc, info, little)
1205 bfd_vma pc;
1206 struct disassemble_info * info;
1207 bfd_boolean little;
1209 unsigned char b[4];
1210 long given;
1211 int status;
1212 int is_thumb;
1214 if (info->disassembler_options)
1216 parse_disassembler_options (info->disassembler_options);
1218 /* To avoid repeated parsing of these options, we remove them here. */
1219 info->disassembler_options = NULL;
1222 is_thumb = force_thumb;
1224 if (!is_thumb && info->symbols != NULL)
1226 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1228 coff_symbol_type * cs;
1230 cs = coffsymbol (*info->symbols);
1231 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1232 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1233 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1234 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1235 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1237 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1239 elf_symbol_type * es;
1240 unsigned int type;
1242 es = *(elf_symbol_type **)(info->symbols);
1243 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1245 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1249 info->bytes_per_chunk = 4;
1250 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1252 if (little)
1254 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1255 if (status != 0 && is_thumb)
1257 info->bytes_per_chunk = 2;
1259 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1260 b[3] = b[2] = 0;
1263 if (status != 0)
1265 info->memory_error_func (status, pc, info);
1266 return -1;
1269 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1271 else
1273 status = info->read_memory_func
1274 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1275 if (status != 0)
1277 info->memory_error_func (status, pc, info);
1278 return -1;
1281 if (is_thumb)
1283 if (pc & 0x2)
1285 given = (b[2] << 8) | b[3];
1287 status = info->read_memory_func
1288 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1289 if (status != 0)
1291 info->memory_error_func (status, pc + 4, info);
1292 return -1;
1295 given |= (b[0] << 24) | (b[1] << 16);
1297 else
1298 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1300 else
1301 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1304 if (info->flags & INSN_HAS_RELOC)
1305 /* If the instruction has a reloc associated with it, then
1306 the offset field in the instruction will actually be the
1307 addend for the reloc. (We are using REL type relocs).
1308 In such cases, we can ignore the pc when computing
1309 addresses, since the addend is not currently pc-relative. */
1310 pc = 0;
1312 if (is_thumb)
1313 status = print_insn_thumb (pc, info, given);
1314 else
1315 status = print_insn_arm (pc, info, given);
1317 return status;
1321 print_insn_big_arm (pc, info)
1322 bfd_vma pc;
1323 struct disassemble_info * info;
1325 return print_insn (pc, info, FALSE);
1329 print_insn_little_arm (pc, info)
1330 bfd_vma pc;
1331 struct disassemble_info * info;
1333 return print_insn (pc, info, TRUE);
1336 void
1337 print_arm_disassembler_options (FILE * stream)
1339 int i;
1341 fprintf (stream, _("\n\
1342 The following ARM specific disassembler options are supported for use with\n\
1343 the -M switch:\n"));
1345 for (i = NUM_ARM_REGNAMES; i--;)
1346 fprintf (stream, " reg-names-%s %*c%s\n",
1347 regnames[i].name,
1348 (int)(14 - strlen (regnames[i].name)), ' ',
1349 regnames[i].description);
1351 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
1352 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");