/* Target dependent code for ARC architecture, for GDB.

   Copyright 2005-2022 Free Software Foundation, Inc.
   Contributed by Synopsys 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/>.  */

/* GDB header files.  */
#include "defs.h"
#include "arch-utils.h"
#include "elf-bfd.h"
#include "disasm.h"
#include "dwarf2/frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "reggroups.h"
#include "gdbcmd.h"
#include "objfiles.h"
#include "osabi.h"
#include "prologue-value.h"
#include "target-descriptions.h"
#include "trad-frame.h"

/* ARC header files.  */
#include "opcode/arc.h"
#include "opcodes/arc-dis.h"
#include "arc-tdep.h"
#include "arch/arc.h"

/* Standard headers.  */
#include <algorithm>
#include <sstream>

/* The frame unwind cache for ARC.  */

struct arc_frame_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;

  /* Register that is a base for this frame - FP for normal frame, SP for
     non-FP frames.  */
  int frame_base_reg;

  /* Offset from the previous SP to the current frame base.  If GCC uses
     `SUB SP,SP,offset` to allocate space for local variables, then it will be
     done after setting up a frame pointer, but it still will be considered
     part of prologue, therefore SP will be lesser than FP at the end of the
     prologue analysis.  In this case that would be an offset from old SP to a
     new FP.  But in case of non-FP frames, frame base is an SP and thus that
     would be an offset from old SP to new SP.  What is important is that this
     is an offset from old SP to a known register, so it can be used to find
     old SP.

     Using FP is preferable, when possible, because SP can change in function
     body after prologue due to alloca, variadic arguments or other shenanigans.
     If that is the case in the caller frame, then PREV_SP will point to SP at
     the moment of function call, but it will be different from SP value at the
     end of the caller prologue.  As a result it will not be possible to
     reconstruct caller's frame and go past it in the backtrace.  Those things
     are unlikely to happen to FP - FP value at the moment of function call (as
     stored on stack in callee prologue) is also an FP value at the end of the
     caller's prologue.  */

  LONGEST frame_base_offset;

  /* Store addresses for registers saved in prologue.  During prologue analysis
     GDB stores offsets relatively to "old SP", then after old SP is evaluated,
     offsets are replaced with absolute addresses.  */
  trad_frame_saved_reg *saved_regs;
};

/* Global debug flag.  */

bool arc_debug;

/* List of "maintenance print arc" commands.  */

static struct cmd_list_element *maintenance_print_arc_list = NULL;

/* A set of registers that we expect to find in a tdesc_feature.  These
   are used in ARC_TDESC_INIT when processing the target description.  */

struct arc_register_feature
{
  /* Information for a single register.  */
  struct register_info
  {
    /* The GDB register number for this register.  */
    int regnum;

    /* List of names for this register.  The first name in this list is the
       preferred name, the name GDB will use when describing this register.  */
    std::vector<const char *> names;

    /* When true, this register must be present in this feature set.  */
    bool required_p;
  };

  /* The name for this feature.  This is the name used to find this feature
     within the target description.  */
  const char *name;

  /* List of all the registers that we expect to encounter in this register
     set.  */
  std::vector<struct register_info> registers;
};

/* Obsolete feature names for backward compatibility.  */
static const char *ARC_CORE_V1_OBSOLETE_FEATURE_NAME
  = "org.gnu.gdb.arc.core.arcompact";
static const char *ARC_CORE_V2_OBSOLETE_FEATURE_NAME
  = "org.gnu.gdb.arc.core.v2";
static const char *ARC_CORE_V2_REDUCED_OBSOLETE_FEATURE_NAME
  = "org.gnu.gdb.arc.core-reduced.v2";
static const char *ARC_AUX_OBSOLETE_FEATURE_NAME
  = "org.gnu.gdb.arc.aux-minimal";
/* Modern feature names.  */
static const char *ARC_CORE_FEATURE_NAME = "org.gnu.gdb.arc.core";
static const char *ARC_AUX_FEATURE_NAME = "org.gnu.gdb.arc.aux";

/* ARCv1 (ARC600, ARC601, ARC700) general core registers feature set.
   See also arc_update_acc_reg_names() for "accl/acch" names.  */

static struct arc_register_feature arc_v1_core_reg_feature =
{
  ARC_CORE_FEATURE_NAME,
  {
    { ARC_R0_REGNUM + 0, { "r0" }, true },
    { ARC_R0_REGNUM + 1, { "r1" }, true },
    { ARC_R0_REGNUM + 2, { "r2" }, true },
    { ARC_R0_REGNUM + 3, { "r3" }, true },
    { ARC_R0_REGNUM + 4, { "r4" }, false },
    { ARC_R0_REGNUM + 5, { "r5" }, false },
    { ARC_R0_REGNUM + 6, { "r6" }, false },
    { ARC_R0_REGNUM + 7, { "r7" }, false },
    { ARC_R0_REGNUM + 8, { "r8" }, false },
    { ARC_R0_REGNUM + 9, { "r9" }, false },
    { ARC_R0_REGNUM + 10, { "r10" }, true },
    { ARC_R0_REGNUM + 11, { "r11" }, true },
    { ARC_R0_REGNUM + 12, { "r12" }, true },
    { ARC_R0_REGNUM + 13, { "r13" }, true },
    { ARC_R0_REGNUM + 14, { "r14" }, true },
    { ARC_R0_REGNUM + 15, { "r15" }, true },
    { ARC_R0_REGNUM + 16, { "r16" }, false },
    { ARC_R0_REGNUM + 17, { "r17" }, false },
    { ARC_R0_REGNUM + 18, { "r18" }, false },
    { ARC_R0_REGNUM + 19, { "r19" }, false },
    { ARC_R0_REGNUM + 20, { "r20" }, false },
    { ARC_R0_REGNUM + 21, { "r21" }, false },
    { ARC_R0_REGNUM + 22, { "r22" }, false },
    { ARC_R0_REGNUM + 23, { "r23" }, false },
    { ARC_R0_REGNUM + 24, { "r24" }, false },
    { ARC_R0_REGNUM + 25, { "r25" }, false },
    { ARC_R0_REGNUM + 26, { "gp" }, true },
    { ARC_R0_REGNUM + 27, { "fp" }, true },
    { ARC_R0_REGNUM + 28, { "sp" }, true },
    { ARC_R0_REGNUM + 29, { "ilink1" }, false },
    { ARC_R0_REGNUM + 30, { "ilink2" }, false },
    { ARC_R0_REGNUM + 31, { "blink" }, true },
    { ARC_R0_REGNUM + 32, { "r32" }, false },
    { ARC_R0_REGNUM + 33, { "r33" }, false },
    { ARC_R0_REGNUM + 34, { "r34" }, false },
    { ARC_R0_REGNUM + 35, { "r35" }, false },
    { ARC_R0_REGNUM + 36, { "r36" }, false },
    { ARC_R0_REGNUM + 37, { "r37" }, false },
    { ARC_R0_REGNUM + 38, { "r38" }, false },
    { ARC_R0_REGNUM + 39, { "r39" }, false },
    { ARC_R0_REGNUM + 40, { "r40" }, false },
    { ARC_R0_REGNUM + 41, { "r41" }, false },
    { ARC_R0_REGNUM + 42, { "r42" }, false },
    { ARC_R0_REGNUM + 43, { "r43" }, false },
    { ARC_R0_REGNUM + 44, { "r44" }, false },
    { ARC_R0_REGNUM + 45, { "r45" }, false },
    { ARC_R0_REGNUM + 46, { "r46" }, false },
    { ARC_R0_REGNUM + 47, { "r47" }, false },
    { ARC_R0_REGNUM + 48, { "r48" }, false },
    { ARC_R0_REGNUM + 49, { "r49" }, false },
    { ARC_R0_REGNUM + 50, { "r50" }, false },
    { ARC_R0_REGNUM + 51, { "r51" }, false },
    { ARC_R0_REGNUM + 52, { "r52" }, false },
    { ARC_R0_REGNUM + 53, { "r53" }, false },
    { ARC_R0_REGNUM + 54, { "r54" }, false },
    { ARC_R0_REGNUM + 55, { "r55" }, false },
    { ARC_R0_REGNUM + 56, { "r56" }, false },
    { ARC_R0_REGNUM + 57, { "r57" }, false },
    { ARC_R0_REGNUM + 58, { "r58", "accl" }, false },
    { ARC_R0_REGNUM + 59, { "r59", "acch" }, false },
    { ARC_R0_REGNUM + 60, { "lp_count" }, false },
    { ARC_R0_REGNUM + 61, { "reserved" }, false },
    { ARC_R0_REGNUM + 62, { "limm" }, false },
    { ARC_R0_REGNUM + 63, { "pcl" }, true }
  }
};

/* ARCv2 (ARCHS) general core registers feature set.  See also
   arc_update_acc_reg_names() for "accl/acch" names.  */

static struct arc_register_feature arc_v2_core_reg_feature =
{
  ARC_CORE_FEATURE_NAME,
  {
    { ARC_R0_REGNUM + 0, { "r0" }, true },
    { ARC_R0_REGNUM + 1, { "r1" }, true },
    { ARC_R0_REGNUM + 2, { "r2" }, true },
    { ARC_R0_REGNUM + 3, { "r3" }, true },
    { ARC_R0_REGNUM + 4, { "r4" }, false },
    { ARC_R0_REGNUM + 5, { "r5" }, false },
    { ARC_R0_REGNUM + 6, { "r6" }, false },
    { ARC_R0_REGNUM + 7, { "r7" }, false },
    { ARC_R0_REGNUM + 8, { "r8" }, false },
    { ARC_R0_REGNUM + 9, { "r9" }, false },
    { ARC_R0_REGNUM + 10, { "r10" }, true },
    { ARC_R0_REGNUM + 11, { "r11" }, true },
    { ARC_R0_REGNUM + 12, { "r12" }, true },
    { ARC_R0_REGNUM + 13, { "r13" }, true },
    { ARC_R0_REGNUM + 14, { "r14" }, true },
    { ARC_R0_REGNUM + 15, { "r15" }, true },
    { ARC_R0_REGNUM + 16, { "r16" }, false },
    { ARC_R0_REGNUM + 17, { "r17" }, false },
    { ARC_R0_REGNUM + 18, { "r18" }, false },
    { ARC_R0_REGNUM + 19, { "r19" }, false },
    { ARC_R0_REGNUM + 20, { "r20" }, false },
    { ARC_R0_REGNUM + 21, { "r21" }, false },
    { ARC_R0_REGNUM + 22, { "r22" }, false },
    { ARC_R0_REGNUM + 23, { "r23" }, false },
    { ARC_R0_REGNUM + 24, { "r24" }, false },
    { ARC_R0_REGNUM + 25, { "r25" }, false },
    { ARC_R0_REGNUM + 26, { "gp" }, true },
    { ARC_R0_REGNUM + 27, { "fp" }, true },
    { ARC_R0_REGNUM + 28, { "sp" }, true },
    { ARC_R0_REGNUM + 29, { "ilink" }, false },
    { ARC_R0_REGNUM + 30, { "r30" }, true },
    { ARC_R0_REGNUM + 31, { "blink" }, true },
    { ARC_R0_REGNUM + 32, { "r32" }, false },
    { ARC_R0_REGNUM + 33, { "r33" }, false },
    { ARC_R0_REGNUM + 34, { "r34" }, false },
    { ARC_R0_REGNUM + 35, { "r35" }, false },
    { ARC_R0_REGNUM + 36, { "r36" }, false },
    { ARC_R0_REGNUM + 37, { "r37" }, false },
    { ARC_R0_REGNUM + 38, { "r38" }, false },
    { ARC_R0_REGNUM + 39, { "r39" }, false },
    { ARC_R0_REGNUM + 40, { "r40" }, false },
    { ARC_R0_REGNUM + 41, { "r41" }, false },
    { ARC_R0_REGNUM + 42, { "r42" }, false },
    { ARC_R0_REGNUM + 43, { "r43" }, false },
    { ARC_R0_REGNUM + 44, { "r44" }, false },
    { ARC_R0_REGNUM + 45, { "r45" }, false },
    { ARC_R0_REGNUM + 46, { "r46" }, false },
    { ARC_R0_REGNUM + 47, { "r47" }, false },
    { ARC_R0_REGNUM + 48, { "r48" }, false },
    { ARC_R0_REGNUM + 49, { "r49" }, false },
    { ARC_R0_REGNUM + 50, { "r50" }, false },
    { ARC_R0_REGNUM + 51, { "r51" }, false },
    { ARC_R0_REGNUM + 52, { "r52" }, false },
    { ARC_R0_REGNUM + 53, { "r53" }, false },
    { ARC_R0_REGNUM + 54, { "r54" }, false },
    { ARC_R0_REGNUM + 55, { "r55" }, false },
    { ARC_R0_REGNUM + 56, { "r56" }, false },
    { ARC_R0_REGNUM + 57, { "r57" }, false },
    { ARC_R0_REGNUM + 58, { "r58", "accl" }, false },
    { ARC_R0_REGNUM + 59, { "r59", "acch" }, false },
    { ARC_R0_REGNUM + 60, { "lp_count" }, false },
    { ARC_R0_REGNUM + 61, { "reserved" }, false },
    { ARC_R0_REGNUM + 62, { "limm" }, false },
    { ARC_R0_REGNUM + 63, { "pcl" }, true }
  }
};

