arm-dis.c revision 130562
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
49static char * arm_conditional[] =
50{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
51 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
52
53typedef struct
54{
55  const char * name;
56  const char * description;
57  const char * reg_names[16];
58}
59arm_regname;
60
61static 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
81static char * iwmmxt_wwnames[] =
82{"b", "h", "w", "d"};
83
84static 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.  */
92static unsigned int regname_selected = 1;
93
94#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
95#define arm_regnames      regnames[regname_selected].reg_names
96
97static bfd_boolean force_thumb = FALSE;
98
99static char * arm_fp_const[] =
100{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
101
102static char * arm_shift[] =
103{"lsl", "lsr", "asr", "ror"};
104
105/* Forward declarations.  */
106static void arm_decode_shift
107  PARAMS ((long, fprintf_ftype, void *));
108static int  print_insn_arm
109  PARAMS ((bfd_vma, struct disassemble_info *, long));
110static int  print_insn_thumb
111  PARAMS ((bfd_vma, struct disassemble_info *, long));
112static void parse_disassembler_options
113  PARAMS ((char *));
114static int  print_insn
115  PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
116static int set_iwmmxt_regnames
117  PARAMS ((void));
118
119int get_arm_regname_num_options
120  PARAMS ((void));
121int set_arm_regname_option
122  PARAMS ((int));
123int get_arm_regnames
124  PARAMS ((int, const char **, const char **, const char ***));
125
126/* Functions.  */
127int
128get_arm_regname_num_options ()
129{
130  return NUM_ARM_REGNAMES;
131}
132
133int
134set_arm_regname_option (option)
135     int option;
136{
137  int old = regname_selected;
138  regname_selected = option;
139  return old;
140}
141
142int
143get_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
155static void
156arm_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
189static int
190set_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
210static int
211print_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 'W':
643				{
644				  long reg;
645
646				  reg = given >> bitstart;
647				  reg &= (2 << (bitend - bitstart)) - 1;
648
649				  func (stream, "%d", reg + 1);
650				}
651				break;
652			      case 'x':
653				{
654				  long reg;
655
656				  reg = given >> bitstart;
657				  reg &= (2 << (bitend - bitstart)) - 1;
658
659				  func (stream, "0x%08x", reg);
660
661				  /* Some SWI instructions have special
662				     meanings.  */
663				  if ((given & 0x0fffffff) == 0x0FF00000)
664				    func (stream, "\t; IMB");
665				  else if ((given & 0x0fffffff) == 0x0FF00001)
666				    func (stream, "\t; IMBRange");
667				}
668				break;
669			      case 'X':
670				{
671				  long reg;
672
673				  reg = given >> bitstart;
674				  reg &= (2 << (bitend - bitstart)) - 1;
675
676				  func (stream, "%01x", reg & 0xf);
677				}
678				break;
679			      case 'f':
680				{
681				  long reg;
682
683				  reg = given >> bitstart;
684				  reg &= (2 << (bitend - bitstart)) - 1;
685
686				  if (reg > 7)
687				    func (stream, "#%s",
688					  arm_fp_const[reg & 7]);
689				  else
690				    func (stream, "f%d", reg);
691				}
692				break;
693
694			      case 'w':
695				{
696				  long reg;
697
698				  if (bitstart != bitend)
699				    {
700				      reg = given >> bitstart;
701				      reg &= (2 << (bitend - bitstart)) - 1;
702				      if (bitend - bitstart == 1)
703					func (stream, "%s", iwmmxt_wwnames[reg]);
704				      else
705					func (stream, "%s", iwmmxt_wwssnames[reg]);
706				    }
707				  else
708				    {
709				      reg = (((given >> 8)  & 0x1) |
710					     ((given >> 22) & 0x1));
711				      func (stream, "%s", iwmmxt_wwnames[reg]);
712				    }
713				}
714				break;
715
716			      case 'g':
717				{
718				  long reg;
719				  int current_regnames;
720
721				  if (! iwmmxt_regnames)
722				    iwmmxt_regnames = set_iwmmxt_regnames ();
723				  current_regnames = set_arm_regname_option
724				    (iwmmxt_regnames);
725
726				  reg = given >> bitstart;
727				  reg &= (2 << (bitend - bitstart)) - 1;
728				  func (stream, "%s", arm_regnames[reg]);
729				  set_arm_regname_option (current_regnames);
730				}
731				break;
732
733			      case 'G':
734				{
735				  long reg;
736				  int current_regnames;
737
738				  if (! iwmmxt_regnames)
739				    iwmmxt_regnames = set_iwmmxt_regnames ();
740				  current_regnames = set_arm_regname_option
741				    (iwmmxt_regnames + 1);
742
743				  reg = given >> bitstart;
744				  reg &= (2 << (bitend - bitstart)) - 1;
745				  func (stream, "%s", arm_regnames[reg]);
746				  set_arm_regname_option (current_regnames);
747				}
748				break;
749
750			      default:
751				abort ();
752			      }
753			    break;
754
755			  case 'y':
756			  case 'z':
757			    {
758			      int single = *c == 'y';
759			      int regno;
760
761			      switch (bitstart)
762				{
763				case 4: /* Sm pair */
764				  func (stream, "{");
765				  /* Fall through.  */
766				case 0: /* Sm, Dm */
767				  regno = given & 0x0000000f;
768				  if (single)
769				    {
770				      regno <<= 1;
771				      regno += (given >> 5) & 1;
772				    }
773				  break;
774
775				case 1: /* Sd, Dd */
776				  regno = (given >> 12) & 0x0000000f;
777				  if (single)
778				    {
779				      regno <<= 1;
780				      regno += (given >> 22) & 1;
781				    }
782				  break;
783
784				case 2: /* Sn, Dn */
785				  regno = (given >> 16) & 0x0000000f;
786				  if (single)
787				    {
788				      regno <<= 1;
789				      regno += (given >> 7) & 1;
790				    }
791				  break;
792
793				case 3: /* List */
794				  func (stream, "{");
795				  regno = (given >> 12) & 0x0000000f;
796				  if (single)
797				    {
798				      regno <<= 1;
799				      regno += (given >> 22) & 1;
800				    }
801				  break;
802
803
804				default:
805				  abort ();
806				}
807
808			      func (stream, "%c%d", single ? 's' : 'd', regno);
809
810			      if (bitstart == 3)
811				{
812				  int count = given & 0xff;
813
814				  if (single == 0)
815				    count >>= 1;
816
817				  if (--count)
818				    {
819				      func (stream, "-%c%d",
820					    single ? 's' : 'd',
821					    regno + count);
822				    }
823
824				  func (stream, "}");
825				}
826			      else if (bitstart == 4)
827				func (stream, ", %c%d}", single ? 's' : 'd',
828				      regno + 1);
829
830			      break;
831			    }
832
833			  case '`':
834			    c++;
835			    if ((given & (1 << bitstart)) == 0)
836			      func (stream, "%c", *c);
837			    break;
838			  case '\'':
839			    c++;
840			    if ((given & (1 << bitstart)) != 0)
841			      func (stream, "%c", *c);
842			    break;
843			  case '?':
844			    ++c;
845			    if ((given & (1 << bitstart)) != 0)
846			      func (stream, "%c", *c++);
847			    else
848			      func (stream, "%c", *++c);
849			    break;
850			  default:
851			    abort ();
852			  }
853			break;
854
855		      case 'L':
856			switch (given & 0x00400100)
857			  {
858			  case 0x00000000: func (stream, "b"); break;
859			  case 0x00400000: func (stream, "h"); break;
860			  case 0x00000100: func (stream, "w"); break;
861			  case 0x00400100: func (stream, "d"); break;
862			  default:
863			    break;
864			  }
865			break;
866
867		      case 'Z':
868			{
869			  int value;
870			  /* given (20, 23) | given (0, 3) */
871			  value = ((given >> 16) & 0xf0) | (given & 0xf);
872			  func (stream, "%d", value);
873			}
874			break;
875
876		      case 'l':
877			/* This is like the 'A' operator, except that if
878			   the width field "M" is zero, then the offset is
879			   *not* multiplied by four.  */
880			{
881			  int offset = given & 0xff;
882			  int multiplier = (given & 0x00000100) ? 4 : 1;
883
884			  func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
885
886			  if (offset)
887			    {
888			      if ((given & 0x01000000) != 0)
889				func (stream, ", #%s%d]%s",
890				      ((given & 0x00800000) == 0 ? "-" : ""),
891				      offset * multiplier,
892				      ((given & 0x00200000) != 0 ? "!" : ""));
893			      else
894				func (stream, "], #%s%d",
895				      ((given & 0x00800000) == 0 ? "-" : ""),
896				      offset * multiplier);
897			    }
898			  else
899			    func (stream, "]");
900			}
901			break;
902
903		      default:
904			abort ();
905		      }
906		    }
907		}
908	      else
909		func (stream, "%c", *c);
910	    }
911	  return 4;
912	}
913    }
914  abort ();
915}
916
917/* Print one instruction from PC on INFO->STREAM.
918   Return the size of the instruction. */
919
920static int
921print_insn_thumb (pc, info, given)
922     bfd_vma pc;
923     struct disassemble_info *info;
924     long given;
925{
926  const struct thumb_opcode *insn;
927  void *stream = info->stream;
928  fprintf_ftype func = info->fprintf_func;
929
930  for (insn = thumb_opcodes; insn->assembler; insn++)
931    {
932      if ((given & insn->mask) == insn->value)
933        {
934          char * c = insn->assembler;
935
936          /* Special processing for Thumb 2 instruction BL sequence:  */
937          if (!*c) /* Check for empty (not NULL) assembler string.  */
938            {
939	      long offset;
940
941	      info->bytes_per_chunk = 4;
942	      info->bytes_per_line  = 4;
943
944	      offset = BDISP23 (given);
945	      offset = offset * 2 + pc + 4;
946
947	      if ((given & 0x10000000) == 0)
948		{
949		  func (stream, "blx\t");
950		  offset &= 0xfffffffc;
951		}
952	      else
953		func (stream, "bl\t");
954
955	      info->print_address_func (offset, info);
956              return 4;
957            }
958          else
959            {
960	      info->bytes_per_chunk = 2;
961	      info->bytes_per_line  = 4;
962
963              given &= 0xffff;
964
965              for (; *c; c++)
966                {
967                  if (*c == '%')
968                    {
969                      int domaskpc = 0;
970                      int domasklr = 0;
971
972                      switch (*++c)
973                        {
974                        case '%':
975                          func (stream, "%%");
976                          break;
977
978                        case 'S':
979                          {
980                            long reg;
981
982                            reg = (given >> 3) & 0x7;
983                            if (given & (1 << 6))
984                              reg += 8;
985
986                            func (stream, "%s", arm_regnames[reg]);
987                          }
988                          break;
989
990                        case 'D':
991                          {
992                            long reg;
993
994                            reg = given & 0x7;
995                            if (given & (1 << 7))
996                             reg += 8;
997
998                            func (stream, "%s", arm_regnames[reg]);
999                          }
1000                          break;
1001
1002                        case 'T':
1003                          func (stream, "%s",
1004                                arm_conditional [(given >> 8) & 0xf]);
1005                          break;
1006
1007                        case 'N':
1008                          if (given & (1 << 8))
1009                            domasklr = 1;
1010                          /* Fall through.  */
1011                        case 'O':
1012                          if (*c == 'O' && (given & (1 << 8)))
1013                            domaskpc = 1;
1014                          /* Fall through.  */
1015                        case 'M':
1016                          {
1017                            int started = 0;
1018                            int reg;
1019
1020                            func (stream, "{");
1021
1022                            /* It would be nice if we could spot
1023                               ranges, and generate the rS-rE format: */
1024                            for (reg = 0; (reg < 8); reg++)
1025                              if ((given & (1 << reg)) != 0)
1026                                {
1027                                  if (started)
1028                                    func (stream, ", ");
1029                                  started = 1;
1030                                  func (stream, "%s", arm_regnames[reg]);
1031                                }
1032
1033                            if (domasklr)
1034                              {
1035                                if (started)
1036                                  func (stream, ", ");
1037                                started = 1;
1038                                func (stream, arm_regnames[14] /* "lr" */);
1039                              }
1040
1041                            if (domaskpc)
1042                              {
1043                                if (started)
1044                                  func (stream, ", ");
1045                                func (stream, arm_regnames[15] /* "pc" */);
1046                              }
1047
1048                            func (stream, "}");
1049                          }
1050                          break;
1051
1052
1053                        case '0': case '1': case '2': case '3': case '4':
1054                        case '5': case '6': case '7': case '8': case '9':
1055                          {
1056                            int bitstart = *c++ - '0';
1057                            int bitend = 0;
1058
1059                            while (*c >= '0' && *c <= '9')
1060                              bitstart = (bitstart * 10) + *c++ - '0';
1061
1062                            switch (*c)
1063                              {
1064                              case '-':
1065                                {
1066                                  long reg;
1067
1068                                  c++;
1069                                  while (*c >= '0' && *c <= '9')
1070                                    bitend = (bitend * 10) + *c++ - '0';
1071                                  if (!bitend)
1072                                    abort ();
1073                                  reg = given >> bitstart;
1074                                  reg &= (2 << (bitend - bitstart)) - 1;
1075                                  switch (*c)
1076                                    {
1077                                    case 'r':
1078                                      func (stream, "%s", arm_regnames[reg]);
1079                                      break;
1080
1081                                    case 'd':
1082                                      func (stream, "%d", reg);
1083                                      break;
1084
1085                                    case 'H':
1086                                      func (stream, "%d", reg << 1);
1087                                      break;
1088
1089                                    case 'W':
1090                                      func (stream, "%d", reg << 2);
1091                                      break;
1092
1093                                    case 'a':
1094				      /* PC-relative address -- the bottom two
1095					 bits of the address are dropped
1096					 before the calculation.  */
1097                                      info->print_address_func
1098					(((pc + 4) & ~3) + (reg << 2), info);
1099                                      break;
1100
1101                                    case 'x':
1102                                      func (stream, "0x%04x", reg);
1103                                      break;
1104
1105                                    case 'I':
1106                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1107                                      func (stream, "%d", reg);
1108                                      break;
1109
1110                                    case 'B':
1111                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1112                                      (*info->print_address_func)
1113                                        (reg * 2 + pc + 4, info);
1114                                      break;
1115
1116                                    default:
1117                                      abort ();
1118                                    }
1119                                }
1120                                break;
1121
1122                              case '\'':
1123                                c++;
1124                                if ((given & (1 << bitstart)) != 0)
1125                                  func (stream, "%c", *c);
1126                                break;
1127
1128                              case '?':
1129                                ++c;
1130                                if ((given & (1 << bitstart)) != 0)
1131                                  func (stream, "%c", *c++);
1132                                else
1133                                  func (stream, "%c", *++c);
1134                                break;
1135
1136                              default:
1137                                 abort ();
1138                              }
1139                          }
1140                          break;
1141
1142                        default:
1143                          abort ();
1144                        }
1145                    }
1146                  else
1147                    func (stream, "%c", *c);
1148                }
1149             }
1150          return 2;
1151       }
1152    }
1153
1154  /* No match.  */
1155  abort ();
1156}
1157
1158/* Disallow mapping symbols ($a, $b, $d, $t etc) from
1159   being displayed in symbol relative addresses.  */
1160
1161bfd_boolean
1162arm_symbol_is_valid (asymbol * sym,
1163		     struct disassemble_info * info ATTRIBUTE_UNUSED)
1164{
1165  const char * name;
1166
1167  if (sym == NULL)
1168    return FALSE;
1169
1170  name = bfd_asymbol_name (sym);
1171
1172  return (name && *name != '$');
1173}
1174
1175/* Parse an individual disassembler option.  */
1176
1177void
1178parse_arm_disassembler_option (option)
1179     char * option;
1180{
1181  if (option == NULL)
1182    return;
1183
1184  if (strneq (option, "reg-names-", 10))
1185    {
1186      int i;
1187
1188      option += 10;
1189
1190      for (i = NUM_ARM_REGNAMES; i--;)
1191	if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1192	  {
1193	    regname_selected = i;
1194	    break;
1195	  }
1196
1197      if (i < 0)
1198	/* XXX - should break 'option' at following delimiter.  */
1199	fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1200    }
1201  else if (strneq (option, "force-thumb", 11))
1202    force_thumb = 1;
1203  else if (strneq (option, "no-force-thumb", 14))
1204    force_thumb = 0;
1205  else
1206    /* XXX - should break 'option' at following delimiter.  */
1207    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1208
1209  return;
1210}
1211
1212/* Parse the string of disassembler options, spliting it at whitespaces
1213   or commas.  (Whitespace separators supported for backwards compatibility).  */
1214
1215static void
1216parse_disassembler_options (options)
1217     char * options;
1218{
1219  if (options == NULL)
1220    return;
1221
1222  while (*options)
1223    {
1224      parse_arm_disassembler_option (options);
1225
1226      /* Skip forward to next seperator.  */
1227      while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1228	++ options;
1229      /* Skip forward past seperators.  */
1230      while (ISSPACE (*options) || (*options == ','))
1231	++ options;
1232    }
1233}
1234
1235/* NOTE: There are no checks in these routines that
1236   the relevant number of data bytes exist.  */
1237
1238static int
1239print_insn (pc, info, little)
1240     bfd_vma pc;
1241     struct disassemble_info * info;
1242     bfd_boolean little;
1243{
1244  unsigned char      b[4];
1245  long               given;
1246  int                status;
1247  int                is_thumb;
1248
1249  if (info->disassembler_options)
1250    {
1251      parse_disassembler_options (info->disassembler_options);
1252
1253      /* To avoid repeated parsing of these options, we remove them here.  */
1254      info->disassembler_options = NULL;
1255    }
1256
1257  is_thumb = force_thumb;
1258
1259  if (!is_thumb && info->symbols != NULL)
1260    {
1261      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1262	{
1263	  coff_symbol_type * cs;
1264
1265	  cs = coffsymbol (*info->symbols);
1266	  is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
1267		      || cs->native->u.syment.n_sclass == C_THUMBSTAT
1268		      || cs->native->u.syment.n_sclass == C_THUMBLABEL
1269		      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1270		      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1271	}
1272      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1273	{
1274	  elf_symbol_type *  es;
1275	  unsigned int       type;
1276
1277	  es = *(elf_symbol_type **)(info->symbols);
1278	  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1279
1280	  is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1281	}
1282    }
1283
1284  info->bytes_per_chunk = 4;
1285  info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1286
1287  if (little)
1288    {
1289      status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
1290      if (status != 0 && is_thumb)
1291	{
1292	  info->bytes_per_chunk = 2;
1293
1294	  status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
1295	  b[3] = b[2] = 0;
1296	}
1297
1298      if (status != 0)
1299	{
1300	  info->memory_error_func (status, pc, info);
1301	  return -1;
1302	}
1303
1304      given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
1305    }
1306  else
1307    {
1308      status = info->read_memory_func
1309	(pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
1310      if (status != 0)
1311	{
1312	  info->memory_error_func (status, pc, info);
1313	  return -1;
1314	}
1315
1316      if (is_thumb)
1317	{
1318	  if (pc & 0x2)
1319	    {
1320	      given = (b[2] << 8) | b[3];
1321
1322	      status = info->read_memory_func
1323		((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
1324	      if (status != 0)
1325		{
1326		  info->memory_error_func (status, pc + 4, info);
1327		  return -1;
1328		}
1329
1330	      given |= (b[0] << 24) | (b[1] << 16);
1331	    }
1332	  else
1333	    given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
1334	}
1335      else
1336	given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
1337    }
1338
1339  if (info->flags & INSN_HAS_RELOC)
1340    /* If the instruction has a reloc associated with it, then
1341       the offset field in the instruction will actually be the
1342       addend for the reloc.  (We are using REL type relocs).
1343       In such cases, we can ignore the pc when computing
1344       addresses, since the addend is not currently pc-relative.  */
1345    pc = 0;
1346
1347  if (is_thumb)
1348    status = print_insn_thumb (pc, info, given);
1349  else
1350    status = print_insn_arm (pc, info, given);
1351
1352  return status;
1353}
1354
1355int
1356print_insn_big_arm (pc, info)
1357     bfd_vma pc;
1358     struct disassemble_info * info;
1359{
1360  return print_insn (pc, info, FALSE);
1361}
1362
1363int
1364print_insn_little_arm (pc, info)
1365     bfd_vma pc;
1366     struct disassemble_info * info;
1367{
1368  return print_insn (pc, info, TRUE);
1369}
1370
1371void
1372print_arm_disassembler_options (FILE * stream)
1373{
1374  int i;
1375
1376  fprintf (stream, _("\n\
1377The following ARM specific disassembler options are supported for use with\n\
1378the -M switch:\n"));
1379
1380  for (i = NUM_ARM_REGNAMES; i--;)
1381    fprintf (stream, "  reg-names-%s %*c%s\n",
1382	     regnames[i].name,
1383	     (int)(14 - strlen (regnames[i].name)), ' ',
1384	     regnames[i].description);
1385
1386  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
1387  fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
1388}
1389