/* Target-dependent code for the S+core architecture, for GDB,
   the GNU Debugger.

   Copyright (C) 2006-2017 Free Software Foundation, Inc.

   Contributed by Qinwei (qinwei@sunnorth.com.cn)
   Contributed by Ching-Peng Lin (cplin@sunplus.com)

   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 "inferior.h"
#include "symtab.h"
#include "objfiles.h"
#include "gdbcore.h"
#include "target.h"
#include "arch-utils.h"
#include "regcache.h"
#include "regset.h"
#include "dis-asm.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
#include "dwarf2-frame.h"
#include "score-tdep.h"

#define G_FLD(_i,_ms,_ls) \
    ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))

typedef struct{
  unsigned long long v;
  unsigned long long raw;
  unsigned int len;
}inst_t;

struct score_frame_cache
{
  CORE_ADDR base;
  CORE_ADDR fp;
  struct trad_frame_saved_reg *saved_regs;
};

static int target_mach = bfd_mach_score7;

static struct type *
score_register_type (struct gdbarch *gdbarch, int regnum)
{
  gdb_assert (regnum >= 0 
              && regnum < ((target_mach == bfd_mach_score7)
			   ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
  return builtin_type (gdbarch)->builtin_uint32;
}

static CORE_ADDR
score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
}

static CORE_ADDR
score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
}

static const char *
score7_register_name (struct gdbarch *gdbarch, int regnum)
{
  const char *score_register_names[] = {
    "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",

    "PSR",     "COND",  "ECR",     "EXCPVEC", "CCR",
    "EPC",     "EMA",   "TLBLOCK", "TLBPT",   "PEADDR",
    "TLBRPT",  "PEVN",  "PECTX",   "LIMPFN",  "LDMPFN", 
    "PREV",    "DREG",  "PC",      "DSAVE",   "COUNTER",
    "LDCR",    "STCR",  "CEH",     "CEL",
  };

  gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS);
  return score_register_names[regnum];
}

static const char *
score3_register_name (struct gdbarch *gdbarch, int regnum)
{
  const char *score_register_names[] = {
    "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",

    "PSR",      "COND",   "ECR",   "EXCPVEC",  "CCR",
    "EPC",      "EMA",    "PREV",  "DREG",     "DSAVE",
    "COUNTER",  "LDCR",   "STCR",  "CEH",      "CEL",
    "",         "",       "PC",
  };

  gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS);
  return score_register_names[regnum];
}

#if WITH_SIM
static int
score_register_sim_regno (struct gdbarch *gdbarch, int regnum)
{
  gdb_assert (regnum >= 0 
              && regnum < ((target_mach == bfd_mach_score7)
			   ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
  return regnum;
}
#endif

static int
score_print_insn (bfd_vma memaddr, struct disassemble_info *info)
{
  if (info->endian == BFD_ENDIAN_BIG)
    return print_insn_big_score (memaddr, info);
  else
    return print_insn_little_score (memaddr, info);
}

static inst_t *
score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *memblock)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  static inst_t inst = { 0, 0, 0 };
  gdb_byte buf[SCORE_INSTLEN] = { 0 };
  int big;
  int ret;

  if (target_has_execution && memblock != NULL)
    {
      /* Fetch instruction from local MEMBLOCK.  */
      memcpy (buf, memblock, SCORE_INSTLEN);
    }
  else
    {
      /* Fetch instruction from target.  */
      ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
      if (ret)
        {
          error (_("Error: target_read_memory in file:%s, line:%d!"),
                  __FILE__, __LINE__);
          return 0;
        }
    }

  inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);
  inst.len = (inst.raw & 0x80008000) ? 4 : 2;
  inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF); 
  big = (byte_order == BFD_ENDIAN_BIG);
  if (inst.len == 2)
    {
      if (big ^ ((addr & 0x2) == 2))
        inst.v = G_FLD (inst.v, 29, 15);
      else
        inst.v = G_FLD (inst.v, 14, 0);
    }
  return &inst;
}

static inst_t *
score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr,
				 enum bfd_endian byte_order)
{
  static inst_t inst = { 0, 0, 0 };

  struct breakplace
  {
    int break_offset;
    int inst_len;
  };
  /*     raw        table 1 (column 2, 3, 4)
    *  0  1  0  *   # 2
    *  0  1  1  0   # 3
    0  1  1  0  *   # 6
                    table 2 (column 1, 2, 3)
    *  0  0  *  *   # 0, 4
    0  1  0  *  *   # 2
    1  1  0  *  *   # 6
   */

  static const struct breakplace bk_table[16] =
    {
      /* table 1 */
      {0, 0},
      {0, 0},
      {0, 4},
      {0, 6},
      {0, 0},
      {0, 0},
      {-2, 6},
      {0, 0},
      /* table 2 */
      {0, 2},
      {0, 0},
      {-2, 4},
      {0, 0},
      {0, 2},
      {0, 0},
      {-4, 6},
      {0, 0}
    };

#define EXTRACT_LEN 2
  CORE_ADDR adjust_pc = *pcptr & ~0x1;
  gdb_byte buf[5][EXTRACT_LEN] =
    {
      {'\0', '\0'},
      {'\0', '\0'},
      {'\0', '\0'},
      {'\0', '\0'},
      {'\0', '\0'}
    };
  int ret;
  unsigned int raw;
  unsigned int cbits = 0;
  int bk_index;
  int i, count;

  inst.v = 0;
  inst.raw = 0;
  inst.len = 0;

