/* Target-dependent code for the 32-bit OpenRISC 1000, for the GDB.
   Copyright (C) 2008-2019 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"

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

/* Global debug flag.  */

static int or1k_debug = 0;

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


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

struct gdbarch_tdep
{
  int bytes_per_word;
  int bytes_per_address;
  CGEN_CPU_DESC gdb_cgen_cpu_desc;
};

/* 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 = TYPE_CODE (valtype);
  unsigned int rv_size = TYPE_LENGTH (valtype);
  int bpw = (gdbarch_tdep (gdbarch))->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;

/* 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;
  CGEN_FIELDS tmp_fields;
  const CGEN_INSN *insn;
  struct regcache *regcache = get_current_regcache ();
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  /* 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;

  insn = cgen_lookup_insn (tdep->gdb_cgen_cpu_desc,
			   NULL,
			   or1k_fetch_instruction (gdbarch, ppc),
			   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));
}

/* 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
	    = SYMTAB_COMPUNIT (prologue_sal.symtab);
	  const char *debug_format = COMPUNIT_DEBUGFORMAT (compunit);

	  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)
    fprintf_unfiltered (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)
    fprintf_unfiltered (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)
    fprintf_unfiltered (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)
    fprintf_unfiltered (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);
  int bpa = (gdbarch_tdep (gdbarch))->bytes_per_address;
  int bpw = (gdbarch_tdep (gdbarch))->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 = TYPE_CODE (arg_type);

      if (TYPE_VARARGS (func_type) && argnum >= TYPE_NFIELDS (func_type))
	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), 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);
	}

      /* 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 = TYPE_CODE (arg_type);

      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 = TYPE_CODE (arg_type);
      /* 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);

      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 usally 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)
    fprintf_unfiltered (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)
	fprintf_unfiltered (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)
    {
      fprintf_unfiltered (gdb_stdlog, "  this_sp_for_id = %s\n",
			  paddress (gdbarch, this_sp_for_id));
      fprintf_unfiltered (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 = {
  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;
  struct gdbarch_tdep *tdep;
  const struct bfd_arch_info *binfo;
  struct tdesc_arch_data *tdesc_data = NULL;
  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;
  tdep = XCNEW (struct 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, i,
                                            or1k_reg_names[i]);

      if (!valid_p)
        {
          tdesc_data_cleanup (tdesc_data);
          return NULL;
        }
    }

  if (tdesc_data != NULL)
    {
      /* If we are using tdesc, register our own reggroups, otherwise we
	 will used the defaults.  */
      reggroup_add (gdbarch, general_reggroup);
      reggroup_add (gdbarch, system_reggroup);
      reggroup_add (gdbarch, float_reggroup);
      reggroup_add (gdbarch, vector_reggroup);
      reggroup_add (gdbarch, all_reggroup);
      reggroup_add (gdbarch, save_reggroup);
      reggroup_add (gdbarch, restore_reggroup);

      tdesc_use_registers (gdbarch, tdesc, 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)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

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

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

void
_initialize_or1k_tdep (void)
{
  /* 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);
}
