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