/* Target-dependent code for Moxie.

   Copyright (C) 2009-2018 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 "frame-unwind.h"
#include "frame-base.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "value.h"
#include "inferior.h"
#include "symfile.h"
#include "objfiles.h"
#include "osabi.h"
#include "language.h"
#include "arch-utils.h"
#include "regcache.h"
#include "trad-frame.h"
#include "dis-asm.h"
#include "record.h"
#include "record-full.h"

#include "moxie-tdep.h"
#include <algorithm>

/* Use an invalid address value as 'not available' marker.  */
enum { REG_UNAVAIL = (CORE_ADDR) -1 };

struct moxie_frame_cache
{
  /* Base address.  */
  CORE_ADDR base;
  CORE_ADDR pc;
  LONGEST framesize;
  CORE_ADDR saved_regs[MOXIE_NUM_REGS];
  CORE_ADDR saved_sp;
};

/* Implement the "frame_align" gdbarch method.  */

static CORE_ADDR
moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  /* Align to the size of an instruction (so that they can safely be
     pushed onto the stack.  */
  return sp & ~1;
}

constexpr gdb_byte moxie_break_insn[] = { 0x35, 0x00 };

typedef BP_MANIPULATION (moxie_break_insn) moxie_breakpoint;

/* Moxie register names.  */

static const char *moxie_register_names[] = {
  "$fp",  "$sp",  "$r0",  "$r1",  "$r2",
  "$r3",  "$r4",  "$r5", "$r6", "$r7",
  "$r8", "$r9", "$r10", "$r11", "$r12",
  "$r13", "$pc", "$cc" };

/* Implement the "register_name" gdbarch method.  */

static const char *
moxie_register_name (struct gdbarch *gdbarch, int reg_nr)
{
  if (reg_nr < 0)
    return NULL;
  if (reg_nr >= MOXIE_NUM_REGS)
    return NULL;
  return moxie_register_names[reg_nr];
}

/* Implement the "register_type" gdbarch method.  */

static struct type *
moxie_register_type (struct gdbarch *gdbarch, int reg_nr)
{
  if (reg_nr == MOXIE_PC_REGNUM)
    return  builtin_type (gdbarch)->builtin_func_ptr;
  else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM)
    return builtin_type (gdbarch)->builtin_data_ptr;
  else
    return builtin_type (gdbarch)->builtin_int32;
}

/* Write into appropriate registers a function return value
   of type TYPE, given in virtual format.  */

static void
moxie_store_return_value (struct type *type, struct regcache *regcache,
			 const gdb_byte *valbuf)
{
  struct gdbarch *gdbarch = regcache->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR regval;
  int len = TYPE_LENGTH (type);

  /* Things always get returned in RET1_REGNUM, RET2_REGNUM.  */
  regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order);
  regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);
  if (len > 4)
    {
      regval = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
      regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
    }
}

/* Decode the instructions within the given address range.  Decide
   when we must have reached the end of the function prologue.  If a
   frame_info pointer is provided, fill in its saved_regs etc.

   Returns the address of the first instruction after the prologue.  */

