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

   Copyright 2005-2023 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 "inferior.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.  */
      regcache *regcache = get_thread_regcache (inferior_thread ());
      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.  */
      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.  */
      regcache *regcache = get_thread_regcache (inferior_thread ());
      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)
    {
      regcache *regcache = get_thread_regcache (inferior_thread ());
      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 = current_inferior ()->arch ();

  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 = args[i]->type ()->length ();
	  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 = args[i]->type ()->length ();
	  unsigned int space = align_up (len, 4);

	  memcpy (data, args[i]->contents ().data (), (size_t) len);
	  arc_debug_printf ("copying arg %d, val 0x%08x, len %d to mem",
			    i, *((int *) args[i]->contents ().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 ();

  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 ();

  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 (frame_info_ptr frame, CORE_ADDR *pc)
{
  arc_debug_printf ("called");

  struct gdbarch *gdbarch = get_frame_arch (frame);
  arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_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
			  || valtype->length () > 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 (frame_info_ptr 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;
}

/* 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 gdb_non_printing_memory_disassembler dis (gdbarch);
      arc_insn_decode (current_prologue_end, dis.disasm_info (),
		       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 (frame_info_ptr 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 (frame_info_ptr 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 (frame_info_ptr 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,
			   frame_info_ptr 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 (frame_info_ptr this_frame)
{
  arc_debug_printf ("called");

  gdbarch *arch = get_frame_arch (this_frame);
  arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_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 (frame_info_ptr 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 (frame_info_ptr 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,
			    frame_info_ptr this_frame,
			    void **this_cache)
{
  arc_debug_printf ("called");

  gdbarch *arch = get_frame_arch (this_frame);
  arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_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 (_("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 (_("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 ());
    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.  */
  gdbarch *gdbarch
    = gdbarch_alloc (&info, gdbarch_tdep_up (new arc_gdbarch_tdep));
  arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_gdbarch_tdep> (gdbarch);
  tdep->jb_pc = -1; /* No longjmp support by default.  */
  tdep->has_hw_loops = arc_check_for_hw_loops (tdesc, tdesc_data.get ());

  /* 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 = gdbarch_tdep<arc_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 = parse_expression (args)->evaluate ();
  else
    val = access_value_history (0);
  val->record_latest ();

  CORE_ADDR address = value_as_address (val);
  struct arc_instruction insn;
  gdb_non_printing_memory_disassembler dis (current_inferior ()->arch ());
  arc_insn_decode (address, dis.disasm_info (), 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_basic_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);
}
