/* Target-dependent code for the 32-bit OpenRISC 1000, for the GDB.
   Copyright (C) 2008-2022 Free Software Foundation, Inc.

   This file is part of GDB.

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

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

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

#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "symtab.h"
#include "value.h"
#include "gdbcmd.h"
#include "language.h"
#include "gdbcore.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbtypes.h"
#include "target.h"
#include "regcache.h"
#include "safe-ctype.h"
#include "block.h"
#include "reggroups.h"
#include "arch-utils.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "dwarf2/frame.h"
#include "trad-frame.h"
#include "regset.h"
#include "remote.h"
#include "target-descriptions.h"
#include <inttypes.h>
#include "dis-asm.h"
#include "gdbarch.h"

/* OpenRISC specific includes.  */
#include "or1k-tdep.h"
#include "features/or1k.c"


/* Global debug flag.  */

static bool or1k_debug = false;

static void
show_or1k_debug (struct ui_file *file, int from_tty,
		 struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("OpenRISC debugging is %s.\n"), value);
}


/* The target-dependent structure for gdbarch.  */

struct or1k_gdbarch_tdep : gdbarch_tdep
{
  int bytes_per_word = 0;
  int bytes_per_address = 0;
  CGEN_CPU_DESC gdb_cgen_cpu_desc = nullptr;
};

/* Support functions for the architecture definition.  */

/* Get an instruction from memory.  */

static ULONGEST
or1k_fetch_instruction (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[OR1K_INSTLEN];

  if (target_read_code (addr, buf, OR1K_INSTLEN)) {
    memory_error (TARGET_XFER_E_IO, addr);
  }

  return extract_unsigned_integer (buf, OR1K_INSTLEN, byte_order);
}

/* Generic function to read bits from an instruction.  */

static bool
or1k_analyse_inst (uint32_t inst, const char *format, ...)
{
  /* Break out each field in turn, validating as we go.  */
  va_list ap;
  int i;
  int iptr = 0; /* Instruction pointer */

  va_start (ap, format);

  for (i = 0; 0 != format[i];)
    {
      const char *start_ptr;
      char *end_ptr;

      uint32_t bits; /* Bit substring of interest */
      uint32_t width; /* Substring width */
      uint32_t *arg_ptr;

      switch (format[i])
	{
	case ' ':
	  i++;
	  break; /* Formatting: ignored */

	case '0':
	case '1': /* Constant bit field */
	  bits = (inst >> (OR1K_INSTBITLEN - iptr - 1)) & 0x1;

	  if ((format[i] - '0') != bits)
	    return false;

	  iptr++;
	  i++;
	  break;

	case '%': /* Bit field */
	  i++;
	  start_ptr = &(format[i]);
	  width = strtoul (start_ptr, &end_ptr, 10);

	  /* Check we got something, and if so skip on.  */
	  if (start_ptr == end_ptr)
	    error (_("bitstring \"%s\" at offset %d has no length field."),
		   format, i);

	  i += end_ptr - start_ptr;

	  /* Look for and skip the terminating 'b'.  If it's not there, we
	     still give a fatal error, because these are fixed strings that
	     just should not be wrong.  */
	  if ('b' != format[i++])
	    error (_("bitstring \"%s\" at offset %d has no terminating 'b'."),
		   format, i);

	  /* Break out the field.  There is a special case with a bit width
	     of 32.  */
	  if (32 == width)
	    bits = inst;
	  else
	    bits =
	      (inst >> (OR1K_INSTBITLEN - iptr - width)) & ((1 << width) - 1);

	  arg_ptr = va_arg (ap, uint32_t *);
	  *arg_ptr = bits;
	  iptr += width;
	  break;

	default:
	  error (_("invalid character in bitstring \"%s\" at offset %d."),
		 format, i);
	  break;
	}
    }

  /* Is the length OK?  */
  gdb_assert (OR1K_INSTBITLEN == iptr);

  return true; /* Success */
}

/* This is used to parse l.addi instructions during various prologue
   analysis routines.  The l.addi instruction has semantics:

     assembly:        l.addi  rD,rA,I
     implementation:  rD = rA + sign_extend(Immediate)

   The rd_ptr, ra_ptr and simm_ptr must be non NULL pointers and are used
   to store the parse results.  Upon successful parsing true is returned,
   false on failure. */

static bool
or1k_analyse_l_addi (uint32_t inst, unsigned int *rd_ptr,
		     unsigned int *ra_ptr, int *simm_ptr)
{
  /* Instruction fields */
  uint32_t rd, ra, i;

  if (or1k_analyse_inst (inst, "10 0111 %5b %5b %16b", &rd, &ra, &i))
    {
      /* Found it.  Construct the result fields.  */
      *rd_ptr = (unsigned int) rd;
      *ra_ptr = (unsigned int) ra;
      *simm_ptr = (int) (((i & 0x8000) == 0x8000) ? 0xffff0000 | i : i);

      return true; /* Success */
    }
  else
    return false; /* Failure */
}

/* This is used to to parse store instructions during various prologue
   analysis routines.  The l.sw instruction has semantics:

     assembly:        l.sw  I(rA),rB
     implementation:  store rB contents to memory at effective address of
		      rA + sign_extend(Immediate)

   The simm_ptr, ra_ptr and rb_ptr must be non NULL pointers and are used
   to store the parse results. Upon successful parsing true is returned,
   false on failure. */