  adjust_pc -= 4;
  for (i = 0; i < 5; i++)
    {
      ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN);
      if (ret != 0)
        {
          buf[i][0] = '\0';
          buf[i][1] = '\0';
	  if (i == 2)
            error (_("Error: target_read_memory in file:%s, line:%d!"),
		   __FILE__, __LINE__);
        }

      raw = extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
      cbits = (cbits << 1) | (raw >> 15); 
    }
  adjust_pc += 4;

  if (cbits & 0x4)
    {
      /* table 1 */
      cbits = (cbits >> 1) & 0x7;
      bk_index = cbits;
    }
  else
    {
      /* table 2 */
      cbits = (cbits >> 2) & 0x7;
      bk_index = cbits + 8; 
    }

  gdb_assert (!((bk_table[bk_index].break_offset == 0)
		&& (bk_table[bk_index].inst_len == 0)));

  inst.len = bk_table[bk_index].inst_len;

  i = (bk_table[bk_index].break_offset + 4) / 2;
  count = inst.len / 2;
  for (; count > 0; i++, count--)
    {
      inst.raw = (inst.raw << 16)
	         | extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order);
    }

  switch (inst.len)
    {
    case 2:
      inst.v = inst.raw & 0x7FFF;
      break;
    case 4:
      inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
      break;
    case 6:
      inst.v = ((inst.raw >> 32 & 0x7FFF) << 30)
	       | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
      break;
    }

  if (pcptr)
    *pcptr = adjust_pc + bk_table[bk_index].break_offset;
  if (lenptr)
    *lenptr = bk_table[bk_index].inst_len;

#undef EXTRACT_LEN

  return &inst;
}

static const gdb_byte *
score7_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
			   int *lenptr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[SCORE_INSTLEN] = { 0 };
  int ret;
  unsigned int raw;

  if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0)
    {
      error (_("Error: target_read_memory in file:%s, line:%d!"),
             __FILE__, __LINE__);
    }
  raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order);

  if (byte_order == BFD_ENDIAN_BIG)
    {
      if (!(raw & 0x80008000))
        {
          /* 16bits instruction.  */
          static gdb_byte big_breakpoint16[] = { 0x60, 0x02 };
          *pcptr &= ~0x1;
          *lenptr = sizeof (big_breakpoint16);
          return big_breakpoint16;
        }
      else
        {
          /* 32bits instruction.  */
          static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 };
          *pcptr &= ~0x3;
          *lenptr = sizeof (big_breakpoint32);
          return big_breakpoint32;
        }
    }
  else
    {
      if (!(raw & 0x80008000))
        {
          /* 16bits instruction.  */
          static gdb_byte little_breakpoint16[] = { 0x02, 0x60 };
          *pcptr &= ~0x1;
          *lenptr = sizeof (little_breakpoint16);
          return little_breakpoint16;
        }
      else
        {
          /* 32bits instruction.  */
          static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 };
          *pcptr &= ~0x3;
          *lenptr = sizeof (little_breakpoint32);
          return little_breakpoint32;
        }
    }
}

static const gdb_byte *
score3_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
			   int *lenptr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR adjust_pc = *pcptr; 
  int len;
  static gdb_byte score_break_insns[6][6] = {
    /* The following three instructions are big endian.  */
    { 0x00, 0x20 },
    { 0x80, 0x00, 0x00, 0x06 },
    { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 },
    /* The following three instructions are little endian.  */
    { 0x20, 0x00 },
    { 0x00, 0x80, 0x06, 0x00 },
    { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};

  gdb_byte *p = NULL;
  int index = 0;

  score3_adjust_pc_and_fetch_inst (&adjust_pc, &len, byte_order);

  index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (len / 2 - 1);
  p = score_break_insns[index];

  *pcptr = adjust_pc;
  *lenptr = len;

  return p;
}

static CORE_ADDR
score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
{
  CORE_ADDR adjust_pc = bpaddr; 

  if (target_mach == bfd_mach_score3)
    score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL,
		    		     gdbarch_byte_order (gdbarch));
  else
    adjust_pc = align_down (adjust_pc, 2);
  
  return adjust_pc;
}

static CORE_ADDR
score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return align_down (addr, 16);
}

static void
score_xfer_register (struct regcache *regcache, int regnum, int length,
                     enum bfd_endian endian, gdb_byte *readbuf,
                     const gdb_byte *writebuf, int buf_offset)
{
  int reg_offset = 0;
  gdb_assert (regnum >= 0 
              && regnum < ((target_mach == bfd_mach_score7)
			   ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));

  switch (endian)
    {
    case BFD_ENDIAN_BIG:
      reg_offset = SCORE_REGSIZE - length;
      break;
    case BFD_ENDIAN_LITTLE:
      reg_offset = 0;
      break;
    case BFD_ENDIAN_UNKNOWN:
      reg_offset = 0;
      break;
    default:
      error (_("Error: score_xfer_register in file:%s, line:%d!"),
             __FILE__, __LINE__);
    }

  if (readbuf != NULL)
    regcache_cooked_read_part (regcache, regnum, reg_offset, length,
                               readbuf + buf_offset);
  if (writebuf != NULL)
    regcache_cooked_write_part (regcache, regnum, reg_offset, length,
                                writebuf + buf_offset);
}