/* The common auxiliary registers feature set.  The REGNUM field
   must match the ARC_REGNUM enum in arc-tdep.h.  */

static const struct arc_register_feature arc_common_aux_reg_feature =
{
  ARC_AUX_FEATURE_NAME,
  {
    { ARC_FIRST_AUX_REGNUM + 0, { "pc" }, true },
    { ARC_FIRST_AUX_REGNUM + 1, { "status32" }, true },
    { ARC_FIRST_AUX_REGNUM + 2, { "lp_start" }, false },
    { ARC_FIRST_AUX_REGNUM + 3, { "lp_end" }, false },
    { ARC_FIRST_AUX_REGNUM + 4, { "bta" }, false }
  }
};

static char *arc_disassembler_options = NULL;

/* Functions are sorted in the order as they are used in the
   _initialize_arc_tdep (), which uses the same order as gdbarch.h.  Static
   functions are defined before the first invocation.  */

/* Returns an unsigned value of OPERAND_NUM in instruction INSN.
   For relative branch instructions returned value is an offset, not an actual
   branch target.  */

static ULONGEST
arc_insn_get_operand_value (const struct arc_instruction &insn,
			    unsigned int operand_num)
{
  switch (insn.operands[operand_num].kind)
    {
    case ARC_OPERAND_KIND_LIMM:
      gdb_assert (insn.limm_p);
      return insn.limm_value;
    case ARC_OPERAND_KIND_SHIMM:
      return insn.operands[operand_num].value;
    default:
      /* Value in instruction is a register number.  */
      struct regcache *regcache = get_current_regcache ();
      ULONGEST value;
      regcache_cooked_read_unsigned (regcache,
				     insn.operands[operand_num].value,
				     &value);
      return value;
    }
}

/* Like arc_insn_get_operand_value, but returns a signed value.  */

static LONGEST
arc_insn_get_operand_value_signed (const struct arc_instruction &insn,
				   unsigned int operand_num)
{
  switch (insn.operands[operand_num].kind)
    {
    case ARC_OPERAND_KIND_LIMM:
      gdb_assert (insn.limm_p);
      /* Convert unsigned raw value to signed one.  This assumes 2's
	 complement arithmetic, but so is the LONG_MIN value from generic
	 defs.h and that assumption is true for ARC.  */
      gdb_static_assert (sizeof (insn.limm_value) == sizeof (int));
      return (((LONGEST) insn.limm_value) ^ INT_MIN) - INT_MIN;
    case ARC_OPERAND_KIND_SHIMM:
      /* Sign conversion has been done by binutils.  */
      return insn.operands[operand_num].value;
    default:
      /* Value in instruction is a register number.  */
      struct regcache *regcache = get_current_regcache ();
      LONGEST value;
      regcache_cooked_read_signed (regcache,
				   insn.operands[operand_num].value,
				   &value);
      return value;
    }
}

/* Get register with base address of memory operation.  */

static int
arc_insn_get_memory_base_reg (const struct arc_instruction &insn)
{
  /* POP_S and PUSH_S have SP as an implicit argument in a disassembler.  */
  if (insn.insn_class == PUSH || insn.insn_class == POP)
    return ARC_SP_REGNUM;

  gdb_assert (insn.insn_class == LOAD || insn.insn_class == STORE);

  /* Other instructions all have at least two operands: operand 0 is data,
     operand 1 is address.  Operand 2 is offset from address.  However, see
     comment to arc_instruction.operands - in some cases, third operand may be
     missing, namely if it is 0.  */
  gdb_assert (insn.operands_count >= 2);
  return insn.operands[1].value;
}

/* Get offset of a memory operation INSN.  */

static CORE_ADDR
arc_insn_get_memory_offset (const struct arc_instruction &insn)
{
  /* POP_S and PUSH_S have offset as an implicit argument in a
     disassembler.  */
  if (insn.insn_class == POP)
    return 4;
  else if (insn.insn_class == PUSH)
    return -4;

  gdb_assert (insn.insn_class == LOAD || insn.insn_class == STORE);

  /* Other instructions all have at least two operands: operand 0 is data,
     operand 1 is address.  Operand 2 is offset from address.  However, see
     comment to arc_instruction.operands - in some cases, third operand may be
     missing, namely if it is 0.  */
  if (insn.operands_count < 3)
    return 0;

  CORE_ADDR value = arc_insn_get_operand_value (insn, 2);
  /* Handle scaling.  */
  if (insn.writeback_mode == ARC_WRITEBACK_AS)
    {
      /* Byte data size is not valid for AS.  Halfword means shift by 1 bit.
	 Word and double word means shift by 2 bits.  */
      gdb_assert (insn.data_size_mode != ARC_SCALING_B);
      if (insn.data_size_mode == ARC_SCALING_H)
	value <<= 1;
      else
	value <<= 2;
    }
  return value;
}

CORE_ADDR
arc_insn_get_branch_target (const struct arc_instruction &insn)
{
  gdb_assert (insn.is_control_flow);

  /* BI [c]: PC = nextPC + (c << 2).  */
  if (insn.insn_class == BI)
    {
      ULONGEST reg_value = arc_insn_get_operand_value (insn, 0);
      return arc_insn_get_linear_next_pc (insn) + (reg_value << 2);
    }
  /* BIH [c]: PC = nextPC + (c << 1).  */
  else if (insn.insn_class == BIH)
    {
      ULONGEST reg_value = arc_insn_get_operand_value (insn, 0);
      return arc_insn_get_linear_next_pc (insn) + (reg_value << 1);
    }
  /* JLI and EI.  */
  /* JLI and EI depend on optional AUX registers.  Not supported right now.  */
  else if (insn.insn_class == JLI)
    {
      gdb_printf (gdb_stderr,
		  "JLI_S instruction is not supported by the GDB.");
      return 0;
    }
  else if (insn.insn_class == EI)
    {
      gdb_printf (gdb_stderr,
		  "EI_S instruction is not supported by the GDB.");
      return 0;
    }
  /* LEAVE_S: PC = BLINK.  */
  else if (insn.insn_class == LEAVE)
    {
      struct regcache *regcache = get_current_regcache ();
      ULONGEST value;
      regcache_cooked_read_unsigned (regcache, ARC_BLINK_REGNUM, &value);
      return value;
    }
  /* BBIT0/1, BRcc: PC = currentPC + operand.  */
  else if (insn.insn_class == BBIT0 || insn.insn_class == BBIT1
	   || insn.insn_class == BRCC)
    {
      /* Most instructions has branch target as their sole argument.  However
	 conditional brcc/bbit has it as a third operand.  */
      CORE_ADDR pcrel_addr = arc_insn_get_operand_value (insn, 2);

      /* Offset is relative to the 4-byte aligned address of the current
	 instruction, hence last two bits should be truncated.  */
      return pcrel_addr + align_down (insn.address, 4);
    }
  /* B, Bcc, BL, BLcc, LP, LPcc: PC = currentPC + operand.  */
  else if (insn.insn_class == BRANCH || insn.insn_class == LOOP)
    {
      CORE_ADDR pcrel_addr = arc_insn_get_operand_value (insn, 0);

      /* Offset is relative to the 4-byte aligned address of the current
	 instruction, hence last two bits should be truncated.  */
      return pcrel_addr + align_down (insn.address, 4);
    }
  /* J, Jcc, JL, JLcc: PC = operand.  */
  else if (insn.insn_class == JUMP)
    {
      /* All jumps are single-operand.  */
      return arc_insn_get_operand_value (insn, 0);
    }

  /* This is some new and unknown instruction.  */
  gdb_assert_not_reached ("Unknown branch instruction.");
}

/* Dump INSN into gdb_stdlog.  */

static void
arc_insn_dump (const struct arc_instruction &insn)
{
  struct gdbarch *gdbarch = target_gdbarch ();

  arc_print ("Dumping arc_instruction at %s\n",
	     paddress (gdbarch, insn.address));
  arc_print ("\tlength = %u\n", insn.length);

  if (!insn.valid)
    {
      arc_print ("\tThis is not a valid ARC instruction.\n");
      return;
    }

  arc_print ("\tlength_with_limm = %u\n", insn.length + (insn.limm_p ? 4 : 0));
  arc_print ("\tcc = 0x%x\n", insn.condition_code);
  arc_print ("\tinsn_class = %u\n", insn.insn_class);
  arc_print ("\tis_control_flow = %i\n", insn.is_control_flow);
  arc_print ("\thas_delay_slot = %i\n", insn.has_delay_slot);

  CORE_ADDR next_pc = arc_insn_get_linear_next_pc (insn);
  arc_print ("\tlinear_next_pc = %s\n", paddress (gdbarch, next_pc));

  if (insn.is_control_flow)
    {
      CORE_ADDR t = arc_insn_get_branch_target (insn);
      arc_print ("\tbranch_target = %s\n", paddress (gdbarch, t));
    }

  arc_print ("\tlimm_p = %i\n", insn.limm_p);
  if (insn.limm_p)
    arc_print ("\tlimm_value = 0x%08x\n", insn.limm_value);

  if (insn.insn_class == STORE || insn.insn_class == LOAD
      || insn.insn_class == PUSH || insn.insn_class == POP)
    {
      arc_print ("\twriteback_mode = %u\n", insn.writeback_mode);
      arc_print ("\tdata_size_mode = %u\n", insn.data_size_mode);
      arc_print ("\tmemory_base_register = %s\n",
		 gdbarch_register_name (gdbarch,
					arc_insn_get_memory_base_reg (insn)));
      /* get_memory_offset returns an unsigned CORE_ADDR, but treat it as a
	 LONGEST for a nicer representation.  */
      arc_print ("\taddr_offset = %s\n",
		 plongest (arc_insn_get_memory_offset (insn)));
    }

  arc_print ("\toperands_count = %u\n", insn.operands_count);
  for (unsigned int i = 0; i < insn.operands_count; ++i)
    {
      int is_reg = (insn.operands[i].kind == ARC_OPERAND_KIND_REG);

      arc_print ("\toperand[%u] = {\n", i);
      arc_print ("\t\tis_reg = %i\n", is_reg);
      if (is_reg)
	arc_print ("\t\tregister = %s\n",
		   gdbarch_register_name (gdbarch, insn.operands[i].value));
      /* Don't know if this value is signed or not, so print both
	 representations.  This tends to look quite ugly, especially for big
	 numbers.  */
      arc_print ("\t\tunsigned value = %s\n",
		 pulongest (arc_insn_get_operand_value (insn, i)));
      arc_print ("\t\tsigned value = %s\n",
		 plongest (arc_insn_get_operand_value_signed (insn, i)));
      arc_print ("\t}\n");
    }
}

