/* Target-dependent code for Morpho mt processor, for GDB.

   Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
   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/>.  */

/* Contributed by Michael Snyder, msnyder@redhat.com.  */

#include "defs.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "symtab.h"
#include "dis-asm.h"
#include "arch-utils.h"
#include "gdbtypes.h"
#include "gdb_string.h"
#include "regcache.h"
#include "reggroups.h"
#include "gdbcore.h"
#include "trad-frame.h"
#include "inferior.h"
#include "dwarf2-frame.h"
#include "infcall.h"
#include "gdb_assert.h"
#include "language.h"
#include "valprint.h"

enum mt_arch_constants
{
  MT_MAX_STRUCT_SIZE = 16
};

enum mt_gdb_regnums
{
  MT_R0_REGNUM,			/* 32 bit regs.  */
  MT_R1_REGNUM,
  MT_1ST_ARGREG = MT_R1_REGNUM,
  MT_R2_REGNUM,
  MT_R3_REGNUM,
  MT_R4_REGNUM,
  MT_LAST_ARGREG = MT_R4_REGNUM,
  MT_R5_REGNUM,
  MT_R6_REGNUM,
  MT_R7_REGNUM,
  MT_R8_REGNUM,
  MT_R9_REGNUM,
  MT_R10_REGNUM,
  MT_R11_REGNUM,
  MT_R12_REGNUM,
  MT_FP_REGNUM = MT_R12_REGNUM,
  MT_R13_REGNUM,
  MT_SP_REGNUM = MT_R13_REGNUM,
  MT_R14_REGNUM,
  MT_RA_REGNUM = MT_R14_REGNUM,
  MT_R15_REGNUM,
  MT_IRA_REGNUM = MT_R15_REGNUM,
  MT_PC_REGNUM,

  /* Interrupt Enable pseudo-register, exported by SID.  */
  MT_INT_ENABLE_REGNUM,
  /* End of CPU regs.  */

  MT_NUM_CPU_REGS,

  /* Co-processor registers.  */
  MT_COPRO_REGNUM = MT_NUM_CPU_REGS,	/* 16 bit regs.  */
  MT_CPR0_REGNUM,
  MT_CPR1_REGNUM,
  MT_CPR2_REGNUM,
  MT_CPR3_REGNUM,
  MT_CPR4_REGNUM,
  MT_CPR5_REGNUM,
  MT_CPR6_REGNUM,
  MT_CPR7_REGNUM,
  MT_CPR8_REGNUM,
  MT_CPR9_REGNUM,
  MT_CPR10_REGNUM,
  MT_CPR11_REGNUM,
  MT_CPR12_REGNUM,
  MT_CPR13_REGNUM,
  MT_CPR14_REGNUM,
  MT_CPR15_REGNUM,
  MT_BYPA_REGNUM,		/* 32 bit regs.  */
  MT_BYPB_REGNUM,
  MT_BYPC_REGNUM,
  MT_FLAG_REGNUM,
  MT_CONTEXT_REGNUM,		/* 38 bits (treat as array of
				   six bytes).  */
  MT_MAC_REGNUM,			/* 32 bits.  */
  MT_Z1_REGNUM,			/* 16 bits.  */
  MT_Z2_REGNUM,			/* 16 bits.  */
  MT_ICHANNEL_REGNUM,		/* 32 bits.  */
  MT_ISCRAMB_REGNUM,		/* 32 bits.  */
  MT_QSCRAMB_REGNUM,		/* 32 bits.  */
  MT_OUT_REGNUM,			/* 16 bits.  */
  MT_EXMAC_REGNUM,		/* 32 bits (8 used).  */
  MT_QCHANNEL_REGNUM,		/* 32 bits.  */
  MT_ZI2_REGNUM,                /* 16 bits.  */
  MT_ZQ2_REGNUM,                /* 16 bits.  */
  MT_CHANNEL2_REGNUM,           /* 32 bits.  */
  MT_ISCRAMB2_REGNUM,           /* 32 bits.  */
  MT_QSCRAMB2_REGNUM,           /* 32 bits.  */
  MT_QCHANNEL2_REGNUM,          /* 32 bits.  */

  /* Number of real registers.  */
  MT_NUM_REGS,

  /* Pseudo-registers.  */
  MT_COPRO_PSEUDOREG_REGNUM = MT_NUM_REGS,
  MT_MAC_PSEUDOREG_REGNUM,
  MT_COPRO_PSEUDOREG_ARRAY,

  MT_COPRO_PSEUDOREG_DIM_1 = 2,
  MT_COPRO_PSEUDOREG_DIM_2 = 8,
  /* The number of pseudo-registers for each coprocessor.  These
     include the real coprocessor registers, the pseudo-registe for
     the coprocessor number, and the pseudo-register for the MAC.  */
  MT_COPRO_PSEUDOREG_REGS = MT_NUM_REGS - MT_NUM_CPU_REGS + 2,
  /* The register number of the MAC, relative to a given coprocessor.  */
  MT_COPRO_PSEUDOREG_MAC_REGNUM = MT_COPRO_PSEUDOREG_REGS - 1,