static bool
or1k_analyse_l_sw (uint32_t inst, int *simm_ptr, unsigned int *ra_ptr,
		   unsigned int *rb_ptr)
{
  /* Instruction fields */
  uint32_t ihi, ilo, ra, rb;

  if (or1k_analyse_inst (inst, "11 0101 %5b %5b %5b %11b", &ihi, &ra, &rb,
			 &ilo))

    {
      /* Found it.  Construct the result fields.  */
      *simm_ptr = (int) ((ihi << 11) | ilo);
      *simm_ptr |= ((ihi & 0x10) == 0x10) ? 0xffff0000 : 0;

      *ra_ptr = (unsigned int) ra;
      *rb_ptr = (unsigned int) rb;

      return true; /* Success */
    }
  else
    return false; /* Failure */
}


/* Functions defining the architecture.  */

/* Implement the return_value gdbarch method.  */

static enum return_value_convention
or1k_return_value (struct gdbarch *gdbarch, struct value *functype,
		   struct type *valtype, struct regcache *regcache,
		   gdb_byte *readbuf, const gdb_byte *writebuf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  enum type_code rv_type = valtype->code ();
  unsigned int rv_size = TYPE_LENGTH (valtype);
  or1k_gdbarch_tdep *tdep = (or1k_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  int bpw = tdep->bytes_per_word;

  /* Deal with struct/union as addresses.  If an array won't fit in a
     single register it is returned as address.  Anything larger than 2
     registers needs to also be passed as address (matches gcc
     default_return_in_memory).  */
  if ((TYPE_CODE_STRUCT == rv_type) || (TYPE_CODE_UNION == rv_type)
      || ((TYPE_CODE_ARRAY == rv_type) && (rv_size > bpw))
      || (rv_size > 2 * bpw))
    {
      if (readbuf != NULL)
	{
	  ULONGEST tmp;

	  regcache_cooked_read_unsigned (regcache, OR1K_RV_REGNUM, &tmp);
	  read_memory (tmp, readbuf, rv_size);
	}
      if (writebuf != NULL)
	{
	  ULONGEST tmp;

	  regcache_cooked_read_unsigned (regcache, OR1K_RV_REGNUM, &tmp);
	  write_memory (tmp, writebuf, rv_size);
	}

      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
    }

  if (rv_size <= bpw)
    {
      /* Up to one word scalars are returned in R11.  */
      if (readbuf != NULL)
	{
	  ULONGEST tmp;

	  regcache_cooked_read_unsigned (regcache, OR1K_RV_REGNUM, &tmp);
	  store_unsigned_integer (readbuf, rv_size, byte_order, tmp);

	}
      if (writebuf != NULL)
	{
	  gdb_byte *buf = XCNEWVEC(gdb_byte, bpw);

	  if (BFD_ENDIAN_BIG == byte_order)
	    memcpy (buf + (sizeof (gdb_byte) * bpw) - rv_size, writebuf,
		    rv_size);
	  else
	    memcpy (buf, writebuf, rv_size);

	  regcache->cooked_write (OR1K_RV_REGNUM, buf);

	  free (buf);
	}
    }
  else
    {
      /* 2 word scalars are returned in r11/r12 (with the MS word in r11).  */
      if (readbuf != NULL)
	{
	  ULONGEST tmp_lo;
	  ULONGEST tmp_hi;
	  ULONGEST tmp;

	  regcache_cooked_read_unsigned (regcache, OR1K_RV_REGNUM,
					 &tmp_hi);
	  regcache_cooked_read_unsigned (regcache, OR1K_RV_REGNUM + 1,
					 &tmp_lo);
	  tmp = (tmp_hi << (bpw * 8)) | tmp_lo;

	  store_unsigned_integer (readbuf, rv_size, byte_order, tmp);
	}
      if (writebuf != NULL)
	{
	  gdb_byte *buf_lo = XCNEWVEC(gdb_byte, bpw);
	  gdb_byte *buf_hi = XCNEWVEC(gdb_byte, bpw);

	  /* This is cheating.  We assume that we fit in 2 words exactly,
	     which wouldn't work if we had (say) a 6-byte scalar type on a
	     big endian architecture (with the OpenRISC 1000 usually is).  */
	  memcpy (buf_hi, writebuf, rv_size - bpw);
	  memcpy (buf_lo, writebuf + bpw, bpw);

	  regcache->cooked_write (OR1K_RV_REGNUM, buf_hi);
	  regcache->cooked_write (OR1K_RV_REGNUM + 1, buf_lo);

	  free (buf_lo);
	  free (buf_hi);
	}
    }

  return RETURN_VALUE_REGISTER_CONVENTION;
}

/* OR1K always uses a l.trap instruction for breakpoints.  */

constexpr gdb_byte or1k_break_insn[] = {0x21, 0x00, 0x00, 0x01};

typedef BP_MANIPULATION (or1k_break_insn) or1k_breakpoint;

static int
or1k_delay_slot_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  const CGEN_INSN *insn;
  CGEN_FIELDS tmp_fields;
  or1k_gdbarch_tdep *tdep = (or1k_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  insn = cgen_lookup_insn (tdep->gdb_cgen_cpu_desc,
			   NULL,
			   or1k_fetch_instruction (gdbarch, pc),
			   NULL, 32, &tmp_fields, 0);

  /* NULL here would mean the last instruction was not understood by cgen.
     This should not usually happen, but if does its not a delay slot.  */
  if (insn == NULL)
    return 0;

  /* TODO: we should add a delay slot flag to the CGEN_INSN and remove
     this hard coded test.  */
  return ((CGEN_INSN_NUM (insn) == OR1K_INSN_L_J)
	  || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JAL)
	  || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JR)
	  || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_JALR)
	  || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_BNF)
	  || (CGEN_INSN_NUM (insn) == OR1K_INSN_L_BF));
}