static CORE_ADDR
moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
			struct moxie_frame_cache *cache,
			struct gdbarch *gdbarch)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR next_addr;
  ULONGEST inst, inst2;
  LONGEST offset;
  int regnum;

  /* Record where the jsra instruction saves the PC and FP.  */
  cache->saved_regs[MOXIE_PC_REGNUM] = -4;
  cache->saved_regs[MOXIE_FP_REGNUM] = 0;
  cache->framesize = 0;

  if (start_addr >= end_addr)
    return end_addr;

  for (next_addr = start_addr; next_addr < end_addr; )
    {
      inst = read_memory_unsigned_integer (next_addr, 2, byte_order);

      /* Match "push $sp $rN" where N is between 0 and 13 inclusive.  */
      if (inst >= 0x0612 && inst <= 0x061f)
	{
	  regnum = inst & 0x000f;
	  cache->framesize += 4;
	  cache->saved_regs[regnum] = cache->framesize;
	  next_addr += 2;
	}
      else
	break;
    }

  inst = read_memory_unsigned_integer (next_addr, 2, byte_order);

  /* Optional stack allocation for args and local vars <= 4
     byte.  */
  if (inst == 0x01e0)          /* ldi.l $r12, X */
    {
      offset = read_memory_integer (next_addr + 2, 4, byte_order);
      inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order);
      
      if (inst2 == 0x291e)     /* sub.l $sp, $r12 */
	{
	  cache->framesize += offset;
	}
      
      return (next_addr + 8);
    }
  else if ((inst & 0xff00) == 0x9100)   /* dec $sp, X */
    {
      cache->framesize += (inst & 0x00ff);
      next_addr += 2;

      while (next_addr < end_addr)
	{
	  inst = read_memory_unsigned_integer (next_addr, 2, byte_order);
	  if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */
	    break;
	  cache->framesize += (inst & 0x00ff);
	  next_addr += 2;
	}
    }

  return next_addr;
}

/* Find the end of function prologue.  */

static CORE_ADDR
moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr = 0, func_end = 0;
  const char *func_name;

  /* See if we can determine the end of the prologue via the symbol table.
     If so, then return either PC, or the PC after the prologue, whichever
     is greater.  */
  if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      if (post_prologue_pc != 0)
	return std::max (pc, post_prologue_pc);
      else
	{
	  /* Can't determine prologue from the symbol table, need to examine
	     instructions.  */
	  struct symtab_and_line sal;
	  struct symbol *sym;
	  struct moxie_frame_cache cache;
	  CORE_ADDR plg_end;
	  
	  memset (&cache, 0, sizeof cache);
	  
	  plg_end = moxie_analyze_prologue (func_addr, 
					    func_end, &cache, gdbarch);
	  /* Found a function.  */
	  sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL).symbol;
	  /* Don't use line number debug info for assembly source
	     files.  */
	  if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
	    {
	      sal = find_pc_line (func_addr, 0);
	      if (sal.end && sal.end < func_end)
		{
		  /* Found a line number, use it as end of
		     prologue.  */
		  return sal.end;
		}
	    }
	  /* No useable line symbol.  Use result of prologue parsing
	     method.  */
	  return plg_end;
	}
    }

  /* No function symbol -- just return the PC.  */
  return (CORE_ADDR) pc;
}

struct moxie_unwind_cache
{
  /* The previous frame's inner most stack address.  Used as this
     frame ID's stack_addr.  */
  CORE_ADDR prev_sp;
  /* The frame's base, optionally used by the high-level debug info.  */
  CORE_ADDR base;
  int size;
  /* How far the SP and r13 (FP) have been offset from the start of
     the stack frame (as defined by the previous frame's stack
     pointer).  */
  LONGEST sp_offset;
  LONGEST r13_offset;
  int uses_frame;
  /* Table indicating the location of each and every register.  */
  struct trad_frame_saved_reg *saved_regs;
};

/* Read an unsigned integer from the inferior, and adjust
   endianess.  */
static ULONGEST
moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
		     int length, enum bfd_endian byte_order)
{
  if (target_read_memory (addr, buf, length))
    {
      if (record_debug)
	printf_unfiltered (_("Process record: error reading memory at "
			     "addr 0x%s len = %d.\n"),
			   paddress (target_gdbarch (), addr), length);
      return -1;
    }

  return extract_unsigned_integer (buf, length, byte_order);
}


/* Helper macro to extract the signed 10-bit offset from a 16-bit
   branch instruction.	*/
#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)

/* Insert a single step breakpoint.  */