  /* Two pseudo-regs ('coprocessor' and 'mac').  */
  MT_NUM_PSEUDO_REGS = 2 + (MT_COPRO_PSEUDOREG_REGS
			    * MT_COPRO_PSEUDOREG_DIM_1
			    * MT_COPRO_PSEUDOREG_DIM_2)
};

/* The tdep structure.  */
struct gdbarch_tdep
{
  /* ISA-specific types.  */
  struct type *copro_type;
};


/* Return name of register number specified by REGNUM.  */

static const char *
mt_register_name (struct gdbarch *gdbarch, int regnum)
{
  static const char *const register_names[] = {
    /* CPU regs.  */
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
    "pc", "IE",
    /* Co-processor regs.  */
    "",				/* copro register.  */
    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
    "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15",
    "bypa", "bypb", "bypc", "flag", "context", "" /* mac.  */ , "z1", "z2",
    "Ichannel", "Iscramb", "Qscramb", "out", "" /* ex-mac.  */ , "Qchannel",
    "zi2", "zq2", "Ichannel2", "Iscramb2", "Qscramb2", "Qchannel2",
    /* Pseudo-registers.  */
    "coprocessor", "MAC"
  };
  static const char *array_names[MT_COPRO_PSEUDOREG_REGS
				 * MT_COPRO_PSEUDOREG_DIM_1
				 * MT_COPRO_PSEUDOREG_DIM_2];

  if (regnum < 0)
    return "";
  if (regnum < ARRAY_SIZE (register_names))
    return register_names[regnum];
  if (array_names[regnum - MT_COPRO_PSEUDOREG_ARRAY])
    return array_names[regnum - MT_COPRO_PSEUDOREG_ARRAY];
  
  {
    char *name;
    const char *stub;
    unsigned dim_1;
    unsigned dim_2;
    unsigned index;
    
    regnum -= MT_COPRO_PSEUDOREG_ARRAY;
    index = regnum % MT_COPRO_PSEUDOREG_REGS;
    dim_2 = (regnum / MT_COPRO_PSEUDOREG_REGS) % MT_COPRO_PSEUDOREG_DIM_2;
    dim_1 = ((regnum / MT_COPRO_PSEUDOREG_REGS / MT_COPRO_PSEUDOREG_DIM_2)
	     %  MT_COPRO_PSEUDOREG_DIM_1);
    
    if (index == MT_COPRO_PSEUDOREG_MAC_REGNUM)
      stub = register_names[MT_MAC_PSEUDOREG_REGNUM];
    else if (index >= MT_NUM_REGS - MT_CPR0_REGNUM)
      stub = "";
    else
      stub = register_names[index + MT_CPR0_REGNUM];
    if (!*stub)
      {
	array_names[regnum] = stub;
	return stub;
      }
    name = xmalloc (30);
    sprintf (name, "copro_%d_%d_%s", dim_1, dim_2, stub);
    array_names[regnum] = name;
    return name;
  }
}

/* Return the type of a coprocessor register.  */

static struct type *
mt_copro_register_type (struct gdbarch *arch, int regnum)
{
  switch (regnum)
    {
    case MT_INT_ENABLE_REGNUM:
    case MT_ICHANNEL_REGNUM:
    case MT_QCHANNEL_REGNUM:
    case MT_ISCRAMB_REGNUM:
    case MT_QSCRAMB_REGNUM:
      return builtin_type (arch)->builtin_int32;
    case MT_BYPA_REGNUM:
    case MT_BYPB_REGNUM:
    case MT_BYPC_REGNUM:
    case MT_Z1_REGNUM:
    case MT_Z2_REGNUM:
    case MT_OUT_REGNUM:
    case MT_ZI2_REGNUM:
    case MT_ZQ2_REGNUM:
      return builtin_type (arch)->builtin_int16;
    case MT_EXMAC_REGNUM:
    case MT_MAC_REGNUM:
      return builtin_type (arch)->builtin_uint32;
    case MT_CONTEXT_REGNUM:
      return builtin_type (arch)->builtin_long_long;
    case MT_FLAG_REGNUM:
      return builtin_type (arch)->builtin_unsigned_char;
    default:
      if (regnum >= MT_CPR0_REGNUM && regnum <= MT_CPR15_REGNUM)
	return builtin_type (arch)->builtin_int16;
      else if (regnum == MT_CPR0_REGNUM + MT_COPRO_PSEUDOREG_MAC_REGNUM)
	{
	  if (gdbarch_bfd_arch_info (arch)->mach == bfd_mach_mrisc2
	      || gdbarch_bfd_arch_info (arch)->mach == bfd_mach_ms2)
	    return builtin_type (arch)->builtin_uint64;
	  else
	    return builtin_type (arch)->builtin_uint32;
	}
      else
	return builtin_type (arch)->builtin_uint32;
    }
}

/* Given ARCH and a register number specified by REGNUM, return the
   type of that register.  */