CORE_ADDR
arc_insn_get_linear_next_pc (const struct arc_instruction &insn)
{
  /* In ARC long immediate is always 4 bytes.  */
  return (insn.address + insn.length + (insn.limm_p ? 4 : 0));
}

/* Implement the "write_pc" gdbarch method.

   In ARC PC register is a normal register so in most cases setting PC value
   is a straightforward process: debugger just writes PC value.  However it
   gets trickier in case when current instruction is an instruction in delay
   slot.  In this case CPU will execute instruction at current PC value, then
   will set PC to the current value of BTA register; also current instruction
   cannot be branch/jump and some of the other instruction types.  Thus if
   debugger would try to just change PC value in this case, this instruction
   will get executed, but then core will "jump" to the original branch target.

   Whether current instruction is a delay-slot instruction or not is indicated
   by DE bit in STATUS32 register indicates if current instruction is a delay
   slot instruction.  This bit is writable by debug host, which allows debug
   host to prevent core from jumping after the delay slot instruction.  It
   also works in another direction: setting this bit will make core to treat
   any current instructions as a delay slot instruction and to set PC to the
   current value of BTA register.

   To workaround issues with changing PC register while in delay slot
   instruction, debugger should check for the STATUS32.DE bit and reset it if
   it is set.  No other change is required in this function.  Most common
   case, where this function might be required is calling inferior functions
   from debugger.  Generic GDB logic handles this pretty well: current values
   of registers are stored, value of PC is changed (that is the job of this
   function), and after inferior function is executed, GDB restores all
   registers, include BTA and STATUS32, which also means that core is returned
   to its original state of being halted on delay slot instructions.

   This method is useless for ARC 600, because it doesn't have externally
   exposed BTA register.  In the case of ARC 600 it is impossible to restore
   core to its state in all occasions thus core should never be halted (from
   the perspective of debugger host) in the delay slot.  */

static void
arc_write_pc (struct regcache *regcache, CORE_ADDR new_pc)
{
  struct gdbarch *gdbarch = regcache->arch ();

  arc_debug_printf ("Writing PC, new value=%s",
		    paddress (gdbarch, new_pc));

  regcache_cooked_write_unsigned (regcache, gdbarch_pc_regnum (gdbarch),
				  new_pc);

  ULONGEST status32;
  regcache_cooked_read_unsigned (regcache, gdbarch_ps_regnum (gdbarch),
				 &status32);

  if ((status32 & ARC_STATUS32_DE_MASK) != 0)
    {
      arc_debug_printf ("Changing PC while in delay slot.  Will "
			"reset STATUS32.DE bit to zero.  Value of STATUS32 "
			"register is 0x%s",
			phex (status32, ARC_REGISTER_SIZE));

      /* Reset bit and write to the cache.  */
      status32 &= ~0x40;
      regcache_cooked_write_unsigned (regcache, gdbarch_ps_regnum (gdbarch),
				      status32);
    }
}

/* Implement the "virtual_frame_pointer" gdbarch method.

   According to ABI the FP (r27) is used to point to the middle of the current
   stack frame, just below the saved FP and before local variables, register
   spill area and outgoing args.  However for optimization levels above O2 and
   in any case in leaf functions, the frame pointer is usually not set at all.
   The exception being when handling nested functions.

   We use this function to return a "virtual" frame pointer, marking the start
   of the current stack frame as a register-offset pair.  If the FP is not
   being used, then it should return SP, with an offset of the frame size.

   The current implementation doesn't actually know the frame size, nor
   whether the FP is actually being used, so for now we just return SP and an
   offset of zero.  This is no worse than other architectures, but is needed
   to avoid assertion failures.

   TODO: Can we determine the frame size to get a correct offset?

   PC is a program counter where we need the virtual FP.  REG_PTR is the base
   register used for the virtual FP.  OFFSET_PTR is the offset used for the
   virtual FP.  */

static void
arc_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc,
			   int *reg_ptr, LONGEST *offset_ptr)
{
  *reg_ptr = gdbarch_sp_regnum (gdbarch);
  *offset_ptr = 0;
}

/* Implement the "push_dummy_call" gdbarch method.

   Stack Frame Layout

   This shows the layout of the stack frame for the general case of a
   function call; a given function might not have a variable number of
   arguments or local variables, or might not save any registers, so it would
   not have the corresponding frame areas.  Additionally, a leaf function
   (i.e. one which calls no other functions) does not need to save the
   contents of the BLINK register (which holds its return address), and a
   function might not have a frame pointer.

   The stack grows downward, so SP points below FP in memory; SP always
   points to the last used word on the stack, not the first one.

		      |                       |   |
		      |      arg word N       |   | caller's
		      |           :           |   | frame
		      |      arg word 10      |   |
		      |      arg word 9       |   |
	  old SP ---> +-----------------------+ --+
		      |                       |   |
		      |      callee-saved     |   |
		      |       registers       |   |
		      |  including fp, blink  |   |
		      |                       |   | callee's
	  new FP ---> +-----------------------+   | frame
		      |                       |   |
		      |         local         |   |
		      |       variables       |   |
		      |                       |   |
		      |       register        |   |
		      |      spill area       |   |
		      |                       |   |
		      |     outgoing args     |   |
		      |                       |   |
	  new SP ---> +-----------------------+ --+
		      |                       |
		      |         unused        |
		      |                       |
				  |
				  |
				  V
			      downwards

   The list of arguments to be passed to a function is considered to be a
   sequence of _N_ words (as though all the parameters were stored in order in
   memory with each parameter occupying an integral number of words).  Words
   1..8 are passed in registers 0..7; if the function has more than 8 words of
   arguments then words 9..@em N are passed on the stack in the caller's frame.

   If the function has a variable number of arguments, e.g. it has a form such
   as `function (p1, p2, ...);' and _P_ words are required to hold the values
   of the named parameters (which are passed in registers 0..@em P -1), then
   the remaining 8 - _P_ words passed in registers _P_..7 are spilled into the
   top of the frame so that the anonymous parameter words occupy a continuous
   region.

   Any arguments are already in target byte order.  We just need to store
   them!

   BP_ADDR is the return address where breakpoint must be placed.  NARGS is
   the number of arguments to the function.  ARGS is the arguments values (in
   target byte order).  SP is the Current value of SP register.  STRUCT_RETURN
   is TRUE if structures are returned by the function.  STRUCT_ADDR is the
   hidden address for returning a struct.  Returns SP of a new frame.  */

static CORE_ADDR
arc_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)
{
  arc_debug_printf ("nargs = %d", nargs);

  int arg_reg = ARC_FIRST_ARG_REGNUM;

  /* Push the return address.  */
  regcache_cooked_write_unsigned (regcache, ARC_BLINK_REGNUM, bp_addr);

  /* Are we returning a value using a structure return instead of a normal
     value return?  If so, struct_addr is the address of the reserved space for
     the return structure to be written on the stack, and that address is
     passed to that function as a hidden first argument.  */
  if (return_method == return_method_struct)
    {
      /* Pass the return address in the first argument register.  */
      regcache_cooked_write_unsigned (regcache, arg_reg, struct_addr);

      arc_debug_printf ("struct return address %s passed in R%d",
			print_core_address (gdbarch, struct_addr), arg_reg);

      arg_reg++;
    }

  if (nargs > 0)
    {
      unsigned int total_space = 0;

      /* How much space do the arguments occupy in total?  Must round each
	 argument's size up to an integral number of words.  */
      for (int i = 0; i < nargs; i++)
	{
	  unsigned int len = TYPE_LENGTH (value_type (args[i]));
	  unsigned int space = align_up (len, 4);

	  total_space += space;

	  arc_debug_printf ("arg %d: %u bytes -> %u", i, len, space);
	}

      /* Allocate a buffer to hold a memory image of the arguments.  */
      gdb_byte *memory_image = XCNEWVEC (gdb_byte, total_space);

      /* Now copy all of the arguments into the buffer, correctly aligned.  */
      gdb_byte *data = memory_image;
      for (int i = 0; i < nargs; i++)
	{
	  unsigned int len = TYPE_LENGTH (value_type (args[i]));
	  unsigned int space = align_up (len, 4);

	  memcpy (data, value_contents (args[i]).data (), (size_t) len);
	  arc_debug_printf ("copying arg %d, val 0x%08x, len %d to mem",
			    i, *((int *) value_contents (args[i]).data ()),
			    len);

	  data += space;
	}

      /* Now load as much as possible of the memory image into registers.  */
      data = memory_image;
      while (arg_reg <= ARC_LAST_ARG_REGNUM)
	{
	  arc_debug_printf ("passing 0x%02x%02x%02x%02x in register R%d",
			    data[0], data[1], data[2], data[3], arg_reg);

	  /* Note we don't use write_unsigned here, since that would convert
	     the byte order, but we are already in the correct byte order.  */
	  regcache->cooked_write (arg_reg, data);

	  data += ARC_REGISTER_SIZE;
	  total_space -= ARC_REGISTER_SIZE;

	  /* All the data is now in registers.  */
	  if (total_space == 0)
	    break;

	  arg_reg++;
	}

      /* If there is any data left, push it onto the stack (in a single write
	 operation).  */
      if (total_space > 0)
	{
	  arc_debug_printf ("passing %d bytes on stack\n", total_space);

	  sp -= total_space;
	  write_memory (sp, data, (int) total_space);
	}

      xfree (memory_image);
    }

  /* Finally, update the SP register.  */
  regcache_cooked_write_unsigned (regcache, gdbarch_sp_regnum (gdbarch), sp);

  return sp;
}

/* Implement the "push_dummy_code" gdbarch method.

   We don't actually push any code.  We just identify where a breakpoint can
   be inserted to which we are can return and the resume address where we
   should be called.

   ARC does not necessarily have an executable stack, so we can't put the
   return breakpoint there.  Instead we put it at the entry point of the
   function.  This means the SP is unchanged.

   SP is a current stack pointer FUNADDR is an address of the function to be
   called.  ARGS is arguments to pass.  NARGS is a number of args to pass.
   VALUE_TYPE is a type of value returned.  REAL_PC is a resume address when
   the function is called.  BP_ADDR is an address where breakpoint should be
   set.  Returns the updated stack pointer.  */

static CORE_ADDR
arc_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr,
		     struct value **args, int nargs, struct type *value_type,
		     CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
		     struct regcache *regcache)
{
  *real_pc = funaddr;
  *bp_addr = entry_point_address ();
  return sp;
}

/* Implement the "cannot_fetch_register" gdbarch method.  */

static int
arc_cannot_fetch_register (struct gdbarch *gdbarch, int regnum)
{
  /* Assume that register is readable if it is unknown.  LIMM and RESERVED are
     not real registers, but specific register numbers.  They are available as
     regnums to align architectural register numbers with GDB internal regnums,
     but they shouldn't appear in target descriptions generated by
     GDB-servers.  */
  switch (regnum)
    {
    case ARC_RESERVED_REGNUM:
    case ARC_LIMM_REGNUM:
      return true;
    default:
      return false;
    }
}

