Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Enumerations | Functions | Variables
arm-dis.c File Reference
#include "sysdep.h"
#include "dis-asm.h"
#include "opcode/arm.h"
#include "opintl.h"
#include "safe-ctype.h"
#include "floatformat.h"
#include "coff/internal.h"
#include "libcoff.h"
#include "elf-bfd.h"
#include "elf/internal.h"
#include "elf/arm.h"

Go to the source code of this file.

Classes

struct  opcode32
struct  opcode16
struct  arm_regname

Defines

#define strneq(a, b, n)   (strncmp ((a), (b), (n)) == 0)
#define NUM_ELEM(a)   (sizeof (a) / sizeof (a)[0])
#define FIRST_IWMMXT_INSN   0x0e130130
#define IWMMXT_INSN_COUNT   73
#define NUM_ARM_REGNAMES   NUM_ELEM (regnames)
#define arm_regnames   regnames[regname_selected].reg_names
#define IFTHEN_COND   ((ifthen_state >> 4) & 0xf)

Enumerations

enum  map_type { MAP_ARM, MAP_THUMB, MAP_DATA }

Functions

enum map_type int
last_mapping_sym bfd_vma
last_mapping_addr int 
get_arm_regname_num_options (void)
int set_arm_regname_option (int option)
int get_arm_regnames (int option, const char **setname, const char **setdescription, const char *const **register_names)
static const char * arm_decode_bitfield (const char *ptr, unsigned long insn, unsigned long *valuep, int *widthp)
static void arm_decode_shift (long given, fprintf_ftype func, void *stream)
static bfd_boolean print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given, bfd_boolean thumb)
static void print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
static bfd_boolean print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
static void print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
static void print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
static const char * psr_name (int regno)
static void print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
static void print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info, long given)
bfd_boolean arm_symbol_is_valid (asymbol *sym, struct disassemble_info *info ATTRIBUTE_UNUSED)
void parse_arm_disassembler_option (char *option)
static void parse_disassembler_options (char *options)
static void find_ifthen_state (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
static int get_sym_code_type (struct disassemble_info *info, int n, enum map_type *map_type)
static int print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
int print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
int print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
void print_arm_disassembler_options (FILE *stream)

Variables

static struct opcode32 []
static struct opcode16 []
static const char *const arm_conditional []
static const char *const arm_fp_const []
static const char *const arm_shift []
static const arm_regname regnames []
static const char *const iwmmxt_wwnames []
static const char *const iwmmxt_wwssnames []
static const char *const iwmmxt_regnames []
static const char *const iwmmxt_cregnames []
static unsigned int regname_selected = 1
static bfd_boolean force_thumb = FALSE
static unsigned int ifthen_state
static unsigned int ifthen_next_state
static bfd_vma ifthen_address

Class Documentation

struct opcode32

Definition at line 47 of file arm-dis.c.

Class Members
unsigned long arch
const char * assembler
unsigned long mask
unsigned long value
struct opcode16

Definition at line 54 of file arm-dis.c.

Class Members
unsigned long arch
const char * assembler
unsigned short mask
unsigned short value
struct arm_regname

Definition at line 1423 of file arm-dis.c.

Class Members
const char * description
const char * name
const char * reg_names

Define Documentation

Definition at line 1471 of file arm-dis.c.

#define FIRST_IWMMXT_INSN   0x0e130130
#define IFTHEN_COND   ((ifthen_state >> 4) & 0xf)

Definition at line 1482 of file arm-dis.c.

#define IWMMXT_INSN_COUNT   73

Definition at line 1470 of file arm-dis.c.

#define NUM_ELEM (   a)    (sizeof (a) / sizeof (a)[0])

Definition at line 44 of file arm-dis.c.

#define strneq (   a,
  b,
  n 
)    (strncmp ((a), (b), (n)) == 0)

Definition at line 40 of file arm-dis.c.


Enumeration Type Documentation

enum map_type
Enumerator:
MAP_ARM 
MAP_THUMB 
MAP_DATA 

Definition at line 1485 of file arm-dis.c.


Function Documentation

static const char* arm_decode_bitfield ( const char *  ptr,
unsigned long  insn,
unsigned long valuep,
int widthp 
) [static]

Definition at line 1527 of file arm-dis.c.

{
  unsigned long value = 0;
  int width = 0;
  
  do 
    {
      int start, end;
      int bits;

      for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
       start = start * 10 + *ptr - '0';
      if (*ptr == '-')
       for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
         end = end * 10 + *ptr - '0';
      else
       end = start;
      bits = end - start;
      if (bits < 0)
       abort ();
      value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
      width += bits + 1;
    }
  while (*ptr++ == ',');
  *valuep = value;
  if (widthp)
    *widthp = width;
  return ptr - 1;
}

Here is the caller graph for this function:

static void arm_decode_shift ( long  given,
fprintf_ftype  func,
void *  stream 
) [static]

Definition at line 1559 of file arm-dis.c.

{
  func (stream, "%s", arm_regnames[given & 0xf]);

  if ((given & 0xff0) != 0)
    {
      if ((given & 0x10) == 0)
       {
         int amount = (given & 0xf80) >> 7;
         int shift = (given & 0x60) >> 5;

         if (amount == 0)
           {
             if (shift == 3)
              {
                func (stream, ", rrx");
                return;
              }

             amount = 32;
           }

         func (stream, ", %s #%d", arm_shift[shift], amount);
       }
      else
       func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
             arm_regnames[(given & 0xf00) >> 8]);
    }
}

Here is the caller graph for this function:

bfd_boolean arm_symbol_is_valid ( asymbol sym,
struct disassemble_info *info  ATTRIBUTE_UNUSED 
)

Definition at line 3752 of file arm-dis.c.

{
  const char * name;
  
  if (sym == NULL)
    return FALSE;

  name = bfd_asymbol_name (sym);

  return (name && *name != '$');
}
static void find_ifthen_state ( bfd_vma  pc,
struct disassemble_info info,
bfd_boolean  little 
) [static]

Definition at line 3826 of file arm-dis.c.

{
  unsigned char b[2];
  unsigned int insn;
  int status;
  /* COUNT is twice the number of instructions seen.  It will be odd if we
     just crossed an instruction boundary.  */
  int count;
  int it_count;
  unsigned int seen_it;
  bfd_vma addr;

  ifthen_address = pc;
  ifthen_state = 0;

  addr = pc;
  count = 1;
  it_count = 0;
  seen_it = 0;
  /* Scan backwards looking for IT instructions, keeping track of where
     instruction boundaries are.  We don't know if something is actually an
     IT instruction until we find a definite instruction boundary.  */
  for (;;)
    {
      if (addr == 0 || info->symbol_at_address_func(addr, info))
       {
         /* A symbol must be on an instruction boundary, and will not
            be within an IT block.  */
         if (seen_it && (count & 1))
           break;

         return;
       }
      addr -= 2;
      status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
      if (status)
       return;

      if (little)
       insn = (b[0]) | (b[1] << 8);
      else
       insn = (b[1]) | (b[0] << 8);
      if (seen_it)
       {
         if ((insn & 0xf800) < 0xe800)
           {
             /* Addr + 2 is an instruction boundary.  See if this matches
                the expected boundary based on the position of the last
               IT candidate.  */
             if (count & 1)
              break;
             seen_it = 0;
           }
       }
      if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
       {
         /* This could be an IT instruction.  */
         seen_it = insn;
         it_count = count >> 1;
       }
      if ((insn & 0xf800) >= 0xe800)
       count++;
      else
       count = (count + 2) | 1;
      /* IT blocks contain at most 4 instructions.  */
      if (count >= 8 && !seen_it)
       return;
    }
  /* We found an IT instruction.  */
  ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
  if ((ifthen_state & 0xf) == 0)
    ifthen_state = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

enum map_type int last_mapping_sym bfd_vma last_mapping_addr int get_arm_regname_num_options ( void  ) [abstract]

Definition at line 1498 of file arm-dis.c.

{
  return NUM_ARM_REGNAMES;
}
int get_arm_regnames ( int  option,
const char **  setname,
const char **  setdescription,
const char *const **  register_names 
)

Definition at line 1512 of file arm-dis.c.

{
  *setname = regnames[option].name;
  *setdescription = regnames[option].description;
  *register_names = regnames[option].reg_names;
  return 16;
}
static int get_sym_code_type ( struct disassemble_info info,
int  n,
enum map_type map_type 
) [static]

Definition at line 3905 of file arm-dis.c.

{
  elf_symbol_type *es;
  unsigned int type;
  const char *name;

  es = *(elf_symbol_type **)(info->symtab + n);
  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);

  /* If the symbol has function type then use that.  */
  if (type == STT_FUNC || type == STT_ARM_TFUNC)
    {
      *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
      return TRUE;
    }

  /* Check for mapping symbols.  */
  name = bfd_asymbol_name(info->symtab[n]);
  if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
      && (name[2] == 0 || name[2] == '.'))
    {
      *map_type = ((name[1] == 'a') ? MAP_ARM
                 : (name[1] == 't') ? MAP_THUMB
                 : MAP_DATA);
      return TRUE;
    }

  return FALSE;
}

Here is the caller graph for this function:

void parse_arm_disassembler_option ( char *  option)

Definition at line 3768 of file arm-dis.c.

{
  if (option == NULL)
    return;

  if (CONST_STRNEQ (option, "reg-names-"))
    {
      int i;

      option += 10;

      for (i = NUM_ARM_REGNAMES; i--;)
       if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
         {
           regname_selected = i;
           break;
         }

      if (i < 0)
       /* XXX - should break 'option' at following delimiter.  */
       fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
    }
  else if (CONST_STRNEQ (option, "force-thumb"))
    force_thumb = 1;
  else if (CONST_STRNEQ (option, "no-force-thumb"))
    force_thumb = 0;
  else
    /* XXX - should break 'option' at following delimiter.  */
    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void parse_disassembler_options ( char *  options) [static]

Definition at line 3805 of file arm-dis.c.

{
  if (options == NULL)
    return;

  while (*options)
    {
      parse_arm_disassembler_option (options);

      /* Skip forward to next seperator.  */
      while ((*options) && (! ISSPACE (*options)) && (*options != ','))
       ++ options;
      /* Skip forward past seperators.  */
      while (ISSPACE (*options) || (*options == ','))
       ++ options;      
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_arm_address ( bfd_vma  pc,
struct disassemble_info info,
long  given 
) [static]

Definition at line 2090 of file arm-dis.c.

{
  void *stream = info->stream;
  fprintf_ftype func = info->fprintf_func;

  if (((given & 0x000f0000) == 0x000f0000)
      && ((given & 0x02000000) == 0))
    {
      int offset = given & 0xfff;

      func (stream, "[pc");

      if (given & 0x01000000)
       {
         if ((given & 0x00800000) == 0)
           offset = - offset;

         /* Pre-indexed.  */
         func (stream, ", #%d]", offset);

         offset += pc + 8;

         /* Cope with the possibility of write-back
            being used.  Probably a very dangerous thing
            for the programmer to do, but who are we to
            argue ?  */
         if (given & 0x00200000)
           func (stream, "!");
       }
      else
       {
         /* Post indexed.  */
         func (stream, "], #%d", offset);

         /* ie ignore the offset.  */
         offset = pc + 8;
       }

      func (stream, "\t; ");
      info->print_address_func (offset, info);
    }
  else
    {
      func (stream, "[%s",
           arm_regnames[(given >> 16) & 0xf]);
      if ((given & 0x01000000) != 0)
       {
         if ((given & 0x02000000) == 0)
           {
             int offset = given & 0xfff;
             if (offset)
              func (stream, ", #%s%d",
                    (((given & 0x00800000) == 0)
                     ? "-" : ""), offset);
           }
         else
           {
             func (stream, ", %s",
                  (((given & 0x00800000) == 0)
                   ? "-" : ""));
             arm_decode_shift (given, func, stream);
           }

         func (stream, "]%s",
              ((given & 0x00200000) != 0) ? "!" : "");
       }
      else
       {
         if ((given & 0x02000000) == 0)
           {
             int offset = given & 0xfff;
             if (offset)
              func (stream, "], #%s%d",
                    (((given & 0x00800000) == 0)
                     ? "-" : ""), offset);
             else
              func (stream, "]");
           }
         else
           {
             func (stream, "], %s",
                  (((given & 0x00800000) == 0)
                   ? "-" : ""));
             arm_decode_shift (given, func, stream);
           }
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void print_arm_disassembler_options ( FILE *  stream)

Definition at line 4190 of file arm-dis.c.

{
  int i;

  fprintf (stream, _("\n\
The following ARM specific disassembler options are supported for use with\n\
the -M switch:\n"));

  for (i = NUM_ARM_REGNAMES; i--;)
    fprintf (stream, "  reg-names-%s %*c%s\n",
            regnames[i].name,
            (int)(14 - strlen (regnames[i].name)), ' ',
            regnames[i].description);

  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");
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int print_insn ( bfd_vma  pc,
struct disassemble_info info,
bfd_boolean  little 
) [static]

Definition at line 3940 of file arm-dis.c.

{
  unsigned char b[4];
  long        given;
  int           status;
  int           is_thumb = FALSE;
  int           is_data = FALSE;
  unsigned int       size = 4;
  void        (*printer) (bfd_vma, struct disassemble_info *, long);
  bfd_boolean   found = FALSE;

  if (info->disassembler_options)
    {
      parse_disassembler_options (info->disassembler_options);

      /* To avoid repeated parsing of these options, we remove them here.  */
      info->disassembler_options = NULL;
    }

  /* First check the full symtab for a mapping symbol, even if there
     are no usable non-mapping symbols for this address.  */
  if (info->symtab != NULL
      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
    {
      bfd_vma addr;
      int n;
      int last_sym = -1;
      enum map_type type;

      if (pc <= last_mapping_addr)
       last_mapping_sym = -1;
      is_thumb = (last_type == MAP_THUMB);
      found = FALSE;
      /* Start scanning at the start of the function, or wherever
        we finished last time.  */
      n = info->symtab_pos + 1;
      if (n < last_mapping_sym)
       n = last_mapping_sym;

      /* Scan up to the location being disassembled.  */
      for (; n < info->symtab_size; n++)
       {
         addr = bfd_asymbol_value (info->symtab[n]);
         if (addr > pc)
           break;
         if (get_sym_code_type (info, n, &type))
           {
             last_sym = n;
             found = TRUE;
           }
       }

      if (!found)
       {
         n = info->symtab_pos;
         if (n < last_mapping_sym - 1)
           n = last_mapping_sym - 1;

         /* No mapping symbol found at this address.  Look backwards
            for a preceeding one.  */
         for (; n >= 0; n--)
           {
             if (get_sym_code_type (info, n, &type))
              {
                last_sym = n;
                found = TRUE;
                break;
              }
           }
       }

      last_mapping_sym = last_sym;
      last_type = type;
      is_thumb = (last_type == MAP_THUMB);
      is_data = (last_type == MAP_DATA);

      /* Look a little bit ahead to see if we should print out
        two or four bytes of data.  If there's a symbol,
        mapping or otherwise, after two bytes then don't
        print more.  */
      if (is_data)
       {
         size = 4 - (pc & 3);
         for (n = last_sym + 1; n < info->symtab_size; n++)
           {
             addr = bfd_asymbol_value (info->symtab[n]);
             if (addr > pc)
              {
                if (addr - pc < size)
                  size = addr - pc;
                break;
              }
           }
         /* If the next symbol is after three bytes, we need to
            print only part of the data, so that we can use either
            .byte or .short.  */
         if (size == 3)
           size = (pc & 1) ? 1 : 2;
       }
    }

  if (info->symbols != NULL)
    {
      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
       {
         coff_symbol_type * cs;

         cs = coffsymbol (*info->symbols);
         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_THUMBLABEL
                    || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
                    || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
       }
      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
              && !found)
       {
         /* If no mapping symbol has been found then fall back to the type
            of the function symbol.  */
         elf_symbol_type *  es;
         unsigned int       type;

         es = *(elf_symbol_type **)(info->symbols);
         type = ELF_ST_TYPE (es->internal_elf_sym.st_info);

         is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
       }
    }

  if (force_thumb)
    is_thumb = TRUE;

  info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
  info->bytes_per_line = 4;

  if (is_data)
    {
      int i;

      /* size was already set above.  */
      info->bytes_per_chunk = size;
      printer = print_insn_data;

      status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
      given = 0;
      if (little)
       for (i = size - 1; i >= 0; i--)
         given = b[i] | (given << 8);
      else
       for (i = 0; i < (int) size; i++)
         given = b[i] | (given << 8);
    }
  else if (!is_thumb)
    {
      /* In ARM mode endianness is a straightforward issue: the instruction
        is four bytes long and is either ordered 0123 or 3210.  */
      printer = print_insn_arm;
      info->bytes_per_chunk = 4;
      size = 4;

      status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
      if (little)
       given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
      else
       given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
    }
  else
    {
      /* In Thumb mode we have the additional wrinkle of two
        instruction lengths.  Fortunately, the bits that determine
        the length of the current instruction are always to be found
        in the first two bytes.  */
      printer = print_insn_thumb16;
      info->bytes_per_chunk = 2;
      size = 2;

      status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
      if (little)
       given = (b[0]) | (b[1] << 8);
      else
       given = (b[1]) | (b[0] << 8);

      if (!status)
       {
         /* These bit patterns signal a four-byte Thumb
            instruction.  */
         if ((given & 0xF800) == 0xF800
             || (given & 0xF800) == 0xF000
             || (given & 0xF800) == 0xE800)
           {
             status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
             if (little)
              given = (b[0]) | (b[1] << 8) | (given << 16);
             else
              given = (b[1]) | (b[0] << 8) | (given << 16);

             printer = print_insn_thumb32;
             size = 4;
           }
       }

      if (ifthen_address != pc)
       find_ifthen_state(pc, info, little);

      if (ifthen_state)
       {
         if ((ifthen_state & 0xf) == 0x8)
           ifthen_next_state = 0;
         else
           ifthen_next_state = (ifthen_state & 0xe0)
                            | ((ifthen_state & 0xf) << 1);
       }
    }

  if (status)
    {
      info->memory_error_func (status, pc, info);
      return -1;
    }
  if (info->flags & INSN_HAS_RELOC)
    /* If the instruction has a reloc associated with it, then
       the offset field in the instruction will actually be the
       addend for the reloc.  (We are using REL type relocs).
       In such cases, we can ignore the pc when computing
       addresses, since the addend is not currently pc-relative.  */
    pc = 0;

  printer (pc, info, given);

  if (is_thumb)
    {
      ifthen_state = ifthen_next_state;
      ifthen_address += size;
    }
  return size;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_insn_arm ( bfd_vma  pc,
struct disassemble_info info,
long  given 
) [static]

Definition at line 2641 of file arm-dis.c.

{
  const struct opcode32 *insn;
  void *stream = info->stream;
  fprintf_ftype func = info->fprintf_func;

  if (print_insn_coprocessor (pc, info, given, FALSE))
    return;

  if (print_insn_neon (info, given, FALSE))
    return;

  for (insn = arm_opcodes; insn->assembler; insn++)
    {
      if (insn->value == FIRST_IWMMXT_INSN
         && info->mach != bfd_mach_arm_XScale
         && info->mach != bfd_mach_arm_iWMMXt)
       insn = insn + IWMMXT_INSN_COUNT;

      if ((given & insn->mask) == insn->value
         /* Special case: an instruction with all bits set in the condition field
            (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
            or by the catchall at the end of the table.  */
         && ((given & 0xF0000000) != 0xF0000000
             || (insn->mask & 0xF0000000) == 0xF0000000
             || (insn->mask == 0 && insn->value == 0)))
       {
         const char *c;

         for (c = insn->assembler; *c; c++)
           {
             if (*c == '%')
              {
                switch (*++c)
                  {
                  case '%':
                    func (stream, "%%");
                    break;

                  case 'a':
                    print_arm_address (pc, info, given);
                    break;

                  case 'P':
                    /* Set P address bit and use normal address
                      printing routine.  */
                    print_arm_address (pc, info, given | (1 << 24));
                    break;

                  case 's':
                      if ((given & 0x004f0000) == 0x004f0000)
                     {
                          /* PC relative with immediate offset.  */
                       int offset = ((given & 0xf00) >> 4) | (given & 0xf);

                       if ((given & 0x00800000) == 0)
                         offset = -offset;

                       func (stream, "[pc, #%d]\t; ", offset);
                       info->print_address_func (offset + pc + 8, info);
                     }
                    else
                     {
                       func (stream, "[%s",
                            arm_regnames[(given >> 16) & 0xf]);
                       if ((given & 0x01000000) != 0)
                         {
                              /* Pre-indexed.  */
                           if ((given & 0x00400000) == 0x00400000)
                            {
                                  /* Immediate.  */
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                              if (offset)
                                func (stream, ", #%s%d",
                                     (((given & 0x00800000) == 0)
                                      ? "-" : ""), offset);
                            }
                           else
                            {
                                  /* Register.  */
                              func (stream, ", %s%s",
                                   (((given & 0x00800000) == 0)
                                    ? "-" : ""),
                                        arm_regnames[given & 0xf]);
                            }

                           func (stream, "]%s",
                                ((given & 0x00200000) != 0) ? "!" : "");
                         }
                       else
                         {
                              /* Post-indexed.  */
                           if ((given & 0x00400000) == 0x00400000)
                            {
                                  /* Immediate.  */
                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                              if (offset)
                                func (stream, "], #%s%d",
                                     (((given & 0x00800000) == 0)
                                      ? "-" : ""), offset);
                              else
                                func (stream, "]");
                            }
                           else
                            {
                                  /* Register.  */
                              func (stream, "], %s%s",
                                   (((given & 0x00800000) == 0)
                                    ? "-" : ""),
                                        arm_regnames[given & 0xf]);
                            }
                         }
                     }
                    break;

                  case 'b':
                    {
                     int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
                     info->print_address_func (disp*4 + pc + 8, info);
                    }
                    break;

                  case 'c':
                    if (((given >> 28) & 0xf) != 0xe)
                     func (stream, "%s",
                           arm_conditional [(given >> 28) & 0xf]);
                    break;

                  case 'm':
                    {
                     int started = 0;
                     int reg;

                     func (stream, "{");
                     for (reg = 0; reg < 16; reg++)
                       if ((given & (1 << reg)) != 0)
                         {
                           if (started)
                            func (stream, ", ");
                           started = 1;
                           func (stream, "%s", arm_regnames[reg]);
                         }
                     func (stream, "}");
                    }
                    break;

                  case 'o':
                    if ((given & 0x02000000) != 0)
                     {
                       int rotate = (given & 0xf00) >> 7;
                       int immed = (given & 0xff);
                       immed = (((immed << (32 - rotate))
                                | (immed >> rotate)) & 0xffffffff);
                       func (stream, "#%d\t; 0x%x", immed, immed);
                     }
                    else
                     arm_decode_shift (given, func, stream);
                    break;

                  case 'p':
                    if ((given & 0x0000f000) == 0x0000f000)
                     func (stream, "p");
                    break;

                  case 't':
                    if ((given & 0x01200000) == 0x00200000)
                     func (stream, "t");
                    break;

                  case 'A':
                    func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);

                    if ((given & (1 << 24)) != 0)
                     {
                       int offset = given & 0xff;

                       if (offset)
                         func (stream, ", #%s%d]%s",
                              ((given & 0x00800000) == 0 ? "-" : ""),
                              offset * 4,
                              ((given & 0x00200000) != 0 ? "!" : ""));
                       else
                         func (stream, "]");
                     }
                    else
                     {
                       int offset = given & 0xff;

                       func (stream, "]");

                       if (given & (1 << 21))
                         {
                           if (offset)
                            func (stream, ", #%s%d",
                                  ((given & 0x00800000) == 0 ? "-" : ""),
                                  offset * 4);
                         }
                       else
                         func (stream, ", {%d}", offset);
                     }
                    break;

                  case 'B':
                    /* Print ARM V5 BLX(1) address: pc+25 bits.  */
                    {
                     bfd_vma address;
                     bfd_vma offset = 0;

                     if (given & 0x00800000)
                       /* Is signed, hi bits should be ones.  */
                       offset = (-1) ^ 0x00ffffff;

                     /* Offset is (SignExtend(offset field)<<2).  */
                     offset += given & 0x00ffffff;
                     offset <<= 2;
                     address = offset + pc + 8;

                     if (given & 0x01000000)
                       /* H bit allows addressing to 2-byte boundaries.  */
                       address += 2;

                      info->print_address_func (address, info);
                    }
                    break;

                  case 'C':
                    func (stream, "_");
                    if (given & 0x80000)
                     func (stream, "f");
                    if (given & 0x40000)
                     func (stream, "s");
                    if (given & 0x20000)
                     func (stream, "x");
                    if (given & 0x10000)
                     func (stream, "c");
                    break;

                  case 'U':
                    switch (given & 0xf)
                     {
                     case 0xf: func(stream, "sy"); break;
                     case 0x7: func(stream, "un"); break;
                     case 0xe: func(stream, "st"); break;
                     case 0x6: func(stream, "unst"); break;
                     default:
                       func(stream, "#%d", (int)given & 0xf);
                       break;
                     }
                    break;

                  case '0': case '1': case '2': case '3': case '4':
                  case '5': case '6': case '7': case '8': case '9':
                    {
                     int width;
                     unsigned long value;

                     c = arm_decode_bitfield (c, given, &value, &width);
                     
                     switch (*c)
                       {
                       case 'r':
                         func (stream, "%s", arm_regnames[value]);
                         break;
                       case 'd':
                         func (stream, "%ld", value);
                         break;
                       case 'b':
                         func (stream, "%ld", value * 8);
                         break;
                       case 'W':
                         func (stream, "%ld", value + 1);
                         break;
                       case 'x':
                         func (stream, "0x%08lx", value);

                         /* Some SWI instructions have special
                            meanings.  */
                         if ((given & 0x0fffffff) == 0x0FF00000)
                           func (stream, "\t; IMB");
                         else if ((given & 0x0fffffff) == 0x0FF00001)
                           func (stream, "\t; IMBRange");
                         break;
                       case 'X':
                         func (stream, "%01lx", value & 0xf);
                         break;
                       case '`':
                         c++;
                         if (value == 0)
                           func (stream, "%c", *c);
                         break;
                       case '\'':
                         c++;
                         if (value == ((1ul << width) - 1))
                           func (stream, "%c", *c);
                         break;
                       case '?':
                         func (stream, "%c", c[(1 << width) - (int)value]);
                         c += 1 << width;
                         break;
                       default:
                         abort ();
                       }
                     break;

                    case 'e':
                     {
                       int imm;

                       imm = (given & 0xf) | ((given & 0xfff00) >> 4);
                       func (stream, "%d", imm);
                     }
                     break;

                    case 'E':
                     /* LSB and WIDTH fields of BFI or BFC.  The machine-
                        language instruction encodes LSB and MSB.  */
                     {
                       long msb = (given & 0x001f0000) >> 16;
                       long lsb = (given & 0x00000f80) >> 7;

                       long width = msb - lsb + 1;
                       if (width > 0)
                         func (stream, "#%lu, #%lu", lsb, width);
                       else
                         func (stream, "(invalid: %lu:%lu)", lsb, msb);
                     }
                     break;

                    case 'V':
                     /* 16-bit unsigned immediate from a MOVT or MOVW
                        instruction, encoded in bits 0:11 and 15:19.  */
                     {
                       long hi = (given & 0x000f0000) >> 4;
                       long lo = (given & 0x00000fff);
                       long imm16 = hi | lo;
                       func (stream, "#%lu\t; 0x%lx", imm16, imm16);
                     }
                     break;

                    default:
                     abort ();
                    }
                  }
              }
             else
              func (stream, "%c", *c);
           }
         return;
       }
    }
  abort ();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4178 of file arm-dis.c.

{
  return print_insn (pc, info, FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean print_insn_coprocessor ( bfd_vma  pc,
struct disassemble_info info,
long  given,
bfd_boolean  thumb 
) [static]

Definition at line 1594 of file arm-dis.c.

{
  const struct opcode32 *insn;
  void *stream = info->stream;
  fprintf_ftype func = info->fprintf_func;
  unsigned long mask;
  unsigned long value;
  int cond;

  for (insn = coprocessor_opcodes; insn->assembler; insn++)
    {
      if (insn->value == FIRST_IWMMXT_INSN
         && info->mach != bfd_mach_arm_XScale
         && info->mach != bfd_mach_arm_iWMMXt
         && info->mach != bfd_mach_arm_iWMMXt2)
       insn = insn + IWMMXT_INSN_COUNT;

      mask = insn->mask;
      value = insn->value;
      if (thumb)
       {
         /* The high 4 bits are 0xe for Arm conditional instructions, and
            0xe for arm unconditional instructions.  The rest of the
            encoding is the same.  */
         mask |= 0xf0000000;
         value |= 0xe0000000;
         if (ifthen_state)
           cond = IFTHEN_COND;
         else
           cond = 16;
       }
      else
       {
         /* Only match unconditional instuctions against unconditional
            patterns.  */
         if ((given & 0xf0000000) == 0xf0000000)
           {
             mask |= 0xf0000000;
             cond = 16;
           }
         else
           {
             cond = (given >> 28) & 0xf;
             if (cond == 0xe)
              cond = 16;
           }
       }
      if ((given & mask) == value)
       {
         const char *c;

         for (c = insn->assembler; *c; c++)
           {
             if (*c == '%')
              {
                switch (*++c)
                  {
                  case '%':
                    func (stream, "%%");
                    break;

                  case 'A':
                    func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);

                    if ((given & (1 << 24)) != 0)
                     {
                       int offset = given & 0xff;

                       if (offset)
                         func (stream, ", #%s%d]%s",
                              ((given & 0x00800000) == 0 ? "-" : ""),
                              offset * 4,
                              ((given & 0x00200000) != 0 ? "!" : ""));
                       else
                         func (stream, "]");
                     }
                    else
                     {
                       int offset = given & 0xff;

                       func (stream, "]");

                       if (given & (1 << 21))
                         {
                           if (offset)
                            func (stream, ", #%s%d",
                                  ((given & 0x00800000) == 0 ? "-" : ""),
                                  offset * 4);
                         }
                       else
                         func (stream, ", {%d}", offset);
                     }
                    break;

                  case 'B':
                    {
                     int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
                     int offset = (given >> 1) & 0x3f;
                     
                     if (offset == 1)
                       func (stream, "{d%d}", regno);
                     else if (regno + offset > 32)
                       func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
                     else
                       func (stream, "{d%d-d%d}", regno, regno + offset - 1);
                    }
                    break;
                    
                  case 'C':
                    {
                     int rn = (given >> 16) & 0xf;
                     int offset = (given & 0xff) * 4;
                     int add = (given >> 23) & 1;
                     
                     func (stream, "[%s", arm_regnames[rn]);
                     
                     if (offset)
                       {
                         if (!add)
                           offset = -offset;
                         func (stream, ", #%d", offset);
                       }
                     func (stream, "]");
                     if (rn == 15)
                       {
                         func (stream, "\t; ");
                            /* FIXME: Unsure if info->bytes_per_chunk is the
                               right thing to use here.  */
                         info->print_address_func (offset + pc
                              + info->bytes_per_chunk * 2, info);
                       }
                    }
                    break;

                  case 'c':
                    func (stream, "%s", arm_conditional[cond]);
                    break;

                  case 'I':
                    /* Print a Cirrus/DSP shift immediate.  */
                    /* Immediates are 7bit signed ints with bits 0..3 in
                      bits 0..3 of opcode and bits 4..6 in bits 5..7
                      of opcode.  */
                    {
                     int imm;

                     imm = (given & 0xf) | ((given & 0xe0) >> 1);

                     /* Is ``imm'' a negative number?  */
                     if (imm & 0x40)
                       imm |= (-1 << 7);

                     func (stream, "%d", imm);
                    }

                    break;

                  case 'F':
                    switch (given & 0x00408000)
                     {
                     case 0:
                       func (stream, "4");
                       break;
                     case 0x8000:
                       func (stream, "1");
                       break;
                     case 0x00400000:
                       func (stream, "2");
                       break;
                     default:
                       func (stream, "3");
                     }
                    break;

                  case 'P':
                    switch (given & 0x00080080)
                     {
                     case 0:
                       func (stream, "s");
                       break;
                     case 0x80:
                       func (stream, "d");
                       break;
                     case 0x00080000:
                       func (stream, "e");
                       break;
                     default:
                       func (stream, _("<illegal precision>"));
                       break;
                     }
                    break;
                  case 'Q':
                    switch (given & 0x00408000)
                     {
                     case 0:
                       func (stream, "s");
                       break;
                     case 0x8000:
                       func (stream, "d");
                       break;
                     case 0x00400000:
                       func (stream, "e");
                       break;
                     default:
                       func (stream, "p");
                       break;
                     }
                    break;
                  case 'R':
                    switch (given & 0x60)
                     {
                     case 0:
                       break;
                     case 0x20:
                       func (stream, "p");
                       break;
                     case 0x40:
                       func (stream, "m");
                       break;
                     default:
                       func (stream, "z");
                       break;
                     }
                    break;

                  case '0': case '1': case '2': case '3': case '4':
                  case '5': case '6': case '7': case '8': case '9':
                    {
                     int width;
                     unsigned long value;

                     c = arm_decode_bitfield (c, given, &value, &width);

                     switch (*c)
                       {
                       case 'r':
                         func (stream, "%s", arm_regnames[value]);
                         break;
                       case 'D':
                         func (stream, "d%ld", value);
                         break;
                       case 'Q':
                         if (value & 1)
                           func (stream, "<illegal reg q%ld.5>", value >> 1);
                         else
                           func (stream, "q%ld", value >> 1);
                         break;
                       case 'd':
                         func (stream, "%ld", value);
                         break;
                          case 'k':
                            {
                              int from = (given & (1 << 7)) ? 32 : 16;
                              func (stream, "%ld", from - value);
                            }
                            break;
                            
                       case 'f':
                         if (value > 7)
                           func (stream, "#%s", arm_fp_const[value & 7]);
                         else
                           func (stream, "f%ld", value);
                         break;

                       case 'w':
                         if (width == 2)
                           func (stream, "%s", iwmmxt_wwnames[value]);
                         else
                           func (stream, "%s", iwmmxt_wwssnames[value]);
                         break;

                       case 'g':
                         func (stream, "%s", iwmmxt_regnames[value]);
                         break;
                       case 'G':
                         func (stream, "%s", iwmmxt_cregnames[value]);
                         break;

                       case 'x':
                         func (stream, "0x%lx", value);
                         break;

                       case '`':
                         c++;
                         if (value == 0)
                           func (stream, "%c", *c);
                         break;
                       case '\'':
                         c++;
                         if (value == ((1ul << width) - 1))
                           func (stream, "%c", *c);
                         break;
                       case '?':
                         func (stream, "%c", c[(1 << width) - (int)value]);
                         c += 1 << width;
                         break;
                       default:
                         abort ();
                       }
                     break;

                    case 'y':
                    case 'z':
                     {
                       int single = *c++ == 'y';
                       int regno;
                       
                       switch (*c)
                         {
                         case '4': /* Sm pair */
                           func (stream, "{");
                           /* Fall through.  */
                         case '0': /* Sm, Dm */
                           regno = given & 0x0000000f;
                           if (single)
                            {
                              regno <<= 1;
                              regno += (given >> 5) & 1;
                            }
                              else
                                regno += ((given >> 5) & 1) << 4;
                           break;

                         case '1': /* Sd, Dd */
                           regno = (given >> 12) & 0x0000000f;
                           if (single)
                            {
                              regno <<= 1;
                              regno += (given >> 22) & 1;
                            }
                              else
                                regno += ((given >> 22) & 1) << 4;
                           break;

                         case '2': /* Sn, Dn */
                           regno = (given >> 16) & 0x0000000f;
                           if (single)
                            {
                              regno <<= 1;
                              regno += (given >> 7) & 1;
                            }
                              else
                                regno += ((given >> 7) & 1) << 4;
                           break;
                           
                         case '3': /* List */
                           func (stream, "{");
                           regno = (given >> 12) & 0x0000000f;
                           if (single)
                            {
                              regno <<= 1;
                              regno += (given >> 22) & 1;
                            }
                              else
                                regno += ((given >> 22) & 1) << 4;
                           break;
                           
                         default:
                           abort ();
                         }

                       func (stream, "%c%d", single ? 's' : 'd', regno);

                       if (*c == '3')
                         {
                           int count = given & 0xff;
                           
                           if (single == 0)
                            count >>= 1;
                           
                           if (--count)
                            {
                              func (stream, "-%c%d",
                                   single ? 's' : 'd',
                                   regno + count);
                            }
                           
                           func (stream, "}");
                         }
                       else if (*c == '4')
                         func (stream, ", %c%d}", single ? 's' : 'd',
                              regno + 1);
                     }
                     break;
                         
                    case 'L':
                     switch (given & 0x00400100)
                       {
                       case 0x00000000: func (stream, "b"); break;
                       case 0x00400000: func (stream, "h"); break;
                       case 0x00000100: func (stream, "w"); break;
                       case 0x00400100: func (stream, "d"); break;
                       default:
                         break;
                       }
                     break;

                    case 'Z':
                     {
                       int value;
                       /* given (20, 23) | given (0, 3) */
                       value = ((given >> 16) & 0xf0) | (given & 0xf);
                       func (stream, "%d", value);
                     }
                     break;

                    case 'l':
                     /* This is like the 'A' operator, except that if
                        the width field "M" is zero, then the offset is
                        *not* multiplied by four.  */
                     {
                       int offset = given & 0xff;
                       int multiplier = (given & 0x00000100) ? 4 : 1;

                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);

                       if (offset)
                         {
                           if ((given & 0x01000000) != 0)
                            func (stream, ", #%s%d]%s",
                                  ((given & 0x00800000) == 0 ? "-" : ""),
                                  offset * multiplier,
                                  ((given & 0x00200000) != 0 ? "!" : ""));
                           else
                            func (stream, "], #%s%d",
                                  ((given & 0x00800000) == 0 ? "-" : ""),
                                  offset * multiplier);
                         }
                       else
                         func (stream, "]");
                     }
                     break;

                    case 'r':
                     {
                       int imm4 = (given >> 4) & 0xf;
                       int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
                       int ubit = (given >> 23) & 1;
                       const char *rm = arm_regnames [given & 0xf];
                       const char *rn = arm_regnames [(given >> 16) & 0xf];

                       switch (puw_bits)
                         {
                         case 1:
                           /* fall through */
                         case 3:
                           func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
                           if (imm4)
                            func (stream, ", lsl #%d", imm4);
                           break;

                         case 4:
                           /* fall through */
                         case 5:
                           /* fall through */
                         case 6:
                           /* fall through */
                         case 7:
                           func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
                           if (imm4 > 0)
                            func (stream, ", lsl #%d", imm4);
                           func (stream, "]");
                           if (puw_bits == 5 || puw_bits == 7)
                            func (stream, "!");
                           break;

                         default:
                           func (stream, "INVALID");
                         }
                     }
                     break;

                    case 'i':
                     {
                       long imm5;
                       imm5 = ((given & 0x100) >> 4) | (given & 0xf);
                       func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
                     }
                     break;

                    default:
                     abort ();
                    }
                  }
              }
             else
              func (stream, "%c", *c);
           }
         return TRUE;
       }
    }
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_insn_data ( bfd_vma pc  ATTRIBUTE_UNUSED,
struct disassemble_info info,
long  given 
) [static]

Definition at line 3729 of file arm-dis.c.

{
  switch (info->bytes_per_chunk)
    {
    case 1:
      info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
      break;
    case 2:
      info->fprintf_func (info->stream, ".short\t0x%04lx", given);
      break;
    case 4:
      info->fprintf_func (info->stream, ".word\t0x%08lx", given);
      break;
    default:
      abort ();
    }
}

Here is the caller graph for this function:

Definition at line 4184 of file arm-dis.c.

{
  return print_insn (pc, info, TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean print_insn_neon ( struct disassemble_info info,
long  given,
bfd_boolean  thumb 
) [static]

Definition at line 2184 of file arm-dis.c.

{
  const struct opcode32 *insn;
  void *stream = info->stream;
  fprintf_ftype func = info->fprintf_func;

  if (thumb)
    {
      if ((given & 0xef000000) == 0xef000000)
       {
         /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding.  */
         unsigned long bit28 = given & (1 << 28);

         given &= 0x00ffffff;
         if (bit28)
            given |= 0xf3000000;
          else
           given |= 0xf2000000;
       }
      else if ((given & 0xff000000) == 0xf9000000)
       given ^= 0xf9000000 ^ 0xf4000000;
      else
       return FALSE;
    }
  
  for (insn = neon_opcodes; insn->assembler; insn++)
    {
      if ((given & insn->mask) == insn->value)
       {
         const char *c;

         for (c = insn->assembler; *c; c++)
           {
             if (*c == '%')
              {
                switch (*++c)
                  {
                  case '%':
                    func (stream, "%%");
                    break;

                  case 'c':
                    if (thumb && ifthen_state)
                     func (stream, "%s", arm_conditional[IFTHEN_COND]);
                    break;

                  case 'A':
                    {
                     static const unsigned char enc[16] = 
                     {
                       0x4, 0x14, /* st4 0,1 */
                       0x4, /* st1 2 */
                       0x4, /* st2 3 */
                       0x3, /* st3 4 */
                       0x13, /* st3 5 */
                       0x3, /* st1 6 */
                       0x1, /* st1 7 */
                       0x2, /* st2 8 */
                       0x12, /* st2 9 */
                       0x2, /* st1 10 */
                       0, 0, 0, 0, 0
                     };
                     int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
                     int rn = ((given >> 16) & 0xf);
                     int rm = ((given >> 0) & 0xf);
                     int align = ((given >> 4) & 0x3);
                     int type = ((given >> 8) & 0xf);
                     int n = enc[type] & 0xf;
                     int stride = (enc[type] >> 4) + 1;
                     int ix;
                     
                     func (stream, "{");
                     if (stride > 1)
                       for (ix = 0; ix != n; ix++)
                         func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
                     else if (n == 1)
                       func (stream, "d%d", rd);
                     else
                       func (stream, "d%d-d%d", rd, rd + n - 1);
                     func (stream, "}, [%s", arm_regnames[rn]);
                     if (align)
                       func (stream, ", :%d", 32 << align);
                     func (stream, "]");
                     if (rm == 0xd)
                       func (stream, "!");
                     else if (rm != 0xf)
                       func (stream, ", %s", arm_regnames[rm]);
                    }
                    break;
                    
                  case 'B':
                    {
                     int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
                     int rn = ((given >> 16) & 0xf);
                     int rm = ((given >> 0) & 0xf);
                     int idx_align = ((given >> 4) & 0xf);
                        int align = 0;
                     int size = ((given >> 10) & 0x3);
                     int idx = idx_align >> (size + 1);
                        int length = ((given >> 8) & 3) + 1;
                        int stride = 1;
                        int i;

                        if (length > 1 && size > 0)
                          stride = (idx_align & (1 << size)) ? 2 : 1;
                     
                        switch (length)
                          {
                          case 1:
                            {
                              int amask = (1 << size) - 1;
                              if ((idx_align & (1 << size)) != 0)
                                return FALSE;
                              if (size > 0)
                                {
                                  if ((idx_align & amask) == amask)
                                    align = 8 << size;
                                  else if ((idx_align & amask) != 0)
                                    return FALSE;
                                }
                              }
                            break;
                          
                          case 2:
                            if (size == 2 && (idx_align & 2) != 0)
                              return FALSE;
                            align = (idx_align & 1) ? 16 << size : 0;
                            break;
                          
                          case 3:
                            if ((size == 2 && (idx_align & 3) != 0)
                                || (idx_align & 1) != 0)
                              return FALSE;
                            break;
                          
                          case 4:
                            if (size == 2)
                              {
                                if ((idx_align & 3) == 3)
                                  return FALSE;
                                align = (idx_align & 3) * 64;
                              }
                            else
                              align = (idx_align & 1) ? 32 << size : 0;
                            break;
                          
                          default:
                            abort ();
                          }
                                
                     func (stream, "{");
                        for (i = 0; i < length; i++)
                          func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
                            rd + i * stride, idx);
                        func (stream, "}, [%s", arm_regnames[rn]);
                     if (align)
                       func (stream, ", :%d", align);
                     func (stream, "]");
                     if (rm == 0xd)
                       func (stream, "!");
                     else if (rm != 0xf)
                       func (stream, ", %s", arm_regnames[rm]);
                    }
                    break;
                    
                  case 'C':
                    {
                     int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
                     int rn = ((given >> 16) & 0xf);
                     int rm = ((given >> 0) & 0xf);
                     int align = ((given >> 4) & 0x1);
                     int size = ((given >> 6) & 0x3);
                     int type = ((given >> 8) & 0x3);
                     int n = type + 1;
                     int stride = ((given >> 5) & 0x1);
                     int ix;
                     
                     if (stride && (n == 1))
                       n++;
                     else
                       stride++;
                     
                     func (stream, "{");
                     if (stride > 1)
                       for (ix = 0; ix != n; ix++)
                         func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
                     else if (n == 1)
                       func (stream, "d%d[]", rd);
                     else
                       func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
                     func (stream, "}, [%s", arm_regnames[rn]);
                     if (align)
                       {
                            int align = (8 * (type + 1)) << size;
                            if (type == 3)
                              align = (size > 1) ? align >> 1 : align;
                         if (type == 2 || (type == 0 && !size))
                           func (stream, ", :<bad align %d>", align);
                         else
                           func (stream, ", :%d", align);
                       }
                     func (stream, "]");
                     if (rm == 0xd)
                       func (stream, "!");
                     else if (rm != 0xf)
                       func (stream, ", %s", arm_regnames[rm]);
                    }
                    break;
                    
                  case 'D':
                    {
                     int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
                     int size = (given >> 20) & 3;
                     int reg = raw_reg & ((4 << size) - 1);
                     int ix = raw_reg >> size >> 2;
                     
                     func (stream, "d%d[%d]", reg, ix);
                    }
                    break;
                    
                  case 'E':
                    /* Neon encoded constant for mov, mvn, vorr, vbic */
                    {
                     int bits = 0;
                     int cmode = (given >> 8) & 0xf;
                     int op = (given >> 5) & 0x1;
                     unsigned long value = 0, hival = 0;
                     unsigned shift;
                        int size = 0;
                        int isfloat = 0;
                     
                     bits |= ((given >> 24) & 1) << 7;
                     bits |= ((given >> 16) & 7) << 4;
                     bits |= ((given >> 0) & 15) << 0;
                     
                     if (cmode < 8)
                       {
                         shift = (cmode >> 1) & 3;
                         value = (unsigned long)bits << (8 * shift);
                            size = 32;
                       }
                     else if (cmode < 12)
                       {
                         shift = (cmode >> 1) & 1;
                         value = (unsigned long)bits << (8 * shift);
                            size = 16;
                       }
                     else if (cmode < 14)
                       {
                         shift = (cmode & 1) + 1;
                         value = (unsigned long)bits << (8 * shift);
                         value |= (1ul << (8 * shift)) - 1;
                            size = 32;
                       }
                     else if (cmode == 14)
                       {
                         if (op)
                           {
                            /* bit replication into bytes */
                            int ix;
                            unsigned long mask;
                            
                            value = 0;
                                hival = 0;
                            for (ix = 7; ix >= 0; ix--)
                              {
                                mask = ((bits >> ix) & 1) ? 0xff : 0;
                                    if (ix <= 3)
                                  value = (value << 8) | mask;
                                    else
                                      hival = (hival << 8) | mask;
                              }
                                size = 64;
                           }
                            else
                              {
                                /* byte replication */
                                value = (unsigned long)bits;
                                size = 8;
                              }
                       }
                     else if (!op)
                       {
                         /* floating point encoding */
                         int tmp;
                         
                         value = (unsigned long)(bits & 0x7f) << 19;
                         value |= (unsigned long)(bits & 0x80) << 24;
                         tmp = bits & 0x40 ? 0x3c : 0x40;
                         value |= (unsigned long)tmp << 24;
                            size = 32;
                            isfloat = 1;
                       }
                     else
                       {
                         func (stream, "<illegal constant %.8x:%x:%x>",
                                  bits, cmode, op);
                            size = 32;
                         break;
                       }
                        switch (size)
                          {
                          case 8:
                         func (stream, "#%ld\t; 0x%.2lx", value, value);
                            break;
                          
                          case 16:
                            func (stream, "#%ld\t; 0x%.4lx", value, value);
                            break;

                          case 32:
                            if (isfloat)
                              {
                                unsigned char valbytes[4];
                                double fvalue;
                                
                                /* Do this a byte at a time so we don't have to
                                   worry about the host's endianness.  */
                                valbytes[0] = value & 0xff;
                                valbytes[1] = (value >> 8) & 0xff;
                                valbytes[2] = (value >> 16) & 0xff;
                                valbytes[3] = (value >> 24) & 0xff;
                                
                                floatformat_to_double 
                                  (&floatformat_ieee_single_little, valbytes,
                                  &fvalue);
                                                                
                                func (stream, "#%.7g\t; 0x%.8lx", fvalue,
                                      value);
                              }
                            else
                              func (stream, "#%ld\t; 0x%.8lx",
                            (long) ((value & 0x80000000)
                                   ? value | ~0xffffffffl : value), value);
                            break;

                          case 64:
                            func (stream, "#0x%.8lx%.8lx", hival, value);
                            break;
                          
                          default:
                            abort ();
                          }
                    }
                    break;
                    
                  case 'F':
                    {
                     int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
                     int num = (given >> 8) & 0x3;
                     
                     if (!num)
                       func (stream, "{d%d}", regno);
                     else if (num + regno >= 32)
                       func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
                     else
                       func (stream, "{d%d-d%d}", regno, regno + num);
                    }
                    break;
      

                  case '0': case '1': case '2': case '3': case '4':
                  case '5': case '6': case '7': case '8': case '9':
                    {
                     int width;
                     unsigned long value;

                     c = arm_decode_bitfield (c, given, &value, &width);
                     
                     switch (*c)
                       {
                       case 'r':
                         func (stream, "%s", arm_regnames[value]);
                         break;
                       case 'd':
                         func (stream, "%ld", value);
                         break;
                       case 'e':
                         func (stream, "%ld", (1ul << width) - value);
                         break;
                         
                       case 'S':
                       case 'T':
                       case 'U':
                         /* various width encodings */
                         {
                           int base = 8 << (*c - 'S'); /* 8,16 or 32 */
                           int limit;
                           unsigned low, high;

                           c++;
                           if (*c >= '0' && *c <= '9')
                            limit = *c - '0';
                           else if (*c >= 'a' && *c <= 'f')
                            limit = *c - 'a' + 10;
                           else
                            abort ();
                           low = limit >> 2;
                           high = limit & 3;

                           if (value < low || value > high)
                            func (stream, "<illegal width %d>", base << value);
                           else
                            func (stream, "%d", base << value);
                         }
                         break;
                       case 'R':
                         if (given & (1 << 6))
                           goto Q;
                         /* FALLTHROUGH */
                       case 'D':
                         func (stream, "d%ld", value);
                         break;
                       case 'Q':
                       Q:
                         if (value & 1)
                           func (stream, "<illegal reg q%ld.5>", value >> 1);
                         else
                           func (stream, "q%ld", value >> 1);
                         break;
                         
                       case '`':
                         c++;
                         if (value == 0)
                           func (stream, "%c", *c);
                         break;
                       case '\'':
                         c++;
                         if (value == ((1ul << width) - 1))
                           func (stream, "%c", *c);
                         break;
                       case '?':
                         func (stream, "%c", c[(1 << width) - (int)value]);
                         c += 1 << width;
                         break;
                       default:
                         abort ();
                       }
                     break;

                    default:
                     abort ();
                    }
                  }
              }
             else
              func (stream, "%c", *c);
           }
         return TRUE;
       }
    }
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_insn_thumb16 ( bfd_vma  pc,
struct disassemble_info info,
long  given 
) [static]

Definition at line 2997 of file arm-dis.c.

{
  const struct opcode16 *insn;
  void *stream = info->stream;
  fprintf_ftype func = info->fprintf_func;

  for (insn = thumb_opcodes; insn->assembler; insn++)
    if ((given & insn->mask) == insn->value)
      {
       const char *c = insn->assembler;
       for (; *c; c++)
         {
           int domaskpc = 0;
           int domasklr = 0;

           if (*c != '%')
             {
              func (stream, "%c", *c);
              continue;
             }

           switch (*++c)
             {
             case '%':
              func (stream, "%%");
              break;

             case 'c':
              if (ifthen_state)
                func (stream, "%s", arm_conditional[IFTHEN_COND]);
              break;

             case 'C':
              if (ifthen_state)
                func (stream, "%s", arm_conditional[IFTHEN_COND]);
              else
                func (stream, "s");
              break;

             case 'I':
              {
                unsigned int tmp;

                ifthen_next_state = given & 0xff;
                for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
                  func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
                func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
              }
              break;

             case 'x':
              if (ifthen_next_state)
                func (stream, "\t; unpredictable branch in IT block\n");
              break;

             case 'X':
              if (ifthen_state)
                func (stream, "\t; unpredictable <IT:%s>",
                     arm_conditional[IFTHEN_COND]);
              break;

             case 'S':
              {
                long reg;

                reg = (given >> 3) & 0x7;
                if (given & (1 << 6))
                  reg += 8;

                func (stream, "%s", arm_regnames[reg]);
              }
              break;

             case 'D':
              {
                long reg;

                reg = given & 0x7;
                if (given & (1 << 7))
                  reg += 8;

                func (stream, "%s", arm_regnames[reg]);
              }
              break;

             case 'N':
              if (given & (1 << 8))
                domasklr = 1;
              /* Fall through.  */
             case 'O':
              if (*c == 'O' && (given & (1 << 8)))
                domaskpc = 1;
              /* Fall through.  */
             case 'M':
              {
                int started = 0;
                int reg;

                func (stream, "{");

                /* It would be nice if we could spot
                   ranges, and generate the rS-rE format: */
                for (reg = 0; (reg < 8); reg++)
                  if ((given & (1 << reg)) != 0)
                    {
                     if (started)
                       func (stream, ", ");
                     started = 1;
                     func (stream, "%s", arm_regnames[reg]);
                    }

                if (domasklr)
                  {
                    if (started)
                     func (stream, ", ");
                    started = 1;
                    func (stream, arm_regnames[14] /* "lr" */);
                  }

                if (domaskpc)
                  {
                    if (started)
                     func (stream, ", ");
                    func (stream, arm_regnames[15] /* "pc" */);
                  }

                func (stream, "}");
              }
              break;

             case 'b':
              /* Print ARM V6T2 CZB address: pc+4+6 bits.  */
              {
                bfd_vma address = (pc + 4
                                 + ((given & 0x00f8) >> 2)
                                 + ((given & 0x0200) >> 3));
                info->print_address_func (address, info);
              }
              break;

             case 's':
              /* Right shift immediate -- bits 6..10; 1-31 print
                 as themselves, 0 prints as 32.  */
              {
                long imm = (given & 0x07c0) >> 6;
                if (imm == 0)
                  imm = 32;
                func (stream, "#%ld", imm);
              }
              break;

             case '0': case '1': case '2': case '3': case '4':
             case '5': case '6': case '7': case '8': case '9':
              {
                int bitstart = *c++ - '0';
                int bitend = 0;

                while (*c >= '0' && *c <= '9')
                  bitstart = (bitstart * 10) + *c++ - '0';

                switch (*c)
                  {
                  case '-':
                    {
                     long reg;

                     c++;
                     while (*c >= '0' && *c <= '9')
                       bitend = (bitend * 10) + *c++ - '0';
                     if (!bitend)
                       abort ();
                     reg = given >> bitstart;
                     reg &= (2 << (bitend - bitstart)) - 1;
                     switch (*c)
                       {
                       case 'r':
                         func (stream, "%s", arm_regnames[reg]);
                         break;

                       case 'd':
                         func (stream, "%ld", reg);
                         break;

                       case 'H':
                         func (stream, "%ld", reg << 1);
                         break;

                       case 'W':
                         func (stream, "%ld", reg << 2);
                         break;

                       case 'a':
                         /* PC-relative address -- the bottom two
                            bits of the address are dropped
                            before the calculation.  */
                         info->print_address_func
                           (((pc + 4) & ~3) + (reg << 2), info);
                         break;

                       case 'x':
                         func (stream, "0x%04lx", reg);
                         break;

                       case 'B':
                         reg = ((reg ^ (1 << bitend)) - (1 << bitend));
                         info->print_address_func (reg * 2 + pc + 4, info);
                         break;

                       case 'c':
                         func (stream, "%s", arm_conditional [reg]);
                         break;

                       default:
                         abort ();
                       }
                    }
                    break;

                  case '\'':
                    c++;
                    if ((given & (1 << bitstart)) != 0)
                     func (stream, "%c", *c);
                    break;

                  case '?':
                    ++c;
                    if ((given & (1 << bitstart)) != 0)
                     func (stream, "%c", *c++);
                    else
                     func (stream, "%c", *++c);
                    break;

                  default:
                    abort ();
                  }
              }
              break;

             default:
              abort ();
             }
         }
       return;
      }

  /* No match.  */
  abort ();
}

Here is the caller graph for this function:

static void print_insn_thumb32 ( bfd_vma  pc,
struct disassemble_info info,
long  given 
) [static]

Definition at line 3273 of file arm-dis.c.

{
  const struct opcode32 *insn;
  void *stream = info->stream;
  fprintf_ftype func = info->fprintf_func;

  if (print_insn_coprocessor (pc, info, given, TRUE))
    return;

  if (print_insn_neon (info, given, TRUE))
    return;

  for (insn = thumb32_opcodes; insn->assembler; insn++)
    if ((given & insn->mask) == insn->value)
      {
       const char *c = insn->assembler;
       for (; *c; c++)
         {
           if (*c != '%')
             {
              func (stream, "%c", *c);
              continue;
             }

           switch (*++c)
             {
             case '%':
              func (stream, "%%");
              break;

             case 'c':
              if (ifthen_state)
                func (stream, "%s", arm_conditional[IFTHEN_COND]);
              break;

             case 'x':
              if (ifthen_next_state)
                func (stream, "\t; unpredictable branch in IT block\n");
              break;

             case 'X':
              if (ifthen_state)
                func (stream, "\t; unpredictable <IT:%s>",
                     arm_conditional[IFTHEN_COND]);
              break;

             case 'I':
              {
                unsigned int imm12 = 0;
                imm12 |= (given & 0x000000ffu);
                imm12 |= (given & 0x00007000u) >> 4;
                imm12 |= (given & 0x04000000u) >> 15;
                func (stream, "#%u\t; 0x%x", imm12, imm12);
              }
              break;

             case 'M':
              {
                unsigned int bits = 0, imm, imm8, mod;
                bits |= (given & 0x000000ffu);
                bits |= (given & 0x00007000u) >> 4;
                bits |= (given & 0x04000000u) >> 15;
                imm8 = (bits & 0x0ff);
                mod = (bits & 0xf00) >> 8;
                switch (mod)
                  {
                  case 0: imm = imm8; break;
                  case 1: imm = ((imm8<<16) | imm8); break;
                  case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
                  case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
                  default:
                    mod  = (bits & 0xf80) >> 7;
                    imm8 = (bits & 0x07f) | 0x80;
                    imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
                  }
                func (stream, "#%u\t; 0x%x", imm, imm);
              }
              break;
                
             case 'J':
              {
                unsigned int imm = 0;
                imm |= (given & 0x000000ffu);
                imm |= (given & 0x00007000u) >> 4;
                imm |= (given & 0x04000000u) >> 15;
                imm |= (given & 0x000f0000u) >> 4;
                func (stream, "#%u\t; 0x%x", imm, imm);
              }
              break;

             case 'K':
              {
                unsigned int imm = 0;
                imm |= (given & 0x000f0000u) >> 16;
                imm |= (given & 0x00000ff0u) >> 0;
                imm |= (given & 0x0000000fu) << 12;
                func (stream, "#%u\t; 0x%x", imm, imm);
              }
              break;

             case 'S':
              {
                unsigned int reg = (given & 0x0000000fu);
                unsigned int stp = (given & 0x00000030u) >> 4;
                unsigned int imm = 0;
                imm |= (given & 0x000000c0u) >> 6;
                imm |= (given & 0x00007000u) >> 10;

                func (stream, "%s", arm_regnames[reg]);
                switch (stp)
                  {
                  case 0:
                    if (imm > 0)
                     func (stream, ", lsl #%u", imm);
                    break;

                  case 1:
                    if (imm == 0)
                     imm = 32;
                    func (stream, ", lsr #%u", imm);
                    break;

                  case 2:
                    if (imm == 0)
                     imm = 32;
                    func (stream, ", asr #%u", imm);
                    break;

                  case 3:
                    if (imm == 0)
                     func (stream, ", rrx");
                    else
                     func (stream, ", ror #%u", imm);
                  }
              }
              break;

             case 'a':
              {
                unsigned int Rn  = (given & 0x000f0000) >> 16;
                unsigned int U   = (given & 0x00800000) >> 23;
                unsigned int op  = (given & 0x00000f00) >> 8;
                unsigned int i12 = (given & 0x00000fff);
                unsigned int i8  = (given & 0x000000ff);
                bfd_boolean writeback = FALSE, postind = FALSE;
                int offset = 0;

                func (stream, "[%s", arm_regnames[Rn]);
                if (U) /* 12-bit positive immediate offset */
                  offset = i12;
                else if (Rn == 15) /* 12-bit negative immediate offset */
                  offset = -(int)i12;
                else if (op == 0x0) /* shifted register offset */
                  {
                    unsigned int Rm = (i8 & 0x0f);
                    unsigned int sh = (i8 & 0x30) >> 4;
                    func (stream, ", %s", arm_regnames[Rm]);
                    if (sh)
                     func (stream, ", lsl #%u", sh);
                    func (stream, "]");
                    break;
                  }
                else switch (op)
                  {
                  case 0xE:  /* 8-bit positive immediate offset */
                    offset = i8;
                    break;

                  case 0xC:  /* 8-bit negative immediate offset */
                    offset = -i8;
                    break;

                  case 0xF:  /* 8-bit + preindex with wb */
                    offset = i8;
                    writeback = TRUE;
                    break;

                  case 0xD:  /* 8-bit - preindex with wb */
                    offset = -i8;
                    writeback = TRUE;
                    break;

                  case 0xB:  /* 8-bit + postindex */
                    offset = i8;
                    postind = TRUE;
                    break;

                  case 0x9:  /* 8-bit - postindex */
                    offset = -i8;
                    postind = TRUE;
                    break;

                  default:
                    func (stream, ", <undefined>]");
                    goto skip;
                  }

                if (postind)
                  func (stream, "], #%d", offset);
                else
                  {
                    if (offset)
                     func (stream, ", #%d", offset);
                    func (stream, writeback ? "]!" : "]");
                  }

                if (Rn == 15)
                  {
                    func (stream, "\t; ");
                    info->print_address_func (((pc + 4) & ~3) + offset, info);
                  }
              }
             skip:
              break;

             case 'A':
              {
                unsigned int P   = (given & 0x01000000) >> 24;
                unsigned int U   = (given & 0x00800000) >> 23;
                unsigned int W   = (given & 0x00400000) >> 21;
                unsigned int Rn  = (given & 0x000f0000) >> 16;
                unsigned int off = (given & 0x000000ff);

                func (stream, "[%s", arm_regnames[Rn]);
                if (P)
                  {
                    if (off || !U)
                     func (stream, ", #%c%u", U ? '+' : '-', off * 4);
                    func (stream, "]");
                    if (W)
                     func (stream, "!");
                  }
                else
                  {
                    func (stream, "], ");
                    if (W)
                     func (stream, "#%c%u", U ? '+' : '-', off * 4);
                    else
                     func (stream, "{%u}", off);
                  }
              }
              break;

             case 'w':
              {
                unsigned int Sbit = (given & 0x01000000) >> 24;
                unsigned int type = (given & 0x00600000) >> 21;
                switch (type)
                  {
                  case 0: func (stream, Sbit ? "sb" : "b"); break;
                  case 1: func (stream, Sbit ? "sh" : "h"); break;
                  case 2:
                    if (Sbit)
                     func (stream, "??");
                    break;
                  case 3:
                    func (stream, "??");
                    break;
                  }
              }
              break;

             case 'm':
              {
                int started = 0;
                int reg;

                func (stream, "{");
                for (reg = 0; reg < 16; reg++)
                  if ((given & (1 << reg)) != 0)
                    {
                     if (started)
                       func (stream, ", ");
                     started = 1;
                     func (stream, "%s", arm_regnames[reg]);
                    }
                func (stream, "}");
              }
              break;

             case 'E':
              {
                unsigned int msb = (given & 0x0000001f);
                unsigned int lsb = 0;
                lsb |= (given & 0x000000c0u) >> 6;
                lsb |= (given & 0x00007000u) >> 10;
                func (stream, "#%u, #%u", lsb, msb - lsb + 1);
              }
              break;

             case 'F':
              {
                unsigned int width = (given & 0x0000001f) + 1;
                unsigned int lsb = 0;
                lsb |= (given & 0x000000c0u) >> 6;
                lsb |= (given & 0x00007000u) >> 10;
                func (stream, "#%u, #%u", lsb, width);
              }
              break;

             case 'b':
              {
                unsigned int S = (given & 0x04000000u) >> 26;
                unsigned int J1 = (given & 0x00002000u) >> 13;
                unsigned int J2 = (given & 0x00000800u) >> 11;
                int offset = 0;

                offset |= !S << 20;
                offset |= J2 << 19;
                offset |= J1 << 18;
                offset |= (given & 0x003f0000) >> 4;
                offset |= (given & 0x000007ff) << 1;
                offset -= (1 << 20);

                info->print_address_func (pc + 4 + offset, info);
              }
              break;

             case 'B':
              {
                unsigned int S = (given & 0x04000000u) >> 26;
                unsigned int I1 = (given & 0x00002000u) >> 13;
                unsigned int I2 = (given & 0x00000800u) >> 11;
                int offset = 0;

                offset |= !S << 24;
                offset |= !(I1 ^ S) << 23;
                offset |= !(I2 ^ S) << 22;
                offset |= (given & 0x03ff0000u) >> 4;
                offset |= (given & 0x000007ffu) << 1;
                offset -= (1 << 24);
                offset += pc + 4;

                /* BLX target addresses are always word aligned.  */
                if ((given & 0x00001000u) == 0)
                    offset &= ~2u;

                info->print_address_func (offset, info);
              }
              break;

             case 's':
              {
                unsigned int shift = 0;
                shift |= (given & 0x000000c0u) >> 6;
                shift |= (given & 0x00007000u) >> 10;
                if (given & 0x00200000u)
                  func (stream, ", asr #%u", shift);
                else if (shift)
                  func (stream, ", lsl #%u", shift);
                /* else print nothing - lsl #0 */
              }
              break;

             case 'R':
              {
                unsigned int rot = (given & 0x00000030) >> 4;
                if (rot)
                  func (stream, ", ror #%u", rot * 8);
              }
              break;

             case 'U':
              switch (given & 0xf)
                {
                case 0xf: func(stream, "sy"); break;
                case 0x7: func(stream, "un"); break;
                case 0xe: func(stream, "st"); break;
                case 0x6: func(stream, "unst"); break;
                default:
                  func(stream, "#%d", (int)given & 0xf);
                  break;
                }
              break;

             case 'C':
              if ((given & 0xff) == 0)
                {
                  func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
                  if (given & 0x800)
                    func (stream, "f");
                  if (given & 0x400)
                    func (stream, "s");
                  if (given & 0x200)
                    func (stream, "x");
                  if (given & 0x100)
                    func (stream, "c");
                }
              else
                {
                  func (stream, psr_name (given & 0xff));
                }
              break;

             case 'D':
              if ((given & 0xff) == 0)
                func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
              else
                func (stream, psr_name (given & 0xff));
              break;

             case '0': case '1': case '2': case '3': case '4':
             case '5': case '6': case '7': case '8': case '9':
              {
                int width;
                unsigned long val;

                c = arm_decode_bitfield (c, given, &val, &width);
                     
                switch (*c)
                  {
                  case 'd': func (stream, "%lu", val); break;
                  case 'W': func (stream, "%lu", val * 4); break;
                  case 'r': func (stream, "%s", arm_regnames[val]); break;

                  case 'c':
                    func (stream, "%s", arm_conditional[val]);
                    break;

                  case '\'':
                    c++;
                    if (val == ((1ul << width) - 1))
                     func (stream, "%c", *c);
                    break;
                    
                  case '`':
                    c++;
                    if (val == 0)
                     func (stream, "%c", *c);
                    break;

                  case '?':
                    func (stream, "%c", c[(1 << width) - (int)val]);
                    c += 1 << width;
                    break;

                  default:
                    abort ();
                  }
              }
              break;

             default:
              abort ();
             }
         }
       return;
      }

  /* No match.  */
  abort ();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* psr_name ( int  regno) [static]

Definition at line 3248 of file arm-dis.c.

{
  switch (regno)
    {
    case 0: return "APSR";
    case 1: return "IAPSR";
    case 2: return "EAPSR";
    case 3: return "PSR";
    case 5: return "IPSR";
    case 6: return "EPSR";
    case 7: return "IEPSR";
    case 8: return "MSP";
    case 9: return "PSP";
    case 16: return "PRIMASK";
    case 17: return "BASEPRI";
    case 18: return "BASEPRI_MASK";
    case 19: return "FAULTMASK";
    case 20: return "CONTROL";
    default: return "<unknown>";
    }
}

Here is the caller graph for this function:

Definition at line 1504 of file arm-dis.c.

{
  int old = regname_selected;
  regname_selected = option;
  return old;
}

Variable Documentation

const char* const arm_conditional[] [static]
Initial value:
{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""}

Definition at line 1413 of file arm-dis.c.

const char* const arm_fp_const[] [static]
Initial value:
{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}

Definition at line 1417 of file arm-dis.c.

const char* const arm_shift[] [static]
Initial value:
{"lsl", "lsr", "asr", "ror"}

Definition at line 1420 of file arm-dis.c.

Definition at line 1473 of file arm-dis.c.

Definition at line 1481 of file arm-dis.c.

Definition at line 1479 of file arm-dis.c.

Definition at line 1477 of file arm-dis.c.

const char* const iwmmxt_cregnames[] [static]
Initial value:
{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
  "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
}

Definition at line 1462 of file arm-dis.c.

const char* const iwmmxt_regnames[] [static]
Initial value:
{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
  "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
}

Definition at line 1457 of file arm-dis.c.

const char* const iwmmxt_wwnames[] [static]
Initial value:
{"b", "h", "w", "d"}

Definition at line 1447 of file arm-dis.c.

const char* const iwmmxt_wwssnames[] [static]
Initial value:
{"b", "bus", "bc", "bss",
 "h", "hus", "hc", "hss",
 "w", "wus", "wc", "wss",
 "d", "dus", "dc", "dss"
}

Definition at line 1450 of file arm-dis.c.

struct opcode16[] [static]

Definition at line 1041 of file arm-dis.c.

static struct opcode32 [static]

Definition at line 109 of file arm-dis.c.

Definition at line 1468 of file arm-dis.c.

Initial value:
{
  { "raw" , "Select raw register names",
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
  { "gcc",  "Select register names used by GCC",
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
  { "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" }},
  { "apcs", "Select register names used in the APCS",
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
  { "atpcs", "Select register names used in the ATPCS",
    { "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",
    { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
}

Definition at line 1431 of file arm-dis.c.