OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [opcodes/] [arm-dis.c] - Diff between revs 579 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 579 Rev 1765
/* Instruction printing code for the ARM
/* Instruction printing code for the ARM
   Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
   Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
   Modification by James G. Smith (jsmith@cygnus.co.uk)
   Modification by James G. Smith (jsmith@cygnus.co.uk)
 
 
This file is part of libopcodes.
This file is part of libopcodes.
 
 
This program is free software; you can redistribute it and/or modify it under
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
Software Foundation; either version 2 of the License, or (at your option)
any later version.
any later version.
 
 
This program is distributed in the hope that it will be useful, but WITHOUT
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.
more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
#include "sysdep.h"
#include "sysdep.h"
#include "dis-asm.h"
#include "dis-asm.h"
#define DEFINE_TABLE
#define DEFINE_TABLE
#include "arm-opc.h"
#include "arm-opc.h"
#include "coff/internal.h"
#include "coff/internal.h"
#include "libcoff.h"
#include "libcoff.h"
#include "opintl.h"
#include "opintl.h"
 
 
/* FIXME: This shouldn't be done here */
/* FIXME: This shouldn't be done here */
#include "elf-bfd.h"
#include "elf-bfd.h"
#include "elf/internal.h"
#include "elf/internal.h"
#include "elf/arm.h"
#include "elf/arm.h"
 
 
#ifndef streq
#ifndef streq
#define streq(a,b)      (strcmp ((a), (b)) == 0)
#define streq(a,b)      (strcmp ((a), (b)) == 0)
#endif
#endif
 
 
#ifndef strneq
#ifndef strneq
#define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
#define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
#endif
#endif
 
 
#ifndef NUM_ELEM
#ifndef NUM_ELEM
#define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
#define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
#endif
#endif
 
 
static char * arm_conditional[] =
static char * arm_conditional[] =
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
 
 
typedef struct
typedef struct
{
{
  const char * name;
  const char * name;
  const char * description;
  const char * description;
  const char * reg_names[16];
  const char * reg_names[16];
}
}
arm_regname;
arm_regname;
 
 
static arm_regname regnames[] =
static arm_regname regnames[] =
{
{
  { "raw" , "Select raw register names",
  { "raw" , "Select raw register names",
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
  { "std",  "Select register names used in ARM's ISA documentation",
  { "std",  "Select register names used in ARM's ISA documentation",
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
  { "apcs", "Select register names used in the APCS",
  { "apcs", "Select register names used in the APCS",
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
  { "atpcs", "Select register names used in the ATPCS",
  { "atpcs", "Select register names used in the ATPCS",
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
  { "special-atpcs", "Select special register names used in the ATPCS",
  { "special-atpcs", "Select special register names used in the ATPCS",
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }}
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }}
};
};
 
 
/* Default to standard register name set.  */
/* Default to standard register name set.  */
static unsigned int regname_selected = 1;
static unsigned int regname_selected = 1;
 
 
#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
#define arm_regnames      regnames[regname_selected].reg_names
#define arm_regnames      regnames[regname_selected].reg_names
 
 
static boolean force_thumb = false;
static boolean force_thumb = false;
 
 
static char * arm_fp_const[] =
static char * arm_fp_const[] =
{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
 
 
static char * arm_shift[] =
static char * arm_shift[] =
{"lsl", "lsr", "asr", "ror"};
{"lsl", "lsr", "asr", "ror"};


/* Forward declarations.  */
/* Forward declarations.  */
static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *));
static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *));
static int  print_insn_arm   PARAMS ((bfd_vma, struct disassemble_info *, long));
static int  print_insn_arm   PARAMS ((bfd_vma, struct disassemble_info *, long));
static int  print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long));
static int  print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long));
static void parse_disassembler_options PARAMS ((char *));
static void parse_disassembler_options PARAMS ((char *));
static int  print_insn       PARAMS ((bfd_vma, struct disassemble_info *, boolean));
static int  print_insn       PARAMS ((bfd_vma, struct disassemble_info *, boolean));
int get_arm_regname_num_options (void);
int get_arm_regname_num_options (void);
int set_arm_regname_option (int option);
int set_arm_regname_option (int option);
int get_arm_regnames (int option, const char **setname,
int get_arm_regnames (int option, const char **setname,
                      const char **setdescription,
                      const char **setdescription,
                      const char ***register_names);
                      const char ***register_names);


/* Functions. */
/* Functions. */
int
int
get_arm_regname_num_options (void)
get_arm_regname_num_options (void)
{
{
  return NUM_ARM_REGNAMES;
  return NUM_ARM_REGNAMES;
}
}
 
 
int
int
set_arm_regname_option (int option)
set_arm_regname_option (int option)
{
{
  int old = regname_selected;
  int old = regname_selected;
  regname_selected = option;
  regname_selected = option;
  return old;
  return old;
}
}
 
 
int
int
get_arm_regnames (int option, const char **setname,
get_arm_regnames (int option, const char **setname,
                  const char **setdescription,
                  const char **setdescription,
                  const char ***register_names)
                  const char ***register_names)
{
{
  *setname = regnames[option].name;
  *setname = regnames[option].name;
  *setdescription = regnames[option].description;
  *setdescription = regnames[option].description;
  *register_names = regnames[option].reg_names;
  *register_names = regnames[option].reg_names;
  return 16;
  return 16;
}
}
 
 
static void
static void
arm_decode_shift (given, func, stream)
arm_decode_shift (given, func, stream)
     long given;
     long given;
     fprintf_ftype func;
     fprintf_ftype func;
     void * stream;
     void * stream;
{
{
  func (stream, "%s", arm_regnames[given & 0xf]);
  func (stream, "%s", arm_regnames[given & 0xf]);
 
 
  if ((given & 0xff0) != 0)
  if ((given & 0xff0) != 0)
    {
    {
      if ((given & 0x10) == 0)
      if ((given & 0x10) == 0)
        {
        {
          int amount = (given & 0xf80) >> 7;
          int amount = (given & 0xf80) >> 7;
          int shift = (given & 0x60) >> 5;
          int shift = (given & 0x60) >> 5;
 
 
          if (amount == 0)
          if (amount == 0)
            {
            {
              if (shift == 3)
              if (shift == 3)
                {
                {
                  func (stream, ", rrx");
                  func (stream, ", rrx");
                  return;
                  return;
                }
                }
 
 
              amount = 32;
              amount = 32;
            }
            }
 
 
          func (stream, ", %s #%d", arm_shift[shift], amount);
          func (stream, ", %s #%d", arm_shift[shift], amount);
        }
        }
      else
      else
        func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
        func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
              arm_regnames[(given & 0xf00) >> 8]);
              arm_regnames[(given & 0xf00) >> 8]);
    }
    }
}
}
 
 
/* Print one instruction from PC on INFO->STREAM.
/* Print one instruction from PC on INFO->STREAM.
   Return the size of the instruction (always 4 on ARM). */
   Return the size of the instruction (always 4 on ARM). */