static struct type *
mt_register_type (struct gdbarch *arch, int regnum)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (arch);

  if (regnum >= 0 && regnum < MT_NUM_REGS + MT_NUM_PSEUDO_REGS)
    {
      switch (regnum)
	{
	case MT_PC_REGNUM:
	case MT_RA_REGNUM:
	case MT_IRA_REGNUM:
	  return builtin_type (arch)->builtin_func_ptr;
	case MT_SP_REGNUM:
	case MT_FP_REGNUM:
	  return builtin_type (arch)->builtin_data_ptr;
	case MT_COPRO_REGNUM:
	case MT_COPRO_PSEUDOREG_REGNUM:
	  if (tdep->copro_type == NULL)
	    {
	      struct type *elt = builtin_type (arch)->builtin_int16;
	      tdep->copro_type = lookup_array_range_type (elt, 0, 1);
	    }
	  return tdep->copro_type;
	case MT_MAC_PSEUDOREG_REGNUM:
	  return mt_copro_register_type (arch,
					 MT_CPR0_REGNUM
					 + MT_COPRO_PSEUDOREG_MAC_REGNUM);
	default:
	  if (regnum >= MT_R0_REGNUM && regnum <= MT_R15_REGNUM)
	    return builtin_type (arch)->builtin_int32;
	  else if (regnum < MT_COPRO_PSEUDOREG_ARRAY)
	    return mt_copro_register_type (arch, regnum);
	  else
	    {
	      regnum -= MT_COPRO_PSEUDOREG_ARRAY;
	      regnum %= MT_COPRO_PSEUDOREG_REGS;
	      regnum += MT_CPR0_REGNUM;
	      return mt_copro_register_type (arch, regnum);
	    }
	}
    }
  internal_error (__FILE__, __LINE__,
		  _("mt_register_type: illegal register number %d"), regnum);
}

/* Return true if register REGNUM is a member of the register group
   specified by GROUP.  */

static int
mt_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			 struct reggroup *group)
{
  /* Groups of registers that can be displayed via "info reg".  */
  if (group == all_reggroup)
    return (regnum >= 0
	    && regnum < MT_NUM_REGS + MT_NUM_PSEUDO_REGS
	    && mt_register_name (gdbarch, regnum)[0] != '\0');

  if (group == general_reggroup)
    return (regnum >= MT_R0_REGNUM && regnum <= MT_R15_REGNUM);

  if (group == float_reggroup)
    return 0;			/* No float regs.  */

  if (group == vector_reggroup)
    return 0;			/* No vector regs.  */

  /* For any that are not handled above.  */
  return default_register_reggroup_p (gdbarch, regnum, group);
}

/* Return the return value convention used for a given type TYPE.
   Optionally, fetch or set the return value via READBUF or
   WRITEBUF respectively using REGCACHE for the register
   values.  */

static enum return_value_convention
mt_return_value (struct gdbarch *gdbarch, struct type *func_type,
		 struct type *type, struct regcache *regcache,
		 gdb_byte *readbuf, const gdb_byte *writebuf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  if (TYPE_LENGTH (type) > 4)
    {
      /* Return values > 4 bytes are returned in memory, 
         pointed to by R11.  */
      if (readbuf)
	{
	  ULONGEST addr;

	  regcache_cooked_read_unsigned (regcache, MT_R11_REGNUM, &addr);
	  read_memory (addr, readbuf, TYPE_LENGTH (type));
	}

      if (writebuf)
	{
	  ULONGEST addr;

	  regcache_cooked_read_unsigned (regcache, MT_R11_REGNUM, &addr);
	  write_memory (addr, writebuf, TYPE_LENGTH (type));
	}

      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
    }
  else
    {
      if (readbuf)
	{
	  ULONGEST temp;

	  /* Return values of <= 4 bytes are returned in R11.  */
	  regcache_cooked_read_unsigned (regcache, MT_R11_REGNUM, &temp);
	  store_unsigned_integer (readbuf, TYPE_LENGTH (type),
				  byte_order, temp);
	}

      if (writebuf)
	{
	  if (TYPE_LENGTH (type) < 4)
	    {
	      gdb_byte buf[4];
	      /* Add leading zeros to the value.  */
	      memset (buf, 0, sizeof (buf));
	      memcpy (buf + sizeof (buf) - TYPE_LENGTH (type),
		      writebuf, TYPE_LENGTH (type));
	      regcache_cooked_write (regcache, MT_R11_REGNUM, buf);
	    }
	  else			/* (TYPE_LENGTH (type) == 4 */
	    regcache_cooked_write (regcache, MT_R11_REGNUM, writebuf);
	}

      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}

/* If the input address, PC, is in a function prologue, return the
   address of the end of the prologue, otherwise return the input
   address.

   Note:  PC is likely to be the function start, since this function
   is mainly used for advancing a breakpoint to the first line, or
   stepping to the first line when we have stepped into a function
   call.  */

static CORE_ADDR
mt_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR func_addr = 0, func_end = 0;
  char *func_name;
  unsigned long instr;

  if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
    {
      struct symtab_and_line sal;
      struct symbol *sym;

      /* Found a function.  */
      sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
      if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
	{
	  /* Don't use this trick for assembly source files.  */
	  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 function symbol, or no line symbol.  Use prologue scanning method.  */
  for (;; pc += 4)
    {
      instr = read_memory_unsigned_integer (pc, 4, byte_order);
      if (instr == 0x12000000)	/* nop */
	continue;
      if (instr == 0x12ddc000)	/* copy sp into fp */
	continue;
      instr >>= 16;
      if (instr == 0x05dd)	/* subi sp, sp, imm */
	continue;
      if (instr >= 0x43c0 && instr <= 0x43df)	/* push */
	continue;
      /* Not an obvious prologue instruction.  */
      break;
    }

  return pc;
}

/* The breakpoint instruction must be the same size as the smallest
   instruction in the instruction set.

   The BP for ms1 is defined as 0x68000000 (BREAK).
   The BP for ms2 is defined as 0x69000000 (illegal).  */

static const gdb_byte *
mt_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
		       int *bp_size)
{
  static gdb_byte ms1_breakpoint[] = { 0x68, 0, 0, 0 };
  static gdb_byte ms2_breakpoint[] = { 0x69, 0, 0, 0 };

  *bp_size = 4;
  if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
    return ms2_breakpoint;
  
  return ms1_breakpoint;
}

/* Select the correct coprocessor register bank.  Return the pseudo
   regnum we really want to read.  */

static int
mt_select_coprocessor (struct gdbarch *gdbarch,
			struct regcache *regcache, int regno)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned index, base;
  gdb_byte copro[4];

  /* Get the copro pseudo regnum.  */
  regcache_raw_read (regcache, MT_COPRO_REGNUM, copro);
  base = ((extract_signed_integer (&copro[0], 2, byte_order)
	   * MT_COPRO_PSEUDOREG_DIM_2)
	  + extract_signed_integer (&copro[2], 2, byte_order));

  regno -= MT_COPRO_PSEUDOREG_ARRAY;
  index = regno % MT_COPRO_PSEUDOREG_REGS;
  regno /= MT_COPRO_PSEUDOREG_REGS;
  if (base != regno)
    {
      /* Select the correct coprocessor register bank.  Invalidate the
	 coprocessor register cache.  */
      unsigned ix;

      store_signed_integer (&copro[0], 2, byte_order,
			    regno / MT_COPRO_PSEUDOREG_DIM_2);
      store_signed_integer (&copro[2], 2, byte_order,
			    regno % MT_COPRO_PSEUDOREG_DIM_2);
      regcache_raw_write (regcache, MT_COPRO_REGNUM, copro);
      
      /* We must flush the cache, as it is now invalid.  */
      for (ix = MT_NUM_CPU_REGS; ix != MT_NUM_REGS; ix++)
	regcache_invalidate (regcache, ix);
    }
  
  return index;
}