/* Implement the "cannot_store_register" gdbarch method.  */

static int
arc_cannot_store_register (struct gdbarch *gdbarch, int regnum)
{
  /* Assume that register is writable if it is unknown.  See comment in
     arc_cannot_fetch_register about LIMM and RESERVED.  */
  switch (regnum)
    {
    case ARC_RESERVED_REGNUM:
    case ARC_LIMM_REGNUM:
    case ARC_PCL_REGNUM:
      return true;
    default:
      return false;
    }
}

/* Get the return value of a function from the registers/memory used to
   return it, according to the convention used by the ABI - 4-bytes values are
   in the R0, while 8-byte values are in the R0-R1.

   TODO: This implementation ignores the case of "complex double", where
   according to ABI, value is returned in the R0-R3 registers.

   TYPE is a returned value's type.  VALBUF is a buffer for the returned
   value.  */

static void
arc_extract_return_value (struct gdbarch *gdbarch, struct type *type,
			  struct regcache *regcache, gdb_byte *valbuf)
{
  unsigned int len = TYPE_LENGTH (type);

  arc_debug_printf ("called");

  if (len <= ARC_REGISTER_SIZE)
    {
      ULONGEST val;

      /* Get the return value from one register.  */
      regcache_cooked_read_unsigned (regcache, ARC_R0_REGNUM, &val);
      store_unsigned_integer (valbuf, (int) len,
			      gdbarch_byte_order (gdbarch), val);

      arc_debug_printf ("returning 0x%s", phex (val, ARC_REGISTER_SIZE));
    }
  else if (len <= ARC_REGISTER_SIZE * 2)
    {
      ULONGEST low, high;

      /* Get the return value from two registers.  */
      regcache_cooked_read_unsigned (regcache, ARC_R0_REGNUM, &low);
      regcache_cooked_read_unsigned (regcache, ARC_R1_REGNUM, &high);

      store_unsigned_integer (valbuf, ARC_REGISTER_SIZE,
			      gdbarch_byte_order (gdbarch), low);
      store_unsigned_integer (valbuf + ARC_REGISTER_SIZE,
			      (int) len - ARC_REGISTER_SIZE,
			      gdbarch_byte_order (gdbarch), high);

      arc_debug_printf ("returning 0x%s%s",
			phex (high, ARC_REGISTER_SIZE),
			phex (low, ARC_REGISTER_SIZE));
    }
  else
    error (_("arc: extract_return_value: type length %u too large"), len);
}


/* Store the return value of a function into the registers/memory used to
   return it, according to the convention used by the ABI.

   TODO: This implementation ignores the case of "complex double", where
   according to ABI, value is returned in the R0-R3 registers.

   TYPE is a returned value's type.  VALBUF is a buffer with the value to
   return.  */

static void
arc_store_return_value (struct gdbarch *gdbarch, struct type *type,
			struct regcache *regcache, const gdb_byte *valbuf)
{
  unsigned int len = TYPE_LENGTH (type);

  arc_debug_printf ("called");

  if (len <= ARC_REGISTER_SIZE)
    {
      ULONGEST val;

      /* Put the return value into one register.  */
      val = extract_unsigned_integer (valbuf, (int) len,
				      gdbarch_byte_order (gdbarch));
      regcache_cooked_write_unsigned (regcache, ARC_R0_REGNUM, val);

      arc_debug_printf ("storing 0x%s", phex (val, ARC_REGISTER_SIZE));
    }
  else if (len <= ARC_REGISTER_SIZE * 2)
    {
      ULONGEST low, high;

      /* Put the return value into  two registers.  */
      low = extract_unsigned_integer (valbuf, ARC_REGISTER_SIZE,
				      gdbarch_byte_order (gdbarch));
      high = extract_unsigned_integer (valbuf + ARC_REGISTER_SIZE,
				       (int) len - ARC_REGISTER_SIZE,
				       gdbarch_byte_order (gdbarch));

      regcache_cooked_write_unsigned (regcache, ARC_R0_REGNUM, low);
      regcache_cooked_write_unsigned (regcache, ARC_R1_REGNUM, high);

      arc_debug_printf ("storing 0x%s%s",
			phex (high, ARC_REGISTER_SIZE),
			phex (low, ARC_REGISTER_SIZE));
    }
  else
    error (_("arc_store_return_value: type length too large."));
}

/* Implement the "get_longjmp_target" gdbarch method.  */

static int
arc_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  arc_debug_printf ("called");

  struct gdbarch *gdbarch = get_frame_arch (frame);
  arc_gdbarch_tdep *tdep = (arc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  int pc_offset = tdep->jb_pc * ARC_REGISTER_SIZE;
  gdb_byte buf[ARC_REGISTER_SIZE];
  CORE_ADDR jb_addr = get_frame_register_unsigned (frame, ARC_FIRST_ARG_REGNUM);

  if (target_read_memory (jb_addr + pc_offset, buf, ARC_REGISTER_SIZE))
    return 0; /* Failed to read from memory.  */

  *pc = extract_unsigned_integer (buf, ARC_REGISTER_SIZE,
				  gdbarch_byte_order (gdbarch));
  return 1;
}

/* Implement the "return_value" gdbarch method.  */

static enum return_value_convention
arc_return_value (struct gdbarch *gdbarch, struct value *function,
		  struct type *valtype, struct regcache *regcache,
		  gdb_byte *readbuf, const gdb_byte *writebuf)
{
  /* If the return type is a struct, or a union, or would occupy more than two
     registers, the ABI uses the "struct return convention": the calling
     function passes a hidden first parameter to the callee (in R0).  That
     parameter is the address at which the value being returned should be
     stored.  Otherwise, the result is returned in registers.  */
  int is_struct_return = (valtype->code () == TYPE_CODE_STRUCT
			  || valtype->code () == TYPE_CODE_UNION
			  || TYPE_LENGTH (valtype) > 2 * ARC_REGISTER_SIZE);

  arc_debug_printf ("readbuf = %s, writebuf = %s",
		    host_address_to_string (readbuf),
		    host_address_to_string (writebuf));

  if (writebuf != NULL)
    {
      /* Case 1.  GDB should not ask us to set a struct return value: it
	 should know the struct return location and write the value there
	 itself.  */
      gdb_assert (!is_struct_return);
      arc_store_return_value (gdbarch, valtype, regcache, writebuf);
    }
  else if (readbuf != NULL)
    {
      /* Case 2.  GDB should not ask us to get a struct return value: it
	 should know the struct return location and read the value from there
	 itself.  */
      gdb_assert (!is_struct_return);
      arc_extract_return_value (gdbarch, valtype, regcache, readbuf);
    }

  return (is_struct_return
	  ? RETURN_VALUE_STRUCT_CONVENTION
	  : RETURN_VALUE_REGISTER_CONVENTION);
}

/* Return the base address of the frame.  For ARC, the base address is the
   frame pointer.  */

static CORE_ADDR
arc_frame_base_address (struct frame_info *this_frame, void **prologue_cache)
{
  return (CORE_ADDR) get_frame_register_unsigned (this_frame, ARC_FP_REGNUM);
}

/* Helper function that returns valid pv_t for an instruction operand:
   either a register or a constant.  */

static pv_t
arc_pv_get_operand (pv_t *regs, const struct arc_instruction &insn, int operand)
{
  if (insn.operands[operand].kind == ARC_OPERAND_KIND_REG)
    return regs[insn.operands[operand].value];
  else
    return pv_constant (arc_insn_get_operand_value (insn, operand));
}

/* Determine whether the given disassembled instruction may be part of a
   function prologue.  If it is, the information in the frame unwind cache will
   be updated.  */