static enum return_value_convention
score_return_value (struct gdbarch *gdbarch, struct value *function,
                    struct type *type, struct regcache *regcache,
                    gdb_byte * readbuf, const gdb_byte * writebuf)
{
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
      || TYPE_CODE (type) == TYPE_CODE_UNION
      || TYPE_CODE (type) == TYPE_CODE_ARRAY)
    return RETURN_VALUE_STRUCT_CONVENTION;
  else
    {
      int offset;
      int regnum;
      for (offset = 0, regnum = SCORE_A0_REGNUM;
           offset < TYPE_LENGTH (type);
           offset += SCORE_REGSIZE, regnum++)
        {
          int xfer = SCORE_REGSIZE;

          if (offset + xfer > TYPE_LENGTH (type))
            xfer = TYPE_LENGTH (type) - offset;
          score_xfer_register (regcache, regnum, xfer,
			       gdbarch_byte_order(gdbarch),
                               readbuf, writebuf, offset);
        }
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}

static struct frame_id
score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  return frame_id_build (get_frame_register_unsigned (this_frame,
						      SCORE_SP_REGNUM),
			 get_frame_pc (this_frame));
}

static int
score_type_needs_double_align (struct type *type)
{
  enum type_code typecode = TYPE_CODE (type);

  if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8)
      || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8))
    return 1;
  else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
    {
      int i, n;

      n = TYPE_NFIELDS (type);
      for (i = 0; i < n; i++)
        if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
          return 1;
      return 0;
    }
  return 0;
}

static CORE_ADDR
score_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                       struct regcache *regcache, CORE_ADDR bp_addr,
                       int nargs, struct value **args, CORE_ADDR sp,
                       int struct_return, CORE_ADDR struct_addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int argnum;
  int argreg;
  int arglen = 0;
  CORE_ADDR stack_offset = 0;
  CORE_ADDR addr = 0;

  /* Step 1, Save RA.  */
  regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr);

  /* Step 2, Make space on the stack for the args.  */
  struct_addr = align_down (struct_addr, 16);
  sp = align_down (sp, 16);
  for (argnum = 0; argnum < nargs; argnum++)
    arglen += align_up (TYPE_LENGTH (value_type (args[argnum])),
                        SCORE_REGSIZE);
  sp -= align_up (arglen, 16);

  argreg = SCORE_BEGIN_ARG_REGNUM;

  /* Step 3, Check if struct return then save the struct address to
     r4 and increase the stack_offset by 4.  */
  if (struct_return)
    {
      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
      stack_offset += SCORE_REGSIZE;
    }

  /* Step 4, Load arguments:
     If arg length is too long (> 4 bytes), then split the arg and
     save every parts.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (value_type (arg));
      enum type_code typecode = TYPE_CODE (arg_type);
      const gdb_byte *val = value_contents (arg);
      int downward_offset = 0;
      int arg_last_part_p = 0;

      arglen = TYPE_LENGTH (arg_type);

      /* If a arg should be aligned to 8 bytes (long long or double),
         the value should be put to even register numbers.  */
      if (score_type_needs_double_align (arg_type))
        {
          if (argreg & 1)
            argreg++;
        }

      /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose
         the default "downward"/"upward" method:

         Example:

         struct struc
         {
           char a; char b; char c;
         } s = {'a', 'b', 'c'};

         Big endian:    s = {X, 'a', 'b', 'c'}
         Little endian: s = {'a', 'b', 'c', X}

         Where X is a hole.  */

      if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
          && (typecode == TYPE_CODE_STRUCT
              || typecode == TYPE_CODE_UNION)
          && argreg > SCORE_LAST_ARG_REGNUM
          && arglen < SCORE_REGSIZE)
        downward_offset += (SCORE_REGSIZE - arglen);

      while (arglen > 0)
        {
          int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE;
          ULONGEST regval = extract_unsigned_integer (val, partial_len,
			  			      byte_order);

          /* The last part of a arg should shift left when
             gdbarch_byte_order is BFD_ENDIAN_BIG.  */
          if (byte_order == BFD_ENDIAN_BIG
              && arg_last_part_p == 1
              && (typecode == TYPE_CODE_STRUCT
                  || typecode == TYPE_CODE_UNION))
            regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT);

          /* Always increase the stack_offset and save args to stack.  */
          addr = sp + stack_offset + downward_offset;
          write_memory (addr, val, partial_len);

          if (argreg <= SCORE_LAST_ARG_REGNUM)
            {
              regcache_cooked_write_unsigned (regcache, argreg++, regval);
              if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2)
                arg_last_part_p = 1;
            }

          val += partial_len;
          arglen -= partial_len;
          stack_offset += align_up (partial_len, SCORE_REGSIZE);
        }
    }

  /* Step 5, Save SP.  */
  regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp);

  return sp;
}