/* Fetch the pseudo registers:

   There are two regular pseudo-registers:
   1) The 'coprocessor' pseudo-register (which mirrors the 
   "real" coprocessor register sent by the target), and
   2) The 'MAC' pseudo-register (which represents the union
   of the original 32 bit target MAC register and the new
   8-bit extended-MAC register).

   Additionally there is an array of coprocessor registers which track
   the coprocessor registers for each coprocessor.  */

static void
mt_pseudo_register_read (struct gdbarch *gdbarch,
			  struct regcache *regcache, int regno, gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  switch (regno)
    {
    case MT_COPRO_REGNUM:
    case MT_COPRO_PSEUDOREG_REGNUM:
      regcache_raw_read (regcache, MT_COPRO_REGNUM, buf);
      break;
    case MT_MAC_REGNUM:
    case MT_MAC_PSEUDOREG_REGNUM:
      if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
	  || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
	{
	  ULONGEST oldmac = 0, ext_mac = 0;
	  ULONGEST newmac;

	  regcache_cooked_read_unsigned (regcache, MT_MAC_REGNUM, &oldmac);
	  regcache_cooked_read_unsigned (regcache, MT_EXMAC_REGNUM, &ext_mac);
	  newmac =
	    (oldmac & 0xffffffff) | ((long long) (ext_mac & 0xff) << 32);
	  store_signed_integer (buf, 8, byte_order, newmac);
	}
      else
	regcache_raw_read (regcache, MT_MAC_REGNUM, buf);
      break;
    default:
      {
	unsigned index = mt_select_coprocessor (gdbarch, regcache, regno);
	
	if (index == MT_COPRO_PSEUDOREG_MAC_REGNUM)
	  mt_pseudo_register_read (gdbarch, regcache,
				   MT_MAC_PSEUDOREG_REGNUM, buf);
	else if (index < MT_NUM_REGS - MT_CPR0_REGNUM)
	  regcache_raw_read (regcache, index + MT_CPR0_REGNUM, buf);
      }
      break;
    }
}

/* Write the pseudo registers:

   Mt pseudo-registers are stored directly to the target.  The
   'coprocessor' register is special, because when it is modified, all
   the other coprocessor regs must be flushed from the reg cache.  */