static bool
arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn,
		    pv_t *regs, struct pv_area *stack)
{
  /* It might be that currently analyzed address doesn't contain an
     instruction, hence INSN is not valid.  It likely means that address points
     to a data, non-initialized memory, or middle of a 32-bit instruction.  In
     practice this may happen if GDB connects to a remote target that has
     non-zeroed memory.  GDB would read PC value and would try to analyze
     prologue, but there is no guarantee that memory contents at the address
     specified in PC is address is a valid instruction.  There is not much that
     that can be done about that.  */
  if (!insn.valid)
    return false;

  /* Branch/jump or a predicated instruction.  */
  if (insn.is_control_flow || insn.condition_code != ARC_CC_AL)
    return false;

  /* Store of some register.  May or may not update base address register.  */
  if (insn.insn_class == STORE || insn.insn_class == PUSH)
    {
      /* There is definitely at least one operand - register/value being
	 stored.  */
      gdb_assert (insn.operands_count > 0);

      /* Store at some constant address.  */
      if (insn.operands_count > 1
	  && insn.operands[1].kind != ARC_OPERAND_KIND_REG)
	return false;

      /* Writeback modes:
	 Mode	Address used		    Writeback value
	 --------------------------------------------------
	 No	reg + offset		    no
	 A/AW	reg + offset		    reg + offset
	 AB	reg			    reg + offset
	 AS	reg + (offset << scaling)   no

	 "PUSH reg" is an alias to "ST.AW reg, [SP, -4]" encoding.  However
	 16-bit PUSH_S is a distinct instruction encoding, where offset and
	 base register are implied through opcode.  */

      /* Register with base memory address.  */
      int base_reg = arc_insn_get_memory_base_reg (insn);

      /* Address where to write.  arc_insn_get_memory_offset returns scaled
	 value for ARC_WRITEBACK_AS.  */
      pv_t addr;
      if (insn.writeback_mode == ARC_WRITEBACK_AB)
	addr = regs[base_reg];
      else
	addr = pv_add_constant (regs[base_reg],
				arc_insn_get_memory_offset (insn));

      if (stack->store_would_trash (addr))
	return false;

      if (insn.data_size_mode != ARC_SCALING_D)
	{
	  /* Find the value being stored.  */
	  pv_t store_value = arc_pv_get_operand (regs, insn, 0);

	  /* What is the size of a the stored value?  */
	  CORE_ADDR size;
	  if (insn.data_size_mode == ARC_SCALING_B)
	    size = 1;
	  else if (insn.data_size_mode == ARC_SCALING_H)
	    size = 2;
	  else
	    size = ARC_REGISTER_SIZE;

	  stack->store (addr, size, store_value);
	}
      else
	{
	  if (insn.operands[0].kind == ARC_OPERAND_KIND_REG)
	    {
	      /* If this is a double store, than write N+1 register as well.  */
	      pv_t store_value1 = regs[insn.operands[0].value];
	      pv_t store_value2 = regs[insn.operands[0].value + 1];
	      stack->store (addr, ARC_REGISTER_SIZE, store_value1);
	      stack->store (pv_add_constant (addr, ARC_REGISTER_SIZE),
			    ARC_REGISTER_SIZE, store_value2);
	    }
	  else
	    {
	      pv_t store_value
		= pv_constant (arc_insn_get_operand_value (insn, 0));
	      stack->store (addr, ARC_REGISTER_SIZE * 2, store_value);
	    }
	}

      /* Is base register updated?  */
      if (insn.writeback_mode == ARC_WRITEBACK_A
	  || insn.writeback_mode == ARC_WRITEBACK_AB)
	regs[base_reg] = pv_add_constant (regs[base_reg],
					  arc_insn_get_memory_offset (insn));

      return true;
    }
  else if (insn.insn_class == MOVE)
    {
      gdb_assert (insn.operands_count == 2);

      /* Destination argument can be "0", so nothing will happen.  */
      if (insn.operands[0].kind == ARC_OPERAND_KIND_REG)
	{
	  int dst_regnum = insn.operands[0].value;
	  regs[dst_regnum] = arc_pv_get_operand (regs, insn, 1);
	}
      return true;
    }
  else if (insn.insn_class == SUB)
    {
      gdb_assert (insn.operands_count == 3);

      /* SUB 0,b,c.  */
      if (insn.operands[0].kind != ARC_OPERAND_KIND_REG)
	return true;

      int dst_regnum = insn.operands[0].value;
      regs[dst_regnum] = pv_subtract (arc_pv_get_operand (regs, insn, 1),
				      arc_pv_get_operand (regs, insn, 2));
      return true;
    }
  else if (insn.insn_class == ENTER)
    {
      /* ENTER_S is a prologue-in-instruction - it saves all callee-saved
	 registers according to given arguments thus greatly reducing code
	 size.  Which registers will be actually saved depends on arguments.

	 ENTER_S {R13-...,FP,BLINK} stores registers in following order:

	 new SP ->
		   BLINK
		   R13
		   R14
		   R15
		   ...
		   FP
	 old SP ->

	 There are up to three arguments for this opcode, as presented by ARC
	 disassembler:
	 1) amount of general-purpose registers to be saved - this argument is
	    always present even when it is 0;
	 2) FP register number (27) if FP has to be stored, otherwise argument
	    is not present;
	 3) BLINK register number (31) if BLINK has to be stored, otherwise
	    argument is not present.  If both FP and BLINK are stored, then FP
	    is present before BLINK in argument list.  */
      gdb_assert (insn.operands_count > 0);

      int regs_saved = arc_insn_get_operand_value (insn, 0);

      bool is_fp_saved;
      if (insn.operands_count > 1)
	is_fp_saved = (insn.operands[1].value  == ARC_FP_REGNUM);
      else
	is_fp_saved = false;

      bool is_blink_saved;
      if (insn.operands_count > 1)
	is_blink_saved = (insn.operands[insn.operands_count - 1].value
			  == ARC_BLINK_REGNUM);
      else
	is_blink_saved = false;

      /* Amount of bytes to be allocated to store specified registers.  */
      CORE_ADDR st_size = ((regs_saved + is_fp_saved + is_blink_saved)
			   * ARC_REGISTER_SIZE);
      pv_t new_sp = pv_add_constant (regs[ARC_SP_REGNUM], -st_size);

      /* Assume that if the last register (closest to new SP) can be written,
	 then it is possible to write all of them.  */
      if (stack->store_would_trash (new_sp))
	return false;

      /* Current store address.  */
      pv_t addr = regs[ARC_SP_REGNUM];

      if (is_fp_saved)
	{
	  addr = pv_add_constant (addr, -ARC_REGISTER_SIZE);
	  stack->store (addr, ARC_REGISTER_SIZE, regs[ARC_FP_REGNUM]);
	}

      /* Registers are stored in backward order: from GP (R26) to R13.  */
      for (int i = ARC_R13_REGNUM + regs_saved - 1; i >= ARC_R13_REGNUM; i--)
	{
	  addr = pv_add_constant (addr, -ARC_REGISTER_SIZE);
	  stack->store (addr, ARC_REGISTER_SIZE, regs[i]);
	}

      if (is_blink_saved)
	{
	  addr = pv_add_constant (addr, -ARC_REGISTER_SIZE);
	  stack->store (addr, ARC_REGISTER_SIZE,
			regs[ARC_BLINK_REGNUM]);
	}

      gdb_assert (pv_is_identical (addr, new_sp));

      regs[ARC_SP_REGNUM] = new_sp;

      if (is_fp_saved)
	regs[ARC_FP_REGNUM] = regs[ARC_SP_REGNUM];

      return true;
    }

  /* Some other architectures, like nds32 or arm, try to continue as far as
     possible when building a prologue cache (as opposed to when skipping
     prologue), so that cache will be as full as possible.  However current
     code for ARC doesn't recognize some instructions that may modify SP, like
     ADD, AND, OR, etc, hence there is no way to guarantee that SP wasn't
     clobbered by the skipped instruction.  Potential existence of extension
     instruction, which may do anything they want makes this even more complex,
     so it is just better to halt on a first unrecognized instruction.  */

  return false;
}

/* See arc-tdep.h.  */

struct disassemble_info
arc_disassemble_info (struct gdbarch *gdbarch)
{
  struct disassemble_info di;
  init_disassemble_info_for_no_printing (&di);
  di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
  di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
  di.endian = gdbarch_byte_order (gdbarch);
  di.read_memory_func = [](bfd_vma memaddr, gdb_byte *myaddr,
			   unsigned int len, struct disassemble_info *info)
    {
      return target_read_code (memaddr, myaddr, len);
    };
  return di;
}

/* Analyze the prologue and update the corresponding frame cache for the frame
   unwinder for unwinding frames that doesn't have debug info.  In such
   situation GDB attempts to parse instructions in the prologue to understand
   where each register is saved.

   If CACHE is not NULL, then it will be filled with information about saved
   registers.

   There are several variations of prologue which GDB may encounter.  "Full"
   prologue looks like this:

	sub	sp,sp,<imm>   ; Space for variadic arguments.
	push	blink	      ; Store return address.
	push	r13	      ; Store callee saved registers (up to R26/GP).
	push	r14
	push	fp	      ; Store frame pointer.
	mov	fp,sp	      ; Update frame pointer.
	sub	sp,sp,<imm>   ; Create space for local vars on the stack.

   Depending on compiler options lots of things may change:

    1) BLINK is not saved in leaf functions.
    2) Frame pointer is not saved and updated if -fomit-frame-pointer is used.
    3) 16-bit versions of those instructions may be used.
    4) Instead of a sequence of several push'es, compiler may instead prefer to
    do one subtract on stack pointer and then store registers using normal
    store, that doesn't update SP.  Like this:


	sub	sp,sp,8		; Create space for callee-saved registers.
	st	r13,[sp,4]      ; Store callee saved registers (up to R26/GP).
	st	r14,[sp,0]

    5) ENTER_S instruction can encode most of prologue sequence in one
    instruction (except for those subtracts for variadic arguments and local
    variables).
    6) GCC may use "millicode" functions from libgcc to store callee-saved
    registers with minimal code-size requirements.  This function currently
    doesn't support this.

   ENTRYPOINT is a function entry point where prologue starts.

   LIMIT_PC is a maximum possible end address of prologue (meaning address
   of first instruction after the prologue).  It might also point to the middle
   of prologue if execution has been stopped by the breakpoint at this address
   - in this case debugger should analyze prologue only up to this address,
   because further instructions haven't been executed yet.

   Returns address of the first instruction after the prologue.  */

static CORE_ADDR
arc_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR entrypoint,
		      const CORE_ADDR limit_pc, struct arc_frame_cache *cache)
{
  arc_debug_printf ("entrypoint=%s, limit_pc=%s",
		    paddress (gdbarch, entrypoint),
		    paddress (gdbarch, limit_pc));

  /* Prologue values.  Only core registers can be stored.  */
  pv_t regs[ARC_LAST_CORE_REGNUM + 1];
  for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++)
    regs[i] = pv_register (i, 0);
  pv_area stack (ARC_SP_REGNUM, gdbarch_addr_bit (gdbarch));

  CORE_ADDR current_prologue_end = entrypoint;

  /* Look at each instruction in the prologue.  */
  while (current_prologue_end < limit_pc)
    {
      struct arc_instruction insn;
      struct disassemble_info di = arc_disassemble_info (gdbarch);
      arc_insn_decode (current_prologue_end, &di, arc_delayed_print_insn,
		       &insn);

      if (arc_debug)
	arc_insn_dump (insn);

      /* If this instruction is in the prologue, fields in the cache will be
	 updated, and the saved registers mask may be updated.  */
      if (!arc_is_in_prologue (gdbarch, insn, regs, &stack))
	{
	  /* Found an instruction that is not in the prologue.  */
	  arc_debug_printf ("End of prologue reached at address %s",
			    paddress (gdbarch, insn.address));
	  break;
	}

      current_prologue_end = arc_insn_get_linear_next_pc (insn);
    }

  if (cache != NULL)
    {
      /* Figure out if it is a frame pointer or just a stack pointer.  */
      if (pv_is_register (regs[ARC_FP_REGNUM], ARC_SP_REGNUM))
	{
	  cache->frame_base_reg = ARC_FP_REGNUM;
	  cache->frame_base_offset = -regs[ARC_FP_REGNUM].k;
	}
      else
	{
	  cache->frame_base_reg = ARC_SP_REGNUM;
	  cache->frame_base_offset = -regs[ARC_SP_REGNUM].k;
	}

      /* Assign offset from old SP to all saved registers.  */
      for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++)
	{
	  CORE_ADDR offset;
	  if (stack.find_reg (gdbarch, i, &offset))
	    cache->saved_regs[i].set_addr (offset);
	}
    }

  return current_prologue_end;
}

/* Estimated maximum prologue length in bytes.  This should include:
   1) Store instruction for each callee-saved register (R25 - R13 + 1)
   2) Two instructions for FP
   3) One for BLINK
   4) Three substract instructions for SP (for variadic args, for
   callee saved regs and for local vars) and assuming that those SUB use
   long-immediate (hence double length).
   5) Stores of arguments registers are considered part of prologue too
      (R7 - R1 + 1).
   This is quite an extreme case, because even with -O0 GCC will collapse first
   two SUBs into one and long immediate values are quite unlikely to appear in
   this case, but still better to overshoot a bit - prologue analysis will
   anyway stop at the first instruction that doesn't fit prologue, so this
   limit will be rarely reached.  */

const static int MAX_PROLOGUE_LENGTH
  = 4 * (ARC_R25_REGNUM - ARC_R13_REGNUM + 1 + 2 + 1 + 6
	 + ARC_LAST_ARG_REGNUM - ARC_FIRST_ARG_REGNUM + 1);

/* Implement the "skip_prologue" gdbarch method.

   Skip the prologue for the function at PC.  This is done by checking from
   the line information read from the DWARF, if possible; otherwise, we scan
   the function prologue to find its end.  */

static CORE_ADDR
arc_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  arc_debug_printf ("pc = %s", paddress (gdbarch, pc));

  CORE_ADDR func_addr;
  const char *func_name;

  /* See what the symbol table says.  */
  if (find_pc_partial_function (pc, &func_name, &func_addr, NULL))
    {
      /* Found a function.  */
      CORE_ADDR postprologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);

      if (postprologue_pc != 0)
	return std::max (pc, postprologue_pc);
    }

  /* No prologue info in symbol table, have to analyze prologue.  */

  /* Find an upper limit on the function prologue using the debug
     information.  If there is no debug information about prologue end, then
     skip_prologue_using_sal will return 0.  */
  CORE_ADDR limit_pc = skip_prologue_using_sal (gdbarch, pc);

  /* If there is no debug information at all, it is required to give some
     semi-arbitrary hard limit on amount of bytes to scan during prologue
     analysis.  */
  if (limit_pc == 0)
    limit_pc = pc + MAX_PROLOGUE_LENGTH;

  /* Find the address of the first instruction after the prologue by scanning
     through it - no other information is needed, so pass NULL as a cache.  */
  return arc_analyze_prologue (gdbarch, pc, limit_pc, NULL);
}

/* Implement the "print_insn" gdbarch method.

   arc_get_disassembler () may return different functions depending on bfd
   type, so it is not possible to pass print_insn directly to
   set_gdbarch_print_insn ().  Instead this wrapper function is used.  It also
   may be used by other functions to get disassemble_info for address.  It is
   important to note, that those print_insn from opcodes always print
   instruction to the stream specified in the INFO.  If this is not desired,
   then either `print_insn` function in INFO should be set to some function
   that will not print, or `stream` should be different from standard
   gdb_stdlog.  */

