s/boolean/bfd_boolean/ s/true/TRUE/ s/false/FALSE/. Simplify
[external/binutils.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5    Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7 This file is part of libopcodes.
8
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.
13
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.
18
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.  */
22
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
31 /* FIXME: This shouldn't be done here.  */
32 #include "elf-bfd.h"
33 #include "elf/internal.h"
34 #include "elf/arm.h"
35
36 #ifndef streq
37 #define streq(a,b)      (strcmp ((a), (b)) == 0)
38 #endif
39
40 #ifndef strneq
41 #define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
42 #endif
43
44 #ifndef NUM_ELEM
45 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
46 #endif
47
48 static char * arm_conditional[] =
49 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
50  "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
51
52 typedef struct
53 {
54   const char * name;
55   const char * description;
56   const char * reg_names[16];
57 }
58 arm_regname;
59
60 static arm_regname regnames[] =
61 {
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 };
75
76 /* Default to GCC register name set.  */
77 static unsigned int regname_selected = 1;
78
79 #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
80 #define arm_regnames      regnames[regname_selected].reg_names
81
82 static bfd_boolean force_thumb = FALSE;
83
84 static char * arm_fp_const[] =
85 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
86
87 static char * arm_shift[] =
88 {"lsl", "lsr", "asr", "ror"};
89 \f
90 /* Forward declarations.  */
91 static void arm_decode_shift
92   PARAMS ((long, fprintf_ftype, void *));
93 static int  print_insn_arm
94   PARAMS ((bfd_vma, struct disassemble_info *, long));
95 static int  print_insn_thumb
96   PARAMS ((bfd_vma, struct disassemble_info *, long));
97 static void parse_disassembler_options
98   PARAMS ((char *));
99 static int  print_insn
100   PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
101 int get_arm_regname_num_options (void);
102 int set_arm_regname_option (int option);
103 int get_arm_regnames (int option, const char **setname,
104                       const char **setdescription,
105                       const char ***register_names);
106 \f
107 /* Functions.  */
108 int
109 get_arm_regname_num_options ()
110 {
111   return NUM_ARM_REGNAMES;
112 }
113
114 int
115 set_arm_regname_option (option)
116      int option;
117 {
118   int old = regname_selected;
119   regname_selected = option;
120   return old;
121 }
122
123 int
124 get_arm_regnames (option, setname, setdescription, register_names)
125      int option;
126      const char **setname;
127      const char **setdescription;
128      const char ***register_names;
129 {
130   *setname = regnames[option].name;
131   *setdescription = regnames[option].description;
132   *register_names = regnames[option].reg_names;
133   return 16;
134 }
135
136 static void
137 arm_decode_shift (given, func, stream)
138      long given;
139      fprintf_ftype func;
140      void * stream;
141 {
142   func (stream, "%s", arm_regnames[given & 0xf]);
143
144   if ((given & 0xff0) != 0)
145     {
146       if ((given & 0x10) == 0)
147         {
148           int amount = (given & 0xf80) >> 7;
149           int shift = (given & 0x60) >> 5;
150
151           if (amount == 0)
152             {
153               if (shift == 3)
154                 {
155                   func (stream, ", rrx");
156                   return;
157                 }
158
159               amount = 32;
160             }
161
162           func (stream, ", %s #%d", arm_shift[shift], amount);
163         }
164       else
165         func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
166               arm_regnames[(given & 0xf00) >> 8]);
167     }
168 }
169
170 /* Print one instruction from PC on INFO->STREAM.
171    Return the size of the instruction (always 4 on ARM). */
172
173 static int
174 print_insn_arm (pc, info, given)
175      bfd_vma                   pc;
176      struct disassemble_info * info;
177      long                      given;
178 {
179   struct arm_opcode *  insn;
180   void *               stream = info->stream;
181   fprintf_ftype        func   = info->fprintf_func;
182
183   for (insn = arm_opcodes; insn->assembler; insn++)
184     {
185       if ((given & insn->mask) == insn->value)
186         {
187           char * c;
188
189           for (c = insn->assembler; *c; c++)
190             {
191               if (*c == '%')
192                 {
193                   switch (*++c)
194                     {
195                     case '%':
196                       func (stream, "%%");
197                       break;
198
199                     case 'a':
200                       if (((given & 0x000f0000) == 0x000f0000)
201                           && ((given & 0x02000000) == 0))
202                         {
203                           int offset = given & 0xfff;
204
205                           func (stream, "[pc");
206
207                           if (given & 0x01000000)
208                             {
209                               if ((given & 0x00800000) == 0)
210                                 offset = - offset;
211
212                               /* Pre-indexed.  */
213                               func (stream, ", #%d]", offset);
214
215                               offset += pc + 8;
216
217                               /* Cope with the possibility of write-back
218                                  being used.  Probably a very dangerous thing
219                                  for the programmer to do, but who are we to
220                                  argue ?  */
221                               if (given & 0x00200000)
222                                 func (stream, "!");
223                             }
224                           else
225                             {
226                               /* Post indexed.  */
227                               func (stream, "], #%d", offset);
228
229                               /* ie ignore the offset.  */
230                               offset = pc + 8;
231                             }
232
233                           func (stream, "\t; ");
234                           info->print_address_func (offset, info);
235                         }
236                       else
237                         {
238                           func (stream, "[%s",
239                                 arm_regnames[(given >> 16) & 0xf]);
240                           if ((given & 0x01000000) != 0)
241                             {
242                               if ((given & 0x02000000) == 0)
243                                 {
244                                   int offset = given & 0xfff;
245                                   if (offset)
246                                     func (stream, ", %s#%d",
247                                           (((given & 0x00800000) == 0)
248                                            ? "-" : ""), offset);
249                                 }
250                               else
251                                 {
252                                   func (stream, ", %s",
253                                         (((given & 0x00800000) == 0)
254                                          ? "-" : ""));
255                                   arm_decode_shift (given, func, stream);
256                                 }
257
258                               func (stream, "]%s",
259                                     ((given & 0x00200000) != 0) ? "!" : "");
260                             }
261                           else
262                             {
263                               if ((given & 0x02000000) == 0)
264                                 {
265                                   int offset = given & 0xfff;
266                                   if (offset)
267                                     func (stream, "], %s#%d",
268                                           (((given & 0x00800000) == 0)
269                                            ? "-" : ""), offset);
270                                   else
271                                     func (stream, "]");
272                                 }
273                               else
274                                 {
275                                   func (stream, "], %s",
276                                         (((given & 0x00800000) == 0)
277                                          ? "-" : ""));
278                                   arm_decode_shift (given, func, stream);
279                                 }
280                             }
281                         }
282                       break;
283
284                     case 's':
285                       if ((given & 0x004f0000) == 0x004f0000)
286                         {
287                           /* PC relative with immediate offset.  */
288                           int offset = ((given & 0xf00) >> 4) | (given & 0xf);
289
290                           if ((given & 0x00800000) == 0)
291                             offset = -offset;
292
293                           func (stream, "[pc, #%d]\t; ", offset);
294
295                           (*info->print_address_func)
296                             (offset + pc + 8, info);
297                         }
298                       else
299                         {
300                           func (stream, "[%s",
301                                 arm_regnames[(given >> 16) & 0xf]);
302                           if ((given & 0x01000000) != 0)
303                             {
304                               /* Pre-indexed.  */
305                               if ((given & 0x00400000) == 0x00400000)
306                                 {
307                                   /* Immediate.  */
308                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
309                                   if (offset)
310                                     func (stream, ", %s#%d",
311                                           (((given & 0x00800000) == 0)
312                                            ? "-" : ""), offset);
313                                 }
314                               else
315                                 {
316                                   /* Register.  */
317                                   func (stream, ", %s%s",
318                                         (((given & 0x00800000) == 0)
319                                          ? "-" : ""),
320                                         arm_regnames[given & 0xf]);
321                                 }
322
323                               func (stream, "]%s",
324                                     ((given & 0x00200000) != 0) ? "!" : "");
325                             }
326                           else
327                             {
328                               /* Post-indexed.  */
329                               if ((given & 0x00400000) == 0x00400000)
330                                 {
331                                   /* Immediate.  */
332                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
333                                   if (offset)
334                                     func (stream, "], %s#%d",
335                                           (((given & 0x00800000) == 0)
336                                            ? "-" : ""), offset);
337                                   else
338                                     func (stream, "]");
339                                 }
340                               else
341                                 {
342                                   /* Register.  */
343                                   func (stream, "], %s%s",
344                                         (((given & 0x00800000) == 0)
345                                          ? "-" : ""),
346                                         arm_regnames[given & 0xf]);
347                                 }
348                             }
349                         }
350                       break;
351
352                     case 'b':
353                       (*info->print_address_func)
354                         (BDISP (given) * 4 + pc + 8, info);
355                       break;
356
357                     case 'c':
358                       func (stream, "%s",
359                             arm_conditional [(given >> 28) & 0xf]);
360                       break;
361
362                     case 'm':
363                       {
364                         int started = 0;
365                         int reg;
366
367                         func (stream, "{");
368                         for (reg = 0; reg < 16; reg++)
369                           if ((given & (1 << reg)) != 0)
370                             {
371                               if (started)
372                                 func (stream, ", ");
373                               started = 1;
374                               func (stream, "%s", arm_regnames[reg]);
375                             }
376                         func (stream, "}");
377                       }
378                       break;
379
380                     case 'o':
381                       if ((given & 0x02000000) != 0)
382                         {
383                           int rotate = (given & 0xf00) >> 7;
384                           int immed = (given & 0xff);
385                           immed = (((immed << (32 - rotate))
386                                     | (immed >> rotate)) & 0xffffffff);
387                           func (stream, "#%d\t; 0x%x", immed, immed);
388                         }
389                       else
390                         arm_decode_shift (given, func, stream);
391                       break;
392
393                     case 'p':
394                       if ((given & 0x0000f000) == 0x0000f000)
395                         func (stream, "p");
396                       break;
397
398                     case 't':
399                       if ((given & 0x01200000) == 0x00200000)
400                         func (stream, "t");
401                       break;
402
403                     case 'A':
404                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
405                       if ((given & 0x01000000) != 0)
406                         {
407                           int offset = given & 0xff;
408                           if (offset)
409                             func (stream, ", %s#%d]%s",
410                                   ((given & 0x00800000) == 0 ? "-" : ""),
411                                   offset * 4,
412                                   ((given & 0x00200000) != 0 ? "!" : ""));
413                           else
414                             func (stream, "]");
415                         }
416                       else
417                         {
418                           int offset = given & 0xff;
419                           if (offset)
420                             func (stream, "], %s#%d",
421                                   ((given & 0x00800000) == 0 ? "-" : ""),
422                                   offset * 4);
423                           else
424                             func (stream, "]");
425                         }
426                       break;
427
428                     case 'B':
429                       /* Print ARM V5 BLX(1) address: pc+25 bits.  */
430                       {
431                         bfd_vma address;
432                         bfd_vma offset = 0;
433
434                         if (given & 0x00800000)
435                           /* Is signed, hi bits should be ones.  */
436                           offset = (-1) ^ 0x00ffffff;
437
438                         /* Offset is (SignExtend(offset field)<<2).  */
439                         offset += given & 0x00ffffff;
440                         offset <<= 2;
441                         address = offset + pc + 8;
442
443                         if (given & 0x01000000)
444                           /* H bit allows addressing to 2-byte boundaries.  */
445                           address += 2;
446
447                         info->print_address_func (address, info);
448                       }
449                       break;
450
451                     case 'I':
452                       /* Print a Cirrus/DSP shift immediate.  */
453                       /* Immediates are 7bit signed ints with bits 0..3 in
454                          bits 0..3 of opcode and bits 4..6 in bits 5..7
455                          of opcode.  */
456                       {
457                         int imm;
458
459                         imm = (given & 0xf) | ((given & 0xe0) >> 1);
460
461                         /* Is ``imm'' a negative number?  */
462                         if (imm & 0x40)
463                           imm |= (-1 << 7);
464
465                         func (stream, "%d", imm);
466                       }
467
468                       break;
469
470                     case 'C':
471                       func (stream, "_");
472                       if (given & 0x80000)
473                         func (stream, "f");
474                       if (given & 0x40000)
475                         func (stream, "s");
476                       if (given & 0x20000)
477                         func (stream, "x");
478                       if (given & 0x10000)
479                         func (stream, "c");
480                       break;
481
482                     case 'F':
483                       switch (given & 0x00408000)
484                         {
485                         case 0:
486                           func (stream, "4");
487                           break;
488                         case 0x8000:
489                           func (stream, "1");
490                           break;
491                         case 0x00400000:
492                           func (stream, "2");
493                           break;
494                         default:
495                           func (stream, "3");
496                         }
497                       break;
498
499                     case 'P':
500                       switch (given & 0x00080080)
501                         {
502                         case 0:
503                           func (stream, "s");
504                           break;
505                         case 0x80:
506                           func (stream, "d");
507                           break;
508                         case 0x00080000:
509                           func (stream, "e");
510                           break;
511                         default:
512                           func (stream, _("<illegal precision>"));
513                           break;
514                         }
515                       break;
516                     case 'Q':
517                       switch (given & 0x00408000)
518                         {
519                         case 0:
520                           func (stream, "s");
521                           break;
522                         case 0x8000:
523                           func (stream, "d");
524                           break;
525                         case 0x00400000:
526                           func (stream, "e");
527                           break;
528                         default:
529                           func (stream, "p");
530                           break;
531                         }
532                       break;
533                     case 'R':
534                       switch (given & 0x60)
535                         {
536                         case 0:
537                           break;
538                         case 0x20:
539                           func (stream, "p");
540                           break;
541                         case 0x40:
542                           func (stream, "m");
543                           break;
544                         default:
545                           func (stream, "z");
546                           break;
547                         }
548                       break;
549
550                     case '0': case '1': case '2': case '3': case '4':
551                     case '5': case '6': case '7': case '8': case '9':
552                       {
553                         int bitstart = *c++ - '0';
554                         int bitend = 0;
555                         while (*c >= '0' && *c <= '9')
556                           bitstart = (bitstart * 10) + *c++ - '0';
557
558                         switch (*c)
559                           {
560                           case '-':
561                             c++;
562
563                             while (*c >= '0' && *c <= '9')
564                               bitend = (bitend * 10) + *c++ - '0';
565
566                             if (!bitend)
567                               abort ();
568
569                             switch (*c)
570                               {
571                               case 'r':
572                                 {
573                                   long reg;
574
575                                   reg = given >> bitstart;
576                                   reg &= (2 << (bitend - bitstart)) - 1;
577
578                                   func (stream, "%s", arm_regnames[reg]);
579                                 }
580                                 break;
581                               case 'd':
582                                 {
583                                   long reg;
584
585                                   reg = given >> bitstart;
586                                   reg &= (2 << (bitend - bitstart)) - 1;
587
588                                   func (stream, "%d", reg);
589                                 }
590                                 break;
591                               case 'x':
592                                 {
593                                   long reg;
594
595                                   reg = given >> bitstart;
596                                   reg &= (2 << (bitend - bitstart)) - 1;
597
598                                   func (stream, "0x%08x", reg);
599
600                                   /* Some SWI instructions have special
601                                      meanings.  */
602                                   if ((given & 0x0fffffff) == 0x0FF00000)
603                                     func (stream, "\t; IMB");
604                                   else if ((given & 0x0fffffff) == 0x0FF00001)
605                                     func (stream, "\t; IMBRange");
606                                 }
607                                 break;
608                               case 'X':
609                                 {
610                                   long reg;
611
612                                   reg = given >> bitstart;
613                                   reg &= (2 << (bitend - bitstart)) - 1;
614
615                                   func (stream, "%01x", reg & 0xf);
616                                 }
617                                 break;
618                               case 'f':
619                                 {
620                                   long reg;
621
622                                   reg = given >> bitstart;
623                                   reg &= (2 << (bitend - bitstart)) - 1;
624
625                                   if (reg > 7)
626                                     func (stream, "#%s",
627                                           arm_fp_const[reg & 7]);
628                                   else
629                                     func (stream, "f%d", reg);
630                                 }
631                                 break;
632                               default:
633                                 abort ();
634                               }
635                             break;
636
637                           case 'y':
638                           case 'z':
639                             {
640                               int single = *c == 'y';
641                               int regno;
642
643                               switch (bitstart)
644                                 {
645                                 case 4: /* Sm pair */
646                                   func (stream, "{");
647                                   /* Fall through.  */
648                                 case 0: /* Sm, Dm */
649                                   regno = given & 0x0000000f;
650                                   if (single)
651                                     {
652                                       regno <<= 1;
653                                       regno += (given >> 5) & 1;
654                                     }
655                                   break;
656
657                                 case 1: /* Sd, Dd */
658                                   regno = (given >> 12) & 0x0000000f;
659                                   if (single)
660                                     {
661                                       regno <<= 1;
662                                       regno += (given >> 22) & 1;
663                                     }
664                                   break;
665
666                                 case 2: /* Sn, Dn */
667                                   regno = (given >> 16) & 0x0000000f;
668                                   if (single)
669                                     {
670                                       regno <<= 1;
671                                       regno += (given >> 7) & 1;
672                                     }
673                                   break;
674
675                                 case 3: /* List */
676                                   func (stream, "{");
677                                   regno = (given >> 12) & 0x0000000f;
678                                   if (single)
679                                     {
680                                       regno <<= 1;
681                                       regno += (given >> 22) & 1;
682                                     }
683                                   break;
684
685
686                                 default:
687                                   abort ();
688                                 }
689
690                               func (stream, "%c%d", single ? 's' : 'd', regno);
691
692                               if (bitstart == 3)
693                                 {
694                                   int count = given & 0xff;
695
696                                   if (single == 0)
697                                     count >>= 1;
698
699                                   if (--count)
700                                     {
701                                       func (stream, "-%c%d",
702                                             single ? 's' : 'd',
703                                             regno + count);
704                                     }
705
706                                   func (stream, "}");
707                                 }
708                               else if (bitstart == 4)
709                                 func (stream, ", %c%d}", single ? 's' : 'd',
710                                       regno + 1);
711
712                               break;
713                             }
714
715                           case '`':
716                             c++;
717                             if ((given & (1 << bitstart)) == 0)
718                               func (stream, "%c", *c);
719                             break;
720                           case '\'':
721                             c++;
722                             if ((given & (1 << bitstart)) != 0)
723                               func (stream, "%c", *c);
724                             break;
725                           case '?':
726                             ++c;
727                             if ((given & (1 << bitstart)) != 0)
728                               func (stream, "%c", *c++);
729                             else
730                               func (stream, "%c", *++c);
731                             break;
732                           default:
733                             abort ();
734                           }
735                         break;
736
737                       default:
738                         abort ();
739                       }
740                     }
741                 }
742               else
743                 func (stream, "%c", *c);
744             }
745           return 4;
746         }
747     }
748   abort ();
749 }
750
751 /* Print one instruction from PC on INFO->STREAM.
752    Return the size of the instruction. */
753
754 static int
755 print_insn_thumb (pc, info, given)
756      bfd_vma                   pc;
757      struct disassemble_info * info;
758      long                      given;
759 {
760   struct thumb_opcode * insn;
761   void *                stream = info->stream;
762   fprintf_ftype         func = info->fprintf_func;
763
764   for (insn = thumb_opcodes; insn->assembler; insn++)
765     {
766       if ((given & insn->mask) == insn->value)
767         {
768           char * c = insn->assembler;
769
770           /* Special processing for Thumb 2 instruction BL sequence:  */
771           if (!*c) /* Check for empty (not NULL) assembler string.  */
772             {
773               long offset;
774
775               info->bytes_per_chunk = 4;
776               info->bytes_per_line  = 4;
777
778               offset = BDISP23 (given);
779               offset = offset * 2 + pc + 4;
780
781               if ((given & 0x10000000) == 0)
782                 {
783                   func (stream, "blx\t");
784                   offset &= 0xfffffffc;
785                 }
786               else
787                 func (stream, "bl\t");
788
789               info->print_address_func (offset, info);
790               return 4;
791             }
792           else
793             {
794               info->bytes_per_chunk = 2;
795               info->bytes_per_line  = 4;
796
797               given &= 0xffff;
798
799               for (; *c; c++)
800                 {
801                   if (*c == '%')
802                     {
803                       int domaskpc = 0;
804                       int domasklr = 0;
805
806                       switch (*++c)
807                         {
808                         case '%':
809                           func (stream, "%%");
810                           break;
811
812                         case 'S':
813                           {
814                             long reg;
815
816                             reg = (given >> 3) & 0x7;
817                             if (given & (1 << 6))
818                               reg += 8;
819
820                             func (stream, "%s", arm_regnames[reg]);
821                           }
822                           break;
823
824                         case 'D':
825                           {
826                             long reg;
827
828                             reg = given & 0x7;
829                             if (given & (1 << 7))
830                              reg += 8;
831
832                             func (stream, "%s", arm_regnames[reg]);
833                           }
834                           break;
835
836                         case 'T':
837                           func (stream, "%s",
838                                 arm_conditional [(given >> 8) & 0xf]);
839                           break;
840
841                         case 'N':
842                           if (given & (1 << 8))
843                             domasklr = 1;
844                           /* Fall through.  */
845                         case 'O':
846                           if (*c == 'O' && (given & (1 << 8)))
847                             domaskpc = 1;
848                           /* Fall through.  */
849                         case 'M':
850                           {
851                             int started = 0;
852                             int reg;
853
854                             func (stream, "{");
855
856                             /* It would be nice if we could spot
857                                ranges, and generate the rS-rE format: */
858                             for (reg = 0; (reg < 8); reg++)
859                               if ((given & (1 << reg)) != 0)
860                                 {
861                                   if (started)
862                                     func (stream, ", ");
863                                   started = 1;
864                                   func (stream, "%s", arm_regnames[reg]);
865                                 }
866
867                             if (domasklr)
868                               {
869                                 if (started)
870                                   func (stream, ", ");
871                                 started = 1;
872                                 func (stream, arm_regnames[14] /* "lr" */);
873                               }
874
875                             if (domaskpc)
876                               {
877                                 if (started)
878                                   func (stream, ", ");
879                                 func (stream, arm_regnames[15] /* "pc" */);
880                               }
881
882                             func (stream, "}");
883                           }
884                           break;
885
886
887                         case '0': case '1': case '2': case '3': case '4':
888                         case '5': case '6': case '7': case '8': case '9':
889                           {
890                             int bitstart = *c++ - '0';
891                             int bitend = 0;
892
893                             while (*c >= '0' && *c <= '9')
894                               bitstart = (bitstart * 10) + *c++ - '0';
895
896                             switch (*c)
897                               {
898                               case '-':
899                                 {
900                                   long reg;
901
902                                   c++;
903                                   while (*c >= '0' && *c <= '9')
904                                     bitend = (bitend * 10) + *c++ - '0';
905                                   if (!bitend)
906                                     abort ();
907                                   reg = given >> bitstart;
908                                   reg &= (2 << (bitend - bitstart)) - 1;
909                                   switch (*c)
910                                     {
911                                     case 'r':
912                                       func (stream, "%s", arm_regnames[reg]);
913                                       break;
914
915                                     case 'd':
916                                       func (stream, "%d", reg);
917                                       break;
918
919                                     case 'H':
920                                       func (stream, "%d", reg << 1);
921                                       break;
922
923                                     case 'W':
924                                       func (stream, "%d", reg << 2);
925                                       break;
926
927                                     case 'a':
928                                       /* PC-relative address -- the bottom two
929                                          bits of the address are dropped
930                                          before the calculation.  */
931                                       info->print_address_func
932                                         (((pc + 4) & ~3) + (reg << 2), info);
933                                       break;
934
935                                     case 'x':
936                                       func (stream, "0x%04x", reg);
937                                       break;
938
939                                     case 'I':
940                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
941                                       func (stream, "%d", reg);
942                                       break;
943
944                                     case 'B':
945                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
946                                       (*info->print_address_func)
947                                         (reg * 2 + pc + 4, info);
948                                       break;
949
950                                     default:
951                                       abort ();
952                                     }
953                                 }
954                                 break;
955
956                               case '\'':
957                                 c++;
958                                 if ((given & (1 << bitstart)) != 0)
959                                   func (stream, "%c", *c);
960                                 break;
961
962                               case '?':
963                                 ++c;
964                                 if ((given & (1 << bitstart)) != 0)
965                                   func (stream, "%c", *c++);
966                                 else
967                                   func (stream, "%c", *++c);
968                                 break;
969
970                               default:
971                                  abort ();
972                               }
973                           }
974                           break;
975
976                         default:
977                           abort ();
978                         }
979                     }
980                   else
981                     func (stream, "%c", *c);
982                 }
983              }
984           return 2;
985        }
986     }
987
988   /* No match.  */
989   abort ();
990 }
991
992 /* Parse an individual disassembler option.  */
993
994 void
995 parse_arm_disassembler_option (option)
996      char * option;
997 {
998   if (option == NULL)
999     return;
1000
1001   if (strneq (option, "reg-names-", 10))
1002     {
1003       int i;
1004
1005       option += 10;
1006
1007       for (i = NUM_ARM_REGNAMES; i--;)
1008         if (streq (option, regnames[i].name))
1009           {
1010             regname_selected = i;
1011             break;
1012           }
1013
1014       if (i < 0)
1015         fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1016     }
1017   else if (streq (option, "force-thumb"))
1018     force_thumb = 1;
1019   else if (streq (option, "no-force-thumb"))
1020     force_thumb = 0;
1021   else
1022     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1023
1024   return;
1025 }
1026
1027 /* Parse the string of disassembler options, spliting it at whitespaces.  */
1028
1029 static void
1030 parse_disassembler_options (options)
1031      char * options;
1032 {
1033   char * space;
1034
1035   if (options == NULL)
1036     return;
1037
1038   do
1039     {
1040       space = strchr (options, ' ');
1041
1042       if (space)
1043         {
1044           * space = '\0';
1045           parse_arm_disassembler_option (options);
1046           * space = ' ';
1047           options = space + 1;
1048         }
1049       else
1050         parse_arm_disassembler_option (options);
1051     }
1052   while (space);
1053 }
1054
1055 /* NOTE: There are no checks in these routines that
1056    the relevant number of data bytes exist.  */
1057
1058 static int
1059 print_insn (pc, info, little)
1060      bfd_vma pc;
1061      struct disassemble_info * info;
1062      bfd_boolean little;
1063 {
1064   unsigned char      b[4];
1065   long               given;
1066   int                status;
1067   int                is_thumb;
1068
1069   if (info->disassembler_options)
1070     {
1071       parse_disassembler_options (info->disassembler_options);
1072
1073       /* To avoid repeated parsing of these options, we remove them here.  */
1074       info->disassembler_options = NULL;
1075     }
1076
1077   is_thumb = force_thumb;
1078
1079   if (!is_thumb && info->symbols != NULL)
1080     {
1081       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1082         {
1083           coff_symbol_type * cs;
1084
1085           cs = coffsymbol (*info->symbols);
1086           is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
1087                       || cs->native->u.syment.n_sclass == C_THUMBSTAT
1088                       || cs->native->u.syment.n_sclass == C_THUMBLABEL
1089                       || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1090                       || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1091         }
1092       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1093         {
1094           elf_symbol_type *  es;
1095           unsigned int       type;
1096
1097           es = *(elf_symbol_type **)(info->symbols);
1098           type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1099
1100           is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1101         }
1102     }
1103
1104   info->bytes_per_chunk = 4;
1105   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1106
1107   if (little)
1108     {
1109       status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1110       if (status != 0 && is_thumb)
1111         {
1112           info->bytes_per_chunk = 2;
1113
1114           status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1115           b[3] = b[2] = 0;
1116         }
1117
1118       if (status != 0)
1119         {
1120           info->memory_error_func (status, pc, info);
1121           return -1;
1122         }
1123
1124       given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1125     }
1126   else
1127     {
1128       status = info->read_memory_func
1129         (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1130       if (status != 0)
1131         {
1132           info->memory_error_func (status, pc, info);
1133           return -1;
1134         }
1135
1136       if (is_thumb)
1137         {
1138           if (pc & 0x2)
1139             {
1140               given = (b[2] << 8) | b[3];
1141
1142               status = info->read_memory_func
1143                 ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1144               if (status != 0)
1145                 {
1146                   info->memory_error_func (status, pc + 4, info);
1147                   return -1;
1148                 }
1149
1150               given |= (b[0] << 24) | (b[1] << 16);
1151             }
1152           else
1153             given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1154         }
1155       else
1156         given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1157     }
1158
1159   if (info->flags & INSN_HAS_RELOC)
1160     /* If the instruction has a reloc associated with it, then
1161        the offset field in the instruction will actually be the
1162        addend for the reloc.  (We are using REL type relocs).
1163        In such cases, we can ignore the pc when computing
1164        addresses, since the addend is not currently pc-relative.  */
1165     pc = 0;
1166
1167   if (is_thumb)
1168     status = print_insn_thumb (pc, info, given);
1169   else
1170     status = print_insn_arm (pc, info, given);
1171
1172   return status;
1173 }
1174
1175 int
1176 print_insn_big_arm (pc, info)
1177      bfd_vma pc;
1178      struct disassemble_info * info;
1179 {
1180   return print_insn (pc, info, FALSE);
1181 }
1182
1183 int
1184 print_insn_little_arm (pc, info)
1185      bfd_vma pc;
1186      struct disassemble_info * info;
1187 {
1188   return print_insn (pc, info, TRUE);
1189 }
1190
1191 void
1192 print_arm_disassembler_options (FILE * stream)
1193 {
1194   int i;
1195
1196   fprintf (stream, _("\n\
1197 The following ARM specific disassembler options are supported for use with\n\
1198 the -M switch:\n"));
1199
1200   for (i = NUM_ARM_REGNAMES; i--;)
1201     fprintf (stream, "  reg-names-%s %*c%s\n",
1202              regnames[i].name,
1203              (int)(14 - strlen (regnames[i].name)), ' ',
1204              regnames[i].description);
1205
1206   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
1207   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
1208 }