static void
mt_pseudo_register_write (struct gdbarch *gdbarch,
			   struct regcache *regcache,
			   int regno, const gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int i;

  switch (regno)
    {
    case MT_COPRO_REGNUM:
    case MT_COPRO_PSEUDOREG_REGNUM:
      regcache_raw_write (regcache, MT_COPRO_REGNUM, buf);
      for (i = MT_NUM_CPU_REGS; i < MT_NUM_REGS; i++)
	regcache_invalidate (regcache, i);
      break;
    case MT_MAC_REGNUM:
    case MT_MAC_PSEUDOREG_REGNUM:
      if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
	  || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
	{
	  /* The 8-byte MAC pseudo-register must be broken down into two
	     32-byte registers.  */
	  unsigned int oldmac, ext_mac;
	  ULONGEST newmac;

	  newmac = extract_unsigned_integer (buf, 8, byte_order);
	  oldmac = newmac & 0xffffffff;
	  ext_mac = (newmac >> 32) & 0xff;
	  regcache_cooked_write_unsigned (regcache, MT_MAC_REGNUM, oldmac);
	  regcache_cooked_write_unsigned (regcache, MT_EXMAC_REGNUM, ext_mac);
	}
      else
	regcache_raw_write (regcache, MT_MAC_REGNUM, buf);
      break;
    default:
      {
	unsigned index = mt_select_coprocessor (gdbarch, regcache, regno);
	
	if (index == MT_COPRO_PSEUDOREG_MAC_REGNUM)
	  mt_pseudo_register_write (gdbarch, regcache,
				    MT_MAC_PSEUDOREG_REGNUM, buf);
	else if (index < MT_NUM_REGS - MT_CPR0_REGNUM)
	  regcache_raw_write (regcache, index + MT_CPR0_REGNUM, buf);
      }
      break;
    }
}

static CORE_ADDR
mt_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  /* Register size is 4 bytes.  */
  return align_down (sp, 4);
}

/* Implements the "info registers" command.   When ``all'' is non-zero,
   the coprocessor registers will be printed in addition to the rest
   of the registers.  */

static void
mt_registers_info (struct gdbarch *gdbarch,
		   struct ui_file *file,
		   struct frame_info *frame, int regnum, int all)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  if (regnum == -1)
    {
      int lim;

      lim = all ? MT_NUM_REGS : MT_NUM_CPU_REGS;

      for (regnum = 0; regnum < lim; regnum++)
	{
	  /* Don't display the Qchannel register since it will be displayed
	     along with Ichannel.  (See below.)  */
	  if (regnum == MT_QCHANNEL_REGNUM)
	    continue;

	  mt_registers_info (gdbarch, file, frame, regnum, all);

	  /* Display the Qchannel register immediately after Ichannel.  */
	  if (regnum == MT_ICHANNEL_REGNUM)
	    mt_registers_info (gdbarch, file, frame, MT_QCHANNEL_REGNUM, all);
	}
    }
  else
    {
      if (regnum == MT_EXMAC_REGNUM)
	return;
      else if (regnum == MT_CONTEXT_REGNUM)
	{
	  /* Special output handling for 38-bit context register.  */
	  unsigned char *buff;
	  unsigned int *bytes, i, regsize;

	  regsize = register_size (gdbarch, regnum);

	  buff = alloca (regsize);
	  bytes = alloca (regsize * sizeof (*bytes));

	  frame_register_read (frame, regnum, buff);

	  fputs_filtered (gdbarch_register_name
			  (gdbarch, regnum), file);
	  print_spaces_filtered (15 - strlen (gdbarch_register_name
					        (gdbarch, regnum)),
				 file);
	  fputs_filtered ("0x", file);

	  for (i = 0; i < regsize; i++)
	    fprintf_filtered (file, "%02x", (unsigned int)
			      extract_unsigned_integer (buff + i, 1, byte_order));
	  fputs_filtered ("\t", file);
	  print_longest (file, 'd', 0,
			 extract_unsigned_integer (buff, regsize, byte_order));
	  fputs_filtered ("\n", file);
	}
      else if (regnum == MT_COPRO_REGNUM
               || regnum == MT_COPRO_PSEUDOREG_REGNUM)
	{
	  /* Special output handling for the 'coprocessor' register.  */
	  gdb_byte *buf;
	  struct value_print_options opts;

	  buf = alloca (register_size (gdbarch, MT_COPRO_REGNUM));
	  frame_register_read (frame, MT_COPRO_REGNUM, buf);
	  /* And print.  */
	  regnum = MT_COPRO_PSEUDOREG_REGNUM;
	  fputs_filtered (gdbarch_register_name (gdbarch, regnum),
			  file);
	  print_spaces_filtered (15 - strlen (gdbarch_register_name
					        (gdbarch, regnum)),
				 file);
	  get_raw_print_options (&opts);
	  opts.deref_ref = 1;
	  val_print (register_type (gdbarch, regnum), buf,
		     0, 0, file, 0, NULL,
		     &opts, current_language);
	  fputs_filtered ("\n", file);
	}
      else if (regnum == MT_MAC_REGNUM || regnum == MT_MAC_PSEUDOREG_REGNUM)
	{
	  ULONGEST oldmac, ext_mac, newmac;
	  gdb_byte buf[3 * sizeof (LONGEST)];

	  /* Get the two "real" mac registers.  */
	  frame_register_read (frame, MT_MAC_REGNUM, buf);
	  oldmac = extract_unsigned_integer
	    (buf, register_size (gdbarch, MT_MAC_REGNUM), byte_order);
	  if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_mrisc2
	      || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_ms2)
	    {
	      frame_register_read (frame, MT_EXMAC_REGNUM, buf);
	      ext_mac = extract_unsigned_integer
		(buf, register_size (gdbarch, MT_EXMAC_REGNUM), byte_order);
	    }
	  else
	    ext_mac = 0;

	  /* Add them together.  */
	  newmac = (oldmac & 0xffffffff) + ((ext_mac & 0xff) << 32);

	  /* And print.  */
	  regnum = MT_MAC_PSEUDOREG_REGNUM;
	  fputs_filtered (gdbarch_register_name (gdbarch, regnum),
			  file);
	  print_spaces_filtered (15 - strlen (gdbarch_register_name
					      (gdbarch, regnum)),
				 file);
	  fputs_filtered ("0x", file);
	  print_longest (file, 'x', 0, newmac);
	  fputs_filtered ("\t", file);
	  print_longest (file, 'u', 0, newmac);
	  fputs_filtered ("\n", file);
	}
      else
	default_print_registers_info (gdbarch, file, frame, regnum, all);
    }
}