static int
static int
print_insn_arm (pc, info, given)
print_insn_arm (pc, info, given)
     bfd_vma                   pc;
     bfd_vma                   pc;
     struct disassemble_info * info;
     struct disassemble_info * info;
     long                      given;
     long                      given;
{
{
  struct arm_opcode *  insn;
  struct arm_opcode *  insn;
  void *               stream = info->stream;
  void *               stream = info->stream;
  fprintf_ftype        func   = info->fprintf_func;
  fprintf_ftype        func   = info->fprintf_func;
 
 
  for (insn = arm_opcodes; insn->assembler; insn++)
  for (insn = arm_opcodes; insn->assembler; insn++)
    {
    {
      if ((given & insn->mask) == insn->value)
      if ((given & insn->mask) == insn->value)
        {
        {
          char * c;
          char * c;
 
 
          for (c = insn->assembler; *c; c++)
          for (c = insn->assembler; *c; c++)
            {
            {
              if (*c == '%')
              if (*c == '%')
                {
                {
                  switch (*++c)
                  switch (*++c)
                    {
                    {
                    case '%':
                    case '%':
                      func (stream, "%%");
                      func (stream, "%%");
                      break;
                      break;
 
 
                    case 'a':
                    case 'a':
                      if (((given & 0x000f0000) == 0x000f0000)
                      if (((given & 0x000f0000) == 0x000f0000)
                          && ((given & 0x02000000) == 0))
                          && ((given & 0x02000000) == 0))
                        {
                        {
                          int offset = given & 0xfff;
                          int offset = given & 0xfff;
 
 
                          func (stream, "[pc");
                          func (stream, "[pc");
 
 
                          if (given & 0x01000000)
                          if (given & 0x01000000)
                            {
                            {
                              if ((given & 0x00800000) == 0)
                              if ((given & 0x00800000) == 0)
                                offset = - offset;
                                offset = - offset;
 
 
                              /* pre-indexed */
                              /* pre-indexed */
                              func (stream, ", #%x]", offset);
                              func (stream, ", #%x]", offset);
 
 
                              offset += pc + 8;
                              offset += pc + 8;
 
 
                              /* Cope with the possibility of write-back
                              /* Cope with the possibility of write-back
                                 being used.  Probably a very dangerous thing
                                 being used.  Probably a very dangerous thing
                                 for the programmer to do, but who are we to
                                 for the programmer to do, but who are we to
                                 argue ?  */
                                 argue ?  */
                              if (given & 0x00200000)
                              if (given & 0x00200000)
                                func (stream, "!");
                                func (stream, "!");
                            }
                            }
                          else
                          else
                            {
                            {
                              /* Post indexed.  */
                              /* Post indexed.  */
                              func (stream, "], #%x", offset);
                              func (stream, "], #%x", offset);
 
 
                              offset = pc + 8;  /* ie ignore the offset.  */
                              offset = pc + 8;  /* ie ignore the offset.  */
                            }
                            }
 
 
                          func (stream, "\t; ");
                          func (stream, "\t; ");
                          info->print_address_func (offset, info);
                          info->print_address_func (offset, info);
                        }
                        }
                      else
                      else
                        {
                        {
                          func (stream, "[%s",
                          func (stream, "[%s",
                                arm_regnames[(given >> 16) & 0xf]);
                                arm_regnames[(given >> 16) & 0xf]);
                          if ((given & 0x01000000) != 0)
                          if ((given & 0x01000000) != 0)
                            {
                            {
                              if ((given & 0x02000000) == 0)
                              if ((given & 0x02000000) == 0)
                                {
                                {
                                  int offset = given & 0xfff;
                                  int offset = given & 0xfff;
                                  if (offset)
                                  if (offset)
                                    func (stream, ", %s#%d",
                                    func (stream, ", %s#%d",
                                          (((given & 0x00800000) == 0)
                                          (((given & 0x00800000) == 0)
                                           ? "-" : ""), offset);
                                           ? "-" : ""), offset);
                                }
                                }
                              else
                              else
                                {
                                {
                                  func (stream, ", %s",
                                  func (stream, ", %s",
                                        (((given & 0x00800000) == 0)
                                        (((given & 0x00800000) == 0)
                                         ? "-" : ""));
                                         ? "-" : ""));
                                  arm_decode_shift (given, func, stream);
                                  arm_decode_shift (given, func, stream);
                                }
                                }
 
 
                              func (stream, "]%s",
                              func (stream, "]%s",
                                    ((given & 0x00200000) != 0) ? "!" : "");
                                    ((given & 0x00200000) != 0) ? "!" : "");
                            }
                            }
                          else
                          else
                            {
                            {
                              if ((given & 0x02000000) == 0)
                              if ((given & 0x02000000) == 0)
                                {
                                {
                                  int offset = given & 0xfff;
                                  int offset = given & 0xfff;
                                  if (offset)
                                  if (offset)
                                    func (stream, "], %s#%d",
                                    func (stream, "], %s#%d",
                                          (((given & 0x00800000) == 0)
                                          (((given & 0x00800000) == 0)
                                           ? "-" : ""), offset);
                                           ? "-" : ""), offset);
                                  else
                                  else
                                    func (stream, "]");
                                    func (stream, "]");
                                }
                                }
                              else
                              else
                                {
                                {
                                  func (stream, "], %s",
                                  func (stream, "], %s",
                                        (((given & 0x00800000) == 0)
                                        (((given & 0x00800000) == 0)
                                         ? "-" : ""));
                                         ? "-" : ""));
                                  arm_decode_shift (given, func, stream);
                                  arm_decode_shift (given, func, stream);
                                }
                                }
                            }
                            }
                        }
                        }
                      break;
                      break;
 
 
                    case 's':
                    case 's':
                      if ((given & 0x004f0000) == 0x004f0000)
                      if ((given & 0x004f0000) == 0x004f0000)
                        {
                        {
                          /* PC relative with immediate offset.  */
                          /* PC relative with immediate offset.  */
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
 
 
                          if ((given & 0x00800000) == 0)
                          if ((given & 0x00800000) == 0)
                            offset = -offset;
                            offset = -offset;
 
 
                          func (stream, "[pc, #%x]\t; ", offset);
                          func (stream, "[pc, #%x]\t; ", offset);
 
 
                          (*info->print_address_func)
                          (*info->print_address_func)
                            (offset + pc + 8, info);
                            (offset + pc + 8, info);
                        }
                        }
                      else
                      else
                        {
                        {
                          func (stream, "[%s",
                          func (stream, "[%s",
                                arm_regnames[(given >> 16) & 0xf]);
                                arm_regnames[(given >> 16) & 0xf]);
                          if ((given & 0x01000000) != 0)
                          if ((given & 0x01000000) != 0)
                            {
                            {
                              /* Pre-indexed.  */
                              /* Pre-indexed.  */
                              if ((given & 0x00400000) == 0x00400000)
                              if ((given & 0x00400000) == 0x00400000)
                                {
                                {
                                  /* Immediate.  */
                                  /* Immediate.  */
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                                  if (offset)
                                  if (offset)
                                    func (stream, ", %s#%d",
                                    func (stream, ", %s#%d",
                                          (((given & 0x00800000) == 0)
                                          (((given & 0x00800000) == 0)
                                           ? "-" : ""), offset);
                                           ? "-" : ""), offset);
                                }
                                }
                              else
                              else
                                {
                                {
                                  /* Register.  */
                                  /* Register.  */
                                  func (stream, ", %s%s",
                                  func (stream, ", %s%s",
                                        (((given & 0x00800000) == 0)
                                        (((given & 0x00800000) == 0)
                                         ? "-" : ""),
                                         ? "-" : ""),
                                        arm_regnames[given & 0xf]);
                                        arm_regnames[given & 0xf]);
                                }
                                }
 
 
                              func (stream, "]%s",
                              func (stream, "]%s",
                                    ((given & 0x00200000) != 0) ? "!" : "");
                                    ((given & 0x00200000) != 0) ? "!" : "");
                            }
                            }
                          else
                          else
                            {
                            {
                              /* Post-indexed.  */
                              /* Post-indexed.  */
                              if ((given & 0x00400000) == 0x00400000)
                              if ((given & 0x00400000) == 0x00400000)
                                {
                                {
                                  /* Immediate.  */
                                  /* Immediate.  */
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                                  if (offset)
                                  if (offset)
                                    func (stream, "], %s#%d",
                                    func (stream, "], %s#%d",
                                          (((given & 0x00800000) == 0)
                                          (((given & 0x00800000) == 0)
                                           ? "-" : ""), offset);
                                           ? "-" : ""), offset);
                                  else
                                  else
                                    func (stream, "]");
                                    func (stream, "]");
                                }
                                }
                              else
                              else
                                {
                                {
                                  /* Register.  */
                                  /* Register.  */
                                  func (stream, "], %s%s",
                                  func (stream, "], %s%s",
                                        (((given & 0x00800000) == 0)
                                        (((given & 0x00800000) == 0)
                                         ? "-" : ""),
                                         ? "-" : ""),
                                        arm_regnames[given & 0xf]);
                                        arm_regnames[given & 0xf]);
                                }
                                }
                            }
                            }
                        }
                        }
                      break;
                      break;
 
 
                    case 'b':
                    case 'b':
                      (*info->print_address_func)
                      (*info->print_address_func)
                        (BDISP (given) * 4 + pc + 8, info);
                        (BDISP (given) * 4 + pc + 8, info);
                      break;
                      break;
 
 
                    case 'c':
                    case 'c':
                      func (stream, "%s",
                      func (stream, "%s",
                            arm_conditional [(given >> 28) & 0xf]);
                            arm_conditional [(given >> 28) & 0xf]);
                      break;
                      break;
 
 
                    case 'm':
                    case 'm':
                      {
                      {
                        int started = 0;
                        int started = 0;
                        int reg;
                        int reg;
 
 
                        func (stream, "{");
                        func (stream, "{");
                        for (reg = 0; reg < 16; reg++)
                        for (reg = 0; reg < 16; reg++)
                          if ((given & (1 << reg)) != 0)
                          if ((given & (1 << reg)) != 0)
                            {
                            {
                              if (started)
                              if (started)
                                func (stream, ", ");
                                func (stream, ", ");
                              started = 1;
                              started = 1;
                              func (stream, "%s", arm_regnames[reg]);
                              func (stream, "%s", arm_regnames[reg]);
                            }
                            }
                        func (stream, "}");
                        func (stream, "}");
                      }
                      }
                      break;
                      break;
 
 
                    case 'o':
                    case 'o':
                      if ((given & 0x02000000) != 0)
                      if ((given & 0x02000000) != 0)
                        {
                        {
                          int rotate = (given & 0xf00) >> 7;
                          int rotate = (given & 0xf00) >> 7;
                          int immed = (given & 0xff);
                          int immed = (given & 0xff);
                          immed = (((immed << (32 - rotate))
                          immed = (((immed << (32 - rotate))
                                    | (immed >> rotate)) & 0xffffffff);
                                    | (immed >> rotate)) & 0xffffffff);
                          func (stream, "#%d\t; 0x%x", immed, immed);
                          func (stream, "#%d\t; 0x%x", immed, immed);
                        }
                        }
                      else
                      else
                        arm_decode_shift (given, func, stream);
                        arm_decode_shift (given, func, stream);
                      break;
                      break;
 
 
                    case 'p':
                    case 'p':
                      if ((given & 0x0000f000) == 0x0000f000)
                      if ((given & 0x0000f000) == 0x0000f000)
                        func (stream, "p");
                        func (stream, "p");
                      break;
                      break;
 
 
                    case 't':
                    case 't':
                      if ((given & 0x01200000) == 0x00200000)
                      if ((given & 0x01200000) == 0x00200000)
                        func (stream, "t");
                        func (stream, "t");
                      break;
                      break;
 
 
                    case 'h':
                    case 'h':
                      if ((given & 0x00000020) == 0x00000020)
                      if ((given & 0x00000020) == 0x00000020)
                        func (stream, "h");
                        func (stream, "h");
                      else
                      else
                        func (stream, "b");
                        func (stream, "b");
                      break;
                      break;
 
 
                    case 'A':
                    case 'A':
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
                      if ((given & 0x01000000) != 0)
                      if ((given & 0x01000000) != 0)
                        {
                        {
                          int offset = given & 0xff;
                          int offset = given & 0xff;
                          if (offset)
                          if (offset)
                            func (stream, ", %s#%d]%s",
                            func (stream, ", %s#%d]%s",
                                  ((given & 0x00800000) == 0 ? "-" : ""),
                                  ((given & 0x00800000) == 0 ? "-" : ""),
                                  offset * 4,
                                  offset * 4,
                                  ((given & 0x00200000) != 0 ? "!" : ""));
                                  ((given & 0x00200000) != 0 ? "!" : ""));
                          else
                          else
                            func (stream, "]");
                            func (stream, "]");
                        }
                        }
                      else
                      else
                        {
                        {
                          int offset = given & 0xff;
                          int offset = given & 0xff;
                          if (offset)
                          if (offset)
                            func (stream, "], %s#%d",
                            func (stream, "], %s#%d",
                                  ((given & 0x00800000) == 0 ? "-" : ""),
                                  ((given & 0x00800000) == 0 ? "-" : ""),
                                  offset * 4);
                                  offset * 4);
                          else
                          else
                            func (stream, "]");
                            func (stream, "]");
                        }
                        }
                      break;
                      break;
 
 
                    case 'C':
                    case 'C':
                      switch (given & 0x00090000)
                      switch (given & 0x00090000)
                        {
                        {
                        default:
                        default:
                          func (stream, "_???");
                          func (stream, "_???");
                          break;
                          break;
                        case 0x90000:
                        case 0x90000:
                          func (stream, "_all");
                          func (stream, "_all");
                          break;
                          break;
                        case 0x10000:
                        case 0x10000:
                          func (stream, "_ctl");
                          func (stream, "_ctl");
                          break;
                          break;
                        case 0x80000:
                        case 0x80000:
                          func (stream, "_flg");
                          func (stream, "_flg");
                          break;
                          break;
                        }
                        }
                      break;
                      break;
 
 
                    case 'F':
                    case 'F':
                      switch (given & 0x00408000)
                      switch (given & 0x00408000)
                        {
                        {
                        case 0:
                        case 0:
                          func (stream, "4");
                          func (stream, "4");
                          break;
                          break;
                        case 0x8000:
                        case 0x8000:
                          func (stream, "1");
                          func (stream, "1");
                          break;
                          break;
                        case 0x00400000:
                        case 0x00400000:
                          func (stream, "2");
                          func (stream, "2");
                          break;
                          break;
                        default:
                        default:
                          func (stream, "3");
                          func (stream, "3");
                        }
                        }
                      break;
                      break;
 
 
                    case 'P':
                    case 'P':
                      switch (given & 0x00080080)
                      switch (given & 0x00080080)
                        {
                        {
                        case 0:
                        case 0:
                          func (stream, "s");
                          func (stream, "s");
                          break;
                          break;
                        case 0x80:
                        case 0x80:
                          func (stream, "d");
                          func (stream, "d");
                          break;
                          break;
                        case 0x00080000:
                        case 0x00080000:
                          func (stream, "e");
                          func (stream, "e");
                          break;
                          break;
                        default:
                        default:
                          func (stream, _("<illegal precision>"));
                          func (stream, _("<illegal precision>"));
                          break;
                          break;
                        }
                        }
                      break;
                      break;
                    case 'Q':
                    case 'Q':
                      switch (given & 0x00408000)
                      switch (given & 0x00408000)
                        {
                        {
                        case 0:
                        case 0:
                          func (stream, "s");
                          func (stream, "s");
                          break;
                          break;
                        case 0x8000:
                        case 0x8000:
                          func (stream, "d");
                          func (stream, "d");
                          break;
                          break;
                        case 0x00400000:
                        case 0x00400000:
                          func (stream, "e");
                          func (stream, "e");
                          break;
                          break;
                        default:
                        default:
                          func (stream, "p");
                          func (stream, "p");
                          break;
                          break;
                        }
                        }
                      break;
                      break;
                    case 'R':
                    case 'R':
                      switch (given & 0x60)
                      switch (given & 0x60)
                        {
                        {
                        case 0:
                        case 0:
                          break;
                          break;
                        case 0x20:
                        case 0x20:
                          func (stream, "p");
                          func (stream, "p");
                          break;
                          break;
                        case 0x40:
                        case 0x40:
                          func (stream, "m");
                          func (stream, "m");
                          break;
                          break;
                        default:
                        default:
                          func (stream, "z");
                          func (stream, "z");
                          break;
                          break;
                        }
                        }
                      break;
                      break;
 
 
                    case '0': case '1': case '2': case '3': case '4':
                    case '0': case '1': case '2': case '3': case '4':
                    case '5': case '6': case '7': case '8': case '9':
                    case '5': case '6': case '7': case '8': case '9':
                      {
                      {
                        int bitstart = *c++ - '0';
                        int bitstart = *c++ - '0';
                        int bitend = 0;
                        int bitend = 0;
                        while (*c >= '0' && *c <= '9')
                        while (*c >= '0' && *c <= '9')
                          bitstart = (bitstart * 10) + *c++ - '0';
                          bitstart = (bitstart * 10) + *c++ - '0';
 
 
                        switch (*c)
                        switch (*c)
                          {
                          {
                          case '-':
                          case '-':
                            c++;
                            c++;
 
 
                            while (*c >= '0' && *c <= '9')
                            while (*c >= '0' && *c <= '9')
                              bitend = (bitend * 10) + *c++ - '0';
                              bitend = (bitend * 10) + *c++ - '0';
 
 
                            if (!bitend)
                            if (!bitend)
                              abort ();
                              abort ();
 
 
                            switch (*c)
                            switch (*c)
                              {
                              {
                              case 'r':
                              case 'r':
                                {
                                {
                                  long reg;
                                  long reg;
 
 
                                  reg = given >> bitstart;
                                  reg = given >> bitstart;
                                  reg &= (2 << (bitend - bitstart)) - 1;
                                  reg &= (2 << (bitend - bitstart)) - 1;
 
 
                                  func (stream, "%s", arm_regnames[reg]);
                                  func (stream, "%s", arm_regnames[reg]);
                                }
                                }
                                break;
                                break;
                              case 'd':
                              case 'd':
                                {
                                {
                                  long reg;
                                  long reg;
 
 
                                  reg = given >> bitstart;
                                  reg = given >> bitstart;
                                  reg &= (2 << (bitend - bitstart)) - 1;
                                  reg &= (2 << (bitend - bitstart)) - 1;
 
 
                                  func (stream, "%d", reg);
                                  func (stream, "%d", reg);
                                }
                                }
                                break;
                                break;
                              case 'x':
                              case 'x':
                                {
                                {
                                  long reg;
                                  long reg;
 
 
                                  reg = given >> bitstart;
                                  reg = given >> bitstart;
                                  reg &= (2 << (bitend - bitstart)) - 1;
                                  reg &= (2 << (bitend - bitstart)) - 1;
 
 
                                  func (stream, "0x%08x", reg);
                                  func (stream, "0x%08x", reg);
 
 
                                  /* Some SWI instructions have special
                                  /* Some SWI instructions have special
                                     meanings.  */
                                     meanings.  */
                                  if ((given & 0x0fffffff) == 0x0FF00000)
                                  if ((given & 0x0fffffff) == 0x0FF00000)
                                    func (stream, "\t; IMB");
                                    func (stream, "\t; IMB");
                                  else if ((given & 0x0fffffff) == 0x0FF00001)
                                  else if ((given & 0x0fffffff) == 0x0FF00001)
                                    func (stream, "\t; IMBRange");
                                    func (stream, "\t; IMBRange");
                                }
                                }
                                break;
                                break;
                              case 'X':
                              case 'X':
                                {
                                {
                                  long reg;
                                  long reg;
 
 
                                  reg = given >> bitstart;
                                  reg = given >> bitstart;
                                  reg &= (2 << (bitend - bitstart)) - 1;
                                  reg &= (2 << (bitend - bitstart)) - 1;
 
 
                                  func (stream, "%01x", reg & 0xf);
                                  func (stream, "%01x", reg & 0xf);
                                }
                                }
                                break;
                                break;
                              case 'f':
                              case 'f':
                                {
                                {
                                  long reg;
                                  long reg;
 
 
                                  reg = given >> bitstart;
                                  reg = given >> bitstart;
                                  reg &= (2 << (bitend - bitstart)) - 1;
                                  reg &= (2 << (bitend - bitstart)) - 1;
 
 
                                  if (reg > 7)
                                  if (reg > 7)
                                    func (stream, "#%s",
                                    func (stream, "#%s",
                                          arm_fp_const[reg & 7]);
                                          arm_fp_const[reg & 7]);
                                  else
                                  else
                                    func (stream, "f%d", reg);
                                    func (stream, "f%d", reg);
                                }
                                }
                                break;
                                break;
                              default:
                              default:
                                abort ();
                                abort ();
                              }
                              }
                            break;
                            break;
 
 
                          case '`':
                          case '`':
                            c++;
                            c++;
                            if ((given & (1 << bitstart)) == 0)
                            if ((given & (1 << bitstart)) == 0)
                              func (stream, "%c", *c);
                              func (stream, "%c", *c);
                            break;
                            break;
                          case '\'':
                          case '\'':
                            c++;
                            c++;
                            if ((given & (1 << bitstart)) != 0)
                            if ((given & (1 << bitstart)) != 0)
                              func (stream, "%c", *c);
                              func (stream, "%c", *c);
                            break;
                            break;
                          case '?':
                          case '?':
                            ++c;
                            ++c;
                            if ((given & (1 << bitstart)) != 0)
                            if ((given & (1 << bitstart)) != 0)
                              func (stream, "%c", *c++);
                              func (stream, "%c", *c++);
                            else
                            else
                              func (stream, "%c", *++c);
                              func (stream, "%c", *++c);
                            break;
                            break;
                          default:
                          default:
                            abort ();
                            abort ();
                          }
                          }
                        break;
                        break;
 
 
                      default:
                      default:
                        abort ();
                        abort ();
                      }
                      }
                    }
                    }
                }
                }
              else
              else
                func (stream, "%c", *c);
                func (stream, "%c", *c);
            }
            }
          return 4;
          return 4;
        }
        }
    }
    }
  abort ();
  abort ();
}
}
 
 
/* Print one instruction from PC on INFO->STREAM.
/* Print one instruction from PC on INFO->STREAM.
   Return the size of the instruction. */
   Return the size of the instruction. */
