/* Common target dependent code for GDB on ARM systems.

   Copyright (C) 1988-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"

#include <ctype.h>		/* XXX for isupper ().  */

#include "frame.h"
#include "inferior.h"
#include "infrun.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "dis-asm.h"		/* For register styles.  */
#include "disasm.h"
#include "regcache.h"
#include "reggroups.h"
#include "target-float.h"
#include "value.h"
#include "arch-utils.h"
#include "osabi.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
#include "objfiles.h"
#include "dwarf2/frame.h"
#include "gdbtypes.h"
#include "prologue-value.h"
#include "remote.h"
#include "target-descriptions.h"
#include "user-regs.h"
#include "observable.h"
#include "count-one-bits.h"

#include "arch/arm.h"
#include "arch/arm-get-next-pcs.h"
#include "arm-tdep.h"
#include "gdb/sim-arm.h"

#include "elf-bfd.h"
#include "coff/internal.h"
#include "elf/arm.h"

#include "record.h"
#include "record-full.h"
#include <algorithm>

#include "producer.h"

#if GDB_SELF_TEST
#include "gdbsupport/selftest.h"
#endif

static bool arm_debug;

/* Print an "arm" debug statement.  */

#define arm_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (arm_debug, "arm", fmt, ##__VA_ARGS__)

/* Macros for setting and testing a bit in a minimal symbol that marks
   it as Thumb function.  The MSB of the minimal symbol's "info" field
   is used for this purpose.

   MSYMBOL_SET_SPECIAL	Actually sets the "special" bit.
   MSYMBOL_IS_SPECIAL   Tests the "special" bit in a minimal symbol.  */

#define MSYMBOL_SET_SPECIAL(msym)				\
	MSYMBOL_TARGET_FLAG_1 (msym) = 1

#define MSYMBOL_IS_SPECIAL(msym)				\
	MSYMBOL_TARGET_FLAG_1 (msym)

struct arm_mapping_symbol
{
  CORE_ADDR value;
  char type;

  bool operator< (const arm_mapping_symbol &other) const
  { return this->value < other.value; }
};

typedef std::vector<arm_mapping_symbol> arm_mapping_symbol_vec;

struct arm_per_bfd
{
  explicit arm_per_bfd (size_t num_sections)
  : section_maps (new arm_mapping_symbol_vec[num_sections]),
    section_maps_sorted (new bool[num_sections] ())
  {}

  DISABLE_COPY_AND_ASSIGN (arm_per_bfd);

  /* Information about mapping symbols ($a, $d, $t) in the objfile.

     The format is an array of vectors of arm_mapping_symbols, there is one
     vector for each section of the objfile (the array is index by BFD section
     index).

     For each section, the vector of arm_mapping_symbol is sorted by
     symbol value (address).  */
  std::unique_ptr<arm_mapping_symbol_vec[]> section_maps;

  /* For each corresponding element of section_maps above, is this vector
     sorted.  */
  std::unique_ptr<bool[]> section_maps_sorted;
};

/* Per-bfd data used for mapping symbols.  */
static bfd_key<arm_per_bfd> arm_bfd_data_key;

/* The list of available "set arm ..." and "show arm ..." commands.  */
static struct cmd_list_element *setarmcmdlist = NULL;
static struct cmd_list_element *showarmcmdlist = NULL;

/* The type of floating-point to use.  Keep this in sync with enum
   arm_float_model, and the help string in _initialize_arm_tdep.  */
static const char *const fp_model_strings[] =
{
  "auto",
  "softfpa",
  "fpa",
  "softvfp",
  "vfp",
  NULL
};

/* A variable that can be configured by the user.  */
static enum arm_float_model arm_fp_model = ARM_FLOAT_AUTO;
static const char *current_fp_model = "auto";

/* The ABI to use.  Keep this in sync with arm_abi_kind.  */
static const char *const arm_abi_strings[] =
{
  "auto",
  "APCS",
  "AAPCS",
  NULL
};

/* A variable that can be configured by the user.  */
static enum arm_abi_kind arm_abi_global = ARM_ABI_AUTO;
static const char *arm_abi_string = "auto";

/* The execution mode to assume.  */
static const char *const arm_mode_strings[] =
  {
    "auto",
    "arm",
    "thumb",
    NULL
  };

static const char *arm_fallback_mode_string = "auto";
static const char *arm_force_mode_string = "auto";

/* The standard register names, and all the valid aliases for them.  Note
   that `fp', `sp' and `pc' are not added in this alias list, because they
   have been added as builtin user registers in
   std-regs.c:_initialize_frame_reg.  */
static const struct
{
  const char *name;
  int regnum;
} arm_register_aliases[] = {
  /* Basic register numbers.  */
  { "r0", 0 },
  { "r1", 1 },
  { "r2", 2 },
  { "r3", 3 },
  { "r4", 4 },
  { "r5", 5 },
  { "r6", 6 },
  { "r7", 7 },
  { "r8", 8 },
  { "r9", 9 },
  { "r10", 10 },
  { "r11", 11 },
  { "r12", 12 },
  { "r13", 13 },
  { "r14", 14 },
  { "r15", 15 },
  /* Synonyms (argument and variable registers).  */
  { "a1", 0 },
  { "a2", 1 },
  { "a3", 2 },
  { "a4", 3 },
  { "v1", 4 },
  { "v2", 5 },
  { "v3", 6 },
  { "v4", 7 },
  { "v5", 8 },
  { "v6", 9 },
  { "v7", 10 },
  { "v8", 11 },
  /* Other platform-specific names for r9.  */
  { "sb", 9 },
  { "tr", 9 },
  /* Special names.  */
  { "ip", 12 },
  { "lr", 14 },
  /* Names used by GCC (not listed in the ARM EABI).  */
  { "sl", 10 },
  /* A special name from the older ATPCS.  */
  { "wr", 7 },
};

static const char *const arm_register_names[] =
{"r0",  "r1",  "r2",  "r3",	/*  0  1  2  3 */
 "r4",  "r5",  "r6",  "r7",	/*  4  5  6  7 */
 "r8",  "r9",  "r10", "r11",	/*  8  9 10 11 */
 "r12", "sp",  "lr",  "pc",	/* 12 13 14 15 */
 "f0",  "f1",  "f2",  "f3",	/* 16 17 18 19 */
 "f4",  "f5",  "f6",  "f7",	/* 20 21 22 23 */
 "fps", "cpsr" };		/* 24 25       */

/* Holds the current set of options to be passed to the disassembler.  */
static char *arm_disassembler_options;

/* Valid register name styles.  */
static const char **valid_disassembly_styles;

/* Disassembly style to use. Default to "std" register names.  */
static const char *disassembly_style;

/* All possible arm target descriptors.  */
static struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID];
static struct target_desc *tdesc_arm_mprofile_list[ARM_M_TYPE_INVALID];

/* This is used to keep the bfd arch_info in sync with the disassembly
   style.  */
static void set_disassembly_style_sfunc (const char *, int,
					 struct cmd_list_element *);
static void show_disassembly_style_sfunc (struct ui_file *, int,
					  struct cmd_list_element *,
					  const char *);

static enum register_status arm_neon_quad_read (struct gdbarch *gdbarch,
						readable_regcache *regcache,
						int regnum, gdb_byte *buf);
static void arm_neon_quad_write (struct gdbarch *gdbarch,
				 struct regcache *regcache,
				 int regnum, const gdb_byte *buf);

static CORE_ADDR
  arm_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self);


/* get_next_pcs operations.  */
static struct arm_get_next_pcs_ops arm_get_next_pcs_ops = {
  arm_get_next_pcs_read_memory_unsigned_integer,
  arm_get_next_pcs_syscall_next_pc,
  arm_get_next_pcs_addr_bits_remove,
  arm_get_next_pcs_is_thumb,
  NULL,
};

struct arm_prologue_cache
{
  /* The stack pointer at the time this frame was created; i.e. the
     caller's stack pointer when this function was called.  It is used
     to identify this frame.  */
  CORE_ADDR prev_sp;

  /* The frame base for this frame is just prev_sp - frame size.
     FRAMESIZE is the distance from the frame pointer to the
     initial stack pointer.  */

  int framesize;

  /* The register used to hold the frame pointer for this frame.  */
  int framereg;

  /* Saved register offsets.  */
  trad_frame_saved_reg *saved_regs;
};

namespace {

/* Abstract class to read ARM instructions from memory.  */

class arm_instruction_reader
{
public:
  /* Read a 4 bytes instruction from memory using the BYTE_ORDER endianness.  */
  virtual uint32_t read (CORE_ADDR memaddr, bfd_endian byte_order) const = 0;
};

/* Read instructions from target memory.  */

class target_arm_instruction_reader : public arm_instruction_reader
{
public:
  uint32_t read (CORE_ADDR memaddr, bfd_endian byte_order) const override
  {
    return read_code_unsigned_integer (memaddr, 4, byte_order);
  }
};

} /* namespace */

static CORE_ADDR arm_analyze_prologue
  (struct gdbarch *gdbarch, CORE_ADDR prologue_start, CORE_ADDR prologue_end,
   struct arm_prologue_cache *cache, const arm_instruction_reader &insn_reader);

/* Architecture version for displaced stepping.  This effects the behaviour of
   certain instructions, and really should not be hard-wired.  */

#define DISPLACED_STEPPING_ARCH_VERSION		5

/* See arm-tdep.h.  */

bool arm_apcs_32 = true;

/* Return the bit mask in ARM_PS_REGNUM that indicates Thumb mode.  */

int
arm_psr_thumb_bit (struct gdbarch *gdbarch)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (tdep->is_m)
    return XPSR_T;
  else
    return CPSR_T;
}

/* Determine if the processor is currently executing in Thumb mode.  */

int
arm_is_thumb (struct regcache *regcache)
{
  ULONGEST cpsr;
  ULONGEST t_bit = arm_psr_thumb_bit (regcache->arch ());

  cpsr = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM);

  return (cpsr & t_bit) != 0;
}

/* Determine if FRAME is executing in Thumb mode.  */

int
arm_frame_is_thumb (struct frame_info *frame)
{
  CORE_ADDR cpsr;
  ULONGEST t_bit = arm_psr_thumb_bit (get_frame_arch (frame));

  /* Every ARM frame unwinder can unwind the T bit of the CPSR, either
     directly (from a signal frame or dummy frame) or by interpreting
     the saved LR (from a prologue or DWARF frame).  So consult it and
     trust the unwinders.  */
  cpsr = get_frame_register_unsigned (frame, ARM_PS_REGNUM);

  return (cpsr & t_bit) != 0;
}

/* Search for the mapping symbol covering MEMADDR.  If one is found,
   return its type.  Otherwise, return 0.  If START is non-NULL,
   set *START to the location of the mapping symbol.  */

static char
arm_find_mapping_symbol (CORE_ADDR memaddr, CORE_ADDR *start)
{
  struct obj_section *sec;

  /* If there are mapping symbols, consult them.  */
  sec = find_pc_section (memaddr);
  if (sec != NULL)
    {
      arm_per_bfd *data = arm_bfd_data_key.get (sec->objfile->obfd);
      if (data != NULL)
	{
	  unsigned int section_idx = sec->the_bfd_section->index;
	  arm_mapping_symbol_vec &map
	    = data->section_maps[section_idx];

	  /* Sort the vector on first use.  */
	  if (!data->section_maps_sorted[section_idx])
	    {
	      std::sort (map.begin (), map.end ());
	      data->section_maps_sorted[section_idx] = true;
	    }

	  arm_mapping_symbol map_key = { memaddr - sec->addr (), 0 };
	  arm_mapping_symbol_vec::const_iterator it
	    = std::lower_bound (map.begin (), map.end (), map_key);

	  /* std::lower_bound finds the earliest ordered insertion
	     point.  If the symbol at this position starts at this exact
	     address, we use that; otherwise, the preceding
	     mapping symbol covers this address.  */
	  if (it < map.end ())
	    {
	      if (it->value == map_key.value)
		{
		  if (start)
		    *start = it->value + sec->addr ();
		  return it->type;
		}
	    }

	  if (it > map.begin ())
	    {
	      arm_mapping_symbol_vec::const_iterator prev_it
		= it - 1;

	      if (start)
		*start = prev_it->value + sec->addr ();
	      return prev_it->type;
	    }
	}
    }

  return 0;
}

/* Determine if the program counter specified in MEMADDR is in a Thumb
   function.  This function should be called for addresses unrelated to
   any executing frame; otherwise, prefer arm_frame_is_thumb.  */

int
arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr)
{
  struct bound_minimal_symbol sym;
  char type;
  arm_displaced_step_copy_insn_closure *dsc = nullptr;
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (gdbarch_displaced_step_copy_insn_closure_by_addr_p (gdbarch))
    dsc = ((arm_displaced_step_copy_insn_closure * )
	   gdbarch_displaced_step_copy_insn_closure_by_addr
	     (gdbarch, current_inferior (), memaddr));

  /* If checking the mode of displaced instruction in copy area, the mode
     should be determined by instruction on the original address.  */
  if (dsc)
    {
      displaced_debug_printf ("check mode of %.8lx instead of %.8lx",
			      (unsigned long) dsc->insn_addr,
			      (unsigned long) memaddr);
      memaddr = dsc->insn_addr;
    }

  /* If bit 0 of the address is set, assume this is a Thumb address.  */
  if (IS_THUMB_ADDR (memaddr))
    return 1;

  /* If the user wants to override the symbol table, let him.  */
  if (strcmp (arm_force_mode_string, "arm") == 0)
    return 0;
  if (strcmp (arm_force_mode_string, "thumb") == 0)
    return 1;

  /* ARM v6-M and v7-M are always in Thumb mode.  */
  if (tdep->is_m)
    return 1;

  /* If there are mapping symbols, consult them.  */
  type = arm_find_mapping_symbol (memaddr, NULL);
  if (type)
    return type == 't';

  /* Thumb functions have a "special" bit set in minimal symbols.  */
  sym = lookup_minimal_symbol_by_pc (memaddr);
  if (sym.minsym)
    return (MSYMBOL_IS_SPECIAL (sym.minsym));

  /* If the user wants to override the fallback mode, let them.  */
  if (strcmp (arm_fallback_mode_string, "arm") == 0)
    return 0;
  if (strcmp (arm_fallback_mode_string, "thumb") == 0)
    return 1;

  /* If we couldn't find any symbol, but we're talking to a running
     target, then trust the current value of $cpsr.  This lets
     "display/i $pc" always show the correct mode (though if there is
     a symbol table we will not reach here, so it still may not be
     displayed in the mode it will be executed).  */
  if (target_has_registers ())
    return arm_frame_is_thumb (get_current_frame ());

  /* Otherwise we're out of luck; we assume ARM.  */
  return 0;
}

/* Determine if the address specified equals any of these magic return
   values, called EXC_RETURN, defined by the ARM v6-M, v7-M and v8-M
   architectures.

   From ARMv6-M Reference Manual B1.5.8
   Table B1-5 Exception return behavior

   EXC_RETURN    Return To        Return Stack
   0xFFFFFFF1    Handler mode     Main
   0xFFFFFFF9    Thread mode      Main
   0xFFFFFFFD    Thread mode      Process

   From ARMv7-M Reference Manual B1.5.8
   Table B1-8 EXC_RETURN definition of exception return behavior, no FP

   EXC_RETURN    Return To        Return Stack
   0xFFFFFFF1    Handler mode     Main
   0xFFFFFFF9    Thread mode      Main
   0xFFFFFFFD    Thread mode      Process

   Table B1-9 EXC_RETURN definition of exception return behavior, with
   FP

   EXC_RETURN    Return To        Return Stack    Frame Type
   0xFFFFFFE1    Handler mode     Main            Extended
   0xFFFFFFE9    Thread mode      Main            Extended
   0xFFFFFFED    Thread mode      Process         Extended
   0xFFFFFFF1    Handler mode     Main            Basic
   0xFFFFFFF9    Thread mode      Main            Basic
   0xFFFFFFFD    Thread mode      Process         Basic

   For more details see "B1.5.8 Exception return behavior"
   in both ARMv6-M and ARMv7-M Architecture Reference Manuals.

   In the ARMv8-M Architecture Technical Reference also adds
   for implementations without the Security Extension:

   EXC_RETURN    Condition
   0xFFFFFFB0    Return to Handler mode.
   0xFFFFFFB8    Return to Thread mode using the main stack.
   0xFFFFFFBC    Return to Thread mode using the process stack.  */

static int
arm_m_addr_is_magic (CORE_ADDR addr)
{
  switch (addr)
    {
      /* Values from ARMv8-M Architecture Technical Reference.  */
      case 0xffffffb0:
      case 0xffffffb8:
      case 0xffffffbc:
      /* Values from Tables in B1.5.8 the EXC_RETURN definitions of
	 the exception return behavior.  */
      case 0xffffffe1:
      case 0xffffffe9:
      case 0xffffffed:
      case 0xfffffff1:
      case 0xfffffff9:
      case 0xfffffffd:
	/* Address is magic.  */
	return 1;

      default:
	/* Address is not magic.  */
	return 0;
    }
}

/* Remove useless bits from addresses in a running program.  */
static CORE_ADDR
arm_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR val)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* On M-profile devices, do not strip the low bit from EXC_RETURN
     (the magic exception return address).  */
  if (tdep->is_m && arm_m_addr_is_magic (val))
    return val;

  if (arm_apcs_32)
    return UNMAKE_THUMB_ADDR (val);
  else
    return (val & 0x03fffffc);
}

/* Return 1 if PC is the start of a compiler helper function which
   can be safely ignored during prologue skipping.  IS_THUMB is true
   if the function is known to be a Thumb function due to the way it
   is being called.  */
static int
skip_prologue_function (struct gdbarch *gdbarch, CORE_ADDR pc, int is_thumb)
{
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  struct bound_minimal_symbol msym;

  msym = lookup_minimal_symbol_by_pc (pc);
  if (msym.minsym != NULL
      && BMSYMBOL_VALUE_ADDRESS (msym) == pc
      && msym.minsym->linkage_name () != NULL)
    {
      const char *name = msym.minsym->linkage_name ();

      /* The GNU linker's Thumb call stub to foo is named
	 __foo_from_thumb.  */
      if (strstr (name, "_from_thumb") != NULL)
	name += 2;

      /* On soft-float targets, __truncdfsf2 is called to convert promoted
	 arguments to their argument types in non-prototyped
	 functions.  */
      if (startswith (name, "__truncdfsf2"))
	return 1;
      if (startswith (name, "__aeabi_d2f"))
	return 1;

      /* Internal functions related to thread-local storage.  */
      if (startswith (name, "__tls_get_addr"))
	return 1;
      if (startswith (name, "__aeabi_read_tp"))
	return 1;
    }
  else
    {
      /* If we run against a stripped glibc, we may be unable to identify
	 special functions by name.  Check for one important case,
	 __aeabi_read_tp, by comparing the *code* against the default
	 implementation (this is hand-written ARM assembler in glibc).  */

      if (!is_thumb
	  && read_code_unsigned_integer (pc, 4, byte_order_for_code)
	     == 0xe3e00a0f /* mov r0, #0xffff0fff */
	  && read_code_unsigned_integer (pc + 4, 4, byte_order_for_code)
	     == 0xe240f01f) /* sub pc, r0, #31 */
	return 1;
    }

  return 0;
}

/* Extract the immediate from instruction movw/movt of encoding T.  INSN1 is
   the first 16-bit of instruction, and INSN2 is the second 16-bit of
   instruction.  */
#define EXTRACT_MOVW_MOVT_IMM_T(insn1, insn2) \
  ((bits ((insn1), 0, 3) << 12)               \
   | (bits ((insn1), 10, 10) << 11)           \
   | (bits ((insn2), 12, 14) << 8)            \
   | bits ((insn2), 0, 7))

/* Extract the immediate from instruction movw/movt of encoding A.  INSN is
   the 32-bit instruction.  */
#define EXTRACT_MOVW_MOVT_IMM_A(insn) \
  ((bits ((insn), 16, 19) << 12) \
   | bits ((insn), 0, 11))

/* Decode immediate value; implements ThumbExpandImmediate pseudo-op.  */

static unsigned int
thumb_expand_immediate (unsigned int imm)
{
  unsigned int count = imm >> 7;

  if (count < 8)
    switch (count / 2)
      {
      case 0:
	return imm & 0xff;
      case 1:
	return (imm & 0xff) | ((imm & 0xff) << 16);
      case 2:
	return ((imm & 0xff) << 8) | ((imm & 0xff) << 24);
      case 3:
	return (imm & 0xff) | ((imm & 0xff) << 8)
		| ((imm & 0xff) << 16) | ((imm & 0xff) << 24);
      }

  return (0x80 | (imm & 0x7f)) << (32 - count);
}

/* Return 1 if the 16-bit Thumb instruction INSN restores SP in
   epilogue, 0 otherwise.  */

static int
thumb_instruction_restores_sp (unsigned short insn)
{
  return (insn == 0x46bd  /* mov sp, r7 */
	  || (insn & 0xff80) == 0xb000  /* add sp, imm */
	  || (insn & 0xfe00) == 0xbc00);  /* pop <registers> */
}

/* Analyze a Thumb prologue, looking for a recognizable stack frame
   and frame pointer.  Scan until we encounter a store that could
   clobber the stack frame unexpectedly, or an unknown instruction.
   Return the last address which is definitely safe to skip for an
   initial breakpoint.  */

static CORE_ADDR
thumb_analyze_prologue (struct gdbarch *gdbarch,
			CORE_ADDR start, CORE_ADDR limit,
			struct arm_prologue_cache *cache)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  int i;
  pv_t regs[16];
  CORE_ADDR offset;
  CORE_ADDR unrecognized_pc = 0;

  for (i = 0; i < 16; i++)
    regs[i] = pv_register (i, 0);
  pv_area stack (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));

  while (start < limit)
    {
      unsigned short insn;

      insn = read_code_unsigned_integer (start, 2, byte_order_for_code);

      if ((insn & 0xfe00) == 0xb400)		/* push { rlist } */
	{
	  int regno;
	  int mask;

	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
	    break;

	  /* Bits 0-7 contain a mask for registers R0-R7.  Bit 8 says
	     whether to save LR (R14).  */
	  mask = (insn & 0xff) | ((insn & 0x100) << 6);

	  /* Calculate offsets of saved R0-R7 and LR.  */
	  for (regno = ARM_LR_REGNUM; regno >= 0; regno--)
	    if (mask & (1 << regno))
	      {
		regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM],
						       -4);
		stack.store (regs[ARM_SP_REGNUM], 4, regs[regno]);
	      }
	}
      else if ((insn & 0xff80) == 0xb080)	/* sub sp, #imm */
	{
	  offset = (insn & 0x7f) << 2;		/* get scaled offset */
	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM],
						 -offset);
	}
      else if (thumb_instruction_restores_sp (insn))
	{
	  /* Don't scan past the epilogue.  */
	  break;
	}
      else if ((insn & 0xf800) == 0xa800)	/* add Rd, sp, #imm */
	regs[bits (insn, 8, 10)] = pv_add_constant (regs[ARM_SP_REGNUM],
						    (insn & 0xff) << 2);
      else if ((insn & 0xfe00) == 0x1c00	/* add Rd, Rn, #imm */
	       && pv_is_register (regs[bits (insn, 3, 5)], ARM_SP_REGNUM))
	regs[bits (insn, 0, 2)] = pv_add_constant (regs[bits (insn, 3, 5)],
						   bits (insn, 6, 8));
      else if ((insn & 0xf800) == 0x3000	/* add Rd, #imm */
	       && pv_is_register (regs[bits (insn, 8, 10)], ARM_SP_REGNUM))
	regs[bits (insn, 8, 10)] = pv_add_constant (regs[bits (insn, 8, 10)],
						    bits (insn, 0, 7));
      else if ((insn & 0xfe00) == 0x1800	/* add Rd, Rn, Rm */
	       && pv_is_register (regs[bits (insn, 6, 8)], ARM_SP_REGNUM)
	       && pv_is_constant (regs[bits (insn, 3, 5)]))
	regs[bits (insn, 0, 2)] = pv_add (regs[bits (insn, 3, 5)],
					  regs[bits (insn, 6, 8)]);
      else if ((insn & 0xff00) == 0x4400	/* add Rd, Rm */
	       && pv_is_constant (regs[bits (insn, 3, 6)]))
	{
	  int rd = (bit (insn, 7) << 3) + bits (insn, 0, 2);
	  int rm = bits (insn, 3, 6);
	  regs[rd] = pv_add (regs[rd], regs[rm]);
	}
      else if ((insn & 0xff00) == 0x4600)	/* mov hi, lo or mov lo, hi */
	{
	  int dst_reg = (insn & 0x7) + ((insn & 0x80) >> 4);
	  int src_reg = (insn & 0x78) >> 3;
	  regs[dst_reg] = regs[src_reg];
	}
      else if ((insn & 0xf800) == 0x9000)	/* str rd, [sp, #off] */
	{
	  /* Handle stores to the stack.  Normally pushes are used,
	     but with GCC -mtpcs-frame, there may be other stores
	     in the prologue to create the frame.  */
	  int regno = (insn >> 8) & 0x7;
	  pv_t addr;

	  offset = (insn & 0xff) << 2;
	  addr = pv_add_constant (regs[ARM_SP_REGNUM], offset);

	  if (stack.store_would_trash (addr))
	    break;

	  stack.store (addr, 4, regs[regno]);
	}
      else if ((insn & 0xf800) == 0x6000)	/* str rd, [rn, #off] */
	{
	  int rd = bits (insn, 0, 2);
	  int rn = bits (insn, 3, 5);
	  pv_t addr;

	  offset = bits (insn, 6, 10) << 2;
	  addr = pv_add_constant (regs[rn], offset);

	  if (stack.store_would_trash (addr))
	    break;

	  stack.store (addr, 4, regs[rd]);
	}
      else if (((insn & 0xf800) == 0x7000	/* strb Rd, [Rn, #off] */
		|| (insn & 0xf800) == 0x8000)	/* strh Rd, [Rn, #off] */
	       && pv_is_register (regs[bits (insn, 3, 5)], ARM_SP_REGNUM))
	/* Ignore stores of argument registers to the stack.  */
	;
      else if ((insn & 0xf800) == 0xc800	/* ldmia Rn!, { registers } */
	       && pv_is_register (regs[bits (insn, 8, 10)], ARM_SP_REGNUM))
	/* Ignore block loads from the stack, potentially copying
	   parameters from memory.  */
	;
      else if ((insn & 0xf800) == 0x9800	/* ldr Rd, [Rn, #immed] */
	       || ((insn & 0xf800) == 0x6800	/* ldr Rd, [sp, #immed] */
		   && pv_is_register (regs[bits (insn, 3, 5)], ARM_SP_REGNUM)))
	/* Similarly ignore single loads from the stack.  */
	;
      else if ((insn & 0xffc0) == 0x0000	/* lsls Rd, Rm, #0 */
	       || (insn & 0xffc0) == 0x1c00)	/* add Rd, Rn, #0 */
	/* Skip register copies, i.e. saves to another register
	   instead of the stack.  */
	;
      else if ((insn & 0xf800) == 0x2000)	/* movs Rd, #imm */
	/* Recognize constant loads; even with small stacks these are necessary
	   on Thumb.  */
	regs[bits (insn, 8, 10)] = pv_constant (bits (insn, 0, 7));
      else if ((insn & 0xf800) == 0x4800)	/* ldr Rd, [pc, #imm] */
	{
	  /* Constant pool loads, for the same reason.  */
	  unsigned int constant;
	  CORE_ADDR loc;

	  loc = start + 4 + bits (insn, 0, 7) * 4;
	  constant = read_memory_unsigned_integer (loc, 4, byte_order);
	  regs[bits (insn, 8, 10)] = pv_constant (constant);
	}
      else if (thumb_insn_size (insn) == 4) /* 32-bit Thumb-2 instructions.  */
	{
	  unsigned short inst2;

	  inst2 = read_code_unsigned_integer (start + 2, 2,
					      byte_order_for_code);

	  if ((insn & 0xf800) == 0xf000 && (inst2 & 0xe800) == 0xe800)
	    {
	      /* BL, BLX.  Allow some special function calls when
		 skipping the prologue; GCC generates these before
		 storing arguments to the stack.  */
	      CORE_ADDR nextpc;
	      int j1, j2, imm1, imm2;

	      imm1 = sbits (insn, 0, 10);
	      imm2 = bits (inst2, 0, 10);
	      j1 = bit (inst2, 13);
	      j2 = bit (inst2, 11);

	      offset = ((imm1 << 12) + (imm2 << 1));
	      offset ^= ((!j2) << 22) | ((!j1) << 23);

	      nextpc = start + 4 + offset;
	      /* For BLX make sure to clear the low bits.  */
	      if (bit (inst2, 12) == 0)
		nextpc = nextpc & 0xfffffffc;

	      if (!skip_prologue_function (gdbarch, nextpc,
					   bit (inst2, 12) != 0))
		break;
	    }

	  else if ((insn & 0xffd0) == 0xe900    /* stmdb Rn{!},
						   { registers } */
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    {
	      pv_t addr = regs[bits (insn, 0, 3)];
	      int regno;

	      if (stack.store_would_trash (addr))
		break;

	      /* Calculate offsets of saved registers.  */
	      for (regno = ARM_LR_REGNUM; regno >= 0; regno--)
		if (inst2 & (1 << regno))
		  {
		    addr = pv_add_constant (addr, -4);
		    stack.store (addr, 4, regs[regno]);
		  }

	      if (insn & 0x0020)
		regs[bits (insn, 0, 3)] = addr;
	    }

	  else if ((insn & 0xff50) == 0xe940	/* strd Rt, Rt2,
						   [Rn, #+/-imm]{!} */
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    {
	      int regno1 = bits (inst2, 12, 15);
	      int regno2 = bits (inst2, 8, 11);
	      pv_t addr = regs[bits (insn, 0, 3)];

	      offset = inst2 & 0xff;
	      if (insn & 0x0080)
		addr = pv_add_constant (addr, offset);
	      else
		addr = pv_add_constant (addr, -offset);

	      if (stack.store_would_trash (addr))
		break;

	      stack.store (addr, 4, regs[regno1]);
	      stack.store (pv_add_constant (addr, 4),
			   4, regs[regno2]);

	      if (insn & 0x0020)
		regs[bits (insn, 0, 3)] = addr;
	    }

	  else if ((insn & 0xfff0) == 0xf8c0	/* str Rt,[Rn,+/-#imm]{!} */
		   && (inst2 & 0x0c00) == 0x0c00
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    {
	      int regno = bits (inst2, 12, 15);
	      pv_t addr = regs[bits (insn, 0, 3)];

	      offset = inst2 & 0xff;
	      if (inst2 & 0x0200)
		addr = pv_add_constant (addr, offset);
	      else
		addr = pv_add_constant (addr, -offset);

	      if (stack.store_would_trash (addr))
		break;

	      stack.store (addr, 4, regs[regno]);

	      if (inst2 & 0x0100)
		regs[bits (insn, 0, 3)] = addr;
	    }

	  else if ((insn & 0xfff0) == 0xf8c0	/* str.w Rt,[Rn,#imm] */
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    {
	      int regno = bits (inst2, 12, 15);
	      pv_t addr;

	      offset = inst2 & 0xfff;
	      addr = pv_add_constant (regs[bits (insn, 0, 3)], offset);

	      if (stack.store_would_trash (addr))
		break;

	      stack.store (addr, 4, regs[regno]);
	    }

	  else if ((insn & 0xffd0) == 0xf880	/* str{bh}.w Rt,[Rn,#imm] */
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    /* Ignore stores of argument registers to the stack.  */
	    ;

	  else if ((insn & 0xffd0) == 0xf800	/* str{bh} Rt,[Rn,#+/-imm] */
		   && (inst2 & 0x0d00) == 0x0c00
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    /* Ignore stores of argument registers to the stack.  */
	    ;

	  else if ((insn & 0xffd0) == 0xe890	/* ldmia Rn[!],
						   { registers } */
		   && (inst2 & 0x8000) == 0x0000
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    /* Ignore block loads from the stack, potentially copying
	       parameters from memory.  */
	    ;

	  else if ((insn & 0xff70) == 0xe950    /* ldrd Rt, Rt2,
						   [Rn, #+/-imm] */
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    /* Similarly ignore dual loads from the stack.  */
	    ;

	  else if ((insn & 0xfff0) == 0xf850	/* ldr Rt,[Rn,#+/-imm] */
		   && (inst2 & 0x0d00) == 0x0c00
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    /* Similarly ignore single loads from the stack.  */
	    ;

	  else if ((insn & 0xfff0) == 0xf8d0	/* ldr.w Rt,[Rn,#imm] */
		   && pv_is_register (regs[bits (insn, 0, 3)], ARM_SP_REGNUM))
	    /* Similarly ignore single loads from the stack.  */
	    ;

	  else if ((insn & 0xfbf0) == 0xf100	/* add.w Rd, Rn, #imm */
		   && (inst2 & 0x8000) == 0x0000)
	    {
	      unsigned int imm = ((bits (insn, 10, 10) << 11)
				  | (bits (inst2, 12, 14) << 8)
				  | bits (inst2, 0, 7));

	      regs[bits (inst2, 8, 11)]
		= pv_add_constant (regs[bits (insn, 0, 3)],
				   thumb_expand_immediate (imm));
	    }

	  else if ((insn & 0xfbf0) == 0xf200	/* addw Rd, Rn, #imm */
		   && (inst2 & 0x8000) == 0x0000)
	    {
	      unsigned int imm = ((bits (insn, 10, 10) << 11)
				  | (bits (inst2, 12, 14) << 8)
				  | bits (inst2, 0, 7));

	      regs[bits (inst2, 8, 11)]
		= pv_add_constant (regs[bits (insn, 0, 3)], imm);
	    }

	  else if ((insn & 0xfbf0) == 0xf1a0	/* sub.w Rd, Rn, #imm */
		   && (inst2 & 0x8000) == 0x0000)
	    {
	      unsigned int imm = ((bits (insn, 10, 10) << 11)
				  | (bits (inst2, 12, 14) << 8)
				  | bits (inst2, 0, 7));

	      regs[bits (inst2, 8, 11)]
		= pv_add_constant (regs[bits (insn, 0, 3)],
				   - (CORE_ADDR) thumb_expand_immediate (imm));
	    }

	  else if ((insn & 0xfbf0) == 0xf2a0	/* subw Rd, Rn, #imm */
		   && (inst2 & 0x8000) == 0x0000)
	    {
	      unsigned int imm = ((bits (insn, 10, 10) << 11)
				  | (bits (inst2, 12, 14) << 8)
				  | bits (inst2, 0, 7));

	      regs[bits (inst2, 8, 11)]
		= pv_add_constant (regs[bits (insn, 0, 3)], - (CORE_ADDR) imm);
	    }

	  else if ((insn & 0xfbff) == 0xf04f)	/* mov.w Rd, #const */
	    {
	      unsigned int imm = ((bits (insn, 10, 10) << 11)
				  | (bits (inst2, 12, 14) << 8)
				  | bits (inst2, 0, 7));

	      regs[bits (inst2, 8, 11)]
		= pv_constant (thumb_expand_immediate (imm));
	    }

	  else if ((insn & 0xfbf0) == 0xf240)	/* movw Rd, #const */
	    {
	      unsigned int imm
		= EXTRACT_MOVW_MOVT_IMM_T (insn, inst2);

	      regs[bits (inst2, 8, 11)] = pv_constant (imm);
	    }

	  else if (insn == 0xea5f		/* mov.w Rd,Rm */
		   && (inst2 & 0xf0f0) == 0)
	    {
	      int dst_reg = (inst2 & 0x0f00) >> 8;
	      int src_reg = inst2 & 0xf;
	      regs[dst_reg] = regs[src_reg];
	    }

	  else if ((insn & 0xff7f) == 0xf85f)	/* ldr.w Rt,<label> */
	    {
	      /* Constant pool loads.  */
	      unsigned int constant;
	      CORE_ADDR loc;

	      offset = bits (inst2, 0, 11);
	      if (insn & 0x0080)
		loc = start + 4 + offset;
	      else
		loc = start + 4 - offset;

	      constant = read_memory_unsigned_integer (loc, 4, byte_order);
	      regs[bits (inst2, 12, 15)] = pv_constant (constant);
	    }

	  else if ((insn & 0xff7f) == 0xe95f)	/* ldrd Rt,Rt2,<label> */
	    {
	      /* Constant pool loads.  */
	      unsigned int constant;
	      CORE_ADDR loc;

	      offset = bits (inst2, 0, 7) << 2;
	      if (insn & 0x0080)
		loc = start + 4 + offset;
	      else
		loc = start + 4 - offset;

	      constant = read_memory_unsigned_integer (loc, 4, byte_order);
	      regs[bits (inst2, 12, 15)] = pv_constant (constant);

	      constant = read_memory_unsigned_integer (loc + 4, 4, byte_order);
	      regs[bits (inst2, 8, 11)] = pv_constant (constant);
	    }

	  else if (thumb2_instruction_changes_pc (insn, inst2))
	    {
	      /* Don't scan past anything that might change control flow.  */
	      break;
	    }
	  else
	    {
	      /* The optimizer might shove anything into the prologue,
		 so we just skip what we don't recognize.  */
	      unrecognized_pc = start;
	    }

	  start += 2;
	}
      else if (thumb_instruction_changes_pc (insn))
	{
	  /* Don't scan past anything that might change control flow.  */
	  break;
	}
      else
	{
	  /* The optimizer might shove anything into the prologue,
	     so we just skip what we don't recognize.  */
	  unrecognized_pc = start;
	}

      start += 2;
    }

  arm_debug_printf ("Prologue scan stopped at %s",
		    paddress (gdbarch, start));

  if (unrecognized_pc == 0)
    unrecognized_pc = start;

  if (cache == NULL)
    return unrecognized_pc;

  if (pv_is_register (regs[ARM_FP_REGNUM], ARM_SP_REGNUM))
    {
      /* Frame pointer is fp.  Frame size is constant.  */
      cache->framereg = ARM_FP_REGNUM;
      cache->framesize = -regs[ARM_FP_REGNUM].k;
    }
  else if (pv_is_register (regs[THUMB_FP_REGNUM], ARM_SP_REGNUM))
    {
      /* Frame pointer is r7.  Frame size is constant.  */
      cache->framereg = THUMB_FP_REGNUM;
      cache->framesize = -regs[THUMB_FP_REGNUM].k;
    }
  else
    {
      /* Try the stack pointer... this is a bit desperate.  */
      cache->framereg = ARM_SP_REGNUM;
      cache->framesize = -regs[ARM_SP_REGNUM].k;
    }

  for (i = 0; i < 16; i++)
    if (stack.find_reg (gdbarch, i, &offset))
      cache->saved_regs[i].set_addr (offset);

  return unrecognized_pc;
}


/* Try to analyze the instructions starting from PC, which load symbol
   __stack_chk_guard.  Return the address of instruction after loading this
   symbol, set the dest register number to *BASEREG, and set the size of
   instructions for loading symbol in OFFSET.  Return 0 if instructions are
   not recognized.  */

static CORE_ADDR
arm_analyze_load_stack_chk_guard(CORE_ADDR pc, struct gdbarch *gdbarch,
				 unsigned int *destreg, int *offset)
{
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  int is_thumb = arm_pc_is_thumb (gdbarch, pc);
  unsigned int low, high, address;

  address = 0;
  if (is_thumb)
    {
      unsigned short insn1
	= read_code_unsigned_integer (pc, 2, byte_order_for_code);

      if ((insn1 & 0xf800) == 0x4800) /* ldr Rd, #immed */
	{
	  *destreg = bits (insn1, 8, 10);
	  *offset = 2;
	  address = (pc & 0xfffffffc) + 4 + (bits (insn1, 0, 7) << 2);
	  address = read_memory_unsigned_integer (address, 4,
						  byte_order_for_code);
	}
      else if ((insn1 & 0xfbf0) == 0xf240) /* movw Rd, #const */
	{
	  unsigned short insn2
	    = read_code_unsigned_integer (pc + 2, 2, byte_order_for_code);

	  low = EXTRACT_MOVW_MOVT_IMM_T (insn1, insn2);

	  insn1
	    = read_code_unsigned_integer (pc + 4, 2, byte_order_for_code);
	  insn2
	    = read_code_unsigned_integer (pc + 6, 2, byte_order_for_code);

	  /* movt Rd, #const */
	  if ((insn1 & 0xfbc0) == 0xf2c0)
	    {
	      high = EXTRACT_MOVW_MOVT_IMM_T (insn1, insn2);
	      *destreg = bits (insn2, 8, 11);
	      *offset = 8;
	      address = (high << 16 | low);
	    }
	}
    }
  else
    {
      unsigned int insn
	= read_code_unsigned_integer (pc, 4, byte_order_for_code);

      if ((insn & 0x0e5f0000) == 0x041f0000) /* ldr Rd, [PC, #immed] */
	{
	  address = bits (insn, 0, 11) + pc + 8;
	  address = read_memory_unsigned_integer (address, 4,
						  byte_order_for_code);

	  *destreg = bits (insn, 12, 15);
	  *offset = 4;
	}
      else if ((insn & 0x0ff00000) == 0x03000000) /* movw Rd, #const */
	{
	  low = EXTRACT_MOVW_MOVT_IMM_A (insn);

	  insn
	    = read_code_unsigned_integer (pc + 4, 4, byte_order_for_code);

	  if ((insn & 0x0ff00000) == 0x03400000) /* movt Rd, #const */
	    {
	      high = EXTRACT_MOVW_MOVT_IMM_A (insn);
	      *destreg = bits (insn, 12, 15);
	      *offset = 8;
	      address = (high << 16 | low);
	    }
	}
    }

  return address;
}

/* Try to skip a sequence of instructions used for stack protector.  If PC
   points to the first instruction of this sequence, return the address of
   first instruction after this sequence, otherwise, return original PC.

   On arm, this sequence of instructions is composed of mainly three steps,
     Step 1: load symbol __stack_chk_guard,
     Step 2: load from address of __stack_chk_guard,
     Step 3: store it to somewhere else.

   Usually, instructions on step 2 and step 3 are the same on various ARM
   architectures.  On step 2, it is one instruction 'ldr Rx, [Rn, #0]', and
   on step 3, it is also one instruction 'str Rx, [r7, #immd]'.  However,
   instructions in step 1 vary from different ARM architectures.  On ARMv7,
   they are,

	movw	Rn, #:lower16:__stack_chk_guard
	movt	Rn, #:upper16:__stack_chk_guard

   On ARMv5t, it is,

	ldr	Rn, .Label
	....
	.Lable:
	.word	__stack_chk_guard

   Since ldr/str is a very popular instruction, we can't use them as
   'fingerprint' or 'signature' of stack protector sequence.  Here we choose
   sequence {movw/movt, ldr}/ldr/str plus symbol __stack_chk_guard, if not
   stripped, as the 'fingerprint' of a stack protector cdoe sequence.  */

static CORE_ADDR
arm_skip_stack_protector(CORE_ADDR pc, struct gdbarch *gdbarch)
{
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  unsigned int basereg;
  struct bound_minimal_symbol stack_chk_guard;
  int offset;
  int is_thumb = arm_pc_is_thumb (gdbarch, pc);
  CORE_ADDR addr;

  /* Try to parse the instructions in Step 1.  */
  addr = arm_analyze_load_stack_chk_guard (pc, gdbarch,
					   &basereg, &offset);
  if (!addr)
    return pc;

  stack_chk_guard = lookup_minimal_symbol_by_pc (addr);
  /* ADDR must correspond to a symbol whose name is __stack_chk_guard.
     Otherwise, this sequence cannot be for stack protector.  */
  if (stack_chk_guard.minsym == NULL
      || !startswith (stack_chk_guard.minsym->linkage_name (), "__stack_chk_guard"))
   return pc;

  if (is_thumb)
    {
      unsigned int destreg;
      unsigned short insn
	= read_code_unsigned_integer (pc + offset, 2, byte_order_for_code);

      /* Step 2: ldr Rd, [Rn, #immed], encoding T1.  */
      if ((insn & 0xf800) != 0x6800)
	return pc;
      if (bits (insn, 3, 5) != basereg)
	return pc;
      destreg = bits (insn, 0, 2);

      insn = read_code_unsigned_integer (pc + offset + 2, 2,
					 byte_order_for_code);
      /* Step 3: str Rd, [Rn, #immed], encoding T1.  */
      if ((insn & 0xf800) != 0x6000)
	return pc;
      if (destreg != bits (insn, 0, 2))
	return pc;
    }
  else
    {
      unsigned int destreg;
      unsigned int insn
	= read_code_unsigned_integer (pc + offset, 4, byte_order_for_code);

      /* Step 2: ldr Rd, [Rn, #immed], encoding A1.  */
      if ((insn & 0x0e500000) != 0x04100000)
	return pc;
      if (bits (insn, 16, 19) != basereg)
	return pc;
      destreg = bits (insn, 12, 15);
      /* Step 3: str Rd, [Rn, #immed], encoding A1.  */
      insn = read_code_unsigned_integer (pc + offset + 4,
					   4, byte_order_for_code);
      if ((insn & 0x0e500000) != 0x04000000)
	return pc;
      if (bits (insn, 12, 15) != destreg)
	return pc;
    }
  /* The size of total two instructions ldr/str is 4 on Thumb-2, while 8
     on arm.  */
  if (is_thumb)
    return pc + offset + 4;
  else
    return pc + offset + 8;
}

/* Advance the PC across any function entry prologue instructions to
   reach some "real" code.

   The APCS (ARM Procedure Call Standard) defines the following
   prologue:

   mov          ip, sp
   [stmfd       sp!, {a1,a2,a3,a4}]
   stmfd        sp!, {...,fp,ip,lr,pc}
   [stfe        f7, [sp, #-12]!]
   [stfe        f6, [sp, #-12]!]
   [stfe        f5, [sp, #-12]!]
   [stfe        f4, [sp, #-12]!]
   sub fp, ip, #nn @@ nn == 20 or 4 depending on second insn.  */

static CORE_ADDR
arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr, limit_pc;

  /* See if we can determine the end of the prologue via the symbol table.
     If so, then return either PC, or the PC after the prologue, whichever
     is greater.  */
  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr);

      if (post_prologue_pc)
	post_prologue_pc
	  = arm_skip_stack_protector (post_prologue_pc, gdbarch);


      /* GCC always emits a line note before the prologue and another
	 one after, even if the two are at the same address or on the
	 same line.  Take advantage of this so that we do not need to
	 know every instruction that might appear in the prologue.  We
	 will have producer information for most binaries; if it is
	 missing (e.g. for -gstabs), assuming the GNU tools.  */
      if (post_prologue_pc
	  && (cust == NULL
	      || COMPUNIT_PRODUCER (cust) == NULL
	      || startswith (COMPUNIT_PRODUCER (cust), "GNU ")
	      || producer_is_llvm (COMPUNIT_PRODUCER (cust))))
	return post_prologue_pc;

      if (post_prologue_pc != 0)
	{
	  CORE_ADDR analyzed_limit;

	  /* For non-GCC compilers, make sure the entire line is an
	     acceptable prologue; GDB will round this function's
	     return value up to the end of the following line so we
	     can not skip just part of a line (and we do not want to).

	     RealView does not treat the prologue specially, but does
	     associate prologue code with the opening brace; so this
	     lets us skip the first line if we think it is the opening
	     brace.  */
	  if (arm_pc_is_thumb (gdbarch, func_addr))
	    analyzed_limit = thumb_analyze_prologue (gdbarch, func_addr,
						     post_prologue_pc, NULL);
	  else
	    analyzed_limit
	      = arm_analyze_prologue (gdbarch, func_addr, post_prologue_pc,
				      NULL, target_arm_instruction_reader ());

	  if (analyzed_limit != post_prologue_pc)
	    return func_addr;

	  return post_prologue_pc;
	}
    }

  /* Can't determine prologue from the symbol table, need to examine
     instructions.  */

  /* Find an upper limit on the function prologue using the debug
     information.  If the debug information could not be used to provide
     that bound, then use an arbitrary large number as the upper bound.  */
  /* Like arm_scan_prologue, stop no later than pc + 64.  */
  limit_pc = skip_prologue_using_sal (gdbarch, pc);
  if (limit_pc == 0)
    limit_pc = pc + 64;          /* Magic.  */


  /* Check if this is Thumb code.  */
  if (arm_pc_is_thumb (gdbarch, pc))
    return thumb_analyze_prologue (gdbarch, pc, limit_pc, NULL);
  else
    return arm_analyze_prologue (gdbarch, pc, limit_pc, NULL,
				 target_arm_instruction_reader ());
}

/* *INDENT-OFF* */
/* Function: thumb_scan_prologue (helper function for arm_scan_prologue)
   This function decodes a Thumb function prologue to determine:
     1) the size of the stack frame
     2) which registers are saved on it
     3) the offsets of saved regs
     4) the offset from the stack pointer to the frame pointer

   A typical Thumb function prologue would create this stack frame
   (offsets relative to FP)
     old SP ->	24  stack parameters
		20  LR
		16  R7
     R7 ->       0  local variables (16 bytes)
     SP ->     -12  additional stack space (12 bytes)
   The frame size would thus be 36 bytes, and the frame offset would be
   12 bytes.  The frame register is R7.
   
   The comments for thumb_skip_prolog() describe the algorithm we use
   to detect the end of the prolog.  */
/* *INDENT-ON* */

static void
thumb_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR prev_pc,
		     CORE_ADDR block_addr, struct arm_prologue_cache *cache)
{
  CORE_ADDR prologue_start;
  CORE_ADDR prologue_end;

  if (find_pc_partial_function (block_addr, NULL, &prologue_start,
				&prologue_end))
    {
      /* See comment in arm_scan_prologue for an explanation of
	 this heuristics.  */
      if (prologue_end > prologue_start + 64)
	{
	  prologue_end = prologue_start + 64;
	}
    }
  else
    /* We're in the boondocks: we have no idea where the start of the
       function is.  */
    return;

  prologue_end = std::min (prologue_end, prev_pc);

  thumb_analyze_prologue (gdbarch, prologue_start, prologue_end, cache);
}

/* Return 1 if the ARM instruction INSN restores SP in epilogue, 0
   otherwise.  */

static int
arm_instruction_restores_sp (unsigned int insn)
{
  if (bits (insn, 28, 31) != INST_NV)
    {
      if ((insn & 0x0df0f000) == 0x0080d000
	  /* ADD SP (register or immediate).  */
	  || (insn & 0x0df0f000) == 0x0040d000
	  /* SUB SP (register or immediate).  */
	  || (insn & 0x0ffffff0) == 0x01a0d000
	  /* MOV SP.  */
	  || (insn & 0x0fff0000) == 0x08bd0000
	  /* POP (LDMIA).  */
	  || (insn & 0x0fff0000) == 0x049d0000)
	  /* POP of a single register.  */
	return 1;
    }

  return 0;
}

/* Implement immediate value decoding, as described in section A5.2.4
   (Modified immediate constants in ARM instructions) of the ARM Architecture
   Reference Manual (ARMv7-A and ARMv7-R edition).  */

static uint32_t
arm_expand_immediate (uint32_t imm)
{
  /* Immediate values are 12 bits long.  */
  gdb_assert ((imm & 0xfffff000) == 0);

  uint32_t unrotated_value = imm & 0xff;
  uint32_t rotate_amount = (imm & 0xf00) >> 7;

  if (rotate_amount == 0)
    return unrotated_value;

  return ((unrotated_value >> rotate_amount)
	  | (unrotated_value << (32 - rotate_amount)));
}

/* Analyze an ARM mode prologue starting at PROLOGUE_START and
   continuing no further than PROLOGUE_END.  If CACHE is non-NULL,
   fill it in.  Return the first address not recognized as a prologue
   instruction.

   We recognize all the instructions typically found in ARM prologues,
   plus harmless instructions which can be skipped (either for analysis
   purposes, or a more restrictive set that can be skipped when finding
   the end of the prologue).  */

static CORE_ADDR
arm_analyze_prologue (struct gdbarch *gdbarch,
		      CORE_ADDR prologue_start, CORE_ADDR prologue_end,
		      struct arm_prologue_cache *cache,
		      const arm_instruction_reader &insn_reader)
{
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  int regno;
  CORE_ADDR offset, current_pc;
  pv_t regs[ARM_FPS_REGNUM];
  CORE_ADDR unrecognized_pc = 0;
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* Search the prologue looking for instructions that set up the
     frame pointer, adjust the stack pointer, and save registers.

     Be careful, however, and if it doesn't look like a prologue,
     don't try to scan it.  If, for instance, a frameless function
     begins with stmfd sp!, then we will tell ourselves there is
     a frame, which will confuse stack traceback, as well as "finish" 
     and other operations that rely on a knowledge of the stack
     traceback.  */

  for (regno = 0; regno < ARM_FPS_REGNUM; regno++)
    regs[regno] = pv_register (regno, 0);
  pv_area stack (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));

  for (current_pc = prologue_start;
       current_pc < prologue_end;
       current_pc += 4)
    {
      uint32_t insn = insn_reader.read (current_pc, byte_order_for_code);

      if (insn == 0xe1a0c00d)		/* mov ip, sp */
	{
	  regs[ARM_IP_REGNUM] = regs[ARM_SP_REGNUM];
	  continue;
	}
      else if ((insn & 0xfff00000) == 0xe2800000	/* add Rd, Rn, #n */
	       && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
	{
	  uint32_t imm = arm_expand_immediate (insn & 0xfff);
	  int rd = bits (insn, 12, 15);
	  regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], imm);
	  continue;
	}
      else if ((insn & 0xfff00000) == 0xe2400000	/* sub Rd, Rn, #n */
	       && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
	{
	  uint32_t imm = arm_expand_immediate (insn & 0xfff);
	  int rd = bits (insn, 12, 15);
	  regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], -imm);
	  continue;
	}
      else if ((insn & 0xffff0fff) == 0xe52d0004)	/* str Rd,
							   [sp, #-4]! */
	{
	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
	    break;
	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -4);
	  stack.store (regs[ARM_SP_REGNUM], 4,
		       regs[bits (insn, 12, 15)]);
	  continue;
	}
      else if ((insn & 0xffff0000) == 0xe92d0000)
	/* stmfd sp!, {..., fp, ip, lr, pc}
	   or
	   stmfd sp!, {a1, a2, a3, a4}  */
	{
	  int mask = insn & 0xffff;

	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
	    break;

	  /* Calculate offsets of saved registers.  */
	  for (regno = ARM_PC_REGNUM; regno >= 0; regno--)
	    if (mask & (1 << regno))
	      {
		regs[ARM_SP_REGNUM]
		  = pv_add_constant (regs[ARM_SP_REGNUM], -4);
		stack.store (regs[ARM_SP_REGNUM], 4, regs[regno]);
	      }
	}
      else if ((insn & 0xffff0000) == 0xe54b0000	/* strb rx,[r11,#-n] */
	       || (insn & 0xffff00f0) == 0xe14b00b0	/* strh rx,[r11,#-n] */
	       || (insn & 0xffffc000) == 0xe50b0000)	/* str  rx,[r11,#-n] */
	{
	  /* No need to add this to saved_regs -- it's just an arg reg.  */
	  continue;
	}
      else if ((insn & 0xffff0000) == 0xe5cd0000	/* strb rx,[sp,#n] */
	       || (insn & 0xffff00f0) == 0xe1cd00b0	/* strh rx,[sp,#n] */
	       || (insn & 0xffffc000) == 0xe58d0000)	/* str  rx,[sp,#n] */
	{
	  /* No need to add this to saved_regs -- it's just an arg reg.  */
	  continue;
	}
      else if ((insn & 0xfff00000) == 0xe8800000	/* stm Rn,
							   { registers } */
	       && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
	{
	  /* No need to add this to saved_regs -- it's just arg regs.  */
	  continue;
	}
      else if ((insn & 0xfffff000) == 0xe24cb000)	/* sub fp, ip #n */
	{
	  uint32_t imm = arm_expand_immediate (insn & 0xfff);
	  regs[ARM_FP_REGNUM] = pv_add_constant (regs[ARM_IP_REGNUM], -imm);
	}
      else if ((insn & 0xfffff000) == 0xe24dd000)	/* sub sp, sp #n */
	{
	  uint32_t imm = arm_expand_immediate(insn & 0xfff);
	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -imm);
	}
      else if ((insn & 0xffff7fff) == 0xed6d0103	/* stfe f?,
							   [sp, -#c]! */
	       && tdep->have_fpa_registers)
	{
	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
	    break;

	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12);
	  regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
	  stack.store (regs[ARM_SP_REGNUM], 12, regs[regno]);
	}
      else if ((insn & 0xffbf0fff) == 0xec2d0200	/* sfmfd f0, 4,
							   [sp!] */
	       && tdep->have_fpa_registers)
	{
	  int n_saved_fp_regs;
	  unsigned int fp_start_reg, fp_bound_reg;

	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
	    break;

	  if ((insn & 0x800) == 0x800)		/* N0 is set */
	    {
	      if ((insn & 0x40000) == 0x40000)	/* N1 is set */
		n_saved_fp_regs = 3;
	      else
		n_saved_fp_regs = 1;
	    }
	  else
	    {
	      if ((insn & 0x40000) == 0x40000)	/* N1 is set */
		n_saved_fp_regs = 2;
	      else
		n_saved_fp_regs = 4;
	    }

	  fp_start_reg = ARM_F0_REGNUM + ((insn >> 12) & 0x7);
	  fp_bound_reg = fp_start_reg + n_saved_fp_regs;
	  for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
	    {
	      regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12);
	      stack.store (regs[ARM_SP_REGNUM], 12,
			   regs[fp_start_reg++]);
	    }
	}
      else if ((insn & 0xff000000) == 0xeb000000 && cache == NULL) /* bl */
	{
	  /* Allow some special function calls when skipping the
	     prologue; GCC generates these before storing arguments to
	     the stack.  */
	  CORE_ADDR dest = BranchDest (current_pc, insn);

	  if (skip_prologue_function (gdbarch, dest, 0))
	    continue;
	  else
	    break;
	}
      else if ((insn & 0xf0000000) != 0xe0000000)
	break;			/* Condition not true, exit early.  */
      else if (arm_instruction_changes_pc (insn))
	/* Don't scan past anything that might change control flow.  */
	break;
      else if (arm_instruction_restores_sp (insn))
	{
	  /* Don't scan past the epilogue.  */
	  break;
	}
      else if ((insn & 0xfe500000) == 0xe8100000	/* ldm */
	       && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
	/* Ignore block loads from the stack, potentially copying
	   parameters from memory.  */
	continue;
      else if ((insn & 0xfc500000) == 0xe4100000
	       && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
	/* Similarly ignore single loads from the stack.  */
	continue;
      else if ((insn & 0xffff0ff0) == 0xe1a00000)
	/* MOV Rd, Rm.  Skip register copies, i.e. saves to another
	   register instead of the stack.  */
	continue;
      else
	{
	  /* The optimizer might shove anything into the prologue, if
	     we build up cache (cache != NULL) from scanning prologue,
	     we just skip what we don't recognize and scan further to
	     make cache as complete as possible.  However, if we skip
	     prologue, we'll stop immediately on unrecognized
	     instruction.  */
	  unrecognized_pc = current_pc;
	  if (cache != NULL)
	    continue;
	  else
	    break;
	}
    }

  if (unrecognized_pc == 0)
    unrecognized_pc = current_pc;

  if (cache)
    {
      int framereg, framesize;

      /* The frame size is just the distance from the frame register
	 to the original stack pointer.  */
      if (pv_is_register (regs[ARM_FP_REGNUM], ARM_SP_REGNUM))
	{
	  /* Frame pointer is fp.  */
	  framereg = ARM_FP_REGNUM;
	  framesize = -regs[ARM_FP_REGNUM].k;
	}
      else
	{
	  /* Try the stack pointer... this is a bit desperate.  */
	  framereg = ARM_SP_REGNUM;
	  framesize = -regs[ARM_SP_REGNUM].k;
	}

      cache->framereg = framereg;
      cache->framesize = framesize;

      for (regno = 0; regno < ARM_FPS_REGNUM; regno++)
	if (stack.find_reg (gdbarch, regno, &offset))
	  cache->saved_regs[regno].set_addr (offset);
    }

  arm_debug_printf ("Prologue scan stopped at %s",
		    paddress (gdbarch, unrecognized_pc));

  return unrecognized_pc;
}

static void
arm_scan_prologue (struct frame_info *this_frame,
		   struct arm_prologue_cache *cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR prologue_start, prologue_end;
  CORE_ADDR prev_pc = get_frame_pc (this_frame);
  CORE_ADDR block_addr = get_frame_address_in_block (this_frame);
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* Assume there is no frame until proven otherwise.  */
  cache->framereg = ARM_SP_REGNUM;
  cache->framesize = 0;

  /* Check for Thumb prologue.  */
  if (arm_frame_is_thumb (this_frame))
    {
      thumb_scan_prologue (gdbarch, prev_pc, block_addr, cache);
      return;
    }

  /* Find the function prologue.  If we can't find the function in
     the symbol table, peek in the stack frame to find the PC.  */
  if (find_pc_partial_function (block_addr, NULL, &prologue_start,
				&prologue_end))
    {
      /* One way to find the end of the prologue (which works well
	 for unoptimized code) is to do the following:

	    struct symtab_and_line sal = find_pc_line (prologue_start, 0);

	    if (sal.line == 0)
	      prologue_end = prev_pc;
	    else if (sal.end < prologue_end)
	      prologue_end = sal.end;

	 This mechanism is very accurate so long as the optimizer
	 doesn't move any instructions from the function body into the
	 prologue.  If this happens, sal.end will be the last
	 instruction in the first hunk of prologue code just before
	 the first instruction that the scheduler has moved from
	 the body to the prologue.

	 In order to make sure that we scan all of the prologue
	 instructions, we use a slightly less accurate mechanism which
	 may scan more than necessary.  To help compensate for this
	 lack of accuracy, the prologue scanning loop below contains
	 several clauses which'll cause the loop to terminate early if
	 an implausible prologue instruction is encountered.

	 The expression

	      prologue_start + 64

	 is a suitable endpoint since it accounts for the largest
	 possible prologue plus up to five instructions inserted by
	 the scheduler.  */

      if (prologue_end > prologue_start + 64)
	{
	  prologue_end = prologue_start + 64;	/* See above.  */
	}
    }
  else
    {
      /* We have no symbol information.  Our only option is to assume this
	 function has a standard stack frame and the normal frame register.
	 Then, we can find the value of our frame pointer on entrance to
	 the callee (or at the present moment if this is the innermost frame).
	 The value stored there should be the address of the stmfd + 8.  */
      CORE_ADDR frame_loc;
      ULONGEST return_value;

      /* AAPCS does not use a frame register, so we can abort here.  */
      if (tdep->arm_abi == ARM_ABI_AAPCS)
	return;

      frame_loc = get_frame_register_unsigned (this_frame, ARM_FP_REGNUM);
      if (!safe_read_memory_unsigned_integer (frame_loc, 4, byte_order,
					      &return_value))
	return;
      else
	{
	  prologue_start = gdbarch_addr_bits_remove
			     (gdbarch, return_value) - 8;
	  prologue_end = prologue_start + 64;	/* See above.  */
	}
    }

  if (prev_pc < prologue_end)
    prologue_end = prev_pc;

  arm_analyze_prologue (gdbarch, prologue_start, prologue_end, cache,
			target_arm_instruction_reader ());
}

static struct arm_prologue_cache *
arm_make_prologue_cache (struct frame_info *this_frame)
{
  int reg;
  struct arm_prologue_cache *cache;
  CORE_ADDR unwound_fp;

  cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  arm_scan_prologue (this_frame, cache);

  unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg);
  if (unwound_fp == 0)
    return cache;

  cache->prev_sp = unwound_fp + cache->framesize;

  /* Calculate actual addresses of saved registers using offsets
     determined by arm_scan_prologue.  */
  for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++)
    if (cache->saved_regs[reg].is_addr ())
      cache->saved_regs[reg].set_addr (cache->saved_regs[reg].addr ()
				       + cache->prev_sp);

  return cache;
}

/* Implementation of the stop_reason hook for arm_prologue frames.  */

static enum unwind_stop_reason
arm_prologue_unwind_stop_reason (struct frame_info *this_frame,
				 void **this_cache)
{
  struct arm_prologue_cache *cache;
  CORE_ADDR pc;

  if (*this_cache == NULL)
    *this_cache = arm_make_prologue_cache (this_frame);
  cache = (struct arm_prologue_cache *) *this_cache;

  /* This is meant to halt the backtrace at "_start".  */
  pc = get_frame_pc (this_frame);
  gdbarch *arch = get_frame_arch (this_frame);
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (arch);
  if (pc <= tdep->lowest_pc)
    return UNWIND_OUTERMOST;

  /* If we've hit a wall, stop.  */
  if (cache->prev_sp == 0)
    return UNWIND_OUTERMOST;

  return UNWIND_NO_REASON;
}

/* Our frame ID for a normal frame is the current function's starting PC
   and the caller's SP when we were called.  */

static void
arm_prologue_this_id (struct frame_info *this_frame,
		      void **this_cache,
		      struct frame_id *this_id)
{
  struct arm_prologue_cache *cache;
  struct frame_id id;
  CORE_ADDR pc, func;

  if (*this_cache == NULL)
    *this_cache = arm_make_prologue_cache (this_frame);
  cache = (struct arm_prologue_cache *) *this_cache;

  /* Use function start address as part of the frame ID.  If we cannot
     identify the start address (due to missing symbol information),
     fall back to just using the current PC.  */
  pc = get_frame_pc (this_frame);
  func = get_frame_func (this_frame);
  if (!func)
    func = pc;

  id = frame_id_build (cache->prev_sp, func);
  *this_id = id;
}

static struct value *
arm_prologue_prev_register (struct frame_info *this_frame,
			    void **this_cache,
			    int prev_regnum)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct arm_prologue_cache *cache;

  if (*this_cache == NULL)
    *this_cache = arm_make_prologue_cache (this_frame);
  cache = (struct arm_prologue_cache *) *this_cache;

  /* If we are asked to unwind the PC, then we need to return the LR
     instead.  The prologue may save PC, but it will point into this
     frame's prologue, not the next frame's resume location.  Also
     strip the saved T bit.  A valid LR may have the low bit set, but
     a valid PC never does.  */
  if (prev_regnum == ARM_PC_REGNUM)
    {
      CORE_ADDR lr;

      lr = frame_unwind_register_unsigned (this_frame, ARM_LR_REGNUM);
      return frame_unwind_got_constant (this_frame, prev_regnum,
					arm_addr_bits_remove (gdbarch, lr));
    }

  /* SP is generally not saved to the stack, but this frame is
     identified by the next frame's stack pointer at the time of the call.
     The value was already reconstructed into PREV_SP.  */
  if (prev_regnum == ARM_SP_REGNUM)
    return frame_unwind_got_constant (this_frame, prev_regnum, cache->prev_sp);

  /* The CPSR may have been changed by the call instruction and by the
     called function.  The only bit we can reconstruct is the T bit,
     by checking the low bit of LR as of the call.  This is a reliable
     indicator of Thumb-ness except for some ARM v4T pre-interworking
     Thumb code, which could get away with a clear low bit as long as
     the called function did not use bx.  Guess that all other
     bits are unchanged; the condition flags are presumably lost,
     but the processor status is likely valid.  */
  if (prev_regnum == ARM_PS_REGNUM)
    {
      CORE_ADDR lr, cpsr;
      ULONGEST t_bit = arm_psr_thumb_bit (gdbarch);

      cpsr = get_frame_register_unsigned (this_frame, prev_regnum);
      lr = frame_unwind_register_unsigned (this_frame, ARM_LR_REGNUM);
      if (IS_THUMB_ADDR (lr))
	cpsr |= t_bit;
      else
	cpsr &= ~t_bit;
      return frame_unwind_got_constant (this_frame, prev_regnum, cpsr);
    }

  return trad_frame_get_prev_register (this_frame, cache->saved_regs,
				       prev_regnum);
}

static frame_unwind arm_prologue_unwind = {
  "arm prologue",
  NORMAL_FRAME,
  arm_prologue_unwind_stop_reason,
  arm_prologue_this_id,
  arm_prologue_prev_register,
  NULL,
  default_frame_sniffer
};

/* Maintain a list of ARM exception table entries per objfile, similar to the
   list of mapping symbols.  We only cache entries for standard ARM-defined
   personality routines; the cache will contain only the frame unwinding
   instructions associated with the entry (not the descriptors).  */

struct arm_exidx_entry
{
  CORE_ADDR addr;
  gdb_byte *entry;

  bool operator< (const arm_exidx_entry &other) const
  {
    return addr < other.addr;
  }
};

struct arm_exidx_data
{
  std::vector<std::vector<arm_exidx_entry>> section_maps;
};

/* Per-BFD key to store exception handling information.  */
static const struct bfd_key<arm_exidx_data> arm_exidx_data_key;

static struct obj_section *
arm_obj_section_from_vma (struct objfile *objfile, bfd_vma vma)
{
  struct obj_section *osect;

  ALL_OBJFILE_OSECTIONS (objfile, osect)
    if (bfd_section_flags (osect->the_bfd_section) & SEC_ALLOC)
      {
	bfd_vma start, size;
	start = bfd_section_vma (osect->the_bfd_section);
	size = bfd_section_size (osect->the_bfd_section);

	if (start <= vma && vma < start + size)
	  return osect;
      }

  return NULL;
}

/* Parse contents of exception table and exception index sections
   of OBJFILE, and fill in the exception table entry cache.

   For each entry that refers to a standard ARM-defined personality
   routine, extract the frame unwinding instructions (from either
   the index or the table section).  The unwinding instructions
   are normalized by:
    - extracting them from the rest of the table data
    - converting to host endianness
    - appending the implicit 0xb0 ("Finish") code

   The extracted and normalized instructions are stored for later
   retrieval by the arm_find_exidx_entry routine.  */
 
static void
arm_exidx_new_objfile (struct objfile *objfile)
{
  struct arm_exidx_data *data;
  asection *exidx, *extab;
  bfd_vma exidx_vma = 0, extab_vma = 0;
  LONGEST i;

  /* If we've already touched this file, do nothing.  */
  if (!objfile || arm_exidx_data_key.get (objfile->obfd) != NULL)
    return;

  /* Read contents of exception table and index.  */
  exidx = bfd_get_section_by_name (objfile->obfd, ELF_STRING_ARM_unwind);
  gdb::byte_vector exidx_data;
  if (exidx)
    {
      exidx_vma = bfd_section_vma (exidx);
      exidx_data.resize (bfd_section_size (exidx));

      if (!bfd_get_section_contents (objfile->obfd, exidx,
				     exidx_data.data (), 0,
				     exidx_data.size ()))
	return;
    }

  extab = bfd_get_section_by_name (objfile->obfd, ".ARM.extab");
  gdb::byte_vector extab_data;
  if (extab)
    {
      extab_vma = bfd_section_vma (extab);
      extab_data.resize (bfd_section_size (extab));

      if (!bfd_get_section_contents (objfile->obfd, extab,
				     extab_data.data (), 0,
				     extab_data.size ()))
	return;
    }

  /* Allocate exception table data structure.  */
  data = arm_exidx_data_key.emplace (objfile->obfd);
  data->section_maps.resize (objfile->obfd->section_count);

  /* Fill in exception table.  */
  for (i = 0; i < exidx_data.size () / 8; i++)
    {
      struct arm_exidx_entry new_exidx_entry;
      bfd_vma idx = bfd_h_get_32 (objfile->obfd, exidx_data.data () + i * 8);
      bfd_vma val = bfd_h_get_32 (objfile->obfd,
				  exidx_data.data () + i * 8 + 4);
      bfd_vma addr = 0, word = 0;
      int n_bytes = 0, n_words = 0;
      struct obj_section *sec;
      gdb_byte *entry = NULL;

      /* Extract address of start of function.  */
      idx = ((idx & 0x7fffffff) ^ 0x40000000) - 0x40000000;
      idx += exidx_vma + i * 8;

      /* Find section containing function and compute section offset.  */
      sec = arm_obj_section_from_vma (objfile, idx);
      if (sec == NULL)
	continue;
      idx -= bfd_section_vma (sec->the_bfd_section);

      /* Determine address of exception table entry.  */
      if (val == 1)
	{
	  /* EXIDX_CANTUNWIND -- no exception table entry present.  */
	}
      else if ((val & 0xff000000) == 0x80000000)
	{
	  /* Exception table entry embedded in .ARM.exidx
	     -- must be short form.  */
	  word = val;
	  n_bytes = 3;
	}
      else if (!(val & 0x80000000))
	{
	  /* Exception table entry in .ARM.extab.  */
	  addr = ((val & 0x7fffffff) ^ 0x40000000) - 0x40000000;
	  addr += exidx_vma + i * 8 + 4;

	  if (addr >= extab_vma && addr + 4 <= extab_vma + extab_data.size ())
	    {
	      word = bfd_h_get_32 (objfile->obfd,
				   extab_data.data () + addr - extab_vma);
	      addr += 4;

	      if ((word & 0xff000000) == 0x80000000)
		{
		  /* Short form.  */
		  n_bytes = 3;
		}
	      else if ((word & 0xff000000) == 0x81000000
		       || (word & 0xff000000) == 0x82000000)
		{
		  /* Long form.  */
		  n_bytes = 2;
		  n_words = ((word >> 16) & 0xff);
		}
	      else if (!(word & 0x80000000))
		{
		  bfd_vma pers;
		  struct obj_section *pers_sec;
		  int gnu_personality = 0;

		  /* Custom personality routine.  */
		  pers = ((word & 0x7fffffff) ^ 0x40000000) - 0x40000000;
		  pers = UNMAKE_THUMB_ADDR (pers + addr - 4);

		  /* Check whether we've got one of the variants of the
		     GNU personality routines.  */
		  pers_sec = arm_obj_section_from_vma (objfile, pers);
		  if (pers_sec)
		    {
		      static const char *personality[] = 
			{
			  "__gcc_personality_v0",
			  "__gxx_personality_v0",
			  "__gcj_personality_v0",
			  "__gnu_objc_personality_v0",
			  NULL
			};

		      CORE_ADDR pc = pers + pers_sec->offset ();
		      int k;

		      for (k = 0; personality[k]; k++)
			if (lookup_minimal_symbol_by_pc_name
			      (pc, personality[k], objfile))
			  {
			    gnu_personality = 1;
			    break;
			  }
		    }

		  /* If so, the next word contains a word count in the high
		     byte, followed by the same unwind instructions as the
		     pre-defined forms.  */
		  if (gnu_personality
		      && addr + 4 <= extab_vma + extab_data.size ())
		    {
		      word = bfd_h_get_32 (objfile->obfd,
					   (extab_data.data ()
					    + addr - extab_vma));
		      addr += 4;
		      n_bytes = 3;
		      n_words = ((word >> 24) & 0xff);
		    }
		}
	    }
	}

      /* Sanity check address.  */
      if (n_words)
	if (addr < extab_vma
	    || addr + 4 * n_words > extab_vma + extab_data.size ())
	  n_words = n_bytes = 0;

      /* The unwind instructions reside in WORD (only the N_BYTES least
	 significant bytes are valid), followed by N_WORDS words in the
	 extab section starting at ADDR.  */
      if (n_bytes || n_words)
	{
	  gdb_byte *p = entry
	    = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack,
					  n_bytes + n_words * 4 + 1);

	  while (n_bytes--)
	    *p++ = (gdb_byte) ((word >> (8 * n_bytes)) & 0xff);

	  while (n_words--)
	    {
	      word = bfd_h_get_32 (objfile->obfd,
				   extab_data.data () + addr - extab_vma);
	      addr += 4;

	      *p++ = (gdb_byte) ((word >> 24) & 0xff);
	      *p++ = (gdb_byte) ((word >> 16) & 0xff);
	      *p++ = (gdb_byte) ((word >> 8) & 0xff);
	      *p++ = (gdb_byte) (word & 0xff);
	    }

	  /* Implied "Finish" to terminate the list.  */
	  *p++ = 0xb0;
	}

      /* Push entry onto vector.  They are guaranteed to always
	 appear in order of increasing addresses.  */
      new_exidx_entry.addr = idx;
      new_exidx_entry.entry = entry;
      data->section_maps[sec->the_bfd_section->index].push_back
	(new_exidx_entry);
    }
}

/* Search for the exception table entry covering MEMADDR.  If one is found,
   return a pointer to its data.  Otherwise, return 0.  If START is non-NULL,
   set *START to the start of the region covered by this entry.  */

static gdb_byte *
arm_find_exidx_entry (CORE_ADDR memaddr, CORE_ADDR *start)
{
  struct obj_section *sec;

  sec = find_pc_section (memaddr);
  if (sec != NULL)
    {
      struct arm_exidx_data *data;
      struct arm_exidx_entry map_key = { memaddr - sec->addr (), 0 };

      data = arm_exidx_data_key.get (sec->objfile->obfd);
      if (data != NULL)
	{
	  std::vector<arm_exidx_entry> &map
	    = data->section_maps[sec->the_bfd_section->index];
	  if (!map.empty ())
	    {
	      auto idx = std::lower_bound (map.begin (), map.end (), map_key);

	      /* std::lower_bound finds the earliest ordered insertion
		 point.  If the following symbol starts at this exact
		 address, we use that; otherwise, the preceding
		 exception table entry covers this address.  */
	      if (idx < map.end ())
		{
		  if (idx->addr == map_key.addr)
		    {
		      if (start)
			*start = idx->addr + sec->addr ();
		      return idx->entry;
		    }
		}

	      if (idx > map.begin ())
		{
		  idx = idx - 1;
		  if (start)
		    *start = idx->addr + sec->addr ();
		  return idx->entry;
		}
	    }
	}
    }

  return NULL;
}

/* Given the current frame THIS_FRAME, and its associated frame unwinding
   instruction list from the ARM exception table entry ENTRY, allocate and
   return a prologue cache structure describing how to unwind this frame.

   Return NULL if the unwinding instruction list contains a "spare",
   "reserved" or "refuse to unwind" instruction as defined in section
   "9.3 Frame unwinding instructions" of the "Exception Handling ABI
   for the ARM Architecture" document.  */

static struct arm_prologue_cache *
arm_exidx_fill_cache (struct frame_info *this_frame, gdb_byte *entry)
{
  CORE_ADDR vsp = 0;
  int vsp_valid = 0;

  struct arm_prologue_cache *cache;
  cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  for (;;)
    {
      gdb_byte insn;

      /* Whenever we reload SP, we actually have to retrieve its
	 actual value in the current frame.  */
      if (!vsp_valid)
	{
	  if (cache->saved_regs[ARM_SP_REGNUM].is_realreg ())
	    {
	      int reg = cache->saved_regs[ARM_SP_REGNUM].realreg ();
	      vsp = get_frame_register_unsigned (this_frame, reg);
	    }
	  else
	    {
	      CORE_ADDR addr = cache->saved_regs[ARM_SP_REGNUM].addr ();
	      vsp = get_frame_memory_unsigned (this_frame, addr, 4);
	    }

	  vsp_valid = 1;
	}

      /* Decode next unwind instruction.  */
      insn = *entry++;

      if ((insn & 0xc0) == 0)
	{
	  int offset = insn & 0x3f;
	  vsp += (offset << 2) + 4;
	}
      else if ((insn & 0xc0) == 0x40)
	{
	  int offset = insn & 0x3f;
	  vsp -= (offset << 2) + 4;
	}
      else if ((insn & 0xf0) == 0x80)
	{
	  int mask = ((insn & 0xf) << 8) | *entry++;
	  int i;

	  /* The special case of an all-zero mask identifies
	     "Refuse to unwind".  We return NULL to fall back
	     to the prologue analyzer.  */
	  if (mask == 0)
	    return NULL;

	  /* Pop registers r4..r15 under mask.  */
	  for (i = 0; i < 12; i++)
	    if (mask & (1 << i))
	      {
		cache->saved_regs[4 + i].set_addr (vsp);
		vsp += 4;
	      }

	  /* Special-case popping SP -- we need to reload vsp.  */
	  if (mask & (1 << (ARM_SP_REGNUM - 4)))
	    vsp_valid = 0;
	}
      else if ((insn & 0xf0) == 0x90)
	{
	  int reg = insn & 0xf;

	  /* Reserved cases.  */
	  if (reg == ARM_SP_REGNUM || reg == ARM_PC_REGNUM)
	    return NULL;

	  /* Set SP from another register and mark VSP for reload.  */
	  cache->saved_regs[ARM_SP_REGNUM] = cache->saved_regs[reg];
	  vsp_valid = 0;
	}
      else if ((insn & 0xf0) == 0xa0)
	{
	  int count = insn & 0x7;
	  int pop_lr = (insn & 0x8) != 0;
	  int i;

	  /* Pop r4..r[4+count].  */
	  for (i = 0; i <= count; i++)
	    {
	      cache->saved_regs[4 + i].set_addr (vsp);
	      vsp += 4;
	    }

	  /* If indicated by flag, pop LR as well.  */
	  if (pop_lr)
	    {
	      cache->saved_regs[ARM_LR_REGNUM].set_addr (vsp);
	      vsp += 4;
	    }
	}
      else if (insn == 0xb0)
	{
	  /* We could only have updated PC by popping into it; if so, it
	     will show up as address.  Otherwise, copy LR into PC.  */
	  if (!cache->saved_regs[ARM_PC_REGNUM].is_addr ())
	    cache->saved_regs[ARM_PC_REGNUM]
	      = cache->saved_regs[ARM_LR_REGNUM];

	  /* We're done.  */
	  break;
	}
      else if (insn == 0xb1)
	{
	  int mask = *entry++;
	  int i;

	  /* All-zero mask and mask >= 16 is "spare".  */
	  if (mask == 0 || mask >= 16)
	    return NULL;

	  /* Pop r0..r3 under mask.  */
	  for (i = 0; i < 4; i++)
	    if (mask & (1 << i))
	      {
		cache->saved_regs[i].set_addr (vsp);
		vsp += 4;
	      }
	}
      else if (insn == 0xb2)
	{
	  ULONGEST offset = 0;
	  unsigned shift = 0;

	  do
	    {
	      offset |= (*entry & 0x7f) << shift;
	      shift += 7;
	    }
	  while (*entry++ & 0x80);

	  vsp += 0x204 + (offset << 2);
	}
      else if (insn == 0xb3)
	{
	  int start = *entry >> 4;
	  int count = (*entry++) & 0xf;
	  int i;

	  /* Only registers D0..D15 are valid here.  */
	  if (start + count >= 16)
	    return NULL;

	  /* Pop VFP double-precision registers D[start]..D[start+count].  */
	  for (i = 0; i <= count; i++)
	    {
	      cache->saved_regs[ARM_D0_REGNUM + start + i].set_addr (vsp);
	      vsp += 8;
	    }

	  /* Add an extra 4 bytes for FSTMFDX-style stack.  */
	  vsp += 4;
	}
      else if ((insn & 0xf8) == 0xb8)
	{
	  int count = insn & 0x7;
	  int i;

	  /* Pop VFP double-precision registers D[8]..D[8+count].  */
	  for (i = 0; i <= count; i++)
	    {
	      cache->saved_regs[ARM_D0_REGNUM + 8 + i].set_addr (vsp);
	      vsp += 8;
	    }

	  /* Add an extra 4 bytes for FSTMFDX-style stack.  */
	  vsp += 4;
	}
      else if (insn == 0xc6)
	{
	  int start = *entry >> 4;
	  int count = (*entry++) & 0xf;
	  int i;

	  /* Only registers WR0..WR15 are valid.  */
	  if (start + count >= 16)
	    return NULL;

	  /* Pop iwmmx registers WR[start]..WR[start+count].  */
	  for (i = 0; i <= count; i++)
	    {
	      cache->saved_regs[ARM_WR0_REGNUM + start + i].set_addr (vsp);
	      vsp += 8;
	    }
	}
      else if (insn == 0xc7)
	{
	  int mask = *entry++;
	  int i;

	  /* All-zero mask and mask >= 16 is "spare".  */
	  if (mask == 0 || mask >= 16)
	    return NULL;

	  /* Pop iwmmx general-purpose registers WCGR0..WCGR3 under mask.  */
	  for (i = 0; i < 4; i++)
	    if (mask & (1 << i))
	      {
		cache->saved_regs[ARM_WCGR0_REGNUM + i].set_addr (vsp);
		vsp += 4;
	      }
	}
      else if ((insn & 0xf8) == 0xc0)
	{
	  int count = insn & 0x7;
	  int i;

	  /* Pop iwmmx registers WR[10]..WR[10+count].  */
	  for (i = 0; i <= count; i++)
	    {
	      cache->saved_regs[ARM_WR0_REGNUM + 10 + i].set_addr (vsp);
	      vsp += 8;
	    }
	}
      else if (insn == 0xc8)
	{
	  int start = *entry >> 4;
	  int count = (*entry++) & 0xf;
	  int i;

	  /* Only registers D0..D31 are valid.  */
	  if (start + count >= 16)
	    return NULL;

	  /* Pop VFP double-precision registers
	     D[16+start]..D[16+start+count].  */
	  for (i = 0; i <= count; i++)
	    {
	      cache->saved_regs[ARM_D0_REGNUM + 16 + start + i].set_addr (vsp);
	      vsp += 8;
	    }
	}
      else if (insn == 0xc9)
	{
	  int start = *entry >> 4;
	  int count = (*entry++) & 0xf;
	  int i;

	  /* Pop VFP double-precision registers D[start]..D[start+count].  */
	  for (i = 0; i <= count; i++)
	    {
	      cache->saved_regs[ARM_D0_REGNUM + start + i].set_addr (vsp);
	      vsp += 8;
	    }
	}
      else if ((insn & 0xf8) == 0xd0)
	{
	  int count = insn & 0x7;
	  int i;

	  /* Pop VFP double-precision registers D[8]..D[8+count].  */
	  for (i = 0; i <= count; i++)
	    {
	      cache->saved_regs[ARM_D0_REGNUM + 8 + i].set_addr (vsp);
	      vsp += 8;
	    }
	}
      else
	{
	  /* Everything else is "spare".  */
	  return NULL;
	}
    }

  /* If we restore SP from a register, assume this was the frame register.
     Otherwise just fall back to SP as frame register.  */
  if (cache->saved_regs[ARM_SP_REGNUM].is_realreg ())
    cache->framereg = cache->saved_regs[ARM_SP_REGNUM].realreg ();
  else
    cache->framereg = ARM_SP_REGNUM;

  /* Determine offset to previous frame.  */
  cache->framesize
    = vsp - get_frame_register_unsigned (this_frame, cache->framereg);

  /* We already got the previous SP.  */
  cache->prev_sp = vsp;

  return cache;
}

/* Unwinding via ARM exception table entries.  Note that the sniffer
   already computes a filled-in prologue cache, which is then used
   with the same arm_prologue_this_id and arm_prologue_prev_register
   routines also used for prologue-parsing based unwinding.  */

static int
arm_exidx_unwind_sniffer (const struct frame_unwind *self,
			  struct frame_info *this_frame,
			  void **this_prologue_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  CORE_ADDR addr_in_block, exidx_region, func_start;
  struct arm_prologue_cache *cache;
  gdb_byte *entry;

  /* See if we have an ARM exception table entry covering this address.  */
  addr_in_block = get_frame_address_in_block (this_frame);
  entry = arm_find_exidx_entry (addr_in_block, &exidx_region);
  if (!entry)
    return 0;

  /* The ARM exception table does not describe unwind information
     for arbitrary PC values, but is guaranteed to be correct only
     at call sites.  We have to decide here whether we want to use
     ARM exception table information for this frame, or fall back
     to using prologue parsing.  (Note that if we have DWARF CFI,
     this sniffer isn't even called -- CFI is always preferred.)

     Before we make this decision, however, we check whether we
     actually have *symbol* information for the current frame.
     If not, prologue parsing would not work anyway, so we might
     as well use the exception table and hope for the best.  */
  if (find_pc_partial_function (addr_in_block, NULL, &func_start, NULL))
    {
      int exc_valid = 0;

      /* If the next frame is "normal", we are at a call site in this
	 frame, so exception information is guaranteed to be valid.  */
      if (get_next_frame (this_frame)
	  && get_frame_type (get_next_frame (this_frame)) == NORMAL_FRAME)
	exc_valid = 1;

      /* We also assume exception information is valid if we're currently
	 blocked in a system call.  The system library is supposed to
	 ensure this, so that e.g. pthread cancellation works.  */
      if (arm_frame_is_thumb (this_frame))
	{
	  ULONGEST insn;

	  if (safe_read_memory_unsigned_integer (get_frame_pc (this_frame) - 2,
						 2, byte_order_for_code, &insn)
	      && (insn & 0xff00) == 0xdf00 /* svc */)
	    exc_valid = 1;
	}
      else
	{
	  ULONGEST insn;

	  if (safe_read_memory_unsigned_integer (get_frame_pc (this_frame) - 4,
						 4, byte_order_for_code, &insn)
	      && (insn & 0x0f000000) == 0x0f000000 /* svc */)
	    exc_valid = 1;
	}
	
      /* Bail out if we don't know that exception information is valid.  */
      if (!exc_valid)
	return 0;

     /* The ARM exception index does not mark the *end* of the region
	covered by the entry, and some functions will not have any entry.
	To correctly recognize the end of the covered region, the linker
	should have inserted dummy records with a CANTUNWIND marker.

	Unfortunately, current versions of GNU ld do not reliably do
	this, and thus we may have found an incorrect entry above.
	As a (temporary) sanity check, we only use the entry if it
	lies *within* the bounds of the function.  Note that this check
	might reject perfectly valid entries that just happen to cover
	multiple functions; therefore this check ought to be removed
	once the linker is fixed.  */
      if (func_start > exidx_region)
	return 0;
    }

  /* Decode the list of unwinding instructions into a prologue cache.
     Note that this may fail due to e.g. a "refuse to unwind" code.  */
  cache = arm_exidx_fill_cache (this_frame, entry);
  if (!cache)
    return 0;

  *this_prologue_cache = cache;
  return 1;
}

struct frame_unwind arm_exidx_unwind = {
  "arm exidx",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  arm_prologue_this_id,
  arm_prologue_prev_register,
  NULL,
  arm_exidx_unwind_sniffer
};

static struct arm_prologue_cache *
arm_make_epilogue_frame_cache (struct frame_info *this_frame)
{
  struct arm_prologue_cache *cache;
  int reg;

  cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  /* Still rely on the offset calculated from prologue.  */
  arm_scan_prologue (this_frame, cache);

  /* Since we are in epilogue, the SP has been restored.  */
  cache->prev_sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);

  /* Calculate actual addresses of saved registers using offsets
     determined by arm_scan_prologue.  */
  for (reg = 0; reg < gdbarch_num_regs (get_frame_arch (this_frame)); reg++)
    if (cache->saved_regs[reg].is_addr ())
      cache->saved_regs[reg].set_addr (cache->saved_regs[reg].addr ()
				       + cache->prev_sp);

  return cache;
}

/* Implementation of function hook 'this_id' in
   'struct frame_uwnind' for epilogue unwinder.  */

static void
arm_epilogue_frame_this_id (struct frame_info *this_frame,
			    void **this_cache,
			    struct frame_id *this_id)
{
  struct arm_prologue_cache *cache;
  CORE_ADDR pc, func;

  if (*this_cache == NULL)
    *this_cache = arm_make_epilogue_frame_cache (this_frame);
  cache = (struct arm_prologue_cache *) *this_cache;

  /* Use function start address as part of the frame ID.  If we cannot
     identify the start address (due to missing symbol information),
     fall back to just using the current PC.  */
  pc = get_frame_pc (this_frame);
  func = get_frame_func (this_frame);
  if (func == 0)
    func = pc;

  (*this_id) = frame_id_build (cache->prev_sp, pc);
}

/* Implementation of function hook 'prev_register' in
   'struct frame_uwnind' for epilogue unwinder.  */

static struct value *
arm_epilogue_frame_prev_register (struct frame_info *this_frame,
				  void **this_cache, int regnum)
{
  if (*this_cache == NULL)
    *this_cache = arm_make_epilogue_frame_cache (this_frame);

  return arm_prologue_prev_register (this_frame, this_cache, regnum);
}

static int arm_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch,
					  CORE_ADDR pc);
static int thumb_stack_frame_destroyed_p (struct gdbarch *gdbarch,
					  CORE_ADDR pc);

/* Implementation of function hook 'sniffer' in
   'struct frame_uwnind' for epilogue unwinder.  */

static int
arm_epilogue_frame_sniffer (const struct frame_unwind *self,
			    struct frame_info *this_frame,
			    void **this_prologue_cache)
{
  if (frame_relative_level (this_frame) == 0)
    {
      struct gdbarch *gdbarch = get_frame_arch (this_frame);
      CORE_ADDR pc = get_frame_pc (this_frame);

      if (arm_frame_is_thumb (this_frame))
	return thumb_stack_frame_destroyed_p (gdbarch, pc);
      else
	return arm_stack_frame_destroyed_p_1 (gdbarch, pc);
    }
  else
    return 0;
}

/* Frame unwinder from epilogue.  */

static const struct frame_unwind arm_epilogue_frame_unwind =
{
  "arm epilogue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  arm_epilogue_frame_this_id,
  arm_epilogue_frame_prev_register,
  NULL,
  arm_epilogue_frame_sniffer,
};

/* Recognize GCC's trampoline for thumb call-indirect.  If we are in a
   trampoline, return the target PC.  Otherwise return 0.

   void call0a (char c, short s, int i, long l) {}

   int main (void)
   {
     (*pointer_to_call0a) (c, s, i, l);
   }

   Instead of calling a stub library function  _call_via_xx (xx is
   the register name), GCC may inline the trampoline in the object
   file as below (register r2 has the address of call0a).

   .global main
   .type main, %function
   ...
   bl .L1
   ...
   .size main, .-main

   .L1:
   bx r2

   The trampoline 'bx r2' doesn't belong to main.  */

static CORE_ADDR
arm_skip_bx_reg (struct frame_info *frame, CORE_ADDR pc)
{
  /* The heuristics of recognizing such trampoline is that FRAME is
     executing in Thumb mode and the instruction on PC is 'bx Rm'.  */
  if (arm_frame_is_thumb (frame))
    {
      gdb_byte buf[2];

      if (target_read_memory (pc, buf, 2) == 0)
	{
	  struct gdbarch *gdbarch = get_frame_arch (frame);
	  enum bfd_endian byte_order_for_code
	    = gdbarch_byte_order_for_code (gdbarch);
	  uint16_t insn
	    = extract_unsigned_integer (buf, 2, byte_order_for_code);

	  if ((insn & 0xff80) == 0x4700)  /* bx <Rm> */
	    {
	      CORE_ADDR dest
		= get_frame_register_unsigned (frame, bits (insn, 3, 6));

	      /* Clear the LSB so that gdb core sets step-resume
		 breakpoint at the right address.  */
	      return UNMAKE_THUMB_ADDR (dest);
	    }
	}
    }

  return 0;
}

static struct arm_prologue_cache *
arm_make_stub_cache (struct frame_info *this_frame)
{
  struct arm_prologue_cache *cache;

  cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  cache->prev_sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);

  return cache;
}

/* Our frame ID for a stub frame is the current SP and LR.  */

static void
arm_stub_this_id (struct frame_info *this_frame,
		  void **this_cache,
		  struct frame_id *this_id)
{
  struct arm_prologue_cache *cache;

  if (*this_cache == NULL)
    *this_cache = arm_make_stub_cache (this_frame);
  cache = (struct arm_prologue_cache *) *this_cache;

  *this_id = frame_id_build (cache->prev_sp, get_frame_pc (this_frame));
}

static int
arm_stub_unwind_sniffer (const struct frame_unwind *self,
			 struct frame_info *this_frame,
			 void **this_prologue_cache)
{
  CORE_ADDR addr_in_block;
  gdb_byte dummy[4];
  CORE_ADDR pc, start_addr;
  const char *name;

  addr_in_block = get_frame_address_in_block (this_frame);
  pc = get_frame_pc (this_frame);
  if (in_plt_section (addr_in_block)
      /* We also use the stub winder if the target memory is unreadable
	 to avoid having the prologue unwinder trying to read it.  */
      || target_read_memory (pc, dummy, 4) != 0)
    return 1;

  if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0
      && arm_skip_bx_reg (this_frame, pc) != 0)
    return 1;

  return 0;
}

struct frame_unwind arm_stub_unwind = {
  "arm stub",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  arm_stub_this_id,
  arm_prologue_prev_register,
  NULL,
  arm_stub_unwind_sniffer
};

/* Put here the code to store, into CACHE->saved_regs, the addresses
   of the saved registers of frame described by THIS_FRAME.  CACHE is
   returned.  */

static struct arm_prologue_cache *
arm_m_exception_cache (struct frame_info *this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct arm_prologue_cache *cache;
  CORE_ADDR lr;
  CORE_ADDR sp;
  CORE_ADDR unwound_sp;
  LONGEST xpsr;
  uint32_t exc_return;
  uint32_t process_stack_used;
  uint32_t extended_frame_used;
  uint32_t secure_stack_used;

  cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  /* ARMv7-M Architecture Reference "B1.5.6 Exception entry behavior"
     describes which bits in LR that define which stack was used prior
     to the exception and if FPU is used (causing extended stack frame).  */

  lr = get_frame_register_unsigned (this_frame, ARM_LR_REGNUM);
  sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);

  /* Check EXC_RETURN indicator bits.  */
  exc_return = (((lr >> 28) & 0xf) == 0xf);

  /* Check EXC_RETURN bit SPSEL if Main or Thread (process) stack used.  */
  process_stack_used = ((lr & (1 << 2)) != 0);
  if (exc_return && process_stack_used)
    {
      /* Thread (process) stack used.
	 Potentially this could be other register defined by target, but PSP
	 can be considered a standard name for the "Process Stack Pointer".
	 To be fully aware of system registers like MSP and PSP, these could
	 be added to a separate XML arm-m-system-profile that is valid for
	 ARMv6-M and ARMv7-M architectures. Also to be able to debug eg a
	 corefile off-line, then these registers must be defined by GDB,
	 and also be included in the corefile regsets.  */

      int psp_regnum = user_reg_map_name_to_regnum (gdbarch, "psp", -1);
      if (psp_regnum == -1)
	{
	  /* Thread (process) stack could not be fetched,
	     give warning and exit.  */

	  warning (_("no PSP thread stack unwinding supported."));

	  /* Terminate any further stack unwinding by refer to self.  */
	  cache->prev_sp = sp;
	  return cache;
	}
      else
	{
	  /* Thread (process) stack used, use PSP as SP.  */
	  unwound_sp = get_frame_register_unsigned (this_frame, psp_regnum);
	}
    }
  else
    {
      /* Main stack used, use MSP as SP.  */
      unwound_sp = sp;
    }

  /* The hardware saves eight 32-bit words, comprising xPSR,
     ReturnAddress, LR (R14), R12, R3, R2, R1, R0.  See details in
     "B1.5.6 Exception entry behavior" in
     "ARMv7-M Architecture Reference Manual".  */
  cache->saved_regs[0].set_addr (unwound_sp);
  cache->saved_regs[1].set_addr (unwound_sp + 4);
  cache->saved_regs[2].set_addr (unwound_sp + 8);
  cache->saved_regs[3].set_addr (unwound_sp + 12);
  cache->saved_regs[ARM_IP_REGNUM].set_addr (unwound_sp + 16);
  cache->saved_regs[ARM_LR_REGNUM].set_addr (unwound_sp + 20);
  cache->saved_regs[ARM_PC_REGNUM].set_addr (unwound_sp + 24);
  cache->saved_regs[ARM_PS_REGNUM].set_addr (unwound_sp + 28);

  /* Check EXC_RETURN bit FTYPE if extended stack frame (FPU regs stored)
     type used.  */
  extended_frame_used = ((lr & (1 << 4)) == 0);
  if (exc_return && extended_frame_used)
    {
      int i;
      int fpu_regs_stack_offset;

      /* This code does not take into account the lazy stacking, see "Lazy
	 context save of FP state", in B1.5.7, also ARM AN298, supported
	 by Cortex-M4F architecture.
	 To fully handle this the FPCCR register (Floating-point Context
	 Control Register) needs to be read out and the bits ASPEN and LSPEN
	 could be checked to setup correct lazy stacked FP registers.
	 This register is located at address 0xE000EF34.  */

      /* Extended stack frame type used.  */
      fpu_regs_stack_offset = unwound_sp + 0x20;
      for (i = 0; i < 16; i++)
	{
	  cache->saved_regs[ARM_D0_REGNUM + i].set_addr (fpu_regs_stack_offset);
	  fpu_regs_stack_offset += 4;
	}
      cache->saved_regs[ARM_FPSCR_REGNUM].set_addr (unwound_sp + 0x60);

      /* Offset 0x64 is reserved.  */
      cache->prev_sp = unwound_sp + 0x68;
    }
  else
    {
      /* Standard stack frame type used.  */
      cache->prev_sp = unwound_sp + 0x20;
    }

  /* Check EXC_RETURN bit S if Secure or Non-secure stack used.  */
  secure_stack_used = ((lr & (1 << 6)) != 0);
  if (exc_return && secure_stack_used)
    {
      /* ARMv8-M Exception and interrupt handling is not considered here.
	 In the ARMv8-M architecture also EXC_RETURN bit S is controlling if
	 the Secure or Non-secure stack was used. To separate Secure and
	 Non-secure stacks, processors that are based on the ARMv8-M
	 architecture support 4 stack pointers: MSP_S, PSP_S, MSP_NS, PSP_NS.
	 In addition, a stack limit feature is provided using stack limit
	 registers (accessible using MSR and MRS instructions) in Privileged
	 level.  */
    }

  /* If bit 9 of the saved xPSR is set, then there is a four-byte
     aligner between the top of the 32-byte stack frame and the
     previous context's stack pointer.  */
  if (safe_read_memory_integer (unwound_sp + 28, 4, byte_order, &xpsr)
      && (xpsr & (1 << 9)) != 0)
    cache->prev_sp += 4;

  return cache;
}

/* Implementation of function hook 'this_id' in
   'struct frame_uwnind'.  */

static void
arm_m_exception_this_id (struct frame_info *this_frame,
			 void **this_cache,
			 struct frame_id *this_id)
{
  struct arm_prologue_cache *cache;

  if (*this_cache == NULL)
    *this_cache = arm_m_exception_cache (this_frame);
  cache = (struct arm_prologue_cache *) *this_cache;

  /* Our frame ID for a stub frame is the current SP and LR.  */
  *this_id = frame_id_build (cache->prev_sp,
			     get_frame_pc (this_frame));
}

/* Implementation of function hook 'prev_register' in
   'struct frame_uwnind'.  */

static struct value *
arm_m_exception_prev_register (struct frame_info *this_frame,
			       void **this_cache,
			       int prev_regnum)
{
  struct arm_prologue_cache *cache;

  if (*this_cache == NULL)
    *this_cache = arm_m_exception_cache (this_frame);
  cache = (struct arm_prologue_cache *) *this_cache;

  /* The value was already reconstructed into PREV_SP.  */
  if (prev_regnum == ARM_SP_REGNUM)
    return frame_unwind_got_constant (this_frame, prev_regnum,
				      cache->prev_sp);

  return trad_frame_get_prev_register (this_frame, cache->saved_regs,
				       prev_regnum);
}

/* Implementation of function hook 'sniffer' in
   'struct frame_uwnind'.  */

static int
arm_m_exception_unwind_sniffer (const struct frame_unwind *self,
				struct frame_info *this_frame,
				void **this_prologue_cache)
{
  CORE_ADDR this_pc = get_frame_pc (this_frame);

  /* No need to check is_m; this sniffer is only registered for
     M-profile architectures.  */

  /* Check if exception frame returns to a magic PC value.  */
  return arm_m_addr_is_magic (this_pc);
}

/* Frame unwinder for M-profile exceptions.  */

struct frame_unwind arm_m_exception_unwind =
{
  "arm m exception",
  SIGTRAMP_FRAME,
  default_frame_unwind_stop_reason,
  arm_m_exception_this_id,
  arm_m_exception_prev_register,
  NULL,
  arm_m_exception_unwind_sniffer
};

static CORE_ADDR
arm_normal_frame_base (struct frame_info *this_frame, void **this_cache)
{
  struct arm_prologue_cache *cache;

  if (*this_cache == NULL)
    *this_cache = arm_make_prologue_cache (this_frame);
  cache = (struct arm_prologue_cache *) *this_cache;

  return cache->prev_sp - cache->framesize;
}

struct frame_base arm_normal_base = {
  &arm_prologue_unwind,
  arm_normal_frame_base,
  arm_normal_frame_base,
  arm_normal_frame_base
};

static struct value *
arm_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache,
			  int regnum)
{
  struct gdbarch * gdbarch = get_frame_arch (this_frame);
  CORE_ADDR lr, cpsr;
  ULONGEST t_bit = arm_psr_thumb_bit (gdbarch);

  switch (regnum)
    {
    case ARM_PC_REGNUM:
      /* The PC is normally copied from the return column, which
	 describes saves of LR.  However, that version may have an
	 extra bit set to indicate Thumb state.  The bit is not
	 part of the PC.  */
      lr = frame_unwind_register_unsigned (this_frame, ARM_LR_REGNUM);
      return frame_unwind_got_constant (this_frame, regnum,
					arm_addr_bits_remove (gdbarch, lr));

    case ARM_PS_REGNUM:
      /* Reconstruct the T bit; see arm_prologue_prev_register for details.  */
      cpsr = get_frame_register_unsigned (this_frame, regnum);
      lr = frame_unwind_register_unsigned (this_frame, ARM_LR_REGNUM);
      if (IS_THUMB_ADDR (lr))
	cpsr |= t_bit;
      else
	cpsr &= ~t_bit;
      return frame_unwind_got_constant (this_frame, regnum, cpsr);

    default:
      internal_error (__FILE__, __LINE__,
		      _("Unexpected register %d"), regnum);
    }
}

static void
arm_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
			   struct dwarf2_frame_state_reg *reg,
			   struct frame_info *this_frame)
{
  switch (regnum)
    {
    case ARM_PC_REGNUM:
    case ARM_PS_REGNUM:
      reg->how = DWARF2_FRAME_REG_FN;
      reg->loc.fn = arm_dwarf2_prev_register;
      break;
    case ARM_SP_REGNUM:
      reg->how = DWARF2_FRAME_REG_CFA;
      break;
    }
}

/* Implement the stack_frame_destroyed_p gdbarch method.  */

static int
thumb_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  unsigned int insn, insn2;
  int found_return = 0, found_stack_adjust = 0;
  CORE_ADDR func_start, func_end;
  CORE_ADDR scan_pc;
  gdb_byte buf[4];

  if (!find_pc_partial_function (pc, NULL, &func_start, &func_end))
    return 0;

  /* The epilogue is a sequence of instructions along the following lines:

    - add stack frame size to SP or FP
    - [if frame pointer used] restore SP from FP
    - restore registers from SP [may include PC]
    - a return-type instruction [if PC wasn't already restored]

    In a first pass, we scan forward from the current PC and verify the
    instructions we find as compatible with this sequence, ending in a
    return instruction.

    However, this is not sufficient to distinguish indirect function calls
    within a function from indirect tail calls in the epilogue in some cases.
    Therefore, if we didn't already find any SP-changing instruction during
    forward scan, we add a backward scanning heuristic to ensure we actually
    are in the epilogue.  */

  scan_pc = pc;
  while (scan_pc < func_end && !found_return)
    {
      if (target_read_memory (scan_pc, buf, 2))
	break;

      scan_pc += 2;
      insn = extract_unsigned_integer (buf, 2, byte_order_for_code);

      if ((insn & 0xff80) == 0x4700)  /* bx <Rm> */
	found_return = 1;
      else if (insn == 0x46f7)  /* mov pc, lr */
	found_return = 1;
      else if (thumb_instruction_restores_sp (insn))
	{
	  if ((insn & 0xff00) == 0xbd00)  /* pop <registers, PC> */
	    found_return = 1;
	}
      else if (thumb_insn_size (insn) == 4)  /* 32-bit Thumb-2 instruction */
	{
	  if (target_read_memory (scan_pc, buf, 2))
	    break;

	  scan_pc += 2;
	  insn2 = extract_unsigned_integer (buf, 2, byte_order_for_code);

	  if (insn == 0xe8bd)  /* ldm.w sp!, <registers> */
	    {
	      if (insn2 & 0x8000)  /* <registers> include PC.  */
		found_return = 1;
	    }
	  else if (insn == 0xf85d  /* ldr.w <Rt>, [sp], #4 */
		   && (insn2 & 0x0fff) == 0x0b04)
	    {
	      if ((insn2 & 0xf000) == 0xf000) /* <Rt> is PC.  */
		found_return = 1;
	    }
	  else if ((insn & 0xffbf) == 0xecbd  /* vldm sp!, <list> */
		   && (insn2 & 0x0e00) == 0x0a00)
	    ;
	  else
	    break;
	}
      else
	break;
    }

  if (!found_return)
    return 0;

  /* Since any instruction in the epilogue sequence, with the possible
     exception of return itself, updates the stack pointer, we need to
     scan backwards for at most one instruction.  Try either a 16-bit or
     a 32-bit instruction.  This is just a heuristic, so we do not worry
     too much about false positives.  */

  if (pc - 4 < func_start)
    return 0;
  if (target_read_memory (pc - 4, buf, 4))
    return 0;

  insn = extract_unsigned_integer (buf, 2, byte_order_for_code);
  insn2 = extract_unsigned_integer (buf + 2, 2, byte_order_for_code);

  if (thumb_instruction_restores_sp (insn2))
    found_stack_adjust = 1;
  else if (insn == 0xe8bd)  /* ldm.w sp!, <registers> */
    found_stack_adjust = 1;
  else if (insn == 0xf85d  /* ldr.w <Rt>, [sp], #4 */
	   && (insn2 & 0x0fff) == 0x0b04)
    found_stack_adjust = 1;
  else if ((insn & 0xffbf) == 0xecbd  /* vldm sp!, <list> */
	   && (insn2 & 0x0e00) == 0x0a00)
    found_stack_adjust = 1;

  return found_stack_adjust;
}

static int
arm_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  unsigned int insn;
  int found_return;
  CORE_ADDR func_start, func_end;

  if (!find_pc_partial_function (pc, NULL, &func_start, &func_end))
    return 0;

  /* We are in the epilogue if the previous instruction was a stack
     adjustment and the next instruction is a possible return (bx, mov
     pc, or pop).  We could have to scan backwards to find the stack
     adjustment, or forwards to find the return, but this is a decent
     approximation.  First scan forwards.  */

  found_return = 0;
  insn = read_memory_unsigned_integer (pc, 4, byte_order_for_code);
  if (bits (insn, 28, 31) != INST_NV)
    {
      if ((insn & 0x0ffffff0) == 0x012fff10)
	/* BX.  */
	found_return = 1;
      else if ((insn & 0x0ffffff0) == 0x01a0f000)
	/* MOV PC.  */
	found_return = 1;
      else if ((insn & 0x0fff0000) == 0x08bd0000
	  && (insn & 0x0000c000) != 0)
	/* POP (LDMIA), including PC or LR.  */
	found_return = 1;
    }

  if (!found_return)
    return 0;

  /* Scan backwards.  This is just a heuristic, so do not worry about
     false positives from mode changes.  */

  if (pc < func_start + 4)
    return 0;

  insn = read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code);
  if (arm_instruction_restores_sp (insn))
    return 1;

  return 0;
}

/* Implement the stack_frame_destroyed_p gdbarch method.  */

static int
arm_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  if (arm_pc_is_thumb (gdbarch, pc))
    return thumb_stack_frame_destroyed_p (gdbarch, pc);
  else
    return arm_stack_frame_destroyed_p_1 (gdbarch, pc);
}

/* When arguments must be pushed onto the stack, they go on in reverse
   order.  The code below implements a FILO (stack) to do this.  */

struct stack_item
{
  int len;
  struct stack_item *prev;
  gdb_byte *data;
};

static struct stack_item *
push_stack_item (struct stack_item *prev, const gdb_byte *contents, int len)
{
  struct stack_item *si;
  si = XNEW (struct stack_item);
  si->data = (gdb_byte *) xmalloc (len);
  si->len = len;
  si->prev = prev;
  memcpy (si->data, contents, len);
  return si;
}

static struct stack_item *
pop_stack_item (struct stack_item *si)
{
  struct stack_item *dead = si;
  si = si->prev;
  xfree (dead->data);
  xfree (dead);
  return si;
}

/* Implement the gdbarch type alignment method, overrides the generic
   alignment algorithm for anything that is arm specific.  */

static ULONGEST
arm_type_align (gdbarch *gdbarch, struct type *t)
{
  t = check_typedef (t);
  if (t->code () == TYPE_CODE_ARRAY && t->is_vector ())
    {
      /* Use the natural alignment for vector types (the same for
	 scalar type), but the maximum alignment is 64-bit.  */
      if (TYPE_LENGTH (t) > 8)
	return 8;
      else
	return TYPE_LENGTH (t);
    }

  /* Allow the common code to calculate the alignment.  */
  return 0;
}

/* Possible base types for a candidate for passing and returning in
   VFP registers.  */

enum arm_vfp_cprc_base_type
{
  VFP_CPRC_UNKNOWN,
  VFP_CPRC_SINGLE,
  VFP_CPRC_DOUBLE,
  VFP_CPRC_VEC64,
  VFP_CPRC_VEC128
};

/* The length of one element of base type B.  */

static unsigned
arm_vfp_cprc_unit_length (enum arm_vfp_cprc_base_type b)
{
  switch (b)
    {
    case VFP_CPRC_SINGLE:
      return 4;
    case VFP_CPRC_DOUBLE:
      return 8;
    case VFP_CPRC_VEC64:
      return 8;
    case VFP_CPRC_VEC128:
      return 16;
    default:
      internal_error (__FILE__, __LINE__, _("Invalid VFP CPRC type: %d."),
		      (int) b);
    }
}

/* The character ('s', 'd' or 'q') for the type of VFP register used
   for passing base type B.  */

static int
arm_vfp_cprc_reg_char (enum arm_vfp_cprc_base_type b)
{
  switch (b)
    {
    case VFP_CPRC_SINGLE:
      return 's';
    case VFP_CPRC_DOUBLE:
      return 'd';
    case VFP_CPRC_VEC64:
      return 'd';
    case VFP_CPRC_VEC128:
      return 'q';
    default:
      internal_error (__FILE__, __LINE__, _("Invalid VFP CPRC type: %d."),
		      (int) b);
    }
}

/* Determine whether T may be part of a candidate for passing and
   returning in VFP registers, ignoring the limit on the total number
   of components.  If *BASE_TYPE is VFP_CPRC_UNKNOWN, set it to the
   classification of the first valid component found; if it is not
   VFP_CPRC_UNKNOWN, all components must have the same classification
   as *BASE_TYPE.  If it is found that T contains a type not permitted
   for passing and returning in VFP registers, a type differently
   classified from *BASE_TYPE, or two types differently classified
   from each other, return -1, otherwise return the total number of
   base-type elements found (possibly 0 in an empty structure or
   array).  Vector types are not currently supported, matching the
   generic AAPCS support.  */

static int
arm_vfp_cprc_sub_candidate (struct type *t,
			    enum arm_vfp_cprc_base_type *base_type)
{
  t = check_typedef (t);
  switch (t->code ())
    {
    case TYPE_CODE_FLT:
      switch (TYPE_LENGTH (t))
	{
	case 4:
	  if (*base_type == VFP_CPRC_UNKNOWN)
	    *base_type = VFP_CPRC_SINGLE;
	  else if (*base_type != VFP_CPRC_SINGLE)
	    return -1;
	  return 1;

	case 8:
	  if (*base_type == VFP_CPRC_UNKNOWN)
	    *base_type = VFP_CPRC_DOUBLE;
	  else if (*base_type != VFP_CPRC_DOUBLE)
	    return -1;
	  return 1;

	default:
	  return -1;
	}
      break;

    case TYPE_CODE_COMPLEX:
      /* Arguments of complex T where T is one of the types float or
	 double get treated as if they are implemented as:

	 struct complexT
	 {
	   T real;
	   T imag;
	 };

      */
      switch (TYPE_LENGTH (t))
	{
	case 8:
	  if (*base_type == VFP_CPRC_UNKNOWN)
	    *base_type = VFP_CPRC_SINGLE;
	  else if (*base_type != VFP_CPRC_SINGLE)
	    return -1;
	  return 2;

	case 16:
	  if (*base_type == VFP_CPRC_UNKNOWN)
	    *base_type = VFP_CPRC_DOUBLE;
	  else if (*base_type != VFP_CPRC_DOUBLE)
	    return -1;
	  return 2;

	default:
	  return -1;
	}
      break;

    case TYPE_CODE_ARRAY:
      {
	if (t->is_vector ())
	  {
	    /* A 64-bit or 128-bit containerized vector type are VFP
	       CPRCs.  */
	    switch (TYPE_LENGTH (t))
	      {
	      case 8:
		if (*base_type == VFP_CPRC_UNKNOWN)
		  *base_type = VFP_CPRC_VEC64;
		return 1;
	      case 16:
		if (*base_type == VFP_CPRC_UNKNOWN)
		  *base_type = VFP_CPRC_VEC128;
		return 1;
	      default:
		return -1;
	      }
	  }
	else
	  {
	    int count;
	    unsigned unitlen;

	    count = arm_vfp_cprc_sub_candidate (TYPE_TARGET_TYPE (t),
						base_type);
	    if (count == -1)
	      return -1;
	    if (TYPE_LENGTH (t) == 0)
	      {
		gdb_assert (count == 0);
		return 0;
	      }
	    else if (count == 0)
	      return -1;
	    unitlen = arm_vfp_cprc_unit_length (*base_type);
	    gdb_assert ((TYPE_LENGTH (t) % unitlen) == 0);
	    return TYPE_LENGTH (t) / unitlen;
	  }
      }
      break;

    case TYPE_CODE_STRUCT:
      {
	int count = 0;
	unsigned unitlen;
	int i;
	for (i = 0; i < t->num_fields (); i++)
	  {
	    int sub_count = 0;

	    if (!field_is_static (&t->field (i)))
	      sub_count = arm_vfp_cprc_sub_candidate (t->field (i).type (),
						      base_type);
	    if (sub_count == -1)
	      return -1;
	    count += sub_count;
	  }
	if (TYPE_LENGTH (t) == 0)
	  {
	    gdb_assert (count == 0);
	    return 0;
	  }
	else if (count == 0)
	  return -1;
	unitlen = arm_vfp_cprc_unit_length (*base_type);
	if (TYPE_LENGTH (t) != unitlen * count)
	  return -1;
	return count;
      }

    case TYPE_CODE_UNION:
      {
	int count = 0;
	unsigned unitlen;
	int i;
	for (i = 0; i < t->num_fields (); i++)
	  {
	    int sub_count = arm_vfp_cprc_sub_candidate (t->field (i).type (),
							base_type);
	    if (sub_count == -1)
	      return -1;
	    count = (count > sub_count ? count : sub_count);
	  }
	if (TYPE_LENGTH (t) == 0)
	  {
	    gdb_assert (count == 0);
	    return 0;
	  }
	else if (count == 0)
	  return -1;
	unitlen = arm_vfp_cprc_unit_length (*base_type);
	if (TYPE_LENGTH (t) != unitlen * count)
	  return -1;
	return count;
      }

    default:
      break;
    }

  return -1;
}

/* Determine whether T is a VFP co-processor register candidate (CPRC)
   if passed to or returned from a non-variadic function with the VFP
   ABI in effect.  Return 1 if it is, 0 otherwise.  If it is, set
   *BASE_TYPE to the base type for T and *COUNT to the number of
   elements of that base type before returning.  */

static int
arm_vfp_call_candidate (struct type *t, enum arm_vfp_cprc_base_type *base_type,
			int *count)
{
  enum arm_vfp_cprc_base_type b = VFP_CPRC_UNKNOWN;
  int c = arm_vfp_cprc_sub_candidate (t, &b);
  if (c <= 0 || c > 4)
    return 0;
  *base_type = b;
  *count = c;
  return 1;
}

/* Return 1 if the VFP ABI should be used for passing arguments to and
   returning values from a function of type FUNC_TYPE, 0
   otherwise.  */

static int
arm_vfp_abi_for_function (struct gdbarch *gdbarch, struct type *func_type)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* Variadic functions always use the base ABI.  Assume that functions
     without debug info are not variadic.  */
  if (func_type && check_typedef (func_type)->has_varargs ())
    return 0;

  /* The VFP ABI is only supported as a variant of AAPCS.  */
  if (tdep->arm_abi != ARM_ABI_AAPCS)
    return 0;

  return tdep->fp_model == ARM_FLOAT_VFP;
}

/* We currently only support passing parameters in integer registers, which
   conforms with GCC's default model, and VFP argument passing following
   the VFP variant of AAPCS.  Several other variants exist and
   we should probably support some of them based on the selected ABI.  */

static CORE_ADDR
arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
		     struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
		     struct value **args, CORE_ADDR sp,
		     function_call_return_method return_method,
		     CORE_ADDR struct_addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int argnum;
  int argreg;
  int nstack;
  struct stack_item *si = NULL;
  int use_vfp_abi;
  struct type *ftype;
  unsigned vfp_regs_free = (1 << 16) - 1;
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* Determine the type of this function and whether the VFP ABI
     applies.  */
  ftype = check_typedef (value_type (function));
  if (ftype->code () == TYPE_CODE_PTR)
    ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
  use_vfp_abi = arm_vfp_abi_for_function (gdbarch, ftype);

  /* Set the return address.  For the ARM, the return breakpoint is
     always at BP_ADDR.  */
  if (arm_pc_is_thumb (gdbarch, bp_addr))
    bp_addr |= 1;
  regcache_cooked_write_unsigned (regcache, ARM_LR_REGNUM, bp_addr);

  /* Walk through the list of args and determine how large a temporary
     stack is required.  Need to take care here as structs may be
     passed on the stack, and we have to push them.  */
  nstack = 0;

  argreg = ARM_A1_REGNUM;
  nstack = 0;

  /* The struct_return pointer occupies the first parameter
     passing register.  */
  if (return_method == return_method_struct)
    {
      arm_debug_printf ("struct return in %s = %s",
			gdbarch_register_name (gdbarch, argreg),
			paddress (gdbarch, struct_addr));

      regcache_cooked_write_unsigned (regcache, argreg, struct_addr);
      argreg++;
    }

  for (argnum = 0; argnum < nargs; argnum++)
    {
      int len;
      struct type *arg_type;
      struct type *target_type;
      enum type_code typecode;
      const bfd_byte *val;
      int align;
      enum arm_vfp_cprc_base_type vfp_base_type;
      int vfp_base_count;
      int may_use_core_reg = 1;

      arg_type = check_typedef (value_type (args[argnum]));
      len = TYPE_LENGTH (arg_type);
      target_type = TYPE_TARGET_TYPE (arg_type);
      typecode = arg_type->code ();
      val = value_contents (args[argnum]).data ();

      align = type_align (arg_type);
      /* Round alignment up to a whole number of words.  */
      align = (align + ARM_INT_REGISTER_SIZE - 1)
		& ~(ARM_INT_REGISTER_SIZE - 1);
      /* Different ABIs have different maximum alignments.  */
      if (tdep->arm_abi == ARM_ABI_APCS)
	{
	  /* The APCS ABI only requires word alignment.  */
	  align = ARM_INT_REGISTER_SIZE;
	}
      else
	{
	  /* The AAPCS requires at most doubleword alignment.  */
	  if (align > ARM_INT_REGISTER_SIZE * 2)
	    align = ARM_INT_REGISTER_SIZE * 2;
	}

      if (use_vfp_abi
	  && arm_vfp_call_candidate (arg_type, &vfp_base_type,
				     &vfp_base_count))
	{
	  int regno;
	  int unit_length;
	  int shift;
	  unsigned mask;

	  /* Because this is a CPRC it cannot go in a core register or
	     cause a core register to be skipped for alignment.
	     Either it goes in VFP registers and the rest of this loop
	     iteration is skipped for this argument, or it goes on the
	     stack (and the stack alignment code is correct for this
	     case).  */
	  may_use_core_reg = 0;

	  unit_length = arm_vfp_cprc_unit_length (vfp_base_type);
	  shift = unit_length / 4;
	  mask = (1 << (shift * vfp_base_count)) - 1;
	  for (regno = 0; regno < 16; regno += shift)
	    if (((vfp_regs_free >> regno) & mask) == mask)
	      break;

	  if (regno < 16)
	    {
	      int reg_char;
	      int reg_scaled;
	      int i;

	      vfp_regs_free &= ~(mask << regno);
	      reg_scaled = regno / shift;
	      reg_char = arm_vfp_cprc_reg_char (vfp_base_type);
	      for (i = 0; i < vfp_base_count; i++)
		{
		  char name_buf[4];
		  int regnum;
		  if (reg_char == 'q')
		    arm_neon_quad_write (gdbarch, regcache, reg_scaled + i,
					 val + i * unit_length);
		  else
		    {
		      xsnprintf (name_buf, sizeof (name_buf), "%c%d",
				 reg_char, reg_scaled + i);
		      regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
							    strlen (name_buf));
		      regcache->cooked_write (regnum, val + i * unit_length);
		    }
		}
	      continue;
	    }
	  else
	    {
	      /* This CPRC could not go in VFP registers, so all VFP
		 registers are now marked as used.  */
	      vfp_regs_free = 0;
	    }
	}

      /* Push stack padding for doubleword alignment.  */
      if (nstack & (align - 1))
	{
	  si = push_stack_item (si, val, ARM_INT_REGISTER_SIZE);
	  nstack += ARM_INT_REGISTER_SIZE;
	}
      
      /* Doubleword aligned quantities must go in even register pairs.  */
      if (may_use_core_reg
	  && argreg <= ARM_LAST_ARG_REGNUM
	  && align > ARM_INT_REGISTER_SIZE
	  && argreg & 1)
	argreg++;

      /* If the argument is a pointer to a function, and it is a
	 Thumb function, create a LOCAL copy of the value and set
	 the THUMB bit in it.  */
      if (TYPE_CODE_PTR == typecode
	  && target_type != NULL
	  && TYPE_CODE_FUNC == check_typedef (target_type)->code ())
	{
	  CORE_ADDR regval = extract_unsigned_integer (val, len, byte_order);
	  if (arm_pc_is_thumb (gdbarch, regval))
	    {
	      bfd_byte *copy = (bfd_byte *) alloca (len);
	      store_unsigned_integer (copy, len, byte_order,
				      MAKE_THUMB_ADDR (regval));
	      val = copy;
	    }
	}

      /* Copy the argument to general registers or the stack in
	 register-sized pieces.  Large arguments are split between
	 registers and stack.  */
      while (len > 0)
	{
	  int partial_len = len < ARM_INT_REGISTER_SIZE
			    ? len : ARM_INT_REGISTER_SIZE;
	  CORE_ADDR regval
	    = extract_unsigned_integer (val, partial_len, byte_order);

	  if (may_use_core_reg && argreg <= ARM_LAST_ARG_REGNUM)
	    {
	      /* The argument is being passed in a general purpose
		 register.  */
	      if (byte_order == BFD_ENDIAN_BIG)
		regval <<= (ARM_INT_REGISTER_SIZE - partial_len) * 8;

	      arm_debug_printf ("arg %d in %s = 0x%s", argnum,
				gdbarch_register_name (gdbarch, argreg),
				phex (regval, ARM_INT_REGISTER_SIZE));

	      regcache_cooked_write_unsigned (regcache, argreg, regval);
	      argreg++;
	    }
	  else
	    {
	      gdb_byte buf[ARM_INT_REGISTER_SIZE];

	      memset (buf, 0, sizeof (buf));
	      store_unsigned_integer (buf, partial_len, byte_order, regval);

	      /* Push the arguments onto the stack.  */
	      arm_debug_printf ("arg %d @ sp + %d", argnum, nstack);
	      si = push_stack_item (si, buf, ARM_INT_REGISTER_SIZE);
	      nstack += ARM_INT_REGISTER_SIZE;
	    }
	      
	  len -= partial_len;
	  val += partial_len;
	}
    }
  /* If we have an odd number of words to push, then decrement the stack
     by one word now, so first stack argument will be dword aligned.  */
  if (nstack & 4)
    sp -= 4;

  while (si)
    {
      sp -= si->len;
      write_memory (sp, si->data, si->len);
      si = pop_stack_item (si);
    }

  /* Finally, update teh SP register.  */
  regcache_cooked_write_unsigned (regcache, ARM_SP_REGNUM, sp);

  return sp;
}


/* Always align the frame to an 8-byte boundary.  This is required on
   some platforms and harmless on the rest.  */

static CORE_ADDR
arm_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  /* Align the stack to eight bytes.  */
  return sp & ~ (CORE_ADDR) 7;
}

static void
print_fpu_flags (struct ui_file *file, int flags)
{
  if (flags & (1 << 0))
    fputs_filtered ("IVO ", file);
  if (flags & (1 << 1))
    fputs_filtered ("DVZ ", file);
  if (flags & (1 << 2))
    fputs_filtered ("OFL ", file);
  if (flags & (1 << 3))
    fputs_filtered ("UFL ", file);
  if (flags & (1 << 4))
    fputs_filtered ("INX ", file);
  fputc_filtered ('\n', file);
}

/* Print interesting information about the floating point processor
   (if present) or emulator.  */
static void
arm_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
		      struct frame_info *frame, const char *args)
{
  unsigned long status = get_frame_register_unsigned (frame, ARM_FPS_REGNUM);
  int type;

  type = (status >> 24) & 127;
  if (status & (1 << 31))
    fprintf_filtered (file, _("Hardware FPU type %d\n"), type);
  else
    fprintf_filtered (file, _("Software FPU type %d\n"), type);
  /* i18n: [floating point unit] mask */
  fputs_filtered (_("mask: "), file);
  print_fpu_flags (file, status >> 16);
  /* i18n: [floating point unit] flags */
  fputs_filtered (_("flags: "), file);
  print_fpu_flags (file, status);
}

/* Construct the ARM extended floating point type.  */
static struct type *
arm_ext_type (struct gdbarch *gdbarch)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (!tdep->arm_ext_type)
    tdep->arm_ext_type
      = arch_float_type (gdbarch, -1, "builtin_type_arm_ext",
			 floatformats_arm_ext);

  return tdep->arm_ext_type;
}

static struct type *
arm_neon_double_type (struct gdbarch *gdbarch)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (tdep->neon_double_type == NULL)
    {
      struct type *t, *elem;

      t = arch_composite_type (gdbarch, "__gdb_builtin_type_neon_d",
			       TYPE_CODE_UNION);
      elem = builtin_type (gdbarch)->builtin_uint8;
      append_composite_type_field (t, "u8", init_vector_type (elem, 8));
      elem = builtin_type (gdbarch)->builtin_uint16;
      append_composite_type_field (t, "u16", init_vector_type (elem, 4));
      elem = builtin_type (gdbarch)->builtin_uint32;
      append_composite_type_field (t, "u32", init_vector_type (elem, 2));
      elem = builtin_type (gdbarch)->builtin_uint64;
      append_composite_type_field (t, "u64", elem);
      elem = builtin_type (gdbarch)->builtin_float;
      append_composite_type_field (t, "f32", init_vector_type (elem, 2));
      elem = builtin_type (gdbarch)->builtin_double;
      append_composite_type_field (t, "f64", elem);

      t->set_is_vector (true);
      t->set_name ("neon_d");
      tdep->neon_double_type = t;
    }

  return tdep->neon_double_type;
}

/* FIXME: The vector types are not correctly ordered on big-endian
   targets.  Just as s0 is the low bits of d0, d0[0] is also the low
   bits of d0 - regardless of what unit size is being held in d0.  So
   the offset of the first uint8 in d0 is 7, but the offset of the
   first float is 4.  This code works as-is for little-endian
   targets.  */

static struct type *
arm_neon_quad_type (struct gdbarch *gdbarch)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (tdep->neon_quad_type == NULL)
    {
      struct type *t, *elem;

      t = arch_composite_type (gdbarch, "__gdb_builtin_type_neon_q",
			       TYPE_CODE_UNION);
      elem = builtin_type (gdbarch)->builtin_uint8;
      append_composite_type_field (t, "u8", init_vector_type (elem, 16));
      elem = builtin_type (gdbarch)->builtin_uint16;
      append_composite_type_field (t, "u16", init_vector_type (elem, 8));
      elem = builtin_type (gdbarch)->builtin_uint32;
      append_composite_type_field (t, "u32", init_vector_type (elem, 4));
      elem = builtin_type (gdbarch)->builtin_uint64;
      append_composite_type_field (t, "u64", init_vector_type (elem, 2));
      elem = builtin_type (gdbarch)->builtin_float;
      append_composite_type_field (t, "f32", init_vector_type (elem, 4));
      elem = builtin_type (gdbarch)->builtin_double;
      append_composite_type_field (t, "f64", init_vector_type (elem, 2));

      t->set_is_vector (true);
      t->set_name ("neon_q");
      tdep->neon_quad_type = t;
    }

  return tdep->neon_quad_type;
}

/* Return true if REGNUM is a Q pseudo register.  Return false
   otherwise.

   REGNUM is the raw register number and not a pseudo-relative register
   number.  */

static bool
is_q_pseudo (struct gdbarch *gdbarch, int regnum)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* Q pseudo registers are available for both NEON (Q0~Q15) and
     MVE (Q0~Q7) features.  */
  if (tdep->have_q_pseudos
      && regnum >= tdep->q_pseudo_base
      && regnum < (tdep->q_pseudo_base + tdep->q_pseudo_count))
    return true;

  return false;
}

/* Return true if REGNUM is a VFP S pseudo register.  Return false
   otherwise.

   REGNUM is the raw register number and not a pseudo-relative register
   number.  */

static bool
is_s_pseudo (struct gdbarch *gdbarch, int regnum)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (tdep->have_s_pseudos
      && regnum >= tdep->s_pseudo_base
      && regnum < (tdep->s_pseudo_base + tdep->s_pseudo_count))
    return true;

  return false;
}

/* Return true if REGNUM is a MVE pseudo register (P0).  Return false
   otherwise.

   REGNUM is the raw register number and not a pseudo-relative register
   number.  */

static bool
is_mve_pseudo (struct gdbarch *gdbarch, int regnum)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (tdep->have_mve
      && regnum >= tdep->mve_pseudo_base
      && regnum < tdep->mve_pseudo_base + tdep->mve_pseudo_count)
    return true;

  return false;
}

/* Return the GDB type object for the "standard" data type of data in
   register N.  */

static struct type *
arm_register_type (struct gdbarch *gdbarch, int regnum)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (is_s_pseudo (gdbarch, regnum))
    return builtin_type (gdbarch)->builtin_float;

  if (is_q_pseudo (gdbarch, regnum))
    return arm_neon_quad_type (gdbarch);

  if (is_mve_pseudo (gdbarch, regnum))
    return builtin_type (gdbarch)->builtin_int16;

  /* If the target description has register information, we are only
     in this function so that we can override the types of
     double-precision registers for NEON.  */
  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
    {
      struct type *t = tdesc_register_type (gdbarch, regnum);

      if (regnum >= ARM_D0_REGNUM && regnum < ARM_D0_REGNUM + 32
	  && t->code () == TYPE_CODE_FLT
	  && tdep->have_neon)
	return arm_neon_double_type (gdbarch);
      else
	return t;
    }

  if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
    {
      if (!tdep->have_fpa_registers)
	return builtin_type (gdbarch)->builtin_void;

      return arm_ext_type (gdbarch);
    }
  else if (regnum == ARM_SP_REGNUM)
    return builtin_type (gdbarch)->builtin_data_ptr;
  else if (regnum == ARM_PC_REGNUM)
    return builtin_type (gdbarch)->builtin_func_ptr;
  else if (regnum >= ARRAY_SIZE (arm_register_names))
    /* These registers are only supported on targets which supply
       an XML description.  */
    return builtin_type (gdbarch)->builtin_int0;
  else
    return builtin_type (gdbarch)->builtin_uint32;
}

/* Map a DWARF register REGNUM onto the appropriate GDB register
   number.  */

static int
arm_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
  /* Core integer regs.  */
  if (reg >= 0 && reg <= 15)
    return reg;

  /* Legacy FPA encoding.  These were once used in a way which
     overlapped with VFP register numbering, so their use is
     discouraged, but GDB doesn't support the ARM toolchain
     which used them for VFP.  */
  if (reg >= 16 && reg <= 23)
    return ARM_F0_REGNUM + reg - 16;

  /* New assignments for the FPA registers.  */
  if (reg >= 96 && reg <= 103)
    return ARM_F0_REGNUM + reg - 96;

  /* WMMX register assignments.  */
  if (reg >= 104 && reg <= 111)
    return ARM_WCGR0_REGNUM + reg - 104;

  if (reg >= 112 && reg <= 127)
    return ARM_WR0_REGNUM + reg - 112;

  if (reg >= 192 && reg <= 199)
    return ARM_WC0_REGNUM + reg - 192;

  /* VFP v2 registers.  A double precision value is actually
     in d1 rather than s2, but the ABI only defines numbering
     for the single precision registers.  This will "just work"
     in GDB for little endian targets (we'll read eight bytes,
     starting in s0 and then progressing to s1), but will be
     reversed on big endian targets with VFP.  This won't
     be a problem for the new Neon quad registers; you're supposed
     to use DW_OP_piece for those.  */
  if (reg >= 64 && reg <= 95)
    {
      char name_buf[4];

      xsnprintf (name_buf, sizeof (name_buf), "s%d", reg - 64);
      return user_reg_map_name_to_regnum (gdbarch, name_buf,
					  strlen (name_buf));
    }

  /* VFP v3 / Neon registers.  This range is also used for VFP v2
     registers, except that it now describes d0 instead of s0.  */
  if (reg >= 256 && reg <= 287)
    {
      char name_buf[4];

      xsnprintf (name_buf, sizeof (name_buf), "d%d", reg - 256);
      return user_reg_map_name_to_regnum (gdbarch, name_buf,
					  strlen (name_buf));
    }

  return -1;
}

/* Map GDB internal REGNUM onto the Arm simulator register numbers.  */
static int
arm_register_sim_regno (struct gdbarch *gdbarch, int regnum)
{
  int reg = regnum;
  gdb_assert (reg >= 0 && reg < gdbarch_num_regs (gdbarch));

  if (regnum >= ARM_WR0_REGNUM && regnum <= ARM_WR15_REGNUM)
    return regnum - ARM_WR0_REGNUM + SIM_ARM_IWMMXT_COP0R0_REGNUM;

  if (regnum >= ARM_WC0_REGNUM && regnum <= ARM_WC7_REGNUM)
    return regnum - ARM_WC0_REGNUM + SIM_ARM_IWMMXT_COP1R0_REGNUM;

  if (regnum >= ARM_WCGR0_REGNUM && regnum <= ARM_WCGR7_REGNUM)
    return regnum - ARM_WCGR0_REGNUM + SIM_ARM_IWMMXT_COP1R8_REGNUM;

  if (reg < NUM_GREGS)
    return SIM_ARM_R0_REGNUM + reg;
  reg -= NUM_GREGS;

  if (reg < NUM_FREGS)
    return SIM_ARM_FP0_REGNUM + reg;
  reg -= NUM_FREGS;

  if (reg < NUM_SREGS)
    return SIM_ARM_FPS_REGNUM + reg;
  reg -= NUM_SREGS;

  internal_error (__FILE__, __LINE__, _("Bad REGNUM %d"), regnum);
}

/* Given BUF, which is OLD_LEN bytes ending at ENDADDR, expand
   the buffer to be NEW_LEN bytes ending at ENDADDR.  Return
   NULL if an error occurs.  BUF is freed.  */

static gdb_byte *
extend_buffer_earlier (gdb_byte *buf, CORE_ADDR endaddr,
		       int old_len, int new_len)
{
  gdb_byte *new_buf;
  int bytes_to_read = new_len - old_len;

  new_buf = (gdb_byte *) xmalloc (new_len);
  memcpy (new_buf + bytes_to_read, buf, old_len);
  xfree (buf);
  if (target_read_code (endaddr - new_len, new_buf, bytes_to_read) != 0)
    {
      xfree (new_buf);
      return NULL;
    }
  return new_buf;
}

/* An IT block is at most the 2-byte IT instruction followed by
   four 4-byte instructions.  The furthest back we must search to
   find an IT block that affects the current instruction is thus
   2 + 3 * 4 == 14 bytes.  */
#define MAX_IT_BLOCK_PREFIX 14

/* Use a quick scan if there are more than this many bytes of
   code.  */
#define IT_SCAN_THRESHOLD 32

/* Adjust a breakpoint's address to move breakpoints out of IT blocks.
   A breakpoint in an IT block may not be hit, depending on the
   condition flags.  */
static CORE_ADDR
arm_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
{
  gdb_byte *buf;
  char map_type;
  CORE_ADDR boundary, func_start;
  int buf_len;
  enum bfd_endian order = gdbarch_byte_order_for_code (gdbarch);
  int i, any, last_it, last_it_count;
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* If we are using BKPT breakpoints, none of this is necessary.  */
  if (tdep->thumb2_breakpoint == NULL)
    return bpaddr;

  /* ARM mode does not have this problem.  */
  if (!arm_pc_is_thumb (gdbarch, bpaddr))
    return bpaddr;

  /* We are setting a breakpoint in Thumb code that could potentially
     contain an IT block.  The first step is to find how much Thumb
     code there is; we do not need to read outside of known Thumb
     sequences.  */
  map_type = arm_find_mapping_symbol (bpaddr, &boundary);
  if (map_type == 0)
    /* Thumb-2 code must have mapping symbols to have a chance.  */
    return bpaddr;

  bpaddr = gdbarch_addr_bits_remove (gdbarch, bpaddr);

  if (find_pc_partial_function (bpaddr, NULL, &func_start, NULL)
      && func_start > boundary)
    boundary = func_start;

  /* Search for a candidate IT instruction.  We have to do some fancy
     footwork to distinguish a real IT instruction from the second
     half of a 32-bit instruction, but there is no need for that if
     there's no candidate.  */
  buf_len = std::min (bpaddr - boundary, (CORE_ADDR) MAX_IT_BLOCK_PREFIX);
  if (buf_len == 0)
    /* No room for an IT instruction.  */
    return bpaddr;

  buf = (gdb_byte *) xmalloc (buf_len);
  if (target_read_code (bpaddr - buf_len, buf, buf_len) != 0)
    return bpaddr;
  any = 0;
  for (i = 0; i < buf_len; i += 2)
    {
      unsigned short inst1 = extract_unsigned_integer (&buf[i], 2, order);
      if ((inst1 & 0xff00) == 0xbf00 && (inst1 & 0x000f) != 0)
	{
	  any = 1;
	  break;
	}
    }

  if (any == 0)
    {
      xfree (buf);
      return bpaddr;
    }

  /* OK, the code bytes before this instruction contain at least one
     halfword which resembles an IT instruction.  We know that it's
     Thumb code, but there are still two possibilities.  Either the
     halfword really is an IT instruction, or it is the second half of
     a 32-bit Thumb instruction.  The only way we can tell is to
     scan forwards from a known instruction boundary.  */
  if (bpaddr - boundary > IT_SCAN_THRESHOLD)
    {
      int definite;

      /* There's a lot of code before this instruction.  Start with an
	 optimistic search; it's easy to recognize halfwords that can
	 not be the start of a 32-bit instruction, and use that to
	 lock on to the instruction boundaries.  */
      buf = extend_buffer_earlier (buf, bpaddr, buf_len, IT_SCAN_THRESHOLD);
      if (buf == NULL)
	return bpaddr;
      buf_len = IT_SCAN_THRESHOLD;

      definite = 0;
      for (i = 0; i < buf_len - sizeof (buf) && ! definite; i += 2)
	{
	  unsigned short inst1 = extract_unsigned_integer (&buf[i], 2, order);
	  if (thumb_insn_size (inst1) == 2)
	    {
	      definite = 1;
	      break;
	    }
	}

      /* At this point, if DEFINITE, BUF[I] is the first place we
	 are sure that we know the instruction boundaries, and it is far
	 enough from BPADDR that we could not miss an IT instruction
	 affecting BPADDR.  If ! DEFINITE, give up - start from a
	 known boundary.  */
      if (! definite)
	{
	  buf = extend_buffer_earlier (buf, bpaddr, buf_len,
				       bpaddr - boundary);
	  if (buf == NULL)
	    return bpaddr;
	  buf_len = bpaddr - boundary;
	  i = 0;
	}
    }
  else
    {
      buf = extend_buffer_earlier (buf, bpaddr, buf_len, bpaddr - boundary);
      if (buf == NULL)
	return bpaddr;
      buf_len = bpaddr - boundary;
      i = 0;
    }

  /* Scan forwards.  Find the last IT instruction before BPADDR.  */
  last_it = -1;
  last_it_count = 0;
  while (i < buf_len)
    {
      unsigned short inst1 = extract_unsigned_integer (&buf[i], 2, order);
      last_it_count--;
      if ((inst1 & 0xff00) == 0xbf00 && (inst1 & 0x000f) != 0)
	{
	  last_it = i;
	  if (inst1 & 0x0001)
	    last_it_count = 4;
	  else if (inst1 & 0x0002)
	    last_it_count = 3;
	  else if (inst1 & 0x0004)
	    last_it_count = 2;
	  else
	    last_it_count = 1;
	}
      i += thumb_insn_size (inst1);
    }

  xfree (buf);

  if (last_it == -1)
    /* There wasn't really an IT instruction after all.  */
    return bpaddr;

  if (last_it_count < 1)
    /* It was too far away.  */
    return bpaddr;

  /* This really is a trouble spot.  Move the breakpoint to the IT
     instruction.  */
  return bpaddr - buf_len + last_it;
}

/* ARM displaced stepping support.

   Generally ARM displaced stepping works as follows:

   1. When an instruction is to be single-stepped, it is first decoded by
      arm_process_displaced_insn.  Depending on the type of instruction, it is
      then copied to a scratch location, possibly in a modified form.  The
      copy_* set of functions performs such modification, as necessary.  A
      breakpoint is placed after the modified instruction in the scratch space
      to return control to GDB.  Note in particular that instructions which
      modify the PC will no longer do so after modification.

   2. The instruction is single-stepped, by setting the PC to the scratch
      location address, and resuming.  Control returns to GDB when the
      breakpoint is hit.

   3. A cleanup function (cleanup_*) is called corresponding to the copy_*
      function used for the current instruction.  This function's job is to
      put the CPU/memory state back to what it would have been if the
      instruction had been executed unmodified in its original location.  */

/* NOP instruction (mov r0, r0).  */
#define ARM_NOP				0xe1a00000
#define THUMB_NOP 0x4600

/* Helper for register reads for displaced stepping.  In particular, this
   returns the PC as it would be seen by the instruction at its original
   location.  */

ULONGEST
displaced_read_reg (regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
		    int regno)
{
  ULONGEST ret;
  CORE_ADDR from = dsc->insn_addr;

  if (regno == ARM_PC_REGNUM)
    {
      /* Compute pipeline offset:
	 - When executing an ARM instruction, PC reads as the address of the
	 current instruction plus 8.
	 - When executing a Thumb instruction, PC reads as the address of the
	 current instruction plus 4.  */

      if (!dsc->is_thumb)
	from += 8;
      else
	from += 4;

      displaced_debug_printf ("read pc value %.8lx",
			      (unsigned long) from);
      return (ULONGEST) from;
    }
  else
    {
      regcache_cooked_read_unsigned (regs, regno, &ret);

      displaced_debug_printf ("read r%d value %.8lx",
			      regno, (unsigned long) ret);

      return ret;
    }
}

static int
displaced_in_arm_mode (struct regcache *regs)
{
  ULONGEST ps;
  ULONGEST t_bit = arm_psr_thumb_bit (regs->arch ());

  regcache_cooked_read_unsigned (regs, ARM_PS_REGNUM, &ps);

  return (ps & t_bit) == 0;
}

/* Write to the PC as from a branch instruction.  */

static void
branch_write_pc (regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
		 ULONGEST val)
{
  if (!dsc->is_thumb)
    /* Note: If bits 0/1 are set, this branch would be unpredictable for
       architecture versions < 6.  */
    regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM,
				    val & ~(ULONGEST) 0x3);
  else
    regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM,
				    val & ~(ULONGEST) 0x1);
}

/* Write to the PC as from a branch-exchange instruction.  */

static void
bx_write_pc (struct regcache *regs, ULONGEST val)
{
  ULONGEST ps;
  ULONGEST t_bit = arm_psr_thumb_bit (regs->arch ());

  regcache_cooked_read_unsigned (regs, ARM_PS_REGNUM, &ps);

  if ((val & 1) == 1)
    {
      regcache_cooked_write_unsigned (regs, ARM_PS_REGNUM, ps | t_bit);
      regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM, val & 0xfffffffe);
    }
  else if ((val & 2) == 0)
    {
      regcache_cooked_write_unsigned (regs, ARM_PS_REGNUM, ps & ~t_bit);
      regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM, val);
    }
  else
    {
      /* Unpredictable behaviour.  Try to do something sensible (switch to ARM
	  mode, align dest to 4 bytes).  */
      warning (_("Single-stepping BX to non-word-aligned ARM instruction."));
      regcache_cooked_write_unsigned (regs, ARM_PS_REGNUM, ps & ~t_bit);
      regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM, val & 0xfffffffc);
    }
}

/* Write to the PC as if from a load instruction.  */

static void
load_write_pc (regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
	       ULONGEST val)
{
  if (DISPLACED_STEPPING_ARCH_VERSION >= 5)
    bx_write_pc (regs, val);
  else
    branch_write_pc (regs, dsc, val);
}

/* Write to the PC as if from an ALU instruction.  */

static void
alu_write_pc (regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
	      ULONGEST val)
{
  if (DISPLACED_STEPPING_ARCH_VERSION >= 7 && !dsc->is_thumb)
    bx_write_pc (regs, val);
  else
    branch_write_pc (regs, dsc, val);
}

/* Helper for writing to registers for displaced stepping.  Writing to the PC
   has a varying effects depending on the instruction which does the write:
   this is controlled by the WRITE_PC argument.  */

void
displaced_write_reg (regcache *regs, arm_displaced_step_copy_insn_closure *dsc,
		     int regno, ULONGEST val, enum pc_write_style write_pc)
{
  if (regno == ARM_PC_REGNUM)
    {
      displaced_debug_printf ("writing pc %.8lx", (unsigned long) val);

      switch (write_pc)
	{
	case BRANCH_WRITE_PC:
	  branch_write_pc (regs, dsc, val);
	  break;

	case BX_WRITE_PC:
	  bx_write_pc (regs, val);
	  break;

	case LOAD_WRITE_PC:
	  load_write_pc (regs, dsc, val);
	  break;

	case ALU_WRITE_PC:
	  alu_write_pc (regs, dsc, val);
	  break;

	case CANNOT_WRITE_PC:
	  warning (_("Instruction wrote to PC in an unexpected way when "
		     "single-stepping"));
	  break;

	default:
	  internal_error (__FILE__, __LINE__,
			  _("Invalid argument to displaced_write_reg"));
	}

      dsc->wrote_to_pc = 1;
    }
  else
    {
      displaced_debug_printf ("writing r%d value %.8lx",
			      regno, (unsigned long) val);
      regcache_cooked_write_unsigned (regs, regno, val);
    }
}

/* This function is used to concisely determine if an instruction INSN
   references PC.  Register fields of interest in INSN should have the
   corresponding fields of BITMASK set to 0b1111.  The function
   returns return 1 if any of these fields in INSN reference the PC
   (also 0b1111, r15), else it returns 0.  */

static int
insn_references_pc (uint32_t insn, uint32_t bitmask)
{
  uint32_t lowbit = 1;

  while (bitmask != 0)
    {
      uint32_t mask;

      for (; lowbit && (bitmask & lowbit) == 0; lowbit <<= 1)
	;

      if (!lowbit)
	break;

      mask = lowbit * 0xf;

      if ((insn & mask) == mask)
	return 1;

      bitmask &= ~mask;
    }

  return 0;
}

/* The simplest copy function.  Many instructions have the same effect no
   matter what address they are executed at: in those cases, use this.  */

static int
arm_copy_unmodified (struct gdbarch *gdbarch, uint32_t insn, const char *iname,
		     arm_displaced_step_copy_insn_closure *dsc)
{
  displaced_debug_printf ("copying insn %.8lx, opcode/class '%s' unmodified",
			  (unsigned long) insn, iname);

  dsc->modinsn[0] = insn;

  return 0;
}

static int
thumb_copy_unmodified_32bit (struct gdbarch *gdbarch, uint16_t insn1,
			     uint16_t insn2, const char *iname,
			     arm_displaced_step_copy_insn_closure *dsc)
{
  displaced_debug_printf ("copying insn %.4x %.4x, opcode/class '%s' "
			  "unmodified", insn1, insn2, iname);

  dsc->modinsn[0] = insn1;
  dsc->modinsn[1] = insn2;
  dsc->numinsns = 2;

  return 0;
}

/* Copy 16-bit Thumb(Thumb and 16-bit Thumb-2) instruction without any
   modification.  */
static int
thumb_copy_unmodified_16bit (struct gdbarch *gdbarch, uint16_t insn,
			     const char *iname,
			     arm_displaced_step_copy_insn_closure *dsc)
{
  displaced_debug_printf ("copying insn %.4x, opcode/class '%s' unmodified",
			  insn, iname);

  dsc->modinsn[0] = insn;

  return 0;
}

/* Preload instructions with immediate offset.  */

static void
cleanup_preload (struct gdbarch *gdbarch, regcache *regs,
		 arm_displaced_step_copy_insn_closure *dsc)
{
  displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);
  if (!dsc->u.preload.immed)
    displaced_write_reg (regs, dsc, 1, dsc->tmp[1], CANNOT_WRITE_PC);
}

static void
install_preload (struct gdbarch *gdbarch, struct regcache *regs,
		 arm_displaced_step_copy_insn_closure *dsc, unsigned int rn)
{
  ULONGEST rn_val;
  /* Preload instructions:

     {pli/pld} [rn, #+/-imm]
     ->
     {pli/pld} [r0, #+/-imm].  */

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  rn_val = displaced_read_reg (regs, dsc, rn);
  displaced_write_reg (regs, dsc, 0, rn_val, CANNOT_WRITE_PC);
  dsc->u.preload.immed = 1;

  dsc->cleanup = &cleanup_preload;
}

static int
arm_copy_preload (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
		  arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rn = bits (insn, 16, 19);

  if (!insn_references_pc (insn, 0x000f0000ul))
    return arm_copy_unmodified (gdbarch, insn, "preload", dsc);

  displaced_debug_printf ("copying preload insn %.8lx", (unsigned long) insn);

  dsc->modinsn[0] = insn & 0xfff0ffff;

  install_preload (gdbarch, regs, dsc, rn);

  return 0;
}

static int
thumb2_copy_preload (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
		     regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rn = bits (insn1, 0, 3);
  unsigned int u_bit = bit (insn1, 7);
  int imm12 = bits (insn2, 0, 11);
  ULONGEST pc_val;

  if (rn != ARM_PC_REGNUM)
    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2, "preload", dsc);

  /* PC is only allowed to use in PLI (immediate,literal) Encoding T3, and
     PLD (literal) Encoding T1.  */
  displaced_debug_printf ("copying pld/pli pc (0x%x) %c imm12 %.4x",
			  (unsigned int) dsc->insn_addr, u_bit ? '+' : '-',
			  imm12);

  if (!u_bit)
    imm12 = -1 * imm12;

  /* Rewrite instruction {pli/pld} PC imm12 into:
     Prepare: tmp[0] <- r0, tmp[1] <- r1, r0 <- pc, r1 <- imm12

     {pli/pld} [r0, r1]

     Cleanup: r0 <- tmp[0], r1 <- tmp[1].  */

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[1] = displaced_read_reg (regs, dsc, 1);

  pc_val = displaced_read_reg (regs, dsc, ARM_PC_REGNUM);

  displaced_write_reg (regs, dsc, 0, pc_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 1, imm12, CANNOT_WRITE_PC);
  dsc->u.preload.immed = 0;

  /* {pli/pld} [r0, r1] */
  dsc->modinsn[0] = insn1 & 0xfff0;
  dsc->modinsn[1] = 0xf001;
  dsc->numinsns = 2;

  dsc->cleanup = &cleanup_preload;
  return 0;
}

/* Preload instructions with register offset.  */

static void
install_preload_reg(struct gdbarch *gdbarch, struct regcache *regs,
		    arm_displaced_step_copy_insn_closure *dsc, unsigned int rn,
		    unsigned int rm)
{
  ULONGEST rn_val, rm_val;

  /* Preload register-offset instructions:

     {pli/pld} [rn, rm {, shift}]
     ->
     {pli/pld} [r0, r1 {, shift}].  */

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[1] = displaced_read_reg (regs, dsc, 1);
  rn_val = displaced_read_reg (regs, dsc, rn);
  rm_val = displaced_read_reg (regs, dsc, rm);
  displaced_write_reg (regs, dsc, 0, rn_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 1, rm_val, CANNOT_WRITE_PC);
  dsc->u.preload.immed = 0;

  dsc->cleanup = &cleanup_preload;
}

static int
arm_copy_preload_reg (struct gdbarch *gdbarch, uint32_t insn,
		      struct regcache *regs,
		      arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rn = bits (insn, 16, 19);
  unsigned int rm = bits (insn, 0, 3);


  if (!insn_references_pc (insn, 0x000f000ful))
    return arm_copy_unmodified (gdbarch, insn, "preload reg", dsc);

  displaced_debug_printf ("copying preload insn %.8lx",
			  (unsigned long) insn);

  dsc->modinsn[0] = (insn & 0xfff0fff0) | 0x1;

  install_preload_reg (gdbarch, regs, dsc, rn, rm);
  return 0;
}

/* Copy/cleanup coprocessor load and store instructions.  */

static void
cleanup_copro_load_store (struct gdbarch *gdbarch,
			  struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc)
{
  ULONGEST rn_val = displaced_read_reg (regs, dsc, 0);

  displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);

  if (dsc->u.ldst.writeback)
    displaced_write_reg (regs, dsc, dsc->u.ldst.rn, rn_val, LOAD_WRITE_PC);
}

static void
install_copro_load_store (struct gdbarch *gdbarch, struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc,
			  int writeback, unsigned int rn)
{
  ULONGEST rn_val;

  /* Coprocessor load/store instructions:

     {stc/stc2} [<Rn>, #+/-imm]  (and other immediate addressing modes)
     ->
     {stc/stc2} [r0, #+/-imm].

     ldc/ldc2 are handled identically.  */

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  rn_val = displaced_read_reg (regs, dsc, rn);
  /* PC should be 4-byte aligned.  */
  rn_val = rn_val & 0xfffffffc;
  displaced_write_reg (regs, dsc, 0, rn_val, CANNOT_WRITE_PC);

  dsc->u.ldst.writeback = writeback;
  dsc->u.ldst.rn = rn;

  dsc->cleanup = &cleanup_copro_load_store;
}

static int
arm_copy_copro_load_store (struct gdbarch *gdbarch, uint32_t insn,
			   struct regcache *regs,
			   arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rn = bits (insn, 16, 19);

  if (!insn_references_pc (insn, 0x000f0000ul))
    return arm_copy_unmodified (gdbarch, insn, "copro load/store", dsc);

  displaced_debug_printf ("copying coprocessor load/store insn %.8lx",
			  (unsigned long) insn);

  dsc->modinsn[0] = insn & 0xfff0ffff;

  install_copro_load_store (gdbarch, regs, dsc, bit (insn, 25), rn);

  return 0;
}

static int
thumb2_copy_copro_load_store (struct gdbarch *gdbarch, uint16_t insn1,
			      uint16_t insn2, struct regcache *regs,
			      arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rn = bits (insn1, 0, 3);

  if (rn != ARM_PC_REGNUM)
    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					"copro load/store", dsc);

  displaced_debug_printf ("copying coprocessor load/store insn %.4x%.4x",
			  insn1, insn2);

  dsc->modinsn[0] = insn1 & 0xfff0;
  dsc->modinsn[1] = insn2;
  dsc->numinsns = 2;

  /* This function is called for copying instruction LDC/LDC2/VLDR, which
     doesn't support writeback, so pass 0.  */
  install_copro_load_store (gdbarch, regs, dsc, 0, rn);

  return 0;
}

/* Clean up branch instructions (actually perform the branch, by setting
   PC).  */

static void
cleanup_branch (struct gdbarch *gdbarch, struct regcache *regs,
		arm_displaced_step_copy_insn_closure *dsc)
{
  uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
  int branch_taken = condition_true (dsc->u.branch.cond, status);
  enum pc_write_style write_pc = dsc->u.branch.exchange
				 ? BX_WRITE_PC : BRANCH_WRITE_PC;

  if (!branch_taken)
    return;

  if (dsc->u.branch.link)
    {
      /* The value of LR should be the next insn of current one.  In order
       not to confuse logic handling later insn `bx lr', if current insn mode
       is Thumb, the bit 0 of LR value should be set to 1.  */
      ULONGEST next_insn_addr = dsc->insn_addr + dsc->insn_size;

      if (dsc->is_thumb)
	next_insn_addr |= 0x1;

      displaced_write_reg (regs, dsc, ARM_LR_REGNUM, next_insn_addr,
			   CANNOT_WRITE_PC);
    }

  displaced_write_reg (regs, dsc, ARM_PC_REGNUM, dsc->u.branch.dest, write_pc);
}

/* Copy B/BL/BLX instructions with immediate destinations.  */

static void
install_b_bl_blx (struct gdbarch *gdbarch, struct regcache *regs,
		  arm_displaced_step_copy_insn_closure *dsc,
		  unsigned int cond, int exchange, int link, long offset)
{
  /* Implement "BL<cond> <label>" as:

     Preparation: cond <- instruction condition
     Insn: mov r0, r0  (nop)
     Cleanup: if (condition true) { r14 <- pc; pc <- label }.

     B<cond> similar, but don't set r14 in cleanup.  */

  dsc->u.branch.cond = cond;
  dsc->u.branch.link = link;
  dsc->u.branch.exchange = exchange;

  dsc->u.branch.dest = dsc->insn_addr;
  if (link && exchange)
    /* For BLX, offset is computed from the Align (PC, 4).  */
    dsc->u.branch.dest = dsc->u.branch.dest & 0xfffffffc;

  if (dsc->is_thumb)
    dsc->u.branch.dest += 4 + offset;
  else
    dsc->u.branch.dest += 8 + offset;

  dsc->cleanup = &cleanup_branch;
}
static int
arm_copy_b_bl_blx (struct gdbarch *gdbarch, uint32_t insn,
		   regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int cond = bits (insn, 28, 31);
  int exchange = (cond == 0xf);
  int link = exchange || bit (insn, 24);
  long offset;

  displaced_debug_printf ("copying %s immediate insn %.8lx",
			  (exchange) ? "blx" : (link) ? "bl" : "b",
			  (unsigned long) insn);
  if (exchange)
    /* For BLX, set bit 0 of the destination.  The cleanup_branch function will
       then arrange the switch into Thumb mode.  */
    offset = (bits (insn, 0, 23) << 2) | (bit (insn, 24) << 1) | 1;
  else
    offset = bits (insn, 0, 23) << 2;

  if (bit (offset, 25))
    offset = offset | ~0x3ffffff;

  dsc->modinsn[0] = ARM_NOP;

  install_b_bl_blx (gdbarch, regs, dsc, cond, exchange, link, offset);
  return 0;
}

static int
thumb2_copy_b_bl_blx (struct gdbarch *gdbarch, uint16_t insn1,
		      uint16_t insn2, struct regcache *regs,
		      arm_displaced_step_copy_insn_closure *dsc)
{
  int link = bit (insn2, 14);
  int exchange = link && !bit (insn2, 12);
  int cond = INST_AL;
  long offset = 0;
  int j1 = bit (insn2, 13);
  int j2 = bit (insn2, 11);
  int s = sbits (insn1, 10, 10);
  int i1 = !(j1 ^ bit (insn1, 10));
  int i2 = !(j2 ^ bit (insn1, 10));

  if (!link && !exchange) /* B */
    {
      offset = (bits (insn2, 0, 10) << 1);
      if (bit (insn2, 12)) /* Encoding T4 */
	{
	  offset |= (bits (insn1, 0, 9) << 12)
	    | (i2 << 22)
	    | (i1 << 23)
	    | (s << 24);
	  cond = INST_AL;
	}
      else /* Encoding T3 */
	{
	  offset |= (bits (insn1, 0, 5) << 12)
	    | (j1 << 18)
	    | (j2 << 19)
	    | (s << 20);
	  cond = bits (insn1, 6, 9);
	}
    }
  else
    {
      offset = (bits (insn1, 0, 9) << 12);
      offset |= ((i2 << 22) | (i1 << 23) | (s << 24));
      offset |= exchange ?
	(bits (insn2, 1, 10) << 2) : (bits (insn2, 0, 10) << 1);
    }

  displaced_debug_printf ("copying %s insn %.4x %.4x with offset %.8lx",
			  link ? (exchange) ? "blx" : "bl" : "b",
			  insn1, insn2, offset);

  dsc->modinsn[0] = THUMB_NOP;

  install_b_bl_blx (gdbarch, regs, dsc, cond, exchange, link, offset);
  return 0;
}

/* Copy B Thumb instructions.  */
static int
thumb_copy_b (struct gdbarch *gdbarch, uint16_t insn,
	      arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int cond = 0;
  int offset = 0;
  unsigned short bit_12_15 = bits (insn, 12, 15);
  CORE_ADDR from = dsc->insn_addr;

  if (bit_12_15 == 0xd)
    {
      /* offset = SignExtend (imm8:0, 32) */
      offset = sbits ((insn << 1), 0, 8);
      cond = bits (insn, 8, 11);
    }
  else if (bit_12_15 == 0xe) /* Encoding T2 */
    {
      offset = sbits ((insn << 1), 0, 11);
      cond = INST_AL;
    }

  displaced_debug_printf ("copying b immediate insn %.4x with offset %d",
			  insn, offset);

  dsc->u.branch.cond = cond;
  dsc->u.branch.link = 0;
  dsc->u.branch.exchange = 0;
  dsc->u.branch.dest = from + 4 + offset;

  dsc->modinsn[0] = THUMB_NOP;

  dsc->cleanup = &cleanup_branch;

  return 0;
}

/* Copy BX/BLX with register-specified destinations.  */

static void
install_bx_blx_reg (struct gdbarch *gdbarch, struct regcache *regs,
		    arm_displaced_step_copy_insn_closure *dsc, int link,
		    unsigned int cond, unsigned int rm)
{
  /* Implement {BX,BLX}<cond> <reg>" as:

     Preparation: cond <- instruction condition
     Insn: mov r0, r0 (nop)
     Cleanup: if (condition true) { r14 <- pc; pc <- dest; }.

     Don't set r14 in cleanup for BX.  */

  dsc->u.branch.dest = displaced_read_reg (regs, dsc, rm);

  dsc->u.branch.cond = cond;
  dsc->u.branch.link = link;

  dsc->u.branch.exchange = 1;

  dsc->cleanup = &cleanup_branch;
}

static int
arm_copy_bx_blx_reg (struct gdbarch *gdbarch, uint32_t insn,
		     regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int cond = bits (insn, 28, 31);
  /* BX:  x12xxx1x
     BLX: x12xxx3x.  */
  int link = bit (insn, 5);
  unsigned int rm = bits (insn, 0, 3);

  displaced_debug_printf ("copying insn %.8lx", (unsigned long) insn);

  dsc->modinsn[0] = ARM_NOP;

  install_bx_blx_reg (gdbarch, regs, dsc, link, cond, rm);
  return 0;
}

static int
thumb_copy_bx_blx_reg (struct gdbarch *gdbarch, uint16_t insn,
		       struct regcache *regs,
		       arm_displaced_step_copy_insn_closure *dsc)
{
  int link = bit (insn, 7);
  unsigned int rm = bits (insn, 3, 6);

  displaced_debug_printf ("copying insn %.4x", (unsigned short) insn);

  dsc->modinsn[0] = THUMB_NOP;

  install_bx_blx_reg (gdbarch, regs, dsc, link, INST_AL, rm);

  return 0;
}


/* Copy/cleanup arithmetic/logic instruction with immediate RHS.  */

static void
cleanup_alu_imm (struct gdbarch *gdbarch,
		 regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
  ULONGEST rd_val = displaced_read_reg (regs, dsc, 0);
  displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 1, dsc->tmp[1], CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, dsc->rd, rd_val, ALU_WRITE_PC);
}

static int
arm_copy_alu_imm (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
		  arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rn = bits (insn, 16, 19);
  unsigned int rd = bits (insn, 12, 15);
  unsigned int op = bits (insn, 21, 24);
  int is_mov = (op == 0xd);
  ULONGEST rd_val, rn_val;

  if (!insn_references_pc (insn, 0x000ff000ul))
    return arm_copy_unmodified (gdbarch, insn, "ALU immediate", dsc);

  displaced_debug_printf ("copying immediate %s insn %.8lx",
			  is_mov ? "move" : "ALU",
			  (unsigned long) insn);

  /* Instruction is of form:

     <op><cond> rd, [rn,] #imm

     Rewrite as:

     Preparation: tmp1, tmp2 <- r0, r1;
		  r0, r1 <- rd, rn
     Insn: <op><cond> r0, r1, #imm
     Cleanup: rd <- r0; r0 <- tmp1; r1 <- tmp2
  */

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[1] = displaced_read_reg (regs, dsc, 1);
  rn_val = displaced_read_reg (regs, dsc, rn);
  rd_val = displaced_read_reg (regs, dsc, rd);
  displaced_write_reg (regs, dsc, 0, rd_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 1, rn_val, CANNOT_WRITE_PC);
  dsc->rd = rd;

  if (is_mov)
    dsc->modinsn[0] = insn & 0xfff00fff;
  else
    dsc->modinsn[0] = (insn & 0xfff00fff) | 0x10000;

  dsc->cleanup = &cleanup_alu_imm;

  return 0;
}

static int
thumb2_copy_alu_imm (struct gdbarch *gdbarch, uint16_t insn1,
		     uint16_t insn2, struct regcache *regs,
		     arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int op = bits (insn1, 5, 8);
  unsigned int rn, rm, rd;
  ULONGEST rd_val, rn_val;

  rn = bits (insn1, 0, 3); /* Rn */
  rm = bits (insn2, 0, 3); /* Rm */
  rd = bits (insn2, 8, 11); /* Rd */

  /* This routine is only called for instruction MOV.  */
  gdb_assert (op == 0x2 && rn == 0xf);

  if (rm != ARM_PC_REGNUM && rd != ARM_PC_REGNUM)
    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2, "ALU imm", dsc);

  displaced_debug_printf ("copying reg %s insn %.4x%.4x", "ALU", insn1, insn2);

  /* Instruction is of form:

     <op><cond> rd, [rn,] #imm

     Rewrite as:

     Preparation: tmp1, tmp2 <- r0, r1;
		  r0, r1 <- rd, rn
     Insn: <op><cond> r0, r1, #imm
     Cleanup: rd <- r0; r0 <- tmp1; r1 <- tmp2
  */

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[1] = displaced_read_reg (regs, dsc, 1);
  rn_val = displaced_read_reg (regs, dsc, rn);
  rd_val = displaced_read_reg (regs, dsc, rd);
  displaced_write_reg (regs, dsc, 0, rd_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 1, rn_val, CANNOT_WRITE_PC);
  dsc->rd = rd;

  dsc->modinsn[0] = insn1;
  dsc->modinsn[1] = ((insn2 & 0xf0f0) | 0x1);
  dsc->numinsns = 2;

  dsc->cleanup = &cleanup_alu_imm;

  return 0;
}

/* Copy/cleanup arithmetic/logic insns with register RHS.  */

static void
cleanup_alu_reg (struct gdbarch *gdbarch,
		 regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
  ULONGEST rd_val;
  int i;

  rd_val = displaced_read_reg (regs, dsc, 0);

  for (i = 0; i < 3; i++)
    displaced_write_reg (regs, dsc, i, dsc->tmp[i], CANNOT_WRITE_PC);

  displaced_write_reg (regs, dsc, dsc->rd, rd_val, ALU_WRITE_PC);
}

static void
install_alu_reg (struct gdbarch *gdbarch, struct regcache *regs,
		 arm_displaced_step_copy_insn_closure *dsc,
		 unsigned int rd, unsigned int rn, unsigned int rm)
{
  ULONGEST rd_val, rn_val, rm_val;

  /* Instruction is of form:

     <op><cond> rd, [rn,] rm [, <shift>]

     Rewrite as:

     Preparation: tmp1, tmp2, tmp3 <- r0, r1, r2;
		  r0, r1, r2 <- rd, rn, rm
     Insn: <op><cond> r0, [r1,] r2 [, <shift>]
     Cleanup: rd <- r0; r0, r1, r2 <- tmp1, tmp2, tmp3
  */

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[1] = displaced_read_reg (regs, dsc, 1);
  dsc->tmp[2] = displaced_read_reg (regs, dsc, 2);
  rd_val = displaced_read_reg (regs, dsc, rd);
  rn_val = displaced_read_reg (regs, dsc, rn);
  rm_val = displaced_read_reg (regs, dsc, rm);
  displaced_write_reg (regs, dsc, 0, rd_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 1, rn_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 2, rm_val, CANNOT_WRITE_PC);
  dsc->rd = rd;

  dsc->cleanup = &cleanup_alu_reg;
}

static int
arm_copy_alu_reg (struct gdbarch *gdbarch, uint32_t insn, struct regcache *regs,
		  arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int op = bits (insn, 21, 24);
  int is_mov = (op == 0xd);

  if (!insn_references_pc (insn, 0x000ff00ful))
    return arm_copy_unmodified (gdbarch, insn, "ALU reg", dsc);

  displaced_debug_printf ("copying reg %s insn %.8lx",
			  is_mov ? "move" : "ALU", (unsigned long) insn);

  if (is_mov)
    dsc->modinsn[0] = (insn & 0xfff00ff0) | 0x2;
  else
    dsc->modinsn[0] = (insn & 0xfff00ff0) | 0x10002;

  install_alu_reg (gdbarch, regs, dsc, bits (insn, 12, 15), bits (insn, 16, 19),
		   bits (insn, 0, 3));
  return 0;
}

static int
thumb_copy_alu_reg (struct gdbarch *gdbarch, uint16_t insn,
		    struct regcache *regs,
		    arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned rm, rd;

  rm = bits (insn, 3, 6);
  rd = (bit (insn, 7) << 3) | bits (insn, 0, 2);

  if (rd != ARM_PC_REGNUM && rm != ARM_PC_REGNUM)
    return thumb_copy_unmodified_16bit (gdbarch, insn, "ALU reg", dsc);

  displaced_debug_printf ("copying ALU reg insn %.4x", (unsigned short) insn);

  dsc->modinsn[0] = ((insn & 0xff00) | 0x10);

  install_alu_reg (gdbarch, regs, dsc, rd, rd, rm);

  return 0;
}

/* Cleanup/copy arithmetic/logic insns with shifted register RHS.  */

static void
cleanup_alu_shifted_reg (struct gdbarch *gdbarch,
			 struct regcache *regs,
			 arm_displaced_step_copy_insn_closure *dsc)
{
  ULONGEST rd_val = displaced_read_reg (regs, dsc, 0);
  int i;

  for (i = 0; i < 4; i++)
    displaced_write_reg (regs, dsc, i, dsc->tmp[i], CANNOT_WRITE_PC);

  displaced_write_reg (regs, dsc, dsc->rd, rd_val, ALU_WRITE_PC);
}

static void
install_alu_shifted_reg (struct gdbarch *gdbarch, struct regcache *regs,
			 arm_displaced_step_copy_insn_closure *dsc,
			 unsigned int rd, unsigned int rn, unsigned int rm,
			 unsigned rs)
{
  int i;
  ULONGEST rd_val, rn_val, rm_val, rs_val;

  /* Instruction is of form:

     <op><cond> rd, [rn,] rm, <shift> rs

     Rewrite as:

     Preparation: tmp1, tmp2, tmp3, tmp4 <- r0, r1, r2, r3
		  r0, r1, r2, r3 <- rd, rn, rm, rs
     Insn: <op><cond> r0, r1, r2, <shift> r3
     Cleanup: tmp5 <- r0
	      r0, r1, r2, r3 <- tmp1, tmp2, tmp3, tmp4
	      rd <- tmp5
  */

  for (i = 0; i < 4; i++)
    dsc->tmp[i] = displaced_read_reg (regs, dsc, i);

  rd_val = displaced_read_reg (regs, dsc, rd);
  rn_val = displaced_read_reg (regs, dsc, rn);
  rm_val = displaced_read_reg (regs, dsc, rm);
  rs_val = displaced_read_reg (regs, dsc, rs);
  displaced_write_reg (regs, dsc, 0, rd_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 1, rn_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 2, rm_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 3, rs_val, CANNOT_WRITE_PC);
  dsc->rd = rd;
  dsc->cleanup = &cleanup_alu_shifted_reg;
}

static int
arm_copy_alu_shifted_reg (struct gdbarch *gdbarch, uint32_t insn,
			  struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int op = bits (insn, 21, 24);
  int is_mov = (op == 0xd);
  unsigned int rd, rn, rm, rs;

  if (!insn_references_pc (insn, 0x000fff0ful))
    return arm_copy_unmodified (gdbarch, insn, "ALU shifted reg", dsc);

  displaced_debug_printf ("copying shifted reg %s insn %.8lx",
			  is_mov ? "move" : "ALU",
			  (unsigned long) insn);

  rn = bits (insn, 16, 19);
  rm = bits (insn, 0, 3);
  rs = bits (insn, 8, 11);
  rd = bits (insn, 12, 15);

  if (is_mov)
    dsc->modinsn[0] = (insn & 0xfff000f0) | 0x302;
  else
    dsc->modinsn[0] = (insn & 0xfff000f0) | 0x10302;

  install_alu_shifted_reg (gdbarch, regs, dsc, rd, rn, rm, rs);

  return 0;
}

/* Clean up load instructions.  */

static void
cleanup_load (struct gdbarch *gdbarch, struct regcache *regs,
	      arm_displaced_step_copy_insn_closure *dsc)
{
  ULONGEST rt_val, rt_val2 = 0, rn_val;

  rt_val = displaced_read_reg (regs, dsc, 0);
  if (dsc->u.ldst.xfersize == 8)
    rt_val2 = displaced_read_reg (regs, dsc, 1);
  rn_val = displaced_read_reg (regs, dsc, 2);

  displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);
  if (dsc->u.ldst.xfersize > 4)
    displaced_write_reg (regs, dsc, 1, dsc->tmp[1], CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 2, dsc->tmp[2], CANNOT_WRITE_PC);
  if (!dsc->u.ldst.immed)
    displaced_write_reg (regs, dsc, 3, dsc->tmp[3], CANNOT_WRITE_PC);

  /* Handle register writeback.  */
  if (dsc->u.ldst.writeback)
    displaced_write_reg (regs, dsc, dsc->u.ldst.rn, rn_val, CANNOT_WRITE_PC);
  /* Put result in right place.  */
  displaced_write_reg (regs, dsc, dsc->rd, rt_val, LOAD_WRITE_PC);
  if (dsc->u.ldst.xfersize == 8)
    displaced_write_reg (regs, dsc, dsc->rd + 1, rt_val2, LOAD_WRITE_PC);
}

/* Clean up store instructions.  */

static void
cleanup_store (struct gdbarch *gdbarch, struct regcache *regs,
	       arm_displaced_step_copy_insn_closure *dsc)
{
  ULONGEST rn_val = displaced_read_reg (regs, dsc, 2);

  displaced_write_reg (regs, dsc, 0, dsc->tmp[0], CANNOT_WRITE_PC);
  if (dsc->u.ldst.xfersize > 4)
    displaced_write_reg (regs, dsc, 1, dsc->tmp[1], CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 2, dsc->tmp[2], CANNOT_WRITE_PC);
  if (!dsc->u.ldst.immed)
    displaced_write_reg (regs, dsc, 3, dsc->tmp[3], CANNOT_WRITE_PC);
  if (!dsc->u.ldst.restore_r4)
    displaced_write_reg (regs, dsc, 4, dsc->tmp[4], CANNOT_WRITE_PC);

  /* Writeback.  */
  if (dsc->u.ldst.writeback)
    displaced_write_reg (regs, dsc, dsc->u.ldst.rn, rn_val, CANNOT_WRITE_PC);
}

/* Copy "extra" load/store instructions.  These are halfword/doubleword
   transfers, which have a different encoding to byte/word transfers.  */

static int
arm_copy_extra_ld_st (struct gdbarch *gdbarch, uint32_t insn, int unprivileged,
		      regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int op1 = bits (insn, 20, 24);
  unsigned int op2 = bits (insn, 5, 6);
  unsigned int rt = bits (insn, 12, 15);
  unsigned int rn = bits (insn, 16, 19);
  unsigned int rm = bits (insn, 0, 3);
  char load[12]     = {0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1};
  char bytesize[12] = {2, 2, 2, 2, 8, 1, 8, 1, 8, 2, 8, 2};
  int immed = (op1 & 0x4) != 0;
  int opcode;
  ULONGEST rt_val, rt_val2 = 0, rn_val, rm_val = 0;

  if (!insn_references_pc (insn, 0x000ff00ful))
    return arm_copy_unmodified (gdbarch, insn, "extra load/store", dsc);

  displaced_debug_printf ("copying %sextra load/store insn %.8lx",
			  unprivileged ? "unprivileged " : "",
			  (unsigned long) insn);

  opcode = ((op2 << 2) | (op1 & 0x1) | ((op1 & 0x4) >> 1)) - 4;

  if (opcode < 0)
    internal_error (__FILE__, __LINE__,
		    _("copy_extra_ld_st: instruction decode error"));

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[1] = displaced_read_reg (regs, dsc, 1);
  dsc->tmp[2] = displaced_read_reg (regs, dsc, 2);
  if (!immed)
    dsc->tmp[3] = displaced_read_reg (regs, dsc, 3);

  rt_val = displaced_read_reg (regs, dsc, rt);
  if (bytesize[opcode] == 8)
    rt_val2 = displaced_read_reg (regs, dsc, rt + 1);
  rn_val = displaced_read_reg (regs, dsc, rn);
  if (!immed)
    rm_val = displaced_read_reg (regs, dsc, rm);

  displaced_write_reg (regs, dsc, 0, rt_val, CANNOT_WRITE_PC);
  if (bytesize[opcode] == 8)
    displaced_write_reg (regs, dsc, 1, rt_val2, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 2, rn_val, CANNOT_WRITE_PC);
  if (!immed)
    displaced_write_reg (regs, dsc, 3, rm_val, CANNOT_WRITE_PC);

  dsc->rd = rt;
  dsc->u.ldst.xfersize = bytesize[opcode];
  dsc->u.ldst.rn = rn;
  dsc->u.ldst.immed = immed;
  dsc->u.ldst.writeback = bit (insn, 24) == 0 || bit (insn, 21) != 0;
  dsc->u.ldst.restore_r4 = 0;

  if (immed)
    /* {ldr,str}<width><cond> rt, [rt2,] [rn, #imm]
	->
       {ldr,str}<width><cond> r0, [r1,] [r2, #imm].  */
    dsc->modinsn[0] = (insn & 0xfff00fff) | 0x20000;
  else
    /* {ldr,str}<width><cond> rt, [rt2,] [rn, +/-rm]
	->
       {ldr,str}<width><cond> r0, [r1,] [r2, +/-r3].  */
    dsc->modinsn[0] = (insn & 0xfff00ff0) | 0x20003;

  dsc->cleanup = load[opcode] ? &cleanup_load : &cleanup_store;

  return 0;
}

/* Copy byte/half word/word loads and stores.  */

static void
install_load_store (struct gdbarch *gdbarch, struct regcache *regs,
		    arm_displaced_step_copy_insn_closure *dsc, int load,
		    int immed, int writeback, int size, int usermode,
		    int rt, int rm, int rn)
{
  ULONGEST rt_val, rn_val, rm_val = 0;

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[2] = displaced_read_reg (regs, dsc, 2);
  if (!immed)
    dsc->tmp[3] = displaced_read_reg (regs, dsc, 3);
  if (!load)
    dsc->tmp[4] = displaced_read_reg (regs, dsc, 4);

  rt_val = displaced_read_reg (regs, dsc, rt);
  rn_val = displaced_read_reg (regs, dsc, rn);
  if (!immed)
    rm_val = displaced_read_reg (regs, dsc, rm);

  displaced_write_reg (regs, dsc, 0, rt_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 2, rn_val, CANNOT_WRITE_PC);
  if (!immed)
    displaced_write_reg (regs, dsc, 3, rm_val, CANNOT_WRITE_PC);
  dsc->rd = rt;
  dsc->u.ldst.xfersize = size;
  dsc->u.ldst.rn = rn;
  dsc->u.ldst.immed = immed;
  dsc->u.ldst.writeback = writeback;

  /* To write PC we can do:

     Before this sequence of instructions:
     r0 is the PC value got from displaced_read_reg, so r0 = from + 8;
     r2 is the Rn value got from displaced_read_reg.

     Insn1: push {pc} Write address of STR instruction + offset on stack
     Insn2: pop  {r4} Read it back from stack, r4 = addr(Insn1) + offset
     Insn3: sub r4, r4, pc   r4 = addr(Insn1) + offset - pc
				= addr(Insn1) + offset - addr(Insn3) - 8
				= offset - 16
     Insn4: add r4, r4, #8   r4 = offset - 8
     Insn5: add r0, r0, r4   r0 = from + 8 + offset - 8
				= from + offset
     Insn6: str r0, [r2, #imm] (or str r0, [r2, r3])

     Otherwise we don't know what value to write for PC, since the offset is
     architecture-dependent (sometimes PC+8, sometimes PC+12).  More details
     of this can be found in Section "Saving from r15" in
     http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204g/Cihbjifh.html */

  dsc->cleanup = load ? &cleanup_load : &cleanup_store;
}


static int
thumb2_copy_load_literal (struct gdbarch *gdbarch, uint16_t insn1,
			  uint16_t insn2, struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc, int size)
{
  unsigned int u_bit = bit (insn1, 7);
  unsigned int rt = bits (insn2, 12, 15);
  int imm12 = bits (insn2, 0, 11);
  ULONGEST pc_val;

  displaced_debug_printf ("copying ldr pc (0x%x) R%d %c imm12 %.4x",
			  (unsigned int) dsc->insn_addr, rt, u_bit ? '+' : '-',
			  imm12);

  if (!u_bit)
    imm12 = -1 * imm12;

  /* Rewrite instruction LDR Rt imm12 into:

     Prepare: tmp[0] <- r0, tmp[1] <- r2, tmp[2] <- r3, r2 <- pc, r3 <- imm12

     LDR R0, R2, R3,

     Cleanup: rt <- r0, r0 <- tmp[0], r2 <- tmp[1], r3 <- tmp[2].  */


  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[2] = displaced_read_reg (regs, dsc, 2);
  dsc->tmp[3] = displaced_read_reg (regs, dsc, 3);

  pc_val = displaced_read_reg (regs, dsc, ARM_PC_REGNUM);

  pc_val = pc_val & 0xfffffffc;

  displaced_write_reg (regs, dsc, 2, pc_val, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 3, imm12, CANNOT_WRITE_PC);

  dsc->rd = rt;

  dsc->u.ldst.xfersize = size;
  dsc->u.ldst.immed = 0;
  dsc->u.ldst.writeback = 0;
  dsc->u.ldst.restore_r4 = 0;

  /* LDR R0, R2, R3 */
  dsc->modinsn[0] = 0xf852;
  dsc->modinsn[1] = 0x3;
  dsc->numinsns = 2;

  dsc->cleanup = &cleanup_load;

  return 0;
}

static int
thumb2_copy_load_reg_imm (struct gdbarch *gdbarch, uint16_t insn1,
			  uint16_t insn2, struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc,
			  int writeback, int immed)
{
  unsigned int rt = bits (insn2, 12, 15);
  unsigned int rn = bits (insn1, 0, 3);
  unsigned int rm = bits (insn2, 0, 3);  /* Only valid if !immed.  */
  /* In LDR (register), there is also a register Rm, which is not allowed to
     be PC, so we don't have to check it.  */

  if (rt != ARM_PC_REGNUM && rn != ARM_PC_REGNUM)
    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2, "load",
					dsc);

  displaced_debug_printf ("copying ldr r%d [r%d] insn %.4x%.4x",
			  rt, rn, insn1, insn2);

  install_load_store (gdbarch, regs, dsc, 1, immed, writeback, 4,
		      0, rt, rm, rn);

  dsc->u.ldst.restore_r4 = 0;

  if (immed)
    /* ldr[b]<cond> rt, [rn, #imm], etc.
       ->
       ldr[b]<cond> r0, [r2, #imm].  */
    {
      dsc->modinsn[0] = (insn1 & 0xfff0) | 0x2;
      dsc->modinsn[1] = insn2 & 0x0fff;
    }
  else
    /* ldr[b]<cond> rt, [rn, rm], etc.
       ->
       ldr[b]<cond> r0, [r2, r3].  */
    {
      dsc->modinsn[0] = (insn1 & 0xfff0) | 0x2;
      dsc->modinsn[1] = (insn2 & 0x0ff0) | 0x3;
    }

  dsc->numinsns = 2;

  return 0;
}


static int
arm_copy_ldr_str_ldrb_strb (struct gdbarch *gdbarch, uint32_t insn,
			    struct regcache *regs,
			    arm_displaced_step_copy_insn_closure *dsc,
			    int load, int size, int usermode)
{
  int immed = !bit (insn, 25);
  int writeback = (bit (insn, 24) == 0 || bit (insn, 21) != 0);
  unsigned int rt = bits (insn, 12, 15);
  unsigned int rn = bits (insn, 16, 19);
  unsigned int rm = bits (insn, 0, 3);  /* Only valid if !immed.  */

  if (!insn_references_pc (insn, 0x000ff00ful))
    return arm_copy_unmodified (gdbarch, insn, "load/store", dsc);

  displaced_debug_printf ("copying %s%s r%d [r%d] insn %.8lx",
			  load ? (size == 1 ? "ldrb" : "ldr")
			       : (size == 1 ? "strb" : "str"),
			  usermode ? "t" : "",
			  rt, rn,
			  (unsigned long) insn);

  install_load_store (gdbarch, regs, dsc, load, immed, writeback, size,
		      usermode, rt, rm, rn);

  if (load || rt != ARM_PC_REGNUM)
    {
      dsc->u.ldst.restore_r4 = 0;

      if (immed)
	/* {ldr,str}[b]<cond> rt, [rn, #imm], etc.
	   ->
	   {ldr,str}[b]<cond> r0, [r2, #imm].  */
	dsc->modinsn[0] = (insn & 0xfff00fff) | 0x20000;
      else
	/* {ldr,str}[b]<cond> rt, [rn, rm], etc.
	   ->
	   {ldr,str}[b]<cond> r0, [r2, r3].  */
	dsc->modinsn[0] = (insn & 0xfff00ff0) | 0x20003;
    }
  else
    {
      /* We need to use r4 as scratch.  Make sure it's restored afterwards.  */
      dsc->u.ldst.restore_r4 = 1;
      dsc->modinsn[0] = 0xe92d8000;  /* push {pc} */
      dsc->modinsn[1] = 0xe8bd0010;  /* pop  {r4} */
      dsc->modinsn[2] = 0xe044400f;  /* sub r4, r4, pc.  */
      dsc->modinsn[3] = 0xe2844008;  /* add r4, r4, #8.  */
      dsc->modinsn[4] = 0xe0800004;  /* add r0, r0, r4.  */

      /* As above.  */
      if (immed)
	dsc->modinsn[5] = (insn & 0xfff00fff) | 0x20000;
      else
	dsc->modinsn[5] = (insn & 0xfff00ff0) | 0x20003;

      dsc->numinsns = 6;
    }

  dsc->cleanup = load ? &cleanup_load : &cleanup_store;

  return 0;
}

/* Cleanup LDM instructions with fully-populated register list.  This is an
   unfortunate corner case: it's impossible to implement correctly by modifying
   the instruction.  The issue is as follows: we have an instruction,

   ldm rN, {r0-r15}

   which we must rewrite to avoid loading PC.  A possible solution would be to
   do the load in two halves, something like (with suitable cleanup
   afterwards):

   mov r8, rN
   ldm[id][ab] r8!, {r0-r7}
   str r7, <temp>
   ldm[id][ab] r8, {r7-r14}
   <bkpt>

   but at present there's no suitable place for <temp>, since the scratch space
   is overwritten before the cleanup routine is called.  For now, we simply
   emulate the instruction.  */

static void
cleanup_block_load_all (struct gdbarch *gdbarch, struct regcache *regs,
			arm_displaced_step_copy_insn_closure *dsc)
{
  int inc = dsc->u.block.increment;
  int bump_before = dsc->u.block.before ? (inc ? 4 : -4) : 0;
  int bump_after = dsc->u.block.before ? 0 : (inc ? 4 : -4);
  uint32_t regmask = dsc->u.block.regmask;
  int regno = inc ? 0 : 15;
  CORE_ADDR xfer_addr = dsc->u.block.xfer_addr;
  int exception_return = dsc->u.block.load && dsc->u.block.user
			 && (regmask & 0x8000) != 0;
  uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
  int do_transfer = condition_true (dsc->u.block.cond, status);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  if (!do_transfer)
    return;

  /* If the instruction is ldm rN, {...pc}^, I don't think there's anything
     sensible we can do here.  Complain loudly.  */
  if (exception_return)
    error (_("Cannot single-step exception return"));

  /* We don't handle any stores here for now.  */
  gdb_assert (dsc->u.block.load != 0);

  displaced_debug_printf ("emulating block transfer: %s %s %s",
			  dsc->u.block.load ? "ldm" : "stm",
			  dsc->u.block.increment ? "inc" : "dec",
			  dsc->u.block.before ? "before" : "after");

  while (regmask)
    {
      uint32_t memword;

      if (inc)
	while (regno <= ARM_PC_REGNUM && (regmask & (1 << regno)) == 0)
	  regno++;
      else
	while (regno >= 0 && (regmask & (1 << regno)) == 0)
	  regno--;

      xfer_addr += bump_before;

      memword = read_memory_unsigned_integer (xfer_addr, 4, byte_order);
      displaced_write_reg (regs, dsc, regno, memword, LOAD_WRITE_PC);

      xfer_addr += bump_after;

      regmask &= ~(1 << regno);
    }

  if (dsc->u.block.writeback)
    displaced_write_reg (regs, dsc, dsc->u.block.rn, xfer_addr,
			 CANNOT_WRITE_PC);
}

/* Clean up an STM which included the PC in the register list.  */

static void
cleanup_block_store_pc (struct gdbarch *gdbarch, struct regcache *regs,
			arm_displaced_step_copy_insn_closure *dsc)
{
  uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
  int store_executed = condition_true (dsc->u.block.cond, status);
  CORE_ADDR pc_stored_at, transferred_regs
    = count_one_bits (dsc->u.block.regmask);
  CORE_ADDR stm_insn_addr;
  uint32_t pc_val;
  long offset;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* If condition code fails, there's nothing else to do.  */
  if (!store_executed)
    return;

  if (dsc->u.block.increment)
    {
      pc_stored_at = dsc->u.block.xfer_addr + 4 * transferred_regs;

      if (dsc->u.block.before)
	 pc_stored_at += 4;
    }
  else
    {
      pc_stored_at = dsc->u.block.xfer_addr;

      if (dsc->u.block.before)
	 pc_stored_at -= 4;
    }

  pc_val = read_memory_unsigned_integer (pc_stored_at, 4, byte_order);
  stm_insn_addr = dsc->scratch_base;
  offset = pc_val - stm_insn_addr;

  displaced_debug_printf ("detected PC offset %.8lx for STM instruction",
			  offset);

  /* Rewrite the stored PC to the proper value for the non-displaced original
     instruction.  */
  write_memory_unsigned_integer (pc_stored_at, 4, byte_order,
				 dsc->insn_addr + offset);
}

/* Clean up an LDM which includes the PC in the register list.  We clumped all
   the registers in the transferred list into a contiguous range r0...rX (to
   avoid loading PC directly and losing control of the debugged program), so we
   must undo that here.  */

static void
cleanup_block_load_pc (struct gdbarch *gdbarch,
		       struct regcache *regs,
		       arm_displaced_step_copy_insn_closure *dsc)
{
  uint32_t status = displaced_read_reg (regs, dsc, ARM_PS_REGNUM);
  int load_executed = condition_true (dsc->u.block.cond, status);
  unsigned int mask = dsc->u.block.regmask, write_reg = ARM_PC_REGNUM;
  unsigned int regs_loaded = count_one_bits (mask);
  unsigned int num_to_shuffle = regs_loaded, clobbered;

  /* The method employed here will fail if the register list is fully populated
     (we need to avoid loading PC directly).  */
  gdb_assert (num_to_shuffle < 16);

  if (!load_executed)
    return;

  clobbered = (1 << num_to_shuffle) - 1;

  while (num_to_shuffle > 0)
    {
      if ((mask & (1 << write_reg)) != 0)
	{
	  unsigned int read_reg = num_to_shuffle - 1;

	  if (read_reg != write_reg)
	    {
	      ULONGEST rval = displaced_read_reg (regs, dsc, read_reg);
	      displaced_write_reg (regs, dsc, write_reg, rval, LOAD_WRITE_PC);
	      displaced_debug_printf ("LDM: move loaded register r%d to r%d",
				      read_reg, write_reg);
	    }
	  else
	    displaced_debug_printf ("LDM: register r%d already in the right "
				    "place", write_reg);

	  clobbered &= ~(1 << write_reg);

	  num_to_shuffle--;
	}

      write_reg--;
    }

  /* Restore any registers we scribbled over.  */
  for (write_reg = 0; clobbered != 0; write_reg++)
    {
      if ((clobbered & (1 << write_reg)) != 0)
	{
	  displaced_write_reg (regs, dsc, write_reg, dsc->tmp[write_reg],
			       CANNOT_WRITE_PC);
	  displaced_debug_printf ("LDM: restored clobbered register r%d",
				  write_reg);
	  clobbered &= ~(1 << write_reg);
	}
    }

  /* Perform register writeback manually.  */
  if (dsc->u.block.writeback)
    {
      ULONGEST new_rn_val = dsc->u.block.xfer_addr;

      if (dsc->u.block.increment)
	new_rn_val += regs_loaded * 4;
      else
	new_rn_val -= regs_loaded * 4;

      displaced_write_reg (regs, dsc, dsc->u.block.rn, new_rn_val,
			   CANNOT_WRITE_PC);
    }
}

/* Handle ldm/stm, apart from some tricky cases which are unlikely to occur
   in user-level code (in particular exception return, ldm rn, {...pc}^).  */

static int
arm_copy_block_xfer (struct gdbarch *gdbarch, uint32_t insn,
		     struct regcache *regs,
		     arm_displaced_step_copy_insn_closure *dsc)
{
  int load = bit (insn, 20);
  int user = bit (insn, 22);
  int increment = bit (insn, 23);
  int before = bit (insn, 24);
  int writeback = bit (insn, 21);
  int rn = bits (insn, 16, 19);

  /* Block transfers which don't mention PC can be run directly
     out-of-line.  */
  if (rn != ARM_PC_REGNUM && (insn & 0x8000) == 0)
    return arm_copy_unmodified (gdbarch, insn, "ldm/stm", dsc);

  if (rn == ARM_PC_REGNUM)
    {
      warning (_("displaced: Unpredictable LDM or STM with "
		 "base register r15"));
      return arm_copy_unmodified (gdbarch, insn, "unpredictable ldm/stm", dsc);
    }

  displaced_debug_printf ("copying block transfer insn %.8lx",
			  (unsigned long) insn);

  dsc->u.block.xfer_addr = displaced_read_reg (regs, dsc, rn);
  dsc->u.block.rn = rn;

  dsc->u.block.load = load;
  dsc->u.block.user = user;
  dsc->u.block.increment = increment;
  dsc->u.block.before = before;
  dsc->u.block.writeback = writeback;
  dsc->u.block.cond = bits (insn, 28, 31);

  dsc->u.block.regmask = insn & 0xffff;

  if (load)
    {
      if ((insn & 0xffff) == 0xffff)
	{
	  /* LDM with a fully-populated register list.  This case is
	     particularly tricky.  Implement for now by fully emulating the
	     instruction (which might not behave perfectly in all cases, but
	     these instructions should be rare enough for that not to matter
	     too much).  */
	  dsc->modinsn[0] = ARM_NOP;

	  dsc->cleanup = &cleanup_block_load_all;
	}
      else
	{
	  /* LDM of a list of registers which includes PC.  Implement by
	     rewriting the list of registers to be transferred into a
	     contiguous chunk r0...rX before doing the transfer, then shuffling
	     registers into the correct places in the cleanup routine.  */
	  unsigned int regmask = insn & 0xffff;
	  unsigned int num_in_list = count_one_bits (regmask), new_regmask;
	  unsigned int i;

	  for (i = 0; i < num_in_list; i++)
	    dsc->tmp[i] = displaced_read_reg (regs, dsc, i);

	  /* Writeback makes things complicated.  We need to avoid clobbering
	     the base register with one of the registers in our modified
	     register list, but just using a different register can't work in
	     all cases, e.g.:

	       ldm r14!, {r0-r13,pc}

	     which would need to be rewritten as:

	       ldm rN!, {r0-r14}

	     but that can't work, because there's no free register for N.

	     Solve this by turning off the writeback bit, and emulating
	     writeback manually in the cleanup routine.  */

	  if (writeback)
	    insn &= ~(1 << 21);

	  new_regmask = (1 << num_in_list) - 1;

	  displaced_debug_printf ("LDM r%d%s, {..., pc}: original reg list "
				  "%.4x, modified list %.4x",
				  rn, writeback ? "!" : "",
				  (int) insn & 0xffff, new_regmask);

	  dsc->modinsn[0] = (insn & ~0xffff) | (new_regmask & 0xffff);

	  dsc->cleanup = &cleanup_block_load_pc;
	}
    }
  else
    {
      /* STM of a list of registers which includes PC.  Run the instruction
	 as-is, but out of line: this will store the wrong value for the PC,
	 so we must manually fix up the memory in the cleanup routine.
	 Doing things this way has the advantage that we can auto-detect
	 the offset of the PC write (which is architecture-dependent) in
	 the cleanup routine.  */
      dsc->modinsn[0] = insn;

      dsc->cleanup = &cleanup_block_store_pc;
    }

  return 0;
}

static int
thumb2_copy_block_xfer (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
			struct regcache *regs,
			arm_displaced_step_copy_insn_closure *dsc)
{
  int rn = bits (insn1, 0, 3);
  int load = bit (insn1, 4);
  int writeback = bit (insn1, 5);

  /* Block transfers which don't mention PC can be run directly
     out-of-line.  */
  if (rn != ARM_PC_REGNUM && (insn2 & 0x8000) == 0)
    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2, "ldm/stm", dsc);

  if (rn == ARM_PC_REGNUM)
    {
      warning (_("displaced: Unpredictable LDM or STM with "
		 "base register r15"));
      return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					  "unpredictable ldm/stm", dsc);
    }

  displaced_debug_printf ("copying block transfer insn %.4x%.4x",
			  insn1, insn2);

  /* Clear bit 13, since it should be always zero.  */
  dsc->u.block.regmask = (insn2 & 0xdfff);
  dsc->u.block.rn = rn;

  dsc->u.block.load = load;
  dsc->u.block.user = 0;
  dsc->u.block.increment = bit (insn1, 7);
  dsc->u.block.before = bit (insn1, 8);
  dsc->u.block.writeback = writeback;
  dsc->u.block.cond = INST_AL;
  dsc->u.block.xfer_addr = displaced_read_reg (regs, dsc, rn);

  if (load)
    {
      if (dsc->u.block.regmask == 0xffff)
	{
	  /* This branch is impossible to happen.  */
	  gdb_assert (0);
	}
      else
	{
	  unsigned int regmask = dsc->u.block.regmask;
	  unsigned int num_in_list = count_one_bits (regmask), new_regmask;
	  unsigned int i;

	  for (i = 0; i < num_in_list; i++)
	    dsc->tmp[i] = displaced_read_reg (regs, dsc, i);

	  if (writeback)
	    insn1 &= ~(1 << 5);

	  new_regmask = (1 << num_in_list) - 1;

	  displaced_debug_printf ("LDM r%d%s, {..., pc}: original reg list "
				  "%.4x, modified list %.4x",
				  rn, writeback ? "!" : "",
				  (int) dsc->u.block.regmask, new_regmask);

	  dsc->modinsn[0] = insn1;
	  dsc->modinsn[1] = (new_regmask & 0xffff);
	  dsc->numinsns = 2;

	  dsc->cleanup = &cleanup_block_load_pc;
	}
    }
  else
    {
      dsc->modinsn[0] = insn1;
      dsc->modinsn[1] = insn2;
      dsc->numinsns = 2;
      dsc->cleanup = &cleanup_block_store_pc;
    }
  return 0;
}

/* Wrapper over read_memory_unsigned_integer for use in arm_get_next_pcs.
 This is used to avoid a dependency on BFD's bfd_endian enum.  */

ULONGEST
arm_get_next_pcs_read_memory_unsigned_integer (CORE_ADDR memaddr, int len,
					       int byte_order)
{
  return read_memory_unsigned_integer (memaddr, len,
				       (enum bfd_endian) byte_order);
}

/* Wrapper over gdbarch_addr_bits_remove for use in arm_get_next_pcs.  */

CORE_ADDR
arm_get_next_pcs_addr_bits_remove (struct arm_get_next_pcs *self,
				   CORE_ADDR val)
{
  return gdbarch_addr_bits_remove (self->regcache->arch (), val);
}

/* Wrapper over syscall_next_pc for use in get_next_pcs.  */

static CORE_ADDR
arm_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self)
{
  return 0;
}

/* Wrapper over arm_is_thumb for use in arm_get_next_pcs.  */

int
arm_get_next_pcs_is_thumb (struct arm_get_next_pcs *self)
{
  return arm_is_thumb (self->regcache);
}

/* single_step() is called just before we want to resume the inferior,
   if we want to single-step it but there is no hardware or kernel
   single-step support.  We find the target of the coming instructions
   and breakpoint them.  */

std::vector<CORE_ADDR>
arm_software_single_step (struct regcache *regcache)
{
  struct gdbarch *gdbarch = regcache->arch ();
  struct arm_get_next_pcs next_pcs_ctx;

  arm_get_next_pcs_ctor (&next_pcs_ctx,
			 &arm_get_next_pcs_ops,
			 gdbarch_byte_order (gdbarch),
			 gdbarch_byte_order_for_code (gdbarch),
			 0,
			 regcache);

  std::vector<CORE_ADDR> next_pcs = arm_get_next_pcs (&next_pcs_ctx);

  for (CORE_ADDR &pc_ref : next_pcs)
    pc_ref = gdbarch_addr_bits_remove (gdbarch, pc_ref);

  return next_pcs;
}

/* Cleanup/copy SVC (SWI) instructions.  These two functions are overridden
   for Linux, where some SVC instructions must be treated specially.  */

static void
cleanup_svc (struct gdbarch *gdbarch, struct regcache *regs,
	     arm_displaced_step_copy_insn_closure *dsc)
{
  CORE_ADDR resume_addr = dsc->insn_addr + dsc->insn_size;

  displaced_debug_printf ("cleanup for svc, resume at %.8lx",
			  (unsigned long) resume_addr);

  displaced_write_reg (regs, dsc, ARM_PC_REGNUM, resume_addr, BRANCH_WRITE_PC);
}


/* Common copy routine for svc instruction.  */

static int
install_svc (struct gdbarch *gdbarch, struct regcache *regs,
	     arm_displaced_step_copy_insn_closure *dsc)
{
  /* Preparation: none.
     Insn: unmodified svc.
     Cleanup: pc <- insn_addr + insn_size.  */

  /* Pretend we wrote to the PC, so cleanup doesn't set PC to the next
     instruction.  */
  dsc->wrote_to_pc = 1;

  /* Allow OS-specific code to override SVC handling.  */
  if (dsc->u.svc.copy_svc_os)
    return dsc->u.svc.copy_svc_os (gdbarch, regs, dsc);
  else
    {
      dsc->cleanup = &cleanup_svc;
      return 0;
    }
}

static int
arm_copy_svc (struct gdbarch *gdbarch, uint32_t insn,
	      regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{

  displaced_debug_printf ("copying svc insn %.8lx",
			  (unsigned long) insn);

  dsc->modinsn[0] = insn;

  return install_svc (gdbarch, regs, dsc);
}

static int
thumb_copy_svc (struct gdbarch *gdbarch, uint16_t insn,
		regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{

  displaced_debug_printf ("copying svc insn %.4x", insn);

  dsc->modinsn[0] = insn;

  return install_svc (gdbarch, regs, dsc);
}

/* Copy undefined instructions.  */

static int
arm_copy_undef (struct gdbarch *gdbarch, uint32_t insn,
		arm_displaced_step_copy_insn_closure *dsc)
{
  displaced_debug_printf ("copying undefined insn %.8lx",
			  (unsigned long) insn);

  dsc->modinsn[0] = insn;

  return 0;
}

static int
thumb_32bit_copy_undef (struct gdbarch *gdbarch, uint16_t insn1, uint16_t insn2,
			arm_displaced_step_copy_insn_closure *dsc)
{

  displaced_debug_printf ("copying undefined insn %.4x %.4x",
			  (unsigned short) insn1, (unsigned short) insn2);

  dsc->modinsn[0] = insn1;
  dsc->modinsn[1] = insn2;
  dsc->numinsns = 2;

  return 0;
}

/* Copy unpredictable instructions.  */

static int
arm_copy_unpred (struct gdbarch *gdbarch, uint32_t insn,
		 arm_displaced_step_copy_insn_closure *dsc)
{
  displaced_debug_printf ("copying unpredictable insn %.8lx",
			  (unsigned long) insn);

  dsc->modinsn[0] = insn;

  return 0;
}

/* The decode_* functions are instruction decoding helpers.  They mostly follow
   the presentation in the ARM ARM.  */

static int
arm_decode_misc_memhint_neon (struct gdbarch *gdbarch, uint32_t insn,
			      struct regcache *regs,
			      arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int op1 = bits (insn, 20, 26), op2 = bits (insn, 4, 7);
  unsigned int rn = bits (insn, 16, 19);

  if (op1 == 0x10 && (op2 & 0x2) == 0x0 && (rn & 0x1) == 0x0)
    return arm_copy_unmodified (gdbarch, insn, "cps", dsc);
  else if (op1 == 0x10 && op2 == 0x0 && (rn & 0x1) == 0x1)
    return arm_copy_unmodified (gdbarch, insn, "setend", dsc);
  else if ((op1 & 0x60) == 0x20)
    return arm_copy_unmodified (gdbarch, insn, "neon dataproc", dsc);
  else if ((op1 & 0x71) == 0x40)
    return arm_copy_unmodified (gdbarch, insn, "neon elt/struct load/store",
				dsc);
  else if ((op1 & 0x77) == 0x41)
    return arm_copy_unmodified (gdbarch, insn, "unallocated mem hint", dsc);
  else if ((op1 & 0x77) == 0x45)
    return arm_copy_preload (gdbarch, insn, regs, dsc);  /* pli.  */
  else if ((op1 & 0x77) == 0x51)
    {
      if (rn != 0xf)
	return arm_copy_preload (gdbarch, insn, regs, dsc);  /* pld/pldw.  */
      else
	return arm_copy_unpred (gdbarch, insn, dsc);
    }
  else if ((op1 & 0x77) == 0x55)
    return arm_copy_preload (gdbarch, insn, regs, dsc);  /* pld/pldw.  */
  else if (op1 == 0x57)
    switch (op2)
      {
      case 0x1: return arm_copy_unmodified (gdbarch, insn, "clrex", dsc);
      case 0x4: return arm_copy_unmodified (gdbarch, insn, "dsb", dsc);
      case 0x5: return arm_copy_unmodified (gdbarch, insn, "dmb", dsc);
      case 0x6: return arm_copy_unmodified (gdbarch, insn, "isb", dsc);
      default: return arm_copy_unpred (gdbarch, insn, dsc);
      }
  else if ((op1 & 0x63) == 0x43)
    return arm_copy_unpred (gdbarch, insn, dsc);
  else if ((op2 & 0x1) == 0x0)
    switch (op1 & ~0x80)
      {
      case 0x61:
	return arm_copy_unmodified (gdbarch, insn, "unallocated mem hint", dsc);
      case 0x65:
	return arm_copy_preload_reg (gdbarch, insn, regs, dsc);  /* pli reg.  */
      case 0x71: case 0x75:
	/* pld/pldw reg.  */
	return arm_copy_preload_reg (gdbarch, insn, regs, dsc);
      case 0x63: case 0x67: case 0x73: case 0x77:
	return arm_copy_unpred (gdbarch, insn, dsc);
      default:
	return arm_copy_undef (gdbarch, insn, dsc);
      }
  else
    return arm_copy_undef (gdbarch, insn, dsc);  /* Probably unreachable.  */
}

static int
arm_decode_unconditional (struct gdbarch *gdbarch, uint32_t insn,
			  struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc)
{
  if (bit (insn, 27) == 0)
    return arm_decode_misc_memhint_neon (gdbarch, insn, regs, dsc);
  /* Switch on bits: 0bxxxxx321xxx0xxxxxxxxxxxxxxxxxxxx.  */
  else switch (((insn & 0x7000000) >> 23) | ((insn & 0x100000) >> 20))
    {
    case 0x0: case 0x2:
      return arm_copy_unmodified (gdbarch, insn, "srs", dsc);

    case 0x1: case 0x3:
      return arm_copy_unmodified (gdbarch, insn, "rfe", dsc);

    case 0x4: case 0x5: case 0x6: case 0x7:
      return arm_copy_b_bl_blx (gdbarch, insn, regs, dsc);

    case 0x8:
      switch ((insn & 0xe00000) >> 21)
	{
	case 0x1: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
	  /* stc/stc2.  */
	  return arm_copy_copro_load_store (gdbarch, insn, regs, dsc);

	case 0x2:
	  return arm_copy_unmodified (gdbarch, insn, "mcrr/mcrr2", dsc);

	default:
	  return arm_copy_undef (gdbarch, insn, dsc);
	}

    case 0x9:
      {
	 int rn_f = (bits (insn, 16, 19) == 0xf);
	switch ((insn & 0xe00000) >> 21)
	  {
	  case 0x1: case 0x3:
	    /* ldc/ldc2 imm (undefined for rn == pc).  */
	    return rn_f ? arm_copy_undef (gdbarch, insn, dsc)
			: arm_copy_copro_load_store (gdbarch, insn, regs, dsc);

	  case 0x2:
	    return arm_copy_unmodified (gdbarch, insn, "mrrc/mrrc2", dsc);

	  case 0x4: case 0x5: case 0x6: case 0x7:
	    /* ldc/ldc2 lit (undefined for rn != pc).  */
	    return rn_f ? arm_copy_copro_load_store (gdbarch, insn, regs, dsc)
			: arm_copy_undef (gdbarch, insn, dsc);

	  default:
	    return arm_copy_undef (gdbarch, insn, dsc);
	  }
      }

    case 0xa:
      return arm_copy_unmodified (gdbarch, insn, "stc/stc2", dsc);

    case 0xb:
      if (bits (insn, 16, 19) == 0xf)
	/* ldc/ldc2 lit.  */
	return arm_copy_copro_load_store (gdbarch, insn, regs, dsc);
      else
	return arm_copy_undef (gdbarch, insn, dsc);

    case 0xc:
      if (bit (insn, 4))
	return arm_copy_unmodified (gdbarch, insn, "mcr/mcr2", dsc);
      else
	return arm_copy_unmodified (gdbarch, insn, "cdp/cdp2", dsc);

    case 0xd:
      if (bit (insn, 4))
	return arm_copy_unmodified (gdbarch, insn, "mrc/mrc2", dsc);
      else
	return arm_copy_unmodified (gdbarch, insn, "cdp/cdp2", dsc);

    default:
      return arm_copy_undef (gdbarch, insn, dsc);
    }
}

/* Decode miscellaneous instructions in dp/misc encoding space.  */

static int
arm_decode_miscellaneous (struct gdbarch *gdbarch, uint32_t insn,
			  struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int op2 = bits (insn, 4, 6);
  unsigned int op = bits (insn, 21, 22);

  switch (op2)
    {
    case 0x0:
      return arm_copy_unmodified (gdbarch, insn, "mrs/msr", dsc);

    case 0x1:
      if (op == 0x1)  /* bx.  */
	return arm_copy_bx_blx_reg (gdbarch, insn, regs, dsc);
      else if (op == 0x3)
	return arm_copy_unmodified (gdbarch, insn, "clz", dsc);
      else
	return arm_copy_undef (gdbarch, insn, dsc);

    case 0x2:
      if (op == 0x1)
	/* Not really supported.  */
	return arm_copy_unmodified (gdbarch, insn, "bxj", dsc);
      else
	return arm_copy_undef (gdbarch, insn, dsc);

    case 0x3:
      if (op == 0x1)
	return arm_copy_bx_blx_reg (gdbarch, insn,
				regs, dsc);  /* blx register.  */
      else
	return arm_copy_undef (gdbarch, insn, dsc);

    case 0x5:
      return arm_copy_unmodified (gdbarch, insn, "saturating add/sub", dsc);

    case 0x7:
      if (op == 0x1)
	return arm_copy_unmodified (gdbarch, insn, "bkpt", dsc);
      else if (op == 0x3)
	/* Not really supported.  */
	return arm_copy_unmodified (gdbarch, insn, "smc", dsc);
      /* Fall through.  */

    default:
      return arm_copy_undef (gdbarch, insn, dsc);
    }
}

static int
arm_decode_dp_misc (struct gdbarch *gdbarch, uint32_t insn,
		    struct regcache *regs,
		    arm_displaced_step_copy_insn_closure *dsc)
{
  if (bit (insn, 25))
    switch (bits (insn, 20, 24))
      {
      case 0x10:
	return arm_copy_unmodified (gdbarch, insn, "movw", dsc);

      case 0x14:
	return arm_copy_unmodified (gdbarch, insn, "movt", dsc);

      case 0x12: case 0x16:
	return arm_copy_unmodified (gdbarch, insn, "msr imm", dsc);

      default:
	return arm_copy_alu_imm (gdbarch, insn, regs, dsc);
      }
  else
    {
      uint32_t op1 = bits (insn, 20, 24), op2 = bits (insn, 4, 7);

      if ((op1 & 0x19) != 0x10 && (op2 & 0x1) == 0x0)
	return arm_copy_alu_reg (gdbarch, insn, regs, dsc);
      else if ((op1 & 0x19) != 0x10 && (op2 & 0x9) == 0x1)
	return arm_copy_alu_shifted_reg (gdbarch, insn, regs, dsc);
      else if ((op1 & 0x19) == 0x10 && (op2 & 0x8) == 0x0)
	return arm_decode_miscellaneous (gdbarch, insn, regs, dsc);
      else if ((op1 & 0x19) == 0x10 && (op2 & 0x9) == 0x8)
	return arm_copy_unmodified (gdbarch, insn, "halfword mul/mla", dsc);
      else if ((op1 & 0x10) == 0x00 && op2 == 0x9)
	return arm_copy_unmodified (gdbarch, insn, "mul/mla", dsc);
      else if ((op1 & 0x10) == 0x10 && op2 == 0x9)
	return arm_copy_unmodified (gdbarch, insn, "synch", dsc);
      else if (op2 == 0xb || (op2 & 0xd) == 0xd)
	/* 2nd arg means "unprivileged".  */
	return arm_copy_extra_ld_st (gdbarch, insn, (op1 & 0x12) == 0x02, regs,
				     dsc);
    }

  /* Should be unreachable.  */
  return 1;
}

static int
arm_decode_ld_st_word_ubyte (struct gdbarch *gdbarch, uint32_t insn,
			     struct regcache *regs,
			     arm_displaced_step_copy_insn_closure *dsc)
{
  int a = bit (insn, 25), b = bit (insn, 4);
  uint32_t op1 = bits (insn, 20, 24);

  if ((!a && (op1 & 0x05) == 0x00 && (op1 & 0x17) != 0x02)
      || (a && (op1 & 0x05) == 0x00 && (op1 & 0x17) != 0x02 && !b))
    return arm_copy_ldr_str_ldrb_strb (gdbarch, insn, regs, dsc, 0, 4, 0);
  else if ((!a && (op1 & 0x17) == 0x02)
	    || (a && (op1 & 0x17) == 0x02 && !b))
    return arm_copy_ldr_str_ldrb_strb (gdbarch, insn, regs, dsc, 0, 4, 1);
  else if ((!a && (op1 & 0x05) == 0x01 && (op1 & 0x17) != 0x03)
	    || (a && (op1 & 0x05) == 0x01 && (op1 & 0x17) != 0x03 && !b))
    return arm_copy_ldr_str_ldrb_strb (gdbarch, insn, regs, dsc, 1, 4, 0);
  else if ((!a && (op1 & 0x17) == 0x03)
	   || (a && (op1 & 0x17) == 0x03 && !b))
    return arm_copy_ldr_str_ldrb_strb (gdbarch, insn, regs, dsc, 1, 4, 1);
  else if ((!a && (op1 & 0x05) == 0x04 && (op1 & 0x17) != 0x06)
	    || (a && (op1 & 0x05) == 0x04 && (op1 & 0x17) != 0x06 && !b))
    return arm_copy_ldr_str_ldrb_strb (gdbarch, insn, regs, dsc, 0, 1, 0);
  else if ((!a && (op1 & 0x17) == 0x06)
	   || (a && (op1 & 0x17) == 0x06 && !b))
    return arm_copy_ldr_str_ldrb_strb (gdbarch, insn, regs, dsc, 0, 1, 1);
  else if ((!a && (op1 & 0x05) == 0x05 && (op1 & 0x17) != 0x07)
	   || (a && (op1 & 0x05) == 0x05 && (op1 & 0x17) != 0x07 && !b))
    return arm_copy_ldr_str_ldrb_strb (gdbarch, insn, regs, dsc, 1, 1, 0);
  else if ((!a && (op1 & 0x17) == 0x07)
	   || (a && (op1 & 0x17) == 0x07 && !b))
    return arm_copy_ldr_str_ldrb_strb (gdbarch, insn, regs, dsc, 1, 1, 1);

  /* Should be unreachable.  */
  return 1;
}

static int
arm_decode_media (struct gdbarch *gdbarch, uint32_t insn,
		  arm_displaced_step_copy_insn_closure *dsc)
{
  switch (bits (insn, 20, 24))
    {
    case 0x00: case 0x01: case 0x02: case 0x03:
      return arm_copy_unmodified (gdbarch, insn, "parallel add/sub signed", dsc);

    case 0x04: case 0x05: case 0x06: case 0x07:
      return arm_copy_unmodified (gdbarch, insn, "parallel add/sub unsigned", dsc);

    case 0x08: case 0x09: case 0x0a: case 0x0b:
    case 0x0c: case 0x0d: case 0x0e: case 0x0f:
      return arm_copy_unmodified (gdbarch, insn,
			      "decode/pack/unpack/saturate/reverse", dsc);

    case 0x18:
      if (bits (insn, 5, 7) == 0)  /* op2.  */
	 {
	  if (bits (insn, 12, 15) == 0xf)
	    return arm_copy_unmodified (gdbarch, insn, "usad8", dsc);
	  else
	    return arm_copy_unmodified (gdbarch, insn, "usada8", dsc);
	}
      else
	 return arm_copy_undef (gdbarch, insn, dsc);

    case 0x1a: case 0x1b:
      if (bits (insn, 5, 6) == 0x2)  /* op2[1:0].  */
	return arm_copy_unmodified (gdbarch, insn, "sbfx", dsc);
      else
	return arm_copy_undef (gdbarch, insn, dsc);

    case 0x1c: case 0x1d:
      if (bits (insn, 5, 6) == 0x0)  /* op2[1:0].  */
	 {
	  if (bits (insn, 0, 3) == 0xf)
	    return arm_copy_unmodified (gdbarch, insn, "bfc", dsc);
	  else
	    return arm_copy_unmodified (gdbarch, insn, "bfi", dsc);
	}
      else
	return arm_copy_undef (gdbarch, insn, dsc);

    case 0x1e: case 0x1f:
      if (bits (insn, 5, 6) == 0x2)  /* op2[1:0].  */
	return arm_copy_unmodified (gdbarch, insn, "ubfx", dsc);
      else
	return arm_copy_undef (gdbarch, insn, dsc);
    }

  /* Should be unreachable.  */
  return 1;
}

static int
arm_decode_b_bl_ldmstm (struct gdbarch *gdbarch, uint32_t insn,
			struct regcache *regs,
			arm_displaced_step_copy_insn_closure *dsc)
{
  if (bit (insn, 25))
    return arm_copy_b_bl_blx (gdbarch, insn, regs, dsc);
  else
    return arm_copy_block_xfer (gdbarch, insn, regs, dsc);
}

static int
arm_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint32_t insn,
			  struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int opcode = bits (insn, 20, 24);

  switch (opcode)
    {
    case 0x04: case 0x05:  /* VFP/Neon mrrc/mcrr.  */
      return arm_copy_unmodified (gdbarch, insn, "vfp/neon mrrc/mcrr", dsc);

    case 0x08: case 0x0a: case 0x0c: case 0x0e:
    case 0x12: case 0x16:
      return arm_copy_unmodified (gdbarch, insn, "vfp/neon vstm/vpush", dsc);

    case 0x09: case 0x0b: case 0x0d: case 0x0f:
    case 0x13: case 0x17:
      return arm_copy_unmodified (gdbarch, insn, "vfp/neon vldm/vpop", dsc);

    case 0x10: case 0x14: case 0x18: case 0x1c:  /* vstr.  */
    case 0x11: case 0x15: case 0x19: case 0x1d:  /* vldr.  */
      /* Note: no writeback for these instructions.  Bit 25 will always be
	 zero though (via caller), so the following works OK.  */
      return arm_copy_copro_load_store (gdbarch, insn, regs, dsc);
    }

  /* Should be unreachable.  */
  return 1;
}

/* Decode shifted register instructions.  */

static int
thumb2_decode_dp_shift_reg (struct gdbarch *gdbarch, uint16_t insn1,
			    uint16_t insn2,  struct regcache *regs,
			    arm_displaced_step_copy_insn_closure *dsc)
{
  /* PC is only allowed to be used in instruction MOV.  */

  unsigned int op = bits (insn1, 5, 8);
  unsigned int rn = bits (insn1, 0, 3);

  if (op == 0x2 && rn == 0xf) /* MOV */
    return thumb2_copy_alu_imm (gdbarch, insn1, insn2, regs, dsc);
  else
    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					"dp (shift reg)", dsc);
}


/* Decode extension register load/store.  Exactly the same as
   arm_decode_ext_reg_ld_st.  */

static int
thumb2_decode_ext_reg_ld_st (struct gdbarch *gdbarch, uint16_t insn1,
			     uint16_t insn2,  struct regcache *regs,
			     arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int opcode = bits (insn1, 4, 8);

  switch (opcode)
    {
    case 0x04: case 0x05:
      return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					  "vfp/neon vmov", dsc);

    case 0x08: case 0x0c: /* 01x00 */
    case 0x0a: case 0x0e: /* 01x10 */
    case 0x12: case 0x16: /* 10x10 */
      return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					  "vfp/neon vstm/vpush", dsc);

    case 0x09: case 0x0d: /* 01x01 */
    case 0x0b: case 0x0f: /* 01x11 */
    case 0x13: case 0x17: /* 10x11 */
      return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					  "vfp/neon vldm/vpop", dsc);

    case 0x10: case 0x14: case 0x18: case 0x1c:  /* vstr.  */
      return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					  "vstr", dsc);
    case 0x11: case 0x15: case 0x19: case 0x1d:  /* vldr.  */
      return thumb2_copy_copro_load_store (gdbarch, insn1, insn2, regs, dsc);
    }

  /* Should be unreachable.  */
  return 1;
}

static int
arm_decode_svc_copro (struct gdbarch *gdbarch, uint32_t insn,
		      regcache *regs, arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int op1 = bits (insn, 20, 25);
  int op = bit (insn, 4);
  unsigned int coproc = bits (insn, 8, 11);

  if ((op1 & 0x20) == 0x00 && (op1 & 0x3a) != 0x00 && (coproc & 0xe) == 0xa)
    return arm_decode_ext_reg_ld_st (gdbarch, insn, regs, dsc);
  else if ((op1 & 0x21) == 0x00 && (op1 & 0x3a) != 0x00
	   && (coproc & 0xe) != 0xa)
    /* stc/stc2.  */
    return arm_copy_copro_load_store (gdbarch, insn, regs, dsc);
  else if ((op1 & 0x21) == 0x01 && (op1 & 0x3a) != 0x00
	   && (coproc & 0xe) != 0xa)
    /* ldc/ldc2 imm/lit.  */
    return arm_copy_copro_load_store (gdbarch, insn, regs, dsc);
  else if ((op1 & 0x3e) == 0x00)
    return arm_copy_undef (gdbarch, insn, dsc);
  else if ((op1 & 0x3e) == 0x04 && (coproc & 0xe) == 0xa)
    return arm_copy_unmodified (gdbarch, insn, "neon 64bit xfer", dsc);
  else if (op1 == 0x04 && (coproc & 0xe) != 0xa)
    return arm_copy_unmodified (gdbarch, insn, "mcrr/mcrr2", dsc);
  else if (op1 == 0x05 && (coproc & 0xe) != 0xa)
    return arm_copy_unmodified (gdbarch, insn, "mrrc/mrrc2", dsc);
  else if ((op1 & 0x30) == 0x20 && !op)
    {
      if ((coproc & 0xe) == 0xa)
	return arm_copy_unmodified (gdbarch, insn, "vfp dataproc", dsc);
      else
	return arm_copy_unmodified (gdbarch, insn, "cdp/cdp2", dsc);
    }
  else if ((op1 & 0x30) == 0x20 && op)
    return arm_copy_unmodified (gdbarch, insn, "neon 8/16/32 bit xfer", dsc);
  else if ((op1 & 0x31) == 0x20 && op && (coproc & 0xe) != 0xa)
    return arm_copy_unmodified (gdbarch, insn, "mcr/mcr2", dsc);
  else if ((op1 & 0x31) == 0x21 && op && (coproc & 0xe) != 0xa)
    return arm_copy_unmodified (gdbarch, insn, "mrc/mrc2", dsc);
  else if ((op1 & 0x30) == 0x30)
    return arm_copy_svc (gdbarch, insn, regs, dsc);
  else
    return arm_copy_undef (gdbarch, insn, dsc);  /* Possibly unreachable.  */
}

static int
thumb2_decode_svc_copro (struct gdbarch *gdbarch, uint16_t insn1,
			 uint16_t insn2, struct regcache *regs,
			 arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int coproc = bits (insn2, 8, 11);
  unsigned int bit_5_8 = bits (insn1, 5, 8);
  unsigned int bit_9 = bit (insn1, 9);
  unsigned int bit_4 = bit (insn1, 4);

  if (bit_9 == 0)
    {
      if (bit_5_8 == 2)
	return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					    "neon 64bit xfer/mrrc/mrrc2/mcrr/mcrr2",
					    dsc);
      else if (bit_5_8 == 0) /* UNDEFINED.  */
	return thumb_32bit_copy_undef (gdbarch, insn1, insn2, dsc);
      else
	{
	   /*coproc is 101x.  SIMD/VFP, ext registers load/store.  */
	  if ((coproc & 0xe) == 0xa)
	    return thumb2_decode_ext_reg_ld_st (gdbarch, insn1, insn2, regs,
						dsc);
	  else /* coproc is not 101x.  */
	    {
	      if (bit_4 == 0) /* STC/STC2.  */
		return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						    "stc/stc2", dsc);
	      else /* LDC/LDC2 {literal, immediate}.  */
		return thumb2_copy_copro_load_store (gdbarch, insn1, insn2,
						     regs, dsc);
	    }
	}
    }
  else
    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2, "coproc", dsc);

  return 0;
}

static void
install_pc_relative (struct gdbarch *gdbarch, struct regcache *regs,
		     arm_displaced_step_copy_insn_closure *dsc, int rd)
{
  /* ADR Rd, #imm

     Rewrite as:

     Preparation: Rd <- PC
     Insn: ADD Rd, #imm
     Cleanup: Null.
  */

  /* Rd <- PC */
  int val = displaced_read_reg (regs, dsc, ARM_PC_REGNUM);
  displaced_write_reg (regs, dsc, rd, val, CANNOT_WRITE_PC);
}

static int
thumb_copy_pc_relative_16bit (struct gdbarch *gdbarch, struct regcache *regs,
			      arm_displaced_step_copy_insn_closure *dsc,
			      int rd, unsigned int imm)
{

  /* Encoding T2: ADDS Rd, #imm */
  dsc->modinsn[0] = (0x3000 | (rd << 8) | imm);

  install_pc_relative (gdbarch, regs, dsc, rd);

  return 0;
}

static int
thumb_decode_pc_relative_16bit (struct gdbarch *gdbarch, uint16_t insn,
				struct regcache *regs,
				arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rd = bits (insn, 8, 10);
  unsigned int imm8 = bits (insn, 0, 7);

  displaced_debug_printf ("copying thumb adr r%d, #%d insn %.4x",
			  rd, imm8, insn);

  return thumb_copy_pc_relative_16bit (gdbarch, regs, dsc, rd, imm8);
}

static int
thumb_copy_pc_relative_32bit (struct gdbarch *gdbarch, uint16_t insn1,
			      uint16_t insn2, struct regcache *regs,
			      arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rd = bits (insn2, 8, 11);
  /* Since immediate has the same encoding in ADR ADD and SUB, so we simply
     extract raw immediate encoding rather than computing immediate.  When
     generating ADD or SUB instruction, we can simply perform OR operation to
     set immediate into ADD.  */
  unsigned int imm_3_8 = insn2 & 0x70ff;
  unsigned int imm_i = insn1 & 0x0400; /* Clear all bits except bit 10.  */

  displaced_debug_printf ("copying thumb adr r%d, #%d:%d insn %.4x%.4x",
			  rd, imm_i, imm_3_8, insn1, insn2);

  if (bit (insn1, 7)) /* Encoding T2 */
    {
      /* Encoding T3: SUB Rd, Rd, #imm */
      dsc->modinsn[0] = (0xf1a0 | rd | imm_i);
      dsc->modinsn[1] = ((rd << 8) | imm_3_8);
    }
  else /* Encoding T3 */
    {
      /* Encoding T3: ADD Rd, Rd, #imm */
      dsc->modinsn[0] = (0xf100 | rd | imm_i);
      dsc->modinsn[1] = ((rd << 8) | imm_3_8);
    }
  dsc->numinsns = 2;

  install_pc_relative (gdbarch, regs, dsc, rd);

  return 0;
}

static int
thumb_copy_16bit_ldr_literal (struct gdbarch *gdbarch, uint16_t insn1,
			      struct regcache *regs,
			      arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned int rt = bits (insn1, 8, 10);
  unsigned int pc;
  int imm8 = (bits (insn1, 0, 7) << 2);

  /* LDR Rd, #imm8

     Rwrite as:

     Preparation: tmp0 <- R0, tmp2 <- R2, tmp3 <- R3, R2 <- PC, R3 <- #imm8;

     Insn: LDR R0, [R2, R3];
     Cleanup: R2 <- tmp2, R3 <- tmp3, Rd <- R0, R0 <- tmp0 */

  displaced_debug_printf ("copying thumb ldr r%d [pc #%d]", rt, imm8);

  dsc->tmp[0] = displaced_read_reg (regs, dsc, 0);
  dsc->tmp[2] = displaced_read_reg (regs, dsc, 2);
  dsc->tmp[3] = displaced_read_reg (regs, dsc, 3);
  pc = displaced_read_reg (regs, dsc, ARM_PC_REGNUM);
  /* The assembler calculates the required value of the offset from the
     Align(PC,4) value of this instruction to the label.  */
  pc = pc & 0xfffffffc;

  displaced_write_reg (regs, dsc, 2, pc, CANNOT_WRITE_PC);
  displaced_write_reg (regs, dsc, 3, imm8, CANNOT_WRITE_PC);

  dsc->rd = rt;
  dsc->u.ldst.xfersize = 4;
  dsc->u.ldst.rn = 0;
  dsc->u.ldst.immed = 0;
  dsc->u.ldst.writeback = 0;
  dsc->u.ldst.restore_r4 = 0;

  dsc->modinsn[0] = 0x58d0; /* ldr r0, [r2, r3]*/

  dsc->cleanup = &cleanup_load;

  return 0;
}

/* Copy Thumb cbnz/cbz instruction.  */

static int
thumb_copy_cbnz_cbz (struct gdbarch *gdbarch, uint16_t insn1,
		     struct regcache *regs,
		     arm_displaced_step_copy_insn_closure *dsc)
{
  int non_zero = bit (insn1, 11);
  unsigned int imm5 = (bit (insn1, 9) << 6) | (bits (insn1, 3, 7) << 1);
  CORE_ADDR from = dsc->insn_addr;
  int rn = bits (insn1, 0, 2);
  int rn_val = displaced_read_reg (regs, dsc, rn);

  dsc->u.branch.cond = (rn_val && non_zero) || (!rn_val && !non_zero);
  /* CBNZ and CBZ do not affect the condition flags.  If condition is true,
     set it INST_AL, so cleanup_branch will know branch is taken, otherwise,
     condition is false, let it be, cleanup_branch will do nothing.  */
  if (dsc->u.branch.cond)
    {
      dsc->u.branch.cond = INST_AL;
      dsc->u.branch.dest = from + 4 + imm5;
    }
  else
      dsc->u.branch.dest = from + 2;

  dsc->u.branch.link = 0;
  dsc->u.branch.exchange = 0;

  displaced_debug_printf ("copying %s [r%d = 0x%x] insn %.4x to %.8lx",
			  non_zero ? "cbnz" : "cbz",
			  rn, rn_val, insn1, dsc->u.branch.dest);

  dsc->modinsn[0] = THUMB_NOP;

  dsc->cleanup = &cleanup_branch;
  return 0;
}

/* Copy Table Branch Byte/Halfword */
static int
thumb2_copy_table_branch (struct gdbarch *gdbarch, uint16_t insn1,
			  uint16_t insn2, struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc)
{
  ULONGEST rn_val, rm_val;
  int is_tbh = bit (insn2, 4);
  CORE_ADDR halfwords = 0;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  rn_val = displaced_read_reg (regs, dsc, bits (insn1, 0, 3));
  rm_val = displaced_read_reg (regs, dsc, bits (insn2, 0, 3));

  if (is_tbh)
    {
      gdb_byte buf[2];

      target_read_memory (rn_val + 2 * rm_val, buf, 2);
      halfwords = extract_unsigned_integer (buf, 2, byte_order);
    }
  else
    {
      gdb_byte buf[1];

      target_read_memory (rn_val + rm_val, buf, 1);
      halfwords = extract_unsigned_integer (buf, 1, byte_order);
    }

  displaced_debug_printf ("%s base 0x%x offset 0x%x offset 0x%x",
			  is_tbh ? "tbh" : "tbb",
			  (unsigned int) rn_val, (unsigned int) rm_val,
			  (unsigned int) halfwords);

  dsc->u.branch.cond = INST_AL;
  dsc->u.branch.link = 0;
  dsc->u.branch.exchange = 0;
  dsc->u.branch.dest = dsc->insn_addr + 4 + 2 * halfwords;

  dsc->cleanup = &cleanup_branch;

  return 0;
}

static void
cleanup_pop_pc_16bit_all (struct gdbarch *gdbarch, struct regcache *regs,
			  arm_displaced_step_copy_insn_closure *dsc)
{
  /* PC <- r7 */
  int val = displaced_read_reg (regs, dsc, 7);
  displaced_write_reg (regs, dsc, ARM_PC_REGNUM, val, BX_WRITE_PC);

  /* r7 <- r8 */
  val = displaced_read_reg (regs, dsc, 8);
  displaced_write_reg (regs, dsc, 7, val, CANNOT_WRITE_PC);

  /* r8 <- tmp[0] */
  displaced_write_reg (regs, dsc, 8, dsc->tmp[0], CANNOT_WRITE_PC);

}

static int
thumb_copy_pop_pc_16bit (struct gdbarch *gdbarch, uint16_t insn1,
			 struct regcache *regs,
			 arm_displaced_step_copy_insn_closure *dsc)
{
  dsc->u.block.regmask = insn1 & 0x00ff;

  /* Rewrite instruction: POP {rX, rY, ...,rZ, PC}
     to :

     (1) register list is full, that is, r0-r7 are used.
     Prepare: tmp[0] <- r8

     POP {r0, r1, ...., r6, r7}; remove PC from reglist
     MOV r8, r7; Move value of r7 to r8;
     POP {r7}; Store PC value into r7.

     Cleanup: PC <- r7, r7 <- r8, r8 <-tmp[0]

     (2) register list is not full, supposing there are N registers in
     register list (except PC, 0 <= N <= 7).
     Prepare: for each i, 0 - N, tmp[i] <- ri.

     POP {r0, r1, ...., rN};

     Cleanup: Set registers in original reglist from r0 - rN.  Restore r0 - rN
     from tmp[] properly.
  */
  displaced_debug_printf ("copying thumb pop {%.8x, pc} insn %.4x",
			  dsc->u.block.regmask, insn1);

  if (dsc->u.block.regmask == 0xff)
    {
      dsc->tmp[0] = displaced_read_reg (regs, dsc, 8);

      dsc->modinsn[0] = (insn1 & 0xfeff); /* POP {r0,r1,...,r6, r7} */
      dsc->modinsn[1] = 0x46b8; /* MOV r8, r7 */
      dsc->modinsn[2] = 0xbc80; /* POP {r7} */

      dsc->numinsns = 3;
      dsc->cleanup = &cleanup_pop_pc_16bit_all;
    }
  else
    {
      unsigned int num_in_list = count_one_bits (dsc->u.block.regmask);
      unsigned int i;
      unsigned int new_regmask;

      for (i = 0; i < num_in_list + 1; i++)
	dsc->tmp[i] = displaced_read_reg (regs, dsc, i);

      new_regmask = (1 << (num_in_list + 1)) - 1;

      displaced_debug_printf ("POP {..., pc}: original reg list %.4x, "
			      "modified list %.4x",
			      (int) dsc->u.block.regmask, new_regmask);

      dsc->u.block.regmask |= 0x8000;
      dsc->u.block.writeback = 0;
      dsc->u.block.cond = INST_AL;

      dsc->modinsn[0] = (insn1 & ~0x1ff) | (new_regmask & 0xff);

      dsc->cleanup = &cleanup_block_load_pc;
    }

  return 0;
}

static void
thumb_process_displaced_16bit_insn (struct gdbarch *gdbarch, uint16_t insn1,
				    struct regcache *regs,
				    arm_displaced_step_copy_insn_closure *dsc)
{
  unsigned short op_bit_12_15 = bits (insn1, 12, 15);
  unsigned short op_bit_10_11 = bits (insn1, 10, 11);
  int err = 0;

  /* 16-bit thumb instructions.  */
  switch (op_bit_12_15)
    {
      /* Shift (imme), add, subtract, move and compare.  */
    case 0: case 1: case 2: case 3:
      err = thumb_copy_unmodified_16bit (gdbarch, insn1,
					 "shift/add/sub/mov/cmp",
					 dsc);
      break;
    case 4:
      switch (op_bit_10_11)
	{
	case 0: /* Data-processing */
	  err = thumb_copy_unmodified_16bit (gdbarch, insn1,
					     "data-processing",
					     dsc);
	  break;
	case 1: /* Special data instructions and branch and exchange.  */
	  {
	    unsigned short op = bits (insn1, 7, 9);
	    if (op == 6 || op == 7) /* BX or BLX */
	      err = thumb_copy_bx_blx_reg (gdbarch, insn1, regs, dsc);
	    else if (bits (insn1, 6, 7) != 0) /* ADD/MOV/CMP high registers.  */
	      err = thumb_copy_alu_reg (gdbarch, insn1, regs, dsc);
	    else
	      err = thumb_copy_unmodified_16bit (gdbarch, insn1, "special data",
						 dsc);
	  }
	  break;
	default: /* LDR (literal) */
	  err = thumb_copy_16bit_ldr_literal (gdbarch, insn1, regs, dsc);
	}
      break;
    case 5: case 6: case 7: case 8: case 9: /* Load/Store single data item */
      err = thumb_copy_unmodified_16bit (gdbarch, insn1, "ldr/str", dsc);
      break;
    case 10:
      if (op_bit_10_11 < 2) /* Generate PC-relative address */
	err = thumb_decode_pc_relative_16bit (gdbarch, insn1, regs, dsc);
      else /* Generate SP-relative address */
	err = thumb_copy_unmodified_16bit (gdbarch, insn1, "sp-relative", dsc);
      break;
    case 11: /* Misc 16-bit instructions */
      {
	switch (bits (insn1, 8, 11))
	  {
	  case 1: case 3:  case 9: case 11: /* CBNZ, CBZ */
	    err = thumb_copy_cbnz_cbz (gdbarch, insn1, regs, dsc);
	    break;
	  case 12: case 13: /* POP */
	    if (bit (insn1, 8)) /* PC is in register list.  */
	      err = thumb_copy_pop_pc_16bit (gdbarch, insn1, regs, dsc);
	    else
	      err = thumb_copy_unmodified_16bit (gdbarch, insn1, "pop", dsc);
	    break;
	  case 15: /* If-Then, and hints */
	    if (bits (insn1, 0, 3))
	      /* If-Then makes up to four following instructions conditional.
		 IT instruction itself is not conditional, so handle it as a
		 common unmodified instruction.  */
	      err = thumb_copy_unmodified_16bit (gdbarch, insn1, "If-Then",
						 dsc);
	    else
	      err = thumb_copy_unmodified_16bit (gdbarch, insn1, "hints", dsc);
	    break;
	  default:
	    err = thumb_copy_unmodified_16bit (gdbarch, insn1, "misc", dsc);
	  }
      }
      break;
    case 12:
      if (op_bit_10_11 < 2) /* Store multiple registers */
	err = thumb_copy_unmodified_16bit (gdbarch, insn1, "stm", dsc);
      else /* Load multiple registers */
	err = thumb_copy_unmodified_16bit (gdbarch, insn1, "ldm", dsc);
      break;
    case 13: /* Conditional branch and supervisor call */
      if (bits (insn1, 9, 11) != 7) /* conditional branch */
	err = thumb_copy_b (gdbarch, insn1, dsc);
      else
	err = thumb_copy_svc (gdbarch, insn1, regs, dsc);
      break;
    case 14: /* Unconditional branch */
      err = thumb_copy_b (gdbarch, insn1, dsc);
      break;
    default:
      err = 1;
    }

  if (err)
    internal_error (__FILE__, __LINE__,
		    _("thumb_process_displaced_16bit_insn: Instruction decode error"));
}

static int
decode_thumb_32bit_ld_mem_hints (struct gdbarch *gdbarch,
				 uint16_t insn1, uint16_t insn2,
				 struct regcache *regs,
				 arm_displaced_step_copy_insn_closure *dsc)
{
  int rt = bits (insn2, 12, 15);
  int rn = bits (insn1, 0, 3);
  int op1 = bits (insn1, 7, 8);

  switch (bits (insn1, 5, 6))
    {
    case 0: /* Load byte and memory hints */
      if (rt == 0xf) /* PLD/PLI */
	{
	  if (rn == 0xf)
	    /* PLD literal or Encoding T3 of PLI(immediate, literal).  */
	    return thumb2_copy_preload (gdbarch, insn1, insn2, regs, dsc);
	  else
	    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						"pli/pld", dsc);
	}
      else
	{
	  if (rn == 0xf) /* LDRB/LDRSB (literal) */
	    return thumb2_copy_load_literal (gdbarch, insn1, insn2, regs, dsc,
					     1);
	  else
	    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						"ldrb{reg, immediate}/ldrbt",
						dsc);
	}

      break;
    case 1: /* Load halfword and memory hints.  */
      if (rt == 0xf) /* PLD{W} and Unalloc memory hint.  */
	return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					    "pld/unalloc memhint", dsc);
      else
	{
	  if (rn == 0xf)
	    return thumb2_copy_load_literal (gdbarch, insn1, insn2, regs, dsc,
					     2);
	  else
	    return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						"ldrh/ldrht", dsc);
	}
      break;
    case 2: /* Load word */
      {
	int insn2_bit_8_11 = bits (insn2, 8, 11);

	if (rn == 0xf)
	  return thumb2_copy_load_literal (gdbarch, insn1, insn2, regs, dsc, 4);
	else if (op1 == 0x1) /* Encoding T3 */
	  return thumb2_copy_load_reg_imm (gdbarch, insn1, insn2, regs, dsc,
					   0, 1);
	else /* op1 == 0x0 */
	  {
	    if (insn2_bit_8_11 == 0xc || (insn2_bit_8_11 & 0x9) == 0x9)
	      /* LDR (immediate) */
	      return thumb2_copy_load_reg_imm (gdbarch, insn1, insn2, regs,
					       dsc, bit (insn2, 8), 1);
	    else if (insn2_bit_8_11 == 0xe) /* LDRT */
	      return thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						  "ldrt", dsc);
	    else
	      /* LDR (register) */
	      return thumb2_copy_load_reg_imm (gdbarch, insn1, insn2, regs,
					       dsc, 0, 0);
	  }
	break;
      }
    default:
      return thumb_32bit_copy_undef (gdbarch, insn1, insn2, dsc);
      break;
    }
  return 0;
}

static void
thumb_process_displaced_32bit_insn (struct gdbarch *gdbarch, uint16_t insn1,
				    uint16_t insn2, struct regcache *regs,
				    arm_displaced_step_copy_insn_closure *dsc)
{
  int err = 0;
  unsigned short op = bit (insn2, 15);
  unsigned int op1 = bits (insn1, 11, 12);

  switch (op1)
    {
    case 1:
      {
	switch (bits (insn1, 9, 10))
	  {
	  case 0:
	    if (bit (insn1, 6))
	      {
		/* Load/store {dual, exclusive}, table branch.  */
		if (bits (insn1, 7, 8) == 1 && bits (insn1, 4, 5) == 1
		    && bits (insn2, 5, 7) == 0)
		  err = thumb2_copy_table_branch (gdbarch, insn1, insn2, regs,
						  dsc);
		else
		  /* PC is not allowed to use in load/store {dual, exclusive}
		     instructions.  */
		  err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						     "load/store dual/ex", dsc);
	      }
	    else /* load/store multiple */
	      {
		switch (bits (insn1, 7, 8))
		  {
		  case 0: case 3: /* SRS, RFE */
		    err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						       "srs/rfe", dsc);
		    break;
		  case 1: case 2: /* LDM/STM/PUSH/POP */
		    err = thumb2_copy_block_xfer (gdbarch, insn1, insn2, regs, dsc);
		    break;
		  }
	      }
	    break;

	  case 1:
	    /* Data-processing (shift register).  */
	    err = thumb2_decode_dp_shift_reg (gdbarch, insn1, insn2, regs,
					      dsc);
	    break;
	  default: /* Coprocessor instructions.  */
	    err = thumb2_decode_svc_copro (gdbarch, insn1, insn2, regs, dsc);
	    break;
	  }
      break;
      }
    case 2: /* op1 = 2 */
      if (op) /* Branch and misc control.  */
	{
	  if (bit (insn2, 14)  /* BLX/BL */
	      || bit (insn2, 12) /* Unconditional branch */
	      || (bits (insn1, 7, 9) != 0x7)) /* Conditional branch */
	    err = thumb2_copy_b_bl_blx (gdbarch, insn1, insn2, regs, dsc);
	  else
	    err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					       "misc ctrl", dsc);
	}
      else
	{
	  if (bit (insn1, 9)) /* Data processing (plain binary imm).  */
	    {
	      int dp_op = bits (insn1, 4, 8);
	      int rn = bits (insn1, 0, 3);
	      if ((dp_op == 0 || dp_op == 0xa) && rn == 0xf)
		err = thumb_copy_pc_relative_32bit (gdbarch, insn1, insn2,
						    regs, dsc);
	      else
		err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						   "dp/pb", dsc);
	    }
	  else /* Data processing (modified immediate) */
	    err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					       "dp/mi", dsc);
	}
      break;
    case 3: /* op1 = 3 */
      switch (bits (insn1, 9, 10))
	{
	case 0:
	  if (bit (insn1, 4))
	    err = decode_thumb_32bit_ld_mem_hints (gdbarch, insn1, insn2,
						   regs, dsc);
	  else /* NEON Load/Store and Store single data item */
	    err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
					       "neon elt/struct load/store",
					       dsc);
	  break;
	case 1: /* op1 = 3, bits (9, 10) == 1 */
	  switch (bits (insn1, 7, 8))
	    {
	    case 0: case 1: /* Data processing (register) */
	      err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						 "dp(reg)", dsc);
	      break;
	    case 2: /* Multiply and absolute difference */
	      err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						 "mul/mua/diff", dsc);
	      break;
	    case 3: /* Long multiply and divide */
	      err = thumb_copy_unmodified_32bit (gdbarch, insn1, insn2,
						 "lmul/lmua", dsc);
	      break;
	    }
	  break;
	default: /* Coprocessor instructions */
	  err = thumb2_decode_svc_copro (gdbarch, insn1, insn2, regs, dsc);
	  break;
	}
      break;
    default:
      err = 1;
    }

  if (err)
    internal_error (__FILE__, __LINE__,
		    _("thumb_process_displaced_32bit_insn: Instruction decode error"));

}

static void
thumb_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
			      struct regcache *regs,
			      arm_displaced_step_copy_insn_closure *dsc)
{
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  uint16_t insn1
    = read_memory_unsigned_integer (from, 2, byte_order_for_code);

  displaced_debug_printf ("process thumb insn %.4x at %.8lx",
			  insn1, (unsigned long) from);

  dsc->is_thumb = 1;
  dsc->insn_size = thumb_insn_size (insn1);
  if (thumb_insn_size (insn1) == 4)
    {
      uint16_t insn2
	= read_memory_unsigned_integer (from + 2, 2, byte_order_for_code);
      thumb_process_displaced_32bit_insn (gdbarch, insn1, insn2, regs, dsc);
    }
  else
    thumb_process_displaced_16bit_insn (gdbarch, insn1, regs, dsc);
}

void
arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
			    CORE_ADDR to, struct regcache *regs,
			    arm_displaced_step_copy_insn_closure *dsc)
{
  int err = 0;
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  uint32_t insn;

  /* Most displaced instructions use a 1-instruction scratch space, so set this
     here and override below if/when necessary.  */
  dsc->numinsns = 1;
  dsc->insn_addr = from;
  dsc->scratch_base = to;
  dsc->cleanup = NULL;
  dsc->wrote_to_pc = 0;

  if (!displaced_in_arm_mode (regs))
    return thumb_process_displaced_insn (gdbarch, from, regs, dsc);

  dsc->is_thumb = 0;
  dsc->insn_size = 4;
  insn = read_memory_unsigned_integer (from, 4, byte_order_for_code);
  displaced_debug_printf ("stepping insn %.8lx at %.8lx",
			  (unsigned long) insn, (unsigned long) from);

  if ((insn & 0xf0000000) == 0xf0000000)
    err = arm_decode_unconditional (gdbarch, insn, regs, dsc);
  else switch (((insn & 0x10) >> 4) | ((insn & 0xe000000) >> 24))
    {
    case 0x0: case 0x1: case 0x2: case 0x3:
      err = arm_decode_dp_misc (gdbarch, insn, regs, dsc);
      break;

    case 0x4: case 0x5: case 0x6:
      err = arm_decode_ld_st_word_ubyte (gdbarch, insn, regs, dsc);
      break;

    case 0x7:
      err = arm_decode_media (gdbarch, insn, dsc);
      break;

    case 0x8: case 0x9: case 0xa: case 0xb:
      err = arm_decode_b_bl_ldmstm (gdbarch, insn, regs, dsc);
      break;

    case 0xc: case 0xd: case 0xe: case 0xf:
      err = arm_decode_svc_copro (gdbarch, insn, regs, dsc);
      break;
    }

  if (err)
    internal_error (__FILE__, __LINE__,
		    _("arm_process_displaced_insn: Instruction decode error"));
}

/* Actually set up the scratch space for a displaced instruction.  */

void
arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from,
			    CORE_ADDR to,
			    arm_displaced_step_copy_insn_closure *dsc)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  unsigned int i, len, offset;
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
  int size = dsc->is_thumb? 2 : 4;
  const gdb_byte *bkp_insn;

  offset = 0;
  /* Poke modified instruction(s).  */
  for (i = 0; i < dsc->numinsns; i++)
    {
      if (size == 4)
	displaced_debug_printf ("writing insn %.8lx at %.8lx",
				dsc->modinsn[i], (unsigned long) to + offset);
      else if (size == 2)
	displaced_debug_printf ("writing insn %.4x at %.8lx",
				(unsigned short) dsc->modinsn[i],
				(unsigned long) to + offset);

      write_memory_unsigned_integer (to + offset, size,
				     byte_order_for_code,
				     dsc->modinsn[i]);
      offset += size;
    }

  /* Choose the correct breakpoint instruction.  */
  if (dsc->is_thumb)
    {
      bkp_insn = tdep->thumb_breakpoint;
      len = tdep->thumb_breakpoint_size;
    }
  else
    {
      bkp_insn = tdep->arm_breakpoint;
      len = tdep->arm_breakpoint_size;
    }

  /* Put breakpoint afterwards.  */
  write_memory (to + offset, bkp_insn, len);

  displaced_debug_printf ("copy %s->%s", paddress (gdbarch, from),
			  paddress (gdbarch, to));
}

/* Entry point for cleaning things up after a displaced instruction has been
   single-stepped.  */

void
arm_displaced_step_fixup (struct gdbarch *gdbarch,
			  struct displaced_step_copy_insn_closure *dsc_,
			  CORE_ADDR from, CORE_ADDR to,
			  struct regcache *regs)
{
  arm_displaced_step_copy_insn_closure *dsc
    = (arm_displaced_step_copy_insn_closure *) dsc_;

  if (dsc->cleanup)
    dsc->cleanup (gdbarch, regs, dsc);

  if (!dsc->wrote_to_pc)
    regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM,
				    dsc->insn_addr + dsc->insn_size);

}

#include "bfd-in2.h"
#include "libcoff.h"

static int
gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info)
{
  gdb_disassembler *di
    = static_cast<gdb_disassembler *>(info->application_data);
  struct gdbarch *gdbarch = di->arch ();

  if (arm_pc_is_thumb (gdbarch, memaddr))
    {
      static asymbol *asym;
      static combined_entry_type ce;
      static struct coff_symbol_struct csym;
      static struct bfd fake_bfd;
      static bfd_target fake_target;

      if (csym.native == NULL)
	{
	  /* Create a fake symbol vector containing a Thumb symbol.
	     This is solely so that the code in print_insn_little_arm() 
	     and print_insn_big_arm() in opcodes/arm-dis.c will detect
	     the presence of a Thumb symbol and switch to decoding
	     Thumb instructions.  */

	  fake_target.flavour = bfd_target_coff_flavour;
	  fake_bfd.xvec = &fake_target;
	  ce.u.syment.n_sclass = C_THUMBEXTFUNC;
	  csym.native = &ce;
	  csym.symbol.the_bfd = &fake_bfd;
	  csym.symbol.name = "fake";
	  asym = (asymbol *) & csym;
	}

      memaddr = UNMAKE_THUMB_ADDR (memaddr);
      info->symbols = &asym;
    }
  else
    info->symbols = NULL;

  /* GDB is able to get bfd_mach from the exe_bfd, info->mach is
     accurate, so mark USER_SPECIFIED_MACHINE_TYPE bit.  Otherwise,
     opcodes/arm-dis.c:print_insn reset info->mach, and it will trigger
     the assert on the mismatch of info->mach and
     bfd_get_mach (current_program_space->exec_bfd ()) in
     default_print_insn.  */
  if (current_program_space->exec_bfd () != NULL
      && (current_program_space->exec_bfd ()->arch_info
	  == gdbarch_bfd_arch_info (gdbarch)))
    info->flags |= USER_SPECIFIED_MACHINE_TYPE;

  return default_print_insn (memaddr, info);
}

/* The following define instruction sequences that will cause ARM
   cpu's to take an undefined instruction trap.  These are used to
   signal a breakpoint to GDB.
   
   The newer ARMv4T cpu's are capable of operating in ARM or Thumb
   modes.  A different instruction is required for each mode.  The ARM
   cpu's can also be big or little endian.  Thus four different
   instructions are needed to support all cases.
   
   Note: ARMv4 defines several new instructions that will take the
   undefined instruction trap.  ARM7TDMI is nominally ARMv4T, but does
   not in fact add the new instructions.  The new undefined
   instructions in ARMv4 are all instructions that had no defined
   behaviour in earlier chips.  There is no guarantee that they will
   raise an exception, but may be treated as NOP's.  In practice, it
   may only safe to rely on instructions matching:
   
   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 
   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
   C C C C 0 1 1 x x x x x x x x x x x x x x x x x x x x 1 x x x x
   
   Even this may only true if the condition predicate is true.  The
   following use a condition predicate of ALWAYS so it is always TRUE.
   
   There are other ways of forcing a breakpoint.  GNU/Linux, RISC iX,
   and NetBSD all use a software interrupt rather than an undefined
   instruction to force a trap.  This can be handled by by the
   abi-specific code during establishment of the gdbarch vector.  */

#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7}
#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE}
#define THUMB_LE_BREAKPOINT {0xbe,0xbe}
#define THUMB_BE_BREAKPOINT {0xbe,0xbe}

static const gdb_byte arm_default_arm_le_breakpoint[] = ARM_LE_BREAKPOINT;
static const gdb_byte arm_default_arm_be_breakpoint[] = ARM_BE_BREAKPOINT;
static const gdb_byte arm_default_thumb_le_breakpoint[] = THUMB_LE_BREAKPOINT;
static const gdb_byte arm_default_thumb_be_breakpoint[] = THUMB_BE_BREAKPOINT;

/* Implement the breakpoint_kind_from_pc gdbarch method.  */

static int
arm_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);

  if (arm_pc_is_thumb (gdbarch, *pcptr))
    {
      *pcptr = UNMAKE_THUMB_ADDR (*pcptr);

      /* If we have a separate 32-bit breakpoint instruction for Thumb-2,
	 check whether we are replacing a 32-bit instruction.  */
      if (tdep->thumb2_breakpoint != NULL)
	{
	  gdb_byte buf[2];

	  if (target_read_memory (*pcptr, buf, 2) == 0)
	    {
	      unsigned short inst1;

	      inst1 = extract_unsigned_integer (buf, 2, byte_order_for_code);
	      if (thumb_insn_size (inst1) == 4)
		return ARM_BP_KIND_THUMB2;
	    }
	}

      return ARM_BP_KIND_THUMB;
    }
  else
    return ARM_BP_KIND_ARM;

}

/* Implement the sw_breakpoint_from_kind gdbarch method.  */

static const gdb_byte *
arm_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  switch (kind)
    {
    case ARM_BP_KIND_ARM:
      *size = tdep->arm_breakpoint_size;
      return tdep->arm_breakpoint;
    case ARM_BP_KIND_THUMB:
      *size = tdep->thumb_breakpoint_size;
      return tdep->thumb_breakpoint;
    case ARM_BP_KIND_THUMB2:
      *size = tdep->thumb2_breakpoint_size;
      return tdep->thumb2_breakpoint;
    default:
      gdb_assert_not_reached ("unexpected arm breakpoint kind");
    }
}

/* Implement the breakpoint_kind_from_current_state gdbarch method.  */

static int
arm_breakpoint_kind_from_current_state (struct gdbarch *gdbarch,
					struct regcache *regcache,
					CORE_ADDR *pcptr)
{
  gdb_byte buf[4];

  /* Check the memory pointed by PC is readable.  */
  if (target_read_memory (regcache_read_pc (regcache), buf, 4) == 0)
    {
      struct arm_get_next_pcs next_pcs_ctx;

      arm_get_next_pcs_ctor (&next_pcs_ctx,
			     &arm_get_next_pcs_ops,
			     gdbarch_byte_order (gdbarch),
			     gdbarch_byte_order_for_code (gdbarch),
			     0,
			     regcache);

      std::vector<CORE_ADDR> next_pcs = arm_get_next_pcs (&next_pcs_ctx);

      /* If MEMADDR is the next instruction of current pc, do the
	 software single step computation, and get the thumb mode by
	 the destination address.  */
      for (CORE_ADDR pc : next_pcs)
	{
	  if (UNMAKE_THUMB_ADDR (pc) == *pcptr)
	    {
	      if (IS_THUMB_ADDR (pc))
		{
		  *pcptr = MAKE_THUMB_ADDR (*pcptr);
		  return arm_breakpoint_kind_from_pc (gdbarch, pcptr);
		}
	      else
		return ARM_BP_KIND_ARM;
	    }
	}
    }

  return arm_breakpoint_kind_from_pc (gdbarch, pcptr);
}

/* Extract from an array REGBUF containing the (raw) register state a
   function return value of type TYPE, and copy that, in virtual
   format, into VALBUF.  */

static void
arm_extract_return_value (struct type *type, struct regcache *regs,
			  gdb_byte *valbuf)
{
  struct gdbarch *gdbarch = regs->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (TYPE_CODE_FLT == type->code ())
    {
      switch (tdep->fp_model)
	{
	case ARM_FLOAT_FPA:
	  {
	    /* The value is in register F0 in internal format.  We need to
	       extract the raw value and then convert it to the desired
	       internal type.  */
	    bfd_byte tmpbuf[ARM_FP_REGISTER_SIZE];

	    regs->cooked_read (ARM_F0_REGNUM, tmpbuf);
	    target_float_convert (tmpbuf, arm_ext_type (gdbarch),
				  valbuf, type);
	  }
	  break;

	case ARM_FLOAT_SOFT_FPA:
	case ARM_FLOAT_SOFT_VFP:
	  /* ARM_FLOAT_VFP can arise if this is a variadic function so
	     not using the VFP ABI code.  */
	case ARM_FLOAT_VFP:
	  regs->cooked_read (ARM_A1_REGNUM, valbuf);
	  if (TYPE_LENGTH (type) > 4)
	    regs->cooked_read (ARM_A1_REGNUM + 1,
			       valbuf + ARM_INT_REGISTER_SIZE);
	  break;

	default:
	  internal_error (__FILE__, __LINE__,
			  _("arm_extract_return_value: "
			    "Floating point model not supported"));
	  break;
	}
    }
  else if (type->code () == TYPE_CODE_INT
	   || type->code () == TYPE_CODE_CHAR
	   || type->code () == TYPE_CODE_BOOL
	   || type->code () == TYPE_CODE_PTR
	   || TYPE_IS_REFERENCE (type)
	   || type->code () == TYPE_CODE_ENUM)
    {
      /* If the type is a plain integer, then the access is
	 straight-forward.  Otherwise we have to play around a bit
	 more.  */
      int len = TYPE_LENGTH (type);
      int regno = ARM_A1_REGNUM;
      ULONGEST tmp;

      while (len > 0)
	{
	  /* By using store_unsigned_integer we avoid having to do
	     anything special for small big-endian values.  */
	  regcache_cooked_read_unsigned (regs, regno++, &tmp);
	  store_unsigned_integer (valbuf, 
				  (len > ARM_INT_REGISTER_SIZE
				   ? ARM_INT_REGISTER_SIZE : len),
				  byte_order, tmp);
	  len -= ARM_INT_REGISTER_SIZE;
	  valbuf += ARM_INT_REGISTER_SIZE;
	}
    }
  else
    {
      /* For a structure or union the behaviour is as if the value had
	 been stored to word-aligned memory and then loaded into 
	 registers with 32-bit load instruction(s).  */
      int len = TYPE_LENGTH (type);
      int regno = ARM_A1_REGNUM;
      bfd_byte tmpbuf[ARM_INT_REGISTER_SIZE];

      while (len > 0)
	{
	  regs->cooked_read (regno++, tmpbuf);
	  memcpy (valbuf, tmpbuf,
		  len > ARM_INT_REGISTER_SIZE ? ARM_INT_REGISTER_SIZE : len);
	  len -= ARM_INT_REGISTER_SIZE;
	  valbuf += ARM_INT_REGISTER_SIZE;
	}
    }
}


/* Will a function return an aggregate type in memory or in a
   register?  Return 0 if an aggregate type can be returned in a
   register, 1 if it must be returned in memory.  */

static int
arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
{
  enum type_code code;

  type = check_typedef (type);

  /* Simple, non-aggregate types (ie not including vectors and
     complex) are always returned in a register (or registers).  */
  code = type->code ();
  if (TYPE_CODE_STRUCT != code && TYPE_CODE_UNION != code
      && TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code)
    return 0;

  if (TYPE_CODE_ARRAY == code && type->is_vector ())
    {
      /* Vector values should be returned using ARM registers if they
	 are not over 16 bytes.  */
      return (TYPE_LENGTH (type) > 16);
    }

  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  if (tdep->arm_abi != ARM_ABI_APCS)
    {
      /* The AAPCS says all aggregates not larger than a word are returned
	 in a register.  */
      if (TYPE_LENGTH (type) <= ARM_INT_REGISTER_SIZE)
	return 0;

      return 1;
    }
  else
    {
      int nRc;

      /* All aggregate types that won't fit in a register must be returned
	 in memory.  */
      if (TYPE_LENGTH (type) > ARM_INT_REGISTER_SIZE)
	return 1;

      /* In the ARM ABI, "integer" like aggregate types are returned in
	 registers.  For an aggregate type to be integer like, its size
	 must be less than or equal to ARM_INT_REGISTER_SIZE and the
	 offset of each addressable subfield must be zero.  Note that bit
	 fields are not addressable, and all addressable subfields of
	 unions always start at offset zero.

	 This function is based on the behaviour of GCC 2.95.1.
	 See: gcc/arm.c: arm_return_in_memory() for details.

	 Note: All versions of GCC before GCC 2.95.2 do not set up the
	 parameters correctly for a function returning the following
	 structure: struct { float f;}; This should be returned in memory,
	 not a register.  Richard Earnshaw sent me a patch, but I do not
	 know of any way to detect if a function like the above has been
	 compiled with the correct calling convention.  */

      /* Assume all other aggregate types can be returned in a register.
	 Run a check for structures, unions and arrays.  */
      nRc = 0;

      if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code))
	{
	  int i;
	  /* Need to check if this struct/union is "integer" like.  For
	     this to be true, its size must be less than or equal to
	     ARM_INT_REGISTER_SIZE and the offset of each addressable
	     subfield must be zero.  Note that bit fields are not
	     addressable, and unions always start at offset zero.  If any
	     of the subfields is a floating point type, the struct/union
	     cannot be an integer type.  */

	  /* For each field in the object, check:
	     1) Is it FP? --> yes, nRc = 1;
	     2) Is it addressable (bitpos != 0) and
	     not packed (bitsize == 0)?
	     --> yes, nRc = 1
	  */

	  for (i = 0; i < type->num_fields (); i++)
	    {
	      enum type_code field_type_code;

	      field_type_code
		= check_typedef (type->field (i).type ())->code ();

	      /* Is it a floating point type field?  */
	      if (field_type_code == TYPE_CODE_FLT)
		{
		  nRc = 1;
		  break;
		}

	      /* If bitpos != 0, then we have to care about it.  */
	      if (type->field (i).loc_bitpos () != 0)
		{
		  /* Bitfields are not addressable.  If the field bitsize is 
		     zero, then the field is not packed.  Hence it cannot be
		     a bitfield or any other packed type.  */
		  if (TYPE_FIELD_BITSIZE (type, i) == 0)
		    {
		      nRc = 1;
		      break;
		    }
		}
	    }
	}

      return nRc;
    }
}

/* Write into appropriate registers a function return value of type
   TYPE, given in virtual format.  */

static void
arm_store_return_value (struct type *type, struct regcache *regs,
			const gdb_byte *valbuf)
{
  struct gdbarch *gdbarch = regs->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  if (type->code () == TYPE_CODE_FLT)
    {
      gdb_byte buf[ARM_FP_REGISTER_SIZE];
      arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

      switch (tdep->fp_model)
	{
	case ARM_FLOAT_FPA:

	  target_float_convert (valbuf, type, buf, arm_ext_type (gdbarch));
	  regs->cooked_write (ARM_F0_REGNUM, buf);
	  break;

	case ARM_FLOAT_SOFT_FPA:
	case ARM_FLOAT_SOFT_VFP:
	  /* ARM_FLOAT_VFP can arise if this is a variadic function so
	     not using the VFP ABI code.  */
	case ARM_FLOAT_VFP:
	  regs->cooked_write (ARM_A1_REGNUM, valbuf);
	  if (TYPE_LENGTH (type) > 4)
	    regs->cooked_write (ARM_A1_REGNUM + 1,
				valbuf + ARM_INT_REGISTER_SIZE);
	  break;

	default:
	  internal_error (__FILE__, __LINE__,
			  _("arm_store_return_value: Floating "
			    "point model not supported"));
	  break;
	}
    }
  else if (type->code () == TYPE_CODE_INT
	   || type->code () == TYPE_CODE_CHAR
	   || type->code () == TYPE_CODE_BOOL
	   || type->code () == TYPE_CODE_PTR
	   || TYPE_IS_REFERENCE (type)
	   || type->code () == TYPE_CODE_ENUM)
    {
      if (TYPE_LENGTH (type) <= 4)
	{
	  /* Values of one word or less are zero/sign-extended and
	     returned in r0.  */
	  bfd_byte tmpbuf[ARM_INT_REGISTER_SIZE];
	  LONGEST val = unpack_long (type, valbuf);

	  store_signed_integer (tmpbuf, ARM_INT_REGISTER_SIZE, byte_order, val);
	  regs->cooked_write (ARM_A1_REGNUM, tmpbuf);
	}
      else
	{
	  /* Integral values greater than one word are stored in consecutive
	     registers starting with r0.  This will always be a multiple of
	     the regiser size.  */
	  int len = TYPE_LENGTH (type);
	  int regno = ARM_A1_REGNUM;

	  while (len > 0)
	    {
	      regs->cooked_write (regno++, valbuf);
	      len -= ARM_INT_REGISTER_SIZE;
	      valbuf += ARM_INT_REGISTER_SIZE;
	    }
	}
    }
  else
    {
      /* For a structure or union the behaviour is as if the value had
	 been stored to word-aligned memory and then loaded into 
	 registers with 32-bit load instruction(s).  */
      int len = TYPE_LENGTH (type);
      int regno = ARM_A1_REGNUM;
      bfd_byte tmpbuf[ARM_INT_REGISTER_SIZE];

      while (len > 0)
	{
	  memcpy (tmpbuf, valbuf,
		  len > ARM_INT_REGISTER_SIZE ? ARM_INT_REGISTER_SIZE : len);
	  regs->cooked_write (regno++, tmpbuf);
	  len -= ARM_INT_REGISTER_SIZE;
	  valbuf += ARM_INT_REGISTER_SIZE;
	}
    }
}


/* Handle function return values.  */

static enum return_value_convention
arm_return_value (struct gdbarch *gdbarch, struct value *function,
		  struct type *valtype, struct regcache *regcache,
		  gdb_byte *readbuf, const gdb_byte *writebuf)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  struct type *func_type = function ? value_type (function) : NULL;
  enum arm_vfp_cprc_base_type vfp_base_type;
  int vfp_base_count;

  if (arm_vfp_abi_for_function (gdbarch, func_type)
      && arm_vfp_call_candidate (valtype, &vfp_base_type, &vfp_base_count))
    {
      int reg_char = arm_vfp_cprc_reg_char (vfp_base_type);
      int unit_length = arm_vfp_cprc_unit_length (vfp_base_type);
      int i;
      for (i = 0; i < vfp_base_count; i++)
	{
	  if (reg_char == 'q')
	    {
	      if (writebuf)
		arm_neon_quad_write (gdbarch, regcache, i,
				     writebuf + i * unit_length);

	      if (readbuf)
		arm_neon_quad_read (gdbarch, regcache, i,
				    readbuf + i * unit_length);
	    }
	  else
	    {
	      char name_buf[4];
	      int regnum;

	      xsnprintf (name_buf, sizeof (name_buf), "%c%d", reg_char, i);
	      regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
						    strlen (name_buf));
	      if (writebuf)
		regcache->cooked_write (regnum, writebuf + i * unit_length);
	      if (readbuf)
		regcache->cooked_read (regnum, readbuf + i * unit_length);
	    }
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }

  if (valtype->code () == TYPE_CODE_STRUCT
      || valtype->code () == TYPE_CODE_UNION
      || valtype->code () == TYPE_CODE_ARRAY)
    {
      if (tdep->struct_return == pcc_struct_return
	  || arm_return_in_memory (gdbarch, valtype))
	return RETURN_VALUE_STRUCT_CONVENTION;
    }
  else if (valtype->code () == TYPE_CODE_COMPLEX)
    {
      if (arm_return_in_memory (gdbarch, valtype))
	return RETURN_VALUE_STRUCT_CONVENTION;
    }

  if (writebuf)
    arm_store_return_value (valtype, regcache, writebuf);

  if (readbuf)
    arm_extract_return_value (valtype, regcache, readbuf);

  return RETURN_VALUE_REGISTER_CONVENTION;
}


static int
arm_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR jb_addr;
  gdb_byte buf[ARM_INT_REGISTER_SIZE];
  
  jb_addr = get_frame_register_unsigned (frame, ARM_A1_REGNUM);

  if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
			  ARM_INT_REGISTER_SIZE))
    return 0;

  *pc = extract_unsigned_integer (buf, ARM_INT_REGISTER_SIZE, byte_order);
  return 1;
}
/* A call to cmse secure entry function "foo" at "a" is modified by
     GNU ld as "b".
     a) bl xxxx <foo>

     <foo>
     xxxx:

     b) bl yyyy <__acle_se_foo>

     section .gnu.sgstubs:
     <foo>
     yyyy: sg   // secure gateway
	   b.w xxxx <__acle_se_foo>  // original_branch_dest

     <__acle_se_foo>
     xxxx:

  When the control at "b", the pc contains "yyyy" (sg address) which is a
  trampoline and does not exist in source code.  This function returns the
  target pc "xxxx".  For more details please refer to section 5.4
  (Entry functions) and section 3.4.4 (C level development flow of secure code)
  of "armv8-m-security-extensions-requirements-on-development-tools-engineering-specification"
  document on www.developer.arm.com.  */

static CORE_ADDR
arm_skip_cmse_entry (CORE_ADDR pc, const char *name, struct objfile *objfile)
{
  int target_len = strlen (name) + strlen ("__acle_se_") + 1;
  char *target_name = (char *) alloca (target_len);
  xsnprintf (target_name, target_len, "%s%s", "__acle_se_", name);

  struct bound_minimal_symbol minsym
   = lookup_minimal_symbol (target_name, NULL, objfile);

  if (minsym.minsym != nullptr)
    return BMSYMBOL_VALUE_ADDRESS (minsym);

  return 0;
}

/* Return true when SEC points to ".gnu.sgstubs" section.  */

static bool
arm_is_sgstubs_section (struct obj_section *sec)
{
  return (sec != nullptr
	  && sec->the_bfd_section != nullptr
	  && sec->the_bfd_section->name != nullptr
	  && streq (sec->the_bfd_section->name, ".gnu.sgstubs"));
}

/* Recognize GCC and GNU ld's trampolines.  If we are in a trampoline,
   return the target PC.  Otherwise return 0.  */

CORE_ADDR
arm_skip_stub (struct frame_info *frame, CORE_ADDR pc)
{
  const char *name;
  int namelen;
  CORE_ADDR start_addr;

  /* Find the starting address and name of the function containing the PC.  */
  if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
    {
      /* Trampoline 'bx reg' doesn't belong to any functions.  Do the
	 check here.  */
      start_addr = arm_skip_bx_reg (frame, pc);
      if (start_addr != 0)
	return start_addr;

      return 0;
    }

  /* If PC is in a Thumb call or return stub, return the address of the
     target PC, which is in a register.  The thunk functions are called
     _call_via_xx, where x is the register name.  The possible names
     are r0-r9, sl, fp, ip, sp, and lr.  ARM RealView has similar
     functions, named __ARM_call_via_r[0-7].  */
  if (startswith (name, "_call_via_")
      || startswith (name, "__ARM_call_via_"))
    {
      /* Use the name suffix to determine which register contains the
	 target PC.  */
      static const char *table[15] =
      {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
       "r8", "r9", "sl", "fp", "ip", "sp", "lr"
      };
      int regno;
      int offset = strlen (name) - 2;

      for (regno = 0; regno <= 14; regno++)
	if (strcmp (&name[offset], table[regno]) == 0)
	  return get_frame_register_unsigned (frame, regno);
    }

  /* GNU ld generates __foo_from_arm or __foo_from_thumb for
     non-interworking calls to foo.  We could decode the stubs
     to find the target but it's easier to use the symbol table.  */
  namelen = strlen (name);
  if (name[0] == '_' && name[1] == '_'
      && ((namelen > 2 + strlen ("_from_thumb")
	   && startswith (name + namelen - strlen ("_from_thumb"), "_from_thumb"))
	  || (namelen > 2 + strlen ("_from_arm")
	      && startswith (name + namelen - strlen ("_from_arm"), "_from_arm"))))
    {
      char *target_name;
      int target_len = namelen - 2;
      struct bound_minimal_symbol minsym;
      struct objfile *objfile;
      struct obj_section *sec;

      if (name[namelen - 1] == 'b')
	target_len -= strlen ("_from_thumb");
      else
	target_len -= strlen ("_from_arm");

      target_name = (char *) alloca (target_len + 1);
      memcpy (target_name, name + 2, target_len);
      target_name[target_len] = '\0';

      sec = find_pc_section (pc);
      objfile = (sec == NULL) ? NULL : sec->objfile;
      minsym = lookup_minimal_symbol (target_name, NULL, objfile);
      if (minsym.minsym != NULL)
	return BMSYMBOL_VALUE_ADDRESS (minsym);
      else
	return 0;
    }

  struct obj_section *section = find_pc_section (pc);

  /* Check whether SECTION points to the ".gnu.sgstubs" section.  */
  if (arm_is_sgstubs_section (section))
    return arm_skip_cmse_entry (pc, name, section->objfile);

  return 0;			/* not a stub */
}

static void
arm_update_current_architecture (void)
{
  /* If the current architecture is not ARM, we have nothing to do.  */
  if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_arm)
    return;

  /* Update the architecture.  */
  gdbarch_info info;
  if (!gdbarch_update_p (info))
    internal_error (__FILE__, __LINE__, _("could not update architecture"));
}

static void
set_fp_model_sfunc (const char *args, int from_tty,
		    struct cmd_list_element *c)
{
  int fp_model;

  for (fp_model = ARM_FLOAT_AUTO; fp_model != ARM_FLOAT_LAST; fp_model++)
    if (strcmp (current_fp_model, fp_model_strings[fp_model]) == 0)
      {
	arm_fp_model = (enum arm_float_model) fp_model;
	break;
      }

  if (fp_model == ARM_FLOAT_LAST)
    internal_error (__FILE__, __LINE__, _("Invalid fp model accepted: %s."),
		    current_fp_model);

  arm_update_current_architecture ();
}

static void
show_fp_model (struct ui_file *file, int from_tty,
	       struct cmd_list_element *c, const char *value)
{
  arm_gdbarch_tdep *tdep
    = (arm_gdbarch_tdep *) gdbarch_tdep (target_gdbarch ());

  if (arm_fp_model == ARM_FLOAT_AUTO
      && gdbarch_bfd_arch_info (target_gdbarch ())->arch == bfd_arch_arm)
    fprintf_filtered (file, _("\
The current ARM floating point model is \"auto\" (currently \"%s\").\n"),
		      fp_model_strings[tdep->fp_model]);
  else
    fprintf_filtered (file, _("\
The current ARM floating point model is \"%s\".\n"),
		      fp_model_strings[arm_fp_model]);
}

static void
arm_set_abi (const char *args, int from_tty,
	     struct cmd_list_element *c)
{
  int arm_abi;

  for (arm_abi = ARM_ABI_AUTO; arm_abi != ARM_ABI_LAST; arm_abi++)
    if (strcmp (arm_abi_string, arm_abi_strings[arm_abi]) == 0)
      {
	arm_abi_global = (enum arm_abi_kind) arm_abi;
	break;
      }

  if (arm_abi == ARM_ABI_LAST)
    internal_error (__FILE__, __LINE__, _("Invalid ABI accepted: %s."),
		    arm_abi_string);

  arm_update_current_architecture ();
}

static void
arm_show_abi (struct ui_file *file, int from_tty,
	     struct cmd_list_element *c, const char *value)
{
  arm_gdbarch_tdep *tdep
    = (arm_gdbarch_tdep *) gdbarch_tdep (target_gdbarch ());

  if (arm_abi_global == ARM_ABI_AUTO
      && gdbarch_bfd_arch_info (target_gdbarch ())->arch == bfd_arch_arm)
    fprintf_filtered (file, _("\
The current ARM ABI is \"auto\" (currently \"%s\").\n"),
		      arm_abi_strings[tdep->arm_abi]);
  else
    fprintf_filtered (file, _("The current ARM ABI is \"%s\".\n"),
		      arm_abi_string);
}

static void
arm_show_fallback_mode (struct ui_file *file, int from_tty,
			struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("The current execution mode assumed "
		      "(when symbols are unavailable) is \"%s\".\n"),
		    arm_fallback_mode_string);
}

static void
arm_show_force_mode (struct ui_file *file, int from_tty,
		     struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("The current execution mode assumed "
		      "(even when symbols are available) is \"%s\".\n"),
		    arm_force_mode_string);
}

/* If the user changes the register disassembly style used for info
   register and other commands, we have to also switch the style used
   in opcodes for disassembly output.  This function is run in the "set
   arm disassembly" command, and does that.  */

static void
set_disassembly_style_sfunc (const char *args, int from_tty,
			     struct cmd_list_element *c)
{
  /* Convert the short style name into the long style name (eg, reg-names-*)
     before calling the generic set_disassembler_options() function.  */
  std::string long_name = std::string ("reg-names-") + disassembly_style;
  set_disassembler_options (&long_name[0]);
}

static void
show_disassembly_style_sfunc (struct ui_file *file, int from_tty,
			      struct cmd_list_element *c, const char *value)
{
  struct gdbarch *gdbarch = get_current_arch ();
  char *options = get_disassembler_options (gdbarch);
  const char *style = "";
  int len = 0;
  const char *opt;

  FOR_EACH_DISASSEMBLER_OPTION (opt, options)
    if (startswith (opt, "reg-names-"))
      {
	style = &opt[strlen ("reg-names-")];
	len = strcspn (style, ",");
      }

  fprintf_unfiltered (file, "The disassembly style is \"%.*s\".\n", len, style);
}

/* Return the ARM register name corresponding to register I.  */
static const char *
arm_register_name (struct gdbarch *gdbarch, int i)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (is_s_pseudo (gdbarch, i))
    {
      static const char *const s_pseudo_names[] = {
	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
	"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
	"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
	"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
      };

      return s_pseudo_names[i - tdep->s_pseudo_base];
    }

  if (is_q_pseudo (gdbarch, i))
    {
      static const char *const q_pseudo_names[] = {
	"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
	"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
      };

      return q_pseudo_names[i - tdep->q_pseudo_base];
    }

  if (is_mve_pseudo (gdbarch, i))
    return "p0";

  if (i >= ARRAY_SIZE (arm_register_names))
    /* These registers are only supported on targets which supply
       an XML description.  */
    return "";

  /* Non-pseudo registers.  */
  return arm_register_names[i];
}

/* Test whether the coff symbol specific value corresponds to a Thumb
   function.  */

static int
coff_sym_is_thumb (int val)
{
  return (val == C_THUMBEXT
	  || val == C_THUMBSTAT
	  || val == C_THUMBEXTFUNC
	  || val == C_THUMBSTATFUNC
	  || val == C_THUMBLABEL);
}

/* arm_coff_make_msymbol_special()
   arm_elf_make_msymbol_special()
   
   These functions test whether the COFF or ELF symbol corresponds to
   an address in thumb code, and set a "special" bit in a minimal
   symbol to indicate that it does.  */
   
static void
arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym)
{
  elf_symbol_type *elfsym = (elf_symbol_type *) sym;

  if (ARM_GET_SYM_BRANCH_TYPE (elfsym->internal_elf_sym.st_target_internal)
      == ST_BRANCH_TO_THUMB)
    MSYMBOL_SET_SPECIAL (msym);
}

static void
arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym)
{
  if (coff_sym_is_thumb (val))
    MSYMBOL_SET_SPECIAL (msym);
}

static void
arm_record_special_symbol (struct gdbarch *gdbarch, struct objfile *objfile,
			   asymbol *sym)
{
  const char *name = bfd_asymbol_name (sym);
  struct arm_per_bfd *data;
  struct arm_mapping_symbol new_map_sym;

  gdb_assert (name[0] == '$');
  if (name[1] != 'a' && name[1] != 't' && name[1] != 'd')
    return;

  data = arm_bfd_data_key.get (objfile->obfd);
  if (data == NULL)
    data = arm_bfd_data_key.emplace (objfile->obfd,
				     objfile->obfd->section_count);
  arm_mapping_symbol_vec &map
    = data->section_maps[bfd_asymbol_section (sym)->index];

  new_map_sym.value = sym->value;
  new_map_sym.type = name[1];

  /* Insert at the end, the vector will be sorted on first use.  */
  map.push_back (new_map_sym);
}

static void
arm_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = regcache->arch ();
  regcache_cooked_write_unsigned (regcache, ARM_PC_REGNUM, pc);

  /* If necessary, set the T bit.  */
  if (arm_apcs_32)
    {
      ULONGEST val, t_bit;
      regcache_cooked_read_unsigned (regcache, ARM_PS_REGNUM, &val);
      t_bit = arm_psr_thumb_bit (gdbarch);
      if (arm_pc_is_thumb (gdbarch, pc))
	regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM,
					val | t_bit);
      else
	regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM,
					val & ~t_bit);
    }
}

/* Read the contents of a NEON quad register, by reading from two
   double registers.  This is used to implement the quad pseudo
   registers, and for argument passing in case the quad registers are
   missing; vectors are passed in quad registers when using the VFP
   ABI, even if a NEON unit is not present.  REGNUM is the index of
   the quad register, in [0, 15].  */

static enum register_status
arm_neon_quad_read (struct gdbarch *gdbarch, readable_regcache *regcache,
		    int regnum, gdb_byte *buf)
{
  char name_buf[4];
  gdb_byte reg_buf[8];
  int offset, double_regnum;
  enum register_status status;

  xsnprintf (name_buf, sizeof (name_buf), "d%d", regnum << 1);
  double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
					       strlen (name_buf));

  /* d0 is always the least significant half of q0.  */
  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
    offset = 8;
  else
    offset = 0;

  status = regcache->raw_read (double_regnum, reg_buf);
  if (status != REG_VALID)
    return status;
  memcpy (buf + offset, reg_buf, 8);

  offset = 8 - offset;
  status = regcache->raw_read (double_regnum + 1, reg_buf);
  if (status != REG_VALID)
    return status;
  memcpy (buf + offset, reg_buf, 8);

  return REG_VALID;
}

/* Read the contents of the MVE pseudo register REGNUM and store it
   in BUF.  */

static enum register_status
arm_mve_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
		     int regnum, gdb_byte *buf)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* P0 is the first 16 bits of VPR.  */
  return regcache->raw_read_part (tdep->mve_vpr_regnum, 0, 2, buf);
}

static enum register_status
arm_pseudo_read (struct gdbarch *gdbarch, readable_regcache *regcache,
		 int regnum, gdb_byte *buf)
{
  const int num_regs = gdbarch_num_regs (gdbarch);
  char name_buf[4];
  gdb_byte reg_buf[8];
  int offset, double_regnum;
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  gdb_assert (regnum >= num_regs);

  if (is_q_pseudo (gdbarch, regnum))
    {
      /* Quad-precision register.  */
      return arm_neon_quad_read (gdbarch, regcache,
				 regnum - tdep->q_pseudo_base, buf);
    }
  else if (is_mve_pseudo (gdbarch, regnum))
    return arm_mve_pseudo_read (gdbarch, regcache, regnum, buf);
  else
    {
      enum register_status status;

      regnum -= tdep->s_pseudo_base;
      /* Single-precision register.  */
      gdb_assert (regnum < 32);

      /* s0 is always the least significant half of d0.  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	offset = (regnum & 1) ? 0 : 4;
      else
	offset = (regnum & 1) ? 4 : 0;

      xsnprintf (name_buf, sizeof (name_buf), "d%d", regnum >> 1);
      double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
						   strlen (name_buf));

      status = regcache->raw_read (double_regnum, reg_buf);
      if (status == REG_VALID)
	memcpy (buf, reg_buf + offset, 4);
      return status;
    }
}

/* Store the contents of BUF to a NEON quad register, by writing to
   two double registers.  This is used to implement the quad pseudo
   registers, and for argument passing in case the quad registers are
   missing; vectors are passed in quad registers when using the VFP
   ABI, even if a NEON unit is not present.  REGNUM is the index
   of the quad register, in [0, 15].  */

static void
arm_neon_quad_write (struct gdbarch *gdbarch, struct regcache *regcache,
		     int regnum, const gdb_byte *buf)
{
  char name_buf[4];
  int offset, double_regnum;

  xsnprintf (name_buf, sizeof (name_buf), "d%d", regnum << 1);
  double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
					       strlen (name_buf));

  /* d0 is always the least significant half of q0.  */
  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
    offset = 8;
  else
    offset = 0;

  regcache->raw_write (double_regnum, buf + offset);
  offset = 8 - offset;
  regcache->raw_write (double_regnum + 1, buf + offset);
}

/* Store the contents of BUF to the MVE pseudo register REGNUM.  */

static void
arm_mve_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
		      int regnum, const gdb_byte *buf)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  /* P0 is the first 16 bits of VPR.  */
  regcache->raw_write_part (tdep->mve_vpr_regnum, 0, 2, buf);
}

static void
arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
		  int regnum, const gdb_byte *buf)
{
  const int num_regs = gdbarch_num_regs (gdbarch);
  char name_buf[4];
  gdb_byte reg_buf[8];
  int offset, double_regnum;
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  gdb_assert (regnum >= num_regs);

  if (is_q_pseudo (gdbarch, regnum))
    {
      /* Quad-precision register.  */
      arm_neon_quad_write (gdbarch, regcache,
			   regnum - tdep->q_pseudo_base, buf);
    }
  else if (is_mve_pseudo (gdbarch, regnum))
    arm_mve_pseudo_write (gdbarch, regcache, regnum, buf);
  else
    {
      regnum -= tdep->s_pseudo_base;
      /* Single-precision register.  */
      gdb_assert (regnum < 32);

      /* s0 is always the least significant half of d0.  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	offset = (regnum & 1) ? 0 : 4;
      else
	offset = (regnum & 1) ? 4 : 0;

      xsnprintf (name_buf, sizeof (name_buf), "d%d", regnum >> 1);
      double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
						   strlen (name_buf));

      regcache->raw_read (double_regnum, reg_buf);
      memcpy (reg_buf + offset, buf, 4);
      regcache->raw_write (double_regnum, reg_buf);
    }
}

static struct value *
value_of_arm_user_reg (struct frame_info *frame, const void *baton)
{
  const int *reg_p = (const int *) baton;
  return value_of_register (*reg_p, frame);
}

static enum gdb_osabi
arm_elf_osabi_sniffer (bfd *abfd)
{
  unsigned int elfosabi;
  enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;

  elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];

  if (elfosabi == ELFOSABI_ARM)
    /* GNU tools use this value.  Check note sections in this case,
       as well.  */
    {
      for (asection *sect : gdb_bfd_sections (abfd))
	generic_elf_osabi_sniff_abi_tag_sections (abfd, sect, &osabi);
    }

  /* Anything else will be handled by the generic ELF sniffer.  */
  return osabi;
}

static int
arm_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			  struct reggroup *group)
{
  /* FPS register's type is INT, but belongs to float_reggroup.  Beside
     this, FPS register belongs to save_regroup, restore_reggroup, and
     all_reggroup, of course.  */
  if (regnum == ARM_FPS_REGNUM)
    return (group == float_reggroup
	    || group == save_reggroup
	    || group == restore_reggroup
	    || group == all_reggroup);
  else
    return default_register_reggroup_p (gdbarch, regnum, group);
}

/* For backward-compatibility we allow two 'g' packet lengths with
   the remote protocol depending on whether FPA registers are
   supplied.  M-profile targets do not have FPA registers, but some
   stubs already exist in the wild which use a 'g' packet which
   supplies them albeit with dummy values.  The packet format which
   includes FPA registers should be considered deprecated for
   M-profile targets.  */

static void
arm_register_g_packet_guesses (struct gdbarch *gdbarch)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (tdep->is_m)
    {
      const target_desc *tdesc;

      /* If we know from the executable this is an M-profile target,
	 cater for remote targets whose register set layout is the
	 same as the FPA layout.  */
      tdesc = arm_read_mprofile_description (ARM_M_TYPE_WITH_FPA);
      register_remote_g_packet_guess (gdbarch,
				      ARM_CORE_REGS_SIZE + ARM_FP_REGS_SIZE,
				      tdesc);

      /* The regular M-profile layout.  */
      tdesc = arm_read_mprofile_description (ARM_M_TYPE_M_PROFILE);
      register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE,
				      tdesc);

      /* M-profile plus M4F VFP.  */
      tdesc = arm_read_mprofile_description (ARM_M_TYPE_VFP_D16);
      register_remote_g_packet_guess (gdbarch,
				      ARM_CORE_REGS_SIZE + ARM_VFP2_REGS_SIZE,
				      tdesc);
      /* M-profile plus MVE.  */
      tdesc = arm_read_mprofile_description (ARM_M_TYPE_MVE);
      register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE
				      + ARM_VFP2_REGS_SIZE
				      + ARM_INT_REGISTER_SIZE, tdesc);
    }

  /* Otherwise we don't have a useful guess.  */
}

/* Implement the code_of_frame_writable gdbarch method.  */

static int
arm_code_of_frame_writable (struct gdbarch *gdbarch, struct frame_info *frame)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (tdep->is_m && get_frame_type (frame) == SIGTRAMP_FRAME)
    {
      /* M-profile exception frames return to some magic PCs, where
	 isn't writable at all.  */
      return 0;
    }
  else
    return 1;
}

/* Implement gdbarch_gnu_triplet_regexp.  If the arch name is arm then allow it
   to be postfixed by a version (eg armv7hl).  */

static const char *
arm_gnu_triplet_regexp (struct gdbarch *gdbarch)
{
  if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "arm") == 0)
    return "arm(v[^- ]*)?";
  return gdbarch_bfd_arch_info (gdbarch)->arch_name;
}

/* Initialize the current architecture based on INFO.  If possible,
   re-use an architecture from ARCHES, which is a list of
   architectures already created during this debugging session.

   Called e.g. at program startup, when reading a core file, and when
   reading a binary file.  */

static struct gdbarch *
arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  struct gdbarch_list *best_arch;
  enum arm_abi_kind arm_abi = arm_abi_global;
  enum arm_float_model fp_model = arm_fp_model;
  tdesc_arch_data_up tdesc_data;
  int i;
  bool is_m = false;
  int vfp_register_count = 0;
  bool have_s_pseudos = false, have_q_pseudos = false;
  bool have_wmmx_registers = false;
  bool have_neon = false;
  bool have_fpa_registers = true;
  const struct target_desc *tdesc = info.target_desc;
  bool have_vfp = false;
  bool have_mve = false;
  int mve_vpr_regnum = -1;
  int register_count = ARM_NUM_REGS;

  /* If we have an object to base this architecture on, try to determine
     its ABI.  */

  if (arm_abi == ARM_ABI_AUTO && info.abfd != NULL)
    {
      int ei_osabi, e_flags;

      switch (bfd_get_flavour (info.abfd))
	{
	case bfd_target_coff_flavour:
	  /* Assume it's an old APCS-style ABI.  */
	  /* XXX WinCE?  */
	  arm_abi = ARM_ABI_APCS;
	  break;

	case bfd_target_elf_flavour:
	  ei_osabi = elf_elfheader (info.abfd)->e_ident[EI_OSABI];
	  e_flags = elf_elfheader (info.abfd)->e_flags;

	  if (ei_osabi == ELFOSABI_ARM)
	    {
	      /* GNU tools used to use this value, but do not for EABI
		 objects.  There's nowhere to tag an EABI version
		 anyway, so assume APCS.  */
	      arm_abi = ARM_ABI_APCS;
	    }
	  else if (ei_osabi == ELFOSABI_NONE || ei_osabi == ELFOSABI_GNU)
	    {
	      int eabi_ver = EF_ARM_EABI_VERSION (e_flags);

	      switch (eabi_ver)
		{
		case EF_ARM_EABI_UNKNOWN:
		  /* Assume GNU tools.  */
		  arm_abi = ARM_ABI_APCS;
		  break;

		case EF_ARM_EABI_VER4:
		case EF_ARM_EABI_VER5:
		  arm_abi = ARM_ABI_AAPCS;
		  /* EABI binaries default to VFP float ordering.
		     They may also contain build attributes that can
		     be used to identify if the VFP argument-passing
		     ABI is in use.  */
		  if (fp_model == ARM_FLOAT_AUTO)
		    {
#ifdef HAVE_ELF
		      switch (bfd_elf_get_obj_attr_int (info.abfd,
							OBJ_ATTR_PROC,
							Tag_ABI_VFP_args))
			{
			case AEABI_VFP_args_base:
			  /* "The user intended FP parameter/result
			     passing to conform to AAPCS, base
			     variant".  */
			  fp_model = ARM_FLOAT_SOFT_VFP;
			  break;
			case AEABI_VFP_args_vfp:
			  /* "The user intended FP parameter/result
			     passing to conform to AAPCS, VFP
			     variant".  */
			  fp_model = ARM_FLOAT_VFP;
			  break;
			case AEABI_VFP_args_toolchain:
			  /* "The user intended FP parameter/result
			     passing to conform to tool chain-specific
			     conventions" - we don't know any such
			     conventions, so leave it as "auto".  */
			  break;
			case AEABI_VFP_args_compatible:
			  /* "Code is compatible with both the base
			     and VFP variants; the user did not permit
			     non-variadic functions to pass FP
			     parameters/results" - leave it as
			     "auto".  */
			  break;
			default:
			  /* Attribute value not mentioned in the
			     November 2012 ABI, so leave it as
			     "auto".  */
			  break;
			}
#else
		      fp_model = ARM_FLOAT_SOFT_VFP;
#endif
		    }
		  break;

		default:
		  /* Leave it as "auto".  */
		  warning (_("unknown ARM EABI version 0x%x"), eabi_ver);
		  break;
		}

#ifdef HAVE_ELF
	      /* Detect M-profile programs.  This only works if the
		 executable file includes build attributes; GCC does
		 copy them to the executable, but e.g. RealView does
		 not.  */
	      int attr_arch
		= bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
					    Tag_CPU_arch);
	      int attr_profile
		= bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC,
					    Tag_CPU_arch_profile);

	      /* GCC specifies the profile for v6-M; RealView only
		 specifies the profile for architectures starting with
		 V7 (as opposed to architectures with a tag
		 numerically greater than TAG_CPU_ARCH_V7).  */
	      if (!tdesc_has_registers (tdesc)
		  && (attr_arch == TAG_CPU_ARCH_V6_M
		      || attr_arch == TAG_CPU_ARCH_V6S_M
		      || attr_arch == TAG_CPU_ARCH_V8_1M_MAIN
		      || attr_profile == 'M'))
		is_m = true;
#endif
	    }

	  if (fp_model == ARM_FLOAT_AUTO)
	    {
	      switch (e_flags & (EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT))
		{
		case 0:
		  /* Leave it as "auto".  Strictly speaking this case
		     means FPA, but almost nobody uses that now, and
		     many toolchains fail to set the appropriate bits
		     for the floating-point model they use.  */
		  break;
		case EF_ARM_SOFT_FLOAT:
		  fp_model = ARM_FLOAT_SOFT_FPA;
		  break;
		case EF_ARM_VFP_FLOAT:
		  fp_model = ARM_FLOAT_VFP;
		  break;
		case EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT:
		  fp_model = ARM_FLOAT_SOFT_VFP;
		  break;
		}
	    }

	  if (e_flags & EF_ARM_BE8)
	    info.byte_order_for_code = BFD_ENDIAN_LITTLE;

	  break;

	default:
	  /* Leave it as "auto".  */
	  break;
	}
    }

  /* Check any target description for validity.  */
  if (tdesc_has_registers (tdesc))
    {
      /* For most registers we require GDB's default names; but also allow
	 the numeric names for sp / lr / pc, as a convenience.  */
      static const char *const arm_sp_names[] = { "r13", "sp", NULL };
      static const char *const arm_lr_names[] = { "r14", "lr", NULL };
      static const char *const arm_pc_names[] = { "r15", "pc", NULL };

      const struct tdesc_feature *feature;
      int valid_p;

      feature = tdesc_find_feature (tdesc,
				    "org.gnu.gdb.arm.core");
      if (feature == NULL)
	{
	  feature = tdesc_find_feature (tdesc,
					"org.gnu.gdb.arm.m-profile");
	  if (feature == NULL)
	    return NULL;
	  else
	    is_m = true;
	}

      tdesc_data = tdesc_data_alloc ();

      valid_p = 1;
      for (i = 0; i < ARM_SP_REGNUM; i++)
	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
					    arm_register_names[i]);
      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
						  ARM_SP_REGNUM,
						  arm_sp_names);
      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
						  ARM_LR_REGNUM,
						  arm_lr_names);
      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
						  ARM_PC_REGNUM,
						  arm_pc_names);
      if (is_m)
	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					    ARM_PS_REGNUM, "xpsr");
      else
	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					    ARM_PS_REGNUM, "cpsr");

      if (!valid_p)
	return NULL;

      feature = tdesc_find_feature (tdesc,
				    "org.gnu.gdb.arm.fpa");
      if (feature != NULL)
	{
	  valid_p = 1;
	  for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
						arm_register_names[i]);
	  if (!valid_p)
	    return NULL;
	}
      else
	have_fpa_registers = false;

      feature = tdesc_find_feature (tdesc,
				    "org.gnu.gdb.xscale.iwmmxt");
      if (feature != NULL)
	{
	  static const char *const iwmmxt_names[] = {
	    "wR0", "wR1", "wR2", "wR3", "wR4", "wR5", "wR6", "wR7",
	    "wR8", "wR9", "wR10", "wR11", "wR12", "wR13", "wR14", "wR15",
	    "wCID", "wCon", "wCSSF", "wCASF", "", "", "", "",
	    "wCGR0", "wCGR1", "wCGR2", "wCGR3", "", "", "", "",
	  };

	  valid_p = 1;
	  for (i = ARM_WR0_REGNUM; i <= ARM_WR15_REGNUM; i++)
	    valid_p
	      &= tdesc_numbered_register (feature, tdesc_data.get (), i,
					  iwmmxt_names[i - ARM_WR0_REGNUM]);

	  /* Check for the control registers, but do not fail if they
	     are missing.  */
	  for (i = ARM_WC0_REGNUM; i <= ARM_WCASF_REGNUM; i++)
	    tdesc_numbered_register (feature, tdesc_data.get (), i,
				     iwmmxt_names[i - ARM_WR0_REGNUM]);

	  for (i = ARM_WCGR0_REGNUM; i <= ARM_WCGR3_REGNUM; i++)
	    valid_p
	      &= tdesc_numbered_register (feature, tdesc_data.get (), i,
					  iwmmxt_names[i - ARM_WR0_REGNUM]);

	  if (!valid_p)
	    return NULL;

	  have_wmmx_registers = true;
	}

      /* If we have a VFP unit, check whether the single precision registers
	 are present.  If not, then we will synthesize them as pseudo
	 registers.  */
      feature = tdesc_find_feature (tdesc,
				    "org.gnu.gdb.arm.vfp");
      if (feature != NULL)
	{
	  static const char *const vfp_double_names[] = {
	    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
	    "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
	    "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
	    "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
	  };

	  /* Require the double precision registers.  There must be either
	     16 or 32.  */
	  valid_p = 1;
	  for (i = 0; i < 32; i++)
	    {
	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  ARM_D0_REGNUM + i,
						  vfp_double_names[i]);
	      if (!valid_p)
		break;
	    }
	  if (!valid_p && i == 16)
	    valid_p = 1;

	  /* Also require FPSCR.  */
	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					      ARM_FPSCR_REGNUM, "fpscr");
	  if (!valid_p)
	    return NULL;

	  have_vfp = true;

	  if (tdesc_unnumbered_register (feature, "s0") == 0)
	    have_s_pseudos = true;

	  vfp_register_count = i;

	  /* If we have VFP, also check for NEON.  The architecture allows
	     NEON without VFP (integer vector operations only), but GDB
	     does not support that.  */
	  feature = tdesc_find_feature (tdesc,
					"org.gnu.gdb.arm.neon");
	  if (feature != NULL)
	    {
	      /* NEON requires 32 double-precision registers.  */
	      if (i != 32)
		return NULL;

	      /* If there are quad registers defined by the stub, use
		 their type; otherwise (normally) provide them with
		 the default type.  */
	      if (tdesc_unnumbered_register (feature, "q0") == 0)
		have_q_pseudos = true;
	    }
	}

      /* Check for MVE after all the checks for GPR's, VFP and Neon.
	 MVE (Helium) is an M-profile extension.  */
      if (is_m)
	{
	  /* Do we have the MVE feature?  */
	  feature = tdesc_find_feature (tdesc,"org.gnu.gdb.arm.m-profile-mve");

	  if (feature != nullptr)
	    {
	      /* If we have MVE, we must always have the VPR register.  */
	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  register_count, "vpr");
	      if (!valid_p)
		{
		  warning (_("MVE feature is missing required register vpr."));
		  return nullptr;
		}

	      have_mve = true;
	      mve_vpr_regnum = register_count;
	      register_count++;

	      /* We can't have Q pseudo registers available here, as that
		 would mean we have NEON features, and that is only available
		 on A and R profiles.  */
	      gdb_assert (!have_q_pseudos);

	      /* Given we have a M-profile target description, if MVE is
		 enabled and there are VFP registers, we should have Q
		 pseudo registers (Q0 ~ Q7).  */
	      if (have_vfp)
		have_q_pseudos = true;
	    }
	}
    }

  /* If there is already a candidate, use it.  */
  for (best_arch = gdbarch_list_lookup_by_info (arches, &info);
       best_arch != NULL;
       best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
    {
      arm_gdbarch_tdep *tdep
	= (arm_gdbarch_tdep *) gdbarch_tdep (best_arch->gdbarch);

      if (arm_abi != ARM_ABI_AUTO && arm_abi != tdep->arm_abi)
	continue;

      if (fp_model != ARM_FLOAT_AUTO && fp_model != tdep->fp_model)
	continue;

      /* There are various other properties in tdep that we do not
	 need to check here: those derived from a target description,
	 since gdbarches with a different target description are
	 automatically disqualified.  */

      /* Do check is_m, though, since it might come from the binary.  */
      if (is_m != tdep->is_m)
	continue;

      /* Found a match.  */
      break;
    }

  if (best_arch != NULL)
    return best_arch->gdbarch;

  arm_gdbarch_tdep *tdep = new arm_gdbarch_tdep;
  gdbarch = gdbarch_alloc (&info, tdep);

  /* Record additional information about the architecture we are defining.
     These are gdbarch discriminators, like the OSABI.  */
  tdep->arm_abi = arm_abi;
  tdep->fp_model = fp_model;
  tdep->is_m = is_m;
  tdep->have_fpa_registers = have_fpa_registers;
  tdep->have_wmmx_registers = have_wmmx_registers;
  gdb_assert (vfp_register_count == 0
	      || vfp_register_count == 16
	      || vfp_register_count == 32);
  tdep->vfp_register_count = vfp_register_count;
  tdep->have_s_pseudos = have_s_pseudos;
  tdep->have_q_pseudos = have_q_pseudos;
  tdep->have_neon = have_neon;

  /* Adjust the MVE feature settings.  */
  if (have_mve)
    {
      tdep->have_mve = true;
      tdep->mve_vpr_regnum = mve_vpr_regnum;
    }

  arm_register_g_packet_guesses (gdbarch);

  /* Breakpoints.  */
  switch (info.byte_order_for_code)
    {
    case BFD_ENDIAN_BIG:
      tdep->arm_breakpoint = arm_default_arm_be_breakpoint;
      tdep->arm_breakpoint_size = sizeof (arm_default_arm_be_breakpoint);
      tdep->thumb_breakpoint = arm_default_thumb_be_breakpoint;
      tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_be_breakpoint);

      break;

    case BFD_ENDIAN_LITTLE:
      tdep->arm_breakpoint = arm_default_arm_le_breakpoint;
      tdep->arm_breakpoint_size = sizeof (arm_default_arm_le_breakpoint);
      tdep->thumb_breakpoint = arm_default_thumb_le_breakpoint;
      tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_le_breakpoint);

      break;

    default:
      internal_error (__FILE__, __LINE__,
		      _("arm_gdbarch_init: bad byte order for float format"));
    }

  /* On ARM targets char defaults to unsigned.  */
  set_gdbarch_char_signed (gdbarch, 0);

  /* wchar_t is unsigned under the AAPCS.  */
  if (tdep->arm_abi == ARM_ABI_AAPCS)
    set_gdbarch_wchar_signed (gdbarch, 0);
  else
    set_gdbarch_wchar_signed (gdbarch, 1);

  /* Compute type alignment.  */
  set_gdbarch_type_align (gdbarch, arm_type_align);

  /* Note: for displaced stepping, this includes the breakpoint, and one word
     of additional scratch space.  This setting isn't used for anything beside
     displaced stepping at present.  */
  set_gdbarch_max_insn_length (gdbarch, 4 * ARM_DISPLACED_MODIFIED_INSNS);

  /* This should be low enough for everything.  */
  tdep->lowest_pc = 0x20;
  tdep->jb_pc = -1;	/* Longjump support not enabled by default.  */

  /* The default, for both APCS and AAPCS, is to return small
     structures in registers.  */
  tdep->struct_return = reg_struct_return;

  set_gdbarch_push_dummy_call (gdbarch, arm_push_dummy_call);
  set_gdbarch_frame_align (gdbarch, arm_frame_align);

  if (is_m)
    set_gdbarch_code_of_frame_writable (gdbarch, arm_code_of_frame_writable);

  set_gdbarch_write_pc (gdbarch, arm_write_pc);

  frame_base_set_default (gdbarch, &arm_normal_base);

  /* Address manipulation.  */
  set_gdbarch_addr_bits_remove (gdbarch, arm_addr_bits_remove);

  /* Advance PC across function entry code.  */
  set_gdbarch_skip_prologue (gdbarch, arm_skip_prologue);

  /* Detect whether PC is at a point where the stack has been destroyed.  */
  set_gdbarch_stack_frame_destroyed_p (gdbarch, arm_stack_frame_destroyed_p);

  /* Skip trampolines.  */
  set_gdbarch_skip_trampoline_code (gdbarch, arm_skip_stub);

  /* The stack grows downward.  */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  /* Breakpoint manipulation.  */
  set_gdbarch_breakpoint_kind_from_pc (gdbarch, arm_breakpoint_kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, arm_sw_breakpoint_from_kind);
  set_gdbarch_breakpoint_kind_from_current_state (gdbarch,
						  arm_breakpoint_kind_from_current_state);

  /* Information about registers, etc.  */
  set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
  set_gdbarch_num_regs (gdbarch, register_count);
  set_gdbarch_register_type (gdbarch, arm_register_type);
  set_gdbarch_register_reggroup_p (gdbarch, arm_register_reggroup_p);

  /* This "info float" is FPA-specific.  Use the generic version if we
     do not have FPA.  */
  if (tdep->have_fpa_registers)
    set_gdbarch_print_float_info (gdbarch, arm_print_float_info);

  /* Internal <-> external register number maps.  */
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, arm_dwarf_reg_to_regnum);
  set_gdbarch_register_sim_regno (gdbarch, arm_register_sim_regno);

  set_gdbarch_register_name (gdbarch, arm_register_name);

  /* Returning results.  */
  set_gdbarch_return_value (gdbarch, arm_return_value);

  /* Disassembly.  */
  set_gdbarch_print_insn (gdbarch, gdb_print_insn_arm);

  /* Minsymbol frobbing.  */
  set_gdbarch_elf_make_msymbol_special (gdbarch, arm_elf_make_msymbol_special);
  set_gdbarch_coff_make_msymbol_special (gdbarch,
					 arm_coff_make_msymbol_special);
  set_gdbarch_record_special_symbol (gdbarch, arm_record_special_symbol);

  /* Thumb-2 IT block support.  */
  set_gdbarch_adjust_breakpoint_address (gdbarch,
					 arm_adjust_breakpoint_address);

  /* Virtual tables.  */
  set_gdbarch_vbit_in_delta (gdbarch, 1);

  /* Hook in the ABI-specific overrides, if they have been registered.  */
  gdbarch_init_osabi (info, gdbarch);

  dwarf2_frame_set_init_reg (gdbarch, arm_dwarf2_frame_init_reg);

  /* Add some default predicates.  */
  if (is_m)
    frame_unwind_append_unwinder (gdbarch, &arm_m_exception_unwind);
  frame_unwind_append_unwinder (gdbarch, &arm_stub_unwind);
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &arm_exidx_unwind);
  frame_unwind_append_unwinder (gdbarch, &arm_epilogue_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &arm_prologue_unwind);

  /* Now we have tuned the configuration, set a few final things,
     based on what the OS ABI has told us.  */

  /* If the ABI is not otherwise marked, assume the old GNU APCS.  EABI
     binaries are always marked.  */
  if (tdep->arm_abi == ARM_ABI_AUTO)
    tdep->arm_abi = ARM_ABI_APCS;

  /* Watchpoints are not steppable.  */
  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);

  /* We used to default to FPA for generic ARM, but almost nobody
     uses that now, and we now provide a way for the user to force
     the model.  So default to the most useful variant.  */
  if (tdep->fp_model == ARM_FLOAT_AUTO)
    tdep->fp_model = ARM_FLOAT_SOFT_FPA;

  if (tdep->jb_pc >= 0)
    set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);

  /* Floating point sizes and format.  */
  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
  if (tdep->fp_model == ARM_FLOAT_SOFT_FPA || tdep->fp_model == ARM_FLOAT_FPA)
    {
      set_gdbarch_double_format
	(gdbarch, floatformats_ieee_double_littlebyte_bigword);
      set_gdbarch_long_double_format
	(gdbarch, floatformats_ieee_double_littlebyte_bigword);
    }
  else
    {
      set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
      set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
    }

  if (tdesc_data != nullptr)
    {
      set_tdesc_pseudo_register_name (gdbarch, arm_register_name);

      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
      register_count = gdbarch_num_regs (gdbarch);

      /* Override tdesc_register_type to adjust the types of VFP
	 registers for NEON.  */
      set_gdbarch_register_type (gdbarch, arm_register_type);
    }

  /* Initialize the pseudo register data.  */
  int num_pseudos = 0;
  if (tdep->have_s_pseudos)
    {
      /* VFP single precision pseudo registers (S0~S31).  */
      tdep->s_pseudo_base = register_count;
      tdep->s_pseudo_count = 32;
      num_pseudos += tdep->s_pseudo_count;

      if (tdep->have_q_pseudos)
	{
	  /* NEON quad precision pseudo registers (Q0~Q15).  */
	  tdep->q_pseudo_base = register_count + num_pseudos;

	  if (have_neon)
	    tdep->q_pseudo_count = 16;
	  else if (have_mve)
	    tdep->q_pseudo_count = ARM_MVE_NUM_Q_REGS;

	  num_pseudos += tdep->q_pseudo_count;
	}
    }

  /* Do we have any MVE pseudo registers?  */
  if (have_mve)
    {
      tdep->mve_pseudo_base = register_count + num_pseudos;
      tdep->mve_pseudo_count = 1;
      num_pseudos += tdep->mve_pseudo_count;
    }

  /* Set some pseudo register hooks, if we have pseudo registers.  */
  if (tdep->have_s_pseudos || have_mve)
    {
      set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos);
      set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read);
      set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
    }

  /* Add standard register aliases.  We add aliases even for those
     names which are used by the current architecture - it's simpler,
     and does no harm, since nothing ever lists user registers.  */
  for (i = 0; i < ARRAY_SIZE (arm_register_aliases); i++)
    user_reg_add (gdbarch, arm_register_aliases[i].name,
		  value_of_arm_user_reg, &arm_register_aliases[i].regnum);

  set_gdbarch_disassembler_options (gdbarch, &arm_disassembler_options);
  set_gdbarch_valid_disassembler_options (gdbarch, disassembler_options_arm ());

  set_gdbarch_gnu_triplet_regexp (gdbarch, arm_gnu_triplet_regexp);

  return gdbarch;
}

static void
arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (tdep == NULL)
    return;

  fprintf_unfiltered (file, _("arm_dump_tdep: fp_model = %i\n"),
		      (int) tdep->fp_model);
  fprintf_unfiltered (file, _("arm_dump_tdep: have_fpa_registers = %i\n"),
		      (int) tdep->have_fpa_registers);
  fprintf_unfiltered (file, _("arm_dump_tdep: have_wmmx_registers = %i\n"),
		      (int) tdep->have_wmmx_registers);
  fprintf_unfiltered (file, _("arm_dump_tdep: vfp_register_count = %i\n"),
		      (int) tdep->vfp_register_count);
  fprintf_unfiltered (file, _("arm_dump_tdep: have_s_pseudos = %s\n"),
		      tdep->have_s_pseudos? "true" : "false");
  fprintf_unfiltered (file, _("arm_dump_tdep: s_pseudo_base = %i\n"),
		      (int) tdep->s_pseudo_base);
  fprintf_unfiltered (file, _("arm_dump_tdep: s_pseudo_count = %i\n"),
		      (int) tdep->s_pseudo_count);
  fprintf_unfiltered (file, _("arm_dump_tdep: have_q_pseudos = %s\n"),
		      tdep->have_q_pseudos? "true" : "false");
  fprintf_unfiltered (file, _("arm_dump_tdep: q_pseudo_base = %i\n"),
		      (int) tdep->q_pseudo_base);
  fprintf_unfiltered (file, _("arm_dump_tdep: q_pseudo_count = %i\n"),
		      (int) tdep->q_pseudo_count);
  fprintf_unfiltered (file, _("arm_dump_tdep: have_neon = %i\n"),
		      (int) tdep->have_neon);
  fprintf_unfiltered (file, _("arm_dump_tdep: have_mve = %s\n"),
		      tdep->have_mve? "yes" : "no");
  fprintf_unfiltered (file, _("arm_dump_tdep: mve_vpr_regnum = %i\n"),
		      tdep->mve_vpr_regnum);
  fprintf_unfiltered (file, _("arm_dump_tdep: mve_pseudo_base = %i\n"),
		      tdep->mve_pseudo_base);
  fprintf_unfiltered (file, _("arm_dump_tdep: mve_pseudo_count = %i\n"),
		      tdep->mve_pseudo_count);
  fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"),
		      (unsigned long) tdep->lowest_pc);
}

#if GDB_SELF_TEST
namespace selftests
{
static void arm_record_test (void);
static void arm_analyze_prologue_test ();
}
#endif

void _initialize_arm_tdep ();
void
_initialize_arm_tdep ()
{
  long length;
  int i, j;
  char regdesc[1024], *rdptr = regdesc;
  size_t rest = sizeof (regdesc);

  gdbarch_register (bfd_arch_arm, arm_gdbarch_init, arm_dump_tdep);

  /* Add ourselves to objfile event chain.  */
  gdb::observers::new_objfile.attach (arm_exidx_new_objfile, "arm-tdep");

  /* Register an ELF OS ABI sniffer for ARM binaries.  */
  gdbarch_register_osabi_sniffer (bfd_arch_arm,
				  bfd_target_elf_flavour,
				  arm_elf_osabi_sniffer);

  /* Add root prefix command for all "set arm"/"show arm" commands.  */
  add_setshow_prefix_cmd ("arm", no_class,
			  _("Various ARM-specific commands."),
			  _("Various ARM-specific commands."),
			  &setarmcmdlist, &showarmcmdlist,
			  &setlist, &showlist);

  arm_disassembler_options = xstrdup ("reg-names-std");
  const disasm_options_t *disasm_options
    = &disassembler_options_arm ()->options;
  int num_disassembly_styles = 0;
  for (i = 0; disasm_options->name[i] != NULL; i++)
    if (startswith (disasm_options->name[i], "reg-names-"))
      num_disassembly_styles++;

  /* Initialize the array that will be passed to add_setshow_enum_cmd().  */
  valid_disassembly_styles = XNEWVEC (const char *,
				      num_disassembly_styles + 1);
  for (i = j = 0; disasm_options->name[i] != NULL; i++)
    if (startswith (disasm_options->name[i], "reg-names-"))
      {
	size_t offset = strlen ("reg-names-");
	const char *style = disasm_options->name[i];
	valid_disassembly_styles[j++] = &style[offset];
	length = snprintf (rdptr, rest, "%s - %s\n", &style[offset],
			   disasm_options->description[i]);
	rdptr += length;
	rest -= length;
      }
  /* Mark the end of valid options.  */
  valid_disassembly_styles[num_disassembly_styles] = NULL;

  /* Create the help text.  */
  std::string helptext = string_printf ("%s%s%s",
					_("The valid values are:\n"),
					regdesc,
					_("The default is \"std\"."));

  add_setshow_enum_cmd("disassembler", no_class,
		       valid_disassembly_styles, &disassembly_style,
		       _("Set the disassembly style."),
		       _("Show the disassembly style."),
		       helptext.c_str (),
		       set_disassembly_style_sfunc,
		       show_disassembly_style_sfunc,
		       &setarmcmdlist, &showarmcmdlist);

  add_setshow_boolean_cmd ("apcs32", no_class, &arm_apcs_32,
			   _("Set usage of ARM 32-bit mode."),
			   _("Show usage of ARM 32-bit mode."),
			   _("When off, a 26-bit PC will be used."),
			   NULL,
			   NULL, /* FIXME: i18n: Usage of ARM 32-bit
				    mode is %s.  */
			   &setarmcmdlist, &showarmcmdlist);

  /* Add a command to allow the user to force the FPU model.  */
  add_setshow_enum_cmd ("fpu", no_class, fp_model_strings, &current_fp_model,
			_("Set the floating point type."),
			_("Show the floating point type."),
			_("auto - Determine the FP typefrom the OS-ABI.\n\
softfpa - Software FP, mixed-endian doubles on little-endian ARMs.\n\
fpa - FPA co-processor (GCC compiled).\n\
softvfp - Software FP with pure-endian doubles.\n\
vfp - VFP co-processor."),
			set_fp_model_sfunc, show_fp_model,
			&setarmcmdlist, &showarmcmdlist);

  /* Add a command to allow the user to force the ABI.  */
  add_setshow_enum_cmd ("abi", class_support, arm_abi_strings, &arm_abi_string,
			_("Set the ABI."),
			_("Show the ABI."),
			NULL, arm_set_abi, arm_show_abi,
			&setarmcmdlist, &showarmcmdlist);

  /* Add two commands to allow the user to force the assumed
     execution mode.  */
  add_setshow_enum_cmd ("fallback-mode", class_support,
			arm_mode_strings, &arm_fallback_mode_string,
			_("Set the mode assumed when symbols are unavailable."),
			_("Show the mode assumed when symbols are unavailable."),
			NULL, NULL, arm_show_fallback_mode,
			&setarmcmdlist, &showarmcmdlist);
  add_setshow_enum_cmd ("force-mode", class_support,
			arm_mode_strings, &arm_force_mode_string,
			_("Set the mode assumed even when symbols are available."),
			_("Show the mode assumed even when symbols are available."),
			NULL, NULL, arm_show_force_mode,
			&setarmcmdlist, &showarmcmdlist);

  /* Debugging flag.  */
  add_setshow_boolean_cmd ("arm", class_maintenance, &arm_debug,
			   _("Set ARM debugging."),
			   _("Show ARM debugging."),
			   _("When on, arm-specific debugging is enabled."),
			   NULL,
			   NULL, /* FIXME: i18n: "ARM debugging is %s.  */
			   &setdebuglist, &showdebuglist);

#if GDB_SELF_TEST
  selftests::register_test ("arm-record", selftests::arm_record_test);
  selftests::register_test ("arm_analyze_prologue", selftests::arm_analyze_prologue_test);
#endif

}

/* ARM-reversible process record data structures.  */

#define ARM_INSN_SIZE_BYTES 4    
#define THUMB_INSN_SIZE_BYTES 2
#define THUMB2_INSN_SIZE_BYTES 4


/* Position of the bit within a 32-bit ARM instruction
   that defines whether the instruction is a load or store.  */
#define INSN_S_L_BIT_NUM 20

#define REG_ALLOC(REGS, LENGTH, RECORD_BUF) \
	do  \
	  { \
	    unsigned int reg_len = LENGTH; \
	    if (reg_len) \
	      { \
		REGS = XNEWVEC (uint32_t, reg_len); \
		memcpy(&REGS[0], &RECORD_BUF[0], sizeof(uint32_t)*LENGTH); \
	      } \
	  } \
	while (0)

#define MEM_ALLOC(MEMS, LENGTH, RECORD_BUF) \
	do  \
	  { \
	    unsigned int mem_len = LENGTH; \
	    if (mem_len) \
	      { \
		MEMS =  XNEWVEC (struct arm_mem_r, mem_len);  \
		memcpy(&MEMS->len, &RECORD_BUF[0], \
		       sizeof(struct arm_mem_r) * LENGTH); \
	      } \
	  } \
	  while (0)

/* Checks whether insn is already recorded or yet to be decoded. (boolean expression).  */
#define INSN_RECORDED(ARM_RECORD) \
	(0 != (ARM_RECORD)->reg_rec_count || 0 != (ARM_RECORD)->mem_rec_count)

/* ARM memory record structure.  */
struct arm_mem_r
{
  uint32_t len;    /* Record length.  */
  uint32_t addr;   /* Memory address.  */
};

/* ARM instruction record contains opcode of current insn
   and execution state (before entry to decode_insn()),
   contains list of to-be-modified registers and
   memory blocks (on return from decode_insn()).  */

typedef struct insn_decode_record_t
{
  struct gdbarch *gdbarch;
  struct regcache *regcache;
  CORE_ADDR this_addr;          /* Address of the insn being decoded.  */
  uint32_t arm_insn;            /* Should accommodate thumb.  */
  uint32_t cond;                /* Condition code.  */
  uint32_t opcode;              /* Insn opcode.  */
  uint32_t decode;              /* Insn decode bits.  */
  uint32_t mem_rec_count;       /* No of mem records.  */
  uint32_t reg_rec_count;       /* No of reg records.  */
  uint32_t *arm_regs;           /* Registers to be saved for this record.  */
  struct arm_mem_r *arm_mems;   /* Memory to be saved for this record.  */
} insn_decode_record;


/* Checks ARM SBZ and SBO mandatory fields.  */

static int
sbo_sbz (uint32_t insn, uint32_t bit_num, uint32_t len, uint32_t sbo)
{
  uint32_t ones = bits (insn, bit_num - 1, (bit_num -1) + (len - 1));

  if (!len)
    return 1;

  if (!sbo)
    ones = ~ones;

  while (ones)
    {
      if (!(ones & sbo))
	{
	  return 0;
	}
      ones = ones >> 1;
    }
  return 1;
}

enum arm_record_result
{
  ARM_RECORD_SUCCESS = 0,
  ARM_RECORD_FAILURE = 1
};

typedef enum
{
  ARM_RECORD_STRH=1,
  ARM_RECORD_STRD
} arm_record_strx_t;

typedef enum
{
  ARM_RECORD=1,
  THUMB_RECORD,
  THUMB2_RECORD
} record_type_t;


static int
arm_record_strx (insn_decode_record *arm_insn_r, uint32_t *record_buf, 
		 uint32_t *record_buf_mem, arm_record_strx_t str_type)
{

  struct regcache *reg_cache = arm_insn_r->regcache;
  ULONGEST u_regval[2]= {0};

  uint32_t reg_src1 = 0, reg_src2 = 0;
  uint32_t immed_high = 0, immed_low = 0,offset_8 = 0, tgt_mem_addr = 0;

  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
  arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);

  if (14 == arm_insn_r->opcode || 10 == arm_insn_r->opcode)
    {
      /* 1) Handle misc store, immediate offset.  */
      immed_low = bits (arm_insn_r->arm_insn, 0, 3);
      immed_high = bits (arm_insn_r->arm_insn, 8, 11);
      reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
      regcache_raw_read_unsigned (reg_cache, reg_src1,
				  &u_regval[0]);
      if (ARM_PC_REGNUM == reg_src1)
	{
	  /* If R15 was used as Rn, hence current PC+8.  */
	  u_regval[0] = u_regval[0] + 8;
	}
      offset_8 = (immed_high << 4) | immed_low;
      /* Calculate target store address.  */
      if (14 == arm_insn_r->opcode)
	{
	  tgt_mem_addr = u_regval[0] + offset_8;
	}
      else
	{
	  tgt_mem_addr = u_regval[0] - offset_8;
	}
      if (ARM_RECORD_STRH == str_type)
	{
	  record_buf_mem[0] = 2;
	  record_buf_mem[1] = tgt_mem_addr;
	  arm_insn_r->mem_rec_count = 1;
	}
      else if (ARM_RECORD_STRD == str_type)
	{
	  record_buf_mem[0] = 4;
	  record_buf_mem[1] = tgt_mem_addr;
	  record_buf_mem[2] = 4;
	  record_buf_mem[3] = tgt_mem_addr + 4;
	  arm_insn_r->mem_rec_count = 2;
	}
    }
  else if (12 == arm_insn_r->opcode || 8 == arm_insn_r->opcode)
    {
      /* 2) Store, register offset.  */
      /* Get Rm.  */
      reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
      /* Get Rn.  */
      reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
      regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
      regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
      if (15 == reg_src2)
	{
	  /* If R15 was used as Rn, hence current PC+8.  */
	  u_regval[0] = u_regval[0] + 8;
	}
      /* Calculate target store address, Rn +/- Rm, register offset.  */
      if (12 == arm_insn_r->opcode)
	{
	  tgt_mem_addr = u_regval[0] + u_regval[1];
	}
      else
	{
	  tgt_mem_addr = u_regval[1] - u_regval[0];
	}
      if (ARM_RECORD_STRH == str_type)
	{
	  record_buf_mem[0] = 2;
	  record_buf_mem[1] = tgt_mem_addr;
	  arm_insn_r->mem_rec_count = 1;
	}
      else if (ARM_RECORD_STRD == str_type)
	{
	  record_buf_mem[0] = 4;
	  record_buf_mem[1] = tgt_mem_addr;
	  record_buf_mem[2] = 4;
	  record_buf_mem[3] = tgt_mem_addr + 4;
	  arm_insn_r->mem_rec_count = 2;
	}
    }
  else if (11 == arm_insn_r->opcode || 15 == arm_insn_r->opcode
	   || 2 == arm_insn_r->opcode  || 6 == arm_insn_r->opcode)
    {
      /* 3) Store, immediate pre-indexed.  */
      /* 5) Store, immediate post-indexed.  */
      immed_low = bits (arm_insn_r->arm_insn, 0, 3);
      immed_high = bits (arm_insn_r->arm_insn, 8, 11);
      offset_8 = (immed_high << 4) | immed_low;
      reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
      regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
      /* Calculate target store address, Rn +/- Rm, register offset.  */
      if (15 == arm_insn_r->opcode || 6 == arm_insn_r->opcode)
	{
	  tgt_mem_addr = u_regval[0] + offset_8;
	}
      else
	{
	  tgt_mem_addr = u_regval[0] - offset_8;
	}
      if (ARM_RECORD_STRH == str_type)
	{
	  record_buf_mem[0] = 2;
	  record_buf_mem[1] = tgt_mem_addr;
	  arm_insn_r->mem_rec_count = 1;
	}
      else if (ARM_RECORD_STRD == str_type)
	{
	  record_buf_mem[0] = 4;
	  record_buf_mem[1] = tgt_mem_addr;
	  record_buf_mem[2] = 4;
	  record_buf_mem[3] = tgt_mem_addr + 4;
	  arm_insn_r->mem_rec_count = 2;
	}
      /* Record Rn also as it changes.  */
      *(record_buf) = bits (arm_insn_r->arm_insn, 16, 19);
      arm_insn_r->reg_rec_count = 1;
    }
  else if (9 == arm_insn_r->opcode || 13 == arm_insn_r->opcode
	   || 0 == arm_insn_r->opcode || 4 == arm_insn_r->opcode)
    {
      /* 4) Store, register pre-indexed.  */
      /* 6) Store, register post -indexed.  */
      reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
      reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
      regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
      regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
      /* Calculate target store address, Rn +/- Rm, register offset.  */
      if (13 == arm_insn_r->opcode || 4 == arm_insn_r->opcode)
	{
	  tgt_mem_addr = u_regval[0] + u_regval[1];
	}
      else
	{
	  tgt_mem_addr = u_regval[1] - u_regval[0];
	}
      if (ARM_RECORD_STRH == str_type)
	{
	  record_buf_mem[0] = 2;
	  record_buf_mem[1] = tgt_mem_addr;
	  arm_insn_r->mem_rec_count = 1;
	}
      else if (ARM_RECORD_STRD == str_type)
	{
	  record_buf_mem[0] = 4;
	  record_buf_mem[1] = tgt_mem_addr;
	  record_buf_mem[2] = 4;
	  record_buf_mem[3] = tgt_mem_addr + 4;
	  arm_insn_r->mem_rec_count = 2;
	}
      /* Record Rn also as it changes.  */
      *(record_buf) = bits (arm_insn_r->arm_insn, 16, 19);
      arm_insn_r->reg_rec_count = 1;
    }
  return 0;
}

/* Handling ARM extension space insns.  */

static int
arm_record_extension_space (insn_decode_record *arm_insn_r)
{
  int ret = 0;  /* Return value: -1:record failure ;  0:success  */
  uint32_t opcode1 = 0, opcode2 = 0, insn_op1 = 0;
  uint32_t record_buf[8], record_buf_mem[8];
  uint32_t reg_src1 = 0;
  struct regcache *reg_cache = arm_insn_r->regcache;
  ULONGEST u_regval = 0;

  gdb_assert (!INSN_RECORDED(arm_insn_r));
  /* Handle unconditional insn extension space.  */

  opcode1 = bits (arm_insn_r->arm_insn, 20, 27);
  opcode2 = bits (arm_insn_r->arm_insn, 4, 7);
  if (arm_insn_r->cond)
    {
      /* PLD has no affect on architectural state, it just affects
	 the caches.  */
      if (5 == ((opcode1 & 0xE0) >> 5))
	{
	  /* BLX(1) */
	  record_buf[0] = ARM_PS_REGNUM;
	  record_buf[1] = ARM_LR_REGNUM;
	  arm_insn_r->reg_rec_count = 2;
	}
      /* STC2, LDC2, MCR2, MRC2, CDP2: <TBD>, co-processor insn.  */
    }


  opcode1 = bits (arm_insn_r->arm_insn, 25, 27);
  if (3 == opcode1 && bit (arm_insn_r->arm_insn, 4))
    {
      ret = -1;
      /* Undefined instruction on ARM V5; need to handle if later 
	 versions define it.  */
    }

  opcode1 = bits (arm_insn_r->arm_insn, 24, 27);
  opcode2 = bits (arm_insn_r->arm_insn, 4, 7);
  insn_op1 = bits (arm_insn_r->arm_insn, 20, 23);

  /* Handle arithmetic insn extension space.  */
  if (!opcode1 && 9 == opcode2 && 1 != arm_insn_r->cond
      && !INSN_RECORDED(arm_insn_r))
    {
      /* Handle MLA(S) and MUL(S).  */
      if (in_inclusive_range (insn_op1, 0U, 3U))
	{
	  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  record_buf[1] = ARM_PS_REGNUM;
	  arm_insn_r->reg_rec_count = 2;
	}
      else if (in_inclusive_range (insn_op1, 4U, 15U))
	{
	  /* Handle SMLAL(S), SMULL(S), UMLAL(S), UMULL(S).  */
	  record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
	  record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
	  record_buf[2] = ARM_PS_REGNUM;
	  arm_insn_r->reg_rec_count = 3;
	}
    }

  opcode1 = bits (arm_insn_r->arm_insn, 26, 27);
  opcode2 = bits (arm_insn_r->arm_insn, 23, 24);
  insn_op1 = bits (arm_insn_r->arm_insn, 21, 22);

  /* Handle control insn extension space.  */

  if (!opcode1 && 2 == opcode2 && !bit (arm_insn_r->arm_insn, 20)
      && 1 != arm_insn_r->cond && !INSN_RECORDED(arm_insn_r))
    {
      if (!bit (arm_insn_r->arm_insn,25))
	{
	  if (!bits (arm_insn_r->arm_insn, 4, 7))
	    {
	      if ((0 == insn_op1) || (2 == insn_op1))
		{
		  /* MRS.  */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;
		}
	      else if (1 == insn_op1)
		{
		  /* CSPR is going to be changed.  */
		  record_buf[0] = ARM_PS_REGNUM;
		  arm_insn_r->reg_rec_count = 1;
		}
	      else if (3 == insn_op1)
		{
		  /* SPSR is going to be changed.  */
		  /* We need to get SPSR value, which is yet to be done.  */
		  return -1;
		}
	    }
	  else if (1 == bits (arm_insn_r->arm_insn, 4, 7))
	    {
	      if (1 == insn_op1)
		{
		  /* BX.  */
		  record_buf[0] = ARM_PS_REGNUM;
		  arm_insn_r->reg_rec_count = 1;
		}
	      else if (3 == insn_op1)
		{
		  /* CLZ.  */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;
		}
	    }
	  else if (3 == bits (arm_insn_r->arm_insn, 4, 7))
	    {
	      /* BLX.  */
	      record_buf[0] = ARM_PS_REGNUM;
	      record_buf[1] = ARM_LR_REGNUM;
	      arm_insn_r->reg_rec_count = 2;
	    }
	  else if (5 == bits (arm_insn_r->arm_insn, 4, 7))
	    {
	      /* QADD, QSUB, QDADD, QDSUB */
	      record_buf[0] = ARM_PS_REGNUM;
	      record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
	      arm_insn_r->reg_rec_count = 2;
	    }
	  else if (7 == bits (arm_insn_r->arm_insn, 4, 7))
	    {
	      /* BKPT.  */
	      record_buf[0] = ARM_PS_REGNUM;
	      record_buf[1] = ARM_LR_REGNUM;
	      arm_insn_r->reg_rec_count = 2;

	      /* Save SPSR also;how?  */
	      return -1;
	    }
	  else if(8 == bits (arm_insn_r->arm_insn, 4, 7) 
		  || 10 == bits (arm_insn_r->arm_insn, 4, 7)
		  || 12 == bits (arm_insn_r->arm_insn, 4, 7)
		  || 14 == bits (arm_insn_r->arm_insn, 4, 7)
		 )
	    {
	      if (0 == insn_op1 || 1 == insn_op1)
		{
		  /* SMLA<x><y>, SMLAW<y>, SMULW<y>.  */
		  /* We dont do optimization for SMULW<y> where we
		     need only Rd.  */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  record_buf[1] = ARM_PS_REGNUM;
		  arm_insn_r->reg_rec_count = 2;
		}
	      else if (2 == insn_op1)
		{
		  /* SMLAL<x><y>.  */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
		  arm_insn_r->reg_rec_count = 2;
		}
	      else if (3 == insn_op1)
		{
		  /* SMUL<x><y>.  */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;
		}
	    }
	}
      else
	{
	  /* MSR : immediate form.  */
	  if (1 == insn_op1)
	    {
	      /* CSPR is going to be changed.  */
	      record_buf[0] = ARM_PS_REGNUM;
	      arm_insn_r->reg_rec_count = 1;
	    }
	  else if (3 == insn_op1)
	    {
	      /* SPSR is going to be changed.  */
	      /* we need to get SPSR value, which is yet to be done  */
	      return -1;
	    }
	}
    }

  opcode1 = bits (arm_insn_r->arm_insn, 25, 27);
  opcode2 = bits (arm_insn_r->arm_insn, 20, 24);
  insn_op1 = bits (arm_insn_r->arm_insn, 5, 6);

  /* Handle load/store insn extension space.  */

  if (!opcode1 && bit (arm_insn_r->arm_insn, 7) 
      && bit (arm_insn_r->arm_insn, 4) && 1 != arm_insn_r->cond
      && !INSN_RECORDED(arm_insn_r))
    {
      /* SWP/SWPB.  */
      if (0 == insn_op1)
	{
	  /* These insn, changes register and memory as well.  */
	  /* SWP or SWPB insn.  */
	  /* Get memory address given by Rn.  */
	  reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
	  regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval);
	  /* SWP insn ?, swaps word.  */
	  if (8 == arm_insn_r->opcode)
	    {
	      record_buf_mem[0] = 4;
	    }
	  else
	    {
	      /* SWPB insn, swaps only byte.  */
	      record_buf_mem[0] = 1;
	    }
	  record_buf_mem[1] = u_regval;
	  arm_insn_r->mem_rec_count = 1;
	  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  arm_insn_r->reg_rec_count = 1;
	}
      else if (1 == insn_op1 && !bit (arm_insn_r->arm_insn, 20))
	{
	  /* STRH.  */
	  arm_record_strx(arm_insn_r, &record_buf[0], &record_buf_mem[0],
			  ARM_RECORD_STRH);
	}
      else if (2 == insn_op1 && !bit (arm_insn_r->arm_insn, 20))
	{
	  /* LDRD.  */
	  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  record_buf[1] = record_buf[0] + 1;
	  arm_insn_r->reg_rec_count = 2;
	}
      else if (3 == insn_op1 && !bit (arm_insn_r->arm_insn, 20))
	{
	  /* STRD.  */
	  arm_record_strx(arm_insn_r, &record_buf[0], &record_buf_mem[0],
			ARM_RECORD_STRD);
	}
      else if (bit (arm_insn_r->arm_insn, 20) && insn_op1 <= 3)
	{
	  /* LDRH, LDRSB, LDRSH.  */
	  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  arm_insn_r->reg_rec_count = 1;
	}

    }

  opcode1 = bits (arm_insn_r->arm_insn, 23, 27);
  if (24 == opcode1 && bit (arm_insn_r->arm_insn, 21)
      && !INSN_RECORDED(arm_insn_r))
    {
      ret = -1;
      /* Handle coprocessor insn extension space.  */
    }

  /* To be done for ARMv5 and later; as of now we return -1.  */
  if (-1 == ret)
    return ret;

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);

  return ret;
}

/* Handling opcode 000 insns.  */

static int
arm_record_data_proc_misc_ld_str (insn_decode_record *arm_insn_r)
{
  struct regcache *reg_cache = arm_insn_r->regcache;
  uint32_t record_buf[8], record_buf_mem[8];
  ULONGEST u_regval[2] = {0};

  uint32_t reg_src1 = 0;
  uint32_t opcode1 = 0;

  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
  arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);
  opcode1 = bits (arm_insn_r->arm_insn, 20, 24);

  if (!((opcode1 & 0x19) == 0x10))
    {
      /* Data-processing (register) and Data-processing (register-shifted
	 register */
      /* Out of 11 shifter operands mode, all the insn modifies destination
	 register, which is specified by 13-16 decode.  */
      record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
      record_buf[1] = ARM_PS_REGNUM;
      arm_insn_r->reg_rec_count = 2;
    }
  else if ((arm_insn_r->decode < 8) && ((opcode1 & 0x19) == 0x10))
    {
      /* Miscellaneous instructions */

      if (3 == arm_insn_r->decode && 0x12 == opcode1
	  && sbo_sbz (arm_insn_r->arm_insn, 9, 12, 1))
	{
	  /* Handle BLX, branch and link/exchange.  */
	  if (9 == arm_insn_r->opcode)
	    {
	      /* Branch is chosen by setting T bit of CSPR, bitp[0] of Rm,
		 and R14 stores the return address.  */
	      record_buf[0] = ARM_PS_REGNUM;
	      record_buf[1] = ARM_LR_REGNUM;
	      arm_insn_r->reg_rec_count = 2;
	    }
	}
      else if (7 == arm_insn_r->decode && 0x12 == opcode1)
	{
	  /* Handle enhanced software breakpoint insn, BKPT.  */
	  /* CPSR is changed to be executed in ARM state,  disabling normal
	     interrupts, entering abort mode.  */
	  /* According to high vector configuration PC is set.  */
	  /* user hit breakpoint and type reverse, in
	     that case, we need to go back with previous CPSR and
	     Program Counter.  */
	  record_buf[0] = ARM_PS_REGNUM;
	  record_buf[1] = ARM_LR_REGNUM;
	  arm_insn_r->reg_rec_count = 2;

	  /* Save SPSR also; how?  */
	  return -1;
	}
      else if (1 == arm_insn_r->decode && 0x12 == opcode1
	       && sbo_sbz (arm_insn_r->arm_insn, 9, 12, 1))
	{
	  /* Handle BX, branch and link/exchange.  */
	  /* Branch is chosen by setting T bit of CSPR, bitp[0] of Rm.  */
	  record_buf[0] = ARM_PS_REGNUM;
	  arm_insn_r->reg_rec_count = 1;
	}
      else if (1 == arm_insn_r->decode && 0x16 == opcode1
	       && sbo_sbz (arm_insn_r->arm_insn, 9, 4, 1)
	       && sbo_sbz (arm_insn_r->arm_insn, 17, 4, 1))
	{
	  /* Count leading zeros: CLZ.  */
	  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  arm_insn_r->reg_rec_count = 1;
	}
      else if (!bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)
	       && (8 == arm_insn_r->opcode || 10 == arm_insn_r->opcode)
	       && sbo_sbz (arm_insn_r->arm_insn, 17, 4, 1)
	       && sbo_sbz (arm_insn_r->arm_insn, 1, 12, 0))
	{
	  /* Handle MRS insn.  */
	  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  arm_insn_r->reg_rec_count = 1;
	}
    }
  else if (9 == arm_insn_r->decode && opcode1 < 0x10)
    {
      /* Multiply and multiply-accumulate */

      /* Handle multiply instructions.  */
      /* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL.  */
      if (0 == arm_insn_r->opcode || 1 == arm_insn_r->opcode)
	{
	  /* Handle MLA and MUL.  */
	  record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
	  record_buf[1] = ARM_PS_REGNUM;
	  arm_insn_r->reg_rec_count = 2;
	}
      else if (4 <= arm_insn_r->opcode && 7 >= arm_insn_r->opcode)
	{
	  /* Handle SMLAL, SMULL, UMLAL, UMULL.  */
	  record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
	  record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
	  record_buf[2] = ARM_PS_REGNUM;
	  arm_insn_r->reg_rec_count = 3;
	}
    }
  else if (9 == arm_insn_r->decode  && opcode1 > 0x10)
    {
      /* Synchronization primitives */

      /* Handling SWP, SWPB.  */
      /* These insn, changes register and memory as well.  */
      /* SWP or SWPB insn.  */

      reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
      regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
      /* SWP insn ?, swaps word.  */
      if (8 == arm_insn_r->opcode)
	{
	  record_buf_mem[0] = 4;
	}
      else
	{
	  /* SWPB insn, swaps only byte.  */
	  record_buf_mem[0] = 1;
	}
      record_buf_mem[1] = u_regval[0];
      arm_insn_r->mem_rec_count = 1;
      record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
      arm_insn_r->reg_rec_count = 1;
    }
  else if (11 == arm_insn_r->decode || 13 == arm_insn_r->decode
	   || 15 == arm_insn_r->decode)
    {
      if ((opcode1 & 0x12) == 2)
	{
	  /* Extra load/store (unprivileged) */
	  return -1;
	}
      else
	{
	  /* Extra load/store */
	  switch (bits (arm_insn_r->arm_insn, 5, 6))
	    {
	    case 1:
	      if ((opcode1 & 0x05) == 0x0 || (opcode1 & 0x05) == 0x4)
		{
		  /* STRH (register), STRH (immediate) */
		  arm_record_strx (arm_insn_r, &record_buf[0],
				   &record_buf_mem[0], ARM_RECORD_STRH);
		}
	      else if ((opcode1 & 0x05) == 0x1)
		{
		  /* LDRH (register) */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;

		  if (bit (arm_insn_r->arm_insn, 21))
		    {
		      /* Write back to Rn.  */
		      record_buf[arm_insn_r->reg_rec_count++]
			= bits (arm_insn_r->arm_insn, 16, 19);
		    }
		}
	      else if ((opcode1 & 0x05) == 0x5)
		{
		  /* LDRH (immediate), LDRH (literal) */
		  int rn = bits (arm_insn_r->arm_insn, 16, 19);

		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;

		  if (rn != 15)
		    {
		      /*LDRH (immediate) */
		      if (bit (arm_insn_r->arm_insn, 21))
			{
			  /* Write back to Rn.  */
			  record_buf[arm_insn_r->reg_rec_count++] = rn;
			}
		    }
		}
	      else
		return -1;
	      break;
	    case 2:
	      if ((opcode1 & 0x05) == 0x0)
		{
		  /* LDRD (register) */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  record_buf[1] = record_buf[0] + 1;
		  arm_insn_r->reg_rec_count = 2;

		  if (bit (arm_insn_r->arm_insn, 21))
		    {
		      /* Write back to Rn.  */
		      record_buf[arm_insn_r->reg_rec_count++]
			= bits (arm_insn_r->arm_insn, 16, 19);
		    }
		}
	      else if ((opcode1 & 0x05) == 0x1)
		{
		  /* LDRSB (register) */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;

		  if (bit (arm_insn_r->arm_insn, 21))
		    {
		      /* Write back to Rn.  */
		      record_buf[arm_insn_r->reg_rec_count++]
			= bits (arm_insn_r->arm_insn, 16, 19);
		    }
		}
	      else if ((opcode1 & 0x05) == 0x4 || (opcode1 & 0x05) == 0x5)
		{
		  /* LDRD (immediate), LDRD (literal), LDRSB (immediate),
		     LDRSB (literal) */
		  int rn = bits (arm_insn_r->arm_insn, 16, 19);

		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;

		  if (rn != 15)
		    {
		      /*LDRD (immediate), LDRSB (immediate) */
		      if (bit (arm_insn_r->arm_insn, 21))
			{
			  /* Write back to Rn.  */
			  record_buf[arm_insn_r->reg_rec_count++] = rn;
			}
		    }
		}
	      else
		return -1;
	      break;
	    case 3:
	      if ((opcode1 & 0x05) == 0x0)
		{
		  /* STRD (register) */
		  arm_record_strx (arm_insn_r, &record_buf[0],
				   &record_buf_mem[0], ARM_RECORD_STRD);
		}
	      else if ((opcode1 & 0x05) == 0x1)
		{
		  /* LDRSH (register) */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;

		  if (bit (arm_insn_r->arm_insn, 21))
		    {
		      /* Write back to Rn.  */
		      record_buf[arm_insn_r->reg_rec_count++]
			= bits (arm_insn_r->arm_insn, 16, 19);
		    }
		}
	      else if ((opcode1 & 0x05) == 0x4)
		{
		  /* STRD (immediate) */
		  arm_record_strx (arm_insn_r, &record_buf[0],
				   &record_buf_mem[0], ARM_RECORD_STRD);
		}
	      else if ((opcode1 & 0x05) == 0x5)
		{
		  /* LDRSH (immediate), LDRSH (literal) */
		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  arm_insn_r->reg_rec_count = 1;

		  if (bit (arm_insn_r->arm_insn, 21))
		    {
		      /* Write back to Rn.  */
		      record_buf[arm_insn_r->reg_rec_count++]
			= bits (arm_insn_r->arm_insn, 16, 19);
		    }
		}
	      else
		return -1;
	      break;
	    default:
	      return -1;
	    }
	}
    }
  else
    {
      return -1;
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
  return 0;
}

/* Handling opcode 001 insns.  */

static int
arm_record_data_proc_imm (insn_decode_record *arm_insn_r)
{
  uint32_t record_buf[8], record_buf_mem[8];

  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
  arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);

  if ((9 == arm_insn_r->opcode || 11 == arm_insn_r->opcode)
      && 2 == bits (arm_insn_r->arm_insn, 20, 21)
      && sbo_sbz (arm_insn_r->arm_insn, 13, 4, 1)
     )
    {
      /* Handle MSR insn.  */
      if (9 == arm_insn_r->opcode)
	{
	  /* CSPR is going to be changed.  */
	  record_buf[0] = ARM_PS_REGNUM;
	  arm_insn_r->reg_rec_count = 1;
	}
      else
	{
	  /* SPSR is going to be changed.  */
	}
    }
  else if (arm_insn_r->opcode <= 15)
    {
      /* Normal data processing insns.  */
      /* Out of 11 shifter operands mode, all the insn modifies destination
	 register, which is specified by 13-16 decode.  */
      record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
      record_buf[1] = ARM_PS_REGNUM;
      arm_insn_r->reg_rec_count = 2;
    }
  else
    {
      return -1;
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
  return 0;
}

static int
arm_record_media (insn_decode_record *arm_insn_r)
{
  uint32_t record_buf[8];

  switch (bits (arm_insn_r->arm_insn, 22, 24))
    {
    case 0:
      /* Parallel addition and subtraction, signed */
    case 1:
      /* Parallel addition and subtraction, unsigned */
    case 2:
    case 3:
      /* Packing, unpacking, saturation and reversal */
      {
	int rd = bits (arm_insn_r->arm_insn, 12, 15);

	record_buf[arm_insn_r->reg_rec_count++] = rd;
      }
      break;

    case 4:
    case 5:
      /* Signed multiplies */
      {
	int rd = bits (arm_insn_r->arm_insn, 16, 19);
	unsigned int op1 = bits (arm_insn_r->arm_insn, 20, 22);

	record_buf[arm_insn_r->reg_rec_count++] = rd;
	if (op1 == 0x0)
	  record_buf[arm_insn_r->reg_rec_count++] = ARM_PS_REGNUM;
	else if (op1 == 0x4)
	  record_buf[arm_insn_r->reg_rec_count++]
	    = bits (arm_insn_r->arm_insn, 12, 15);
      }
      break;

    case 6:
      {
	if (bit (arm_insn_r->arm_insn, 21)
	    && bits (arm_insn_r->arm_insn, 5, 6) == 0x2)
	  {
	    /* SBFX */
	    record_buf[arm_insn_r->reg_rec_count++]
	      = bits (arm_insn_r->arm_insn, 12, 15);
	  }
	else if (bits (arm_insn_r->arm_insn, 20, 21) == 0x0
		 && bits (arm_insn_r->arm_insn, 5, 7) == 0x0)
	  {
	    /* USAD8 and USADA8 */
	    record_buf[arm_insn_r->reg_rec_count++]
	      = bits (arm_insn_r->arm_insn, 16, 19);
	  }
      }
      break;

    case 7:
      {
	if (bits (arm_insn_r->arm_insn, 20, 21) == 0x3
	    && bits (arm_insn_r->arm_insn, 5, 7) == 0x7)
	  {
	    /* Permanently UNDEFINED */
	    return -1;
	  }
	else
	  {
	    /* BFC, BFI and UBFX */
	    record_buf[arm_insn_r->reg_rec_count++]
	      = bits (arm_insn_r->arm_insn, 12, 15);
	  }
      }
      break;

    default:
      return -1;
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);

  return 0;
}

/* Handle ARM mode instructions with opcode 010.  */

static int
arm_record_ld_st_imm_offset (insn_decode_record *arm_insn_r)
{
  struct regcache *reg_cache = arm_insn_r->regcache;

  uint32_t reg_base , reg_dest;
  uint32_t offset_12, tgt_mem_addr;
  uint32_t record_buf[8], record_buf_mem[8];
  unsigned char wback;
  ULONGEST u_regval;

  /* Calculate wback.  */
  wback = (bit (arm_insn_r->arm_insn, 24) == 0)
	  || (bit (arm_insn_r->arm_insn, 21) == 1);

  arm_insn_r->reg_rec_count = 0;
  reg_base = bits (arm_insn_r->arm_insn, 16, 19);

  if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
    {
      /* LDR (immediate), LDR (literal), LDRB (immediate), LDRB (literal), LDRBT
	 and LDRT.  */

      reg_dest = bits (arm_insn_r->arm_insn, 12, 15);
      record_buf[arm_insn_r->reg_rec_count++] = reg_dest;

      /* The LDR instruction is capable of doing branching.  If MOV LR, PC
	 preceeds a LDR instruction having R15 as reg_base, it
	 emulates a branch and link instruction, and hence we need to save
	 CPSR and PC as well.  */
      if (ARM_PC_REGNUM == reg_dest)
	record_buf[arm_insn_r->reg_rec_count++] = ARM_PS_REGNUM;

      /* If wback is true, also save the base register, which is going to be
	 written to.  */
      if (wback)
	record_buf[arm_insn_r->reg_rec_count++] = reg_base;
    }
  else
    {
      /* STR (immediate), STRB (immediate), STRBT and STRT.  */

      offset_12 = bits (arm_insn_r->arm_insn, 0, 11);
      regcache_raw_read_unsigned (reg_cache, reg_base, &u_regval);

      /* Handle bit U.  */
      if (bit (arm_insn_r->arm_insn, 23))
	{
	  /* U == 1: Add the offset. */
	  tgt_mem_addr = (uint32_t) u_regval + offset_12;
	}
      else
	{
	  /* U == 0: subtract the offset. */
	  tgt_mem_addr = (uint32_t) u_regval - offset_12;
	}

      /* Bit 22 tells us whether the store instruction writes 1 byte or 4
	 bytes.  */
      if (bit (arm_insn_r->arm_insn, 22))
	{
	  /* STRB and STRBT: 1 byte.  */
	  record_buf_mem[0] = 1;
	}
      else
	{
	  /* STR and STRT: 4 bytes.  */
	  record_buf_mem[0] = 4;
	}

      /* Handle bit P.  */
      if (bit (arm_insn_r->arm_insn, 24))
	record_buf_mem[1] = tgt_mem_addr;
      else
	record_buf_mem[1] = (uint32_t) u_regval;

      arm_insn_r->mem_rec_count = 1;

      /* If wback is true, also save the base register, which is going to be
	 written to.  */
      if (wback)
	record_buf[arm_insn_r->reg_rec_count++] = reg_base;
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
  return 0;
}

/* Handling opcode 011 insns.  */

static int
arm_record_ld_st_reg_offset (insn_decode_record *arm_insn_r)
{
  struct regcache *reg_cache = arm_insn_r->regcache;

  uint32_t shift_imm = 0;
  uint32_t reg_src1 = 0, reg_src2 = 0, reg_dest = 0;
  uint32_t offset_12 = 0, tgt_mem_addr = 0;
  uint32_t record_buf[8], record_buf_mem[8];

  LONGEST s_word;
  ULONGEST u_regval[2];

  if (bit (arm_insn_r->arm_insn, 4))
    return arm_record_media (arm_insn_r);

  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
  arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);

  /* Handle enhanced store insns and LDRD DSP insn,
     order begins according to addressing modes for store insns
     STRH insn.  */

  /* LDR or STR?  */
  if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
    {
      reg_dest = bits (arm_insn_r->arm_insn, 12, 15);
      /* LDR insn has a capability to do branching, if
	 MOV LR, PC is preceded by LDR insn having Rn as R15
	 in that case, it emulates branch and link insn, and hence we
	 need to save CSPR and PC as well.  */
      if (15 != reg_dest)
	{
	  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  arm_insn_r->reg_rec_count = 1;
	}
      else
	{
	  record_buf[0] = reg_dest;
	  record_buf[1] = ARM_PS_REGNUM;
	  arm_insn_r->reg_rec_count = 2;
	}
    }
  else
    {
      if (! bits (arm_insn_r->arm_insn, 4, 11))
	{
	  /* Store insn, register offset and register pre-indexed,
	     register post-indexed.  */
	  /* Get Rm.  */
	  reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
	  /* Get Rn.  */
	  reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
	  regcache_raw_read_unsigned (reg_cache, reg_src1
				      , &u_regval[0]);
	  regcache_raw_read_unsigned (reg_cache, reg_src2
				      , &u_regval[1]);
	  if (15 == reg_src2)
	    {
	      /* If R15 was used as Rn, hence current PC+8.  */
	      /* Pre-indexed mode doesnt reach here ; illegal insn.  */
		u_regval[0] = u_regval[0] + 8;
	    }
	  /* Calculate target store address, Rn +/- Rm, register offset.  */
	  /* U == 1.  */
	  if (bit (arm_insn_r->arm_insn, 23))
	    {
	      tgt_mem_addr = u_regval[0] + u_regval[1];
	    }
	  else
	    {
	      tgt_mem_addr = u_regval[1] - u_regval[0];
	    }

	  switch (arm_insn_r->opcode)
	    {
	      /* STR.  */
	      case 8:
	      case 12:
	      /* STR.  */    
	      case 9:
	      case 13:
	      /* STRT.  */
	      case 1:
	      case 5:
	      /* STR.  */
	      case 0:
	      case 4:
		record_buf_mem[0] = 4;
	      break;

	      /* STRB.  */
	      case 10:
	      case 14:
	      /* STRB.  */
	      case 11:
	      case 15:
	      /* STRBT.  */    
	      case 3:
	      case 7:
	      /* STRB.  */
	      case 2:
	      case 6:
		record_buf_mem[0] = 1;
	      break;

	      default:
		gdb_assert_not_reached ("no decoding pattern found");
	      break;
	    }
	  record_buf_mem[1] = tgt_mem_addr;
	  arm_insn_r->mem_rec_count = 1;

	  if (9 == arm_insn_r->opcode || 11 == arm_insn_r->opcode
	      || 13 == arm_insn_r->opcode || 15 == arm_insn_r->opcode
	      || 0 == arm_insn_r->opcode || 2 == arm_insn_r->opcode
	      || 4 == arm_insn_r->opcode || 6 == arm_insn_r->opcode
	      || 1 == arm_insn_r->opcode || 3 == arm_insn_r->opcode
	      || 5 == arm_insn_r->opcode || 7 == arm_insn_r->opcode
	     )
	    {
	      /* Rn is going to be changed in pre-indexed mode and
		 post-indexed mode as well.  */
	      record_buf[0] = reg_src2;
	      arm_insn_r->reg_rec_count = 1;
	    }
	}
      else
	{
	  /* Store insn, scaled register offset; scaled pre-indexed.  */
	  offset_12 = bits (arm_insn_r->arm_insn, 5, 6);
	  /* Get Rm.  */
	  reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
	  /* Get Rn.  */
	  reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
	  /* Get shift_imm.  */
	  shift_imm = bits (arm_insn_r->arm_insn, 7, 11);
	  regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
	  regcache_raw_read_signed (reg_cache, reg_src1, &s_word);
	  regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
	  /* Offset_12 used as shift.  */
	  switch (offset_12)
	    {
	      case 0:
		/* Offset_12 used as index.  */
		offset_12 = u_regval[0] << shift_imm;
	      break;

	      case 1:
		offset_12 = (!shift_imm)?0:u_regval[0] >> shift_imm;
	      break;

	      case 2:
		if (!shift_imm)
		  {
		    if (bit (u_regval[0], 31))
		      {
			offset_12 = 0xFFFFFFFF;
		      }
		    else
		      {
			offset_12 = 0;
		      }
		  }
		else
		  {
		    /* This is arithmetic shift.  */
		    offset_12 = s_word >> shift_imm;
		  }
		break;

	      case 3:
		if (!shift_imm)
		  {
		    regcache_raw_read_unsigned (reg_cache, ARM_PS_REGNUM,
						&u_regval[1]);
		    /* Get C flag value and shift it by 31.  */
		    offset_12 = (((bit (u_regval[1], 29)) << 31) \
				  | (u_regval[0]) >> 1);
		  }
		else
		  {
		    offset_12 = (u_regval[0] >> shift_imm) \
				| (u_regval[0] <<
				(sizeof(uint32_t) - shift_imm));
		  }
	      break;

	      default:
		gdb_assert_not_reached ("no decoding pattern found");
	      break;
	    }

	  regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
	  /* bit U set.  */
	  if (bit (arm_insn_r->arm_insn, 23))
	    {
	      tgt_mem_addr = u_regval[1] + offset_12;
	    }
	  else
	    {
	      tgt_mem_addr = u_regval[1] - offset_12;
	    }

	  switch (arm_insn_r->opcode)
	    {
	      /* STR.  */
	      case 8:
	      case 12:
	      /* STR.  */    
	      case 9:
	      case 13:
	      /* STRT.  */
	      case 1:
	      case 5:
	      /* STR.  */
	      case 0:
	      case 4:
		record_buf_mem[0] = 4;
	      break;

	      /* STRB.  */
	      case 10:
	      case 14:
	      /* STRB.  */
	      case 11:
	      case 15:
	      /* STRBT.  */    
	      case 3:
	      case 7:
	      /* STRB.  */
	      case 2:
	      case 6:
		record_buf_mem[0] = 1;
	      break;

	      default:
		gdb_assert_not_reached ("no decoding pattern found");
	      break;
	    }
	  record_buf_mem[1] = tgt_mem_addr;
	  arm_insn_r->mem_rec_count = 1;

	  if (9 == arm_insn_r->opcode || 11 == arm_insn_r->opcode
	      || 13 == arm_insn_r->opcode || 15 == arm_insn_r->opcode
	      || 0 == arm_insn_r->opcode || 2 == arm_insn_r->opcode
	      || 4 == arm_insn_r->opcode || 6 == arm_insn_r->opcode
	      || 1 == arm_insn_r->opcode || 3 == arm_insn_r->opcode
	      || 5 == arm_insn_r->opcode || 7 == arm_insn_r->opcode
	     )
	    {
	      /* Rn is going to be changed in register scaled pre-indexed
		 mode,and scaled post indexed mode.  */
	      record_buf[0] = reg_src2;
	      arm_insn_r->reg_rec_count = 1;
	    }
	}
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
  return 0;
}

/* Handle ARM mode instructions with opcode 100.  */

static int
arm_record_ld_st_multiple (insn_decode_record *arm_insn_r)
{
  struct regcache *reg_cache = arm_insn_r->regcache;
  uint32_t register_count = 0, register_bits;
  uint32_t reg_base, addr_mode;
  uint32_t record_buf[24], record_buf_mem[48];
  uint32_t wback;
  ULONGEST u_regval;

  /* Fetch the list of registers.  */
  register_bits = bits (arm_insn_r->arm_insn, 0, 15);
  arm_insn_r->reg_rec_count = 0;

  /* Fetch the base register that contains the address we are loading data
     to.  */
  reg_base = bits (arm_insn_r->arm_insn, 16, 19);

  /* Calculate wback.  */
  wback = (bit (arm_insn_r->arm_insn, 21) == 1);

  if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
    {
      /* LDM/LDMIA/LDMFD, LDMDA/LDMFA, LDMDB and LDMIB.  */

      /* Find out which registers are going to be loaded from memory.  */
      while (register_bits)
	{
	  if (register_bits & 0x00000001)
	    record_buf[arm_insn_r->reg_rec_count++] = register_count;
	  register_bits = register_bits >> 1;
	  register_count++;
	}

  
      /* If wback is true, also save the base register, which is going to be
	 written to.  */
      if (wback)
	record_buf[arm_insn_r->reg_rec_count++] = reg_base;

      /* Save the CPSR register.  */
      record_buf[arm_insn_r->reg_rec_count++] = ARM_PS_REGNUM;
    }
  else
    {
      /* STM (STMIA, STMEA), STMDA (STMED), STMDB (STMFD) and STMIB (STMFA).  */

      addr_mode = bits (arm_insn_r->arm_insn, 23, 24); 

      regcache_raw_read_unsigned (reg_cache, reg_base, &u_regval);

      /* Find out how many registers are going to be stored to memory.  */
      while (register_bits)
	{
	  if (register_bits & 0x00000001)
	    register_count++;
	  register_bits = register_bits >> 1;
	}

      switch (addr_mode)
	{
	  /* STMDA (STMED): Decrement after.  */
	  case 0:
	  record_buf_mem[1] = (uint32_t) u_regval
			      - register_count * ARM_INT_REGISTER_SIZE + 4;
	  break;
	  /* STM (STMIA, STMEA): Increment after.  */
	  case 1:
	  record_buf_mem[1] = (uint32_t) u_regval;
	  break;
	  /* STMDB (STMFD): Decrement before.  */
	  case 2:
	  record_buf_mem[1] = (uint32_t) u_regval
			      - register_count * ARM_INT_REGISTER_SIZE;
	  break;
	  /* STMIB (STMFA): Increment before.  */
	  case 3:
	  record_buf_mem[1] = (uint32_t) u_regval + ARM_INT_REGISTER_SIZE;
	  break;
	  default:
	    gdb_assert_not_reached ("no decoding pattern found");
	  break;
	}

      record_buf_mem[0] = register_count * ARM_INT_REGISTER_SIZE;
      arm_insn_r->mem_rec_count = 1;

      /* If wback is true, also save the base register, which is going to be
	 written to.  */
      if (wback)
	record_buf[arm_insn_r->reg_rec_count++] = reg_base;
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
  return 0;
}

/* Handling opcode 101 insns.  */

static int
arm_record_b_bl (insn_decode_record *arm_insn_r)
{
  uint32_t record_buf[8];

  /* Handle B, BL, BLX(1) insns.  */
  /* B simply branches so we do nothing here.  */
  /* Note: BLX(1) doesnt fall here but instead it falls into
     extension space.  */
  if (bit (arm_insn_r->arm_insn, 24))
    {
      record_buf[0] = ARM_LR_REGNUM;
      arm_insn_r->reg_rec_count = 1;
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);

  return 0;
}

static int
arm_record_unsupported_insn (insn_decode_record *arm_insn_r)
{
  printf_unfiltered (_("Process record does not support instruction "
		       "0x%0x at address %s.\n"),arm_insn_r->arm_insn,
		     paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));

  return -1;
}

/* Record handler for vector data transfer instructions.  */

static int
arm_record_vdata_transfer_insn (insn_decode_record *arm_insn_r)
{
  uint32_t bits_a, bit_c, bit_l, reg_t, reg_v;
  uint32_t record_buf[4];

  reg_t = bits (arm_insn_r->arm_insn, 12, 15);
  reg_v = bits (arm_insn_r->arm_insn, 21, 23);
  bits_a = bits (arm_insn_r->arm_insn, 21, 23);
  bit_l = bit (arm_insn_r->arm_insn, 20);
  bit_c = bit (arm_insn_r->arm_insn, 8);

  /* Handle VMOV instruction.  */
  if (bit_l && bit_c)
    {
      record_buf[0] = reg_t;
      arm_insn_r->reg_rec_count = 1;
    }
  else if (bit_l && !bit_c)
    {
      /* Handle VMOV instruction.  */
      if (bits_a == 0x00)
	{
	  record_buf[0] = reg_t;
	  arm_insn_r->reg_rec_count = 1;
	}
      /* Handle VMRS instruction.  */
      else if (bits_a == 0x07)
	{
	  if (reg_t == 15)
	    reg_t = ARM_PS_REGNUM;

	  record_buf[0] = reg_t;
	  arm_insn_r->reg_rec_count = 1;
	}
    }
  else if (!bit_l && !bit_c)
    {
      /* Handle VMOV instruction.  */
      if (bits_a == 0x00)
	{
	  record_buf[0] = ARM_D0_REGNUM + reg_v;

	  arm_insn_r->reg_rec_count = 1;
	}
      /* Handle VMSR instruction.  */
      else if (bits_a == 0x07)
	{
	  record_buf[0] = ARM_FPSCR_REGNUM;
	  arm_insn_r->reg_rec_count = 1;
	}
    }
  else if (!bit_l && bit_c)
    {
      /* Handle VMOV instruction.  */
      if (!(bits_a & 0x04))
	{
	  record_buf[0] = (reg_v | (bit (arm_insn_r->arm_insn, 7) << 4))
			  + ARM_D0_REGNUM;
	  arm_insn_r->reg_rec_count = 1;
	}
      /* Handle VDUP instruction.  */
      else
	{
	  if (bit (arm_insn_r->arm_insn, 21))
	    {
	      reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
	      record_buf[0] = reg_v + ARM_D0_REGNUM;
	      record_buf[1] = reg_v + ARM_D0_REGNUM + 1;
	      arm_insn_r->reg_rec_count = 2;
	    }
	  else
	    {
	      reg_v = reg_v | (bit (arm_insn_r->arm_insn, 7) << 4);
	      record_buf[0] = reg_v + ARM_D0_REGNUM;
	      arm_insn_r->reg_rec_count = 1;
	    }
	}
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  return 0;
}

/* Record handler for extension register load/store instructions.  */

static int
arm_record_exreg_ld_st_insn (insn_decode_record *arm_insn_r)
{
  uint32_t opcode, single_reg;
  uint8_t op_vldm_vstm;
  uint32_t record_buf[8], record_buf_mem[128];
  ULONGEST u_regval = 0;

  struct regcache *reg_cache = arm_insn_r->regcache;

  opcode = bits (arm_insn_r->arm_insn, 20, 24);
  single_reg = !bit (arm_insn_r->arm_insn, 8);
  op_vldm_vstm = opcode & 0x1b;

  /* Handle VMOV instructions.  */
  if ((opcode & 0x1e) == 0x04)
    {
      if (bit (arm_insn_r->arm_insn, 20)) /* to_arm_registers bit 20? */
	{
	  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  record_buf[1] = bits (arm_insn_r->arm_insn, 16, 19);
	  arm_insn_r->reg_rec_count = 2;
	}
      else
	{
	  uint8_t reg_m = bits (arm_insn_r->arm_insn, 0, 3);
	  uint8_t bit_m = bit (arm_insn_r->arm_insn, 5);

	  if (single_reg)
	    {
	      /* The first S register number m is REG_M:M (M is bit 5),
		 the corresponding D register number is REG_M:M / 2, which
		 is REG_M.  */
	      record_buf[arm_insn_r->reg_rec_count++] = ARM_D0_REGNUM + reg_m;
	      /* The second S register number is REG_M:M + 1, the
		 corresponding D register number is (REG_M:M + 1) / 2.
		 IOW, if bit M is 1, the first and second S registers
		 are mapped to different D registers, otherwise, they are
		 in the same D register.  */
	      if (bit_m)
		{
		  record_buf[arm_insn_r->reg_rec_count++]
		    = ARM_D0_REGNUM + reg_m + 1;
		}
	    }
	  else
	    {
	      record_buf[0] = ((bit_m << 4) + reg_m + ARM_D0_REGNUM);
	      arm_insn_r->reg_rec_count = 1;
	    }
	}
    }
  /* Handle VSTM and VPUSH instructions.  */
  else if (op_vldm_vstm == 0x08 || op_vldm_vstm == 0x0a
	   || op_vldm_vstm == 0x12)
    {
      uint32_t start_address, reg_rn, imm_off32, imm_off8, memory_count;
      uint32_t memory_index = 0;

      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
      imm_off32 = imm_off8 << 2;
      memory_count = imm_off8;

      if (bit (arm_insn_r->arm_insn, 23))
	start_address = u_regval;
      else
	start_address = u_regval - imm_off32;

      if (bit (arm_insn_r->arm_insn, 21))
	{
	  record_buf[0] = reg_rn;
	  arm_insn_r->reg_rec_count = 1;
	}

      while (memory_count > 0)
	{
	  if (single_reg)
	    {
	      record_buf_mem[memory_index] = 4;
	      record_buf_mem[memory_index + 1] = start_address;
	      start_address = start_address + 4;
	      memory_index = memory_index + 2;
	    }
	  else
	    {
	      record_buf_mem[memory_index] = 4;
	      record_buf_mem[memory_index + 1] = start_address;
	      record_buf_mem[memory_index + 2] = 4;
	      record_buf_mem[memory_index + 3] = start_address + 4;
	      start_address = start_address + 8;
	      memory_index = memory_index + 4;
	    }
	  memory_count--;
	}
      arm_insn_r->mem_rec_count = (memory_index >> 1);
    }
  /* Handle VLDM instructions.  */
  else if (op_vldm_vstm == 0x09 || op_vldm_vstm == 0x0b
	   || op_vldm_vstm == 0x13)
    {
      uint32_t reg_count, reg_vd;
      uint32_t reg_index = 0;
      uint32_t bit_d = bit (arm_insn_r->arm_insn, 22);

      reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
      reg_count = bits (arm_insn_r->arm_insn, 0, 7);

      /* REG_VD is the first D register number.  If the instruction
	 loads memory to S registers (SINGLE_REG is TRUE), the register
	 number is (REG_VD << 1 | bit D), so the corresponding D
	 register number is (REG_VD << 1 | bit D) / 2 = REG_VD.  */
      if (!single_reg)
	reg_vd = reg_vd | (bit_d << 4);

      if (bit (arm_insn_r->arm_insn, 21) /* write back */)
	record_buf[reg_index++] = bits (arm_insn_r->arm_insn, 16, 19);

      /* If the instruction loads memory to D register, REG_COUNT should
	 be divided by 2, according to the ARM Architecture Reference
	 Manual.  If the instruction loads memory to S register, divide by
	 2 as well because two S registers are mapped to D register.  */
      reg_count  = reg_count / 2;
      if (single_reg && bit_d)
	{
	  /* Increase the register count if S register list starts from
	     an odd number (bit d is one).  */
	  reg_count++;
	}

      while (reg_count > 0)
	{
	  record_buf[reg_index++] = ARM_D0_REGNUM + reg_vd + reg_count - 1;
	  reg_count--;
	}
      arm_insn_r->reg_rec_count = reg_index;
    }
  /* VSTR Vector store register.  */
  else if ((opcode & 0x13) == 0x10)
    {
      uint32_t start_address, reg_rn, imm_off32, imm_off8;
      uint32_t memory_index = 0;

      reg_rn = bits (arm_insn_r->arm_insn, 16, 19);
      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
      imm_off8 = bits (arm_insn_r->arm_insn, 0, 7);
      imm_off32 = imm_off8 << 2;

      if (bit (arm_insn_r->arm_insn, 23))
	start_address = u_regval + imm_off32;
      else
	start_address = u_regval - imm_off32;

      if (single_reg)
	{
	  record_buf_mem[memory_index] = 4;
	  record_buf_mem[memory_index + 1] = start_address;
	  arm_insn_r->mem_rec_count = 1;
	}
      else
	{
	  record_buf_mem[memory_index] = 4;
	  record_buf_mem[memory_index + 1] = start_address;
	  record_buf_mem[memory_index + 2] = 4;
	  record_buf_mem[memory_index + 3] = start_address + 4;
	  arm_insn_r->mem_rec_count = 2;
	}
    }
  /* VLDR Vector load register.  */
  else if ((opcode & 0x13) == 0x11)
    {
      uint32_t reg_vd = bits (arm_insn_r->arm_insn, 12, 15);

      if (!single_reg)
	{
	  reg_vd = reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4);
	  record_buf[0] = ARM_D0_REGNUM + reg_vd;
	}
      else
	{
	  reg_vd = (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22);
	  /* Record register D rather than pseudo register S.  */
	  record_buf[0] = ARM_D0_REGNUM + reg_vd / 2;
	}
      arm_insn_r->reg_rec_count = 1;
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
  return 0;
}

/* Record handler for arm/thumb mode VFP data processing instructions.  */

static int
arm_record_vfp_data_proc_insn (insn_decode_record *arm_insn_r)
{
  uint32_t opc1, opc2, opc3, dp_op_sz, bit_d, reg_vd;
  uint32_t record_buf[4];
  enum insn_types {INSN_T0, INSN_T1, INSN_T2, INSN_T3, INSN_INV};
  enum insn_types curr_insn_type = INSN_INV;

  reg_vd = bits (arm_insn_r->arm_insn, 12, 15);
  opc1 = bits (arm_insn_r->arm_insn, 20, 23);
  opc2 = bits (arm_insn_r->arm_insn, 16, 19);
  opc3 = bits (arm_insn_r->arm_insn, 6, 7);
  dp_op_sz = bit (arm_insn_r->arm_insn, 8);
  bit_d = bit (arm_insn_r->arm_insn, 22);
  /* Mask off the "D" bit.  */
  opc1 = opc1 & ~0x04;

  /* Handle VMLA, VMLS.  */
  if (opc1 == 0x00)
    {
      if (bit (arm_insn_r->arm_insn, 10))
	{
	  if (bit (arm_insn_r->arm_insn, 6))
	    curr_insn_type = INSN_T0;
	  else
	    curr_insn_type = INSN_T1;
	}
      else
	{
	  if (dp_op_sz)
	    curr_insn_type = INSN_T1;
	  else
	    curr_insn_type = INSN_T2;
	}
    }
  /* Handle VNMLA, VNMLS, VNMUL.  */
  else if (opc1 == 0x01)
    {
      if (dp_op_sz)
	curr_insn_type = INSN_T1;
      else
	curr_insn_type = INSN_T2;
    }
  /* Handle VMUL.  */
  else if (opc1 == 0x02 && !(opc3 & 0x01))
    {
      if (bit (arm_insn_r->arm_insn, 10))
	{
	  if (bit (arm_insn_r->arm_insn, 6))
	    curr_insn_type = INSN_T0;
	  else
	    curr_insn_type = INSN_T1;
	}
      else
	{
	  if (dp_op_sz)
	    curr_insn_type = INSN_T1;
	  else
	    curr_insn_type = INSN_T2;
	}
    }
  /* Handle VADD, VSUB.  */
  else if (opc1 == 0x03)
    {
      if (!bit (arm_insn_r->arm_insn, 9))
	{
	  if (bit (arm_insn_r->arm_insn, 6))
	    curr_insn_type = INSN_T0;
	  else
	    curr_insn_type = INSN_T1;
	}
      else
	{
	  if (dp_op_sz)
	    curr_insn_type = INSN_T1;
	  else
	    curr_insn_type = INSN_T2;
	}
    }
  /* Handle VDIV.  */
  else if (opc1 == 0x08)
    {
      if (dp_op_sz)
	curr_insn_type = INSN_T1;
      else
	curr_insn_type = INSN_T2;
    }
  /* Handle all other vfp data processing instructions.  */
  else if (opc1 == 0x0b)
    {
      /* Handle VMOV.  */
      if (!(opc3 & 0x01) || (opc2 == 0x00 && opc3 == 0x01))
	{
	  if (bit (arm_insn_r->arm_insn, 4))
	    {
	      if (bit (arm_insn_r->arm_insn, 6))
		curr_insn_type = INSN_T0;
	      else
		curr_insn_type = INSN_T1;
	    }
	  else
	    {
	      if (dp_op_sz)
		curr_insn_type = INSN_T1;
	      else
		curr_insn_type = INSN_T2;
	    }
	}
      /* Handle VNEG and VABS.  */
      else if ((opc2 == 0x01 && opc3 == 0x01)
	      || (opc2 == 0x00 && opc3 == 0x03))
	{
	  if (!bit (arm_insn_r->arm_insn, 11))
	    {
	      if (bit (arm_insn_r->arm_insn, 6))
		curr_insn_type = INSN_T0;
	      else
		curr_insn_type = INSN_T1;
	    }
	  else
	    {
	      if (dp_op_sz)
		curr_insn_type = INSN_T1;
	      else
		curr_insn_type = INSN_T2;
	    }
	}
      /* Handle VSQRT.  */
      else if (opc2 == 0x01 && opc3 == 0x03)
	{
	  if (dp_op_sz)
	    curr_insn_type = INSN_T1;
	  else
	    curr_insn_type = INSN_T2;
	}
      /* Handle VCVT.  */
      else if (opc2 == 0x07 && opc3 == 0x03)
	{
	  if (!dp_op_sz)
	    curr_insn_type = INSN_T1;
	  else
	    curr_insn_type = INSN_T2;
	}
      else if (opc3 & 0x01)
	{
	  /* Handle VCVT.  */
	  if ((opc2 == 0x08) || (opc2 & 0x0e) == 0x0c)
	    {
	      if (!bit (arm_insn_r->arm_insn, 18))
		curr_insn_type = INSN_T2;
	      else
		{
		  if (dp_op_sz)
		    curr_insn_type = INSN_T1;
		  else
		    curr_insn_type = INSN_T2;
		}
	    }
	  /* Handle VCVT.  */
	  else if ((opc2 & 0x0e) == 0x0a || (opc2 & 0x0e) == 0x0e)
	    {
	      if (dp_op_sz)
		curr_insn_type = INSN_T1;
	      else
		curr_insn_type = INSN_T2;
	    }
	  /* Handle VCVTB, VCVTT.  */
	  else if ((opc2 & 0x0e) == 0x02)
	    curr_insn_type = INSN_T2;
	  /* Handle VCMP, VCMPE.  */
	  else if ((opc2 & 0x0e) == 0x04)
	    curr_insn_type = INSN_T3;
	}
    }

  switch (curr_insn_type)
    {
      case INSN_T0:
	reg_vd = reg_vd | (bit_d << 4);
	record_buf[0] = reg_vd + ARM_D0_REGNUM;
	record_buf[1] = reg_vd + ARM_D0_REGNUM + 1;
	arm_insn_r->reg_rec_count = 2;
	break;

      case INSN_T1:
	reg_vd = reg_vd | (bit_d << 4);
	record_buf[0] = reg_vd + ARM_D0_REGNUM;
	arm_insn_r->reg_rec_count = 1;
	break;

      case INSN_T2:
	reg_vd = (reg_vd << 1) | bit_d;
	record_buf[0] = reg_vd + ARM_D0_REGNUM;
	arm_insn_r->reg_rec_count = 1;
	break;

      case INSN_T3:
	record_buf[0] = ARM_FPSCR_REGNUM;
	arm_insn_r->reg_rec_count = 1;
	break;

      default:
	gdb_assert_not_reached ("no decoding pattern found");
	break;
    }

  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
  return 0;
}

/* Handling opcode 110 insns.  */

static int
arm_record_asimd_vfp_coproc (insn_decode_record *arm_insn_r)
{
  uint32_t op1, op1_ebit, coproc;

  coproc = bits (arm_insn_r->arm_insn, 8, 11);
  op1 = bits (arm_insn_r->arm_insn, 20, 25);
  op1_ebit = bit (arm_insn_r->arm_insn, 20);

  if ((coproc & 0x0e) == 0x0a)
    {
      /* Handle extension register ld/st instructions.  */
      if (!(op1 & 0x20))
	return arm_record_exreg_ld_st_insn (arm_insn_r);

      /* 64-bit transfers between arm core and extension registers.  */
      if ((op1 & 0x3e) == 0x04)
	return arm_record_exreg_ld_st_insn (arm_insn_r);
    }
  else
    {
      /* Handle coprocessor ld/st instructions.  */
      if (!(op1 & 0x3a))
	{
	  /* Store.  */
	  if (!op1_ebit)
	    return arm_record_unsupported_insn (arm_insn_r);
	  else
	    /* Load.  */
	    return arm_record_unsupported_insn (arm_insn_r);
	}

      /* Move to coprocessor from two arm core registers.  */
      if (op1 == 0x4)
	return arm_record_unsupported_insn (arm_insn_r);

      /* Move to two arm core registers from coprocessor.  */
      if (op1 == 0x5)
	{
	  uint32_t reg_t[2];

	  reg_t[0] = bits (arm_insn_r->arm_insn, 12, 15);
	  reg_t[1] = bits (arm_insn_r->arm_insn, 16, 19);
	  arm_insn_r->reg_rec_count = 2;

	  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, reg_t);
	  return 0;
       }
    }
  return arm_record_unsupported_insn (arm_insn_r);
}

/* Handling opcode 111 insns.  */

static int
arm_record_coproc_data_proc (insn_decode_record *arm_insn_r)
{
  uint32_t op, op1_ebit, coproc, bits_24_25;
  arm_gdbarch_tdep *tdep
    = (arm_gdbarch_tdep *) gdbarch_tdep (arm_insn_r->gdbarch);
  struct regcache *reg_cache = arm_insn_r->regcache;

  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 24, 27);
  coproc = bits (arm_insn_r->arm_insn, 8, 11);
  op1_ebit = bit (arm_insn_r->arm_insn, 20);
  op = bit (arm_insn_r->arm_insn, 4);
  bits_24_25 = bits (arm_insn_r->arm_insn, 24, 25);

  /* Handle arm SWI/SVC system call instructions.  */
  if (bits_24_25 == 0x3)
    {
      if (tdep->arm_syscall_record != NULL)
	{
	  ULONGEST svc_operand, svc_number;

	  svc_operand = (0x00ffffff & arm_insn_r->arm_insn);

	  if (svc_operand)  /* OABI.  */
	    svc_number = svc_operand - 0x900000;
	  else /* EABI.  */
	    regcache_raw_read_unsigned (reg_cache, 7, &svc_number);

	  return tdep->arm_syscall_record (reg_cache, svc_number);
	}
      else
	{
	  printf_unfiltered (_("no syscall record support\n"));
	  return -1;
	}
    }
  else if (bits_24_25 == 0x02)
    {
      if (op)
	{
	  if ((coproc & 0x0e) == 0x0a)
	    {
	      /* 8, 16, and 32-bit transfer */
	      return arm_record_vdata_transfer_insn (arm_insn_r);
	    }
	  else
	    {
	      if (op1_ebit)
		{
		  /* MRC, MRC2 */
		  uint32_t record_buf[1];

		  record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
		  if (record_buf[0] == 15)
		    record_buf[0] = ARM_PS_REGNUM;

		  arm_insn_r->reg_rec_count = 1;
		  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count,
			     record_buf);
		  return 0;
		}
	      else
		{
		  /* MCR, MCR2 */
		  return -1;
		}
	    }
	}
      else
	{
	  if ((coproc & 0x0e) == 0x0a)
	    {
	      /* VFP data-processing instructions.  */
	      return arm_record_vfp_data_proc_insn (arm_insn_r);
	    }
	  else
	    {
	      /* CDP, CDP2 */
	      return -1;
	    }
	}
    }
  else
    {
      unsigned int op1 = bits (arm_insn_r->arm_insn, 20, 25);

      if (op1 == 5)
	{
	  if ((coproc & 0x0e) != 0x0a)
	    {
	      /* MRRC, MRRC2 */
	      return -1;
	    }
	}
      else if (op1 == 4 || op1 == 5)
	{
	  if ((coproc & 0x0e) == 0x0a)
	    {
	      /* 64-bit transfers between ARM core and extension */
	      return -1;
	    }
	  else if (op1 == 4)
	    {
	      /* MCRR, MCRR2 */
	      return -1;
	    }
	}
      else if (op1 == 0 || op1 == 1)
	{
	  /* UNDEFINED */
	  return -1;
	}
      else
	{
	  if ((coproc & 0x0e) == 0x0a)
	    {
	      /* Extension register load/store */
	    }
	  else
	    {
	      /* STC, STC2, LDC, LDC2 */
	    }
	  return -1;
	}
    }

  return -1;
}

/* Handling opcode 000 insns.  */

static int
thumb_record_shift_add_sub (insn_decode_record *thumb_insn_r)
{
  uint32_t record_buf[8];
  uint32_t reg_src1 = 0;

  reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);

  record_buf[0] = ARM_PS_REGNUM;
  record_buf[1] = reg_src1;
  thumb_insn_r->reg_rec_count = 2;

  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);

  return 0;
}


/* Handling opcode 001 insns.  */

static int
thumb_record_add_sub_cmp_mov (insn_decode_record *thumb_insn_r)
{
  uint32_t record_buf[8];
  uint32_t reg_src1 = 0;

  reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);

  record_buf[0] = ARM_PS_REGNUM;
  record_buf[1] = reg_src1;
  thumb_insn_r->reg_rec_count = 2;

  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);

  return 0;
}

/* Handling opcode 010 insns.  */

static int
thumb_record_ld_st_reg_offset (insn_decode_record *thumb_insn_r)
{
  struct regcache *reg_cache =  thumb_insn_r->regcache;
  uint32_t record_buf[8], record_buf_mem[8];

  uint32_t reg_src1 = 0, reg_src2 = 0;
  uint32_t opcode1 = 0, opcode2 = 0, opcode3 = 0;

  ULONGEST u_regval[2] = {0};

  opcode1 = bits (thumb_insn_r->arm_insn, 10, 12);

  if (bit (thumb_insn_r->arm_insn, 12))
    {
      /* Handle load/store register offset.  */
      uint32_t opB = bits (thumb_insn_r->arm_insn, 9, 11);

      if (in_inclusive_range (opB, 4U, 7U))
	{
	  /* LDR(2), LDRB(2) , LDRH(2), LDRSB, LDRSH.  */
	  reg_src1 = bits (thumb_insn_r->arm_insn,0, 2);
	  record_buf[0] = reg_src1;
	  thumb_insn_r->reg_rec_count = 1;
	}
      else if (in_inclusive_range (opB, 0U, 2U))
	{
	  /* STR(2), STRB(2), STRH(2) .  */
	  reg_src1 = bits (thumb_insn_r->arm_insn, 3, 5);
	  reg_src2 = bits (thumb_insn_r->arm_insn, 6, 8);
	  regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval[0]);
	  regcache_raw_read_unsigned (reg_cache, reg_src2, &u_regval[1]);
	  if (0 == opB)
	    record_buf_mem[0] = 4;    /* STR (2).  */
	  else if (2 == opB)
	    record_buf_mem[0] = 1;    /*  STRB (2).  */
	  else if (1 == opB)
	    record_buf_mem[0] = 2;    /* STRH (2).  */
	  record_buf_mem[1] = u_regval[0] + u_regval[1];
	  thumb_insn_r->mem_rec_count = 1;
	}
    }
  else if (bit (thumb_insn_r->arm_insn, 11))
    {
      /* Handle load from literal pool.  */
      /* LDR(3).  */
      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
      record_buf[0] = reg_src1;
      thumb_insn_r->reg_rec_count = 1;
    }
  else if (opcode1)
    {
      /* Special data instructions and branch and exchange */
      opcode2 = bits (thumb_insn_r->arm_insn, 8, 9);
      opcode3 = bits (thumb_insn_r->arm_insn, 0, 2);
      if ((3 == opcode2) && (!opcode3))
	{
	  /* Branch with exchange.  */
	  record_buf[0] = ARM_PS_REGNUM;
	  thumb_insn_r->reg_rec_count = 1;
	}
      else
	{
	  /* Format 8; special data processing insns.  */
	  record_buf[0] = ARM_PS_REGNUM;
	  record_buf[1] = (bit (thumb_insn_r->arm_insn, 7) << 3
			   | bits (thumb_insn_r->arm_insn, 0, 2));
	  thumb_insn_r->reg_rec_count = 2;
	}
    }
  else
    {
      /* Format 5; data processing insns.  */
      reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
      if (bit (thumb_insn_r->arm_insn, 7))
	{
	  reg_src1 = reg_src1 + 8;
	}
      record_buf[0] = ARM_PS_REGNUM;
      record_buf[1] = reg_src1;
      thumb_insn_r->reg_rec_count = 2;
    }

  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
	     record_buf_mem);

  return 0;
}

/* Handling opcode 001 insns.  */

static int
thumb_record_ld_st_imm_offset (insn_decode_record *thumb_insn_r)
{
  struct regcache *reg_cache = thumb_insn_r->regcache;
  uint32_t record_buf[8], record_buf_mem[8];

  uint32_t reg_src1 = 0;
  uint32_t opcode = 0, immed_5 = 0;

  ULONGEST u_regval = 0;

  opcode = bits (thumb_insn_r->arm_insn, 11, 12);

  if (opcode)
    {
      /* LDR(1).  */
      reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
      record_buf[0] = reg_src1;
      thumb_insn_r->reg_rec_count = 1;
    }
  else
    {
      /* STR(1).  */
      reg_src1 = bits (thumb_insn_r->arm_insn, 3, 5);
      immed_5 = bits (thumb_insn_r->arm_insn, 6, 10);
      regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval);
      record_buf_mem[0] = 4;
      record_buf_mem[1] = u_regval + (immed_5 * 4);
      thumb_insn_r->mem_rec_count = 1;
    }

  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, 
	     record_buf_mem);

  return 0;
}

/* Handling opcode 100 insns.  */

static int
thumb_record_ld_st_stack (insn_decode_record *thumb_insn_r)
{
  struct regcache *reg_cache = thumb_insn_r->regcache;
  uint32_t record_buf[8], record_buf_mem[8];

  uint32_t reg_src1 = 0;
  uint32_t opcode = 0, immed_8 = 0, immed_5 = 0;

  ULONGEST u_regval = 0;

  opcode = bits (thumb_insn_r->arm_insn, 11, 12);

  if (3 == opcode)
    {
      /* LDR(4).  */
      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
      record_buf[0] = reg_src1;
      thumb_insn_r->reg_rec_count = 1;
    }
  else if (1 == opcode)
    {
      /* LDRH(1).  */
      reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
      record_buf[0] = reg_src1;
      thumb_insn_r->reg_rec_count = 1;
    }
  else if (2 == opcode)
    {
      /* STR(3).  */
      immed_8 = bits (thumb_insn_r->arm_insn, 0, 7);
      regcache_raw_read_unsigned (reg_cache, ARM_SP_REGNUM, &u_regval);
      record_buf_mem[0] = 4;
      record_buf_mem[1] = u_regval + (immed_8 * 4);
      thumb_insn_r->mem_rec_count = 1;
    }
  else if (0 == opcode)
    {
      /* STRH(1).  */
      immed_5 = bits (thumb_insn_r->arm_insn, 6, 10);
      reg_src1 = bits (thumb_insn_r->arm_insn, 3, 5);
      regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval);
      record_buf_mem[0] = 2;
      record_buf_mem[1] = u_regval + (immed_5 * 2);
      thumb_insn_r->mem_rec_count = 1;
    }

  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
	     record_buf_mem);

  return 0;
}

/* Handling opcode 101 insns.  */

static int
thumb_record_misc (insn_decode_record *thumb_insn_r)
{
  struct regcache *reg_cache = thumb_insn_r->regcache;

  uint32_t opcode = 0;
  uint32_t register_bits = 0, register_count = 0;
  uint32_t index = 0, start_address = 0;
  uint32_t record_buf[24], record_buf_mem[48];
  uint32_t reg_src1;

  ULONGEST u_regval = 0;

  opcode = bits (thumb_insn_r->arm_insn, 11, 12);

  if (opcode == 0 || opcode == 1)
    {
      /* ADR and ADD (SP plus immediate) */

      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
      record_buf[0] = reg_src1;
      thumb_insn_r->reg_rec_count = 1;
    }
  else
    {
      /* Miscellaneous 16-bit instructions */
      uint32_t opcode2 = bits (thumb_insn_r->arm_insn, 8, 11);

      switch (opcode2)
	{
	case 6:
	  /* SETEND and CPS */
	  break;
	case 0:
	  /* ADD/SUB (SP plus immediate)  */
	  reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
	  record_buf[0] = ARM_SP_REGNUM;
	  thumb_insn_r->reg_rec_count = 1;
	  break;
	case 1: /* fall through  */
	case 3: /* fall through  */
	case 9: /* fall through  */
	case 11:
	  /* CBNZ, CBZ */
	  break;
	case 2:
	  /* SXTH, SXTB, UXTH, UXTB */
	  record_buf[0] = bits (thumb_insn_r->arm_insn, 0, 2);
	  thumb_insn_r->reg_rec_count = 1;
	  break;
	case 4: /* fall through  */
	case 5:
	  /* PUSH.  */
	  register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
	  regcache_raw_read_unsigned (reg_cache, ARM_SP_REGNUM, &u_regval);
	  while (register_bits)
	    {
	      if (register_bits & 0x00000001)
		register_count++;
	      register_bits = register_bits >> 1;
	    }
	  start_address = u_regval -  \
	    (4 * (bit (thumb_insn_r->arm_insn, 8) + register_count));
	  thumb_insn_r->mem_rec_count = register_count;
	  while (register_count)
	    {
	      record_buf_mem[(register_count * 2) - 1] = start_address;
	      record_buf_mem[(register_count * 2) - 2] = 4;
	      start_address = start_address + 4;
	      register_count--;
	    }
	  record_buf[0] = ARM_SP_REGNUM;
	  thumb_insn_r->reg_rec_count = 1;
	  break;
	case 10:
	  /* REV, REV16, REVSH */
	  record_buf[0] = bits (thumb_insn_r->arm_insn, 0, 2);
	  thumb_insn_r->reg_rec_count = 1;
	  break;
	case 12: /* fall through  */
	case 13:
	  /* POP.  */
	  register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
	  while (register_bits)
	    {
	      if (register_bits & 0x00000001)
		record_buf[index++] = register_count;
	      register_bits = register_bits >> 1;
	      register_count++;
	    }
	  record_buf[index++] = ARM_PS_REGNUM;
	  record_buf[index++] = ARM_SP_REGNUM;
	  thumb_insn_r->reg_rec_count = index;
	  break;
	case 0xe:
	  /* BKPT insn.  */
	  /* Handle enhanced software breakpoint insn, BKPT.  */
	  /* CPSR is changed to be executed in ARM state,  disabling normal
	     interrupts, entering abort mode.  */
	  /* According to high vector configuration PC is set.  */
	  /* User hits breakpoint and type reverse, in that case, we need to go back with 
	     previous CPSR and Program Counter.  */
	  record_buf[0] = ARM_PS_REGNUM;
	  record_buf[1] = ARM_LR_REGNUM;
	  thumb_insn_r->reg_rec_count = 2;
	  /* We need to save SPSR value, which is not yet done.  */
	  printf_unfiltered (_("Process record does not support instruction "
			       "0x%0x at address %s.\n"),
			     thumb_insn_r->arm_insn,
			     paddress (thumb_insn_r->gdbarch,
				       thumb_insn_r->this_addr));
	  return -1;

	case 0xf:
	  /* If-Then, and hints */
	  break;
	default:
	  return -1;
	};
    }

  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
	     record_buf_mem);

  return 0;
}

/* Handling opcode 110 insns.  */

static int
thumb_record_ldm_stm_swi (insn_decode_record *thumb_insn_r)
{
  arm_gdbarch_tdep *tdep
    = (arm_gdbarch_tdep *) gdbarch_tdep  (thumb_insn_r->gdbarch);
  struct regcache *reg_cache = thumb_insn_r->regcache;

  uint32_t ret = 0; /* function return value: -1:record failure ;  0:success  */
  uint32_t reg_src1 = 0;
  uint32_t opcode1 = 0, opcode2 = 0, register_bits = 0, register_count = 0;
  uint32_t index = 0, start_address = 0;
  uint32_t record_buf[24], record_buf_mem[48];

  ULONGEST u_regval = 0;

  opcode1 = bits (thumb_insn_r->arm_insn, 8, 12);
  opcode2 = bits (thumb_insn_r->arm_insn, 11, 12);

  if (1 == opcode2)
    {

      /* LDMIA.  */
      register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
      /* Get Rn.  */
      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
      while (register_bits)
	{
	  if (register_bits & 0x00000001)
	    record_buf[index++] = register_count;
	  register_bits = register_bits >> 1;
	  register_count++;
	}
      record_buf[index++] = reg_src1;
      thumb_insn_r->reg_rec_count = index;
    }
  else if (0 == opcode2)
    {
      /* It handles both STMIA.  */
      register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
      /* Get Rn.  */
      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
      regcache_raw_read_unsigned (reg_cache, reg_src1, &u_regval);
      while (register_bits)
	{
	  if (register_bits & 0x00000001)
	    register_count++;
	  register_bits = register_bits >> 1;
	}
      start_address = u_regval;
      thumb_insn_r->mem_rec_count = register_count;
      while (register_count)
	{
	  record_buf_mem[(register_count * 2) - 1] = start_address;
	  record_buf_mem[(register_count * 2) - 2] = 4;
	  start_address = start_address + 4;
	  register_count--;
	}
    }
  else if (0x1F == opcode1)
    {
	/* Handle arm syscall insn.  */
	if (tdep->arm_syscall_record != NULL)
	  {
	    regcache_raw_read_unsigned (reg_cache, 7, &u_regval);
	    ret = tdep->arm_syscall_record (reg_cache, u_regval);
	  }
	else
	  {
	    printf_unfiltered (_("no syscall record support\n"));
	    return -1;
	  }
    }

  /* B (1), conditional branch is automatically taken care in process_record,
    as PC is saved there.  */

  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count,
	     record_buf_mem);

  return ret;
}

/* Handling opcode 111 insns.  */

static int
thumb_record_branch (insn_decode_record *thumb_insn_r)
{
  uint32_t record_buf[8];
  uint32_t bits_h = 0;

  bits_h = bits (thumb_insn_r->arm_insn, 11, 12);

  if (2 == bits_h || 3 == bits_h)
    {
      /* BL */
      record_buf[0] = ARM_LR_REGNUM;
      thumb_insn_r->reg_rec_count = 1;
    }
  else if (1 == bits_h)
    {
      /* BLX(1). */
      record_buf[0] = ARM_PS_REGNUM;
      record_buf[1] = ARM_LR_REGNUM;
      thumb_insn_r->reg_rec_count = 2;
    }

  /* B(2) is automatically taken care in process_record, as PC is 
     saved there.  */

  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);

  return 0;     
}

/* Handler for thumb2 load/store multiple instructions.  */

static int
thumb2_record_ld_st_multiple (insn_decode_record *thumb2_insn_r)
{
  struct regcache *reg_cache = thumb2_insn_r->regcache;

  uint32_t reg_rn, op;
  uint32_t register_bits = 0, register_count = 0;
  uint32_t index = 0, start_address = 0;
  uint32_t record_buf[24], record_buf_mem[48];

  ULONGEST u_regval = 0;

  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
  op = bits (thumb2_insn_r->arm_insn, 23, 24);

  if (0 == op || 3 == op)
    {
      if (bit (thumb2_insn_r->arm_insn, INSN_S_L_BIT_NUM))
	{
	  /* Handle RFE instruction.  */
	  record_buf[0] = ARM_PS_REGNUM;
	  thumb2_insn_r->reg_rec_count = 1;
	}
      else
	{
	  /* Handle SRS instruction after reading banked SP.  */
	  return arm_record_unsupported_insn (thumb2_insn_r);
	}
    }
  else if (1 == op || 2 == op)
    {
      if (bit (thumb2_insn_r->arm_insn, INSN_S_L_BIT_NUM))
	{
	  /* Handle LDM/LDMIA/LDMFD and LDMDB/LDMEA instructions.  */
	  register_bits = bits (thumb2_insn_r->arm_insn, 0, 15);
	  while (register_bits)
	    {
	      if (register_bits & 0x00000001)
		record_buf[index++] = register_count;

	      register_count++;
	      register_bits = register_bits >> 1;
	    }
	  record_buf[index++] = reg_rn;
	  record_buf[index++] = ARM_PS_REGNUM;
	  thumb2_insn_r->reg_rec_count = index;
	}
      else
	{
	  /* Handle STM/STMIA/STMEA and STMDB/STMFD.  */
	  register_bits = bits (thumb2_insn_r->arm_insn, 0, 15);
	  regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
	  while (register_bits)
	    {
	      if (register_bits & 0x00000001)
		register_count++;

	      register_bits = register_bits >> 1;
	    }

	  if (1 == op)
	    {
	      /* Start address calculation for LDMDB/LDMEA.  */
	      start_address = u_regval;
	    }
	  else if (2 == op)
	    {
	      /* Start address calculation for LDMDB/LDMEA.  */
	      start_address = u_regval - register_count * 4;
	    }

	  thumb2_insn_r->mem_rec_count = register_count;
	  while (register_count)
	    {
	      record_buf_mem[register_count * 2 - 1] = start_address;
	      record_buf_mem[register_count * 2 - 2] = 4;
	      start_address = start_address + 4;
	      register_count--;
	    }
	  record_buf[0] = reg_rn;
	  record_buf[1] = ARM_PS_REGNUM;
	  thumb2_insn_r->reg_rec_count = 2;
	}
    }

  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
	    record_buf_mem);
  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  return ARM_RECORD_SUCCESS;
}

/* Handler for thumb2 load/store (dual/exclusive) and table branch
   instructions.  */

static int
thumb2_record_ld_st_dual_ex_tbb (insn_decode_record *thumb2_insn_r)
{
  struct regcache *reg_cache = thumb2_insn_r->regcache;

  uint32_t reg_rd, reg_rn, offset_imm;
  uint32_t reg_dest1, reg_dest2;
  uint32_t address, offset_addr;
  uint32_t record_buf[8], record_buf_mem[8];
  uint32_t op1, op2, op3;

  ULONGEST u_regval[2];

  op1 = bits (thumb2_insn_r->arm_insn, 23, 24);
  op2 = bits (thumb2_insn_r->arm_insn, 20, 21);
  op3 = bits (thumb2_insn_r->arm_insn, 4, 7);

  if (bit (thumb2_insn_r->arm_insn, INSN_S_L_BIT_NUM))
    {
      if(!(1 == op1 && 1 == op2 && (0 == op3 || 1 == op3)))
	{
	  reg_dest1 = bits (thumb2_insn_r->arm_insn, 12, 15);
	  record_buf[0] = reg_dest1;
	  record_buf[1] = ARM_PS_REGNUM;
	  thumb2_insn_r->reg_rec_count = 2;
	}

      if (3 == op2 || (op1 & 2) || (1 == op1 && 1 == op2 && 7 == op3))
	{
	  reg_dest2 = bits (thumb2_insn_r->arm_insn, 8, 11);
	  record_buf[2] = reg_dest2;
	  thumb2_insn_r->reg_rec_count = 3;
	}
    }
  else
    {
      reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval[0]);

      if (0 == op1 && 0 == op2)
	{
	  /* Handle STREX.  */
	  offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);
	  address = u_regval[0] + (offset_imm * 4);
	  record_buf_mem[0] = 4;
	  record_buf_mem[1] = address;
	  thumb2_insn_r->mem_rec_count = 1;
	  reg_rd = bits (thumb2_insn_r->arm_insn, 0, 3);
	  record_buf[0] = reg_rd;
	  thumb2_insn_r->reg_rec_count = 1;
	}
      else if (1 == op1 && 0 == op2)
	{
	  reg_rd = bits (thumb2_insn_r->arm_insn, 0, 3);
	  record_buf[0] = reg_rd;
	  thumb2_insn_r->reg_rec_count = 1;
	  address = u_regval[0];
	  record_buf_mem[1] = address;

	  if (4 == op3)
	    {
	      /* Handle STREXB.  */
	      record_buf_mem[0] = 1;
	      thumb2_insn_r->mem_rec_count = 1;
	    }
	  else if (5 == op3)
	    {
	      /* Handle STREXH.  */
	      record_buf_mem[0] = 2 ;
	      thumb2_insn_r->mem_rec_count = 1;
	    }
	  else if (7 == op3)
	    {
	      /* Handle STREXD.  */
	      address = u_regval[0];
	      record_buf_mem[0] = 4;
	      record_buf_mem[2] = 4;
	      record_buf_mem[3] = address + 4;
	      thumb2_insn_r->mem_rec_count = 2;
	    }
	}
      else
	{
	  offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);

	  if (bit (thumb2_insn_r->arm_insn, 24))
	    {
	      if (bit (thumb2_insn_r->arm_insn, 23))
		offset_addr = u_regval[0] + (offset_imm * 4);
	      else
		offset_addr = u_regval[0] - (offset_imm * 4);

	      address = offset_addr;
	    }
	  else
	    address = u_regval[0];

	  record_buf_mem[0] = 4;
	  record_buf_mem[1] = address;
	  record_buf_mem[2] = 4;
	  record_buf_mem[3] = address + 4;
	  thumb2_insn_r->mem_rec_count = 2;
	  record_buf[0] = reg_rn;
	  thumb2_insn_r->reg_rec_count = 1;
	}
    }

  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
	    record_buf_mem);
  return ARM_RECORD_SUCCESS;
}

/* Handler for thumb2 data processing (shift register and modified immediate)
   instructions.  */

static int
thumb2_record_data_proc_sreg_mimm (insn_decode_record *thumb2_insn_r)
{
  uint32_t reg_rd, op;
  uint32_t record_buf[8];

  op = bits (thumb2_insn_r->arm_insn, 21, 24);
  reg_rd = bits (thumb2_insn_r->arm_insn, 8, 11);

  if ((0 == op || 4 == op || 8 == op || 13 == op) && 15 == reg_rd)
    {
      record_buf[0] = ARM_PS_REGNUM;
      thumb2_insn_r->reg_rec_count = 1;
    }
  else
    {
      record_buf[0] = reg_rd;
      record_buf[1] = ARM_PS_REGNUM;
      thumb2_insn_r->reg_rec_count = 2;
    }

  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  return ARM_RECORD_SUCCESS;
}

/* Generic handler for thumb2 instructions which effect destination and PS
   registers.  */

static int
thumb2_record_ps_dest_generic (insn_decode_record *thumb2_insn_r)
{
  uint32_t reg_rd;
  uint32_t record_buf[8];

  reg_rd = bits (thumb2_insn_r->arm_insn, 8, 11);

  record_buf[0] = reg_rd;
  record_buf[1] = ARM_PS_REGNUM;
  thumb2_insn_r->reg_rec_count = 2;

  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  return ARM_RECORD_SUCCESS;
}

/* Handler for thumb2 branch and miscellaneous control instructions.  */

static int
thumb2_record_branch_misc_cntrl (insn_decode_record *thumb2_insn_r)
{
  uint32_t op, op1, op2;
  uint32_t record_buf[8];

  op = bits (thumb2_insn_r->arm_insn, 20, 26);
  op1 = bits (thumb2_insn_r->arm_insn, 12, 14);
  op2 = bits (thumb2_insn_r->arm_insn, 8, 11);

  /* Handle MSR insn.  */
  if (!(op1 & 0x2) && 0x38 == op)
    {
      if (!(op2 & 0x3))
	{
	  /* CPSR is going to be changed.  */
	  record_buf[0] = ARM_PS_REGNUM;
	  thumb2_insn_r->reg_rec_count = 1;
	}
      else
	{
	  arm_record_unsupported_insn(thumb2_insn_r);
	  return -1;
	}
    }
  else if (4 == (op1 & 0x5) || 5 == (op1 & 0x5))
    {
      /* BLX.  */
      record_buf[0] = ARM_PS_REGNUM;
      record_buf[1] = ARM_LR_REGNUM;
      thumb2_insn_r->reg_rec_count = 2;
    }

  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  return ARM_RECORD_SUCCESS;
}

/* Handler for thumb2 store single data item instructions.  */

static int
thumb2_record_str_single_data (insn_decode_record *thumb2_insn_r)
{
  struct regcache *reg_cache = thumb2_insn_r->regcache;

  uint32_t reg_rn, reg_rm, offset_imm, shift_imm;
  uint32_t address, offset_addr;
  uint32_t record_buf[8], record_buf_mem[8];
  uint32_t op1, op2;

  ULONGEST u_regval[2];

  op1 = bits (thumb2_insn_r->arm_insn, 21, 23);
  op2 = bits (thumb2_insn_r->arm_insn, 6, 11);
  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
  regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval[0]);

  if (bit (thumb2_insn_r->arm_insn, 23))
    {
      /* T2 encoding.  */
      offset_imm = bits (thumb2_insn_r->arm_insn, 0, 11);
      offset_addr = u_regval[0] + offset_imm;
      address = offset_addr;
    }
  else
    {
      /* T3 encoding.  */
      if ((0 == op1 || 1 == op1 || 2 == op1) && !(op2 & 0x20))
	{
	  /* Handle STRB (register).  */
	  reg_rm = bits (thumb2_insn_r->arm_insn, 0, 3);
	  regcache_raw_read_unsigned (reg_cache, reg_rm, &u_regval[1]);
	  shift_imm = bits (thumb2_insn_r->arm_insn, 4, 5);
	  offset_addr = u_regval[1] << shift_imm;
	  address = u_regval[0] + offset_addr;
	}
      else
	{
	  offset_imm = bits (thumb2_insn_r->arm_insn, 0, 7);
	  if (bit (thumb2_insn_r->arm_insn, 10))
	    {
	      if (bit (thumb2_insn_r->arm_insn, 9))
		offset_addr = u_regval[0] + offset_imm;
	      else
		offset_addr = u_regval[0] - offset_imm;

	      address = offset_addr;
	    }
	  else
	    address = u_regval[0];
	}
    }

  switch (op1)
    {
      /* Store byte instructions.  */
      case 4:
      case 0:
	record_buf_mem[0] = 1;
	break;
      /* Store half word instructions.  */
      case 1:
      case 5:
	record_buf_mem[0] = 2;
	break;
      /* Store word instructions.  */
      case 2:
      case 6:
	record_buf_mem[0] = 4;
	break;

      default:
	gdb_assert_not_reached ("no decoding pattern found");
	break;
    }

  record_buf_mem[1] = address;
  thumb2_insn_r->mem_rec_count = 1;
  record_buf[0] = reg_rn;
  thumb2_insn_r->reg_rec_count = 1;

  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
	    record_buf_mem);
  return ARM_RECORD_SUCCESS;
}

/* Handler for thumb2 load memory hints instructions.  */

static int
thumb2_record_ld_mem_hints (insn_decode_record *thumb2_insn_r)
{
  uint32_t record_buf[8];
  uint32_t reg_rt, reg_rn;

  reg_rt = bits (thumb2_insn_r->arm_insn, 12, 15);
  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);

  if (ARM_PC_REGNUM != reg_rt)
    {
      record_buf[0] = reg_rt;
      record_buf[1] = reg_rn;
      record_buf[2] = ARM_PS_REGNUM;
      thumb2_insn_r->reg_rec_count = 3;

      REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
		record_buf);
      return ARM_RECORD_SUCCESS;
    }

  return ARM_RECORD_FAILURE;
}

/* Handler for thumb2 load word instructions.  */

static int
thumb2_record_ld_word (insn_decode_record *thumb2_insn_r)
{
  uint32_t record_buf[8];

  record_buf[0] = bits (thumb2_insn_r->arm_insn, 12, 15);
  record_buf[1] = ARM_PS_REGNUM;
  thumb2_insn_r->reg_rec_count = 2;

  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  return ARM_RECORD_SUCCESS;
}

/* Handler for thumb2 long multiply, long multiply accumulate, and
   divide instructions.  */

static int
thumb2_record_lmul_lmla_div (insn_decode_record *thumb2_insn_r)
{
  uint32_t opcode1 = 0, opcode2 = 0;
  uint32_t record_buf[8];

  opcode1 = bits (thumb2_insn_r->arm_insn, 20, 22);
  opcode2 = bits (thumb2_insn_r->arm_insn, 4, 7);

  if (0 == opcode1 || 2 == opcode1 || (opcode1 >= 4 && opcode1 <= 6))
    {
      /* Handle SMULL, UMULL, SMULAL.  */
      /* Handle SMLAL(S), SMULL(S), UMLAL(S), UMULL(S).  */
      record_buf[0] = bits (thumb2_insn_r->arm_insn, 16, 19);
      record_buf[1] = bits (thumb2_insn_r->arm_insn, 12, 15);
      record_buf[2] = ARM_PS_REGNUM;
      thumb2_insn_r->reg_rec_count = 3;
    }
  else if (1 == opcode1 || 3 == opcode2)
    {
      /* Handle SDIV and UDIV.  */
      record_buf[0] = bits (thumb2_insn_r->arm_insn, 16, 19);
      record_buf[1] = bits (thumb2_insn_r->arm_insn, 12, 15);
      record_buf[2] = ARM_PS_REGNUM;
      thumb2_insn_r->reg_rec_count = 3;
    }
  else
    return ARM_RECORD_FAILURE;

  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  return ARM_RECORD_SUCCESS;
}

/* Record handler for thumb32 coprocessor instructions.  */

static int
thumb2_record_coproc_insn (insn_decode_record *thumb2_insn_r)
{
  if (bit (thumb2_insn_r->arm_insn, 25))
    return arm_record_coproc_data_proc (thumb2_insn_r);
  else
    return arm_record_asimd_vfp_coproc (thumb2_insn_r);
}

/* Record handler for advance SIMD structure load/store instructions.  */

static int
thumb2_record_asimd_struct_ld_st (insn_decode_record *thumb2_insn_r)
{
  struct regcache *reg_cache = thumb2_insn_r->regcache;
  uint32_t l_bit, a_bit, b_bits;
  uint32_t record_buf[128], record_buf_mem[128];
  uint32_t reg_rn, reg_vd, address, f_elem;
  uint32_t index_r = 0, index_e = 0, bf_regs = 0, index_m = 0, loop_t = 0;
  uint8_t f_ebytes;

  l_bit = bit (thumb2_insn_r->arm_insn, 21);
  a_bit = bit (thumb2_insn_r->arm_insn, 23);
  b_bits = bits (thumb2_insn_r->arm_insn, 8, 11);
  reg_rn = bits (thumb2_insn_r->arm_insn, 16, 19);
  reg_vd = bits (thumb2_insn_r->arm_insn, 12, 15);
  reg_vd = (bit (thumb2_insn_r->arm_insn, 22) << 4) | reg_vd;
  f_ebytes = (1 << bits (thumb2_insn_r->arm_insn, 6, 7));
  f_elem = 8 / f_ebytes;

  if (!l_bit)
    {
      ULONGEST u_regval = 0;
      regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval);
      address = u_regval;

      if (!a_bit)
	{
	  /* Handle VST1.  */
	  if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
	    {
	      if (b_bits == 0x07)
		bf_regs = 1;
	      else if (b_bits == 0x0a)
		bf_regs = 2;
	      else if (b_bits == 0x06)
		bf_regs = 3;
	      else if (b_bits == 0x02)
		bf_regs = 4;
	      else
		bf_regs = 0;

	      for (index_r = 0; index_r < bf_regs; index_r++)
		{
		  for (index_e = 0; index_e < f_elem; index_e++)
		    {
		      record_buf_mem[index_m++] = f_ebytes;
		      record_buf_mem[index_m++] = address;
		      address = address + f_ebytes;
		      thumb2_insn_r->mem_rec_count += 1;
		    }
		}
	    }
	  /* Handle VST2.  */
	  else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
	    {
	      if (b_bits == 0x09 || b_bits == 0x08)
		bf_regs = 1;
	      else if (b_bits == 0x03)
		bf_regs = 2;
	      else
		bf_regs = 0;

	      for (index_r = 0; index_r < bf_regs; index_r++)
		for (index_e = 0; index_e < f_elem; index_e++)
		  {
		    for (loop_t = 0; loop_t < 2; loop_t++)
		      {
			record_buf_mem[index_m++] = f_ebytes;
			record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
			thumb2_insn_r->mem_rec_count += 1;
		      }
		    address = address + (2 * f_ebytes);
		  }
	    }
	  /* Handle VST3.  */
	  else if ((b_bits & 0x0e) == 0x04)
	    {
	      for (index_e = 0; index_e < f_elem; index_e++)
		{
		  for (loop_t = 0; loop_t < 3; loop_t++)
		    {
		      record_buf_mem[index_m++] = f_ebytes;
		      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
		      thumb2_insn_r->mem_rec_count += 1;
		    }
		  address = address + (3 * f_ebytes);
		}
	    }
	  /* Handle VST4.  */
	  else if (!(b_bits & 0x0e))
	    {
	      for (index_e = 0; index_e < f_elem; index_e++)
		{
		  for (loop_t = 0; loop_t < 4; loop_t++)
		    {
		      record_buf_mem[index_m++] = f_ebytes;
		      record_buf_mem[index_m++] = address + (loop_t * f_ebytes);
		      thumb2_insn_r->mem_rec_count += 1;
		    }
		  address = address + (4 * f_ebytes);
		}
	    }
	}
      else
	{
	  uint8_t bft_size = bits (thumb2_insn_r->arm_insn, 10, 11);

	  if (bft_size == 0x00)
	    f_ebytes = 1;
	  else if (bft_size == 0x01)
	    f_ebytes = 2;
	  else if (bft_size == 0x02)
	    f_ebytes = 4;
	  else
	    f_ebytes = 0;

	  /* Handle VST1.  */
	  if (!(b_bits & 0x0b) || b_bits == 0x08)
	    thumb2_insn_r->mem_rec_count = 1;
	  /* Handle VST2.  */
	  else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09)
	    thumb2_insn_r->mem_rec_count = 2;
	  /* Handle VST3.  */
	  else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a)
	    thumb2_insn_r->mem_rec_count = 3;
	  /* Handle VST4.  */
	  else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b)
	    thumb2_insn_r->mem_rec_count = 4;

	  for (index_m = 0; index_m < thumb2_insn_r->mem_rec_count; index_m++)
	    {
	      record_buf_mem[index_m] = f_ebytes;
	      record_buf_mem[index_m] = address + (index_m * f_ebytes);
	    }
	}
    }
  else
    {
      if (!a_bit)
	{
	  /* Handle VLD1.  */
	  if (b_bits == 0x02 || b_bits == 0x0a || (b_bits & 0x0e) == 0x06)
	    thumb2_insn_r->reg_rec_count = 1;
	  /* Handle VLD2.  */
	  else if (b_bits == 0x03 || (b_bits & 0x0e) == 0x08)
	    thumb2_insn_r->reg_rec_count = 2;
	  /* Handle VLD3.  */
	  else if ((b_bits & 0x0e) == 0x04)
	    thumb2_insn_r->reg_rec_count = 3;
	  /* Handle VLD4.  */
	  else if (!(b_bits & 0x0e))
	    thumb2_insn_r->reg_rec_count = 4;
	}
      else
	{
	  /* Handle VLD1.  */
	  if (!(b_bits & 0x0b) || b_bits == 0x08 || b_bits == 0x0c)
	    thumb2_insn_r->reg_rec_count = 1;
	  /* Handle VLD2.  */
	  else if ((b_bits & 0x0b) == 0x01 || b_bits == 0x09 || b_bits == 0x0d)
	    thumb2_insn_r->reg_rec_count = 2;
	  /* Handle VLD3.  */
	  else if ((b_bits & 0x0b) == 0x02 || b_bits == 0x0a || b_bits == 0x0e)
	    thumb2_insn_r->reg_rec_count = 3;
	  /* Handle VLD4.  */
	  else if ((b_bits & 0x0b) == 0x03 || b_bits == 0x0b || b_bits == 0x0f)
	    thumb2_insn_r->reg_rec_count = 4;

	  for (index_r = 0; index_r < thumb2_insn_r->reg_rec_count; index_r++)
	    record_buf[index_r] = reg_vd + ARM_D0_REGNUM + index_r;
	}
    }

  if (bits (thumb2_insn_r->arm_insn, 0, 3) != 15)
    {
      record_buf[index_r] = reg_rn;
      thumb2_insn_r->reg_rec_count += 1;
    }

  REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count,
	    record_buf);
  MEM_ALLOC (thumb2_insn_r->arm_mems, thumb2_insn_r->mem_rec_count,
	    record_buf_mem);
  return 0;
}

/* Decodes thumb2 instruction type and invokes its record handler.  */

static unsigned int
thumb2_record_decode_insn_handler (insn_decode_record *thumb2_insn_r)
{
  uint32_t op, op1, op2;

  op = bit (thumb2_insn_r->arm_insn, 15);
  op1 = bits (thumb2_insn_r->arm_insn, 27, 28);
  op2 = bits (thumb2_insn_r->arm_insn, 20, 26);

  if (op1 == 0x01)
    {
      if (!(op2 & 0x64 ))
	{
	  /* Load/store multiple instruction.  */
	  return thumb2_record_ld_st_multiple (thumb2_insn_r);
	}
      else if ((op2 & 0x64) == 0x4)
	{
	  /* Load/store (dual/exclusive) and table branch instruction.  */
	  return thumb2_record_ld_st_dual_ex_tbb (thumb2_insn_r);
	}
      else if ((op2 & 0x60) == 0x20)
	{
	  /* Data-processing (shifted register).  */
	  return thumb2_record_data_proc_sreg_mimm (thumb2_insn_r);
	}
      else if (op2 & 0x40)
	{
	  /* Co-processor instructions.  */
	  return thumb2_record_coproc_insn (thumb2_insn_r);
	}
    }
  else if (op1 == 0x02)
    {
      if (op)
	{
	  /* Branches and miscellaneous control instructions.  */
	  return thumb2_record_branch_misc_cntrl (thumb2_insn_r);
	}
      else if (op2 & 0x20)
	{
	  /* Data-processing (plain binary immediate) instruction.  */
	  return thumb2_record_ps_dest_generic (thumb2_insn_r);
	}
      else
	{
	  /* Data-processing (modified immediate).  */
	  return thumb2_record_data_proc_sreg_mimm (thumb2_insn_r);
	}
    }
  else if (op1 == 0x03)
    {
      if (!(op2 & 0x71 ))
	{
	  /* Store single data item.  */
	  return thumb2_record_str_single_data (thumb2_insn_r);
	}
      else if (!((op2 & 0x71) ^ 0x10))
	{
	  /* Advanced SIMD or structure load/store instructions.  */
	  return thumb2_record_asimd_struct_ld_st (thumb2_insn_r);
	}
      else if (!((op2 & 0x67) ^ 0x01))
	{
	  /* Load byte, memory hints instruction.  */
	  return thumb2_record_ld_mem_hints (thumb2_insn_r);
	}
      else if (!((op2 & 0x67) ^ 0x03))
	{
	  /* Load halfword, memory hints instruction.  */
	  return thumb2_record_ld_mem_hints (thumb2_insn_r);
	}
      else if (!((op2 & 0x67) ^ 0x05))
	{
	  /* Load word instruction.  */
	  return thumb2_record_ld_word (thumb2_insn_r);
	}
      else if (!((op2 & 0x70) ^ 0x20))
	{
	  /* Data-processing (register) instruction.  */
	  return thumb2_record_ps_dest_generic (thumb2_insn_r);
	}
      else if (!((op2 & 0x78) ^ 0x30))
	{
	  /* Multiply, multiply accumulate, abs diff instruction.  */
	  return thumb2_record_ps_dest_generic (thumb2_insn_r);
	}
      else if (!((op2 & 0x78) ^ 0x38))
	{
	  /* Long multiply, long multiply accumulate, and divide.  */
	  return thumb2_record_lmul_lmla_div (thumb2_insn_r);
	}
      else if (op2 & 0x40)
	{
	  /* Co-processor instructions.  */
	  return thumb2_record_coproc_insn (thumb2_insn_r);
	}
   }

  return -1;
}

namespace {
/* Abstract memory reader.  */

class abstract_memory_reader
{
public:
  /* Read LEN bytes of target memory at address MEMADDR, placing the
     results in GDB's memory at BUF.  Return true on success.  */

  virtual bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len) = 0;
};

/* Instruction reader from real target.  */

class instruction_reader : public abstract_memory_reader
{
 public:
  bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len) override
  {
    if (target_read_memory (memaddr, buf, len))
      return false;
    else
      return true;
  }
};

} // namespace

/* Extracts arm/thumb/thumb2 insn depending on the size, and returns 0 on success 
and positive val on failure.  */

static int
extract_arm_insn (abstract_memory_reader& reader,
		  insn_decode_record *insn_record, uint32_t insn_size)
{
  gdb_byte buf[insn_size];

  memset (&buf[0], 0, insn_size);
  
  if (!reader.read (insn_record->this_addr, buf, insn_size))
    return 1;
  insn_record->arm_insn = (uint32_t) extract_unsigned_integer (&buf[0],
			   insn_size, 
			   gdbarch_byte_order_for_code (insn_record->gdbarch));
  return 0;
}

typedef int (*sti_arm_hdl_fp_t) (insn_decode_record*);

/* Decode arm/thumb insn depending on condition cods and opcodes; and
   dispatch it.  */

static int
decode_insn (abstract_memory_reader &reader, insn_decode_record *arm_record,
	     record_type_t record_type, uint32_t insn_size)
{

  /* (Starting from numerical 0); bits 25, 26, 27 decodes type of arm
     instruction.  */
  static const sti_arm_hdl_fp_t arm_handle_insn[8] =
  {
    arm_record_data_proc_misc_ld_str,   /* 000.  */
    arm_record_data_proc_imm,           /* 001.  */
    arm_record_ld_st_imm_offset,        /* 010.  */
    arm_record_ld_st_reg_offset,        /* 011.  */
    arm_record_ld_st_multiple,          /* 100.  */
    arm_record_b_bl,                    /* 101.  */
    arm_record_asimd_vfp_coproc,        /* 110.  */
    arm_record_coproc_data_proc         /* 111.  */
  };

  /* (Starting from numerical 0); bits 13,14,15 decodes type of thumb
     instruction.  */
  static const sti_arm_hdl_fp_t thumb_handle_insn[8] =
  { \
    thumb_record_shift_add_sub,        /* 000.  */
    thumb_record_add_sub_cmp_mov,      /* 001.  */
    thumb_record_ld_st_reg_offset,     /* 010.  */
    thumb_record_ld_st_imm_offset,     /* 011.  */
    thumb_record_ld_st_stack,          /* 100.  */
    thumb_record_misc,                 /* 101.  */
    thumb_record_ldm_stm_swi,          /* 110.  */
    thumb_record_branch                /* 111.  */
  };

  uint32_t ret = 0;    /* return value: negative:failure   0:success.  */
  uint32_t insn_id = 0;

  if (extract_arm_insn (reader, arm_record, insn_size))
    {
      if (record_debug)
	{
	  printf_unfiltered (_("Process record: error reading memory at "
			       "addr %s len = %d.\n"),
			     paddress (arm_record->gdbarch,
				       arm_record->this_addr), insn_size);
	}
      return -1;
    }
  else if (ARM_RECORD == record_type)
    {
      arm_record->cond = bits (arm_record->arm_insn, 28, 31);
      insn_id = bits (arm_record->arm_insn, 25, 27);

      if (arm_record->cond == 0xf)
	ret = arm_record_extension_space (arm_record);
      else
	{
	  /* If this insn has fallen into extension space
	     then we need not decode it anymore.  */
	  ret = arm_handle_insn[insn_id] (arm_record);
	}
      if (ret != ARM_RECORD_SUCCESS)
	{
	  arm_record_unsupported_insn (arm_record);
	  ret = -1;
	}
    }
  else if (THUMB_RECORD == record_type)
    {
      /* As thumb does not have condition codes, we set negative.  */
      arm_record->cond = -1;
      insn_id = bits (arm_record->arm_insn, 13, 15);
      ret = thumb_handle_insn[insn_id] (arm_record);
      if (ret != ARM_RECORD_SUCCESS)
	{
	  arm_record_unsupported_insn (arm_record);
	  ret = -1;
	}
    }
  else if (THUMB2_RECORD == record_type)
    {
      /* As thumb does not have condition codes, we set negative.  */
      arm_record->cond = -1;

      /* Swap first half of 32bit thumb instruction with second half.  */
      arm_record->arm_insn
	= (arm_record->arm_insn >> 16) | (arm_record->arm_insn << 16);

      ret = thumb2_record_decode_insn_handler (arm_record);

      if (ret != ARM_RECORD_SUCCESS)
	{
	  arm_record_unsupported_insn (arm_record);
	  ret = -1;
	}
    }
  else
    {
      /* Throw assertion.  */
      gdb_assert_not_reached ("not a valid instruction, could not decode");
    }

  return ret;
}

#if GDB_SELF_TEST
namespace selftests {

/* Provide both 16-bit and 32-bit thumb instructions.  */

class instruction_reader_thumb : public abstract_memory_reader
{
public:
  template<size_t SIZE>
  instruction_reader_thumb (enum bfd_endian endian,
			    const uint16_t (&insns)[SIZE])
    : m_endian (endian), m_insns (insns), m_insns_size (SIZE)
  {}

  bool read (CORE_ADDR memaddr, gdb_byte *buf, const size_t len) override
  {
    SELF_CHECK (len == 4 || len == 2);
    SELF_CHECK (memaddr % 2 == 0);
    SELF_CHECK ((memaddr / 2) < m_insns_size);

    store_unsigned_integer (buf, 2, m_endian, m_insns[memaddr / 2]);
    if (len == 4)
      {
	store_unsigned_integer (&buf[2], 2, m_endian,
				m_insns[memaddr / 2 + 1]);
      }
    return true;
  }

private:
  enum bfd_endian m_endian;
  const uint16_t *m_insns;
  size_t m_insns_size;
};

static void
arm_record_test (void)
{
  struct gdbarch_info info;
  info.bfd_arch_info = bfd_scan_arch ("arm");

  struct gdbarch *gdbarch = gdbarch_find_by_info (info);

  SELF_CHECK (gdbarch != NULL);

  /* 16-bit Thumb instructions.  */
  {
    insn_decode_record arm_record;

    memset (&arm_record, 0, sizeof (insn_decode_record));
    arm_record.gdbarch = gdbarch;

    static const uint16_t insns[] = {
      /* db b2	uxtb	r3, r3 */
      0xb2db,
      /* cd 58	ldr	r5, [r1, r3] */
      0x58cd,
    };

    enum bfd_endian endian = gdbarch_byte_order_for_code (arm_record.gdbarch);
    instruction_reader_thumb reader (endian, insns);
    int ret = decode_insn (reader, &arm_record, THUMB_RECORD,
			   THUMB_INSN_SIZE_BYTES);

    SELF_CHECK (ret == 0);
    SELF_CHECK (arm_record.mem_rec_count == 0);
    SELF_CHECK (arm_record.reg_rec_count == 1);
    SELF_CHECK (arm_record.arm_regs[0] == 3);

    arm_record.this_addr += 2;
    ret = decode_insn (reader, &arm_record, THUMB_RECORD,
		       THUMB_INSN_SIZE_BYTES);

    SELF_CHECK (ret == 0);
    SELF_CHECK (arm_record.mem_rec_count == 0);
    SELF_CHECK (arm_record.reg_rec_count == 1);
    SELF_CHECK (arm_record.arm_regs[0] == 5);
  }

  /* 32-bit Thumb-2 instructions.  */
  {
    insn_decode_record arm_record;

    memset (&arm_record, 0, sizeof (insn_decode_record));
    arm_record.gdbarch = gdbarch;

    static const uint16_t insns[] = {
      /* 1d ee 70 7f	 mrc	15, 0, r7, cr13, cr0, {3} */
      0xee1d, 0x7f70,
    };

    enum bfd_endian endian = gdbarch_byte_order_for_code (arm_record.gdbarch);
    instruction_reader_thumb reader (endian, insns);
    int ret = decode_insn (reader, &arm_record, THUMB2_RECORD,
			   THUMB2_INSN_SIZE_BYTES);

    SELF_CHECK (ret == 0);
    SELF_CHECK (arm_record.mem_rec_count == 0);
    SELF_CHECK (arm_record.reg_rec_count == 1);
    SELF_CHECK (arm_record.arm_regs[0] == 7);
  }
}

/* Instruction reader from manually cooked instruction sequences.  */

class test_arm_instruction_reader : public arm_instruction_reader
{
public:
  explicit test_arm_instruction_reader (gdb::array_view<const uint32_t> insns)
    : m_insns (insns)
  {}

  uint32_t read (CORE_ADDR memaddr, enum bfd_endian byte_order) const override
  {
    SELF_CHECK (memaddr % 4 == 0);
    SELF_CHECK (memaddr / 4 < m_insns.size ());

    return m_insns[memaddr / 4];
  }

private:
  const gdb::array_view<const uint32_t> m_insns;
};

static void
arm_analyze_prologue_test ()
{
  for (bfd_endian endianness : {BFD_ENDIAN_LITTLE, BFD_ENDIAN_BIG})
    {
      struct gdbarch_info info;
      info.byte_order = endianness;
      info.byte_order_for_code = endianness;
      info.bfd_arch_info = bfd_scan_arch ("arm");

      struct gdbarch *gdbarch = gdbarch_find_by_info (info);

      SELF_CHECK (gdbarch != NULL);

      /* The "sub" instruction contains an immediate value rotate count of 0,
	 which resulted in a 32-bit shift of a 32-bit value, caught by
	 UBSan.  */
      const uint32_t insns[] = {
	  0xe92d4ff0, /* push    {r4, r5, r6, r7, r8, r9, sl, fp, lr} */
	  0xe1a05000, /* mov     r5, r0 */
	  0xe5903020, /* ldr     r3, [r0, #32] */
	  0xe24dd044, /* sub     sp, sp, #68     ; 0x44 */
      };

      test_arm_instruction_reader mem_reader (insns);
      arm_prologue_cache cache;
      cache.saved_regs = trad_frame_alloc_saved_regs (gdbarch);

      arm_analyze_prologue (gdbarch, 0, sizeof (insns) - 1, &cache, mem_reader);
    }
}

} // namespace selftests
#endif /* GDB_SELF_TEST */

/* Cleans up local record registers and memory allocations.  */

static void 
deallocate_reg_mem (insn_decode_record *record)
{
  xfree (record->arm_regs);
  xfree (record->arm_mems);    
}


/* Parse the current instruction and record the values of the registers and
   memory that will be changed in current instruction to record_arch_list".
   Return -1 if something is wrong.  */

int
arm_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
		    CORE_ADDR insn_addr)
{

  uint32_t no_of_rec = 0;
  uint32_t ret = 0;  /* return value: -1:record failure ;  0:success  */
  ULONGEST t_bit = 0, insn_id = 0;

  ULONGEST u_regval = 0;

  insn_decode_record arm_record;

  memset (&arm_record, 0, sizeof (insn_decode_record));
  arm_record.regcache = regcache;
  arm_record.this_addr = insn_addr;
  arm_record.gdbarch = gdbarch;


  if (record_debug > 1)
    {
      fprintf_unfiltered (gdb_stdlog, "Process record: arm_process_record "
			  "addr = %s\n",
      paddress (gdbarch, arm_record.this_addr));
    }

  instruction_reader reader;
  if (extract_arm_insn (reader, &arm_record, 2))
    {
      if (record_debug)
	{
	  printf_unfiltered (_("Process record: error reading memory at "
			       "addr %s len = %d.\n"),
			     paddress (arm_record.gdbarch,
				       arm_record.this_addr), 2);
	}
      return -1;
    }

  /* Check the insn, whether it is thumb or arm one.  */

  t_bit = arm_psr_thumb_bit (arm_record.gdbarch);
  regcache_raw_read_unsigned (arm_record.regcache, ARM_PS_REGNUM, &u_regval);


  if (!(u_regval & t_bit))
    {
      /* We are decoding arm insn.  */
      ret = decode_insn (reader, &arm_record, ARM_RECORD, ARM_INSN_SIZE_BYTES);
    }
  else
    {
      insn_id = bits (arm_record.arm_insn, 11, 15);
      /* is it thumb2 insn?  */
      if ((0x1D == insn_id) || (0x1E == insn_id) || (0x1F == insn_id))
	{
	  ret = decode_insn (reader, &arm_record, THUMB2_RECORD,
			     THUMB2_INSN_SIZE_BYTES);
	}
      else
	{
	  /* We are decoding thumb insn.  */
	  ret = decode_insn (reader, &arm_record, THUMB_RECORD,
			     THUMB_INSN_SIZE_BYTES);
	}
    }

  if (0 == ret)
    {
      /* Record registers.  */
      record_full_arch_list_add_reg (arm_record.regcache, ARM_PC_REGNUM);
      if (arm_record.arm_regs)
	{
	  for (no_of_rec = 0; no_of_rec < arm_record.reg_rec_count; no_of_rec++)
	    {
	      if (record_full_arch_list_add_reg
		  (arm_record.regcache , arm_record.arm_regs[no_of_rec]))
		ret = -1;
	    }
	}
      /* Record memories.  */
      if (arm_record.arm_mems)
	{
	  for (no_of_rec = 0; no_of_rec < arm_record.mem_rec_count; no_of_rec++)
	    {
	      if (record_full_arch_list_add_mem
		  ((CORE_ADDR)arm_record.arm_mems[no_of_rec].addr,
		   arm_record.arm_mems[no_of_rec].len))
		ret = -1;
	    }
	}

      if (record_full_arch_list_add_end ())
	ret = -1;
    }


  deallocate_reg_mem (&arm_record);

  return ret;
}

/* See arm-tdep.h.  */

const target_desc *
arm_read_description (arm_fp_type fp_type)
{
  struct target_desc *tdesc = tdesc_arm_list[fp_type];

  if (tdesc == nullptr)
    {
      tdesc = arm_create_target_description (fp_type);
      tdesc_arm_list[fp_type] = tdesc;
    }

  return tdesc;
}

/* See arm-tdep.h.  */

const target_desc *
arm_read_mprofile_description (arm_m_profile_type m_type)
{
  struct target_desc *tdesc = tdesc_arm_mprofile_list[m_type];

  if (tdesc == nullptr)
    {
      tdesc = arm_create_mprofile_target_description (m_type);
      tdesc_arm_mprofile_list[m_type] = tdesc;
    }

  return tdesc;
}