static std::vector<CORE_ADDR>
moxie_software_single_step (struct regcache *regcache)
{
  struct gdbarch *gdbarch = regcache->arch ();
  CORE_ADDR addr;
  gdb_byte buf[4];
  uint16_t inst;
  uint32_t tmpu32;
  ULONGEST fp;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  std::vector<CORE_ADDR> next_pcs;

  addr = regcache_read_pc (regcache);

  inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);

  /* Decode instruction.  */
  if (inst & (1 << 15))
    {
      if (inst & (1 << 14))
	{
	  /* This is a Form 3 instruction.  */
	  int opcode = (inst >> 10 & 0xf);

	  switch (opcode)
	    {
	    case 0x00: /* beq */
	    case 0x01: /* bne */
	    case 0x02: /* blt */
	    case 0x03: /* bgt */
	    case 0x04: /* bltu */
	    case 0x05: /* bgtu */
	    case 0x06: /* bge */
	    case 0x07: /* ble */
	    case 0x08: /* bgeu */
	    case 0x09: /* bleu */
	      /* Insert breaks on both branches, because we can't currently tell
		 which way things will go.  */
	      next_pcs.push_back (addr + 2);
	      next_pcs.push_back (addr + 2 + INST2OFFSET(inst));
	      break;
	    default:
	      {
		/* Do nothing.	*/
		break;
	      }
	    }
	}
      else
	{
	  /* This is a Form 2 instruction.  They are all 16 bits.  */
	  next_pcs.push_back (addr + 2);
	}
    }
  else
    {
      /* This is a Form 1 instruction.	*/
      int opcode = inst >> 8;

      switch (opcode)
	{
	  /* 16-bit instructions.  */
	case 0x00: /* bad */
	case 0x02: /* mov (register-to-register) */
	case 0x05: /* add.l */
	case 0x06: /* push */
	case 0x07: /* pop */
	case 0x0a: /* ld.l (register indirect) */
	case 0x0b: /* st.l */
	case 0x0e: /* cmp */
	case 0x0f: /* nop */
	case 0x10: /* sex.b */
	case 0x11: /* sex.s */
	case 0x12: /* zex.b */
	case 0x13: /* zex.s */
	case 0x14: /* umul.x */
	case 0x15: /* mul.x */
	case 0x16:
	case 0x17:
	case 0x18:
	case 0x1c: /* ld.b (register indirect) */
	case 0x1e: /* st.b */
	case 0x21: /* ld.s (register indirect) */
	case 0x23: /* st.s */
	case 0x26: /* and */
	case 0x27: /* lshr */
	case 0x28: /* ashl */
	case 0x29: /* sub.l */
	case 0x2a: /* neg */
	case 0x2b: /* or */
	case 0x2c: /* not */
	case 0x2d: /* ashr */
	case 0x2e: /* xor */
	case 0x2f: /* mul.l */
	case 0x31: /* div.l */
	case 0x32: /* udiv.l */
	case 0x33: /* mod.l */
	case 0x34: /* umod.l */
	  next_pcs.push_back (addr + 2);
	  break;

	  /* 32-bit instructions.  */
	case 0x0c: /* ldo.l */
	case 0x0d: /* sto.l */
	case 0x36: /* ldo.b */
	case 0x37: /* sto.b */
	case 0x38: /* ldo.s */
	case 0x39: /* sto.s */
	  next_pcs.push_back (addr + 4);
	  break;

	  /* 48-bit instructions.  */
	case 0x01: /* ldi.l (immediate) */
	case 0x08: /* lda.l */
	case 0x09: /* sta.l */
	case 0x1b: /* ldi.b (immediate) */
	case 0x1d: /* lda.b */
	case 0x1f: /* sta.b */
	case 0x20: /* ldi.s (immediate) */
	case 0x22: /* lda.s */
	case 0x24: /* sta.s */
	  next_pcs.push_back (addr + 6);
	  break;

	  /* Control flow instructions.	 */
	case 0x03: /* jsra */
	case 0x1a: /* jmpa */
	  next_pcs.push_back (moxie_process_readu (addr + 2, buf, 4,
						   byte_order));
	  break;

	case 0x04: /* ret */
	  regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp);
	  next_pcs.push_back (moxie_process_readu (fp + 4, buf, 4, byte_order));
	  break;

	case 0x19: /* jsr */
	case 0x25: /* jmp */
	  regcache->raw_read ((inst >> 4) & 0xf, (gdb_byte *) & tmpu32);
	  next_pcs.push_back (tmpu32);
	  break;

	case 0x30: /* swi */
	case 0x35: /* brk */
	  /* Unsupported, for now.  */
	  break;
	}
    }

  return next_pcs;
}