static CORE_ADDR
score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR cpc = pc;
  int iscan = 32, stack_sub = 0;
  while (iscan-- > 0)
    {
      inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
      if (!inst)
        break;
      if ((inst->len == 4) && !stack_sub
          && (G_FLD (inst->v, 29, 25) == 0x1
              && G_FLD (inst->v, 24, 20) == 0x0))
        {
          /* addi r0, offset */
          stack_sub = cpc + SCORE_INSTLEN;
          pc = cpc + SCORE_INSTLEN;
        }
      else if ((inst->len == 4)
               && (G_FLD (inst->v, 29, 25) == 0x0)
               && (G_FLD (inst->v, 24, 20) == 0x2)
               && (G_FLD (inst->v, 19, 15) == 0x0)
               && (G_FLD (inst->v, 14, 10) == 0xF)
               && (G_FLD (inst->v, 9, 0) == 0x56))
        {
          /* mv r2, r0  */
          pc = cpc + SCORE_INSTLEN;
          break;
        }
      else if ((inst->len == 2)
               && (G_FLD (inst->v, 14, 12) == 0x0)
               && (G_FLD (inst->v, 11, 8) == 0x2)
               && (G_FLD (inst->v, 7, 4) == 0x0)
               && (G_FLD (inst->v, 3, 0) == 0x3))
        {
          /* mv! r2, r0 */
          pc = cpc + SCORE16_INSTLEN;
          break;
        }
      else if ((inst->len == 2)
               && ((G_FLD (inst->v, 14, 12) == 3)    /* j15 form */
                   || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */
                   || (G_FLD (inst->v, 14, 12) == 0x0
                       && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */
        break;
      else if ((inst->len == 4)
               && ((G_FLD (inst->v, 29, 25) == 2)    /* j32 form */
                   || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */
                   || (G_FLD (inst->v, 29, 25) == 0x0
                       && G_FLD (inst->v, 6, 1) == 0x4)))  /* br */
        break;

      cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
    }
  return pc;
}

static CORE_ADDR
score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR cpc = pc;
  int iscan = 32, stack_sub = 0;
  while (iscan-- > 0)
    {
      inst_t *inst
	= score3_adjust_pc_and_fetch_inst (&cpc, NULL,
					   gdbarch_byte_order (gdbarch));

      if (!inst)
        break;
      if (inst->len == 4 && !stack_sub
          && (G_FLD (inst->v, 29, 25) == 0x1)
          && (G_FLD (inst->v, 19, 17) == 0x0)
	  && (G_FLD (inst->v, 24, 20) == 0x0))
        {
          /* addi r0, offset */
          stack_sub = cpc + inst->len;
          pc = cpc + inst->len;
        }
      else if (inst->len == 4
               && (G_FLD (inst->v, 29, 25) == 0x0)
	       && (G_FLD (inst->v, 24, 20) == 0x2)
	       && (G_FLD (inst->v, 19, 15) == 0x0)
	       && (G_FLD (inst->v, 14, 10) == 0xF)
	       && (G_FLD (inst->v, 9, 0) == 0x56))
        {
          /* mv r2, r0  */
          pc = cpc + inst->len;
          break;
        }
      else if ((inst->len == 2)
               && (G_FLD (inst->v, 14, 10) == 0x10)
               && (G_FLD (inst->v, 9, 5) == 0x2)
	       && (G_FLD (inst->v, 4, 0) == 0x0))
        {
          /* mv! r2, r0 */
          pc = cpc + inst->len;
          break;
        }
      else if (inst->len == 2
               && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
                   || (G_FLD (inst->v, 14, 12) == 0x0
                       && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
        break;
      else if (inst->len == 4
               && ((G_FLD (inst->v, 29, 25) == 2)    /* j32 form */
                   || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
        break;

      cpc += inst->len;
    }
  return pc;
}

/* Implement the stack_frame_destroyed_p gdbarch method. */

static int
score7_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
{
  inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);

  if (inst->v == 0x23)
    return 1;   /* mv! r0, r2 */
  else if (G_FLD (inst->v, 14, 12) == 0x2
           && G_FLD (inst->v, 3, 0) == 0xa)
    return 1;   /* pop! */
  else if (G_FLD (inst->v, 14, 12) == 0x0
           && G_FLD (inst->v, 7, 0) == 0x34)
    return 1;   /* br! r3 */
  else if (G_FLD (inst->v, 29, 15) == 0x2
           && G_FLD (inst->v, 6, 1) == 0x2b)
    return 1;   /* mv r0, r2 */
  else if (G_FLD (inst->v, 29, 25) == 0x0
           && G_FLD (inst->v, 6, 1) == 0x4
           && G_FLD (inst->v, 19, 15) == 0x3)
    return 1;   /* br r3 */
  else
    return 0;
}

/* Implement the stack_frame_destroyed_p gdbarch method. */

static int
score3_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
{
  CORE_ADDR pc = cur_pc;
  inst_t *inst
    = score3_adjust_pc_and_fetch_inst (&pc, NULL,
				       gdbarch_byte_order (gdbarch));

  if (inst->len == 2
      && (G_FLD (inst->v, 14, 10) == 0x10)
      && (G_FLD (inst->v, 9, 5) == 0x0)
      && (G_FLD (inst->v, 4, 0) == 0x2))
    return 1;   /* mv! r0, r2 */
  else if (inst->len == 4
           && (G_FLD (inst->v, 29, 25) == 0x0)
           && (G_FLD (inst->v, 24, 20) == 0x2)
           && (G_FLD (inst->v, 19, 15) == 0x0)
	   && (G_FLD (inst->v, 14, 10) == 0xF)
	   && (G_FLD (inst->v, 9, 0) == 0x56))
    return 1;   /* mv r0, r2 */
  else if (inst->len == 2
           && (G_FLD (inst->v, 14, 12) == 0x0)
           && (G_FLD (inst->v, 11, 5) == 0x2))
    return 1;   /* pop! */
  else if (inst->len == 2
           && (G_FLD (inst->v, 14, 12) == 0x0)
           && (G_FLD (inst->v, 11, 7) == 0x0)
           && (G_FLD (inst->v, 6, 5) == 0x2))
    return 1;   /* rpop! */
  else if (inst->len == 2
           && (G_FLD (inst->v, 14, 12) == 0x0)
           && (G_FLD (inst->v, 11, 5) == 0x4)
           && (G_FLD (inst->v, 4, 0) == 0x3))
    return 1;   /* br! r3 */
  else if (inst->len == 4
           && (G_FLD (inst->v, 29, 25) == 0x0)
           && (G_FLD (inst->v, 24, 20) == 0x0)
           && (G_FLD (inst->v, 19, 15) == 0x3)
           && (G_FLD (inst->v, 14, 10) == 0xF)
           && (G_FLD (inst->v, 9, 0) == 0x8))
    return 1;   /* br r3 */
  else
    return 0;
}

static gdb_byte *
score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
{
  int ret;
  gdb_byte *memblock = NULL;

  if (size == 0)
    return NULL;

  memblock = (gdb_byte *) xmalloc (size);
  memset (memblock, 0, size);
  ret = target_read_memory (addr & ~0x3, memblock, size);
  if (ret)
    {
      error (_("Error: target_read_memory in file:%s, line:%d!"),
             __FILE__, __LINE__);
      return NULL;
    }
  return memblock;
}

static void
score7_free_memblock (gdb_byte *memblock)
{
  xfree (memblock);
}

static void
score7_adjust_memblock_ptr (gdb_byte **memblock, CORE_ADDR prev_pc,
                           CORE_ADDR cur_pc)
{
  if (prev_pc == -1)
    {
      /* First time call this function, do nothing.  */
    }
  else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
    {
      /* First 16-bit instruction, then 32-bit instruction.  */
      *memblock += SCORE_INSTLEN;
    }
  else if (cur_pc - prev_pc == 4)
    {
      /* Is 32-bit instruction, increase MEMBLOCK by 4.  */
      *memblock += SCORE_INSTLEN;
    }
}

static void
score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
                        struct frame_info *this_frame,
                        struct score_frame_cache *this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR sp;
  CORE_ADDR fp;
  CORE_ADDR cur_pc = startaddr;

  int sp_offset = 0;
  int ra_offset = 0;
  int fp_offset = 0;
  int ra_offset_p = 0;
  int fp_offset_p = 0;
  int inst_len = 0;

  gdb_byte *memblock = NULL;
  gdb_byte *memblock_ptr = NULL;
  CORE_ADDR prev_pc = -1;

  /* Allocate MEMBLOCK if PC - STARTADDR > 0.  */
  memblock_ptr = memblock =
    score7_malloc_and_get_memblock (startaddr, pc - startaddr);

  sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
  fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);

  for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
    {
      inst_t *inst = NULL;
      if (memblock != NULL)
        {
          /* Reading memory block from target succefully and got all
             the instructions(from STARTADDR to PC) needed.  */
          score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
          inst = score7_fetch_inst (gdbarch, cur_pc, memblock);
        }
      else
        {
          /* Otherwise, we fetch 4 bytes from target, and GDB also
             work correctly.  */
          inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
        }

      /* FIXME: make a full-power prologue analyzer.  */
      if (inst->len == 2)
        {
          inst_len = SCORE16_INSTLEN;

          if (G_FLD (inst->v, 14, 12) == 0x2
              && G_FLD (inst->v, 3, 0) == 0xe)
            {
              /* push! */
              sp_offset += 4;

              if (G_FLD (inst->v, 11, 7) == 0x6
                  && ra_offset_p == 0)
                {
                  /* push! r3, [r0] */
                  ra_offset = sp_offset;
                  ra_offset_p = 1;
                }
              else if (G_FLD (inst->v, 11, 7) == 0x4
                       && fp_offset_p == 0)
                {
                  /* push! r2, [r0] */
                  fp_offset = sp_offset;
                  fp_offset_p = 1;
                }
            }
          else if (G_FLD (inst->v, 14, 12) == 0x2
                   && G_FLD (inst->v, 3, 0) == 0xa)
            {
              /* pop! */
              sp_offset -= 4;
            }
          else if (G_FLD (inst->v, 14, 7) == 0xc1
                   && G_FLD (inst->v, 2, 0) == 0x0)
            {
              /* subei! r0, n */
              sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3));
            }
          else if (G_FLD (inst->v, 14, 7) == 0xc0
                   && G_FLD (inst->v, 2, 0) == 0x0)
            {
              /* addei! r0, n */
              sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3));
            }
        }
      else
        {
          inst_len = SCORE_INSTLEN;

          if (G_FLD(inst->v, 29, 25) == 0x3
              && G_FLD(inst->v, 2, 0) == 0x4
              && G_FLD(inst->v, 19, 15) == 0)
            {
                /* sw rD, [r0, offset]+ */
                sp_offset += SCORE_INSTLEN;

                if (G_FLD(inst->v, 24, 20) == 0x3)
                  {
                      /* rD = r3 */
                      if (ra_offset_p == 0)
                        {
                            ra_offset = sp_offset;
                            ra_offset_p = 1;
                        }
                  }
                else if (G_FLD(inst->v, 24, 20) == 0x2)
                  {
                      /* rD = r2 */
                      if (fp_offset_p == 0)
                        {
                            fp_offset = sp_offset;
                            fp_offset_p = 1;
                        }
                  }
            }
          else if (G_FLD(inst->v, 29, 25) == 0x14
                   && G_FLD(inst->v, 19,15) == 0)
            {
                /* sw rD, [r0, offset] */
                if (G_FLD(inst->v, 24, 20) == 0x3)
                  {
                      /* rD = r3 */
                      ra_offset = sp_offset - G_FLD(inst->v, 14, 0);
                      ra_offset_p = 1;
                  }
                else if (G_FLD(inst->v, 24, 20) == 0x2)
                  {
                      /* rD = r2 */
                      fp_offset = sp_offset - G_FLD(inst->v, 14, 0);
                      fp_offset_p = 1;
                  }
            }
          else if (G_FLD (inst->v, 29, 15) == 0x1c60
                   && G_FLD (inst->v, 2, 0) == 0x0)
            {
              /* lw r3, [r0]+, 4 */
              sp_offset -= SCORE_INSTLEN;
              ra_offset_p = 1;
            }
          else if (G_FLD (inst->v, 29, 15) == 0x1c40
                   && G_FLD (inst->v, 2, 0) == 0x0)
            {
              /* lw r2, [r0]+, 4 */
              sp_offset -= SCORE_INSTLEN;
              fp_offset_p = 1;
            }

          else if (G_FLD (inst->v, 29, 17) == 0x100
                   && G_FLD (inst->v, 0, 0) == 0x0)
            {
              /* addi r0, -offset */
              sp_offset += 65536 - G_FLD (inst->v, 16, 1);
            }
          else if (G_FLD (inst->v, 29, 17) == 0x110
                   && G_FLD (inst->v, 0, 0) == 0x0)
            {
              /* addi r2, offset */
              if (pc - cur_pc > 4)
                {
                  unsigned int save_v = inst->v;
                  inst_t *inst2 =
                    score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
                  if (inst2->v == 0x23)
                    {
                      /* mv! r0, r2 */
                      sp_offset -= G_FLD (save_v, 16, 1);
                    }
                }
            }
        }
    }

  /* Save RA.  */
  if (ra_offset_p == 1)
    {
      if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
        this_cache->saved_regs[SCORE_PC_REGNUM].addr =
          sp + sp_offset - ra_offset;
    }
  else
    {
      this_cache->saved_regs[SCORE_PC_REGNUM] =
        this_cache->saved_regs[SCORE_RA_REGNUM];
    }

  /* Save FP.  */
  if (fp_offset_p == 1)
    {
      if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
        this_cache->saved_regs[SCORE_FP_REGNUM].addr =
          sp + sp_offset - fp_offset;
    }

  /* Save SP and FP.  */
  this_cache->base = sp + sp_offset;
  this_cache->fp = fp;

  /* Don't forget to free MEMBLOCK if we allocated it.  */
  if (memblock_ptr != NULL)
    score7_free_memblock (memblock_ptr);
}

