* configure.in: Add ${libgcj} to noconfigdirs for xtensa-*-* targets.
[binutils.git] / opcodes / arm-dis.c
blob2c9e385707ab5a19d0dc222ffa012e0cd5ac56b4
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"
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" }},
74 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
75 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
76 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
77 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
80 static char * iwmmxt_wwnames[] =
81 {"b", "h", "w", "d"};
83 static char * iwmmxt_wwssnames[] =
84 {"b", "bus", "b", "bss",
85 "h", "hus", "h", "hss",
86 "w", "wus", "w", "wss",
87 "d", "dus", "d", "dss"
90 /* Default to GCC register name set. */
91 static unsigned int regname_selected = 1;
93 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
94 #define arm_regnames regnames[regname_selected].reg_names
96 static bfd_boolean force_thumb = FALSE;
98 static char * arm_fp_const[] =
99 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
101 static char * arm_shift[] =
102 {"lsl", "lsr", "asr", "ror"};
104 /* Forward declarations. */
105 static void arm_decode_shift
106 PARAMS ((long, fprintf_ftype, void *));
107 static int print_insn_arm
108 PARAMS ((bfd_vma, struct disassemble_info *, long));
109 static int print_insn_thumb
110 PARAMS ((bfd_vma, struct disassemble_info *, long));
111 static void parse_disassembler_options
112 PARAMS ((char *));
113 static int print_insn
114 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
115 static int set_iwmmxt_regnames
116 PARAMS ((void));
118 int get_arm_regname_num_options
119 PARAMS ((void));
120 int set_arm_regname_option
121 PARAMS ((int));
122 int get_arm_regnames
123 PARAMS ((int, const char **, const char **, const char ***));
125 /* Functions. */
127 get_arm_regname_num_options ()
129 return NUM_ARM_REGNAMES;
133 set_arm_regname_option (option)
134 int option;
136 int old = regname_selected;
137 regname_selected = option;
138 return old;
142 get_arm_regnames (option, setname, setdescription, register_names)
143 int option;
144 const char **setname;
145 const char **setdescription;
146 const char ***register_names;
148 *setname = regnames[option].name;
149 *setdescription = regnames[option].description;
150 *register_names = regnames[option].reg_names;
151 return 16;
154 static void
155 arm_decode_shift (given, func, stream)
156 long given;
157 fprintf_ftype func;
158 void * stream;
160 func (stream, "%s", arm_regnames[given & 0xf]);
162 if ((given & 0xff0) != 0)
164 if ((given & 0x10) == 0)
166 int amount = (given & 0xf80) >> 7;
167 int shift = (given & 0x60) >> 5;
169 if (amount == 0)
171 if (shift == 3)
173 func (stream, ", rrx");
174 return;
177 amount = 32;
180 func (stream, ", %s #%d", arm_shift[shift], amount);
182 else
183 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
184 arm_regnames[(given & 0xf00) >> 8]);
188 static int
189 set_iwmmxt_regnames ()
191 const char * setname;
192 const char * setdesc;
193 const char ** regnames;
194 int iwmmxt_regnames = 0;
195 int num_regnames = get_arm_regname_num_options ();
197 get_arm_regnames (iwmmxt_regnames, &setname,
198 &setdesc, &regnames);
199 while ((strcmp ("iwmmxt_regnames", setname))
200 && (iwmmxt_regnames < num_regnames))
201 get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
203 return iwmmxt_regnames;
206 /* Print one instruction from PC on INFO->STREAM.
207 Return the size of the instruction (always 4 on ARM). */
209 static int
210 print_insn_arm (pc, info, given)
211 bfd_vma pc;
212 struct disassemble_info *info;
213 long given;
215 const struct arm_opcode *insn;
216 void *stream = info->stream;
217 fprintf_ftype func = info->fprintf_func;
218 static int iwmmxt_regnames = 0;
220 for (insn = arm_opcodes; insn->assembler; insn++)
222 if (insn->value == FIRST_IWMMXT_INSN
223 && info->mach != bfd_mach_arm_XScale
224 && info->mach != bfd_mach_arm_iWMMXt)
225 insn = insn + IWMMXT_INSN_COUNT;
227 if ((given & insn->mask) == insn->value)
229 char * c;
231 for (c = insn->assembler; *c; c++)
233 if (*c == '%')
235 switch (*++c)
237 case '%':
238 func (stream, "%%");
239 break;
241 case 'a':
242 if (((given & 0x000f0000) == 0x000f0000)
243 && ((given & 0x02000000) == 0))
245 int offset = given & 0xfff;
247 func (stream, "[pc");
249 if (given & 0x01000000)
251 if ((given & 0x00800000) == 0)
252 offset = - offset;
254 /* Pre-indexed. */
255 func (stream, ", #%d]", offset);
257 offset += pc + 8;
259 /* Cope with the possibility of write-back
260 being used. Probably a very dangerous thing
261 for the programmer to do, but who are we to
262 argue ? */
263 if (given & 0x00200000)
264 func (stream, "!");
266 else
268 /* Post indexed. */
269 func (stream, "], #%d", offset);
271 /* ie ignore the offset. */
272 offset = pc + 8;
275 func (stream, "\t; ");
276 info->print_address_func (offset, info);
278 else
280 func (stream, "[%s",
281 arm_regnames[(given >> 16) & 0xf]);
282 if ((given & 0x01000000) != 0)
284 if ((given & 0x02000000) == 0)
286 int offset = given & 0xfff;
287 if (offset)
288 func (stream, ", %s#%d",
289 (((given & 0x00800000) == 0)
290 ? "-" : ""), offset);
292 else
294 func (stream, ", %s",
295 (((given & 0x00800000) == 0)
296 ? "-" : ""));
297 arm_decode_shift (given, func, stream);
300 func (stream, "]%s",
301 ((given & 0x00200000) != 0) ? "!" : "");
303 else
305 if ((given & 0x02000000) == 0)
307 int offset = given & 0xfff;
308 if (offset)
309 func (stream, "], %s#%d",
310 (((given & 0x00800000) == 0)
311 ? "-" : ""), offset);
312 else
313 func (stream, "]");
315 else
317 func (stream, "], %s",
318 (((given & 0x00800000) == 0)
319 ? "-" : ""));
320 arm_decode_shift (given, func, stream);
324 break;
326 case 's':
327 if ((given & 0x004f0000) == 0x004f0000)
329 /* PC relative with immediate offset. */
330 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
332 if ((given & 0x00800000) == 0)
333 offset = -offset;
335 func (stream, "[pc, #%d]\t; ", offset);
337 (*info->print_address_func)
338 (offset + pc + 8, info);
340 else
342 func (stream, "[%s",
343 arm_regnames[(given >> 16) & 0xf]);
344 if ((given & 0x01000000) != 0)
346 /* Pre-indexed. */
347 if ((given & 0x00400000) == 0x00400000)
349 /* Immediate. */
350 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
351 if (offset)
352 func (stream, ", %s#%d",
353 (((given & 0x00800000) == 0)
354 ? "-" : ""), offset);
356 else
358 /* Register. */
359 func (stream, ", %s%s",
360 (((given & 0x00800000) == 0)
361 ? "-" : ""),
362 arm_regnames[given & 0xf]);
365 func (stream, "]%s",
366 ((given & 0x00200000) != 0) ? "!" : "");
368 else
370 /* Post-indexed. */
371 if ((given & 0x00400000) == 0x00400000)
373 /* Immediate. */
374 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
375 if (offset)
376 func (stream, "], %s#%d",
377 (((given & 0x00800000) == 0)
378 ? "-" : ""), offset);
379 else
380 func (stream, "]");
382 else
384 /* Register. */
385 func (stream, "], %s%s",
386 (((given & 0x00800000) == 0)
387 ? "-" : ""),
388 arm_regnames[given & 0xf]);
392 break;
394 case 'b':
395 (*info->print_address_func)
396 (BDISP (given) * 4 + pc + 8, info);
397 break;
399 case 'c':
400 func (stream, "%s",
401 arm_conditional [(given >> 28) & 0xf]);
402 break;
404 case 'm':
406 int started = 0;
407 int reg;
409 func (stream, "{");
410 for (reg = 0; reg < 16; reg++)
411 if ((given & (1 << reg)) != 0)
413 if (started)
414 func (stream, ", ");
415 started = 1;
416 func (stream, "%s", arm_regnames[reg]);
418 func (stream, "}");
420 break;
422 case 'o':
423 if ((given & 0x02000000) != 0)
425 int rotate = (given & 0xf00) >> 7;
426 int immed = (given & 0xff);
427 immed = (((immed << (32 - rotate))
428 | (immed >> rotate)) & 0xffffffff);
429 func (stream, "#%d\t; 0x%x", immed, immed);
431 else
432 arm_decode_shift (given, func, stream);
433 break;
435 case 'p':
436 if ((given & 0x0000f000) == 0x0000f000)
437 func (stream, "p");
438 break;
440 case 't':
441 if ((given & 0x01200000) == 0x00200000)
442 func (stream, "t");
443 break;
445 case 'A':
446 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
447 if ((given & 0x01000000) != 0)
449 int offset = given & 0xff;
450 if (offset)
451 func (stream, ", %s#%d]%s",
452 ((given & 0x00800000) == 0 ? "-" : ""),
453 offset * 4,
454 ((given & 0x00200000) != 0 ? "!" : ""));
455 else
456 func (stream, "]");
458 else
460 int offset = given & 0xff;
461 if (offset)
462 func (stream, "], %s#%d",
463 ((given & 0x00800000) == 0 ? "-" : ""),
464 offset * 4);
465 else
466 func (stream, "]");
468 break;
470 case 'B':
471 /* Print ARM V5 BLX(1) address: pc+25 bits. */
473 bfd_vma address;
474 bfd_vma offset = 0;
476 if (given & 0x00800000)
477 /* Is signed, hi bits should be ones. */
478 offset = (-1) ^ 0x00ffffff;
480 /* Offset is (SignExtend(offset field)<<2). */
481 offset += given & 0x00ffffff;
482 offset <<= 2;
483 address = offset + pc + 8;
485 if (given & 0x01000000)
486 /* H bit allows addressing to 2-byte boundaries. */
487 address += 2;
489 info->print_address_func (address, info);
491 break;
493 case 'I':
494 /* Print a Cirrus/DSP shift immediate. */
495 /* Immediates are 7bit signed ints with bits 0..3 in
496 bits 0..3 of opcode and bits 4..6 in bits 5..7
497 of opcode. */
499 int imm;
501 imm = (given & 0xf) | ((given & 0xe0) >> 1);
503 /* Is ``imm'' a negative number? */
504 if (imm & 0x40)
505 imm |= (-1 << 7);
507 func (stream, "%d", imm);
510 break;
512 case 'C':
513 func (stream, "_");
514 if (given & 0x80000)
515 func (stream, "f");
516 if (given & 0x40000)
517 func (stream, "s");
518 if (given & 0x20000)
519 func (stream, "x");
520 if (given & 0x10000)
521 func (stream, "c");
522 break;
524 case 'F':
525 switch (given & 0x00408000)
527 case 0:
528 func (stream, "4");
529 break;
530 case 0x8000:
531 func (stream, "1");
532 break;
533 case 0x00400000:
534 func (stream, "2");
535 break;
536 default:
537 func (stream, "3");
539 break;
541 case 'P':
542 switch (given & 0x00080080)
544 case 0:
545 func (stream, "s");
546 break;
547 case 0x80:
548 func (stream, "d");
549 break;
550 case 0x00080000:
551 func (stream, "e");
552 break;
553 default:
554 func (stream, _("<illegal precision>"));
555 break;
557 break;
558 case 'Q':
559 switch (given & 0x00408000)
561 case 0:
562 func (stream, "s");
563 break;
564 case 0x8000:
565 func (stream, "d");
566 break;
567 case 0x00400000:
568 func (stream, "e");
569 break;
570 default:
571 func (stream, "p");
572 break;
574 break;
575 case 'R':
576 switch (given & 0x60)
578 case 0:
579 break;
580 case 0x20:
581 func (stream, "p");
582 break;
583 case 0x40:
584 func (stream, "m");
585 break;
586 default:
587 func (stream, "z");
588 break;
590 break;
592 case '0': case '1': case '2': case '3': case '4':
593 case '5': case '6': case '7': case '8': case '9':
595 int bitstart = *c++ - '0';
596 int bitend = 0;
597 while (*c >= '0' && *c <= '9')
598 bitstart = (bitstart * 10) + *c++ - '0';
600 switch (*c)
602 case '-':
603 c++;
605 while (*c >= '0' && *c <= '9')
606 bitend = (bitend * 10) + *c++ - '0';
608 if (!bitend)
609 abort ();
611 switch (*c)
613 case 'r':
615 long reg;
617 reg = given >> bitstart;
618 reg &= (2 << (bitend - bitstart)) - 1;
620 func (stream, "%s", arm_regnames[reg]);
622 break;
623 case 'd':
625 long reg;
627 reg = given >> bitstart;
628 reg &= (2 << (bitend - bitstart)) - 1;
630 func (stream, "%d", reg);
632 break;
633 case 'x':
635 long reg;
637 reg = given >> bitstart;
638 reg &= (2 << (bitend - bitstart)) - 1;
640 func (stream, "0x%08x", reg);
642 /* Some SWI instructions have special
643 meanings. */
644 if ((given & 0x0fffffff) == 0x0FF00000)
645 func (stream, "\t; IMB");
646 else if ((given & 0x0fffffff) == 0x0FF00001)
647 func (stream, "\t; IMBRange");
649 break;
650 case 'X':
652 long reg;
654 reg = given >> bitstart;
655 reg &= (2 << (bitend - bitstart)) - 1;
657 func (stream, "%01x", reg & 0xf);
659 break;
660 case 'f':
662 long reg;
664 reg = given >> bitstart;
665 reg &= (2 << (bitend - bitstart)) - 1;
667 if (reg > 7)
668 func (stream, "#%s",
669 arm_fp_const[reg & 7]);
670 else
671 func (stream, "f%d", reg);
673 break;
675 case 'w':
677 long reg;
679 if (bitstart != bitend)
681 reg = given >> bitstart;
682 reg &= (2 << (bitend - bitstart)) - 1;
683 if (bitend - bitstart == 1)
684 func (stream, "%s", iwmmxt_wwnames[reg]);
685 else
686 func (stream, "%s", iwmmxt_wwssnames[reg]);
688 else
690 reg = (((given >> 8) & 0x1) |
691 ((given >> 22) & 0x1));
692 func (stream, "%s", iwmmxt_wwnames[reg]);
695 break;
697 case 'g':
699 long reg;
700 int current_regnames;
702 if (! iwmmxt_regnames)
703 iwmmxt_regnames = set_iwmmxt_regnames ();
704 current_regnames = set_arm_regname_option
705 (iwmmxt_regnames);
707 reg = given >> bitstart;
708 reg &= (2 << (bitend - bitstart)) - 1;
709 func (stream, "%s", arm_regnames[reg]);
710 set_arm_regname_option (current_regnames);
712 break;
714 case 'G':
716 long reg;
717 int current_regnames;
719 if (! iwmmxt_regnames)
720 iwmmxt_regnames = set_iwmmxt_regnames ();
721 current_regnames = set_arm_regname_option
722 (iwmmxt_regnames + 1);
724 reg = given >> bitstart;
725 reg &= (2 << (bitend - bitstart)) - 1;
726 func (stream, "%s", arm_regnames[reg]);
727 set_arm_regname_option (current_regnames);
729 break;
731 default:
732 abort ();
734 break;
736 case 'y':
737 case 'z':
739 int single = *c == 'y';
740 int regno;
742 switch (bitstart)
744 case 4: /* Sm pair */
745 func (stream, "{");
746 /* Fall through. */
747 case 0: /* Sm, Dm */
748 regno = given & 0x0000000f;
749 if (single)
751 regno <<= 1;
752 regno += (given >> 5) & 1;
754 break;
756 case 1: /* Sd, Dd */
757 regno = (given >> 12) & 0x0000000f;
758 if (single)
760 regno <<= 1;
761 regno += (given >> 22) & 1;
763 break;
765 case 2: /* Sn, Dn */
766 regno = (given >> 16) & 0x0000000f;
767 if (single)
769 regno <<= 1;
770 regno += (given >> 7) & 1;
772 break;
774 case 3: /* List */
775 func (stream, "{");
776 regno = (given >> 12) & 0x0000000f;
777 if (single)
779 regno <<= 1;
780 regno += (given >> 22) & 1;
782 break;
785 default:
786 abort ();
789 func (stream, "%c%d", single ? 's' : 'd', regno);
791 if (bitstart == 3)
793 int count = given & 0xff;
795 if (single == 0)
796 count >>= 1;
798 if (--count)
800 func (stream, "-%c%d",
801 single ? 's' : 'd',
802 regno + count);
805 func (stream, "}");
807 else if (bitstart == 4)
808 func (stream, ", %c%d}", single ? 's' : 'd',
809 regno + 1);
811 break;
814 case '`':
815 c++;
816 if ((given & (1 << bitstart)) == 0)
817 func (stream, "%c", *c);
818 break;
819 case '\'':
820 c++;
821 if ((given & (1 << bitstart)) != 0)
822 func (stream, "%c", *c);
823 break;
824 case '?':
825 ++c;
826 if ((given & (1 << bitstart)) != 0)
827 func (stream, "%c", *c++);
828 else
829 func (stream, "%c", *++c);
830 break;
831 default:
832 abort ();
834 break;
836 case 'L':
837 switch (given & 0x00400100)
839 case 0x00000000: func (stream, "b"); break;
840 case 0x00400000: func (stream, "h"); break;
841 case 0x00000100: func (stream, "w"); break;
842 case 0x00400100: func (stream, "d"); break;
843 default:
844 break;
846 break;
848 case 'Z':
850 int value;
851 /* given (20, 23) | given (0, 3) */
852 value = ((given >> 16) & 0xf0) | (given & 0xf);
853 func (stream, "%d", value);
855 break;
857 case 'l':
858 /* This is like the 'A' operator, except that if
859 the width field "M" is zero, then the offset is
860 *not* multiplied by four. */
862 int offset = given & 0xff;
863 int multiplier = (given & 0x00000100) ? 4 : 1;
865 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
867 if (offset)
869 if ((given & 0x01000000) != 0)
870 func (stream, ", %s#%d]%s",
871 ((given & 0x00800000) == 0 ? "-" : ""),
872 offset * multiplier,
873 ((given & 0x00200000) != 0 ? "!" : ""));
874 else
875 func (stream, "], %s#%d",
876 ((given & 0x00800000) == 0 ? "-" : ""),
877 offset * multiplier);
879 else
880 func (stream, "]");
882 break;
884 default:
885 abort ();
889 else
890 func (stream, "%c", *c);
892 return 4;
895 abort ();
898 /* Print one instruction from PC on INFO->STREAM.
899 Return the size of the instruction. */
901 static int
902 print_insn_thumb (pc, info, given)
903 bfd_vma pc;
904 struct disassemble_info *info;
905 long given;
907 const struct thumb_opcode *insn;
908 void *stream = info->stream;
909 fprintf_ftype func = info->fprintf_func;
911 for (insn = thumb_opcodes; insn->assembler; insn++)
913 if ((given & insn->mask) == insn->value)
915 char * c = insn->assembler;
917 /* Special processing for Thumb 2 instruction BL sequence: */
918 if (!*c) /* Check for empty (not NULL) assembler string. */
920 long offset;
922 info->bytes_per_chunk = 4;
923 info->bytes_per_line = 4;
925 offset = BDISP23 (given);
926 offset = offset * 2 + pc + 4;
928 if ((given & 0x10000000) == 0)
930 func (stream, "blx\t");
931 offset &= 0xfffffffc;
933 else
934 func (stream, "bl\t");
936 info->print_address_func (offset, info);
937 return 4;
939 else
941 info->bytes_per_chunk = 2;
942 info->bytes_per_line = 4;
944 given &= 0xffff;
946 for (; *c; c++)
948 if (*c == '%')
950 int domaskpc = 0;
951 int domasklr = 0;
953 switch (*++c)
955 case '%':
956 func (stream, "%%");
957 break;
959 case 'S':
961 long reg;
963 reg = (given >> 3) & 0x7;
964 if (given & (1 << 6))
965 reg += 8;
967 func (stream, "%s", arm_regnames[reg]);
969 break;
971 case 'D':
973 long reg;
975 reg = given & 0x7;
976 if (given & (1 << 7))
977 reg += 8;
979 func (stream, "%s", arm_regnames[reg]);
981 break;
983 case 'T':
984 func (stream, "%s",
985 arm_conditional [(given >> 8) & 0xf]);
986 break;
988 case 'N':
989 if (given & (1 << 8))
990 domasklr = 1;
991 /* Fall through. */
992 case 'O':
993 if (*c == 'O' && (given & (1 << 8)))
994 domaskpc = 1;
995 /* Fall through. */
996 case 'M':
998 int started = 0;
999 int reg;
1001 func (stream, "{");
1003 /* It would be nice if we could spot
1004 ranges, and generate the rS-rE format: */
1005 for (reg = 0; (reg < 8); reg++)
1006 if ((given & (1 << reg)) != 0)
1008 if (started)
1009 func (stream, ", ");
1010 started = 1;
1011 func (stream, "%s", arm_regnames[reg]);
1014 if (domasklr)
1016 if (started)
1017 func (stream, ", ");
1018 started = 1;
1019 func (stream, arm_regnames[14] /* "lr" */);
1022 if (domaskpc)
1024 if (started)
1025 func (stream, ", ");
1026 func (stream, arm_regnames[15] /* "pc" */);
1029 func (stream, "}");
1031 break;
1034 case '0': case '1': case '2': case '3': case '4':
1035 case '5': case '6': case '7': case '8': case '9':
1037 int bitstart = *c++ - '0';
1038 int bitend = 0;
1040 while (*c >= '0' && *c <= '9')
1041 bitstart = (bitstart * 10) + *c++ - '0';
1043 switch (*c)
1045 case '-':
1047 long reg;
1049 c++;
1050 while (*c >= '0' && *c <= '9')
1051 bitend = (bitend * 10) + *c++ - '0';
1052 if (!bitend)
1053 abort ();
1054 reg = given >> bitstart;
1055 reg &= (2 << (bitend - bitstart)) - 1;
1056 switch (*c)
1058 case 'r':
1059 func (stream, "%s", arm_regnames[reg]);
1060 break;
1062 case 'd':
1063 func (stream, "%d", reg);
1064 break;
1066 case 'H':
1067 func (stream, "%d", reg << 1);
1068 break;
1070 case 'W':
1071 func (stream, "%d", reg << 2);
1072 break;
1074 case 'a':
1075 /* PC-relative address -- the bottom two
1076 bits of the address are dropped
1077 before the calculation. */
1078 info->print_address_func
1079 (((pc + 4) & ~3) + (reg << 2), info);
1080 break;
1082 case 'x':
1083 func (stream, "0x%04x", reg);
1084 break;
1086 case 'I':
1087 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1088 func (stream, "%d", reg);
1089 break;
1091 case 'B':
1092 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1093 (*info->print_address_func)
1094 (reg * 2 + pc + 4, info);
1095 break;
1097 default:
1098 abort ();
1101 break;
1103 case '\'':
1104 c++;
1105 if ((given & (1 << bitstart)) != 0)
1106 func (stream, "%c", *c);
1107 break;
1109 case '?':
1110 ++c;
1111 if ((given & (1 << bitstart)) != 0)
1112 func (stream, "%c", *c++);
1113 else
1114 func (stream, "%c", *++c);
1115 break;
1117 default:
1118 abort ();
1121 break;
1123 default:
1124 abort ();
1127 else
1128 func (stream, "%c", *c);
1131 return 2;
1135 /* No match. */
1136 abort ();
1139 /* Parse an individual disassembler option. */
1141 void
1142 parse_arm_disassembler_option (option)
1143 char * option;
1145 if (option == NULL)
1146 return;
1148 if (strneq (option, "reg-names-", 10))
1150 int i;
1152 option += 10;
1154 for (i = NUM_ARM_REGNAMES; i--;)
1155 if (streq (option, regnames[i].name))
1157 regname_selected = i;
1158 break;
1161 if (i < 0)
1162 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1164 else if (streq (option, "force-thumb"))
1165 force_thumb = 1;
1166 else if (streq (option, "no-force-thumb"))
1167 force_thumb = 0;
1168 else
1169 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1171 return;
1174 /* Parse the string of disassembler options, spliting it at whitespaces. */
1176 static void
1177 parse_disassembler_options (options)
1178 char * options;
1180 char * space;
1182 if (options == NULL)
1183 return;
1187 space = strchr (options, ' ');
1189 if (space)
1191 * space = '\0';
1192 parse_arm_disassembler_option (options);
1193 * space = ' ';
1194 options = space + 1;
1196 else
1197 parse_arm_disassembler_option (options);
1199 while (space);
1202 /* NOTE: There are no checks in these routines that
1203 the relevant number of data bytes exist. */
1205 static int
1206 print_insn (pc, info, little)
1207 bfd_vma pc;
1208 struct disassemble_info * info;
1209 bfd_boolean little;
1211 unsigned char b[4];
1212 long given;
1213 int status;
1214 int is_thumb;
1216 if (info->disassembler_options)
1218 parse_disassembler_options (info->disassembler_options);
1220 /* To avoid repeated parsing of these options, we remove them here. */
1221 info->disassembler_options = NULL;
1224 is_thumb = force_thumb;
1226 if (!is_thumb && info->symbols != NULL)
1228 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1230 coff_symbol_type * cs;
1232 cs = coffsymbol (*info->symbols);
1233 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1234 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1235 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1236 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1237 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1239 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1241 elf_symbol_type * es;
1242 unsigned int type;
1244 es = *(elf_symbol_type **)(info->symbols);
1245 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1247 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1251 info->bytes_per_chunk = 4;
1252 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1254 if (little)
1256 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1257 if (status != 0 && is_thumb)
1259 info->bytes_per_chunk = 2;
1261 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1262 b[3] = b[2] = 0;
1265 if (status != 0)
1267 info->memory_error_func (status, pc, info);
1268 return -1;
1271 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1273 else
1275 status = info->read_memory_func
1276 (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1277 if (status != 0)
1279 info->memory_error_func (status, pc, info);
1280 return -1;
1283 if (is_thumb)
1285 if (pc & 0x2)
1287 given = (b[2] << 8) | b[3];
1289 status = info->read_memory_func
1290 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1291 if (status != 0)
1293 info->memory_error_func (status, pc + 4, info);
1294 return -1;
1297 given |= (b[0] << 24) | (b[1] << 16);
1299 else
1300 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1302 else
1303 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1306 if (info->flags & INSN_HAS_RELOC)
1307 /* If the instruction has a reloc associated with it, then
1308 the offset field in the instruction will actually be the
1309 addend for the reloc. (We are using REL type relocs).
1310 In such cases, we can ignore the pc when computing
1311 addresses, since the addend is not currently pc-relative. */
1312 pc = 0;
1314 if (is_thumb)
1315 status = print_insn_thumb (pc, info, given);
1316 else
1317 status = print_insn_arm (pc, info, given);
1319 return status;
1323 print_insn_big_arm (pc, info)
1324 bfd_vma pc;
1325 struct disassemble_info * info;
1327 return print_insn (pc, info, FALSE);
1331 print_insn_little_arm (pc, info)
1332 bfd_vma pc;
1333 struct disassemble_info * info;
1335 return print_insn (pc, info, TRUE);
1338 void
1339 print_arm_disassembler_options (FILE * stream)
1341 int i;
1343 fprintf (stream, _("\n\
1344 The following ARM specific disassembler options are supported for use with\n\
1345 the -M switch:\n"));
1347 for (i = NUM_ARM_REGNAMES; i--;)
1348 fprintf (stream, " reg-names-%s %*c%s\n",
1349 regnames[i].name,
1350 (int)(14 - strlen (regnames[i].name)), ' ',
1351 regnames[i].description);
1353 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
1354 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");