/* Set up the callee's arguments for an inferior function call.  The
   arguments are pushed on the stack or are placed in registers as
   appropriate.  It also sets up the return address (which points to
   the call dummy breakpoint).

   Returns the updated (and aligned) stack pointer.  */

static CORE_ADDR
mt_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)
{
#define wordsize 4
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[MT_MAX_STRUCT_SIZE];
  int argreg = MT_1ST_ARGREG;
  int split_param_len = 0;
  int stack_dest = sp;
  int slacklen;
  int typelen;
  int i, j;

  /* First handle however many args we can fit into MT_1ST_ARGREG thru
     MT_LAST_ARGREG.  */
  for (i = 0; i < nargs && argreg <= MT_LAST_ARGREG; i++)
    {
      const gdb_byte *val;
      typelen = TYPE_LENGTH (value_type (args[i]));
      switch (typelen)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	  regcache_cooked_write_unsigned (regcache, argreg++,
					  extract_unsigned_integer
					  (value_contents (args[i]),
					   wordsize, byte_order));
	  break;
	case 8:
	case 12:
	case 16:
	  val = value_contents (args[i]);
	  while (typelen > 0)
	    {
	      if (argreg <= MT_LAST_ARGREG)
		{
		  /* This word of the argument is passed in a register.  */
		  regcache_cooked_write_unsigned (regcache, argreg++,
						  extract_unsigned_integer
						  (val, wordsize, byte_order));
		  typelen -= wordsize;
		  val += wordsize;
		}
	      else
		{
		  /* Remainder of this arg must be passed on the stack
		     (deferred to do later).  */
		  split_param_len = typelen;
		  memcpy (buf, val, typelen);
		  break;	/* No more args can be handled in regs.  */
		}
	    }
	  break;
	default:
	  /* By reverse engineering of gcc output, args bigger than
	     16 bytes go on the stack, and their address is passed
	     in the argreg.  */
	  stack_dest -= typelen;
	  write_memory (stack_dest, value_contents (args[i]), typelen);
	  regcache_cooked_write_unsigned (regcache, argreg++, stack_dest);
	  break;
	}
    }

  /* Next, the rest of the arguments go onto the stack, in reverse order.  */
  for (j = nargs - 1; j >= i; j--)
    {
      gdb_byte *val;
      
      /* Right-justify the value in an aligned-length buffer.  */
      typelen = TYPE_LENGTH (value_type (args[j]));
      slacklen = (wordsize - (typelen % wordsize)) % wordsize;
      val = alloca (typelen + slacklen);
      memcpy (val, value_contents (args[j]), typelen);
      memset (val + typelen, 0, slacklen);
      /* Now write this data to the stack.  */
      stack_dest -= typelen + slacklen;
      write_memory (stack_dest, val, typelen + slacklen);
    }

  /* Finally, if a param needs to be split between registers and stack, 
     write the second half to the stack now.  */
  if (split_param_len != 0)
    {
      stack_dest -= split_param_len;
      write_memory (stack_dest, buf, split_param_len);
    }

  /* Set up return address (provided to us as bp_addr).  */
  regcache_cooked_write_unsigned (regcache, MT_RA_REGNUM, bp_addr);

  /* Store struct return address, if given.  */
  if (struct_return && struct_addr != 0)
    regcache_cooked_write_unsigned (regcache, MT_R11_REGNUM, struct_addr);

  /* Set aside 16 bytes for the callee to save regs 1-4.  */
  stack_dest -= 16;

  /* Update the stack pointer.  */
  regcache_cooked_write_unsigned (regcache, MT_SP_REGNUM, stack_dest);

  /* And that should do it.  Return the new stack pointer.  */
  return stack_dest;
}


/* The 'unwind_cache' data structure.  */

struct mt_unwind_cache
{
  /* The previous frame's inner most stack address.
     Used as this frame ID's stack_addr.  */
  CORE_ADDR prev_sp;
  CORE_ADDR frame_base;
  int framesize;
  int frameless_p;