int
arc_delayed_print_insn (bfd_vma addr, struct disassemble_info *info)
{
  /* Standard BFD "machine number" field allows libopcodes disassembler to
     distinguish ARC 600, 700 and v2 cores, however v2 encompasses both ARC EM
     and HS, which have some difference between.  There are two ways to specify
     what is the target core:
     1) via the disassemble_info->disassembler_options;
     2) otherwise libopcodes will use private (architecture-specific) ELF
     header.

     Using disassembler_options is preferable, because it comes directly from
     GDBserver which scanned an actual ARC core identification info.  However,
     not all GDBservers report core architecture, so as a fallback GDB still
     should support analysis of ELF header.  The libopcodes disassembly code
     uses the section to find the BFD and the BFD to find the ELF header,
     therefore this function should set disassemble_info->section properly.

     disassembler_options was already set by non-target specific code with
     proper options obtained via gdbarch_disassembler_options ().

     This function might be called multiple times in a sequence, reusing same
     disassemble_info.  */
  if ((info->disassembler_options == NULL) && (info->section == NULL))
    {
      struct obj_section *s = find_pc_section (addr);
      if (s != NULL)
	info->section = s->the_bfd_section;
    }

  return default_print_insn (addr, info);
}

/* Baremetal breakpoint instructions.

   ARC supports both big- and little-endian.  However, instructions for
   little-endian processors are encoded in the middle-endian: half-words are
   in big-endian, while bytes inside the half-words are in little-endian; data
   is represented in the "normal" little-endian.  Big-endian processors treat
   data and code identically.

   Assuming the number 0x01020304, it will be presented this way:

   Address            :  N   N+1  N+2  N+3
   little-endian      : 0x04 0x03 0x02 0x01
   big-endian         : 0x01 0x02 0x03 0x04
   ARC middle-endian  : 0x02 0x01 0x04 0x03
  */

static const gdb_byte arc_brk_s_be[] = { 0x7f, 0xff };
static const gdb_byte arc_brk_s_le[] = { 0xff, 0x7f };
static const gdb_byte arc_brk_be[] = { 0x25, 0x6f, 0x00, 0x3f };
static const gdb_byte arc_brk_le[] = { 0x6f, 0x25, 0x3f, 0x00 };

/* For ARC ELF, breakpoint uses the 16-bit BRK_S instruction, which is 0x7fff
   (little endian) or 0xff7f (big endian).  We used to insert BRK_S even
   instead of 32-bit instructions, which works mostly ok, unless breakpoint is
   inserted into delay slot instruction.  In this case if branch is taken
   BLINK value will be set to address of instruction after delay slot, however
   if we replaced 32-bit instruction in delay slot with 16-bit long BRK_S,
   then BLINK value will have an invalid value - it will point to the address
   after the BRK_S (which was there at the moment of branch execution) while
   it should point to the address after the 32-bit long instruction.  To avoid
   such issues this function disassembles instruction at target location and
   evaluates it value.

   ARC 600 supports only 16-bit BRK_S.

   NB: Baremetal GDB uses BRK[_S], while user-space GDB uses TRAP_S.  BRK[_S]
   is much better because it doesn't commit unlike TRAP_S, so it can be set in
   delay slots; however it cannot be used in user-mode, hence usage of TRAP_S
   in GDB for user-space.  */

/* Implement the "breakpoint_kind_from_pc" gdbarch method.  */

static int
arc_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
  size_t length_with_limm = gdb_insn_length (gdbarch, *pcptr);

  /* Replace 16-bit instruction with BRK_S, replace 32-bit instructions with
     BRK.  LIMM is part of instruction length, so it can be either 4 or 8
     bytes for 32-bit instructions.  */
  if ((length_with_limm == 4 || length_with_limm == 8)
      && !arc_mach_is_arc600 (gdbarch))
    return sizeof (arc_brk_le);
  else
    return sizeof (arc_brk_s_le);
}

/* Implement the "sw_breakpoint_from_kind" gdbarch method.  */

static const gdb_byte *
arc_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
  gdb_assert (kind == 2 || kind == 4);
  *size = kind;

  if (kind == sizeof (arc_brk_le))
    {
      return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	      ? arc_brk_be
	      : arc_brk_le);
    }
  else
    {
      return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	      ? arc_brk_s_be
	      : arc_brk_s_le);
    }
}

/* Implement the "frame_align" gdbarch method.  */

static CORE_ADDR
arc_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  return align_down (sp, 4);
}

/* Dump the frame info.  Used for internal debugging only.  */

static void
arc_print_frame_cache (struct gdbarch *gdbarch, const char *message,
		       struct arc_frame_cache *cache, int addresses_known)
{
  arc_debug_printf ("frame_info %s", message);
  arc_debug_printf ("prev_sp = %s", paddress (gdbarch, cache->prev_sp));
  arc_debug_printf ("frame_base_reg = %i", cache->frame_base_reg);
  arc_debug_printf ("frame_base_offset = %s",
		    plongest (cache->frame_base_offset));

  for (int i = 0; i <= ARC_BLINK_REGNUM; i++)
    {
      if (cache->saved_regs[i].is_addr ())
	arc_debug_printf ("saved register %s at %s %s",
			  gdbarch_register_name (gdbarch, i),
			  (addresses_known) ? "address" : "offset",
			      paddress (gdbarch, cache->saved_regs[i].addr ()));
    }
}

/* Frame unwinder for normal frames.  */

static struct arc_frame_cache *
arc_make_frame_cache (struct frame_info *this_frame)
{
  arc_debug_printf ("called");

  struct gdbarch *gdbarch = get_frame_arch (this_frame);

  CORE_ADDR block_addr = get_frame_address_in_block (this_frame);
  CORE_ADDR entrypoint, prologue_end;
  if (find_pc_partial_function (block_addr, NULL, &entrypoint, &prologue_end))
    {
      struct symtab_and_line sal = find_pc_line (entrypoint, 0);
      CORE_ADDR prev_pc = get_frame_pc (this_frame);
      if (sal.line == 0)
	/* No line info so use current PC.  */
	prologue_end = prev_pc;
      else if (sal.end < prologue_end)
	/* The next line begins after the function end.  */
	prologue_end = sal.end;

      prologue_end = std::min (prologue_end, prev_pc);
    }
  else
    {
      /* If find_pc_partial_function returned nothing then there is no symbol
	 information at all for this PC.  Currently it is assumed in this case
	 that current PC is entrypoint to function and try to construct the
	 frame from that.  This is, probably, suboptimal, for example ARM
	 assumes in this case that program is inside the normal frame (with
	 frame pointer).  ARC, perhaps, should try to do the same.  */
      entrypoint = get_frame_register_unsigned (this_frame,
						gdbarch_pc_regnum (gdbarch));
      prologue_end = entrypoint + MAX_PROLOGUE_LENGTH;
    }

  /* Allocate new frame cache instance and space for saved register info.
     FRAME_OBSTACK_ZALLOC will initialize fields to zeroes.  */
  struct arc_frame_cache *cache
    = FRAME_OBSTACK_ZALLOC (struct arc_frame_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  arc_analyze_prologue (gdbarch, entrypoint, prologue_end, cache);

  if (arc_debug)
    arc_print_frame_cache (gdbarch, "after prologue", cache, false);

  CORE_ADDR unwound_fb = get_frame_register_unsigned (this_frame,
						      cache->frame_base_reg);
  if (unwound_fb == 0)
    return cache;
  cache->prev_sp = unwound_fb + cache->frame_base_offset;

  for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++)
    {
      if (cache->saved_regs[i].is_addr ())
	cache->saved_regs[i].set_addr (cache->saved_regs[i].addr ()
				       + cache->prev_sp);
    }

  if (arc_debug)
    arc_print_frame_cache (gdbarch, "after previous SP found", cache, true);

  return cache;
}

/* Implement the "this_id" frame_unwind method.  */

static void
arc_frame_this_id (struct frame_info *this_frame, void **this_cache,
		   struct frame_id *this_id)
{
  arc_debug_printf ("called");

  struct gdbarch *gdbarch = get_frame_arch (this_frame);

  if (*this_cache == NULL)
    *this_cache = arc_make_frame_cache (this_frame);
  struct arc_frame_cache *cache = (struct arc_frame_cache *) (*this_cache);

  CORE_ADDR stack_addr = cache->prev_sp;

  /* There are 4 possible situation which decide how frame_id->code_addr is
     evaluated:

     1) Function is compiled with option -g.  Then frame_id will be created
     in dwarf_* function and not in this function.  NB: even if target
     binary is compiled with -g, some std functions like __start and _init
     are not, so they still will follow one of the following choices.

     2) Function is compiled without -g and binary hasn't been stripped in
     any way.  In this case GDB still has enough information to evaluate
     frame code_addr properly.  This case is covered by call to
     get_frame_func ().

     3) Binary has been striped with option -g (strip debug symbols).  In
     this case there is still enough symbols for get_frame_func () to work
     properly, so this case is also covered by it.

     4) Binary has been striped with option -s (strip all symbols).  In this
     case GDB cannot get function start address properly, so we return current
     PC value instead.
   */
  CORE_ADDR code_addr = get_frame_func (this_frame);
  if (code_addr == 0)
    code_addr = get_frame_register_unsigned (this_frame,
					     gdbarch_pc_regnum (gdbarch));

  *this_id = frame_id_build (stack_addr, code_addr);
}

/* Implement the "prev_register" frame_unwind method.  */

static struct value *
arc_frame_prev_register (struct frame_info *this_frame,
			 void **this_cache, int regnum)
{
  if (*this_cache == NULL)
    *this_cache = arc_make_frame_cache (this_frame);
  struct arc_frame_cache *cache = (struct arc_frame_cache *) (*this_cache);

  struct gdbarch *gdbarch = get_frame_arch (this_frame);

  /* If we are asked to unwind the PC, then we need to return BLINK instead:
     the saved value of PC points into this frame's function's prologue, not
     the next frame's function's resume location.  */
  if (regnum == gdbarch_pc_regnum (gdbarch))
    regnum = ARC_BLINK_REGNUM;

  /* SP is a special case - we should return prev_sp, because
     trad_frame_get_prev_register will return _current_ SP value.
     Alternatively we could have stored cache->prev_sp in the cache->saved
     regs, but here we follow the lead of AArch64, ARM and Xtensa and will
     leave that logic in this function, instead of prologue analyzers.  That I
     think is a bit more clear as `saved_regs` should contain saved regs, not
     computable.

     Because value has been computed, "got_constant" should be used, so that
     returned value will be a "not_lval" - immutable.  */

  if (regnum == gdbarch_sp_regnum (gdbarch))
    return frame_unwind_got_constant (this_frame, regnum, cache->prev_sp);

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

/* Implement the "init_reg" dwarf2_frame method.  */

static void
arc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
			   struct dwarf2_frame_state_reg *reg,
			   struct frame_info *info)
{
  if (regnum == gdbarch_pc_regnum (gdbarch))
    /* The return address column.  */
    reg->how = DWARF2_FRAME_REG_RA;
  else if (regnum == gdbarch_sp_regnum (gdbarch))
    /* The call frame address.  */
    reg->how = DWARF2_FRAME_REG_CFA;
}

/*  Signal trampoline frame unwinder.  Allows frame unwinding to happen
    from within signal handlers.  */