/* Implement the "unwind_sp" gdbarch method.  */

static CORE_ADDR
moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM);
}

/* Given a return value in `regbuf' with a type `valtype', 
   extract and copy its value into `valbuf'.  */

static void
moxie_extract_return_value (struct type *type, struct regcache *regcache,
			    gdb_byte *dst)
{
  struct gdbarch *gdbarch = regcache->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int len = TYPE_LENGTH (type);
  ULONGEST tmp;

  /* By using store_unsigned_integer we avoid having to do
     anything special for small big-endian values.  */
  regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
  store_unsigned_integer (dst, (len > 4 ? len - 4 : len), byte_order, tmp);

  /* Ignore return values more than 8 bytes in size because the moxie
     returns anything more than 8 bytes in the stack.  */
  if (len > 4)
    {
      regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
      store_unsigned_integer (dst + len - 4, 4, byte_order, tmp);
    }
}

/* Implement the "return_value" gdbarch method.  */

static enum return_value_convention
moxie_return_value (struct gdbarch *gdbarch, struct value *function,
		   struct type *valtype, struct regcache *regcache,
		   gdb_byte *readbuf, const gdb_byte *writebuf)
{
  if (TYPE_LENGTH (valtype) > 8)
    return RETURN_VALUE_STRUCT_CONVENTION;
  else
    {
      if (readbuf != NULL)
	moxie_extract_return_value (valtype, regcache, readbuf);
      if (writebuf != NULL)
	moxie_store_return_value (valtype, regcache, writebuf);
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}

/* Allocate and initialize a moxie_frame_cache object.  */

static struct moxie_frame_cache *
moxie_alloc_frame_cache (void)
{
  struct moxie_frame_cache *cache;
  int i;

  cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache);

  cache->base = 0;
  cache->saved_sp = 0;
  cache->pc = 0;
  cache->framesize = 0;
  for (i = 0; i < MOXIE_NUM_REGS; ++i)
    cache->saved_regs[i] = REG_UNAVAIL;

  return cache;
}

/* Populate a moxie_frame_cache object for this_frame.  */

static struct moxie_frame_cache *
moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct moxie_frame_cache *cache;
  CORE_ADDR current_pc;
  int i;

  if (*this_cache)
    return (struct moxie_frame_cache *) *this_cache;

  cache = moxie_alloc_frame_cache ();
  *this_cache = cache;

  cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
  if (cache->base == 0)
    return cache;

  cache->pc = get_frame_func (this_frame);
  current_pc = get_frame_pc (this_frame);
  if (cache->pc)
    {
      struct gdbarch *gdbarch = get_frame_arch (this_frame);
      moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
    }

  cache->saved_sp = cache->base - cache->framesize;

  for (i = 0; i < MOXIE_NUM_REGS; ++i)
    if (cache->saved_regs[i] != REG_UNAVAIL)
      cache->saved_regs[i] = cache->base - cache->saved_regs[i];

  return cache;
}

/* Implement the "unwind_pc" gdbarch method.  */

static CORE_ADDR
moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
}

/* Given a GDB frame, determine the address of the calling function's
   frame.  This will be used to create a new GDB frame struct.  */

static void
moxie_frame_this_id (struct frame_info *this_frame,
		    void **this_prologue_cache, struct frame_id *this_id)
{
  struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
						   this_prologue_cache);

  /* This marks the outermost frame.  */
  if (cache->base == 0)
    return;

  *this_id = frame_id_build (cache->saved_sp, cache->pc);
}

/* Get the value of register regnum in the previous stack frame.  */