/* Implement the single_step_through_delay gdbarch method.  */

static int
or1k_single_step_through_delay (struct gdbarch *gdbarch,
				struct frame_info *this_frame)
{
  ULONGEST val;
  CORE_ADDR ppc;
  CORE_ADDR npc;
  struct regcache *regcache = get_current_regcache ();

  /* Get the previous and current instruction addresses.  If they are not
    adjacent, we cannot be in a delay slot.  */
  regcache_cooked_read_unsigned (regcache, OR1K_PPC_REGNUM, &val);
  ppc = (CORE_ADDR) val;
  regcache_cooked_read_unsigned (regcache, OR1K_NPC_REGNUM, &val);
  npc = (CORE_ADDR) val;

  if (0x4 != (npc - ppc))
    return 0;

  return or1k_delay_slot_p (gdbarch, ppc);
}

/* or1k_software_single_step() is called just before we want to resume
   the inferior, if we want to single-step it but there is no hardware
   or kernel single-step support (OpenRISC on GNU/Linux for example).  We
   find the target of the coming instruction skipping over delay slots
   and breakpoint it.  */

std::vector<CORE_ADDR>
or1k_software_single_step (struct regcache *regcache)
{
  struct gdbarch *gdbarch = regcache->arch ();
  CORE_ADDR pc, next_pc;

  pc = regcache_read_pc (regcache);
  next_pc = pc + 4;

  if (or1k_delay_slot_p (gdbarch, pc))
    next_pc += 4;

  return {next_pc};
}

/* Name for or1k general registers.  */

static const char *const or1k_reg_names[OR1K_NUM_REGS] = {
  /* general purpose registers */
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",

  /* previous program counter, next program counter and status register */
  "ppc", "npc", "sr"
};

static int
or1k_is_arg_reg (unsigned int regnum)
{
  return (OR1K_FIRST_ARG_REGNUM <= regnum)
    && (regnum <= OR1K_LAST_ARG_REGNUM);
}

static int
or1k_is_callee_saved_reg (unsigned int regnum)
{
  return (OR1K_FIRST_SAVED_REGNUM <= regnum) && (0 == regnum % 2);
}

/* Implement the skip_prologue gdbarch method.  */

static CORE_ADDR
or1k_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR start_pc;
  CORE_ADDR addr;
  uint32_t inst;

  unsigned int ra, rb, rd; /* for instruction analysis */
  int simm;

  int frame_size = 0;

  /* Try using SAL first if we have symbolic information available.  This
     only works for DWARF 2, not STABS.  */

  if (find_pc_partial_function (pc, NULL, &start_pc, NULL))
    {
      CORE_ADDR prologue_end = skip_prologue_using_sal (gdbarch, pc);

      if (0 != prologue_end)
	{
	  struct symtab_and_line prologue_sal = find_pc_line (start_pc, 0);
	  struct compunit_symtab *compunit
	    = prologue_sal.symtab->compunit ();
	  const char *debug_format = compunit->debugformat ();

	  if ((NULL != debug_format)
	      && (strlen ("dwarf") <= strlen (debug_format))
	      && (0 == strncasecmp ("dwarf", debug_format, strlen ("dwarf"))))
	    return (prologue_end > pc) ? prologue_end : pc;
	}
    }

  /* Look to see if we can find any of the standard prologue sequence.  All
     quite difficult, since any or all of it may be missing.  So this is
     just a best guess!  */

  addr = pc; /* Where we have got to */
  inst = or1k_fetch_instruction (gdbarch, addr);

  /* Look for the new stack pointer being set up.  */
  if (or1k_analyse_l_addi (inst, &rd, &ra, &simm)
      && (OR1K_SP_REGNUM == rd) && (OR1K_SP_REGNUM == ra)
      && (simm < 0) && (0 == (simm % 4)))
    {
      frame_size = -simm;
      addr += OR1K_INSTLEN;
      inst = or1k_fetch_instruction (gdbarch, addr);
    }

  /* Look for the frame pointer being manipulated.  */
  if (or1k_analyse_l_sw (inst, &simm, &ra, &rb)
      && (OR1K_SP_REGNUM == ra) && (OR1K_FP_REGNUM == rb)
      && (simm >= 0) && (0 == (simm % 4)))
    {
      addr += OR1K_INSTLEN;
      inst = or1k_fetch_instruction (gdbarch, addr);

      gdb_assert (or1k_analyse_l_addi (inst, &rd, &ra, &simm)
		  && (OR1K_FP_REGNUM == rd) && (OR1K_SP_REGNUM == ra)
		  && (simm == frame_size));

      addr += OR1K_INSTLEN;
      inst = or1k_fetch_instruction (gdbarch, addr);
    }

  /* Look for the link register being saved.  */
  if (or1k_analyse_l_sw (inst, &simm, &ra, &rb)
      && (OR1K_SP_REGNUM == ra) && (OR1K_LR_REGNUM == rb)
      && (simm >= 0) && (0 == (simm % 4)))
    {
      addr += OR1K_INSTLEN;
      inst = or1k_fetch_instruction (gdbarch, addr);
    }

  /* Look for arguments or callee-saved register being saved.  The register
     must be one of the arguments (r3-r8) or the 10 callee saved registers
     (r10, r12, r14, r16, r18, r20, r22, r24, r26, r28, r30).  The base
     register must be the FP (for the args) or the SP (for the callee_saved
     registers).  */
  while (1)
    {
      if (or1k_analyse_l_sw (inst, &simm, &ra, &rb)
	  && (((OR1K_FP_REGNUM == ra) && or1k_is_arg_reg (rb))
	      || ((OR1K_SP_REGNUM == ra) && or1k_is_callee_saved_reg (rb)))
	  && (0 == (simm % 4)))
	{
	  addr += OR1K_INSTLEN;
	  inst = or1k_fetch_instruction (gdbarch, addr);
	}
      else
	{
	  /* Nothing else to look for.  We have found the end of the
	     prologue.  */
	  break;
	}
    }
  return addr;
}