static struct arc_frame_cache *
arc_make_sigtramp_frame_cache (struct frame_info *this_frame)
{
  arc_debug_printf ("called");

  gdbarch *arch = get_frame_arch (this_frame);
  arc_gdbarch_tdep *tdep = (arc_gdbarch_tdep *) gdbarch_tdep (arch);

  /* Allocate new frame cache instance and space for saved register info.  */
  struct arc_frame_cache *cache = FRAME_OBSTACK_ZALLOC (struct arc_frame_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  /* Get the stack pointer and use it as the frame base.  */
  cache->prev_sp = arc_frame_base_address (this_frame, NULL);

  /* If the ARC-private target-dependent info doesn't have a table of
     offsets of saved register contents within an OS signal context
     structure, then there is nothing to analyze.  */
  if (tdep->sc_reg_offset == NULL)
    return cache;

  /* Find the address of the sigcontext structure.  */
  CORE_ADDR addr = tdep->sigcontext_addr (this_frame);

  /* For each register, if its contents have been saved within the
     sigcontext structure, determine the address of those contents.  */
  gdb_assert (tdep->sc_num_regs <= (ARC_LAST_REGNUM + 1));
  for (int i = 0; i < tdep->sc_num_regs; i++)
    {
      if (tdep->sc_reg_offset[i] != ARC_OFFSET_NO_REGISTER)
	cache->saved_regs[i].set_addr (addr + tdep->sc_reg_offset[i]);
    }

  return cache;
}

/* Implement the "this_id" frame_unwind method for signal trampoline
   frames.  */

static void
arc_sigtramp_frame_this_id (struct frame_info *this_frame,
			    void **this_cache, struct frame_id *this_id)
{
  arc_debug_printf ("called");

  if (*this_cache == NULL)
    *this_cache = arc_make_sigtramp_frame_cache (this_frame);

  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct arc_frame_cache *cache = (struct arc_frame_cache *) *this_cache;
  CORE_ADDR stack_addr = cache->prev_sp;
  CORE_ADDR code_addr
    = get_frame_register_unsigned (this_frame, gdbarch_pc_regnum (gdbarch));
  *this_id = frame_id_build (stack_addr, code_addr);
}

/* Get a register from a signal handler frame.  */

static struct value *
arc_sigtramp_frame_prev_register (struct frame_info *this_frame,
				  void **this_cache, int regnum)
{
  arc_debug_printf ("regnum = %d", regnum);

  /* Make sure we've initialized the cache.  */
  if (*this_cache == NULL)
    *this_cache = arc_make_sigtramp_frame_cache (this_frame);

  struct arc_frame_cache *cache = (struct arc_frame_cache *) *this_cache;
  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
}

/* Frame sniffer for signal handler frame.  Only recognize a frame if we
   have a sigcontext_addr handler in the target dependency.  */

static int
arc_sigtramp_frame_sniffer (const struct frame_unwind *self,
			    struct frame_info *this_frame,
			    void **this_cache)
{
  arc_debug_printf ("called");

  gdbarch *arch = get_frame_arch (this_frame);
  arc_gdbarch_tdep *tdep = (arc_gdbarch_tdep *) gdbarch_tdep (arch);

  /* If we have a sigcontext_addr handler, then just return 1 (same as the
     "default_frame_sniffer ()").  */
  return (tdep->sigcontext_addr != NULL && tdep->is_sigtramp != NULL
	  && tdep->is_sigtramp (this_frame));
}

/* Structure defining the ARC ordinary frame unwind functions.  Since we are
   the fallback unwinder, we use the default frame sniffer, which always
   accepts the frame.  */

static const struct frame_unwind arc_frame_unwind = {
  "arc prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  arc_frame_this_id,
  arc_frame_prev_register,
  NULL,
  default_frame_sniffer,
  NULL,
  NULL
};

/* Structure defining the ARC signal frame unwind functions.  Custom
   sniffer is used, because this frame must be accepted only in the right
   context.  */

static const struct frame_unwind arc_sigtramp_frame_unwind = {
  "arc sigtramp",
  SIGTRAMP_FRAME,
  default_frame_unwind_stop_reason,
  arc_sigtramp_frame_this_id,
  arc_sigtramp_frame_prev_register,
  NULL,
  arc_sigtramp_frame_sniffer,
  NULL,
  NULL
};


static const struct frame_base arc_normal_base = {
  &arc_frame_unwind,
  arc_frame_base_address,
  arc_frame_base_address,
  arc_frame_base_address
};

static enum arc_isa
mach_type_to_arc_isa (const unsigned long mach)
{
  switch (mach)
    {
    case bfd_mach_arc_arc600:
    case bfd_mach_arc_arc601:
    case bfd_mach_arc_arc700:
      return ARC_ISA_ARCV1;
    case bfd_mach_arc_arcv2:
      return ARC_ISA_ARCV2;
    default:
	internal_error (__FILE__, __LINE__,
			_("unknown machine id %lu"), mach);
    }
}

/* See arc-tdep.h.  */

arc_arch_features
arc_arch_features_create (const bfd *abfd, const unsigned long mach)
{
  /* Use 4 as a fallback value.  */
  int reg_size = 4;

  /* Try to guess the features parameters by looking at the binary to be
     executed.  If the user is providing a binary that does not match the
     target, then tough luck.  This is the last effort to makes sense of
     what's going on.  */
  if (abfd != nullptr && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    {
      unsigned char eclass = elf_elfheader (abfd)->e_ident[EI_CLASS];

      if (eclass == ELFCLASS32)
	reg_size = 4;
      else if (eclass == ELFCLASS64)
	reg_size = 8;
      else
	internal_error (__FILE__, __LINE__,
			_("unknown ELF header class %d"), eclass);
    }

  /* MACH from a bfd_arch_info struct is used here.  It should be a safe
     bet, as it looks like the struct is always initialized even when we
     don't pass any elf file to GDB at all (it uses default arch in that
     case).  */
  arc_isa isa = mach_type_to_arc_isa (mach);

  return arc_arch_features (reg_size, isa);
}

/* Look for obsolete core feature names in TDESC.  */

static const struct tdesc_feature *
find_obsolete_core_names (const struct target_desc *tdesc)
{
  const struct tdesc_feature *feat = nullptr;

  feat = tdesc_find_feature (tdesc, ARC_CORE_V1_OBSOLETE_FEATURE_NAME);

  if (feat == nullptr)
    feat = tdesc_find_feature (tdesc, ARC_CORE_V2_OBSOLETE_FEATURE_NAME);

  if (feat == nullptr)
    feat = tdesc_find_feature
      (tdesc, ARC_CORE_V2_REDUCED_OBSOLETE_FEATURE_NAME);

  return feat;
}

/* Look for obsolete aux feature names in TDESC.  */

static const struct tdesc_feature *
find_obsolete_aux_names (const struct target_desc *tdesc)
{
  return tdesc_find_feature (tdesc, ARC_AUX_OBSOLETE_FEATURE_NAME);
}

/* Based on the MACH value, determines which core register features set
   must be used.  */

static arc_register_feature *
determine_core_reg_feature_set (const unsigned long mach)
{
  switch (mach_type_to_arc_isa (mach))
    {
    case ARC_ISA_ARCV1:
      return &arc_v1_core_reg_feature;
    case ARC_ISA_ARCV2:
      return &arc_v2_core_reg_feature;
    default:
      gdb_assert_not_reached
	("Unknown machine type to determine the core feature set.");
    }
}

/* At the moment, there is only 1 auxiliary register features set.
   This is a place holder for future extendability.  */

static const arc_register_feature *
determine_aux_reg_feature_set ()
{
  return &arc_common_aux_reg_feature;
}

/* Update accumulator register names (ACCH/ACCL) for r58 and r59 in the
   register sets.  The endianness determines the assignment:

	,------.------.
	| acch | accl |
   ,----|------+------|
   | LE | r59  | r58  |
   | BE | r58  | r59  |
   `----^------^------'  */

static void
arc_update_acc_reg_names (const int byte_order)
{
  const char *r58_alias
    = byte_order == BFD_ENDIAN_LITTLE ? "accl" : "acch";
  const char *r59_alias
    = byte_order == BFD_ENDIAN_LITTLE ? "acch" : "accl";

  /* Subscript 1 must be OK because those registers have 2 names.  */
  arc_v1_core_reg_feature.registers[ARC_R58_REGNUM].names[1] = r58_alias;
  arc_v1_core_reg_feature.registers[ARC_R59_REGNUM].names[1] = r59_alias;
  arc_v2_core_reg_feature.registers[ARC_R58_REGNUM].names[1] = r58_alias;
  arc_v2_core_reg_feature.registers[ARC_R59_REGNUM].names[1] = r59_alias;
}

/* Go through all the registers in REG_SET and check if they exist
   in FEATURE.  The TDESC_DATA is updated with the register number
   in REG_SET if it is found in the feature.  If a required register
   is not found, this function returns false.  */

static bool
arc_check_tdesc_feature (struct tdesc_arch_data *tdesc_data,
			 const struct tdesc_feature *feature,
			 const struct arc_register_feature *reg_set)
{
  for (const auto &reg : reg_set->registers)
    {
      bool found = false;

      for (const char *name : reg.names)
	{
	  found
	    = tdesc_numbered_register (feature, tdesc_data, reg.regnum, name);

	  if (found)
	    break;
	}

      if (!found && reg.required_p)
	{
	  std::ostringstream reg_names;
	  for (std::size_t i = 0; i < reg.names.size(); ++i)
	    {
	      if (i == 0)
		reg_names << "'" << reg.names[0] << "'";
	      else
		reg_names << " or '" << reg.names[0] << "'";
	    }
	  arc_print (_("Error: Cannot find required register(s) %s "
		       "in feature '%s'.\n"), reg_names.str ().c_str (),
		       feature->name.c_str ());
	  return false;
	}
    }

  return true;
}

/* Check for the existance of "lp_start" and "lp_end" in target description.
   If both are present, assume there is hardware loop support in the target.
   This can be improved by looking into "lpc_size" field of "isa_config"
   auxiliary register.  */

static bool
arc_check_for_hw_loops (const struct target_desc *tdesc,
			struct tdesc_arch_data *data)
{
  const auto feature_aux = tdesc_find_feature (tdesc, ARC_AUX_FEATURE_NAME);
  const auto aux_regset = determine_aux_reg_feature_set ();

  if (feature_aux == nullptr)
    return false;

  bool hw_loop_p = false;
  const auto lp_start_name =
    aux_regset->registers[ARC_LP_START_REGNUM - ARC_FIRST_AUX_REGNUM].names[0];
  const auto lp_end_name =
    aux_regset->registers[ARC_LP_END_REGNUM - ARC_FIRST_AUX_REGNUM].names[0];

  hw_loop_p = tdesc_numbered_register (feature_aux, data,
				       ARC_LP_START_REGNUM, lp_start_name);
  hw_loop_p &= tdesc_numbered_register (feature_aux, data,
				       ARC_LP_END_REGNUM, lp_end_name);

  return hw_loop_p;
}

/* Initialize target description for the ARC.

   Returns true if input TDESC was valid and in this case it will assign TDESC
   and TDESC_DATA output parameters.  */

static bool
arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
		tdesc_arch_data_up *tdesc_data)
{
  const struct target_desc *tdesc_loc = info.target_desc;
  arc_debug_printf ("Target description initialization.");

  /* If target doesn't provide a description, use the default ones.  */
  if (!tdesc_has_registers (tdesc_loc))
    {
      arc_arch_features features
	= arc_arch_features_create (info.abfd,
				    info.bfd_arch_info->mach);
      tdesc_loc = arc_lookup_target_description (features);
    }
  gdb_assert (tdesc_loc != nullptr);

  arc_debug_printf ("Have got a target description");

  const struct tdesc_feature *feature_core
    = tdesc_find_feature (tdesc_loc, ARC_CORE_FEATURE_NAME);
  const struct tdesc_feature *feature_aux
    = tdesc_find_feature (tdesc_loc, ARC_AUX_FEATURE_NAME);

  /* Maybe there still is a chance to salvage the input.  */
  if (feature_core == nullptr)
    feature_core = find_obsolete_core_names (tdesc_loc);
  if (feature_aux == nullptr)
    feature_aux = find_obsolete_aux_names (tdesc_loc);

  if (feature_core == nullptr)
    {
      arc_print (_("Error: Cannot find required feature '%s' in supplied "
		   "target description.\n"), ARC_CORE_FEATURE_NAME);
      return false;
    }

  if (feature_aux == nullptr)
    {
      arc_print (_("Error: Cannot find required feature '%s' in supplied "
		   "target description.\n"), ARC_AUX_FEATURE_NAME);
      return false;
    }

  const arc_register_feature *arc_core_reg_feature
    = determine_core_reg_feature_set (info.bfd_arch_info->mach);
  const arc_register_feature *arc_aux_reg_feature
    = determine_aux_reg_feature_set ();

  tdesc_arch_data_up tdesc_data_loc = tdesc_data_alloc ();

  arc_update_acc_reg_names (info.byte_order);

  bool valid_p = arc_check_tdesc_feature (tdesc_data_loc.get (),
					  feature_core,
					  arc_core_reg_feature);

  valid_p &= arc_check_tdesc_feature (tdesc_data_loc.get (),
				      feature_aux,
				      arc_aux_reg_feature);

  if (!valid_p)
    {
      arc_debug_printf ("Target description is not valid");
      return false;
    }

  *tdesc = tdesc_loc;
  *tdesc_data = std::move (tdesc_data_loc);

  return true;
}

/* Implement the type_align gdbarch function.  */

static ULONGEST
arc_type_align (struct gdbarch *gdbarch, struct type *type)
{
  switch (type->code ())
    {
    case TYPE_CODE_PTR:
    case TYPE_CODE_FUNC:
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_INT:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_FLT:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_DECFLOAT:
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_MEMBERPTR:
      type = check_typedef (type);
      return std::min<ULONGEST> (4, TYPE_LENGTH (type));
    default:
      return 0;
    }
}

/* Implement the "init" gdbarch method.  */

static struct gdbarch *
arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  const struct target_desc *tdesc;
  tdesc_arch_data_up tdesc_data;

  arc_debug_printf ("Architecture initialization.");

  if (!arc_tdesc_init (info, &tdesc, &tdesc_data))
    return nullptr;

  /* Allocate the ARC-private target-dependent information structure, and the
     GDB target-independent information structure.  */
  std::unique_ptr<arc_gdbarch_tdep> tdep_holder (new arc_gdbarch_tdep);
  arc_gdbarch_tdep *tdep = tdep_holder.get ();
  tdep->jb_pc = -1; /* No longjmp support by default.  */
  tdep->has_hw_loops = arc_check_for_hw_loops (tdesc, tdesc_data.get ());
  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep_holder.release ());

  /* Data types.  */
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 32);
  set_gdbarch_long_bit (gdbarch, 32);
  set_gdbarch_long_long_bit (gdbarch, 64);
  set_gdbarch_type_align (gdbarch, arc_type_align);
  set_gdbarch_float_bit (gdbarch, 32);
  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
  set_gdbarch_double_bit (gdbarch, 64);
  set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
  set_gdbarch_ptr_bit (gdbarch, 32);
  set_gdbarch_addr_bit (gdbarch, 32);
  set_gdbarch_char_signed (gdbarch, 0);

  set_gdbarch_write_pc (gdbarch, arc_write_pc);

  set_gdbarch_virtual_frame_pointer (gdbarch, arc_virtual_frame_pointer);

  /* tdesc_use_registers expects gdbarch_num_regs to return number of registers
     parsed by gdbarch_init, and then it will add all of the remaining
     registers and will increase number of registers.  */
  set_gdbarch_num_regs (gdbarch, ARC_LAST_REGNUM + 1);
  set_gdbarch_num_pseudo_regs (gdbarch, 0);
  set_gdbarch_sp_regnum (gdbarch, ARC_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, ARC_PC_REGNUM);
  set_gdbarch_ps_regnum (gdbarch, ARC_STATUS32_REGNUM);
  set_gdbarch_fp0_regnum (gdbarch, -1);	/* No FPU registers.  */

  set_gdbarch_push_dummy_call (gdbarch, arc_push_dummy_call);
  set_gdbarch_push_dummy_code (gdbarch, arc_push_dummy_code);

  set_gdbarch_cannot_fetch_register (gdbarch, arc_cannot_fetch_register);
  set_gdbarch_cannot_store_register (gdbarch, arc_cannot_store_register);

  set_gdbarch_believe_pcc_promotion (gdbarch, 1);

  set_gdbarch_return_value (gdbarch, arc_return_value);

  set_gdbarch_skip_prologue (gdbarch, arc_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  set_gdbarch_breakpoint_kind_from_pc (gdbarch, arc_breakpoint_kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, arc_sw_breakpoint_from_kind);

  /* On ARC 600 BRK_S instruction advances PC, unlike other ARC cores.  */
  if (!arc_mach_is_arc600 (gdbarch))
    set_gdbarch_decr_pc_after_break (gdbarch, 0);
  else
    set_gdbarch_decr_pc_after_break (gdbarch, 2);

  set_gdbarch_frame_align (gdbarch, arc_frame_align);

  set_gdbarch_print_insn (gdbarch, arc_delayed_print_insn);

  set_gdbarch_cannot_step_breakpoint (gdbarch, 1);

  /* "nonsteppable" watchpoint means that watchpoint triggers before
     instruction is committed, therefore it is required to remove watchpoint
     to step though instruction that triggers it.  ARC watchpoints trigger
     only after instruction is committed, thus there is no need to remove
     them.  In fact on ARC watchpoint for memory writes may trigger with more
     significant delay, like one or two instructions, depending on type of
     memory where write is performed (CCM or external) and next instruction
     after the memory write.  */
  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 0);

  /* This doesn't include possible long-immediate value.  */
  set_gdbarch_max_insn_length (gdbarch, 4);

  /* Frame unwinders and sniffers.  */
  dwarf2_frame_set_init_reg (gdbarch, arc_dwarf2_frame_init_reg);
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &arc_sigtramp_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &arc_frame_unwind);
  frame_base_set_default (gdbarch, &arc_normal_base);

  /* Setup stuff specific to a particular environment (baremetal or Linux).
     It can override functions set earlier.  */
  gdbarch_init_osabi (info, gdbarch);

  if (tdep->jb_pc >= 0)
    set_gdbarch_get_longjmp_target (gdbarch, arc_get_longjmp_target);

  /* Disassembler options.  Enforce CPU if it was specified in XML target
     description, otherwise use default method of determining CPU (ELF private
     header).  */
  if (info.target_desc != NULL)
    {
      const struct bfd_arch_info *tdesc_arch
	= tdesc_architecture (info.target_desc);
      if (tdesc_arch != NULL)
	{
	  xfree (arc_disassembler_options);
	  /* FIXME: It is not really good to change disassembler options
	     behind the scene, because that might override options
	     specified by the user.  However as of now ARC doesn't support
	     `set disassembler-options' hence this code is the only place
	     where options are changed.  It also changes options for all
	     existing gdbarches, which also can be problematic, if
	     arc_gdbarch_init will start reusing existing gdbarch
	     instances.  */
	  /* Target description specifies a BFD architecture, which is
	     different from ARC cpu, as accepted by disassembler (and most
	     other ARC tools), because cpu values are much more fine grained -
	     there can be multiple cpu values per single BFD architecture.  As
	     a result this code should translate architecture to some cpu
	     value.  Since there is no info on exact cpu configuration, it is
	     best to use the most feature-rich CPU, so that disassembler will
	     recognize all instructions available to the specified
	     architecture.  */
	  switch (tdesc_arch->mach)
	    {
	    case bfd_mach_arc_arc601:
	      arc_disassembler_options = xstrdup ("cpu=arc601");
	      break;
	    case bfd_mach_arc_arc600:
	      arc_disassembler_options = xstrdup ("cpu=arc600");
	      break;
	    case bfd_mach_arc_arc700:
	      arc_disassembler_options = xstrdup ("cpu=arc700");
	      break;
	    case bfd_mach_arc_arcv2:
	      /* Machine arcv2 has three arches: ARCv2, EM and HS; where ARCv2
		 is treated as EM.  */
	      if (arc_arch_is_hs (tdesc_arch))
		arc_disassembler_options = xstrdup ("cpu=hs38_linux");
	      else
		arc_disassembler_options = xstrdup ("cpu=em4_fpuda");
	      break;
	    default:
	      arc_disassembler_options = NULL;
	      break;
	    }
	}
    }

  set_gdbarch_disassembler_options (gdbarch, &arc_disassembler_options);
  set_gdbarch_valid_disassembler_options (gdbarch,
					  disassembler_options_arc ());

  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

  return gdbarch;
}