static int
static int
print_insn_thumb (pc, info, given)
print_insn_thumb (pc, info, given)
     bfd_vma                   pc;
     bfd_vma                   pc;
     struct disassemble_info * info;
     struct disassemble_info * info;
     long                      given;
     long                      given;
{
{
  struct thumb_opcode * insn;
  struct thumb_opcode * insn;
  void *                stream = info->stream;
  void *                stream = info->stream;
  fprintf_ftype         func = info->fprintf_func;
  fprintf_ftype         func = info->fprintf_func;
 
 
  for (insn = thumb_opcodes; insn->assembler; insn++)
  for (insn = thumb_opcodes; insn->assembler; insn++)
    {
    {
      if ((given & insn->mask) == insn->value)
      if ((given & insn->mask) == insn->value)
        {
        {
          char * c = insn->assembler;
          char * c = insn->assembler;
 
 
          /* Special processing for Thumb 2 instruction BL sequence:  */
          /* Special processing for Thumb 2 instruction BL sequence:  */
          if (!*c) /* Check for empty (not NULL) assembler string.  */
          if (!*c) /* Check for empty (not NULL) assembler string.  */
            {
            {
              info->bytes_per_chunk = 4;
              info->bytes_per_chunk = 4;
              info->bytes_per_line  = 4;
              info->bytes_per_line  = 4;
 
 
                func (stream, "bl\t");
                func (stream, "bl\t");
 
 
              info->print_address_func (BDISP23 (given) * 2 + pc + 4, info);
              info->print_address_func (BDISP23 (given) * 2 + pc + 4, info);
              return 4;
              return 4;
            }
            }
          else
          else
            {
            {
              info->bytes_per_chunk = 2;
              info->bytes_per_chunk = 2;
              info->bytes_per_line  = 4;
              info->bytes_per_line  = 4;
 
 
              given &= 0xffff;
              given &= 0xffff;
 
 
              for (; *c; c++)
              for (; *c; c++)
                {
                {
                  if (*c == '%')
                  if (*c == '%')
                    {
                    {
                      int domaskpc = 0;
                      int domaskpc = 0;
                      int domasklr = 0;
                      int domasklr = 0;
 
 
                      switch (*++c)
                      switch (*++c)
                        {
                        {
                        case '%':
                        case '%':
                          func (stream, "%%");
                          func (stream, "%%");
                          break;
                          break;
 
 
                        case 'S':
                        case 'S':
                          {
                          {
                            long reg;
                            long reg;
 
 
                            reg = (given >> 3) & 0x7;
                            reg = (given >> 3) & 0x7;
                            if (given & (1 << 6))
                            if (given & (1 << 6))
                              reg += 8;
                              reg += 8;
 
 
                            func (stream, "%s", arm_regnames[reg]);
                            func (stream, "%s", arm_regnames[reg]);
                          }
                          }
                          break;
                          break;
 
 
                        case 'D':
                        case 'D':
                          {
                          {
                            long reg;
                            long reg;
 
 
                            reg = given & 0x7;
                            reg = given & 0x7;
                            if (given & (1 << 7))
                            if (given & (1 << 7))
                             reg += 8;
                             reg += 8;
 
 
                            func (stream, "%s", arm_regnames[reg]);
                            func (stream, "%s", arm_regnames[reg]);
                          }
                          }
                          break;
                          break;
 
 
                        case 'T':
                        case 'T':
                          func (stream, "%s",
                          func (stream, "%s",
                                arm_conditional [(given >> 8) & 0xf]);
                                arm_conditional [(given >> 8) & 0xf]);
                          break;
                          break;
 
 
                        case 'N':
                        case 'N':
                          if (given & (1 << 8))
                          if (given & (1 << 8))
                            domasklr = 1;
                            domasklr = 1;
                          /* Fall through.  */
                          /* Fall through.  */
                        case 'O':
                        case 'O':
                          if (*c == 'O' && (given & (1 << 8)))
                          if (*c == 'O' && (given & (1 << 8)))
                            domaskpc = 1;
                            domaskpc = 1;
                          /* Fall through.  */
                          /* Fall through.  */
                        case 'M':
                        case 'M':
                          {
                          {
                            int started = 0;
                            int started = 0;
                            int reg;
                            int reg;
 
 
                            func (stream, "{");
                            func (stream, "{");
 
 
                            /* It would be nice if we could spot
                            /* It would be nice if we could spot
                               ranges, and generate the rS-rE format: */
                               ranges, and generate the rS-rE format: */
                            for (reg = 0; (reg < 8); reg++)
                            for (reg = 0; (reg < 8); reg++)
                              if ((given & (1 << reg)) != 0)
                              if ((given & (1 << reg)) != 0)
                                {
                                {
                                  if (started)
                                  if (started)
                                    func (stream, ", ");
                                    func (stream, ", ");
                                  started = 1;
                                  started = 1;
                                  func (stream, "%s", arm_regnames[reg]);
                                  func (stream, "%s", arm_regnames[reg]);
                                }
                                }
 
 
                            if (domasklr)
                            if (domasklr)
                              {
                              {
                                if (started)
                                if (started)
                                  func (stream, ", ");
                                  func (stream, ", ");
                                started = 1;
                                started = 1;
                                func (stream, arm_regnames[14] /* "lr" */);
                                func (stream, arm_regnames[14] /* "lr" */);
                              }
                              }
 
 
                            if (domaskpc)
                            if (domaskpc)
                              {
                              {
                                if (started)
                                if (started)
                                  func (stream, ", ");
                                  func (stream, ", ");
                                func (stream, arm_regnames[15] /* "pc" */);
                                func (stream, arm_regnames[15] /* "pc" */);
                              }
                              }
 
 
                            func (stream, "}");
                            func (stream, "}");
                          }
                          }
                          break;
                          break;
 
 
 
 
                        case '0': case '1': case '2': case '3': case '4':
                        case '0': case '1': case '2': case '3': case '4':
                        case '5': case '6': case '7': case '8': case '9':
                        case '5': case '6': case '7': case '8': case '9':
                          {
                          {
                            int bitstart = *c++ - '0';
                            int bitstart = *c++ - '0';
                            int bitend = 0;
                            int bitend = 0;
 
 
                            while (*c >= '0' && *c <= '9')
                            while (*c >= '0' && *c <= '9')
                              bitstart = (bitstart * 10) + *c++ - '0';
                              bitstart = (bitstart * 10) + *c++ - '0';
 
 
                            switch (*c)
                            switch (*c)
                              {
                              {
                              case '-':
                              case '-':
                                {
                                {
                                  long reg;
                                  long reg;
 
 
                                  c++;
                                  c++;
                                  while (*c >= '0' && *c <= '9')
                                  while (*c >= '0' && *c <= '9')
                                    bitend = (bitend * 10) + *c++ - '0';
                                    bitend = (bitend * 10) + *c++ - '0';
                                  if (!bitend)
                                  if (!bitend)
                                    abort ();
                                    abort ();
                                  reg = given >> bitstart;
                                  reg = given >> bitstart;
                                  reg &= (2 << (bitend - bitstart)) - 1;
                                  reg &= (2 << (bitend - bitstart)) - 1;
                                  switch (*c)
                                  switch (*c)
                                    {
                                    {
                                    case 'r':
                                    case 'r':
                                      func (stream, "%s", arm_regnames[reg]);
                                      func (stream, "%s", arm_regnames[reg]);
                                      break;
                                      break;
 
 
                                    case 'd':
                                    case 'd':
                                      func (stream, "%d", reg);
                                      func (stream, "%d", reg);
                                      break;
                                      break;
 
 
                                    case 'H':
                                    case 'H':
                                      func (stream, "%d", reg << 1);
                                      func (stream, "%d", reg << 1);
                                      break;
                                      break;
 
 
                                    case 'W':
                                    case 'W':
                                      func (stream, "%d", reg << 2);
                                      func (stream, "%d", reg << 2);
                                      break;
                                      break;
 
 
                                    case 'a':
                                    case 'a':
                                      /* PC-relative address -- the bottom two
                                      /* PC-relative address -- the bottom two
                                         bits of the address are dropped
                                         bits of the address are dropped
                                         before the calculation.  */
                                         before the calculation.  */
                                      info->print_address_func
                                      info->print_address_func
                                        (((pc + 4) & ~3) + (reg << 2), info);
                                        (((pc + 4) & ~3) + (reg << 2), info);
                                      break;
                                      break;
 
 
                                    case 'x':
                                    case 'x':
                                      func (stream, "0x%04x", reg);
                                      func (stream, "0x%04x", reg);
                                      break;
                                      break;
 
 
                                    case 'I':
                                    case 'I':
                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));
                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));
                                      func (stream, "%d", reg);
                                      func (stream, "%d", reg);
                                      break;
                                      break;
 
 
                                    case 'B':
                                    case 'B':
                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));
                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));
                                      (*info->print_address_func)
                                      (*info->print_address_func)
                                        (reg * 2 + pc + 4, info);
                                        (reg * 2 + pc + 4, info);
                                      break;
                                      break;
 
 
                                    default:
                                    default:
                                      abort ();
                                      abort ();
                                    }
                                    }
                                }
                                }
                                break;
                                break;
 
 
                              case '\'':
                              case '\'':
                                c++;
                                c++;
                                if ((given & (1 << bitstart)) != 0)
                                if ((given & (1 << bitstart)) != 0)
                                  func (stream, "%c", *c);
                                  func (stream, "%c", *c);
                                break;
                                break;
 
 
                              case '?':
                              case '?':
                                ++c;
                                ++c;
                                if ((given & (1 << bitstart)) != 0)
                                if ((given & (1 << bitstart)) != 0)
                                  func (stream, "%c", *c++);
                                  func (stream, "%c", *c++);
                                else
                                else
                                  func (stream, "%c", *++c);
                                  func (stream, "%c", *++c);
                                break;
                                break;
 
 
                              default:
                              default:
                                 abort ();
                                 abort ();
                              }
                              }
                          }
                          }
                          break;
                          break;
 
 
                        default:
                        default:
                          abort ();
                          abort ();
                        }
                        }
                    }
                    }
                  else
                  else
                    func (stream, "%c", *c);
                    func (stream, "%c", *c);
                }
                }
             }
             }
          return 2;
          return 2;
       }
       }
    }
    }
 
 
  /* No match.  */
  /* No match.  */
  abort ();
  abort ();
}
}
 
 
/* Parse an individual disassembler option.  */
/* Parse an individual disassembler option.  */
void
void
parse_arm_disassembler_option (option)
parse_arm_disassembler_option (option)
     char * option;
     char * option;
{
{
  if (option == NULL)
  if (option == NULL)
    return;
    return;
 
 
  if (strneq (option, "reg-names-", 10))
  if (strneq (option, "reg-names-", 10))
    {
    {
      int i;
      int i;
 
 
      option += 10;
      option += 10;
 
 
      for (i = NUM_ARM_REGNAMES; i--;)
      for (i = NUM_ARM_REGNAMES; i--;)
        if (streq (option, regnames[i].name))
        if (streq (option, regnames[i].name))
          {
          {
            regname_selected = i;
            regname_selected = i;
            break;
            break;
          }
          }
 
 
      if (i < 0)
      if (i < 0)
        fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
        fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
    }
    }
  else if (streq (option, "force-thumb"))
  else if (streq (option, "force-thumb"))
    force_thumb = 1;
    force_thumb = 1;
  else if (streq (option, "no-force-thumb"))
  else if (streq (option, "no-force-thumb"))
    force_thumb = 0;
    force_thumb = 0;
  else
  else
    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
 
 
  return;
  return;
}
}
 
 
/* Parse the string of disassembler options, spliting it at whitespaces.  */
/* Parse the string of disassembler options, spliting it at whitespaces.  */
static void
static void
parse_disassembler_options (options)
parse_disassembler_options (options)
     char * options;
     char * options;
{
{
  char * space;
  char * space;
 
 
  if (options == NULL)
  if (options == NULL)
    return;
    return;
 
 
  do
  do
    {
    {
      space = strchr (options, ' ');
      space = strchr (options, ' ');
 
 
      if (space)
      if (space)
        {
        {
          * space = '\0';
          * space = '\0';
          parse_arm_disassembler_option (options);
          parse_arm_disassembler_option (options);
          * space = ' ';
          * space = ' ';
          options = space + 1;
          options = space + 1;
        }
        }
      else
      else
        parse_arm_disassembler_option (options);
        parse_arm_disassembler_option (options);
    }
    }
  while (space);
  while (space);
}
}
 
 
/* NOTE: There are no checks in these routines that
/* NOTE: There are no checks in these routines that
   the relevant number of data bytes exist.  */
   the relevant number of data bytes exist.  */