/* Implement the frame_align gdbarch method.  */

static CORE_ADDR
or1k_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  return align_down (sp, OR1K_STACK_ALIGN);
}

/* Implement the unwind_pc gdbarch method.  */

static CORE_ADDR
or1k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  CORE_ADDR pc;

  if (or1k_debug)
    gdb_printf (gdb_stdlog, "or1k_unwind_pc, next_frame=%d\n",
		frame_relative_level (next_frame));

  pc = frame_unwind_register_unsigned (next_frame, OR1K_NPC_REGNUM);

  if (or1k_debug)
    gdb_printf (gdb_stdlog, "or1k_unwind_pc, pc=%s\n",
		paddress (gdbarch, pc));

  return pc;
}

/* Implement the unwind_sp gdbarch method.  */

static CORE_ADDR
or1k_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  CORE_ADDR sp;

  if (or1k_debug)
    gdb_printf (gdb_stdlog, "or1k_unwind_sp, next_frame=%d\n",
		frame_relative_level (next_frame));

  sp = frame_unwind_register_unsigned (next_frame, OR1K_SP_REGNUM);

  if (or1k_debug)
    gdb_printf (gdb_stdlog, "or1k_unwind_sp, sp=%s\n",
		paddress (gdbarch, sp));

  return sp;
}

/* Implement the push_dummy_code gdbarch method.  */

static CORE_ADDR
or1k_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
		      CORE_ADDR function, struct value **args, int nargs,
		      struct type *value_type, CORE_ADDR * real_pc,
		      CORE_ADDR * bp_addr, struct regcache *regcache)
{
  CORE_ADDR bp_slot;

  /* Reserve enough room on the stack for our breakpoint instruction.  */
  bp_slot = sp - 4;
  /* Store the address of that breakpoint.  */
  *bp_addr = bp_slot;
  /* keeping the stack aligned.  */
  sp = or1k_frame_align (gdbarch, bp_slot);
  /* The call starts at the callee's entry point.  */
  *real_pc = function;

  return sp;
}

/* Implement the push_dummy_call gdbarch method.  */