static void
score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
                        struct frame_info *this_frame,
                        struct score_frame_cache *this_cache)
{
  CORE_ADDR sp;
  CORE_ADDR fp;
  CORE_ADDR cur_pc = startaddr;
  enum bfd_endian byte_order
    = gdbarch_byte_order (get_frame_arch (this_frame));

  int sp_offset = 0;
  int ra_offset = 0;
  int fp_offset = 0;
  int ra_offset_p = 0;
  int fp_offset_p = 0;
  int inst_len = 0;

  sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
  fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);

  for (; cur_pc < pc; cur_pc += inst_len)
    {
      inst_t *inst = NULL;

      inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order);

      /* FIXME: make a full-power prologue analyzer.  */
      if (inst->len == 2)
        {
          if (G_FLD (inst->v, 14, 12) == 0x0
              && G_FLD (inst->v, 11, 7) == 0x0
              && G_FLD (inst->v, 6, 5) == 0x3)
            {
              /* push! */
              sp_offset += 4;

              if (G_FLD (inst->v, 4, 0) == 0x3
                  && ra_offset_p == 0)
                {
                  /* push! r3, [r0] */
                  ra_offset = sp_offset;
                  ra_offset_p = 1;
                }
              else if (G_FLD (inst->v, 4, 0) == 0x2
                       && fp_offset_p == 0)
                {
                  /* push! r2, [r0] */
                  fp_offset = sp_offset;
                  fp_offset_p = 1;
                }
            }
          else if (G_FLD (inst->v, 14, 12) == 0x6
                   && G_FLD (inst->v, 11, 10) == 0x3)
            {
              /* rpush! */
              int start_r = G_FLD (inst->v, 9, 5);
              int cnt = G_FLD (inst->v, 4, 0);
     
              if ((ra_offset_p == 0)
		  && (start_r <= SCORE_RA_REGNUM)
                  && (SCORE_RA_REGNUM < start_r + cnt))
                {
                  /* rpush! contains r3 */
                  ra_offset_p = 1;
                  ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
                }

              if ((fp_offset_p == 0)
		  && (start_r <= SCORE_FP_REGNUM)
                  && (SCORE_FP_REGNUM < start_r + cnt))
                {
                  /* rpush! contains r2 */
                  fp_offset_p = 1;
                  fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
                }

              sp_offset += 4 * cnt;
            }
          else if (G_FLD (inst->v, 14, 12) == 0x0
                   && G_FLD (inst->v, 11, 7) == 0x0
                   && G_FLD (inst->v, 6, 5) == 0x2)
            {
              /* pop! */
              sp_offset -= 4;
            }
          else if (G_FLD (inst->v, 14, 12) == 0x6
                   && G_FLD (inst->v, 11, 10) == 0x2)
            {
              /* rpop! */
              sp_offset -= 4 * G_FLD (inst->v, 4, 0);
            }
          else if (G_FLD (inst->v, 14, 12) == 0x5
                   && G_FLD (inst->v, 11, 10) == 0x3
                   && G_FLD (inst->v, 9, 6) == 0x0)
            {
              /* addi! r0, -offset */
              int imm = G_FLD (inst->v, 5, 0);
	      if (imm >> 5)
		imm = -(0x3F - imm + 1);
	      sp_offset -= imm;
            }
          else if (G_FLD (inst->v, 14, 12) == 0x5
                   && G_FLD (inst->v, 11, 10) == 0x3
                   && G_FLD (inst->v, 9, 6) == 0x2)
            {
              /* addi! r2, offset */
              if (pc - cur_pc >= 2)
                {
		  inst_t *inst2;
		  
		  cur_pc += inst->len;
		  inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
							   byte_order);

                  if (inst2->len == 2
                      && G_FLD (inst2->v, 14, 10) == 0x10
                      && G_FLD (inst2->v, 9, 5) == 0x0
                      && G_FLD (inst2->v, 4, 0) == 0x2)
                    {
                      /* mv! r0, r2 */
                      int imm = G_FLD (inst->v, 5, 0);
	              if (imm >> 5)
		        imm = -(0x3F - imm + 1);
                      sp_offset -= imm;
                    }
                }
	    }
        }
      else if (inst->len == 4)
        {
          if (G_FLD (inst->v, 29, 25) == 0x3
              && G_FLD (inst->v, 2, 0) == 0x4
              && G_FLD (inst->v, 24, 20) == 0x3
              && G_FLD (inst->v, 19, 15) == 0x0)
            {
              /* sw r3, [r0, offset]+ */
              sp_offset += inst->len;
              if (ra_offset_p == 0)
                {
                  ra_offset = sp_offset;
                  ra_offset_p = 1;
                }
            }
          else if (G_FLD (inst->v, 29, 25) == 0x3
                   && G_FLD (inst->v, 2, 0) == 0x4
                   && G_FLD (inst->v, 24, 20) == 0x2
                   && G_FLD (inst->v, 19, 15) == 0x0)
            {
              /* sw r2, [r0, offset]+ */
              sp_offset += inst->len;
              if (fp_offset_p == 0)
                {
                  fp_offset = sp_offset;
                  fp_offset_p = 1;
                }
            }
          else if (G_FLD (inst->v, 29, 25) == 0x7
                   && G_FLD (inst->v, 2, 0) == 0x0
                   && G_FLD (inst->v, 24, 20) == 0x3
                   && G_FLD (inst->v, 19, 15) == 0x0)
            {
              /* lw r3, [r0]+, 4 */
              sp_offset -= inst->len;
              ra_offset_p = 1;
            }
          else if (G_FLD (inst->v, 29, 25) == 0x7
                   && G_FLD (inst->v, 2, 0) == 0x0
                   && G_FLD (inst->v, 24, 20) == 0x2
                   && G_FLD (inst->v, 19, 15) == 0x0)
            {
              /* lw r2, [r0]+, 4 */
              sp_offset -= inst->len;
              fp_offset_p = 1;
            }
          else if (G_FLD (inst->v, 29, 25) == 0x1
                   && G_FLD (inst->v, 19, 17) == 0x0
                   && G_FLD (inst->v, 24, 20) == 0x0
                   && G_FLD (inst->v, 0, 0) == 0x0)
            {
              /* addi r0, -offset */
              int imm = G_FLD (inst->v, 16, 1);
	      if (imm >> 15)
		imm = -(0xFFFF - imm + 1);
              sp_offset -= imm;
            }
          else if (G_FLD (inst->v, 29, 25) == 0x1
                   && G_FLD (inst->v, 19, 17) == 0x0
                   && G_FLD (inst->v, 24, 20) == 0x2
                   && G_FLD (inst->v, 0, 0) == 0x0)
            {
              /* addi r2, offset */
              if (pc - cur_pc >= 2)
                {
		  inst_t *inst2;
		  
		  cur_pc += inst->len;
		  inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL,
							   byte_order);

                  if (inst2->len == 2
                      && G_FLD (inst2->v, 14, 10) == 0x10
                      && G_FLD (inst2->v, 9, 5) == 0x0
                      && G_FLD (inst2->v, 4, 0) == 0x2)
                    {
                      /* mv! r0, r2 */
                      int imm = G_FLD (inst->v, 16, 1);
	              if (imm >> 15)
		        imm = -(0xFFFF - imm + 1);
                      sp_offset -= imm;
                    }
                }
            }
        }
    }

  /* Save RA.  */
  if (ra_offset_p == 1)
    {
      if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
        this_cache->saved_regs[SCORE_PC_REGNUM].addr =
          sp + sp_offset - ra_offset;
    }
  else
    {
      this_cache->saved_regs[SCORE_PC_REGNUM] =
        this_cache->saved_regs[SCORE_RA_REGNUM];
    }

  /* Save FP.  */
  if (fp_offset_p == 1)
    {
      if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
        this_cache->saved_regs[SCORE_FP_REGNUM].addr =
          sp + sp_offset - fp_offset;
    }

  /* Save SP and FP.  */
  this_cache->base = sp + sp_offset;
  this_cache->fp = fp;
}