static struct value *
moxie_frame_prev_register (struct frame_info *this_frame,
			  void **this_prologue_cache, int regnum)
{
  struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
						   this_prologue_cache);

  gdb_assert (regnum >= 0);

  if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
    return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);

  if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
    return frame_unwind_got_memory (this_frame, regnum,
				    cache->saved_regs[regnum]);

  return frame_unwind_got_register (this_frame, regnum, regnum);
}

static const struct frame_unwind moxie_frame_unwind = {
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  moxie_frame_this_id,
  moxie_frame_prev_register,
  NULL,
  default_frame_sniffer
};

/* Return the base address of this_frame.  */

static CORE_ADDR
moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
  struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
						       this_cache);

  return cache->base;
}

static const struct frame_base moxie_frame_base = {
  &moxie_frame_unwind,
  moxie_frame_base_address,
  moxie_frame_base_address,
  moxie_frame_base_address
};

static struct frame_id
moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM);

  return frame_id_build (sp, get_frame_pc (this_frame));
}

/* Parse the current instruction and record the values of the registers and
   memory that will be changed in current instruction to "record_arch_list".
   Return -1 if something wrong.  */

static int
moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
		      CORE_ADDR addr)
{
  gdb_byte buf[4];
  uint16_t inst;
  uint32_t tmpu32;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  if (record_debug > 1)
    fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record "
			            "addr = 0x%s\n",
			paddress (target_gdbarch (), addr));

  inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order);

  /* Decode instruction.  */
  if (inst & (1 << 15))
    {
      if (inst & (1 << 14))
	{
	  /* This is a Form 3 instruction.  */
	  int opcode = (inst >> 10 & 0xf);
	  
	  switch (opcode)
	    {
	    case 0x00: /* beq */
	    case 0x01: /* bne */
	    case 0x02: /* blt */
	    case 0x03: /* bgt */
	    case 0x04: /* bltu */
	    case 0x05: /* bgtu */
	    case 0x06: /* bge */
	    case 0x07: /* ble */
	    case 0x08: /* bgeu */
	    case 0x09: /* bleu */
	      /* Do nothing.  */
	      break;
	    default:
	      {
		/* Do nothing.  */
		break;
	      }
	    }
	}
      else
	{
	  /* This is a Form 2 instruction.  */
	  int opcode = (inst >> 12 & 0x3);
	  switch (opcode)
	    {
	    case 0x00: /* inc */
	    case 0x01: /* dec */
	    case 0x02: /* gsr */
	      {
		int reg = (inst >> 8) & 0xf;
		if (record_full_arch_list_add_reg (regcache, reg))
		  return -1;
	      }
	      break;
	    case 0x03: /* ssr */
	      {
		/* Do nothing until GDB learns about moxie's special
		   registers.  */
	      }
	      break;
	    default:
	      /* Do nothing.  */
	      break;
	    }
	}
    }
  else
    {
      /* This is a Form 1 instruction.  */
      int opcode = inst >> 8;

      switch (opcode)
	{
	case 0x00: /* nop */
	  /* Do nothing.  */
	  break;
	case 0x01: /* ldi.l (immediate) */
	case 0x02: /* mov (register-to-register) */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x03: /* jsra */
	  {
	    regcache->raw_read (
			       MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
		|| (record_full_arch_list_add_reg (regcache,
						   MOXIE_SP_REGNUM))
		|| record_full_arch_list_add_mem (tmpu32 - 12, 12))
	      return -1;
	  }
	  break;
	case 0x04: /* ret */
	  {
	    if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
		|| (record_full_arch_list_add_reg (regcache,
						   MOXIE_SP_REGNUM)))
	      return -1;
	  }
	  break;
	case 0x05: /* add.l */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x06: /* push */
	  {
	    int reg = (inst >> 4) & 0xf;
	    regcache->raw_read (reg, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    if (record_full_arch_list_add_reg (regcache, reg)
		|| record_full_arch_list_add_mem (tmpu32 - 4, 4))
	      return -1;
	  }
	  break;
	case 0x07: /* pop */
	  {
	    int a = (inst >> 4) & 0xf;
	    int b = inst & 0xf;
	    if (record_full_arch_list_add_reg (regcache, a)
		|| record_full_arch_list_add_reg (regcache, b))
	      return -1;
	  }
	  break;
	case 0x08: /* lda.l */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x09: /* sta.l */
	  {
	    tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf, 
						     4, byte_order);
	    if (record_full_arch_list_add_mem (tmpu32, 4))
	      return -1;
	  }
	  break;
	case 0x0a: /* ld.l (register indirect) */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x0b: /* st.l */
	  {
	    int reg = (inst >> 4) & 0xf;
	    regcache->raw_read (reg, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    if (record_full_arch_list_add_mem (tmpu32, 4))
	      return -1;
	  }
	  break;
	case 0x0c: /* ldo.l */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x0d: /* sto.l */
	  {
	    int reg = (inst >> 4) & 0xf;
	    uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
							       byte_order)) << 16 ) >> 16;
	    regcache->raw_read (reg, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    tmpu32 += offset;
	    if (record_full_arch_list_add_mem (tmpu32, 4))
	      return -1;
	  }
	  break;
	case 0x0e: /* cmp */
	  {
	    if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM))
	      return -1;
	  }
	  break;
	case 0x0f: /* nop */
	  {
	    /* Do nothing.  */
	    break;
	  }
	case 0x10: /* sex.b */
	case 0x11: /* sex.s */
	case 0x12: /* zex.b */
	case 0x13: /* zex.s */
	case 0x14: /* umul.x */
	case 0x15: /* mul.x */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x16:
	case 0x17:
	case 0x18:
	  {
	    /* Do nothing.  */
	    break;
	  }
	case 0x19: /* jsr */
	  {
	    regcache->raw_read (
			       MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM)
		|| (record_full_arch_list_add_reg (regcache,
						   MOXIE_SP_REGNUM))
		|| record_full_arch_list_add_mem (tmpu32 - 12, 12))
	      return -1;
	  }
	  break;
	case 0x1a: /* jmpa */
	  {
	    /* Do nothing.  */
	  }
	  break;
	case 0x1b: /* ldi.b (immediate) */
	case 0x1c: /* ld.b (register indirect) */
	case 0x1d: /* lda.b */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x1e: /* st.b */
	  {
	    int reg = (inst >> 4) & 0xf;
	    regcache->raw_read (reg, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    if (record_full_arch_list_add_mem (tmpu32, 1))
	      return -1;
	  }
	  break;
	case 0x1f: /* sta.b */
	  {
	    tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
	    if (record_full_arch_list_add_mem (tmpu32, 1))
	      return -1;
	  }
	  break;
	case 0x20: /* ldi.s (immediate) */
	case 0x21: /* ld.s (register indirect) */
	case 0x22: /* lda.s */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x23: /* st.s */
	  {
	    int reg = (inst >> 4) & 0xf;
	    regcache->raw_read (reg, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    if (record_full_arch_list_add_mem (tmpu32, 2))
	      return -1;
	  }
	  break;
	case 0x24: /* sta.s */
	  {
	    tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order);
	    if (record_full_arch_list_add_mem (tmpu32, 2))
	      return -1;
	  }
	  break;
	case 0x25: /* jmp */
	  {
	    /* Do nothing.  */
	  }
	  break;
	case 0x26: /* and */
	case 0x27: /* lshr */
	case 0x28: /* ashl */
	case 0x29: /* sub */
	case 0x2a: /* neg */
	case 0x2b: /* or */
	case 0x2c: /* not */
	case 0x2d: /* ashr */
	case 0x2e: /* xor */
	case 0x2f: /* mul */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x30: /* swi */
	  {
	    /* We currently implement support for libgloss' 
	       system calls.  */

	    int inum = moxie_process_readu (addr+2, buf, 4, byte_order);

	    switch (inum)
	      {
	      case 0x1: /* SYS_exit */
		{
		  /* Do nothing.  */
		}
		break;
	      case 0x2: /* SYS_open */
		{
		  if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
		    return -1;
		}
		break;
	      case 0x4: /* SYS_read */
		{
		  uint32_t length, ptr;

		  /* Read buffer pointer is in $r1.  */
		  regcache->raw_read (3, (gdb_byte *) & ptr);
		  ptr = extract_unsigned_integer ((gdb_byte *) & ptr, 
						  4, byte_order);

		  /* String length is at 0x12($fp).  */
		  regcache->raw_read (
				     MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32);
		  tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
						     4, byte_order);
		  length = moxie_process_readu (tmpu32+20, buf, 4, byte_order);

		  if (record_full_arch_list_add_mem (ptr, length))
		    return -1;
		}
		break;
	      case 0x5: /* SYS_write */
		{
		  if (record_full_arch_list_add_reg (regcache, RET1_REGNUM))
		    return -1;
		}
		break;
	      default:
		break;
	      }
	  }
	  break;
	case 0x31: /* div.l */
	case 0x32: /* udiv.l */
	case 0x33: /* mod.l */
	case 0x34: /* umod.l */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x35: /* brk */
	  /* Do nothing.  */
	  break;
	case 0x36: /* ldo.b */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x37: /* sto.b */
	  {
	    int reg = (inst >> 4) & 0xf;
	    uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
							       byte_order)) << 16 ) >> 16;
	    regcache->raw_read (reg, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    tmpu32 += offset;
	    if (record_full_arch_list_add_mem (tmpu32, 1))
	      return -1;
	  }
	  break;
	case 0x38: /* ldo.s */
	  {
	    int reg = (inst >> 4) & 0xf;
	    if (record_full_arch_list_add_reg (regcache, reg))
	      return -1;
	  }
	  break;
	case 0x39: /* sto.s */
	  {
	    int reg = (inst >> 4) & 0xf;
	    uint32_t offset = (((int16_t) moxie_process_readu (addr+2, buf, 2,
							       byte_order)) << 16 ) >> 16;
	    regcache->raw_read (reg, (gdb_byte *) & tmpu32);
	    tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 
					       4, byte_order);
	    tmpu32 += offset;
	    if (record_full_arch_list_add_mem (tmpu32, 2))
	      return -1;
	  }
	  break;
	default:
	  /* Do nothing.  */
	  break;
	}
    }

  if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM))
    return -1;
  if (record_full_arch_list_add_end ())
    return -1;
  return 0;
}