static CORE_ADDR
or1k_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)
{

  int argreg;
  int argnum;
  int first_stack_arg;
  int stack_offset = 0;
  int heap_offset = 0;
  CORE_ADDR heap_sp = sp - 128;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  or1k_gdbarch_tdep *tdep = (or1k_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  int bpa = tdep->bytes_per_address;
  int bpw = tdep->bytes_per_word;
  struct type *func_type = value_type (function);

  /* Return address */
  regcache_cooked_write_unsigned (regcache, OR1K_LR_REGNUM, bp_addr);

  /* Register for the next argument.  */
  argreg = OR1K_FIRST_ARG_REGNUM;

  /* Location for a returned structure.  This is passed as a silent first
     argument.  */
  if (return_method == return_method_struct)
    {
      regcache_cooked_write_unsigned (regcache, OR1K_FIRST_ARG_REGNUM,
				      struct_addr);
      argreg++;
    }

  /* Put as many args as possible in registers.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      const gdb_byte *val;
      gdb_byte valbuf[sizeof (ULONGEST)];

      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (value_type (arg));
      int len = TYPE_LENGTH (arg_type);
      enum type_code typecode = arg_type->code ();

      if (func_type->has_varargs () && argnum >= func_type->num_fields ())
	break; /* end or regular args, varargs go to stack.  */

      /* Extract the value, either a reference or the data.  */
      if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)
	  || (len > bpw * 2))
	{
	  CORE_ADDR valaddr = value_address (arg);

	  /* If the arg is fabricated (i.e. 3*i, instead of i) valaddr is
	     undefined.  */
	  if (valaddr == 0)
	    {
	      /* The argument needs to be copied into the target space.
		 Since the bottom of the stack is reserved for function
		 arguments we store this at the these at the top growing
		 down.  */
	      heap_offset += align_up (len, bpw);
	      valaddr = heap_sp + heap_offset;

	      write_memory (valaddr, value_contents (arg).data (), len);
	    }

	  /* The ABI passes all structures by reference, so get its
	     address.  */
	  store_unsigned_integer (valbuf, bpa, byte_order, valaddr);
	  len = bpa;
	  val = valbuf;
	}
      else
	{
	  /* Everything else, we just get the value.  */
	  val = value_contents (arg).data ();
	}

      /* Stick the value in a register.  */
      if (len > bpw)
	{
	  /* Big scalars use two registers, but need NOT be pair aligned.  */

	  if (argreg <= (OR1K_LAST_ARG_REGNUM - 1))
	    {
	      ULONGEST regval =	extract_unsigned_integer (val, len,
							  byte_order);

	      unsigned int bits_per_word = bpw * 8;
	      ULONGEST mask = (((ULONGEST) 1) << bits_per_word) - 1;
	      ULONGEST lo = regval & mask;
	      ULONGEST hi = regval >> bits_per_word;

	      regcache_cooked_write_unsigned (regcache, argreg, hi);
	      regcache_cooked_write_unsigned (regcache, argreg + 1, lo);
	      argreg += 2;
	    }
	  else
	    {
	      /* Run out of regs */
	      break;
	    }
	}
      else if (argreg <= OR1K_LAST_ARG_REGNUM)
	{
	  /* Smaller scalars fit in a single register.  */
	  regcache_cooked_write_unsigned
	    (regcache, argreg, extract_unsigned_integer (val, len,
							 byte_order));
	  argreg++;
	}
      else
	{
	  /* Ran out of regs.  */
	  break;
	}
    }

  first_stack_arg = argnum;

  /* If we get here with argnum < nargs, then arguments remain to be
     placed on the stack.  This is tricky, since they must be pushed in
     reverse order and the stack in the end must be aligned.  The only
     solution is to do it in two stages, the first to compute the stack
     size, the second to save the args.  */

  for (argnum = first_stack_arg; argnum < nargs; argnum++)
    {
      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (value_type (arg));
      int len = TYPE_LENGTH (arg_type);
      enum type_code typecode = arg_type->code ();

      if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)
	  || (len > bpw * 2))
	{
	  /* Structures are passed as addresses.  */
	  sp -= bpa;
	}
      else
	{
	  /* Big scalars use more than one word.  Code here allows for
	     future quad-word entities (e.g. long double.)  */
	  sp -= align_up (len, bpw);
	}

      /* Ensure our dummy heap doesn't touch the stack, this could only
	 happen if we have many arguments including fabricated arguments.  */
      gdb_assert (heap_offset == 0 || ((heap_sp + heap_offset) < sp));
    }

  sp = gdbarch_frame_align (gdbarch, sp);
  stack_offset = 0;

  /* Push the remaining args on the stack.  */
  for (argnum = first_stack_arg; argnum < nargs; argnum++)
    {
      const gdb_byte *val;
      gdb_byte valbuf[sizeof (ULONGEST)];

      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (value_type (arg));
      int len = TYPE_LENGTH (arg_type);
      enum type_code typecode = arg_type->code ();
      /* The EABI passes structures that do not fit in a register by
	 reference.  In all other cases, pass the structure by value.  */
      if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)
	  || (len > bpw * 2))
	{
	  store_unsigned_integer (valbuf, bpa, byte_order,
				  value_address (arg));
	  len = bpa;
	  val = valbuf;
	}
      else
	val = value_contents (arg).data ();

      while (len > 0)
	{
	  int partial_len = (len < bpw ? len : bpw);

	  write_memory (sp + stack_offset, val, partial_len);
	  stack_offset += align_up (partial_len, bpw);
	  len -= partial_len;
	  val += partial_len;
	}
    }

  /* Save the updated stack pointer.  */
  regcache_cooked_write_unsigned (regcache, OR1K_SP_REGNUM, sp);

  if (heap_offset > 0)
    sp = heap_sp;

  return sp;
}



/* Support functions for frame handling.  */

/* Initialize a prologue cache

   We build a cache, saying where registers of the prev frame can be found
   from the data so far set up in this this.

   We also compute a unique ID for this frame, based on the function start
   address and the stack pointer (as it will be, even if it has yet to be
   computed.

   STACK FORMAT
   ============

   The OR1K has a falling stack frame and a simple prolog.  The Stack
   pointer is R1 and the frame pointer R2.  The frame base is therefore the
   address held in R2 and the stack pointer (R1) is the frame base of the
   next frame.

   l.addi  r1,r1,-frame_size	# SP now points to end of new stack frame

   The stack pointer may not be set up in a frameless function (e.g. a
   simple leaf function).

   l.sw    fp_loc(r1),r2        # old FP saved in new stack frame
   l.addi  r2,r1,frame_size     # FP now points to base of new stack frame

   The frame pointer is not necessarily saved right at the end of the stack
   frame - OR1K saves enough space for any args to called functions right
   at the end (this is a difference from the Architecture Manual).

   l.sw    lr_loc(r1),r9        # Link (return) address

   The link register is usually saved at fp_loc - 4.  It may not be saved at
   all in a leaf function.

   l.sw    reg_loc(r1),ry       # Save any callee saved regs

   The offsets x for the callee saved registers generally (always?) rise in
   increments of 4, starting at fp_loc + 4.  If the frame pointer is
   omitted (an option to GCC), then it may not be saved at all.  There may
   be no callee saved registers.

   So in summary none of this may be present.  However what is present
   seems always to follow this fixed order, and occur before any
   substantive code (it is possible for GCC to have more flexible
   scheduling of the prologue, but this does not seem to occur for OR1K).

   ANALYSIS
   ========

   This prolog is used, even for -O3 with GCC.

   All this analysis must allow for the possibility that the PC is in the
   middle of the prologue.  Data in the cache should only be set up insofar
   as it has been computed.

   HOWEVER.  The frame_id must be created with the SP *as it will be* at
   the end of the Prologue.  Otherwise a recursive call, checking the frame
   with the PC at the start address will end up with the same frame_id as
   the caller.

   A suite of "helper" routines are used, allowing reuse for
   or1k_skip_prologue().

   Reportedly, this is only valid for frames less than 0x7fff in size.  */

