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

   Copyright (C) 2006-2016 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)
    {
      error (_("Error: malloc size < 0 in file:%s, line:%d!"),
             __FILE__, __LINE__);
      return NULL;
    }
  else 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);
}