static struct score_frame_cache *
score_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
{
  struct score_frame_cache *cache;

  if ((*this_cache) != NULL)
    return (struct score_frame_cache *) (*this_cache);

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

  /* Analyze the prologue.  */
  {
    const CORE_ADDR pc = get_frame_pc (this_frame);
    CORE_ADDR start_addr;

    find_pc_partial_function (pc, NULL, &start_addr, NULL);
    if (start_addr == 0)
      return cache;

    if (target_mach == bfd_mach_score3)
      score3_analyze_prologue (start_addr, pc, this_frame,
			       (struct score_frame_cache *) *this_cache);
    else
      score7_analyze_prologue (start_addr, pc, this_frame,
			       (struct score_frame_cache *) *this_cache);
  }

  /* Save SP.  */
  trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base);

  return (struct score_frame_cache *) (*this_cache);
}

static void
score_prologue_this_id (struct frame_info *this_frame, void **this_cache,
                        struct frame_id *this_id)
{
  struct score_frame_cache *info = score_make_prologue_cache (this_frame,
                                                              this_cache);
  (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
}

static struct value *
score_prologue_prev_register (struct frame_info *this_frame,
                              void **this_cache, int regnum)
{
  struct score_frame_cache *info = score_make_prologue_cache (this_frame,
                                                              this_cache);
  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}

static const struct frame_unwind score_prologue_unwind =
{
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  score_prologue_this_id,
  score_prologue_prev_register,
  NULL,
  default_frame_sniffer,
  NULL
};

static CORE_ADDR
score_prologue_frame_base_address (struct frame_info *this_frame,
                                   void **this_cache)
{
  struct score_frame_cache *info =
    score_make_prologue_cache (this_frame, this_cache);
  return info->fp;
}

static const struct frame_base score_prologue_frame_base =
{
  &score_prologue_unwind,
  score_prologue_frame_base_address,
  score_prologue_frame_base_address,
  score_prologue_frame_base_address,
};

static const struct frame_base *
score_prologue_frame_base_sniffer (struct frame_info *this_frame)
{
  return &score_prologue_frame_base;
}

/* Core file support.  */

static const struct regcache_map_entry score7_linux_gregmap[] =
  {
    /* FIXME: According to the current Linux kernel, r0 is preceded by
       9 rather than 7 words.  */
    { 7, REGCACHE_MAP_SKIP, 4 },
    { 32, 0, 4 },		/* r0 ... r31 */
    { 1, 55, 4 },		/* CEL */
    { 1, 54, 4 },		/* CEH */
    { 1, 53, 4 },		/* sr0, i.e. cnt or COUNTER */
    { 1, 52, 4 },		/* sr1, i.e. lcr or LDCR */
    { 1, 51, 4 },		/* sr2, i.e. scr or STCR */
    { 1, 49, 4 },		/* PC (same slot as EPC) */
    { 1, 38, 4 },		/* EMA */
    { 1, 32, 4 },		/* PSR */
    { 1, 34, 4 },		/* ECR */
    { 1, 33, 4 },		/* COND */
    { 0 }
  };

#define SCORE7_LINUX_EPC_OFFSET (44 * 4)
#define SCORE7_LINUX_SIZEOF_GREGSET (49 * 4)

static void
score7_linux_supply_gregset(const struct regset *regset,
			    struct regcache *regcache,
			    int regnum, const void *buf,
			    size_t size)
{
  regcache_supply_regset (regset, regcache, regnum, buf, size);

  /* Supply the EPC from the same slot as the PC.  Note that the
     collect function will store the PC in that slot.  */
  if ((regnum == -1 || regnum == SCORE_EPC_REGNUM)
      && size >= SCORE7_LINUX_EPC_OFFSET + 4)
    regcache_raw_supply (regcache, SCORE_EPC_REGNUM,
			 (const gdb_byte *) buf
			 + SCORE7_LINUX_EPC_OFFSET);
}

static const struct regset score7_linux_gregset =
  {
    score7_linux_gregmap,
    score7_linux_supply_gregset,
    regcache_collect_regset
  };

/* Iterate over core file register note sections.  */

static void
score7_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
					   iterate_over_regset_sections_cb *cb,
					   void *cb_data,
					   const struct regcache *regcache)
{
  cb (".reg", SCORE7_LINUX_SIZEOF_GREGSET, &score7_linux_gregset,
      NULL, cb_data);
}

