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