/* Allocate and initialize the moxie gdbarch object.  */

static struct gdbarch *
moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  struct gdbarch_tdep *tdep;

  /* If there is already a candidate, use it.  */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    return arches->gdbarch;

  /* Allocate space for the new architecture.  */
  tdep = XCNEW (struct gdbarch_tdep);
  gdbarch = gdbarch_alloc (&info, tdep);

  set_gdbarch_wchar_bit (gdbarch, 32);
  set_gdbarch_wchar_signed (gdbarch, 0);

  set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp);

  set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS);
  set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM);
  set_gdbarch_register_name (gdbarch, moxie_register_name);
  set_gdbarch_register_type (gdbarch, moxie_register_type);

  set_gdbarch_return_value (gdbarch, moxie_return_value);

  set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_breakpoint_kind_from_pc (gdbarch,
				       moxie_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
				       moxie_breakpoint::bp_from_kind);
  set_gdbarch_frame_align (gdbarch, moxie_frame_align);

  frame_base_set_default (gdbarch, &moxie_frame_base);

  /* Methods for saving / extracting a dummy frame's ID.  The ID's
     stack address must match the SP value returned by
     PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
  set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);

  set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);

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

  /* Hook in the default unwinders.  */
  frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind);

  /* Single stepping.  */
  set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);

  /* Support simple overlay manager.  */
  set_gdbarch_overlay_update (gdbarch, simple_overlay_update);

  /* Support reverse debugging.  */
  set_gdbarch_process_record (gdbarch, moxie_process_record);

  return gdbarch;
}

/* Register this machine's init routine.  */

void
_initialize_moxie_tdep (void)
{
  register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init);
}