static struct gdbarch *
score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  target_mach = info.bfd_arch_info->mach;

  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    {
      return (arches->gdbarch);
    }
  gdbarch = gdbarch_alloc (&info, NULL);

  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 32);
  set_gdbarch_float_bit (gdbarch, 32);
  set_gdbarch_double_bit (gdbarch, 64);
  set_gdbarch_long_double_bit (gdbarch, 64);
#if WITH_SIM
  set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno);
#endif
  set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM);
  set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM);
  set_gdbarch_adjust_breakpoint_address (gdbarch,
					 score_adjust_breakpoint_address);
  set_gdbarch_register_type (gdbarch, score_register_type);
  set_gdbarch_frame_align (gdbarch, score_frame_align);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
  set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
  set_gdbarch_print_insn (gdbarch, score_print_insn);

  switch (target_mach)
    {
    case bfd_mach_score7:
      set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc);
      set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
      set_gdbarch_stack_frame_destroyed_p (gdbarch,
					   score7_stack_frame_destroyed_p);
      set_gdbarch_register_name (gdbarch, score7_register_name);
      set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
      /* Core file support.  */
      set_gdbarch_iterate_over_regset_sections
	(gdbarch, score7_linux_iterate_over_regset_sections);
      break;

    case bfd_mach_score3:
      set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc);
      set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
      set_gdbarch_stack_frame_destroyed_p (gdbarch,
					   score3_stack_frame_destroyed_p);
      set_gdbarch_register_name (gdbarch, score3_register_name);
      set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
      break;
    }

  /* Watchpoint hooks.  */
  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);

  /* Dummy frame hooks.  */
  set_gdbarch_return_value (gdbarch, score_return_value);
  set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
  set_gdbarch_dummy_id (gdbarch, score_dummy_id);
  set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call);

  /* Normal frame hooks.  */
  dwarf2_append_unwinders (gdbarch);
  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
  frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind);
  frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer);

  return gdbarch;
}

extern initialize_file_ftype _initialize_score_tdep;

void
_initialize_score_tdep (void)
{
  gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL);
}
