OSDN Git Service

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