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