/* Implement the "dump_tdep" gdbarch method.  */

static void
arc_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
  arc_gdbarch_tdep *tdep = (arc_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  gdb_printf (file, "arc_dump_tdep: jb_pc = %i\n", tdep->jb_pc);

  gdb_printf (file, "arc_dump_tdep: is_sigtramp = <%s>\n",
	      host_address_to_string (tdep->is_sigtramp));
  gdb_printf (file, "arc_dump_tdep: sigcontext_addr = <%s>\n",
	      host_address_to_string (tdep->sigcontext_addr));
  gdb_printf (file, "arc_dump_tdep: sc_reg_offset = <%s>\n",
	      host_address_to_string (tdep->sc_reg_offset));
  gdb_printf (file, "arc_dump_tdep: sc_num_regs = %d\n",
	      tdep->sc_num_regs);
}

/* This command accepts single argument - address of instruction to
   disassemble.  */

static void
dump_arc_instruction_command (const char *args, int from_tty)
{
  struct value *val;
  if (args != NULL && strlen (args) > 0)
    val = evaluate_expression (parse_expression (args).get ());
  else
    val = access_value_history (0);
  record_latest_value (val);

  CORE_ADDR address = value_as_address (val);
  struct arc_instruction insn;
  struct disassemble_info di = arc_disassemble_info (target_gdbarch ());
  arc_insn_decode (address, &di, arc_delayed_print_insn, &insn);
  arc_insn_dump (insn);
}

void _initialize_arc_tdep ();
void
_initialize_arc_tdep ()
{
  gdbarch_register (bfd_arch_arc, arc_gdbarch_init, arc_dump_tdep);

  /* Register ARC-specific commands with gdb.  */

  /* Add root prefix command for "maintenance print arc" commands.  */
  add_show_prefix_cmd ("arc", class_maintenance,
		       _("ARC-specific maintenance commands for printing GDB "
			 "internal state."),
		       &maintenance_print_arc_list,
		       0, &maintenanceprintlist);

  add_cmd ("arc-instruction", class_maintenance,
	   dump_arc_instruction_command,
	   _("Dump arc_instruction structure for specified address."),
	   &maintenance_print_arc_list);

  /* Debug internals for ARC GDB.  */
  add_setshow_boolean_cmd ("arc", class_maintenance,
			   &arc_debug,
			   _("Set ARC specific debugging."),
			   _("Show ARC specific debugging."),
			   _("When set, ARC specific debugging is enabled."),
			   NULL, NULL, &setdebuglist, &showdebuglist);
}