  /* Table indicating the location of each and every register.  */
  struct trad_frame_saved_reg *saved_regs;
};

/* Initialize an unwind_cache.  Build up the saved_regs table etc. for
   the frame.  */

static struct mt_unwind_cache *
mt_frame_unwind_cache (struct frame_info *this_frame,
			void **this_prologue_cache)
{
  struct gdbarch *gdbarch;
  struct mt_unwind_cache *info;
  CORE_ADDR next_addr, start_addr, end_addr, prologue_end_addr;
  unsigned long instr, upper_half, delayed_store = 0;
  int regnum, offset;
  ULONGEST sp, fp;

  if ((*this_prologue_cache))
    return (*this_prologue_cache);

  gdbarch = get_frame_arch (this_frame);
  info = FRAME_OBSTACK_ZALLOC (struct mt_unwind_cache);
  (*this_prologue_cache) = info;

  info->prev_sp = 0;
  info->framesize = 0;
  info->frame_base = 0;
  info->frameless_p = 1;
  info->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  /* Grab the frame-relative values of SP and FP, needed below.
     The frame_saved_register function will find them on the
     stack or in the registers as appropriate.  */
  sp = get_frame_register_unsigned (this_frame, MT_SP_REGNUM);
  fp = get_frame_register_unsigned (this_frame, MT_FP_REGNUM);

  start_addr = get_frame_func (this_frame);

  /* Return early if GDB couldn't find the function.  */
  if (start_addr == 0)
    return info;

  end_addr = get_frame_pc (this_frame);
  prologue_end_addr = skip_prologue_using_sal (gdbarch, start_addr);
  if (end_addr == 0)
  for (next_addr = start_addr; next_addr < end_addr; next_addr += 4)
    {
      instr = get_frame_memory_unsigned (this_frame, next_addr, 4);
      if (delayed_store)	/* Previous instr was a push.  */
	{
	  upper_half = delayed_store >> 16;
	  regnum = upper_half & 0xf;
	  offset = delayed_store & 0xffff;
	  switch (upper_half & 0xfff0)
	    {
	    case 0x43c0:	/* push using frame pointer.  */
	      info->saved_regs[regnum].addr = offset;
	      break;
	    case 0x43d0:	/* push using stack pointer.  */
	      info->saved_regs[regnum].addr = offset;
	      break;
	    default:		/* lint */
	      break;
	    }
	  delayed_store = 0;
	}

      switch (instr)
	{
	case 0x12000000:	/* NO-OP */
	  continue;
	case 0x12ddc000:	/* copy sp into fp */
	  info->frameless_p = 0;	/* Record that the frame
					   pointer is in use.  */
	  continue;
	default:
	  upper_half = instr >> 16;
	  if (upper_half == 0x05dd ||	/* subi  sp, sp, imm */
	      upper_half == 0x07dd)	/* subui sp, sp, imm */
	    {
	      /* Record the frame size.  */
	      info->framesize = instr & 0xffff;
	      continue;
	    }
	  if ((upper_half & 0xfff0) == 0x43c0 ||	/* frame push */
	      (upper_half & 0xfff0) == 0x43d0)	/* stack push */
	    {
	      /* Save this instruction, but don't record the 
	         pushed register as 'saved' until we see the
	         next instruction.  That's because of deferred stores
	         on this target -- GDB won't be able to read the register
	         from the stack until one instruction later.  */
	      delayed_store = instr;
	      continue;
	    }
	  /* Not a prologue instruction.  Is this the end of the prologue?
	     This is the most difficult decision; when to stop scanning. 

	     If we have no line symbol, then the best thing we can do
	     is to stop scanning when we encounter an instruction that
	     is not likely to be a part of the prologue. 

	     But if we do have a line symbol, then we should 
	     keep scanning until we reach it (or we reach end_addr).  */

	  if (prologue_end_addr && (prologue_end_addr > (next_addr + 4)))
	    continue;	/* Keep scanning, recording saved_regs etc.  */
	  else
	    break;	/* Quit scanning: breakpoint can be set here.  */
	}
    }

  /* Special handling for the "saved" address of the SP:
     The SP is of course never saved on the stack at all, so
     by convention what we put here is simply the previous 
     _value_ of the SP (as opposed to an address where the
     previous value would have been pushed).  This will also
     give us the frame base address.  */

  if (info->frameless_p)
    {
      info->frame_base = sp + info->framesize;
      info->prev_sp = sp + info->framesize;
    }
  else
    {
      info->frame_base = fp + info->framesize;
      info->prev_sp = fp + info->framesize;
    }
  /* Save prev_sp in saved_regs as a value, not as an address.  */
  trad_frame_set_value (info->saved_regs, MT_SP_REGNUM, info->prev_sp);

  /* Now convert frame offsets to actual addresses (not offsets).  */
  for (regnum = 0; regnum < MT_NUM_REGS; regnum++)
    if (trad_frame_addr_p (info->saved_regs, regnum))
      info->saved_regs[regnum].addr += info->frame_base - info->framesize;

  /* The call instruction moves the caller's PC in the callee's RA reg.
     Since this is an unwind, do the reverse.  Copy the location of RA
     into PC (the address / regnum) so that a request for PC will be
     converted into a request for the RA.  */
  info->saved_regs[MT_PC_REGNUM] = info->saved_regs[MT_RA_REGNUM];

  return info;
}

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

  pc = frame_unwind_register_unsigned (next_frame, MT_PC_REGNUM);
  return pc;
}

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

  sp = frame_unwind_register_unsigned (next_frame, MT_SP_REGNUM);
  return sp;
}

/* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy
   frame.  The frame ID's base needs to match the TOS value saved by
   save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint.  */

static struct frame_id
mt_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, MT_SP_REGNUM);
  return frame_id_build (sp, get_frame_pc (this_frame));
}

/* 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
mt_frame_this_id (struct frame_info *this_frame,
		   void **this_prologue_cache, struct frame_id *this_id)
{
  struct mt_unwind_cache *info =
    mt_frame_unwind_cache (this_frame, this_prologue_cache);

  if (!(info == NULL || info->prev_sp == 0))
    (*this_id) = frame_id_build (info->prev_sp, get_frame_func (this_frame));

  return;
}

static struct value *
mt_frame_prev_register (struct frame_info *this_frame,
			 void **this_prologue_cache, int regnum)
{
  struct mt_unwind_cache *info =
    mt_frame_unwind_cache (this_frame, this_prologue_cache);

  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}

static CORE_ADDR
mt_frame_base_address (struct frame_info *this_frame,
			void **this_prologue_cache)
{
  struct mt_unwind_cache *info =
    mt_frame_unwind_cache (this_frame, this_prologue_cache);

  return info->frame_base;
}

/* This is a shared interface:  the 'frame_unwind' object is what's
   returned by the 'sniffer' function, and in turn specifies how to
   get a frame's ID and prev_regs.

   This exports the 'prev_register' and 'this_id' methods.  */

static const struct frame_unwind mt_frame_unwind = {
  NORMAL_FRAME,
  mt_frame_this_id,
  mt_frame_prev_register,
  NULL,
  default_frame_sniffer
};

/* Another shared interface:  the 'frame_base' object specifies how to
   unwind a frame and secure the base addresses for frame objects
   (locals, args).  */

static struct frame_base mt_frame_base = {
  &mt_frame_unwind,
  mt_frame_base_address,
  mt_frame_base_address,
  mt_frame_base_address
};

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

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

  /* None found, create a new architecture from the information
     provided.  */
  tdep = XCALLOC (1, struct gdbarch_tdep);
  gdbarch = gdbarch_alloc (&info, tdep);

  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
  set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);

  set_gdbarch_register_name (gdbarch, mt_register_name);
  set_gdbarch_num_regs (gdbarch, MT_NUM_REGS);
  set_gdbarch_num_pseudo_regs (gdbarch, MT_NUM_PSEUDO_REGS);
  set_gdbarch_pc_regnum (gdbarch, MT_PC_REGNUM);
  set_gdbarch_sp_regnum (gdbarch, MT_SP_REGNUM);
  set_gdbarch_pseudo_register_read (gdbarch, mt_pseudo_register_read);
  set_gdbarch_pseudo_register_write (gdbarch, mt_pseudo_register_write);
  set_gdbarch_skip_prologue (gdbarch, mt_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_breakpoint_from_pc (gdbarch, mt_breakpoint_from_pc);
  set_gdbarch_decr_pc_after_break (gdbarch, 0);
  set_gdbarch_frame_args_skip (gdbarch, 0);
  set_gdbarch_print_insn (gdbarch, print_insn_mt);
  set_gdbarch_register_type (gdbarch, mt_register_type);
  set_gdbarch_register_reggroup_p (gdbarch, mt_register_reggroup_p);

  set_gdbarch_return_value (gdbarch, mt_return_value);
  set_gdbarch_sp_regnum (gdbarch, MT_SP_REGNUM);

  set_gdbarch_frame_align (gdbarch, mt_frame_align);

  set_gdbarch_print_registers_info (gdbarch, mt_registers_info);

  set_gdbarch_push_dummy_call (gdbarch, mt_push_dummy_call);

  /* Target builtin data types.  */
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 32);
  set_gdbarch_long_bit (gdbarch, 32);
  set_gdbarch_long_long_bit (gdbarch, 64);
  set_gdbarch_float_bit (gdbarch, 32);
  set_gdbarch_double_bit (gdbarch, 64);
  set_gdbarch_long_double_bit (gdbarch, 64);
  set_gdbarch_ptr_bit (gdbarch, 32);

  /* Register the DWARF 2 sniffer first, and then the traditional prologue
     based sniffer.  */
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &mt_frame_unwind);
  frame_base_set_default (gdbarch, &mt_frame_base);

  /* Register the 'unwind_pc' method.  */
  set_gdbarch_unwind_pc (gdbarch, mt_unwind_pc);
  set_gdbarch_unwind_sp (gdbarch, mt_unwind_sp);

  /* 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, mt_dummy_id);

  return gdbarch;
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_mt_tdep;

void
_initialize_mt_tdep (void)
{
  register_gdbarch_init (bfd_arch_mt, mt_gdbarch_init);
}