static struct trad_frame_cache *
or1k_frame_cache (struct frame_info *this_frame, void **prologue_cache)
{
  struct gdbarch *gdbarch;
  struct trad_frame_cache *info;

  CORE_ADDR this_pc;
  CORE_ADDR this_sp;
  CORE_ADDR this_sp_for_id;
  int frame_size = 0;

  CORE_ADDR start_addr;
  CORE_ADDR end_addr;

  if (or1k_debug)
    gdb_printf (gdb_stdlog,
		"or1k_frame_cache, prologue_cache = %s\n",
		host_address_to_string (*prologue_cache));

  /* Nothing to do if we already have this info.  */
  if (NULL != *prologue_cache)
    return (struct trad_frame_cache *) *prologue_cache;

  /* Get a new prologue cache and populate it with default values.  */
  info = trad_frame_cache_zalloc (this_frame);
  *prologue_cache = info;

  /* Find the start address of this function (which is a normal frame, even
     if the next frame is the sentinel frame) and the end of its prologue.  */
  this_pc = get_frame_pc (this_frame);
  find_pc_partial_function (this_pc, NULL, &start_addr, NULL);

  /* Get the stack pointer if we have one (if there's no process executing
     yet we won't have a frame.  */
  this_sp = (NULL == this_frame) ? 0 :
    get_frame_register_unsigned (this_frame, OR1K_SP_REGNUM);

  /* Return early if GDB couldn't find the function.  */
  if (start_addr == 0)
    {
      if (or1k_debug)
	gdb_printf (gdb_stdlog, "  couldn't find function\n");

      /* JPB: 28-Apr-11.  This is a temporary patch, to get round GDB
	 crashing right at the beginning.  Build the frame ID as best we
	 can.  */
      trad_frame_set_id (info, frame_id_build (this_sp, this_pc));

      return info;
    }

  /* The default frame base of this frame (for ID purposes only - frame
     base is an overloaded term) is its stack pointer.  For now we use the
     value of the SP register in this frame.  However if the PC is in the
     prologue of this frame, before the SP has been set up, then the value
     will actually be that of the prev frame, and we'll need to adjust it
     later.  */
  trad_frame_set_this_base (info, this_sp);
  this_sp_for_id = this_sp;

  /* The default is to find the PC of the previous frame in the link
     register of this frame.  This may be changed if we find the link
     register was saved on the stack.  */
  trad_frame_set_reg_realreg (info, OR1K_NPC_REGNUM, OR1K_LR_REGNUM);

  /* We should only examine code that is in the prologue.  This is all code
     up to (but not including) end_addr.  We should only populate the cache
     while the address is up to (but not including) the PC or end_addr,
     whichever is first.  */
  gdbarch = get_frame_arch (this_frame);
  end_addr = or1k_skip_prologue (gdbarch, start_addr);

  /* All the following analysis only occurs if we are in the prologue and
     have executed the code.  Check we have a sane prologue size, and if
     zero we are frameless and can give up here.  */
  if (end_addr < start_addr)
    error (_("end addr %s is less than start addr %s"),
	   paddress (gdbarch, end_addr), paddress (gdbarch, start_addr));

  if (end_addr == start_addr)
    frame_size = 0;
  else
    {
      /* We have a frame.  Look for the various components.  */
      CORE_ADDR addr = start_addr; /* Where we have got to */
      uint32_t inst = or1k_fetch_instruction (gdbarch, addr);

      unsigned int ra, rb, rd; /* for instruction analysis */
      int simm;

      /* Look for the new stack pointer being set up.  */
      if (or1k_analyse_l_addi (inst, &rd, &ra, &simm)
	  && (OR1K_SP_REGNUM == rd) && (OR1K_SP_REGNUM == ra)
	  && (simm < 0) && (0 == (simm % 4)))
	{
	  frame_size = -simm;
	  addr += OR1K_INSTLEN;
	  inst = or1k_fetch_instruction (gdbarch, addr);

	  /* If the PC has not actually got to this point, then the frame
	     base will be wrong, and we adjust it.

	     If we are past this point, then we need to populate the stack
	     accordingly.  */
	  if (this_pc <= addr)
	    {
	      /* Only do if executing.  */
	      if (0 != this_sp)
		{
		  this_sp_for_id = this_sp + frame_size;
		  trad_frame_set_this_base (info, this_sp_for_id);
		}
	    }
	  else
	    {
	      /* We are past this point, so the stack pointer of the prev
		 frame is frame_size greater than the stack pointer of this
		 frame.  */
	      trad_frame_set_reg_value (info, OR1K_SP_REGNUM,
					this_sp + frame_size);
	    }
	}

      /* From now on we are only populating the cache, so we stop once we
	 get to either the end OR the current PC.  */
      end_addr = (this_pc < end_addr) ? this_pc : end_addr;

      /* Look for the frame pointer being manipulated.  */
      if ((addr < end_addr)
	  && or1k_analyse_l_sw (inst, &simm, &ra, &rb)
	  && (OR1K_SP_REGNUM == ra) && (OR1K_FP_REGNUM == rb)
	  && (simm >= 0) && (0 == (simm % 4)))
	{
	  addr += OR1K_INSTLEN;
	  inst = or1k_fetch_instruction (gdbarch, addr);

	  /* At this stage, we can find the frame pointer of the previous
	     frame on the stack of the current frame.  */
	  trad_frame_set_reg_addr (info, OR1K_FP_REGNUM, this_sp + simm);

	  /* Look for the new frame pointer being set up.  */
	  if ((addr < end_addr)
	      && or1k_analyse_l_addi (inst, &rd, &ra, &simm)
	      && (OR1K_FP_REGNUM == rd) && (OR1K_SP_REGNUM == ra)
	      && (simm == frame_size))
	    {
	      addr += OR1K_INSTLEN;
	      inst = or1k_fetch_instruction (gdbarch, addr);

	      /* If we have got this far, the stack pointer of the previous
		 frame is the frame pointer of this frame.  */
	      trad_frame_set_reg_realreg (info, OR1K_SP_REGNUM,
					  OR1K_FP_REGNUM);
	    }
	}

      /* Look for the link register being saved.  */
      if ((addr < end_addr)
	  && or1k_analyse_l_sw (inst, &simm, &ra, &rb)
	  && (OR1K_SP_REGNUM == ra) && (OR1K_LR_REGNUM == rb)
	  && (simm >= 0) && (0 == (simm % 4)))
	{
	  addr += OR1K_INSTLEN;
	  inst = or1k_fetch_instruction (gdbarch, addr);

	  /* If the link register is saved in the this frame, it holds the
	     value of the PC in the previous frame.  This overwrites the
	     previous information about finding the PC in the link
	     register.  */
	  trad_frame_set_reg_addr (info, OR1K_NPC_REGNUM, this_sp + simm);
	}

      /* Look for arguments or callee-saved register being saved.  The
	 register must be one of the arguments (r3-r8) or the 10 callee
	 saved registers (r10, r12, r14, r16, r18, r20, r22, r24, r26, r28,
	 r30).  The base register must be the FP (for the args) or the SP
	 (for the callee_saved registers).  */
      while (addr < end_addr)
	{
	  if (or1k_analyse_l_sw (inst, &simm, &ra, &rb)
	      && (((OR1K_FP_REGNUM == ra) && or1k_is_arg_reg (rb))
		  || ((OR1K_SP_REGNUM == ra)
		      && or1k_is_callee_saved_reg (rb)))
	      && (0 == (simm % 4)))
	    {
	      addr += OR1K_INSTLEN;
	      inst = or1k_fetch_instruction (gdbarch, addr);

	      /* The register in the previous frame can be found at this
		 location in this frame.  */
	      trad_frame_set_reg_addr (info, rb, this_sp + simm);
	    }
	  else
	    break; /* Not a register save instruction.  */
	}
    }

  /* Build the frame ID */
  trad_frame_set_id (info, frame_id_build (this_sp_for_id, start_addr));

  if (or1k_debug)
    {
      gdb_printf (gdb_stdlog, "  this_sp_for_id = %s\n",
		  paddress (gdbarch, this_sp_for_id));
      gdb_printf (gdb_stdlog, "  start_addr     = %s\n",
		  paddress (gdbarch, start_addr));
    }

  return info;
}

