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