static int
static int
print_insn (pc, info, little)
print_insn (pc, info, little)
     bfd_vma pc;
     bfd_vma pc;
     struct disassemble_info * info;
     struct disassemble_info * info;
     boolean little;
     boolean little;
{
{
  unsigned char      b[4];
  unsigned char      b[4];
  long               given;
  long               given;
  int                status;
  int                status;
  int                is_thumb;
  int                is_thumb;
 
 
  if (info->disassembler_options)
  if (info->disassembler_options)
    {
    {
      parse_disassembler_options (info->disassembler_options);
      parse_disassembler_options (info->disassembler_options);
 
 
      /* To avoid repeated parsing of these options, we remove them here.  */
      /* To avoid repeated parsing of these options, we remove them here.  */
      info->disassembler_options = NULL;
      info->disassembler_options = NULL;
    }
    }
 
 
  is_thumb = force_thumb;
  is_thumb = force_thumb;
 
 
  if (!is_thumb && info->symbols != NULL)
  if (!is_thumb && info->symbols != NULL)
    {
    {
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
        {
        {
          coff_symbol_type * cs;
          coff_symbol_type * cs;
 
 
          cs = coffsymbol (*info->symbols);
          cs = coffsymbol (*info->symbols);
          is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
          is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
                      || cs->native->u.syment.n_sclass == C_THUMBSTAT
                      || cs->native->u.syment.n_sclass == C_THUMBSTAT
                      || cs->native->u.syment.n_sclass == C_THUMBLABEL
                      || cs->native->u.syment.n_sclass == C_THUMBLABEL
                      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
                      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
                      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
                      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
        }
        }
      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
        {
        {
          elf_symbol_type *  es;
          elf_symbol_type *  es;
          unsigned int       type;
          unsigned int       type;
 
 
          es = *(elf_symbol_type **)(info->symbols);
          es = *(elf_symbol_type **)(info->symbols);
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
 
 
          is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
          is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
        }
        }
    }
    }
 
 
  info->bytes_per_chunk = 4;
  info->bytes_per_chunk = 4;
  info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
  info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
 
 
  if (little)
  if (little)
    {
    {
      status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
      status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
      if (status != 0 && is_thumb)
      if (status != 0 && is_thumb)
        {
        {
          info->bytes_per_chunk = 2;
          info->bytes_per_chunk = 2;
 
 
          status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
          status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
          b[3] = b[2] = 0;
          b[3] = b[2] = 0;
        }
        }
 
 
      if (status != 0)
      if (status != 0)
        {
        {
          info->memory_error_func (status, pc, info);
          info->memory_error_func (status, pc, info);
          return -1;
          return -1;
        }
        }
 
 
      given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
      given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
    }
    }
  else
  else
    {
    {
      status = info->read_memory_func
      status = info->read_memory_func
        (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
        (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
      if (status != 0)
      if (status != 0)
        {
        {
          info->memory_error_func (status, pc, info);
          info->memory_error_func (status, pc, info);
          return -1;
          return -1;
        }
        }
 
 
      if (is_thumb)
      if (is_thumb)
        {
        {
          if (pc & 0x2)
          if (pc & 0x2)
            {
            {
              given = (b[2] << 8) | b[3];
              given = (b[2] << 8) | b[3];
 
 
              status = info->read_memory_func
              status = info->read_memory_func
                ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
                ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
              if (status != 0)
              if (status != 0)
                {
                {
                  info->memory_error_func (status, pc + 4, info);
                  info->memory_error_func (status, pc + 4, info);
                  return -1;
                  return -1;
                }
                }
 
 
              given |= (b[0] << 24) | (b[1] << 16);
              given |= (b[0] << 24) | (b[1] << 16);
            }
            }
          else
          else
            given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
            given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
        }
        }
      else
      else
        given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
        given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
    }
    }
 
 
  if (is_thumb)
  if (is_thumb)
    status = print_insn_thumb (pc, info, given);
    status = print_insn_thumb (pc, info, given);
  else
  else
    status = print_insn_arm (pc, info, given);
    status = print_insn_arm (pc, info, given);
 
 
  return status;
  return status;
}
}
 
 
int
int
print_insn_big_arm (pc, info)
print_insn_big_arm (pc, info)
     bfd_vma pc;
     bfd_vma pc;
     struct disassemble_info * info;
     struct disassemble_info * info;
{
{
  return print_insn (pc, info, false);
  return print_insn (pc, info, false);
}
}
 
 
int
int
print_insn_little_arm (pc, info)
print_insn_little_arm (pc, info)
     bfd_vma pc;
     bfd_vma pc;
     struct disassemble_info * info;
     struct disassemble_info * info;
{
{
  return print_insn (pc, info, true);
  return print_insn (pc, info, true);
}
}
 
 
void
void
print_arm_disassembler_options (FILE * stream)
print_arm_disassembler_options (FILE * stream)
{
{
  int i;
  int i;
 
 
  fprintf (stream, _("\n\
  fprintf (stream, _("\n\
The following ARM specific disassembler options are supported for use with\n\
The following ARM specific disassembler options are supported for use with\n\
the -M switch:\n"));
the -M switch:\n"));
 
 
  for (i = NUM_ARM_REGNAMES; i--;)
  for (i = NUM_ARM_REGNAMES; i--;)
    fprintf (stream, "  reg-names-%s %*c%s\n",
    fprintf (stream, "  reg-names-%s %*c%s\n",
             regnames[i].name,
             regnames[i].name,
             14 - strlen (regnames[i].name), ' ',
             14 - strlen (regnames[i].name), ' ',
             regnames[i].description);
             regnames[i].description);
 
 
  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
  fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
  fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.