/* Implement the this_id function for the stub unwinder.  */

static void
or1k_frame_this_id (struct frame_info *this_frame,
		    void **prologue_cache, struct frame_id *this_id)
{
  struct trad_frame_cache *info = or1k_frame_cache (this_frame,
						    prologue_cache);

  trad_frame_get_id (info, this_id);
}

/* Implement the prev_register function for the stub unwinder.  */

static struct value *
or1k_frame_prev_register (struct frame_info *this_frame,
			  void **prologue_cache, int regnum)
{
  struct trad_frame_cache *info = or1k_frame_cache (this_frame,
						    prologue_cache);

  return trad_frame_get_register (info, this_frame, regnum);
}

/* Data structures for the normal prologue-analysis-based unwinder.  */

static const struct frame_unwind or1k_frame_unwind = {
  "or1k prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  or1k_frame_this_id,
  or1k_frame_prev_register,
  NULL,
  default_frame_sniffer,
  NULL,
};

/* Architecture initialization for OpenRISC 1000.  */

static struct gdbarch *
or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  const struct bfd_arch_info *binfo;
  tdesc_arch_data_up tdesc_data;
  const struct target_desc *tdesc = info.target_desc;

  /* Find a candidate among the list of pre-declared architectures.  */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (NULL != arches)
    return arches->gdbarch;

  /* None found, create a new architecture from the information
     provided.  Can't initialize all the target dependencies until we
     actually know which target we are talking to, but put in some defaults
     for now.  */
  binfo = info.bfd_arch_info;
  or1k_gdbarch_tdep *tdep = new or1k_gdbarch_tdep;
  tdep->bytes_per_word = binfo->bits_per_word / binfo->bits_per_byte;
  tdep->bytes_per_address = binfo->bits_per_address / binfo->bits_per_byte;
  gdbarch = gdbarch_alloc (&info, tdep);

  /* Target 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_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_long_double_bit (gdbarch, 64);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
  set_gdbarch_ptr_bit (gdbarch, binfo->bits_per_address);
  set_gdbarch_addr_bit (gdbarch, binfo->bits_per_address);
  set_gdbarch_char_signed (gdbarch, 1);

  /* Information about the target architecture */
  set_gdbarch_return_value (gdbarch, or1k_return_value);
  set_gdbarch_breakpoint_kind_from_pc (gdbarch,
				       or1k_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
				       or1k_breakpoint::bp_from_kind);
  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);

  /* Register architecture */
  set_gdbarch_num_regs (gdbarch, OR1K_NUM_REGS);
  set_gdbarch_num_pseudo_regs (gdbarch, OR1K_NUM_PSEUDO_REGS);
  set_gdbarch_sp_regnum (gdbarch, OR1K_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, OR1K_NPC_REGNUM);
  set_gdbarch_ps_regnum (gdbarch, OR1K_SR_REGNUM);
  set_gdbarch_deprecated_fp_regnum (gdbarch, OR1K_FP_REGNUM);

  /* Functions to analyse frames */
  set_gdbarch_skip_prologue (gdbarch, or1k_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_frame_align (gdbarch, or1k_frame_align);
  set_gdbarch_frame_red_zone_size (gdbarch, OR1K_FRAME_RED_ZONE_SIZE);

  /* Functions to access frame data */
  set_gdbarch_unwind_pc (gdbarch, or1k_unwind_pc);
  set_gdbarch_unwind_sp (gdbarch, or1k_unwind_sp);

  /* Functions handling dummy frames */
  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
  set_gdbarch_push_dummy_code (gdbarch, or1k_push_dummy_code);
  set_gdbarch_push_dummy_call (gdbarch, or1k_push_dummy_call);

  /* Frame unwinders.  Use DWARF debug info if available, otherwise use our
     own unwinder.  */
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &or1k_frame_unwind);

  /* Get a CGEN CPU descriptor for this architecture.  */
  {

    const char *mach_name = binfo->printable_name;
    enum cgen_endian endian = (info.byte_order == BFD_ENDIAN_BIG
			       ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);

    tdep->gdb_cgen_cpu_desc =
      or1k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
			  CGEN_CPU_OPEN_ENDIAN, endian, CGEN_CPU_OPEN_END);

    or1k_cgen_init_asm (tdep->gdb_cgen_cpu_desc);
  }

  /* If this mach has a delay slot.  */
  if (binfo->mach == bfd_mach_or1k)
    set_gdbarch_single_step_through_delay (gdbarch,
					   or1k_single_step_through_delay);

  if (!tdesc_has_registers (info.target_desc))
    /* Pick a default target description.  */
    tdesc = tdesc_or1k;

  /* Check any target description for validity.  */
  if (tdesc_has_registers (tdesc))
    {
      const struct tdesc_feature *feature;
      int valid_p;
      int i;

      feature = tdesc_find_feature (tdesc, "org.gnu.gdb.or1k.group0");
      if (feature == NULL)
	return NULL;

      tdesc_data = tdesc_data_alloc ();

      valid_p = 1;

      for (i = 0; i < OR1K_NUM_REGS; i++)
	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
					    or1k_reg_names[i]);

      if (!valid_p)
	return NULL;
    }

  if (tdesc_data != NULL)
    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

  /* Hook in ABI-specific overrides, if they have been registered.  */
  gdbarch_init_osabi (info, gdbarch);

  return gdbarch;
}

/* Dump the target specific data for this architecture.  */

static void
or1k_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
  or1k_gdbarch_tdep *tdep = (or1k_gdbarch_tdep *) gdbarch_tdep (gdbarch);

  if (NULL == tdep)
    return; /* Nothing to report */

  gdb_printf (file, "or1k_dump_tdep: %d bytes per word\n",
	      tdep->bytes_per_word);
  gdb_printf (file, "or1k_dump_tdep: %d bytes per address\n",
	      tdep->bytes_per_address);
}


void _initialize_or1k_tdep ();
void
_initialize_or1k_tdep ()
{
  /* Register this architecture.  */
  gdbarch_register (bfd_arch_or1k, or1k_gdbarch_init, or1k_dump_tdep);

  initialize_tdesc_or1k ();

  /* Debugging flag.  */
  add_setshow_boolean_cmd ("or1k", class_maintenance, &or1k_debug,
			   _("Set OpenRISC debugging."),
			   _("Show OpenRISC debugging."),
			   _("When on, OpenRISC specific debugging is enabled."),
			   NULL,
			   show_or1k_debug,
			   &setdebuglist, &showdebuglist);
}
