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