xref: /openbsd-src/gnu/usr.bin/binutils/opcodes/arm-dis.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* Instruction printing code for the ARM
2c074d1c9Sdrahn    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3b55d4692Sfgsch    Free Software Foundation, Inc.
42159047fSniklas    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5b305b0f1Sespie    Modification by James G. Smith (jsmith@cygnus.co.uk)
62159047fSniklas 
72159047fSniklas    This file is part of libopcodes.
82159047fSniklas 
92159047fSniklas    This program is free software; you can redistribute it and/or modify it under
102159047fSniklas    the terms of the GNU General Public License as published by the Free
112159047fSniklas    Software Foundation; either version 2 of the License, or (at your option)
122159047fSniklas    any later version.
132159047fSniklas 
142159047fSniklas    This program is distributed in the hope that it will be useful, but WITHOUT
152159047fSniklas    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
162159047fSniklas    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
172159047fSniklas    more details.
182159047fSniklas 
19b305b0f1Sespie    You should have received a copy of the GNU General Public License
20b305b0f1Sespie    along with this program; if not, write to the Free Software
21b305b0f1Sespie    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
222159047fSniklas 
23b305b0f1Sespie #include "sysdep.h"
242159047fSniklas #include "dis-asm.h"
252159047fSniklas #define DEFINE_TABLE
262159047fSniklas #include "arm-opc.h"
27b305b0f1Sespie #include "coff/internal.h"
28b305b0f1Sespie #include "libcoff.h"
29b305b0f1Sespie #include "opintl.h"
30*007c2a45Smiod #include "safe-ctype.h"
312159047fSniklas 
32c074d1c9Sdrahn /* FIXME: This shouldn't be done here.  */
33b305b0f1Sespie #include "elf-bfd.h"
34b305b0f1Sespie #include "elf/internal.h"
35b305b0f1Sespie #include "elf/arm.h"
36b305b0f1Sespie 
37b305b0f1Sespie #ifndef streq
38b305b0f1Sespie #define streq(a,b)	(strcmp ((a), (b)) == 0)
39b305b0f1Sespie #endif
40b305b0f1Sespie 
41b305b0f1Sespie #ifndef strneq
42b305b0f1Sespie #define strneq(a,b,n)	(strncmp ((a), (b), (n)) == 0)
43b305b0f1Sespie #endif
44b305b0f1Sespie 
45b305b0f1Sespie #ifndef NUM_ELEM
46b305b0f1Sespie #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
47b305b0f1Sespie #endif
482159047fSniklas 
492159047fSniklas static char * arm_conditional[] =
502159047fSniklas {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
512159047fSniklas  "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
522159047fSniklas 
53b305b0f1Sespie typedef struct
54b305b0f1Sespie {
55b305b0f1Sespie   const char * name;
56b305b0f1Sespie   const char * description;
57b305b0f1Sespie   const char * reg_names[16];
58b305b0f1Sespie }
59b305b0f1Sespie arm_regname;
60b305b0f1Sespie 
61b305b0f1Sespie static arm_regname regnames[] =
62b305b0f1Sespie {
63b305b0f1Sespie   { "raw" , "Select raw register names",
64b305b0f1Sespie     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
65b55d4692Sfgsch   { "gcc",  "Select register names used by GCC",
66b55d4692Sfgsch     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
67b305b0f1Sespie   { "std",  "Select register names used in ARM's ISA documentation",
68b305b0f1Sespie     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
69b305b0f1Sespie   { "apcs", "Select register names used in the APCS",
70b305b0f1Sespie     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
71b305b0f1Sespie   { "atpcs", "Select register names used in the ATPCS",
72b305b0f1Sespie     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
73b305b0f1Sespie   { "special-atpcs", "Select special register names used in the ATPCS",
74c074d1c9Sdrahn     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
75c074d1c9Sdrahn   { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
76c074d1c9Sdrahn     { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
77c074d1c9Sdrahn   { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
78c074d1c9Sdrahn     {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
79c074d1c9Sdrahn };
80c074d1c9Sdrahn 
81c074d1c9Sdrahn static char * iwmmxt_wwnames[] =
82c074d1c9Sdrahn {"b", "h", "w", "d"};
83c074d1c9Sdrahn 
84c074d1c9Sdrahn static char * iwmmxt_wwssnames[] =
85c074d1c9Sdrahn {"b", "bus", "b", "bss",
86c074d1c9Sdrahn  "h", "hus", "h", "hss",
87c074d1c9Sdrahn  "w", "wus", "w", "wss",
88c074d1c9Sdrahn  "d", "dus", "d", "dss"
89b305b0f1Sespie };
90b305b0f1Sespie 
91b55d4692Sfgsch /* Default to GCC register name set.  */
92b305b0f1Sespie static unsigned int regname_selected = 1;
93b305b0f1Sespie 
94b305b0f1Sespie #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
95b305b0f1Sespie #define arm_regnames      regnames[regname_selected].reg_names
96b305b0f1Sespie 
97c074d1c9Sdrahn static bfd_boolean force_thumb = FALSE;
982159047fSniklas 
992159047fSniklas static char * arm_fp_const[] =
1002159047fSniklas {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1012159047fSniklas 
1022159047fSniklas static char * arm_shift[] =
1032159047fSniklas {"lsl", "lsr", "asr", "ror"};
104b305b0f1Sespie 
105b305b0f1Sespie /* Forward declarations.  */
106c074d1c9Sdrahn static void arm_decode_shift
107c074d1c9Sdrahn   PARAMS ((long, fprintf_ftype, void *));
108c074d1c9Sdrahn static int  print_insn_arm
109c074d1c9Sdrahn   PARAMS ((bfd_vma, struct disassemble_info *, long));
110c074d1c9Sdrahn static int  print_insn_thumb
111c074d1c9Sdrahn   PARAMS ((bfd_vma, struct disassemble_info *, long));
112c074d1c9Sdrahn static void parse_disassembler_options
113c074d1c9Sdrahn   PARAMS ((char *));
114c074d1c9Sdrahn static int  print_insn
115c074d1c9Sdrahn   PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
116c074d1c9Sdrahn static int set_iwmmxt_regnames
117c074d1c9Sdrahn   PARAMS ((void));
118c074d1c9Sdrahn 
119c074d1c9Sdrahn int get_arm_regname_num_options
120c074d1c9Sdrahn   PARAMS ((void));
121c074d1c9Sdrahn int set_arm_regname_option
122c074d1c9Sdrahn   PARAMS ((int));
123c074d1c9Sdrahn int get_arm_regnames
124c074d1c9Sdrahn   PARAMS ((int, const char **, const char **, const char ***));
125b305b0f1Sespie 
126b305b0f1Sespie /* Functions.  */
127b305b0f1Sespie int
get_arm_regname_num_options()128c074d1c9Sdrahn get_arm_regname_num_options ()
129b305b0f1Sespie {
130b305b0f1Sespie   return NUM_ARM_REGNAMES;
131b305b0f1Sespie }
132b305b0f1Sespie 
133b305b0f1Sespie int
set_arm_regname_option(option)134c074d1c9Sdrahn set_arm_regname_option (option)
135c074d1c9Sdrahn      int option;
136b305b0f1Sespie {
137b305b0f1Sespie   int old = regname_selected;
138b305b0f1Sespie   regname_selected = option;
139b305b0f1Sespie   return old;
140b305b0f1Sespie }
141b305b0f1Sespie 
142b305b0f1Sespie int
get_arm_regnames(option,setname,setdescription,register_names)143c074d1c9Sdrahn get_arm_regnames (option, setname, setdescription, register_names)
144c074d1c9Sdrahn      int option;
145c074d1c9Sdrahn      const char **setname;
146c074d1c9Sdrahn      const char **setdescription;
147c074d1c9Sdrahn      const char ***register_names;
148b305b0f1Sespie {
149b305b0f1Sespie   *setname = regnames[option].name;
150b305b0f1Sespie   *setdescription = regnames[option].description;
151b305b0f1Sespie   *register_names = regnames[option].reg_names;
152b305b0f1Sespie   return 16;
153b305b0f1Sespie }
1542159047fSniklas 
1552159047fSniklas static void
arm_decode_shift(given,func,stream)1562159047fSniklas arm_decode_shift (given, func, stream)
1572159047fSniklas      long given;
1582159047fSniklas      fprintf_ftype func;
1592159047fSniklas      void * stream;
1602159047fSniklas {
1612159047fSniklas   func (stream, "%s", arm_regnames[given & 0xf]);
162b305b0f1Sespie 
1632159047fSniklas   if ((given & 0xff0) != 0)
1642159047fSniklas     {
1652159047fSniklas       if ((given & 0x10) == 0)
1662159047fSniklas 	{
1672159047fSniklas 	  int amount = (given & 0xf80) >> 7;
1682159047fSniklas 	  int shift = (given & 0x60) >> 5;
169b305b0f1Sespie 
1702159047fSniklas 	  if (amount == 0)
1712159047fSniklas 	    {
1722159047fSniklas 	      if (shift == 3)
1732159047fSniklas 		{
1742159047fSniklas 		  func (stream, ", rrx");
1752159047fSniklas 		  return;
1762159047fSniklas 		}
177b305b0f1Sespie 
1782159047fSniklas 	      amount = 32;
1792159047fSniklas 	    }
180b305b0f1Sespie 
181b305b0f1Sespie 	  func (stream, ", %s #%d", arm_shift[shift], amount);
1822159047fSniklas 	}
1832159047fSniklas       else
1842159047fSniklas 	func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1852159047fSniklas 	      arm_regnames[(given & 0xf00) >> 8]);
1862159047fSniklas     }
1872159047fSniklas }
1882159047fSniklas 
189c074d1c9Sdrahn static int
set_iwmmxt_regnames()190c074d1c9Sdrahn set_iwmmxt_regnames ()
191c074d1c9Sdrahn {
192c074d1c9Sdrahn   const char * setname;
193c074d1c9Sdrahn   const char * setdesc;
194c074d1c9Sdrahn   const char ** regnames;
195c074d1c9Sdrahn   int iwmmxt_regnames = 0;
196c074d1c9Sdrahn   int num_regnames = get_arm_regname_num_options ();
197c074d1c9Sdrahn 
198c074d1c9Sdrahn   get_arm_regnames (iwmmxt_regnames, &setname,
199c074d1c9Sdrahn 		    &setdesc, &regnames);
200c074d1c9Sdrahn   while ((strcmp ("iwmmxt_regnames", setname))
201c074d1c9Sdrahn 	 && (iwmmxt_regnames < num_regnames))
202c074d1c9Sdrahn     get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
203c074d1c9Sdrahn 
204c074d1c9Sdrahn   return iwmmxt_regnames;
205c074d1c9Sdrahn }
206c074d1c9Sdrahn 
2072159047fSniklas /* Print one instruction from PC on INFO->STREAM.
2082159047fSniklas    Return the size of the instruction (always 4 on ARM). */
209c074d1c9Sdrahn 
2102159047fSniklas static int
print_insn_arm(pc,info,given)2112159047fSniklas print_insn_arm (pc, info, given)
2122159047fSniklas      bfd_vma pc;
2132159047fSniklas      struct disassemble_info *info;
2142159047fSniklas      long given;
2152159047fSniklas {
216c074d1c9Sdrahn   const struct arm_opcode *insn;
2172159047fSniklas   void *stream = info->stream;
2182159047fSniklas   fprintf_ftype func   = info->fprintf_func;
219c074d1c9Sdrahn   static int iwmmxt_regnames = 0;
2202159047fSniklas 
2212159047fSniklas   for (insn = arm_opcodes; insn->assembler; insn++)
2222159047fSniklas     {
223c074d1c9Sdrahn       if (insn->value == FIRST_IWMMXT_INSN
224c074d1c9Sdrahn 	  && info->mach != bfd_mach_arm_XScale
225c074d1c9Sdrahn 	  && info->mach != bfd_mach_arm_iWMMXt)
226c074d1c9Sdrahn 	insn = insn + IWMMXT_INSN_COUNT;
227c074d1c9Sdrahn 
2282159047fSniklas       if ((given & insn->mask) == insn->value)
2292159047fSniklas 	{
2302159047fSniklas 	  char * c;
231b305b0f1Sespie 
2322159047fSniklas 	  for (c = insn->assembler; *c; c++)
2332159047fSniklas 	    {
2342159047fSniklas 	      if (*c == '%')
2352159047fSniklas 		{
2362159047fSniklas 		  switch (*++c)
2372159047fSniklas 		    {
2382159047fSniklas 		    case '%':
2392159047fSniklas 		      func (stream, "%%");
2402159047fSniklas 		      break;
2412159047fSniklas 
2422159047fSniklas 		    case 'a':
2432159047fSniklas 		      if (((given & 0x000f0000) == 0x000f0000)
2442159047fSniklas 			  && ((given & 0x02000000) == 0))
2452159047fSniklas 			{
2462159047fSniklas 			  int offset = given & 0xfff;
247b305b0f1Sespie 
248b305b0f1Sespie 			  func (stream, "[pc");
249b305b0f1Sespie 
250b305b0f1Sespie 			  if (given & 0x01000000)
251b305b0f1Sespie 			    {
2522159047fSniklas 			      if ((given & 0x00800000) == 0)
2532159047fSniklas 				offset = - offset;
254b305b0f1Sespie 
255c074d1c9Sdrahn 			      /* Pre-indexed.  */
256c074d1c9Sdrahn 			      func (stream, ", #%d]", offset);
257b305b0f1Sespie 
258b305b0f1Sespie 			      offset += pc + 8;
259b305b0f1Sespie 
260b305b0f1Sespie 			      /* Cope with the possibility of write-back
261b305b0f1Sespie 				 being used.  Probably a very dangerous thing
262b305b0f1Sespie 				 for the programmer to do, but who are we to
263b305b0f1Sespie 				 argue ?  */
264b305b0f1Sespie 			      if (given & 0x00200000)
265b305b0f1Sespie 				func (stream, "!");
266b305b0f1Sespie 			    }
267b305b0f1Sespie 			  else
268b305b0f1Sespie 			    {
269b305b0f1Sespie 			      /* Post indexed.  */
270c074d1c9Sdrahn 			      func (stream, "], #%d", offset);
271b305b0f1Sespie 
272c074d1c9Sdrahn 			      /* ie ignore the offset.  */
273c074d1c9Sdrahn 			      offset = pc + 8;
274b305b0f1Sespie 			    }
275b305b0f1Sespie 
276b305b0f1Sespie 			  func (stream, "\t; ");
277b305b0f1Sespie 			  info->print_address_func (offset, info);
2782159047fSniklas 			}
2792159047fSniklas 		      else
2802159047fSniklas 			{
2812159047fSniklas 			  func (stream, "[%s",
2822159047fSniklas 				arm_regnames[(given >> 16) & 0xf]);
2832159047fSniklas 			  if ((given & 0x01000000) != 0)
2842159047fSniklas 			    {
2852159047fSniklas 			      if ((given & 0x02000000) == 0)
2862159047fSniklas 				{
2872159047fSniklas 				  int offset = given & 0xfff;
2882159047fSniklas 				  if (offset)
289*007c2a45Smiod 				    func (stream, ", #%s%d",
2902159047fSniklas 					  (((given & 0x00800000) == 0)
2912159047fSniklas 					   ? "-" : ""), offset);
2922159047fSniklas 				}
2932159047fSniklas 			      else
2942159047fSniklas 				{
2952159047fSniklas 				  func (stream, ", %s",
2962159047fSniklas 					(((given & 0x00800000) == 0)
2972159047fSniklas 					 ? "-" : ""));
2982159047fSniklas 				  arm_decode_shift (given, func, stream);
2992159047fSniklas 				}
3002159047fSniklas 
3012159047fSniklas 			      func (stream, "]%s",
3022159047fSniklas 				    ((given & 0x00200000) != 0) ? "!" : "");
3032159047fSniklas 			    }
3042159047fSniklas 			  else
3052159047fSniklas 			    {
3062159047fSniklas 			      if ((given & 0x02000000) == 0)
3072159047fSniklas 				{
3082159047fSniklas 				  int offset = given & 0xfff;
3092159047fSniklas 				  if (offset)
310*007c2a45Smiod 				    func (stream, "], #%s%d",
3112159047fSniklas 					  (((given & 0x00800000) == 0)
3122159047fSniklas 					   ? "-" : ""), offset);
3132159047fSniklas 				  else
3142159047fSniklas 				    func (stream, "]");
3152159047fSniklas 				}
3162159047fSniklas 			      else
3172159047fSniklas 				{
3182159047fSniklas 				  func (stream, "], %s",
3192159047fSniklas 					(((given & 0x00800000) == 0)
3202159047fSniklas 					 ? "-" : ""));
3212159047fSniklas 				  arm_decode_shift (given, func, stream);
3222159047fSniklas 				}
3232159047fSniklas 			    }
3242159047fSniklas 			}
3252159047fSniklas 		      break;
3262159047fSniklas 
3274361b62eSniklas 		    case 's':
3284361b62eSniklas                       if ((given & 0x004f0000) == 0x004f0000)
3294361b62eSniklas 			{
330b305b0f1Sespie                           /* PC relative with immediate offset.  */
3314361b62eSniklas 			  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
332b305b0f1Sespie 
3334361b62eSniklas 			  if ((given & 0x00800000) == 0)
3344361b62eSniklas 			    offset = -offset;
335b305b0f1Sespie 
336c074d1c9Sdrahn 			  func (stream, "[pc, #%d]\t; ", offset);
337b305b0f1Sespie 
3384361b62eSniklas 			  (*info->print_address_func)
3394361b62eSniklas 			    (offset + pc + 8, info);
3404361b62eSniklas 			}
3414361b62eSniklas 		      else
3424361b62eSniklas 			{
3434361b62eSniklas 			  func (stream, "[%s",
3444361b62eSniklas 				arm_regnames[(given >> 16) & 0xf]);
3454361b62eSniklas 			  if ((given & 0x01000000) != 0)
3464361b62eSniklas 			    {
347b305b0f1Sespie                               /* Pre-indexed.  */
3484361b62eSniklas 			      if ((given & 0x00400000) == 0x00400000)
3494361b62eSniklas 				{
350b305b0f1Sespie                                   /* Immediate.  */
3514361b62eSniklas                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3524361b62eSniklas 				  if (offset)
353*007c2a45Smiod 				    func (stream, ", #%s%d",
3544361b62eSniklas 					  (((given & 0x00800000) == 0)
3554361b62eSniklas 					   ? "-" : ""), offset);
3564361b62eSniklas 				}
3574361b62eSniklas 			      else
3584361b62eSniklas 				{
359b305b0f1Sespie                                   /* Register.  */
3604361b62eSniklas 				  func (stream, ", %s%s",
3614361b62eSniklas 					(((given & 0x00800000) == 0)
3624361b62eSniklas 					 ? "-" : ""),
3634361b62eSniklas                                         arm_regnames[given & 0xf]);
3644361b62eSniklas 				}
3654361b62eSniklas 
3664361b62eSniklas 			      func (stream, "]%s",
3674361b62eSniklas 				    ((given & 0x00200000) != 0) ? "!" : "");
3684361b62eSniklas 			    }
3694361b62eSniklas 			  else
3704361b62eSniklas 			    {
371b305b0f1Sespie                               /* Post-indexed.  */
3724361b62eSniklas 			      if ((given & 0x00400000) == 0x00400000)
3734361b62eSniklas 				{
374b305b0f1Sespie                                   /* Immediate.  */
3754361b62eSniklas                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3764361b62eSniklas 				  if (offset)
377*007c2a45Smiod 				    func (stream, "], #%s%d",
3784361b62eSniklas 					  (((given & 0x00800000) == 0)
3794361b62eSniklas 					   ? "-" : ""), offset);
3804361b62eSniklas 				  else
3814361b62eSniklas 				    func (stream, "]");
3824361b62eSniklas 				}
3834361b62eSniklas 			      else
3844361b62eSniklas 				{
385b305b0f1Sespie                                   /* Register.  */
3864361b62eSniklas 				  func (stream, "], %s%s",
3874361b62eSniklas 					(((given & 0x00800000) == 0)
3884361b62eSniklas 					 ? "-" : ""),
3894361b62eSniklas                                         arm_regnames[given & 0xf]);
3904361b62eSniklas 				}
3914361b62eSniklas 			    }
3924361b62eSniklas 			}
3934361b62eSniklas 		      break;
3944361b62eSniklas 
3952159047fSniklas 		    case 'b':
3962159047fSniklas 		      (*info->print_address_func)
3972159047fSniklas 			(BDISP (given) * 4 + pc + 8, info);
3982159047fSniklas 		      break;
3992159047fSniklas 
4002159047fSniklas 		    case 'c':
4012159047fSniklas 		      func (stream, "%s",
4022159047fSniklas 			    arm_conditional [(given >> 28) & 0xf]);
4032159047fSniklas 		      break;
4042159047fSniklas 
4052159047fSniklas 		    case 'm':
4062159047fSniklas 		      {
4072159047fSniklas 			int started = 0;
4082159047fSniklas 			int reg;
4092159047fSniklas 
4102159047fSniklas 			func (stream, "{");
4112159047fSniklas 			for (reg = 0; reg < 16; reg++)
4122159047fSniklas 			  if ((given & (1 << reg)) != 0)
4132159047fSniklas 			    {
4142159047fSniklas 			      if (started)
4152159047fSniklas 				func (stream, ", ");
4162159047fSniklas 			      started = 1;
4172159047fSniklas 			      func (stream, "%s", arm_regnames[reg]);
4182159047fSniklas 			    }
4192159047fSniklas 			func (stream, "}");
4202159047fSniklas 		      }
4212159047fSniklas 		      break;
4222159047fSniklas 
4232159047fSniklas 		    case 'o':
4242159047fSniklas 		      if ((given & 0x02000000) != 0)
4252159047fSniklas 			{
4262159047fSniklas 			  int rotate = (given & 0xf00) >> 7;
4272159047fSniklas 			  int immed = (given & 0xff);
428b305b0f1Sespie 			  immed = (((immed << (32 - rotate))
4292159047fSniklas 				    | (immed >> rotate)) & 0xffffffff);
430b305b0f1Sespie 			  func (stream, "#%d\t; 0x%x", immed, immed);
4312159047fSniklas 			}
4322159047fSniklas 		      else
4332159047fSniklas 			arm_decode_shift (given, func, stream);
4342159047fSniklas 		      break;
4352159047fSniklas 
4362159047fSniklas 		    case 'p':
4372159047fSniklas 		      if ((given & 0x0000f000) == 0x0000f000)
4382159047fSniklas 			func (stream, "p");
4392159047fSniklas 		      break;
4402159047fSniklas 
4412159047fSniklas 		    case 't':
4422159047fSniklas 		      if ((given & 0x01200000) == 0x00200000)
4432159047fSniklas 			func (stream, "t");
4442159047fSniklas 		      break;
4452159047fSniklas 
4462159047fSniklas 		    case 'A':
4472159047fSniklas 		      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
448*007c2a45Smiod 
449*007c2a45Smiod 		      if ((given & (1 << 24)) != 0)
4502159047fSniklas 			{
4512159047fSniklas 			  int offset = given & 0xff;
452*007c2a45Smiod 
4532159047fSniklas 			  if (offset)
454*007c2a45Smiod 			    func (stream, ", #%s%d]%s",
4552159047fSniklas 				  ((given & 0x00800000) == 0 ? "-" : ""),
4562159047fSniklas 				  offset * 4,
4572159047fSniklas 				  ((given & 0x00200000) != 0 ? "!" : ""));
4582159047fSniklas 			  else
4592159047fSniklas 			    func (stream, "]");
4602159047fSniklas 			}
4612159047fSniklas 		      else
4622159047fSniklas 			{
4632159047fSniklas 			  int offset = given & 0xff;
464*007c2a45Smiod 
465*007c2a45Smiod 			  func (stream, "]");
466*007c2a45Smiod 
467*007c2a45Smiod 			  if (given & (1 << 21))
468*007c2a45Smiod 			    {
4692159047fSniklas 			      if (offset)
470*007c2a45Smiod 				func (stream, ", #%s%d",
4712159047fSniklas 				      ((given & 0x00800000) == 0 ? "-" : ""),
4722159047fSniklas 				      offset * 4);
473*007c2a45Smiod 			    }
4742159047fSniklas 			  else
475*007c2a45Smiod 			    func (stream, ", {%d}", offset);
4762159047fSniklas 			}
4772159047fSniklas 		      break;
4782159047fSniklas 
479b55d4692Sfgsch 		    case 'B':
480b55d4692Sfgsch 		      /* Print ARM V5 BLX(1) address: pc+25 bits.  */
4812159047fSniklas 		      {
482b55d4692Sfgsch 			bfd_vma address;
483b55d4692Sfgsch 			bfd_vma offset = 0;
484b55d4692Sfgsch 
485b55d4692Sfgsch 			if (given & 0x00800000)
486b55d4692Sfgsch 			  /* Is signed, hi bits should be ones.  */
487b55d4692Sfgsch 			  offset = (-1) ^ 0x00ffffff;
488b55d4692Sfgsch 
489b55d4692Sfgsch 			/* Offset is (SignExtend(offset field)<<2).  */
490b55d4692Sfgsch 			offset += given & 0x00ffffff;
491b55d4692Sfgsch 			offset <<= 2;
492b55d4692Sfgsch 			address = offset + pc + 8;
493b55d4692Sfgsch 
494b55d4692Sfgsch 			if (given & 0x01000000)
495b55d4692Sfgsch 			  /* H bit allows addressing to 2-byte boundaries.  */
496b55d4692Sfgsch 			  address += 2;
497b55d4692Sfgsch 
498b55d4692Sfgsch 		        info->print_address_func (address, info);
4992159047fSniklas 		      }
5002159047fSniklas 		      break;
5012159047fSniklas 
502c074d1c9Sdrahn 		    case 'I':
503c074d1c9Sdrahn 		      /* Print a Cirrus/DSP shift immediate.  */
504c074d1c9Sdrahn 		      /* Immediates are 7bit signed ints with bits 0..3 in
505c074d1c9Sdrahn 			 bits 0..3 of opcode and bits 4..6 in bits 5..7
506c074d1c9Sdrahn 			 of opcode.  */
507c074d1c9Sdrahn 		      {
508c074d1c9Sdrahn 			int imm;
509c074d1c9Sdrahn 
510c074d1c9Sdrahn 			imm = (given & 0xf) | ((given & 0xe0) >> 1);
511c074d1c9Sdrahn 
512c074d1c9Sdrahn 			/* Is ``imm'' a negative number?  */
513c074d1c9Sdrahn 			if (imm & 0x40)
514c074d1c9Sdrahn 			  imm |= (-1 << 7);
515c074d1c9Sdrahn 
516c074d1c9Sdrahn 			func (stream, "%d", imm);
517c074d1c9Sdrahn 		      }
518c074d1c9Sdrahn 
519c074d1c9Sdrahn 		      break;
520c074d1c9Sdrahn 
521b55d4692Sfgsch 		    case 'C':
522b55d4692Sfgsch 		      func (stream, "_");
523b55d4692Sfgsch 		      if (given & 0x80000)
524b55d4692Sfgsch 			func (stream, "f");
525b55d4692Sfgsch 		      if (given & 0x40000)
526b55d4692Sfgsch 			func (stream, "s");
527b55d4692Sfgsch 		      if (given & 0x20000)
528b55d4692Sfgsch 			func (stream, "x");
529b55d4692Sfgsch 		      if (given & 0x10000)
530b55d4692Sfgsch 			func (stream, "c");
531b55d4692Sfgsch 		      break;
532b55d4692Sfgsch 
5332159047fSniklas 		    case 'F':
5342159047fSniklas 		      switch (given & 0x00408000)
5352159047fSniklas 			{
5362159047fSniklas 			case 0:
5372159047fSniklas 			  func (stream, "4");
5382159047fSniklas 			  break;
5392159047fSniklas 			case 0x8000:
5402159047fSniklas 			  func (stream, "1");
5412159047fSniklas 			  break;
5422159047fSniklas 			case 0x00400000:
5432159047fSniklas 			  func (stream, "2");
5442159047fSniklas 			  break;
5452159047fSniklas 			default:
5462159047fSniklas 			  func (stream, "3");
5472159047fSniklas 			}
5482159047fSniklas 		      break;
5492159047fSniklas 
5502159047fSniklas 		    case 'P':
5512159047fSniklas 		      switch (given & 0x00080080)
5522159047fSniklas 			{
5532159047fSniklas 			case 0:
5542159047fSniklas 			  func (stream, "s");
5552159047fSniklas 			  break;
5562159047fSniklas 			case 0x80:
5572159047fSniklas 			  func (stream, "d");
5582159047fSniklas 			  break;
5592159047fSniklas 			case 0x00080000:
5602159047fSniklas 			  func (stream, "e");
5612159047fSniklas 			  break;
5622159047fSniklas 			default:
563b305b0f1Sespie 			  func (stream, _("<illegal precision>"));
5642159047fSniklas 			  break;
5652159047fSniklas 			}
5662159047fSniklas 		      break;
5672159047fSniklas 		    case 'Q':
5682159047fSniklas 		      switch (given & 0x00408000)
5692159047fSniklas 			{
5702159047fSniklas 			case 0:
5712159047fSniklas 			  func (stream, "s");
5722159047fSniklas 			  break;
5732159047fSniklas 			case 0x8000:
5742159047fSniklas 			  func (stream, "d");
5752159047fSniklas 			  break;
5762159047fSniklas 			case 0x00400000:
5772159047fSniklas 			  func (stream, "e");
5782159047fSniklas 			  break;
5792159047fSniklas 			default:
5802159047fSniklas 			  func (stream, "p");
5812159047fSniklas 			  break;
5822159047fSniklas 			}
5832159047fSniklas 		      break;
5842159047fSniklas 		    case 'R':
5852159047fSniklas 		      switch (given & 0x60)
5862159047fSniklas 			{
5872159047fSniklas 			case 0:
5882159047fSniklas 			  break;
5892159047fSniklas 			case 0x20:
5902159047fSniklas 			  func (stream, "p");
5912159047fSniklas 			  break;
5922159047fSniklas 			case 0x40:
5932159047fSniklas 			  func (stream, "m");
5942159047fSniklas 			  break;
5952159047fSniklas 			default:
5962159047fSniklas 			  func (stream, "z");
5972159047fSniklas 			  break;
5982159047fSniklas 			}
5992159047fSniklas 		      break;
6002159047fSniklas 
6012159047fSniklas 		    case '0': case '1': case '2': case '3': case '4':
6022159047fSniklas 		    case '5': case '6': case '7': case '8': case '9':
6032159047fSniklas 		      {
6042159047fSniklas 			int bitstart = *c++ - '0';
6052159047fSniklas 			int bitend = 0;
6062159047fSniklas 			while (*c >= '0' && *c <= '9')
6072159047fSniklas 			  bitstart = (bitstart * 10) + *c++ - '0';
6082159047fSniklas 
6092159047fSniklas 			switch (*c)
6102159047fSniklas 			  {
6112159047fSniklas 			  case '-':
6122159047fSniklas 			    c++;
613b305b0f1Sespie 
6142159047fSniklas 			    while (*c >= '0' && *c <= '9')
6152159047fSniklas 			      bitend = (bitend * 10) + *c++ - '0';
616b305b0f1Sespie 
6172159047fSniklas 			    if (!bitend)
6182159047fSniklas 			      abort ();
619b305b0f1Sespie 
6202159047fSniklas 			    switch (*c)
6212159047fSniklas 			      {
6222159047fSniklas 			      case 'r':
6232159047fSniklas 				{
6242159047fSniklas 				  long reg;
625b305b0f1Sespie 
6262159047fSniklas 				  reg = given >> bitstart;
6272159047fSniklas 				  reg &= (2 << (bitend - bitstart)) - 1;
628b305b0f1Sespie 
6292159047fSniklas 				  func (stream, "%s", arm_regnames[reg]);
6302159047fSniklas 				}
6312159047fSniklas 				break;
6322159047fSniklas 			      case 'd':
6332159047fSniklas 				{
6342159047fSniklas 				  long reg;
635b305b0f1Sespie 
6362159047fSniklas 				  reg = given >> bitstart;
6372159047fSniklas 				  reg &= (2 << (bitend - bitstart)) - 1;
638b305b0f1Sespie 
6392159047fSniklas 				  func (stream, "%d", reg);
6402159047fSniklas 				}
6412159047fSniklas 				break;
642*007c2a45Smiod 			      case 'W':
643*007c2a45Smiod 				{
644*007c2a45Smiod 				  long reg;
645*007c2a45Smiod 
646*007c2a45Smiod 				  reg = given >> bitstart;
647*007c2a45Smiod 				  reg &= (2 << (bitend - bitstart)) - 1;
648*007c2a45Smiod 
649*007c2a45Smiod 				  func (stream, "%d", reg + 1);
650*007c2a45Smiod 				}
651*007c2a45Smiod 				break;
6522159047fSniklas 			      case 'x':
6532159047fSniklas 				{
6542159047fSniklas 				  long reg;
655b305b0f1Sespie 
6562159047fSniklas 				  reg = given >> bitstart;
6572159047fSniklas 				  reg &= (2 << (bitend - bitstart)) - 1;
658b305b0f1Sespie 
6592159047fSniklas 				  func (stream, "0x%08x", reg);
660b305b0f1Sespie 
661b305b0f1Sespie 				  /* Some SWI instructions have special
662b305b0f1Sespie 				     meanings.  */
663b305b0f1Sespie 				  if ((given & 0x0fffffff) == 0x0FF00000)
664b305b0f1Sespie 				    func (stream, "\t; IMB");
665b305b0f1Sespie 				  else if ((given & 0x0fffffff) == 0x0FF00001)
666b305b0f1Sespie 				    func (stream, "\t; IMBRange");
667b305b0f1Sespie 				}
668b305b0f1Sespie 				break;
669b305b0f1Sespie 			      case 'X':
670b305b0f1Sespie 				{
671b305b0f1Sespie 				  long reg;
672b305b0f1Sespie 
673b305b0f1Sespie 				  reg = given >> bitstart;
674b305b0f1Sespie 				  reg &= (2 << (bitend - bitstart)) - 1;
675b305b0f1Sespie 
676b305b0f1Sespie 				  func (stream, "%01x", reg & 0xf);
6772159047fSniklas 				}
6782159047fSniklas 				break;
6792159047fSniklas 			      case 'f':
6802159047fSniklas 				{
6812159047fSniklas 				  long reg;
682b305b0f1Sespie 
6832159047fSniklas 				  reg = given >> bitstart;
6842159047fSniklas 				  reg &= (2 << (bitend - bitstart)) - 1;
685b305b0f1Sespie 
6862159047fSniklas 				  if (reg > 7)
6872159047fSniklas 				    func (stream, "#%s",
6882159047fSniklas 					  arm_fp_const[reg & 7]);
6892159047fSniklas 				  else
6902159047fSniklas 				    func (stream, "f%d", reg);
6912159047fSniklas 				}
6922159047fSniklas 				break;
693c074d1c9Sdrahn 
694c074d1c9Sdrahn 			      case 'w':
695c074d1c9Sdrahn 				{
696c074d1c9Sdrahn 				  long reg;
697c074d1c9Sdrahn 
698c074d1c9Sdrahn 				  if (bitstart != bitend)
699c074d1c9Sdrahn 				    {
700c074d1c9Sdrahn 				      reg = given >> bitstart;
701c074d1c9Sdrahn 				      reg &= (2 << (bitend - bitstart)) - 1;
702c074d1c9Sdrahn 				      if (bitend - bitstart == 1)
703c074d1c9Sdrahn 					func (stream, "%s", iwmmxt_wwnames[reg]);
704c074d1c9Sdrahn 				      else
705c074d1c9Sdrahn 					func (stream, "%s", iwmmxt_wwssnames[reg]);
706c074d1c9Sdrahn 				    }
707c074d1c9Sdrahn 				  else
708c074d1c9Sdrahn 				    {
709c074d1c9Sdrahn 				      reg = (((given >> 8)  & 0x1) |
710c074d1c9Sdrahn 					     ((given >> 22) & 0x1));
711c074d1c9Sdrahn 				      func (stream, "%s", iwmmxt_wwnames[reg]);
712c074d1c9Sdrahn 				    }
713c074d1c9Sdrahn 				}
714c074d1c9Sdrahn 				break;
715c074d1c9Sdrahn 
716c074d1c9Sdrahn 			      case 'g':
717c074d1c9Sdrahn 				{
718c074d1c9Sdrahn 				  long reg;
719c074d1c9Sdrahn 				  int current_regnames;
720c074d1c9Sdrahn 
721c074d1c9Sdrahn 				  if (! iwmmxt_regnames)
722c074d1c9Sdrahn 				    iwmmxt_regnames = set_iwmmxt_regnames ();
723c074d1c9Sdrahn 				  current_regnames = set_arm_regname_option
724c074d1c9Sdrahn 				    (iwmmxt_regnames);
725c074d1c9Sdrahn 
726c074d1c9Sdrahn 				  reg = given >> bitstart;
727c074d1c9Sdrahn 				  reg &= (2 << (bitend - bitstart)) - 1;
728c074d1c9Sdrahn 				  func (stream, "%s", arm_regnames[reg]);
729c074d1c9Sdrahn 				  set_arm_regname_option (current_regnames);
730c074d1c9Sdrahn 				}
731c074d1c9Sdrahn 				break;
732c074d1c9Sdrahn 
733c074d1c9Sdrahn 			      case 'G':
734c074d1c9Sdrahn 				{
735c074d1c9Sdrahn 				  long reg;
736c074d1c9Sdrahn 				  int current_regnames;
737c074d1c9Sdrahn 
738c074d1c9Sdrahn 				  if (! iwmmxt_regnames)
739c074d1c9Sdrahn 				    iwmmxt_regnames = set_iwmmxt_regnames ();
740c074d1c9Sdrahn 				  current_regnames = set_arm_regname_option
741c074d1c9Sdrahn 				    (iwmmxt_regnames + 1);
742c074d1c9Sdrahn 
743c074d1c9Sdrahn 				  reg = given >> bitstart;
744c074d1c9Sdrahn 				  reg &= (2 << (bitend - bitstart)) - 1;
745c074d1c9Sdrahn 				  func (stream, "%s", arm_regnames[reg]);
746c074d1c9Sdrahn 				  set_arm_regname_option (current_regnames);
747c074d1c9Sdrahn 				}
748c074d1c9Sdrahn 				break;
749c074d1c9Sdrahn 
7502159047fSniklas 			      default:
7512159047fSniklas 				abort ();
7522159047fSniklas 			      }
7532159047fSniklas 			    break;
754b305b0f1Sespie 
755c074d1c9Sdrahn 			  case 'y':
756c074d1c9Sdrahn 			  case 'z':
757c074d1c9Sdrahn 			    {
758c074d1c9Sdrahn 			      int single = *c == 'y';
759c074d1c9Sdrahn 			      int regno;
760c074d1c9Sdrahn 
761c074d1c9Sdrahn 			      switch (bitstart)
762c074d1c9Sdrahn 				{
763c074d1c9Sdrahn 				case 4: /* Sm pair */
764c074d1c9Sdrahn 				  func (stream, "{");
765c074d1c9Sdrahn 				  /* Fall through.  */
766c074d1c9Sdrahn 				case 0: /* Sm, Dm */
767c074d1c9Sdrahn 				  regno = given & 0x0000000f;
768c074d1c9Sdrahn 				  if (single)
769c074d1c9Sdrahn 				    {
770c074d1c9Sdrahn 				      regno <<= 1;
771c074d1c9Sdrahn 				      regno += (given >> 5) & 1;
772c074d1c9Sdrahn 				    }
773c074d1c9Sdrahn 				  break;
774c074d1c9Sdrahn 
775c074d1c9Sdrahn 				case 1: /* Sd, Dd */
776c074d1c9Sdrahn 				  regno = (given >> 12) & 0x0000000f;
777c074d1c9Sdrahn 				  if (single)
778c074d1c9Sdrahn 				    {
779c074d1c9Sdrahn 				      regno <<= 1;
780c074d1c9Sdrahn 				      regno += (given >> 22) & 1;
781c074d1c9Sdrahn 				    }
782c074d1c9Sdrahn 				  break;
783c074d1c9Sdrahn 
784c074d1c9Sdrahn 				case 2: /* Sn, Dn */
785c074d1c9Sdrahn 				  regno = (given >> 16) & 0x0000000f;
786c074d1c9Sdrahn 				  if (single)
787c074d1c9Sdrahn 				    {
788c074d1c9Sdrahn 				      regno <<= 1;
789c074d1c9Sdrahn 				      regno += (given >> 7) & 1;
790c074d1c9Sdrahn 				    }
791c074d1c9Sdrahn 				  break;
792c074d1c9Sdrahn 
793c074d1c9Sdrahn 				case 3: /* List */
794c074d1c9Sdrahn 				  func (stream, "{");
795c074d1c9Sdrahn 				  regno = (given >> 12) & 0x0000000f;
796c074d1c9Sdrahn 				  if (single)
797c074d1c9Sdrahn 				    {
798c074d1c9Sdrahn 				      regno <<= 1;
799c074d1c9Sdrahn 				      regno += (given >> 22) & 1;
800c074d1c9Sdrahn 				    }
801c074d1c9Sdrahn 				  break;
802c074d1c9Sdrahn 
803c074d1c9Sdrahn 
804c074d1c9Sdrahn 				default:
805c074d1c9Sdrahn 				  abort ();
806c074d1c9Sdrahn 				}
807c074d1c9Sdrahn 
808c074d1c9Sdrahn 			      func (stream, "%c%d", single ? 's' : 'd', regno);
809c074d1c9Sdrahn 
810c074d1c9Sdrahn 			      if (bitstart == 3)
811c074d1c9Sdrahn 				{
812c074d1c9Sdrahn 				  int count = given & 0xff;
813c074d1c9Sdrahn 
814c074d1c9Sdrahn 				  if (single == 0)
815c074d1c9Sdrahn 				    count >>= 1;
816c074d1c9Sdrahn 
817c074d1c9Sdrahn 				  if (--count)
818c074d1c9Sdrahn 				    {
819c074d1c9Sdrahn 				      func (stream, "-%c%d",
820c074d1c9Sdrahn 					    single ? 's' : 'd',
821c074d1c9Sdrahn 					    regno + count);
822c074d1c9Sdrahn 				    }
823c074d1c9Sdrahn 
824c074d1c9Sdrahn 				  func (stream, "}");
825c074d1c9Sdrahn 				}
826c074d1c9Sdrahn 			      else if (bitstart == 4)
827c074d1c9Sdrahn 				func (stream, ", %c%d}", single ? 's' : 'd',
828c074d1c9Sdrahn 				      regno + 1);
829c074d1c9Sdrahn 
830c074d1c9Sdrahn 			      break;
831c074d1c9Sdrahn 			    }
832c074d1c9Sdrahn 
8332159047fSniklas 			  case '`':
8342159047fSniklas 			    c++;
8352159047fSniklas 			    if ((given & (1 << bitstart)) == 0)
8362159047fSniklas 			      func (stream, "%c", *c);
8372159047fSniklas 			    break;
8382159047fSniklas 			  case '\'':
8392159047fSniklas 			    c++;
8402159047fSniklas 			    if ((given & (1 << bitstart)) != 0)
8412159047fSniklas 			      func (stream, "%c", *c);
8422159047fSniklas 			    break;
8432159047fSniklas 			  case '?':
8442159047fSniklas 			    ++c;
8452159047fSniklas 			    if ((given & (1 << bitstart)) != 0)
8462159047fSniklas 			      func (stream, "%c", *c++);
8472159047fSniklas 			    else
8482159047fSniklas 			      func (stream, "%c", *++c);
8492159047fSniklas 			    break;
8502159047fSniklas 			  default:
8512159047fSniklas 			    abort ();
8522159047fSniklas 			  }
8532159047fSniklas 			break;
8542159047fSniklas 
855c074d1c9Sdrahn 		      case 'L':
856c074d1c9Sdrahn 			switch (given & 0x00400100)
857c074d1c9Sdrahn 			  {
858c074d1c9Sdrahn 			  case 0x00000000: func (stream, "b"); break;
859c074d1c9Sdrahn 			  case 0x00400000: func (stream, "h"); break;
860c074d1c9Sdrahn 			  case 0x00000100: func (stream, "w"); break;
861c074d1c9Sdrahn 			  case 0x00400100: func (stream, "d"); break;
862c074d1c9Sdrahn 			  default:
863c074d1c9Sdrahn 			    break;
864c074d1c9Sdrahn 			  }
865c074d1c9Sdrahn 			break;
866c074d1c9Sdrahn 
867c074d1c9Sdrahn 		      case 'Z':
868c074d1c9Sdrahn 			{
869c074d1c9Sdrahn 			  int value;
870c074d1c9Sdrahn 			  /* given (20, 23) | given (0, 3) */
871c074d1c9Sdrahn 			  value = ((given >> 16) & 0xf0) | (given & 0xf);
872c074d1c9Sdrahn 			  func (stream, "%d", value);
873c074d1c9Sdrahn 			}
874c074d1c9Sdrahn 			break;
875c074d1c9Sdrahn 
876c074d1c9Sdrahn 		      case 'l':
877c074d1c9Sdrahn 			/* This is like the 'A' operator, except that if
878c074d1c9Sdrahn 			   the width field "M" is zero, then the offset is
879c074d1c9Sdrahn 			   *not* multiplied by four.  */
880c074d1c9Sdrahn 			{
881c074d1c9Sdrahn 			  int offset = given & 0xff;
882c074d1c9Sdrahn 			  int multiplier = (given & 0x00000100) ? 4 : 1;
883c074d1c9Sdrahn 
884c074d1c9Sdrahn 			  func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
885c074d1c9Sdrahn 
886c074d1c9Sdrahn 			  if (offset)
887c074d1c9Sdrahn 			    {
888c074d1c9Sdrahn 			      if ((given & 0x01000000) != 0)
889*007c2a45Smiod 				func (stream, ", #%s%d]%s",
890c074d1c9Sdrahn 				      ((given & 0x00800000) == 0 ? "-" : ""),
891c074d1c9Sdrahn 				      offset * multiplier,
892c074d1c9Sdrahn 				      ((given & 0x00200000) != 0 ? "!" : ""));
893c074d1c9Sdrahn 			      else
894*007c2a45Smiod 				func (stream, "], #%s%d",
895c074d1c9Sdrahn 				      ((given & 0x00800000) == 0 ? "-" : ""),
896c074d1c9Sdrahn 				      offset * multiplier);
897c074d1c9Sdrahn 			    }
898c074d1c9Sdrahn 			  else
899c074d1c9Sdrahn 			    func (stream, "]");
900c074d1c9Sdrahn 			}
901c074d1c9Sdrahn 			break;
902c074d1c9Sdrahn 
9032159047fSniklas 		      default:
9042159047fSniklas 			abort ();
9052159047fSniklas 		      }
9062159047fSniklas 		    }
9072159047fSniklas 		}
9082159047fSniklas 	      else
9092159047fSniklas 		func (stream, "%c", *c);
9102159047fSniklas 	    }
9112159047fSniklas 	  return 4;
9122159047fSniklas 	}
9132159047fSniklas     }
9142159047fSniklas   abort ();
9152159047fSniklas }
9162159047fSniklas 
917b305b0f1Sespie /* Print one instruction from PC on INFO->STREAM.
918b305b0f1Sespie    Return the size of the instruction. */
919c074d1c9Sdrahn 
920b305b0f1Sespie static int
print_insn_thumb(pc,info,given)921b305b0f1Sespie print_insn_thumb (pc, info, given)
922b305b0f1Sespie      bfd_vma pc;
923b305b0f1Sespie      struct disassemble_info *info;
924b305b0f1Sespie      long given;
925b305b0f1Sespie {
926c074d1c9Sdrahn   const struct thumb_opcode *insn;
927b305b0f1Sespie   void *stream = info->stream;
928b305b0f1Sespie   fprintf_ftype func = info->fprintf_func;
929b305b0f1Sespie 
930b305b0f1Sespie   for (insn = thumb_opcodes; insn->assembler; insn++)
931b305b0f1Sespie     {
932b305b0f1Sespie       if ((given & insn->mask) == insn->value)
933b305b0f1Sespie         {
934b305b0f1Sespie           char * c = insn->assembler;
935b305b0f1Sespie 
936b305b0f1Sespie           /* Special processing for Thumb 2 instruction BL sequence:  */
937b305b0f1Sespie           if (!*c) /* Check for empty (not NULL) assembler string.  */
938b305b0f1Sespie             {
939c074d1c9Sdrahn 	      long offset;
940c074d1c9Sdrahn 
941b305b0f1Sespie 	      info->bytes_per_chunk = 4;
942b305b0f1Sespie 	      info->bytes_per_line  = 4;
943b305b0f1Sespie 
944c074d1c9Sdrahn 	      offset = BDISP23 (given);
945c074d1c9Sdrahn 	      offset = offset * 2 + pc + 4;
946c074d1c9Sdrahn 
947b55d4692Sfgsch 	      if ((given & 0x10000000) == 0)
948c074d1c9Sdrahn 		{
949b55d4692Sfgsch 		  func (stream, "blx\t");
950c074d1c9Sdrahn 		  offset &= 0xfffffffc;
951c074d1c9Sdrahn 		}
952b55d4692Sfgsch 	      else
953b305b0f1Sespie 		func (stream, "bl\t");
954b305b0f1Sespie 
955c074d1c9Sdrahn 	      info->print_address_func (offset, info);
956b305b0f1Sespie               return 4;
957b305b0f1Sespie             }
958b305b0f1Sespie           else
959b305b0f1Sespie             {
960b305b0f1Sespie 	      info->bytes_per_chunk = 2;
961b305b0f1Sespie 	      info->bytes_per_line  = 4;
962b305b0f1Sespie 
963b305b0f1Sespie               given &= 0xffff;
964b305b0f1Sespie 
965b305b0f1Sespie               for (; *c; c++)
966b305b0f1Sespie                 {
967b305b0f1Sespie                   if (*c == '%')
968b305b0f1Sespie                     {
969b305b0f1Sespie                       int domaskpc = 0;
970b305b0f1Sespie                       int domasklr = 0;
971b305b0f1Sespie 
972b305b0f1Sespie                       switch (*++c)
973b305b0f1Sespie                         {
974b305b0f1Sespie                         case '%':
975b305b0f1Sespie                           func (stream, "%%");
976b305b0f1Sespie                           break;
977b305b0f1Sespie 
978b305b0f1Sespie                         case 'S':
979b305b0f1Sespie                           {
980b305b0f1Sespie                             long reg;
981b305b0f1Sespie 
982b305b0f1Sespie                             reg = (given >> 3) & 0x7;
983b305b0f1Sespie                             if (given & (1 << 6))
984b305b0f1Sespie                               reg += 8;
985b305b0f1Sespie 
986b305b0f1Sespie                             func (stream, "%s", arm_regnames[reg]);
987b305b0f1Sespie                           }
988b305b0f1Sespie                           break;
989b305b0f1Sespie 
990b305b0f1Sespie                         case 'D':
991b305b0f1Sespie                           {
992b305b0f1Sespie                             long reg;
993b305b0f1Sespie 
994b305b0f1Sespie                             reg = given & 0x7;
995b305b0f1Sespie                             if (given & (1 << 7))
996b305b0f1Sespie                              reg += 8;
997b305b0f1Sespie 
998b305b0f1Sespie                             func (stream, "%s", arm_regnames[reg]);
999b305b0f1Sespie                           }
1000b305b0f1Sespie                           break;
1001b305b0f1Sespie 
1002b305b0f1Sespie                         case 'T':
1003b305b0f1Sespie                           func (stream, "%s",
1004b305b0f1Sespie                                 arm_conditional [(given >> 8) & 0xf]);
1005b305b0f1Sespie                           break;
1006b305b0f1Sespie 
1007b305b0f1Sespie                         case 'N':
1008b305b0f1Sespie                           if (given & (1 << 8))
1009b305b0f1Sespie                             domasklr = 1;
1010b305b0f1Sespie                           /* Fall through.  */
1011b305b0f1Sespie                         case 'O':
1012b305b0f1Sespie                           if (*c == 'O' && (given & (1 << 8)))
1013b305b0f1Sespie                             domaskpc = 1;
1014b305b0f1Sespie                           /* Fall through.  */
1015b305b0f1Sespie                         case 'M':
1016b305b0f1Sespie                           {
1017b305b0f1Sespie                             int started = 0;
1018b305b0f1Sespie                             int reg;
1019b305b0f1Sespie 
1020b305b0f1Sespie                             func (stream, "{");
1021b305b0f1Sespie 
1022b305b0f1Sespie                             /* It would be nice if we could spot
1023b305b0f1Sespie                                ranges, and generate the rS-rE format: */
1024b305b0f1Sespie                             for (reg = 0; (reg < 8); reg++)
1025b305b0f1Sespie                               if ((given & (1 << reg)) != 0)
1026b305b0f1Sespie                                 {
1027b305b0f1Sespie                                   if (started)
1028b305b0f1Sespie                                     func (stream, ", ");
1029b305b0f1Sespie                                   started = 1;
1030b305b0f1Sespie                                   func (stream, "%s", arm_regnames[reg]);
1031b305b0f1Sespie                                 }
1032b305b0f1Sespie 
1033b305b0f1Sespie                             if (domasklr)
1034b305b0f1Sespie                               {
1035b305b0f1Sespie                                 if (started)
1036b305b0f1Sespie                                   func (stream, ", ");
1037b305b0f1Sespie                                 started = 1;
1038b305b0f1Sespie                                 func (stream, arm_regnames[14] /* "lr" */);
1039b305b0f1Sespie                               }
1040b305b0f1Sespie 
1041b305b0f1Sespie                             if (domaskpc)
1042b305b0f1Sespie                               {
1043b305b0f1Sespie                                 if (started)
1044b305b0f1Sespie                                   func (stream, ", ");
1045b305b0f1Sespie                                 func (stream, arm_regnames[15] /* "pc" */);
1046b305b0f1Sespie                               }
1047b305b0f1Sespie 
1048b305b0f1Sespie                             func (stream, "}");
1049b305b0f1Sespie                           }
1050b305b0f1Sespie                           break;
1051b305b0f1Sespie 
1052b305b0f1Sespie 
1053b305b0f1Sespie                         case '0': case '1': case '2': case '3': case '4':
1054b305b0f1Sespie                         case '5': case '6': case '7': case '8': case '9':
1055b305b0f1Sespie                           {
1056b305b0f1Sespie                             int bitstart = *c++ - '0';
1057b305b0f1Sespie                             int bitend = 0;
1058b305b0f1Sespie 
1059b305b0f1Sespie                             while (*c >= '0' && *c <= '9')
1060b305b0f1Sespie                               bitstart = (bitstart * 10) + *c++ - '0';
1061b305b0f1Sespie 
1062b305b0f1Sespie                             switch (*c)
1063b305b0f1Sespie                               {
1064b305b0f1Sespie                               case '-':
1065b305b0f1Sespie                                 {
1066b305b0f1Sespie                                   long reg;
1067b305b0f1Sespie 
1068b305b0f1Sespie                                   c++;
1069b305b0f1Sespie                                   while (*c >= '0' && *c <= '9')
1070b305b0f1Sespie                                     bitend = (bitend * 10) + *c++ - '0';
1071b305b0f1Sespie                                   if (!bitend)
1072b305b0f1Sespie                                     abort ();
1073b305b0f1Sespie                                   reg = given >> bitstart;
1074b305b0f1Sespie                                   reg &= (2 << (bitend - bitstart)) - 1;
1075b305b0f1Sespie                                   switch (*c)
1076b305b0f1Sespie                                     {
1077b305b0f1Sespie                                     case 'r':
1078b305b0f1Sespie                                       func (stream, "%s", arm_regnames[reg]);
1079b305b0f1Sespie                                       break;
1080b305b0f1Sespie 
1081b305b0f1Sespie                                     case 'd':
1082b305b0f1Sespie                                       func (stream, "%d", reg);
1083b305b0f1Sespie                                       break;
1084b305b0f1Sespie 
1085b305b0f1Sespie                                     case 'H':
1086b305b0f1Sespie                                       func (stream, "%d", reg << 1);
1087b305b0f1Sespie                                       break;
1088b305b0f1Sespie 
1089b305b0f1Sespie                                     case 'W':
1090b305b0f1Sespie                                       func (stream, "%d", reg << 2);
1091b305b0f1Sespie                                       break;
1092b305b0f1Sespie 
1093b305b0f1Sespie                                     case 'a':
1094b305b0f1Sespie 				      /* PC-relative address -- the bottom two
1095b305b0f1Sespie 					 bits of the address are dropped
1096b305b0f1Sespie 					 before the calculation.  */
1097b305b0f1Sespie                                       info->print_address_func
1098b305b0f1Sespie 					(((pc + 4) & ~3) + (reg << 2), info);
1099b305b0f1Sespie                                       break;
1100b305b0f1Sespie 
1101b305b0f1Sespie                                     case 'x':
1102b305b0f1Sespie                                       func (stream, "0x%04x", reg);
1103b305b0f1Sespie                                       break;
1104b305b0f1Sespie 
1105b305b0f1Sespie                                     case 'I':
1106b305b0f1Sespie                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1107b305b0f1Sespie                                       func (stream, "%d", reg);
1108b305b0f1Sespie                                       break;
1109b305b0f1Sespie 
1110b305b0f1Sespie                                     case 'B':
1111b305b0f1Sespie                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1112b305b0f1Sespie                                       (*info->print_address_func)
1113b305b0f1Sespie                                         (reg * 2 + pc + 4, info);
1114b305b0f1Sespie                                       break;
1115b305b0f1Sespie 
1116b305b0f1Sespie                                     default:
1117b305b0f1Sespie                                       abort ();
1118b305b0f1Sespie                                     }
1119b305b0f1Sespie                                 }
1120b305b0f1Sespie                                 break;
1121b305b0f1Sespie 
1122b305b0f1Sespie                               case '\'':
1123b305b0f1Sespie                                 c++;
1124b305b0f1Sespie                                 if ((given & (1 << bitstart)) != 0)
1125b305b0f1Sespie                                   func (stream, "%c", *c);
1126b305b0f1Sespie                                 break;
1127b305b0f1Sespie 
1128b305b0f1Sespie                               case '?':
1129b305b0f1Sespie                                 ++c;
1130b305b0f1Sespie                                 if ((given & (1 << bitstart)) != 0)
1131b305b0f1Sespie                                   func (stream, "%c", *c++);
1132b305b0f1Sespie                                 else
1133b305b0f1Sespie                                   func (stream, "%c", *++c);
1134b305b0f1Sespie                                 break;
1135b305b0f1Sespie 
1136b305b0f1Sespie                               default:
1137b305b0f1Sespie                                  abort ();
1138b305b0f1Sespie                               }
1139b305b0f1Sespie                           }
1140b305b0f1Sespie                           break;
1141b305b0f1Sespie 
1142b305b0f1Sespie                         default:
1143b305b0f1Sespie                           abort ();
1144b305b0f1Sespie                         }
1145b305b0f1Sespie                     }
1146b305b0f1Sespie                   else
1147b305b0f1Sespie                     func (stream, "%c", *c);
1148b305b0f1Sespie                 }
1149b305b0f1Sespie              }
1150b305b0f1Sespie           return 2;
1151b305b0f1Sespie        }
1152b305b0f1Sespie     }
1153b305b0f1Sespie 
1154b305b0f1Sespie   /* No match.  */
1155b305b0f1Sespie   abort ();
1156b305b0f1Sespie }
1157b305b0f1Sespie 
1158*007c2a45Smiod /* Disallow mapping symbols ($a, $b, $d, $t etc) from
1159*007c2a45Smiod    being displayed in symbol relative addresses.  */
1160*007c2a45Smiod 
1161*007c2a45Smiod bfd_boolean
arm_symbol_is_valid(asymbol * sym,struct disassemble_info * info ATTRIBUTE_UNUSED)1162*007c2a45Smiod arm_symbol_is_valid (asymbol * sym,
1163*007c2a45Smiod 		     struct disassemble_info * info ATTRIBUTE_UNUSED)
1164*007c2a45Smiod {
1165*007c2a45Smiod   const char * name;
1166*007c2a45Smiod 
1167*007c2a45Smiod   if (sym == NULL)
1168*007c2a45Smiod     return FALSE;
1169*007c2a45Smiod 
1170*007c2a45Smiod   name = bfd_asymbol_name (sym);
1171*007c2a45Smiod 
1172*007c2a45Smiod   return (name && *name != '$');
1173*007c2a45Smiod }
1174*007c2a45Smiod 
1175b305b0f1Sespie /* Parse an individual disassembler option.  */
1176c074d1c9Sdrahn 
1177b305b0f1Sespie void
parse_arm_disassembler_option(option)1178b305b0f1Sespie parse_arm_disassembler_option (option)
1179b305b0f1Sespie      char * option;
1180b305b0f1Sespie {
1181b305b0f1Sespie   if (option == NULL)
1182b305b0f1Sespie     return;
1183b305b0f1Sespie 
1184b305b0f1Sespie   if (strneq (option, "reg-names-", 10))
1185b305b0f1Sespie     {
1186b305b0f1Sespie       int i;
1187b305b0f1Sespie 
1188b305b0f1Sespie       option += 10;
1189b305b0f1Sespie 
1190b305b0f1Sespie       for (i = NUM_ARM_REGNAMES; i--;)
1191*007c2a45Smiod 	if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1192b305b0f1Sespie 	  {
1193b305b0f1Sespie 	    regname_selected = i;
1194b305b0f1Sespie 	    break;
1195b305b0f1Sespie 	  }
1196b305b0f1Sespie 
1197b305b0f1Sespie       if (i < 0)
1198*007c2a45Smiod 	/* XXX - should break 'option' at following delimiter.  */
1199b305b0f1Sespie 	fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1200b305b0f1Sespie     }
1201*007c2a45Smiod   else if (strneq (option, "force-thumb", 11))
1202b305b0f1Sespie     force_thumb = 1;
1203*007c2a45Smiod   else if (strneq (option, "no-force-thumb", 14))
1204b305b0f1Sespie     force_thumb = 0;
1205b305b0f1Sespie   else
1206*007c2a45Smiod     /* XXX - should break 'option' at following delimiter.  */
1207b305b0f1Sespie     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1208b305b0f1Sespie 
1209b305b0f1Sespie   return;
1210b305b0f1Sespie }
1211b305b0f1Sespie 
1212*007c2a45Smiod /* Parse the string of disassembler options, spliting it at whitespaces
1213*007c2a45Smiod    or commas.  (Whitespace separators supported for backwards compatibility).  */
1214c074d1c9Sdrahn 
1215b305b0f1Sespie static void
parse_disassembler_options(options)1216b305b0f1Sespie parse_disassembler_options (options)
1217b305b0f1Sespie      char * options;
1218b305b0f1Sespie {
1219b305b0f1Sespie   if (options == NULL)
1220b305b0f1Sespie     return;
1221b305b0f1Sespie 
1222*007c2a45Smiod   while (*options)
1223b305b0f1Sespie     {
1224*007c2a45Smiod       parse_arm_disassembler_option (options);
1225b305b0f1Sespie 
1226*007c2a45Smiod       /* Skip forward to next seperator.  */
1227*007c2a45Smiod       while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1228*007c2a45Smiod 	++ options;
1229*007c2a45Smiod       /* Skip forward past seperators.  */
1230*007c2a45Smiod       while (ISSPACE (*options) || (*options == ','))
1231*007c2a45Smiod 	++ options;
1232b305b0f1Sespie     }
1233b305b0f1Sespie }
1234b305b0f1Sespie 
1235b305b0f1Sespie /* NOTE: There are no checks in these routines that
1236b305b0f1Sespie    the relevant number of data bytes exist.  */
1237c074d1c9Sdrahn 
1238b305b0f1Sespie static int
print_insn(pc,info,little)1239b305b0f1Sespie print_insn (pc, info, little)
1240b305b0f1Sespie      bfd_vma pc;
1241b305b0f1Sespie      struct disassemble_info * info;
1242c074d1c9Sdrahn      bfd_boolean little;
1243b305b0f1Sespie {
1244b305b0f1Sespie   unsigned char      b[4];
1245b305b0f1Sespie   long               given;
1246b305b0f1Sespie   int                status;
1247b305b0f1Sespie   int                is_thumb;
1248b305b0f1Sespie 
1249b305b0f1Sespie   if (info->disassembler_options)
1250b305b0f1Sespie     {
1251b305b0f1Sespie       parse_disassembler_options (info->disassembler_options);
1252b305b0f1Sespie 
1253b305b0f1Sespie       /* To avoid repeated parsing of these options, we remove them here.  */
1254b305b0f1Sespie       info->disassembler_options = NULL;
1255b305b0f1Sespie     }
1256b305b0f1Sespie 
1257b305b0f1Sespie   is_thumb = force_thumb;
1258b305b0f1Sespie 
1259b305b0f1Sespie   if (!is_thumb && info->symbols != NULL)
1260b305b0f1Sespie     {
1261b305b0f1Sespie       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1262b305b0f1Sespie 	{
1263b305b0f1Sespie 	  coff_symbol_type * cs;
1264b305b0f1Sespie 
1265b305b0f1Sespie 	  cs = coffsymbol (*info->symbols);
1266b305b0f1Sespie 	  is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
1267b305b0f1Sespie 		      || cs->native->u.syment.n_sclass == C_THUMBSTAT
1268b305b0f1Sespie 		      || cs->native->u.syment.n_sclass == C_THUMBLABEL
1269b305b0f1Sespie 		      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1270b305b0f1Sespie 		      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1271b305b0f1Sespie 	}
1272b305b0f1Sespie       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1273b305b0f1Sespie 	{
1274b305b0f1Sespie 	  elf_symbol_type *  es;
1275b305b0f1Sespie 	  unsigned int       type;
1276b305b0f1Sespie 
1277b305b0f1Sespie 	  es = *(elf_symbol_type **)(info->symbols);
1278b305b0f1Sespie 	  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1279b305b0f1Sespie 
1280b305b0f1Sespie 	  is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1281b305b0f1Sespie 	}
1282b305b0f1Sespie     }
1283b305b0f1Sespie 
1284b305b0f1Sespie   info->bytes_per_chunk = 4;
1285b305b0f1Sespie   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1286b305b0f1Sespie 
1287b305b0f1Sespie   if (little)
1288b305b0f1Sespie     {
1289b305b0f1Sespie       status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1290b305b0f1Sespie       if (status != 0 && is_thumb)
1291b305b0f1Sespie 	{
1292b305b0f1Sespie 	  info->bytes_per_chunk = 2;
1293b305b0f1Sespie 
1294b305b0f1Sespie 	  status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1295b305b0f1Sespie 	  b[3] = b[2] = 0;
1296b305b0f1Sespie 	}
1297b305b0f1Sespie 
1298b305b0f1Sespie       if (status != 0)
1299b305b0f1Sespie 	{
1300b305b0f1Sespie 	  info->memory_error_func (status, pc, info);
1301b305b0f1Sespie 	  return -1;
1302b305b0f1Sespie 	}
1303b305b0f1Sespie 
1304b305b0f1Sespie       given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1305b305b0f1Sespie     }
1306b305b0f1Sespie   else
1307b305b0f1Sespie     {
1308b305b0f1Sespie       status = info->read_memory_func
1309b305b0f1Sespie 	(pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1310b305b0f1Sespie       if (status != 0)
1311b305b0f1Sespie 	{
1312b305b0f1Sespie 	  info->memory_error_func (status, pc, info);
1313b305b0f1Sespie 	  return -1;
1314b305b0f1Sespie 	}
1315b305b0f1Sespie 
1316b305b0f1Sespie       if (is_thumb)
1317b305b0f1Sespie 	{
1318b305b0f1Sespie 	  if (pc & 0x2)
1319b305b0f1Sespie 	    {
1320b305b0f1Sespie 	      given = (b[2] << 8) | b[3];
1321b305b0f1Sespie 
1322b305b0f1Sespie 	      status = info->read_memory_func
1323b305b0f1Sespie 		((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1324b305b0f1Sespie 	      if (status != 0)
1325b305b0f1Sespie 		{
1326b305b0f1Sespie 		  info->memory_error_func (status, pc + 4, info);
1327b305b0f1Sespie 		  return -1;
1328b305b0f1Sespie 		}
1329b305b0f1Sespie 
1330b305b0f1Sespie 	      given |= (b[0] << 24) | (b[1] << 16);
1331b305b0f1Sespie 	    }
1332b305b0f1Sespie 	  else
1333b305b0f1Sespie 	    given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1334b305b0f1Sespie 	}
1335b305b0f1Sespie       else
1336b305b0f1Sespie 	given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1337b305b0f1Sespie     }
1338b305b0f1Sespie 
1339b55d4692Sfgsch   if (info->flags & INSN_HAS_RELOC)
1340b55d4692Sfgsch     /* If the instruction has a reloc associated with it, then
1341b55d4692Sfgsch        the offset field in the instruction will actually be the
1342b55d4692Sfgsch        addend for the reloc.  (We are using REL type relocs).
1343b55d4692Sfgsch        In such cases, we can ignore the pc when computing
1344b55d4692Sfgsch        addresses, since the addend is not currently pc-relative.  */
1345b55d4692Sfgsch     pc = 0;
1346b55d4692Sfgsch 
1347b305b0f1Sespie   if (is_thumb)
1348b305b0f1Sespie     status = print_insn_thumb (pc, info, given);
1349b305b0f1Sespie   else
1350b305b0f1Sespie     status = print_insn_arm (pc, info, given);
1351b305b0f1Sespie 
1352b305b0f1Sespie   return status;
1353b305b0f1Sespie }
1354b305b0f1Sespie 
13552159047fSniklas int
print_insn_big_arm(pc,info)13562159047fSniklas print_insn_big_arm (pc, info)
13572159047fSniklas      bfd_vma pc;
13582159047fSniklas      struct disassemble_info * info;
13592159047fSniklas {
1360c074d1c9Sdrahn   return print_insn (pc, info, FALSE);
13612159047fSniklas }
13622159047fSniklas 
13632159047fSniklas int
print_insn_little_arm(pc,info)13642159047fSniklas print_insn_little_arm (pc, info)
13652159047fSniklas      bfd_vma pc;
13662159047fSniklas      struct disassemble_info * info;
13672159047fSniklas {
1368c074d1c9Sdrahn   return print_insn (pc, info, TRUE);
13692159047fSniklas }
13702159047fSniklas 
1371b305b0f1Sespie void
print_arm_disassembler_options(FILE * stream)1372b305b0f1Sespie print_arm_disassembler_options (FILE * stream)
1373b305b0f1Sespie {
1374b305b0f1Sespie   int i;
13752159047fSniklas 
1376b305b0f1Sespie   fprintf (stream, _("\n\
1377b305b0f1Sespie The following ARM specific disassembler options are supported for use with\n\
1378b305b0f1Sespie the -M switch:\n"));
1379b305b0f1Sespie 
1380b305b0f1Sespie   for (i = NUM_ARM_REGNAMES; i--;)
1381b305b0f1Sespie     fprintf (stream, "  reg-names-%s %*c%s\n",
1382b305b0f1Sespie 	     regnames[i].name,
1383c074d1c9Sdrahn 	     (int)(14 - strlen (regnames[i].name)), ' ',
1384b305b0f1Sespie 	     regnames[i].description);
1385b305b0f1Sespie 
1386b305b0f1Sespie   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
1387b305b0f1Sespie   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
13882159047fSniklas }
1389