/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.

   Copyright (C) 1988-2024 Free Software Foundation, Inc.

   Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
   and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "symtab.h"
#include "value.h"
#include "gdbcmd.h"
#include "language.h"
#include "gdbcore.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbtypes.h"
#include "target.h"
#include "arch-utils.h"
#include "regcache.h"
#include "osabi.h"
#include "mips-tdep.h"
#include "block.h"
#include "reggroups.h"
#include "opcode/mips.h"
#include "elf/mips.h"
#include "elf-bfd.h"
#include "symcat.h"
#include "sim-regno.h"
#include "dis-asm.h"
#include "disasm.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
#include "infcall.h"
#include "remote.h"
#include "target-descriptions.h"
#include "dwarf2/frame.h"
#include "user-regs.h"
#include "valprint.h"
#include "ax.h"
#include "target-float.h"
#include <algorithm>

static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum);

static int mips32_instruction_has_delay_slot (struct gdbarch *gdbarch,
					      ULONGEST inst);
static int micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32);
static int mips16_instruction_has_delay_slot (unsigned short inst,
					      int mustbe32);

static int mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
					     CORE_ADDR addr);
static int micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
						CORE_ADDR addr, int mustbe32);
static int mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
					     CORE_ADDR addr, int mustbe32);

static void mips_print_float_info (struct gdbarch *, struct ui_file *,
				   const frame_info_ptr &, const char *);

/* A useful bit in the CP0 status register (MIPS_PS_REGNUM).  */
/* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip.  */
#define ST0_FR (1 << 26)

/* The sizes of floating point registers.  */

enum
{
  MIPS_FPU_SINGLE_REGSIZE = 4,
  MIPS_FPU_DOUBLE_REGSIZE = 8
};

enum
{
  MIPS32_REGSIZE = 4,
  MIPS64_REGSIZE = 8
};

static const char *mips_abi_string;

static const char *const mips_abi_strings[] = {
  "auto",
  "n32",
  "o32",
  "n64",
  "o64",
  "eabi32",
  "eabi64",
  NULL
};

/* Enum describing the different kinds of breakpoints.  */

enum mips_breakpoint_kind
{
  /* 16-bit MIPS16 mode breakpoint.  */
  MIPS_BP_KIND_MIPS16 = 2,

  /* 16-bit microMIPS mode breakpoint.  */
  MIPS_BP_KIND_MICROMIPS16 = 3,

  /* 32-bit standard MIPS mode breakpoint.  */
  MIPS_BP_KIND_MIPS32 = 4,

  /* 32-bit microMIPS mode breakpoint.  */
  MIPS_BP_KIND_MICROMIPS32 = 5,
};

/* For backwards compatibility we default to MIPS16.  This flag is
   overridden as soon as unambiguous ELF file flags tell us the
   compressed ISA encoding used.  */
static const char mips_compression_mips16[] = "mips16";
static const char mips_compression_micromips[] = "micromips";
static const char *const mips_compression_strings[] =
{
  mips_compression_mips16,
  mips_compression_micromips,
  NULL
};

static const char *mips_compression_string = mips_compression_mips16;

/* The standard register names, and all the valid aliases for them.  */
struct register_alias
{
  const char *name;
  int regnum;
};

/* Aliases for o32 and most other ABIs.  */
const struct register_alias mips_o32_aliases[] = {
  { "ta0", 12 },
  { "ta1", 13 },
  { "ta2", 14 },
  { "ta3", 15 }
};

/* Aliases for n32 and n64.  */
const struct register_alias mips_n32_n64_aliases[] = {
  { "ta0", 8 },
  { "ta1", 9 },
  { "ta2", 10 },
  { "ta3", 11 }
};

/* Aliases for ABI-independent registers.  */
const struct register_alias mips_register_aliases[] = {
  /* The architecture manuals specify these ABI-independent names for
     the GPRs.  */
#define R(n) { "r" #n, n }
  R(0), R(1), R(2), R(3), R(4), R(5), R(6), R(7),
  R(8), R(9), R(10), R(11), R(12), R(13), R(14), R(15),
  R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
  R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
#undef R

  /* k0 and k1 are sometimes called these instead (for "kernel
     temp").  */
  { "kt0", 26 },
  { "kt1", 27 },

  /* This is the traditional GDB name for the CP0 status register.  */
  { "sr", MIPS_PS_REGNUM },

  /* This is the traditional GDB name for the CP0 BadVAddr register.  */
  { "bad", MIPS_EMBED_BADVADDR_REGNUM },

  /* This is the traditional GDB name for the FCSR.  */
  { "fsr", MIPS_EMBED_FP0_REGNUM + 32 }
};

const struct register_alias mips_numeric_register_aliases[] = {
#define R(n) { #n, n }
  R(0), R(1), R(2), R(3), R(4), R(5), R(6), R(7),
  R(8), R(9), R(10), R(11), R(12), R(13), R(14), R(15),
  R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
  R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
#undef R
};

#ifndef MIPS_DEFAULT_FPU_TYPE
#define MIPS_DEFAULT_FPU_TYPE MIPS_FPU_DOUBLE
#endif
static int mips_fpu_type_auto = 1;
static enum mips_fpu_type mips_fpu_type = MIPS_DEFAULT_FPU_TYPE;

static unsigned int mips_debug = 0;

/* Properties (for struct target_desc) describing the g/G packet
   layout.  */
#define PROPERTY_GP32 "internal: transfers-32bit-registers"
#define PROPERTY_GP64 "internal: transfers-64bit-registers"

struct target_desc *mips_tdesc_gp32;
struct target_desc *mips_tdesc_gp64;

/* The current set of options to be passed to the disassembler.  */
static char *mips_disassembler_options;

/* Implicit disassembler options for individual ABIs.  These tell
   libopcodes to use general-purpose register names corresponding
   to the ABI we have selected, perhaps via a `set mips abi ...'
   override, rather than ones inferred from the ABI set in the ELF
   headers of the binary file selected for debugging.  */
static const char mips_disassembler_options_o32[] = "gpr-names=32";
static const char mips_disassembler_options_n32[] = "gpr-names=n32";
static const char mips_disassembler_options_n64[] = "gpr-names=64";

const struct mips_regnum *
mips_regnum (struct gdbarch *gdbarch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
  return tdep->regnum;
}

static int
mips_fpa0_regnum (struct gdbarch *gdbarch)
{
  return mips_regnum (gdbarch)->fp0 + 12;
}

/* Return 1 if REGNUM refers to a floating-point general register, raw
   or cooked.  Otherwise return 0.  */

static int
mips_float_register_p (struct gdbarch *gdbarch, int regnum)
{
  int rawnum = regnum % gdbarch_num_regs (gdbarch);

  return (rawnum >= mips_regnum (gdbarch)->fp0
	  && rawnum < mips_regnum (gdbarch)->fp0 + 32);
}

static bool
mips_eabi (gdbarch *arch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (arch);
  return (tdep->mips_abi == MIPS_ABI_EABI32 \
	  || tdep->mips_abi == MIPS_ABI_EABI64);
}

static int
mips_last_fp_arg_regnum (gdbarch *arch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (arch);
  return tdep->mips_last_fp_arg_regnum;
}

static int
mips_last_arg_regnum (gdbarch *arch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (arch);
  return tdep->mips_last_arg_regnum;
}

static enum mips_fpu_type
mips_get_fpu_type (gdbarch *arch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (arch);
  return tdep->mips_fpu_type;
}

/* Return the MIPS ABI associated with GDBARCH.  */
enum mips_abi
mips_abi (struct gdbarch *gdbarch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
  return tdep->mips_abi;
}

int
mips_isa_regsize (struct gdbarch *gdbarch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

  /* If we know how big the registers are, use that size.  */
  if (tdep->register_size_valid_p)
    return tdep->register_size;

  /* Fall back to the previous behavior.  */
  return (gdbarch_bfd_arch_info (gdbarch)->bits_per_word
	  / gdbarch_bfd_arch_info (gdbarch)->bits_per_byte);
}

/* Max saved register size.  */
#define MAX_MIPS_ABI_REGSIZE 8

/* Return the currently configured (or set) saved register size.  */

unsigned int
mips_abi_regsize (struct gdbarch *gdbarch)
{
  switch (mips_abi (gdbarch))
    {
    case MIPS_ABI_EABI32:
    case MIPS_ABI_O32:
      return 4;
    case MIPS_ABI_N32:
    case MIPS_ABI_N64:
    case MIPS_ABI_O64:
    case MIPS_ABI_EABI64:
      return 8;
    case MIPS_ABI_UNKNOWN:
    case MIPS_ABI_LAST:
    default:
      internal_error (_("bad switch"));
    }
}

/* MIPS16/microMIPS function addresses are odd (bit 0 is set).  Here
   are some functions to handle addresses associated with compressed
   code including but not limited to testing, setting, or clearing
   bit 0 of such addresses.  */

/* Return one iff compressed code is the MIPS16 instruction set.  */

static int
is_mips16_isa (struct gdbarch *gdbarch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
  return tdep->mips_isa == ISA_MIPS16;
}

/* Return one iff compressed code is the microMIPS instruction set.  */

static int
is_micromips_isa (struct gdbarch *gdbarch)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
  return tdep->mips_isa == ISA_MICROMIPS;
}

/* Return one iff ADDR denotes compressed code.  */

static int
is_compact_addr (CORE_ADDR addr)
{
  return ((addr) & 1);
}

/* Return one iff ADDR denotes standard ISA code.  */

static int
is_mips_addr (CORE_ADDR addr)
{
  return !is_compact_addr (addr);
}

/* Return one iff ADDR denotes MIPS16 code.  */

static int
is_mips16_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return is_compact_addr (addr) && is_mips16_isa (gdbarch);
}

/* Return one iff ADDR denotes microMIPS code.  */

static int
is_micromips_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return is_compact_addr (addr) && is_micromips_isa (gdbarch);
}

/* Strip the ISA (compression) bit off from ADDR.  */

static CORE_ADDR
unmake_compact_addr (CORE_ADDR addr)
{
  return ((addr) & ~(CORE_ADDR) 1);
}

/* Add the ISA (compression) bit to ADDR.  */

static CORE_ADDR
make_compact_addr (CORE_ADDR addr)
{
  return ((addr) | (CORE_ADDR) 1);
}

/* Extern version of unmake_compact_addr; we use a separate function
   so that unmake_compact_addr can be inlined throughout this file.  */

CORE_ADDR
mips_unmake_compact_addr (CORE_ADDR addr)
{
  return unmake_compact_addr (addr);
}

/* Functions for setting and testing a bit in a minimal symbol that
   marks it as MIPS16 or microMIPS function.  The MSB of the minimal
   symbol's "info" field is used for this purpose.

   gdbarch_elf_make_msymbol_special tests whether an ELF symbol is
   "special", i.e. refers to a MIPS16 or microMIPS function, and sets
   one of the "special" bits in a minimal symbol to mark it accordingly.
   The test checks an ELF-private flag that is valid for true function
   symbols only; for synthetic symbols such as for PLT stubs that have
   no ELF-private part at all the MIPS BFD backend arranges for this
   information to be carried in the asymbol's udata field instead.

   msymbol_is_mips16 and msymbol_is_micromips test the "special" bit
   in a minimal symbol.  */

static void
mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym)
{
  elf_symbol_type *elfsym = (elf_symbol_type *) sym;
  unsigned char st_other;

  if ((sym->flags & BSF_SYNTHETIC) == 0)
    st_other = elfsym->internal_elf_sym.st_other;
  else if ((sym->flags & BSF_FUNCTION) != 0)
    st_other = sym->udata.i;
  else
    return;

  if (ELF_ST_IS_MICROMIPS (st_other))
    {
      SET_MSYMBOL_TARGET_FLAG_MICROMIPS (msym);
      CORE_ADDR fixed = CORE_ADDR (msym->unrelocated_address ()) | 1;
      msym->set_unrelocated_address (unrelocated_addr (fixed));
    }
  else if (ELF_ST_IS_MIPS16 (st_other))
    {
      SET_MSYMBOL_TARGET_FLAG_MIPS16 (msym);
      CORE_ADDR fixed = CORE_ADDR (msym->unrelocated_address ()) | 1;
      msym->set_unrelocated_address (unrelocated_addr (fixed));
    }
}

/* Return one iff MSYM refers to standard ISA code.  */

static int
msymbol_is_mips (struct minimal_symbol *msym)
{
  return !(MSYMBOL_TARGET_FLAG_MIPS16 (msym)
	   || MSYMBOL_TARGET_FLAG_MICROMIPS (msym));
}

/* Return one iff MSYM refers to MIPS16 code.  */

static int
msymbol_is_mips16 (struct minimal_symbol *msym)
{
  return MSYMBOL_TARGET_FLAG_MIPS16 (msym);
}

/* Return one iff MSYM refers to microMIPS code.  */

static int
msymbol_is_micromips (struct minimal_symbol *msym)
{
  return MSYMBOL_TARGET_FLAG_MICROMIPS (msym);
}

/* Set the ISA bit in the main symbol too, complementing the corresponding
   minimal symbol setting and reflecting the run-time value of the symbol.
   The need for comes from the ISA bit having been cleared as code in
   `_bfd_mips_elf_symbol_processing' separated it into the ELF symbol's
   `st_other' STO_MIPS16 or STO_MICROMIPS annotation, making the values
   of symbols referring to compressed code different in GDB to the values
   used by actual code.  That in turn makes them evaluate incorrectly in
   expressions, producing results different to what the same expressions
   yield when compiled into the program being debugged.  */

static void
mips_make_symbol_special (struct symbol *sym, struct objfile *objfile)
{
  if (sym->aclass () == LOC_BLOCK)
    {
      /* We are in symbol reading so it is OK to cast away constness.  */
      struct block *block = (struct block *) sym->value_block ();
      CORE_ADDR compact_block_start;
      struct bound_minimal_symbol msym;

      compact_block_start = block->start () | 1;
      msym = lookup_minimal_symbol_by_pc (compact_block_start);
      if (msym.minsym && !msymbol_is_mips (msym.minsym))
	{
	  block->set_start (compact_block_start);
	}
    }
}

/* XFER a value from the big/little/left end of the register.
   Depending on the size of the value it might occupy the entire
   register or just part of it.  Make an allowance for this, aligning
   things accordingly.  */

static void
mips_xfer_register (struct gdbarch *gdbarch, struct regcache *regcache,
		    int reg_num, int length,
		    enum bfd_endian endian, gdb_byte *in,
		    const gdb_byte *out, int buf_offset)
{
  int reg_offset = 0;

  gdb_assert (reg_num >= gdbarch_num_regs (gdbarch));
  /* Need to transfer the left or right part of the register, based on
     the targets byte order.  */
  switch (endian)
    {
    case BFD_ENDIAN_BIG:
      reg_offset = register_size (gdbarch, reg_num) - length;
      break;
    case BFD_ENDIAN_LITTLE:
      reg_offset = 0;
      break;
    case BFD_ENDIAN_UNKNOWN:	/* Indicates no alignment.  */
      reg_offset = 0;
      break;
    default:
      internal_error (_("bad switch"));
    }
  if (mips_debug)
    gdb_printf (gdb_stderr,
		"xfer $%d, reg offset %d, buf offset %d, length %d, ",
		reg_num, reg_offset, buf_offset, length);
  if (mips_debug && out != NULL)
    {
      int i;
      gdb_printf (gdb_stdlog, "out ");
      for (i = 0; i < length; i++)
	gdb_printf (gdb_stdlog, "%02x", out[buf_offset + i]);
    }
  if (in != NULL)
    regcache->cooked_read_part (reg_num, reg_offset, length, in + buf_offset);
  if (out != NULL)
    regcache->cooked_write_part (reg_num, reg_offset, length, out + buf_offset);
  if (mips_debug && in != NULL)
    {
      int i;
      gdb_printf (gdb_stdlog, "in ");
      for (i = 0; i < length; i++)
	gdb_printf (gdb_stdlog, "%02x", in[buf_offset + i]);
    }
  if (mips_debug)
    gdb_printf (gdb_stdlog, "\n");
}

/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
   compatiblity mode.  A return value of 1 means that we have
   physical 64-bit registers, but should treat them as 32-bit registers.  */

static int
mips2_fp_compat (const frame_info_ptr &frame)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
     meaningful.  */
  if (register_size (gdbarch, mips_regnum (gdbarch)->fp0) == 4)
    return 0;

#if 0
  /* FIXME drow 2002-03-10: This is disabled until we can do it consistently,
     in all the places we deal with FP registers.  PR gdb/413.  */
  /* Otherwise check the FR bit in the status register - it controls
     the FP compatiblity mode.  If it is clear we are in compatibility
     mode.  */
  if ((get_frame_register_unsigned (frame, MIPS_PS_REGNUM) & ST0_FR) == 0)
    return 1;
#endif

  return 0;
}

#define VM_MIN_ADDRESS (CORE_ADDR)0x400000

static CORE_ADDR heuristic_proc_start (struct gdbarch *, CORE_ADDR);

/* The list of available "set mips " and "show mips " commands.  */

static struct cmd_list_element *setmipscmdlist = NULL;
static struct cmd_list_element *showmipscmdlist = NULL;

/* Integer registers 0 thru 31 are handled explicitly by
   mips_register_name().  Processor specific registers 32 and above
   are listed in the following tables.  */

enum
{ NUM_MIPS_PROCESSOR_REGS = (90 - 32) };

/* Generic MIPS.  */

static const char * const mips_generic_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
  "sr", "lo", "hi", "bad", "cause", "pc",
  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
  "fsr", "fir",
};

/* Names of tx39 registers.  */

static const char * const mips_tx39_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
  "sr", "lo", "hi", "bad", "cause", "pc",
  "", "", "", "", "", "", "", "",
  "", "", "", "", "", "", "", "",
  "", "", "", "", "", "", "", "",
  "", "", "", "", "", "", "", "",
  "", "", "", "",
  "", "", "", "", "", "", "", "",
  "", "", "config", "cache", "debug", "depc", "epc",
};

/* Names of registers with Linux kernels.  */
static const char * const mips_linux_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
  "sr", "lo", "hi", "bad", "cause", "pc",
  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
  "fsr", "fir"
};


/* Return the name of the register corresponding to REGNO.  */
static const char *
mips_register_name (struct gdbarch *gdbarch, int regno)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
  /* GPR names for all ABIs other than n32/n64.  */
  static const char *mips_gpr_names[] = {
    "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
  };

  /* GPR names for n32 and n64 ABIs.  */
  static const char *mips_n32_n64_gpr_names[] = {
    "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
    "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
  };

  enum mips_abi abi = mips_abi (gdbarch);

  /* Map [gdbarch_num_regs .. 2*gdbarch_num_regs) onto the raw registers, 
     but then don't make the raw register names visible.  This (upper)
     range of user visible register numbers are the pseudo-registers.

     This approach was adopted accommodate the following scenario:
     It is possible to debug a 64-bit device using a 32-bit
     programming model.  In such instances, the raw registers are
     configured to be 64-bits wide, while the pseudo registers are
     configured to be 32-bits wide.  The registers that the user
     sees - the pseudo registers - match the users expectations
     given the programming model being used.  */
  int rawnum = regno % gdbarch_num_regs (gdbarch);
  if (regno < gdbarch_num_regs (gdbarch))
    return "";

  /* The MIPS integer registers are always mapped from 0 to 31.  The
     names of the registers (which reflects the conventions regarding
     register use) vary depending on the ABI.  */
  if (0 <= rawnum && rawnum < 32)
    {
      if (abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64)
	return mips_n32_n64_gpr_names[rawnum];
      else
	return mips_gpr_names[rawnum];
    }
  else if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
    return tdesc_register_name (gdbarch, rawnum);
  else if (32 <= rawnum && rawnum < gdbarch_num_regs (gdbarch))
    {
      gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS);
      if (tdep->mips_processor_reg_names[rawnum - 32])
	return tdep->mips_processor_reg_names[rawnum - 32];
      return "";
    }
  else
    internal_error (_("mips_register_name: bad register number %d"), rawnum);
}

/* Return the groups that a MIPS register can be categorised into.  */

static int
mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			  const struct reggroup *reggroup)
{
  int vector_p;
  int float_p;
  int raw_p;
  int rawnum = regnum % gdbarch_num_regs (gdbarch);
  int pseudo = regnum / gdbarch_num_regs (gdbarch);
  if (reggroup == all_reggroup)
    return pseudo;
  vector_p = register_type (gdbarch, regnum)->is_vector ();
  float_p = register_type (gdbarch, regnum)->code () == TYPE_CODE_FLT;
  /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs
     (gdbarch), as not all architectures are multi-arch.  */
  raw_p = rawnum < gdbarch_num_regs (gdbarch);
  if (gdbarch_register_name (gdbarch, regnum)[0] == '\0')
    return 0;
  if (reggroup == float_reggroup)
    return float_p && pseudo;
  if (reggroup == vector_reggroup)
    return vector_p && pseudo;
  if (reggroup == general_reggroup)
    return (!vector_p && !float_p) && pseudo;
  /* Save the pseudo registers.  Need to make certain that any code
     extracting register values from a saved register cache also uses
     pseudo registers.  */
  if (reggroup == save_reggroup)
    return raw_p && pseudo;
  /* Restore the same pseudo register.  */
  if (reggroup == restore_reggroup)
    return raw_p && pseudo;
  return 0;
}

/* Return the groups that a MIPS register can be categorised into.
   This version is only used if we have a target description which
   describes real registers (and their groups).  */

static int
mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
				const struct reggroup *reggroup)
{
  int rawnum = regnum % gdbarch_num_regs (gdbarch);
  int pseudo = regnum / gdbarch_num_regs (gdbarch);
  int ret;

  /* Only save, restore, and display the pseudo registers.  Need to
     make certain that any code extracting register values from a
     saved register cache also uses pseudo registers.

     Note: saving and restoring the pseudo registers is slightly
     strange; if we have 64 bits, we should save and restore all
     64 bits.  But this is hard and has little benefit.  */
  if (!pseudo)
    return 0;

  ret = tdesc_register_in_reggroup_p (gdbarch, rawnum, reggroup);
  if (ret != -1)
    return ret;

  return mips_register_reggroup_p (gdbarch, regnum, reggroup);
}

/* Map the symbol table registers which live in the range [1 *
   gdbarch_num_regs .. 2 * gdbarch_num_regs) back onto the corresponding raw
   registers.  Take care of alignment and size problems.  */

static enum register_status
mips_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
			   int cookednum, gdb_byte *buf)
{
  int rawnum = cookednum % gdbarch_num_regs (gdbarch);
  gdb_assert (cookednum >= gdbarch_num_regs (gdbarch)
	      && cookednum < 2 * gdbarch_num_regs (gdbarch));
  if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
    return regcache->raw_read (rawnum, buf);
  else if (register_size (gdbarch, rawnum) >
	   register_size (gdbarch, cookednum))
    {
      mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

      if (tdep->mips64_transfers_32bit_regs_p)
	return regcache->raw_read_part (rawnum, 0, 4, buf);
      else
	{
	  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
	  LONGEST regval;
	  enum register_status status;

	  status = regcache->raw_read (rawnum, &regval);
	  if (status == REG_VALID)
	    store_signed_integer (buf, 4, byte_order, regval);
	  return status;
	}
    }
  else
    internal_error (_("bad register size"));
}

static void
mips_pseudo_register_write (struct gdbarch *gdbarch,
			    struct regcache *regcache, int cookednum,
			    const gdb_byte *buf)
{
  int rawnum = cookednum % gdbarch_num_regs (gdbarch);
  gdb_assert (cookednum >= gdbarch_num_regs (gdbarch)
	      && cookednum < 2 * gdbarch_num_regs (gdbarch));
  if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
    regcache->raw_write (rawnum, buf);
  else if (register_size (gdbarch, rawnum) >
	   register_size (gdbarch, cookednum))
    {
      mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

      if (tdep->mips64_transfers_32bit_regs_p)
	regcache->raw_write_part (rawnum, 0, 4, buf);
      else
	{
	  /* Sign extend the shortened version of the register prior
	     to placing it in the raw register.  This is required for
	     some mips64 parts in order to avoid unpredictable behavior.  */
	  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
	  LONGEST regval = extract_signed_integer (buf, 4, byte_order);
	  regcache_raw_write_signed (regcache, rawnum, regval);
	}
    }
  else
    internal_error (_("bad register size"));
}

static int
mips_ax_pseudo_register_collect (struct gdbarch *gdbarch,
				 struct agent_expr *ax, int reg)
{
  int rawnum = reg % gdbarch_num_regs (gdbarch);
  gdb_assert (reg >= gdbarch_num_regs (gdbarch)
	      && reg < 2 * gdbarch_num_regs (gdbarch));

  ax_reg_mask (ax, rawnum);

  return 0;
}

static int
mips_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
				    struct agent_expr *ax, int reg)
{
  int rawnum = reg % gdbarch_num_regs (gdbarch);
  gdb_assert (reg >= gdbarch_num_regs (gdbarch)
	      && reg < 2 * gdbarch_num_regs (gdbarch));
  if (register_size (gdbarch, rawnum) >= register_size (gdbarch, reg))
    {
      ax_reg (ax, rawnum);

      if (register_size (gdbarch, rawnum) > register_size (gdbarch, reg))
	{
	  mips_gdbarch_tdep *tdep
	    = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

	  if (!tdep->mips64_transfers_32bit_regs_p
	      || gdbarch_byte_order (gdbarch) != BFD_ENDIAN_BIG)
	    {
	      ax_const_l (ax, 32);
	      ax_simple (ax, aop_lsh);
	    }
	  ax_const_l (ax, 32);
	  ax_simple (ax, aop_rsh_signed);
	}
    }
  else
    internal_error (_("bad register size"));

  return 0;
}

/* Table to translate 3-bit register field to actual register number.  */
static const signed char mips_reg3_to_reg[8] = { 16, 17, 2, 3, 4, 5, 6, 7 };

/* Heuristic_proc_start may hunt through the text section for a long
   time across a 2400 baud serial line.  Allows the user to limit this
   search.  */

static int heuristic_fence_post = 0;

/* Number of bytes of storage in the actual machine representation for
   register N.  NOTE: This defines the pseudo register type so need to
   rebuild the architecture vector.  */

static bool mips64_transfers_32bit_regs_p = false;

static void
set_mips64_transfers_32bit_regs (const char *args, int from_tty,
				 struct cmd_list_element *c)
{
  struct gdbarch_info info;
  /* FIXME: cagney/2003-11-15: Should be setting a field in "info"
     instead of relying on globals.  Doing that would let generic code
     handle the search for this specific architecture.  */
  if (!gdbarch_update_p (info))
    {
      mips64_transfers_32bit_regs_p = 0;
      error (_("32-bit compatibility mode not supported"));
    }
}

/* Convert to/from a register and the corresponding memory value.  */

/* This predicate tests for the case of an 8 byte floating point
   value that is being transferred to or from a pair of floating point
   registers each of which are (or are considered to be) only 4 bytes
   wide.  */
static int
mips_convert_register_float_case_p (struct gdbarch *gdbarch, int regnum,
				    struct type *type)
{
  return (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
	  && register_size (gdbarch, regnum) == 4
	  && mips_float_register_p (gdbarch, regnum)
	  && type->code () == TYPE_CODE_FLT && type->length () == 8);
}

/* This predicate tests for the case of a value of less than 8
   bytes in width that is being transfered to or from an 8 byte
   general purpose register.  */
static int
mips_convert_register_gpreg_case_p (struct gdbarch *gdbarch, int regnum,
				    struct type *type)
{
  int num_regs = gdbarch_num_regs (gdbarch);

  return (register_size (gdbarch, regnum) == 8
	  && regnum % num_regs > 0 && regnum % num_regs < 32
	  && type->length () < 8);
}

static int
mips_convert_register_p (struct gdbarch *gdbarch,
			 int regnum, struct type *type)
{
  return (mips_convert_register_float_case_p (gdbarch, regnum, type)
	  || mips_convert_register_gpreg_case_p (gdbarch, regnum, type));
}

static int
mips_register_to_value (const frame_info_ptr &frame, int regnum,
			struct type *type, gdb_byte *to,
			int *optimizedp, int *unavailablep)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame);

  if (mips_convert_register_float_case_p (gdbarch, regnum, type))
    {
      get_frame_register (frame, regnum + 0, to + 4);
      get_frame_register (frame, regnum + 1, to + 0);

      if (!get_frame_register_bytes (next_frame, regnum + 0, 0, { to + 4, 4 },
				     optimizedp, unavailablep))
	return 0;

      if (!get_frame_register_bytes (next_frame, regnum + 1, 0, { to + 0, 4 },
				     optimizedp, unavailablep))
	return 0;
      *optimizedp = *unavailablep = 0;
      return 1;
    }
  else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type))
    {
      size_t len = type->length ();
      CORE_ADDR offset;

      offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 8 - len : 0;
      if (!get_frame_register_bytes (next_frame, regnum, offset, { to, len },
				     optimizedp, unavailablep))
	return 0;

      *optimizedp = *unavailablep = 0;
      return 1;
    }
  else
    {
      internal_error (_("mips_register_to_value: unrecognized case"));
    }
}

static void
mips_value_to_register (const frame_info_ptr &frame, int regnum,
			struct type *type, const gdb_byte *from)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);

  if (mips_convert_register_float_case_p (gdbarch, regnum, type))
    {
      auto from_view = gdb::make_array_view (from, 8);
      frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame);
      put_frame_register (next_frame, regnum, from_view.slice (4));
      put_frame_register (next_frame, regnum + 1, from_view.slice (0, 4));
    }
  else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type))
    {
      gdb_byte fill[8];
      size_t len = type->length ();
      frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame);

      /* Sign extend values, irrespective of type, that are stored to 
	 a 64-bit general purpose register.  (32-bit unsigned values
	 are stored as signed quantities within a 64-bit register.
	 When performing an operation, in compiled code, that combines
	 a 32-bit unsigned value with a signed 64-bit value, a type
	 conversion is first performed that zeroes out the high 32 bits.)  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	{
	  if (from[0] & 0x80)
	    store_signed_integer (fill, 8, BFD_ENDIAN_BIG, -1);
	  else
	    store_signed_integer (fill, 8, BFD_ENDIAN_BIG, 0);
	  put_frame_register_bytes (next_frame, regnum, 0, {fill, 8 - len});
	  put_frame_register_bytes (next_frame, regnum, 8 - len, {from, len});
	}
      else
	{
	  if (from[len-1] & 0x80)
	    store_signed_integer (fill, 8, BFD_ENDIAN_LITTLE, -1);
	  else
	    store_signed_integer (fill, 8, BFD_ENDIAN_LITTLE, 0);
	  put_frame_register_bytes (next_frame, regnum, 0, {from, len});
	  put_frame_register_bytes (next_frame, regnum, len, {fill, 8 - len});
	}
    }
  else
    {
      internal_error (_("mips_value_to_register: unrecognized case"));
    }
}

/* Return the GDB type object for the "standard" data type of data in
   register REG.  */

static struct type *
mips_register_type (struct gdbarch *gdbarch, int regnum)
{
  gdb_assert (regnum >= 0 && regnum < 2 * gdbarch_num_regs (gdbarch));
  if (mips_float_register_p (gdbarch, regnum))
    {
      /* The floating-point registers raw, or cooked, always match
	 mips_isa_regsize(), and also map 1:1, byte for byte.  */
      if (mips_isa_regsize (gdbarch) == 4)
	return builtin_type (gdbarch)->builtin_float;
      else
	return builtin_type (gdbarch)->builtin_double;
    }
  else if (regnum < gdbarch_num_regs (gdbarch))
    {
      /* The raw or ISA registers.  These are all sized according to
	 the ISA regsize.  */
      if (mips_isa_regsize (gdbarch) == 4)
	return builtin_type (gdbarch)->builtin_int32;
      else
	return builtin_type (gdbarch)->builtin_int64;
    }
  else
    {
      int rawnum = regnum - gdbarch_num_regs (gdbarch);
      mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

      /* The cooked or ABI registers.  These are sized according to
	 the ABI (with a few complications).  */
      if (rawnum == mips_regnum (gdbarch)->fp_control_status
	  || rawnum == mips_regnum (gdbarch)->fp_implementation_revision)
	return builtin_type (gdbarch)->builtin_int32;
      else if (gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
	       && rawnum >= MIPS_FIRST_EMBED_REGNUM
	       && rawnum <= MIPS_LAST_EMBED_REGNUM)
	/* The pseudo/cooked view of the embedded registers is always
	   32-bit.  The raw view is handled below.  */
	return builtin_type (gdbarch)->builtin_int32;
      else if (tdep->mips64_transfers_32bit_regs_p)
	/* The target, while possibly using a 64-bit register buffer,
	   is only transfering 32-bits of each integer register.
	   Reflect this in the cooked/pseudo (ABI) register value.  */
	return builtin_type (gdbarch)->builtin_int32;
      else if (mips_abi_regsize (gdbarch) == 4)
	/* The ABI is restricted to 32-bit registers (the ISA could be
	   32- or 64-bit).  */
	return builtin_type (gdbarch)->builtin_int32;
      else
	/* 64-bit ABI.  */
	return builtin_type (gdbarch)->builtin_int64;
    }
}

/* Return the GDB type for the pseudo register REGNUM, which is the
   ABI-level view.  This function is only called if there is a target
   description which includes registers, so we know precisely the
   types of hardware registers.  */

static struct type *
mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
{
  const int num_regs = gdbarch_num_regs (gdbarch);
  int rawnum = regnum % num_regs;
  struct type *rawtype;

  gdb_assert (regnum >= num_regs && regnum < 2 * num_regs);

  /* Absent registers are still absent.  */
  rawtype = gdbarch_register_type (gdbarch, rawnum);
  if (rawtype->length () == 0)
    return rawtype;

  /* Present the floating point registers however the hardware did;
     do not try to convert between FPU layouts.  */
  if (mips_float_register_p (gdbarch, rawnum))
    return rawtype;

  /* Floating-point control registers are always 32-bit even though for
     backwards compatibility reasons 64-bit targets will transfer them
     as 64-bit quantities even if using XML descriptions.  */
  if (rawnum == mips_regnum (gdbarch)->fp_control_status
      || rawnum == mips_regnum (gdbarch)->fp_implementation_revision)
    return builtin_type (gdbarch)->builtin_int32;

  /* Use pointer types for registers if we can.  For n32 we can not,
     since we do not have a 64-bit pointer type.  */
  if (mips_abi_regsize (gdbarch)
      == builtin_type (gdbarch)->builtin_data_ptr->length())
    {
      if (rawnum == MIPS_SP_REGNUM
	  || rawnum == mips_regnum (gdbarch)->badvaddr)
	return builtin_type (gdbarch)->builtin_data_ptr;
      else if (rawnum == mips_regnum (gdbarch)->pc)
	return builtin_type (gdbarch)->builtin_func_ptr;
    }

  if (mips_abi_regsize (gdbarch) == 4 && rawtype->length () == 8
      && ((rawnum >= MIPS_ZERO_REGNUM && rawnum <= MIPS_PS_REGNUM)
	  || rawnum == mips_regnum (gdbarch)->lo
	  || rawnum == mips_regnum (gdbarch)->hi
	  || rawnum == mips_regnum (gdbarch)->badvaddr
	  || rawnum == mips_regnum (gdbarch)->cause
	  || rawnum == mips_regnum (gdbarch)->pc
	  || (mips_regnum (gdbarch)->dspacc != -1
	      && rawnum >= mips_regnum (gdbarch)->dspacc
	      && rawnum < mips_regnum (gdbarch)->dspacc + 6)))
    return builtin_type (gdbarch)->builtin_int32;

  /* The pseudo/cooked view of embedded registers is always
     32-bit, even if the target transfers 64-bit values for them.
     New targets relying on XML descriptions should only transfer
     the necessary 32 bits, but older versions of GDB expected 64,
     so allow the target to provide 64 bits without interfering
     with the displayed type.  */
  if (gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
      && rawnum >= MIPS_FIRST_EMBED_REGNUM
      && rawnum <= MIPS_LAST_EMBED_REGNUM)
    return builtin_type (gdbarch)->builtin_int32;

  /* For all other registers, pass through the hardware type.  */
  return rawtype;
}

/* Should the upper word of 64-bit addresses be zeroed?  */
static enum auto_boolean mask_address_var = AUTO_BOOLEAN_AUTO;

static int
mips_mask_address_p (mips_gdbarch_tdep *tdep)
{
  switch (mask_address_var)
    {
    case AUTO_BOOLEAN_TRUE:
      return 1;
    case AUTO_BOOLEAN_FALSE:
      return 0;
      break;
    case AUTO_BOOLEAN_AUTO:
      return tdep->default_mask_address_p;
    default:
      internal_error (_("mips_mask_address_p: bad switch"));
      return -1;
    }
}

static void
show_mask_address (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  const char *additional_text = "";
  if (mask_address_var == AUTO_BOOLEAN_AUTO)
    {
      if (gdbarch_bfd_arch_info (current_inferior ()->arch ())->arch
	  != bfd_arch_mips)
	additional_text = _(" (current architecture is not MIPS)");
      else
	{
	  mips_gdbarch_tdep *tdep
	    = gdbarch_tdep<mips_gdbarch_tdep> (current_inferior ()->arch  ());

	  if (mips_mask_address_p (tdep))
	    additional_text = _(" (currently \"on\")");
	  else
	    additional_text = _(" (currently \"off\")");
	}
    }

  gdb_printf (file, _("Zeroing of upper 32 bits of 64-bit addresses is \"%s\"%s.\n"),
	      value, additional_text);
}

/* Tell if the program counter value in MEMADDR is in a standard ISA
   function.  */

int
mips_pc_is_mips (CORE_ADDR memaddr)
{
  struct bound_minimal_symbol sym;

  /* Flags indicating that this is a MIPS16 or microMIPS function is
     stored by elfread.c in the high bit of the info field.  Use this
     to decide if the function is standard MIPS.  Otherwise if bit 0
     of the address is clear, then this is a standard MIPS function.  */
  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
  if (sym.minsym)
    return msymbol_is_mips (sym.minsym);
  else
    return is_mips_addr (memaddr);
}

/* Tell if the program counter value in MEMADDR is in a MIPS16 function.  */

int
mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr)
{
  struct bound_minimal_symbol sym;

  /* A flag indicating that this is a MIPS16 function is stored by
     elfread.c in the high bit of the info field.  Use this to decide
     if the function is MIPS16.  Otherwise if bit 0 of the address is
     set, then ELF file flags will tell if this is a MIPS16 function.  */
  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
  if (sym.minsym)
    return msymbol_is_mips16 (sym.minsym);
  else
    return is_mips16_addr (gdbarch, memaddr);
}

/* Tell if the program counter value in MEMADDR is in a microMIPS function.  */

int
mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr)
{
  struct bound_minimal_symbol sym;

  /* A flag indicating that this is a microMIPS function is stored by
     elfread.c in the high bit of the info field.  Use this to decide
     if the function is microMIPS.  Otherwise if bit 0 of the address
     is set, then ELF file flags will tell if this is a microMIPS
     function.  */
  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
  if (sym.minsym)
    return msymbol_is_micromips (sym.minsym);
  else
    return is_micromips_addr (gdbarch, memaddr);
}

/* Tell the ISA type of the function the program counter value in MEMADDR
   is in.  */

static enum mips_isa
mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr)
{
  struct bound_minimal_symbol sym;

  /* A flag indicating that this is a MIPS16 or a microMIPS function
     is stored by elfread.c in the high bit of the info field.  Use
     this to decide if the function is MIPS16 or microMIPS or normal
     MIPS.  Otherwise if bit 0 of the address is set, then ELF file
     flags will tell if this is a MIPS16 or a microMIPS function.  */
  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
  if (sym.minsym)
    {
      if (msymbol_is_micromips (sym.minsym))
	return ISA_MICROMIPS;
      else if (msymbol_is_mips16 (sym.minsym))
	return ISA_MIPS16;
      else
	return ISA_MIPS;
    }
  else
    {
      if (is_mips_addr (memaddr))
	return ISA_MIPS;
      else if (is_micromips_addr (gdbarch, memaddr))
	return ISA_MICROMIPS;
      else
	return ISA_MIPS16;
    }
}

/* Set the ISA bit correctly in the PC, used by DWARF-2 machinery.
   The need for comes from the ISA bit having been cleared, making
   addresses in FDE, range records, etc. referring to compressed code
   different to those in line information, the symbol table and finally
   the PC register.  That in turn confuses many operations.  */

static CORE_ADDR
mips_adjust_dwarf2_addr (CORE_ADDR pc)
{
  pc = unmake_compact_addr (pc);
  return mips_pc_is_mips (pc) ? pc : make_compact_addr (pc);
}

/* Recalculate the line record requested so that the resulting PC has
   the ISA bit set correctly, used by DWARF-2 machinery.  The need for
   this adjustment comes from some records associated with compressed
   code having the ISA bit cleared, most notably at function prologue
   ends.  The ISA bit is in this context retrieved from the minimal
   symbol covering the address requested, which in turn has been
   constructed from the binary's symbol table rather than DWARF-2
   information.  The correct setting of the ISA bit is required for
   breakpoint addresses to correctly match against the stop PC.

   As line entries can specify relative address adjustments we need to
   keep track of the absolute value of the last line address recorded
   in line information, so that we can calculate the actual address to
   apply the ISA bit adjustment to.  We use PC for this tracking and
   keep the original address there.

   As such relative address adjustments can be odd within compressed
   code we need to keep track of the last line address with the ISA
   bit adjustment applied too, as the original address may or may not
   have had the ISA bit set.  We use ADJ_PC for this tracking and keep
   the adjusted address there.

   For relative address adjustments we then use these variables to
   calculate the address intended by line information, which will be
   PC-relative, and return an updated adjustment carrying ISA bit
   information, which will be ADJ_PC-relative.  For absolute address
   adjustments we just return the same address that we store in ADJ_PC
   too.

   As the first line entry can be relative to an implied address value
   of 0 we need to have the initial address set up that we store in PC
   and ADJ_PC.  This is arranged with a call from `dwarf_decode_lines_1'
   that sets PC to 0 and ADJ_PC accordingly, usually 0 as well.  */

static CORE_ADDR
mips_adjust_dwarf2_line (CORE_ADDR addr, int rel)
{
  static CORE_ADDR adj_pc;
  static CORE_ADDR pc;
  CORE_ADDR isa_pc;

  pc = rel ? pc + addr : addr;
  isa_pc = mips_adjust_dwarf2_addr (pc);
  addr = rel ? isa_pc - adj_pc : isa_pc;
  adj_pc = isa_pc;
  return addr;
}

/* Various MIPS16 thunk (aka stub or trampoline) names.  */

static const char mips_str_mips16_call_stub[] = "__mips16_call_stub_";
static const char mips_str_mips16_ret_stub[] = "__mips16_ret_";
static const char mips_str_call_fp_stub[] = "__call_stub_fp_";
static const char mips_str_call_stub[] = "__call_stub_";
static const char mips_str_fn_stub[] = "__fn_stub_";

/* This is used as a PIC thunk prefix.  */

static const char mips_str_pic[] = ".pic.";

/* Return non-zero if the PC is inside a call thunk (aka stub or
   trampoline) that should be treated as a temporary frame.  */

static int
mips_in_frame_stub (CORE_ADDR pc)
{
  CORE_ADDR start_addr;
  const char *name;

  /* Find the starting address of the function containing the PC.  */
  if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
    return 0;

  /* If the PC is in __mips16_call_stub_*, this is a call/return stub.  */
  if (startswith (name, mips_str_mips16_call_stub))
    return 1;
  /* If the PC is in __call_stub_*, this is a call/return or a call stub.  */
  if (startswith (name, mips_str_call_stub))
    return 1;
  /* If the PC is in __fn_stub_*, this is a call stub.  */
  if (startswith (name, mips_str_fn_stub))
    return 1;

  return 0;			/* Not a stub.  */
}

/* MIPS believes that the PC has a sign extended value.  Perhaps the
   all registers should be sign extended for simplicity?  */

static CORE_ADDR
mips_read_pc (readable_regcache *regcache)
{
  int regnum = gdbarch_pc_regnum (regcache->arch ());
  LONGEST pc;

  regcache->cooked_read (regnum, &pc);
  return pc;
}

static CORE_ADDR
mips_unwind_pc (struct gdbarch *gdbarch, const frame_info_ptr &next_frame)
{
  CORE_ADDR pc;

  pc = frame_unwind_register_signed (next_frame, gdbarch_pc_regnum (gdbarch));
  /* macro/2012-04-20: This hack skips over MIPS16 call thunks as
     intermediate frames.  In this case we can get the caller's address
     from $ra, or if $ra contains an address within a thunk as well, then
     it must be in the return path of __mips16_call_stub_{s,d}{f,c}_{0..10}
     and thus the caller's address is in $s2.  */
  if (frame_relative_level (next_frame) >= 0 && mips_in_frame_stub (pc))
    {
      pc = frame_unwind_register_signed
	     (next_frame, gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM);
      if (mips_in_frame_stub (pc))
	pc = frame_unwind_register_signed
	       (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
    }
  return pc;
}

static CORE_ADDR
mips_unwind_sp (struct gdbarch *gdbarch, const frame_info_ptr &next_frame)
{
  return frame_unwind_register_signed
	   (next_frame, gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM);
}

/* 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
mips_dummy_id (struct gdbarch *gdbarch, const frame_info_ptr &this_frame)
{
  return frame_id_build
	   (get_frame_register_signed (this_frame,
				       gdbarch_num_regs (gdbarch)
				       + MIPS_SP_REGNUM),
	    get_frame_pc (this_frame));
}

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

void
mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
  int regnum = gdbarch_pc_regnum (regcache->arch ());

  regcache_cooked_write_unsigned (regcache, regnum, pc);
}

/* Fetch and return instruction from the specified location.  Handle
   MIPS16/microMIPS as appropriate.  */

static ULONGEST
mips_fetch_instruction (struct gdbarch *gdbarch,
			enum mips_isa isa, CORE_ADDR addr, int *errp)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[MIPS_INSN32_SIZE];
  int instlen;
  int err;

  switch (isa)
    {
    case ISA_MICROMIPS:
    case ISA_MIPS16:
      instlen = MIPS_INSN16_SIZE;
      addr = unmake_compact_addr (addr);
      break;
    case ISA_MIPS:
      instlen = MIPS_INSN32_SIZE;
      break;
    default:
      internal_error (_("invalid ISA"));
      break;
    }
  err = target_read_memory (addr, buf, instlen);
  if (errp != NULL)
    *errp = err;
  if (err != 0)
    {
      if (errp == NULL)
	memory_error (TARGET_XFER_E_IO, addr);
      return 0;
    }
  return extract_unsigned_integer (buf, instlen, byte_order);
}

/* These are the fields of 32 bit mips instructions.  */
#define mips32_op(x) (x >> 26)
#define itype_op(x) (x >> 26)
#define itype_rs(x) ((x >> 21) & 0x1f)
#define itype_rt(x) ((x >> 16) & 0x1f)
#define itype_immediate(x) (x & 0xffff)

#define jtype_op(x) (x >> 26)
#define jtype_target(x) (x & 0x03ffffff)

#define rtype_op(x) (x >> 26)
#define rtype_rs(x) ((x >> 21) & 0x1f)
#define rtype_rt(x) ((x >> 16) & 0x1f)
#define rtype_rd(x) ((x >> 11) & 0x1f)
#define rtype_shamt(x) ((x >> 6) & 0x1f)
#define rtype_funct(x) (x & 0x3f)

/* MicroMIPS instruction fields.  */
#define micromips_op(x) ((x) >> 10)

/* 16-bit/32-bit-high-part instruction formats, B and S refer to the lowest
   bit and the size respectively of the field extracted.  */
#define b0s4_imm(x) ((x) & 0xf)
#define b0s5_imm(x) ((x) & 0x1f)
#define b0s5_reg(x) ((x) & 0x1f)
#define b0s7_imm(x) ((x) & 0x7f)
#define b0s10_imm(x) ((x) & 0x3ff)
#define b1s4_imm(x) (((x) >> 1) & 0xf)
#define b1s9_imm(x) (((x) >> 1) & 0x1ff)
#define b2s3_cc(x) (((x) >> 2) & 0x7)
#define b4s2_regl(x) (((x) >> 4) & 0x3)
#define b5s5_op(x) (((x) >> 5) & 0x1f)
#define b5s5_reg(x) (((x) >> 5) & 0x1f)
#define b6s4_op(x) (((x) >> 6) & 0xf)
#define b7s3_reg(x) (((x) >> 7) & 0x7)

/* 32-bit instruction formats, B and S refer to the lowest bit and the size
   respectively of the field extracted.  */
#define b0s6_op(x) ((x) & 0x3f)
#define b0s11_op(x) ((x) & 0x7ff)
#define b0s12_imm(x) ((x) & 0xfff)
#define b0s16_imm(x) ((x) & 0xffff)
#define b0s26_imm(x) ((x) & 0x3ffffff)
#define b6s10_ext(x) (((x) >> 6) & 0x3ff)
#define b11s5_reg(x) (((x) >> 11) & 0x1f)
#define b12s4_op(x) (((x) >> 12) & 0xf)

/* Return the size in bytes of the instruction INSN encoded in the ISA
   instruction set.  */

static int
mips_insn_size (enum mips_isa isa, ULONGEST insn)
{
  switch (isa)
    {
    case ISA_MICROMIPS:
      if ((micromips_op (insn) & 0x4) == 0x4
	  || (micromips_op (insn) & 0x7) == 0x0)
	return 2 * MIPS_INSN16_SIZE;
      else
	return MIPS_INSN16_SIZE;
    case ISA_MIPS16:
      if ((insn & 0xf800) == 0xf000)
	return 2 * MIPS_INSN16_SIZE;
      else
	return MIPS_INSN16_SIZE;
    case ISA_MIPS:
	return MIPS_INSN32_SIZE;
    }
  internal_error (_("invalid ISA"));
}

static LONGEST
mips32_relative_offset (ULONGEST inst)
{
  return ((itype_immediate (inst) ^ 0x8000) - 0x8000) << 2;
}

/* Determine the address of the next instruction executed after the INST
   floating condition branch instruction at PC.  COUNT specifies the
   number of the floating condition bits tested by the branch.  */

static CORE_ADDR
mips32_bc1_pc (struct gdbarch *gdbarch, struct regcache *regcache,
	       ULONGEST inst, CORE_ADDR pc, int count)
{
  int fcsr = mips_regnum (gdbarch)->fp_control_status;
  int cnum = (itype_rt (inst) >> 2) & (count - 1);
  int tf = itype_rt (inst) & 1;
  int mask = (1 << count) - 1;
  ULONGEST fcs;
  int cond;

  if (fcsr == -1)
    /* No way to handle; it'll most likely trap anyway.  */
    return pc;

  fcs = regcache_raw_get_unsigned (regcache, fcsr);
  cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);

  if (((cond >> cnum) & mask) != mask * !tf)
    pc += mips32_relative_offset (inst);
  else
    pc += 4;

  return pc;
}

/* Return nonzero if the gdbarch is an Octeon series.  */

static int
is_octeon (struct gdbarch *gdbarch)
{
  const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);

  return (info->mach == bfd_mach_mips_octeon
	 || info->mach == bfd_mach_mips_octeonp
	 || info->mach == bfd_mach_mips_octeon2);
}

/* Return true if the OP represents the Octeon's BBIT instruction.  */

static int
is_octeon_bbit_op (int op, struct gdbarch *gdbarch)
{
  if (!is_octeon (gdbarch))
    return 0;
  /* BBIT0 is encoded as LWC2: 110 010.  */
  /* BBIT032 is encoded as LDC2: 110 110.  */
  /* BBIT1 is encoded as SWC2: 111 010.  */
  /* BBIT132 is encoded as SDC2: 111 110.  */
  if (op == 50 || op == 54 || op == 58 || op == 62)
    return 1;
  return 0;
}


/* Determine where to set a single step breakpoint while considering
   branch prediction.  */

static CORE_ADDR
mips32_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = regcache->arch ();
  unsigned long inst;
  int op;
  inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
  op = itype_op (inst);
  if ((inst & 0xe0000000) != 0)		/* Not a special, jump or branch
					   instruction.  */
    {
      if (op >> 2 == 5)
	/* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
	{
	  switch (op & 0x03)
	    {
	    case 0:		/* BEQL */
	      goto equal_branch;
	    case 1:		/* BNEL */
	      goto neq_branch;
	    case 2:		/* BLEZL */
	      goto less_branch;
	    case 3:		/* BGTZL */
	      goto greater_branch;
	    default:
	      pc += 4;
	    }
	}
      else if (op == 17 && itype_rs (inst) == 8)
	/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
	pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 1);
      else if (op == 17 && itype_rs (inst) == 9
	       && (itype_rt (inst) & 2) == 0)
	/* BC1ANY2F, BC1ANY2T: 010001 01001 xxx0x */
	pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 2);
      else if (op == 17 && itype_rs (inst) == 10
	       && (itype_rt (inst) & 2) == 0)
	/* BC1ANY4F, BC1ANY4T: 010001 01010 xxx0x */
	pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 4);
      else if (op == 29)
	/* JALX: 011101 */
	/* The new PC will be alternate mode.  */
	{
	  unsigned long reg;

	  reg = jtype_target (inst) << 2;
	  /* Add 1 to indicate 16-bit mode -- invert ISA mode.  */
	  pc = ((pc + 4) & ~(CORE_ADDR) 0x0fffffff) + reg + 1;
	}
      else if (is_octeon_bbit_op (op, gdbarch))
	{
	  int bit, branch_if;

	  branch_if = op == 58 || op == 62;
	  bit = itype_rt (inst);

	  /* Take into account the *32 instructions.  */
	  if (op == 54 || op == 62)
	    bit += 32;

	  if (((regcache_raw_get_signed (regcache,
					 itype_rs (inst)) >> bit) & 1)
	      == branch_if)
	    pc += mips32_relative_offset (inst) + 4;
	  else
	    pc += 8;        /* After the delay slot.  */
	}

      else
	pc += 4;		/* Not a branch, next instruction is easy.  */
    }
  else
    {				/* This gets way messy.  */

      /* Further subdivide into SPECIAL, REGIMM and other.  */
      switch (op & 0x07)	/* Extract bits 28,27,26.  */
	{
	case 0:		/* SPECIAL */
	  op = rtype_funct (inst);
	  switch (op)
	    {
	    case 8:		/* JR */
	    case 9:		/* JALR */
	      /* Set PC to that address.  */
	      pc = regcache_raw_get_signed (regcache, rtype_rs (inst));
	      break;
	    case 12:            /* SYSCALL */
	      {
		mips_gdbarch_tdep *tdep
		  = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

		if (tdep->syscall_next_pc != NULL)
		  pc = tdep->syscall_next_pc (get_current_frame ());
		else
		  pc += 4;
	      }
	      break;
	    default:
	      pc += 4;
	    }

	  break;		/* end SPECIAL */
	case 1:			/* REGIMM */
	  {
	    op = itype_rt (inst);	/* branch condition */
	    switch (op)
	      {
	      case 0:		/* BLTZ */
	      case 2:		/* BLTZL */
	      case 16:		/* BLTZAL */
	      case 18:		/* BLTZALL */
	      less_branch:
		if (regcache_raw_get_signed (regcache, itype_rs (inst)) < 0)
		  pc += mips32_relative_offset (inst) + 4;
		else
		  pc += 8;	/* after the delay slot */
		break;
	      case 1:		/* BGEZ */
	      case 3:		/* BGEZL */
	      case 17:		/* BGEZAL */
	      case 19:		/* BGEZALL */
		if (regcache_raw_get_signed (regcache, itype_rs (inst)) >= 0)
		  pc += mips32_relative_offset (inst) + 4;
		else
		  pc += 8;	/* after the delay slot */
		break;
	      case 0x1c:	/* BPOSGE32 */
	      case 0x1e:	/* BPOSGE64 */
		pc += 4;
		if (itype_rs (inst) == 0)
		  {
		    unsigned int pos = (op & 2) ? 64 : 32;
		    int dspctl = mips_regnum (gdbarch)->dspctl;

		    if (dspctl == -1)
		      /* No way to handle; it'll most likely trap anyway.  */
		      break;

		    if ((regcache_raw_get_unsigned (regcache,
						    dspctl) & 0x7f) >= pos)
		      pc += mips32_relative_offset (inst);
		    else
		      pc += 4;
		  }
		break;
		/* All of the other instructions in the REGIMM category */
	      default:
		pc += 4;
	      }
	  }
	  break;		/* end REGIMM */
	case 2:		/* J */
	case 3:		/* JAL */
	  {
	    unsigned long reg;
	    reg = jtype_target (inst) << 2;
	    /* Upper four bits get never changed...  */
	    pc = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff);
	  }
	  break;
	case 4:		/* BEQ, BEQL */
	equal_branch:
	  if (regcache_raw_get_signed (regcache, itype_rs (inst)) ==
	      regcache_raw_get_signed (regcache, itype_rt (inst)))
	    pc += mips32_relative_offset (inst) + 4;
	  else
	    pc += 8;
	  break;
	case 5:		/* BNE, BNEL */
	neq_branch:
	  if (regcache_raw_get_signed (regcache, itype_rs (inst)) !=
	      regcache_raw_get_signed (regcache, itype_rt (inst)))
	    pc += mips32_relative_offset (inst) + 4;
	  else
	    pc += 8;
	  break;
	case 6:		/* BLEZ, BLEZL */
	  if (regcache_raw_get_signed (regcache, itype_rs (inst)) <= 0)
	    pc += mips32_relative_offset (inst) + 4;
	  else
	    pc += 8;
	  break;
	case 7:
	default:
	greater_branch:	/* BGTZ, BGTZL */
	  if (regcache_raw_get_signed (regcache, itype_rs (inst)) > 0)
	    pc += mips32_relative_offset (inst) + 4;
	  else
	    pc += 8;
	  break;
	}			/* switch */
    }				/* else */
  return pc;
}				/* mips32_next_pc */

/* Extract the 7-bit signed immediate offset from the microMIPS instruction
   INSN.  */

static LONGEST
micromips_relative_offset7 (ULONGEST insn)
{
  return ((b0s7_imm (insn) ^ 0x40) - 0x40) << 1;
}

/* Extract the 10-bit signed immediate offset from the microMIPS instruction
   INSN.  */

static LONGEST
micromips_relative_offset10 (ULONGEST insn)
{
  return ((b0s10_imm (insn) ^ 0x200) - 0x200) << 1;
}

/* Extract the 16-bit signed immediate offset from the microMIPS instruction
   INSN.  */

static LONGEST
micromips_relative_offset16 (ULONGEST insn)
{
  return ((b0s16_imm (insn) ^ 0x8000) - 0x8000) << 1;
}

/* Return the size in bytes of the microMIPS instruction at the address PC.  */

static int
micromips_pc_insn_size (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  ULONGEST insn;

  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
  return mips_insn_size (ISA_MICROMIPS, insn);
}

/* Calculate the address of the next microMIPS instruction to execute
   after the INSN coprocessor 1 conditional branch instruction at the
   address PC.  COUNT denotes the number of coprocessor condition bits
   examined by the branch.  */

static CORE_ADDR
micromips_bc1_pc (struct gdbarch *gdbarch, struct regcache *regcache,
		  ULONGEST insn, CORE_ADDR pc, int count)
{
  int fcsr = mips_regnum (gdbarch)->fp_control_status;
  int cnum = b2s3_cc (insn >> 16) & (count - 1);
  int tf = b5s5_op (insn >> 16) & 1;
  int mask = (1 << count) - 1;
  ULONGEST fcs;
  int cond;

  if (fcsr == -1)
    /* No way to handle; it'll most likely trap anyway.  */
    return pc;

  fcs = regcache_raw_get_unsigned (regcache, fcsr);
  cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);

  if (((cond >> cnum) & mask) != mask * !tf)
    pc += micromips_relative_offset16 (insn);
  else
    pc += micromips_pc_insn_size (gdbarch, pc);

  return pc;
}

/* Calculate the address of the next microMIPS instruction to execute
   after the instruction at the address PC.  */

static CORE_ADDR
micromips_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = regcache->arch ();
  ULONGEST insn;

  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
  pc += MIPS_INSN16_SIZE;
  switch (mips_insn_size (ISA_MICROMIPS, insn))
    {
    /* 32-bit instructions.  */
    case 2 * MIPS_INSN16_SIZE:
      insn <<= 16;
      insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
      pc += MIPS_INSN16_SIZE;
      switch (micromips_op (insn >> 16))
	{
	case 0x00: /* POOL32A: bits 000000 */
	  switch (b0s6_op (insn))
	    {
	    case 0x3c: /* POOL32Axf: bits 000000 ... 111100 */
	      switch (b6s10_ext (insn))
		{
		case 0x3c:  /* JALR:     000000 0000111100 111100 */
		case 0x7c:  /* JALR.HB:  000000 0001111100 111100 */
		case 0x13c: /* JALRS:    000000 0100111100 111100 */
		case 0x17c: /* JALRS.HB: 000000 0101111100 111100 */
		  pc = regcache_raw_get_signed (regcache,
						b0s5_reg (insn >> 16));
		  break;
		case 0x22d: /* SYSCALL:  000000 1000101101 111100 */
		  {
		    mips_gdbarch_tdep *tdep
		      = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

		    if (tdep->syscall_next_pc != NULL)
		      pc = tdep->syscall_next_pc (get_current_frame ());
		  }
		  break;
		}
	      break;
	    }
	  break;

	case 0x10: /* POOL32I: bits 010000 */
	  switch (b5s5_op (insn >> 16))
	    {
	    case 0x00: /* BLTZ: bits 010000 00000 */
	    case 0x01: /* BLTZAL: bits 010000 00001 */
	    case 0x11: /* BLTZALS: bits 010000 10001 */
	      if (regcache_raw_get_signed (regcache,
					   b0s5_reg (insn >> 16)) < 0)
		pc += micromips_relative_offset16 (insn);
	      else
		pc += micromips_pc_insn_size (gdbarch, pc);
	      break;

	    case 0x02: /* BGEZ: bits 010000 00010 */
	    case 0x03: /* BGEZAL: bits 010000 00011 */
	    case 0x13: /* BGEZALS: bits 010000 10011 */
	      if (regcache_raw_get_signed (regcache,
					   b0s5_reg (insn >> 16)) >= 0)
		pc += micromips_relative_offset16 (insn);
	      else
		pc += micromips_pc_insn_size (gdbarch, pc);
	      break;

	    case 0x04: /* BLEZ: bits 010000 00100 */
	      if (regcache_raw_get_signed (regcache,
					   b0s5_reg (insn >> 16)) <= 0)
		pc += micromips_relative_offset16 (insn);
	      else
		pc += micromips_pc_insn_size (gdbarch, pc);
	      break;

	    case 0x05: /* BNEZC: bits 010000 00101 */
	      if (regcache_raw_get_signed (regcache,
					   b0s5_reg (insn >> 16)) != 0)
		pc += micromips_relative_offset16 (insn);
	      break;

	    case 0x06: /* BGTZ: bits 010000 00110 */
	      if (regcache_raw_get_signed (regcache,
					   b0s5_reg (insn >> 16)) > 0)
		pc += micromips_relative_offset16 (insn);
	      else
		pc += micromips_pc_insn_size (gdbarch, pc);
	      break;

	    case 0x07: /* BEQZC: bits 010000 00111 */
	      if (regcache_raw_get_signed (regcache,
					   b0s5_reg (insn >> 16)) == 0)
		pc += micromips_relative_offset16 (insn);
	      break;

	    case 0x14: /* BC2F: bits 010000 10100 xxx00 */
	    case 0x15: /* BC2T: bits 010000 10101 xxx00 */
	      if (((insn >> 16) & 0x3) == 0x0)
		/* BC2F, BC2T: don't know how to handle these.  */
		break;
	      break;

	    case 0x1a: /* BPOSGE64: bits 010000 11010 */
	    case 0x1b: /* BPOSGE32: bits 010000 11011 */
	      {
		unsigned int pos = (b5s5_op (insn >> 16) & 1) ? 32 : 64;
		int dspctl = mips_regnum (gdbarch)->dspctl;

		if (dspctl == -1)
		  /* No way to handle; it'll most likely trap anyway.  */
		  break;

		if ((regcache_raw_get_unsigned (regcache,
						dspctl) & 0x7f) >= pos)
		  pc += micromips_relative_offset16 (insn);
		else
		  pc += micromips_pc_insn_size (gdbarch, pc);
	      }
	      break;

	    case 0x1c: /* BC1F: bits 010000 11100 xxx00 */
		       /* BC1ANY2F: bits 010000 11100 xxx01 */
	    case 0x1d: /* BC1T: bits 010000 11101 xxx00 */
		       /* BC1ANY2T: bits 010000 11101 xxx01 */
	      if (((insn >> 16) & 0x2) == 0x0)
		pc = micromips_bc1_pc (gdbarch, regcache, insn, pc,
				       ((insn >> 16) & 0x1) + 1);
	      break;

	    case 0x1e: /* BC1ANY4F: bits 010000 11110 xxx01 */
	    case 0x1f: /* BC1ANY4T: bits 010000 11111 xxx01 */
	      if (((insn >> 16) & 0x3) == 0x1)
		pc = micromips_bc1_pc (gdbarch, regcache, insn, pc, 4);
	      break;
	    }
	  break;

	case 0x1d: /* JALS: bits 011101 */
	case 0x35: /* J: bits 110101 */
	case 0x3d: /* JAL: bits 111101 */
	    pc = ((pc | 0x7fffffe) ^ 0x7fffffe) | (b0s26_imm (insn) << 1);
	  break;

	case 0x25: /* BEQ: bits 100101 */
	    if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
		== regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16)))
	      pc += micromips_relative_offset16 (insn);
	    else
	      pc += micromips_pc_insn_size (gdbarch, pc);
	  break;

	case 0x2d: /* BNE: bits 101101 */
	  if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
		!= regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16)))
	      pc += micromips_relative_offset16 (insn);
	  else
	      pc += micromips_pc_insn_size (gdbarch, pc);
	  break;

	case 0x3c: /* JALX: bits 111100 */
	    pc = ((pc | 0xfffffff) ^ 0xfffffff) | (b0s26_imm (insn) << 2);
	  break;
	}
      break;

    /* 16-bit instructions.  */
    case MIPS_INSN16_SIZE:
      switch (micromips_op (insn))
	{
	case 0x11: /* POOL16C: bits 010001 */
	  if ((b5s5_op (insn) & 0x1c) == 0xc)
	    /* JR16, JRC, JALR16, JALRS16: 010001 011xx */
	    pc = regcache_raw_get_signed (regcache, b0s5_reg (insn));
	  else if (b5s5_op (insn) == 0x18)
	    /* JRADDIUSP: bits 010001 11000 */
	    pc = regcache_raw_get_signed (regcache, MIPS_RA_REGNUM);
	  break;

	case 0x23: /* BEQZ16: bits 100011 */
	  {
	    int rs = mips_reg3_to_reg[b7s3_reg (insn)];

	    if (regcache_raw_get_signed (regcache, rs) == 0)
	      pc += micromips_relative_offset7 (insn);
	    else
	      pc += micromips_pc_insn_size (gdbarch, pc);
	  }
	  break;

	case 0x2b: /* BNEZ16: bits 101011 */
	  {
	    int rs = mips_reg3_to_reg[b7s3_reg (insn)];

	    if (regcache_raw_get_signed (regcache, rs) != 0)
	      pc += micromips_relative_offset7 (insn);
	    else
	      pc += micromips_pc_insn_size (gdbarch, pc);
	  }
	  break;

	case 0x33: /* B16: bits 110011 */
	  pc += micromips_relative_offset10 (insn);
	  break;
	}
      break;
    }

  return pc;
}

/* Decoding the next place to set a breakpoint is irregular for the
   mips 16 variant, but fortunately, there fewer instructions.  We have
   to cope ith extensions for 16 bit instructions and a pair of actual
   32 bit instructions.  We dont want to set a single step instruction
   on the extend instruction either.  */

/* Lots of mips16 instruction formats */
/* Predicting jumps requires itype,ritype,i8type
   and their extensions      extItype,extritype,extI8type.  */
enum mips16_inst_fmts
{
  itype,			/* 0  immediate 5,10 */
  ritype,			/* 1   5,3,8 */
  rrtype,			/* 2   5,3,3,5 */
  rritype,			/* 3   5,3,3,5 */
  rrrtype,			/* 4   5,3,3,3,2 */
  rriatype,			/* 5   5,3,3,1,4 */
  shifttype,			/* 6   5,3,3,3,2 */
  i8type,			/* 7   5,3,8 */
  i8movtype,			/* 8   5,3,3,5 */
  i8mov32rtype,			/* 9   5,3,5,3 */
  i64type,			/* 10  5,3,8 */
  ri64type,			/* 11  5,3,3,5 */
  jalxtype,			/* 12  5,1,5,5,16 - a 32 bit instruction */
  exiItype,			/* 13  5,6,5,5,1,1,1,1,1,1,5 */
  extRitype,			/* 14  5,6,5,5,3,1,1,1,5 */
  extRRItype,			/* 15  5,5,5,5,3,3,5 */
  extRRIAtype,			/* 16  5,7,4,5,3,3,1,4 */
  EXTshifttype,			/* 17  5,5,1,1,1,1,1,1,5,3,3,1,1,1,2 */
  extI8type,			/* 18  5,6,5,5,3,1,1,1,5 */
  extI64type,			/* 19  5,6,5,5,3,1,1,1,5 */
  extRi64type,			/* 20  5,6,5,5,3,3,5 */
  extshift64type		/* 21  5,5,1,1,1,1,1,1,5,1,1,1,3,5 */
};
/* I am heaping all the fields of the formats into one structure and
   then, only the fields which are involved in instruction extension.  */
struct upk_mips16
{
  CORE_ADDR offset;
  unsigned int regx;		/* Function in i8 type.  */
  unsigned int regy;
};


/* The EXT-I, EXT-ri nad EXT-I8 instructions all have the same format
   for the bits which make up the immediate extension.  */

static CORE_ADDR
extended_offset (unsigned int extension)
{
  CORE_ADDR value;

  value = (extension >> 16) & 0x1f;	/* Extract 15:11.  */
  value = value << 6;
  value |= (extension >> 21) & 0x3f;	/* Extract 10:5.  */
  value = value << 5;
  value |= extension & 0x1f;		/* Extract 4:0.  */

  return value;
}

/* Only call this function if you know that this is an extendable
   instruction.  It won't malfunction, but why make excess remote memory
   references?  If the immediate operands get sign extended or something,
   do it after the extension is performed.  */
/* FIXME: Every one of these cases needs to worry about sign extension
   when the offset is to be used in relative addressing.  */

static unsigned int
fetch_mips_16 (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[8];

  pc = unmake_compact_addr (pc);	/* Clear the low order bit.  */
  target_read_memory (pc, buf, 2);
  return extract_unsigned_integer (buf, 2, byte_order);
}

static void
unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
	       unsigned int extension,
	       unsigned int inst,
	       enum mips16_inst_fmts insn_format, struct upk_mips16 *upk)
{
  CORE_ADDR offset;
  int regx;
  int regy;
  switch (insn_format)
    {
    case itype:
      {
	CORE_ADDR value;
	if (extension)
	  {
	    value = extended_offset ((extension << 16) | inst);
	    value = (value ^ 0x8000) - 0x8000;		/* Sign-extend.  */
	  }
	else
	  {
	    value = inst & 0x7ff;
	    value = (value ^ 0x400) - 0x400;		/* Sign-extend.  */
	  }
	offset = value;
	regx = -1;
	regy = -1;
      }
      break;
    case ritype:
    case i8type:
      {				/* A register identifier and an offset.  */
	/* Most of the fields are the same as I type but the
	   immediate value is of a different length.  */
	CORE_ADDR value;
	if (extension)
	  {
	    value = extended_offset ((extension << 16) | inst);
	    value = (value ^ 0x8000) - 0x8000;		/* Sign-extend.  */
	  }
	else
	  {
	    value = inst & 0xff;			/* 8 bits */
	    value = (value ^ 0x80) - 0x80;		/* Sign-extend.  */
	  }
	offset = value;
	regx = (inst >> 8) & 0x07;			/* i8 funct */
	regy = -1;
	break;
      }
    case jalxtype:
      {
	unsigned long value;
	unsigned int nexthalf;
	value = ((inst & 0x1f) << 5) | ((inst >> 5) & 0x1f);
	value = value << 16;
	nexthalf = mips_fetch_instruction (gdbarch, ISA_MIPS16, pc + 2, NULL);
						/* Low bit still set.  */
	value |= nexthalf;
	offset = value;
	regx = -1;
	regy = -1;
	break;
      }
    default:
      internal_error (_("bad switch"));
    }
  upk->offset = offset;
  upk->regx = regx;
  upk->regy = regy;
}


/* Calculate the destination of a branch whose 16-bit opcode word is at PC,
   and having a signed 16-bit OFFSET.  */

static CORE_ADDR
add_offset_16 (CORE_ADDR pc, int offset)
{
  return pc + (offset << 1) + 2;
}

static CORE_ADDR
extended_mips16_next_pc (regcache *regcache, CORE_ADDR pc,
			 unsigned int extension, unsigned int insn)
{
  struct gdbarch *gdbarch = regcache->arch ();
  int op = (insn >> 11);
  switch (op)
    {
    case 2:			/* Branch */
      {
	struct upk_mips16 upk;
	unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk);
	pc = add_offset_16 (pc, upk.offset);
	break;
      }
    case 3:			/* JAL , JALX - Watch out, these are 32 bit
				   instructions.  */
      {
	struct upk_mips16 upk;
	unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk);
	pc = ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2);
	if ((insn >> 10) & 0x01)	/* Exchange mode */
	  pc = pc & ~0x01;	/* Clear low bit, indicate 32 bit mode.  */
	else
	  pc |= 0x01;
	break;
      }
    case 4:			/* beqz */
      {
	struct upk_mips16 upk;
	int reg;
	unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
	reg = regcache_raw_get_signed (regcache, mips_reg3_to_reg[upk.regx]);
	if (reg == 0)
	  pc = add_offset_16 (pc, upk.offset);
	else
	  pc += 2;
	break;
      }
    case 5:			/* bnez */
      {
	struct upk_mips16 upk;
	int reg;
	unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
	reg = regcache_raw_get_signed (regcache, mips_reg3_to_reg[upk.regx]);
	if (reg != 0)
	  pc = add_offset_16 (pc, upk.offset);
	else
	  pc += 2;
	break;
      }
    case 12:			/* I8 Formats btez btnez */
      {
	struct upk_mips16 upk;
	int reg;
	unpack_mips16 (gdbarch, pc, extension, insn, i8type, &upk);
	/* upk.regx contains the opcode */
	/* Test register is 24 */
	reg = regcache_raw_get_signed (regcache, 24);
	if (((upk.regx == 0) && (reg == 0))	/* BTEZ */
	    || ((upk.regx == 1) && (reg != 0)))	/* BTNEZ */
	  pc = add_offset_16 (pc, upk.offset);
	else
	  pc += 2;
	break;
      }
    case 29:			/* RR Formats JR, JALR, JALR-RA */
      {
	struct upk_mips16 upk;
	/* upk.fmt = rrtype; */
	op = insn & 0x1f;
	if (op == 0)
	  {
	    int reg;
	    upk.regx = (insn >> 8) & 0x07;
	    upk.regy = (insn >> 5) & 0x07;
	    if ((upk.regy & 1) == 0)
	      reg = mips_reg3_to_reg[upk.regx];
	    else
	      reg = 31;		/* Function return instruction.  */
	    pc = regcache_raw_get_signed (regcache, reg);
	  }
	else
	  pc += 2;
	break;
      }
    case 30:
      /* This is an instruction extension.  Fetch the real instruction
	 (which follows the extension) and decode things based on
	 that.  */
      {
	pc += 2;
	pc = extended_mips16_next_pc (regcache, pc, insn,
				      fetch_mips_16 (gdbarch, pc));
	break;
      }
    default:
      {
	pc += 2;
	break;
      }
    }
  return pc;
}

static CORE_ADDR
mips16_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = regcache->arch ();
  unsigned int insn = fetch_mips_16 (gdbarch, pc);
  return extended_mips16_next_pc (regcache, pc, 0, insn);
}

/* The mips_next_pc function supports single_step when the remote
   target monitor or stub is not developed enough to do a single_step.
   It works by decoding the current instruction and predicting where a
   branch will go.  This isn't hard because all the data is available.
   The MIPS32, MIPS16 and microMIPS variants are quite different.  */
static CORE_ADDR
mips_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = regcache->arch ();

  if (mips_pc_is_mips16 (gdbarch, pc))
    return mips16_next_pc (regcache, pc);
  else if (mips_pc_is_micromips (gdbarch, pc))
    return micromips_next_pc (regcache, pc);
  else
    return mips32_next_pc (regcache, pc);
}

/* Return non-zero if the MIPS16 instruction INSN is a compact branch
   or jump.  */

static int
mips16_instruction_is_compact_branch (unsigned short insn)
{
  switch (insn & 0xf800)
    {
    case 0xe800:
      return (insn & 0x009f) == 0x80;	/* JALRC/JRC */
    case 0x6000:
      return (insn & 0x0600) == 0;	/* BTNEZ/BTEQZ */
    case 0x2800:			/* BNEZ */
    case 0x2000:			/* BEQZ */
    case 0x1000:			/* B */
      return 1;
    default:
      return 0;
    }
}

/* Return non-zero if the microMIPS instruction INSN is a compact branch
   or jump.  */

static int
micromips_instruction_is_compact_branch (unsigned short insn)
{
  switch (micromips_op (insn))
    {
    case 0x11:			/* POOL16C: bits 010001 */
      return (b5s5_op (insn) == 0x18
				/* JRADDIUSP: bits 010001 11000 */
	      || b5s5_op (insn) == 0xd);
				/* JRC: bits 010011 01101 */
    case 0x10:			/* POOL32I: bits 010000 */
      return (b5s5_op (insn) & 0x1d) == 0x5;
				/* BEQZC/BNEZC: bits 010000 001x1 */
    default:
      return 0;
    }
}

struct mips_frame_cache
{
  CORE_ADDR base;
  trad_frame_saved_reg *saved_regs;
};

/* Set a register's saved stack address in temp_saved_regs.  If an
   address has already been set for this register, do nothing; this
   way we will only recognize the first save of a given register in a
   function prologue.

   For simplicity, save the address in both [0 .. gdbarch_num_regs) and
   [gdbarch_num_regs .. 2*gdbarch_num_regs).
   Strictly speaking, only the second range is used as it is only second
   range (the ABI instead of ISA registers) that comes into play when finding
   saved registers in a frame.  */

static void
set_reg_offset (struct gdbarch *gdbarch, struct mips_frame_cache *this_cache,
		int regnum, CORE_ADDR offset)
{
  if (this_cache != NULL
      && this_cache->saved_regs[regnum].is_realreg ()
      && this_cache->saved_regs[regnum].realreg () == regnum)
    {
      this_cache->saved_regs[regnum + 0
			     * gdbarch_num_regs (gdbarch)].set_addr (offset);
      this_cache->saved_regs[regnum + 1
			     * gdbarch_num_regs (gdbarch)].set_addr (offset);
    }
}


/* Fetch the immediate value from a MIPS16 instruction.
   If the previous instruction was an EXTEND, use it to extend
   the upper bits of the immediate value.  This is a helper function
   for mips16_scan_prologue.  */

static int
mips16_get_imm (unsigned short prev_inst,	/* previous instruction */
		unsigned short inst,	/* current instruction */
		int nbits,	/* number of bits in imm field */
		int scale,	/* scale factor to be applied to imm */
		int is_signed)	/* is the imm field signed?  */
{
  int offset;

  if ((prev_inst & 0xf800) == 0xf000)	/* prev instruction was EXTEND? */
    {
      offset = ((prev_inst & 0x1f) << 11) | (prev_inst & 0x7e0);
      if (offset & 0x8000)	/* check for negative extend */
	offset = 0 - (0x10000 - (offset & 0xffff));
      return offset | (inst & 0x1f);
    }
  else
    {
      int max_imm = 1 << nbits;
      int mask = max_imm - 1;
      int sign_bit = max_imm >> 1;

      offset = inst & mask;
      if (is_signed && (offset & sign_bit))
	offset = 0 - (max_imm - offset);
      return offset * scale;
    }
}


/* Analyze the function prologue from START_PC to LIMIT_PC. Builds
   the associated FRAME_CACHE if not null.
   Return the address of the first instruction past the prologue.  */

static CORE_ADDR
mips16_scan_prologue (struct gdbarch *gdbarch,
		      CORE_ADDR start_pc, CORE_ADDR limit_pc,
		      const frame_info_ptr &this_frame,
		      struct mips_frame_cache *this_cache)
{
  int prev_non_prologue_insn = 0;
  int this_non_prologue_insn;
  int non_prologue_insns = 0;
  CORE_ADDR prev_pc;
  CORE_ADDR cur_pc;
  CORE_ADDR frame_addr = 0;	/* Value of $r17, used as frame pointer.  */
  CORE_ADDR sp;
  long frame_offset = 0;        /* Size of stack frame.  */
  long frame_adjust = 0;        /* Offset of FP from SP.  */
  int frame_reg = MIPS_SP_REGNUM;
  unsigned short prev_inst = 0;	/* saved copy of previous instruction.  */
  unsigned inst = 0;		/* current instruction */
  unsigned entry_inst = 0;	/* the entry instruction */
  unsigned save_inst = 0;	/* the save instruction */
  int prev_delay_slot = 0;
  int in_delay_slot;
  int reg, offset;

  int extend_bytes = 0;
  int prev_extend_bytes = 0;
  CORE_ADDR end_prologue_addr;

  /* Can be called when there's no process, and hence when there's no
     THIS_FRAME.  */
  if (this_frame != NULL)
    sp = get_frame_register_signed (this_frame,
				    gdbarch_num_regs (gdbarch)
				    + MIPS_SP_REGNUM);
  else
    sp = 0;

  if (limit_pc > start_pc + 200)
    limit_pc = start_pc + 200;
  prev_pc = start_pc;

  /* Permit at most one non-prologue non-control-transfer instruction
     in the middle which may have been reordered by the compiler for
     optimisation.  */
  for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN16_SIZE)
    {
      this_non_prologue_insn = 0;
      in_delay_slot = 0;

      /* Save the previous instruction.  If it's an EXTEND, we'll extract
	 the immediate offset extension from it in mips16_get_imm.  */
      prev_inst = inst;

      /* Fetch and decode the instruction.  */
      inst = (unsigned short) mips_fetch_instruction (gdbarch, ISA_MIPS16,
						      cur_pc, NULL);

      /* Normally we ignore extend instructions.  However, if it is
	 not followed by a valid prologue instruction, then this
	 instruction is not part of the prologue either.  We must
	 remember in this case to adjust the end_prologue_addr back
	 over the extend.  */
      if ((inst & 0xf800) == 0xf000)    /* extend */
	{
	  extend_bytes = MIPS_INSN16_SIZE;
	  continue;
	}

      prev_extend_bytes = extend_bytes;
      extend_bytes = 0;

      if ((inst & 0xff00) == 0x6300	/* addiu sp */
	  || (inst & 0xff00) == 0xfb00)	/* daddiu sp */
	{
	  offset = mips16_get_imm (prev_inst, inst, 8, 8, 1);
	  if (offset < 0)	/* Negative stack adjustment?  */
	    frame_offset -= offset;
	  else
	    /* Exit loop if a positive stack adjustment is found, which
	       usually means that the stack cleanup code in the function
	       epilogue is reached.  */
	    break;
	}
      else if ((inst & 0xf800) == 0xd000)	/* sw reg,n($sp) */
	{
	  offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
	  reg = mips_reg3_to_reg[(inst & 0x700) >> 8];
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	}
      else if ((inst & 0xff00) == 0xf900)	/* sd reg,n($sp) */
	{
	  offset = mips16_get_imm (prev_inst, inst, 5, 8, 0);
	  reg = mips_reg3_to_reg[(inst & 0xe0) >> 5];
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	}
      else if ((inst & 0xff00) == 0x6200)	/* sw $ra,n($sp) */
	{
	  offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
	  set_reg_offset (gdbarch, this_cache, MIPS_RA_REGNUM, sp + offset);
	}
      else if ((inst & 0xff00) == 0xfa00)	/* sd $ra,n($sp) */
	{
	  offset = mips16_get_imm (prev_inst, inst, 8, 8, 0);
	  set_reg_offset (gdbarch, this_cache, MIPS_RA_REGNUM, sp + offset);
	}
      else if (inst == 0x673d)	/* move $s1, $sp */
	{
	  frame_addr = sp;
	  frame_reg = 17;
	}
      else if ((inst & 0xff00) == 0x0100)	/* addiu $s1,sp,n */
	{
	  offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
	  frame_addr = sp + offset;
	  frame_reg = 17;
	  frame_adjust = offset;
	}
      else if ((inst & 0xFF00) == 0xd900)	/* sw reg,offset($s1) */
	{
	  offset = mips16_get_imm (prev_inst, inst, 5, 4, 0);
	  reg = mips_reg3_to_reg[(inst & 0xe0) >> 5];
	  set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset);
	}
      else if ((inst & 0xFF00) == 0x7900)	/* sd reg,offset($s1) */
	{
	  offset = mips16_get_imm (prev_inst, inst, 5, 8, 0);
	  reg = mips_reg3_to_reg[(inst & 0xe0) >> 5];
	  set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset);
	}
      else if ((inst & 0xf81f) == 0xe809
	       && (inst & 0x700) != 0x700)	/* entry */
	entry_inst = inst;	/* Save for later processing.  */
      else if ((inst & 0xff80) == 0x6480)	/* save */
	{
	  save_inst = inst;	/* Save for later processing.  */
	  if (prev_extend_bytes)		/* extend */
	    save_inst |= prev_inst << 16;
	}
      else if ((inst & 0xff1c) == 0x6704)	/* move reg,$a0-$a3 */
	{
	  /* This instruction is part of the prologue, but we don't
	     need to do anything special to handle it.  */
	}
      else if (mips16_instruction_has_delay_slot (inst, 0))
						/* JAL/JALR/JALX/JR */
	{
	  /* The instruction in the delay slot can be a part
	     of the prologue, so move forward once more.  */
	  in_delay_slot = 1;
	  if (mips16_instruction_has_delay_slot (inst, 1))
						/* JAL/JALX */
	    {
	      prev_extend_bytes = MIPS_INSN16_SIZE;
	      cur_pc += MIPS_INSN16_SIZE;	/* 32-bit instruction */
	    }
	}
      else
	{
	  this_non_prologue_insn = 1;
	}

      non_prologue_insns += this_non_prologue_insn;

      /* A jump or branch, or enough non-prologue insns seen?  If so,
	 then we must have reached the end of the prologue by now.  */
      if (prev_delay_slot || non_prologue_insns > 1
	  || mips16_instruction_is_compact_branch (inst))
	break;

      prev_non_prologue_insn = this_non_prologue_insn;
      prev_delay_slot = in_delay_slot;
      prev_pc = cur_pc - prev_extend_bytes;
    }

  /* The entry instruction is typically the first instruction in a function,
     and it stores registers at offsets relative to the value of the old SP
     (before the prologue).  But the value of the sp parameter to this
     function is the new SP (after the prologue has been executed).  So we
     can't calculate those offsets until we've seen the entire prologue,
     and can calculate what the old SP must have been.  */
  if (entry_inst != 0)
    {
      int areg_count = (entry_inst >> 8) & 7;
      int sreg_count = (entry_inst >> 6) & 3;

      /* The entry instruction always subtracts 32 from the SP.  */
      frame_offset += 32;

      /* Now we can calculate what the SP must have been at the
	 start of the function prologue.  */
      sp += frame_offset;

      /* Check if a0-a3 were saved in the caller's argument save area.  */
      for (reg = 4, offset = 0; reg < areg_count + 4; reg++)
	{
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	  offset += mips_abi_regsize (gdbarch);
	}

      /* Check if the ra register was pushed on the stack.  */
      offset = -4;
      if (entry_inst & 0x20)
	{
	  set_reg_offset (gdbarch, this_cache, MIPS_RA_REGNUM, sp + offset);
	  offset -= mips_abi_regsize (gdbarch);
	}

      /* Check if the s0 and s1 registers were pushed on the stack.  */
      for (reg = 16; reg < sreg_count + 16; reg++)
	{
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	  offset -= mips_abi_regsize (gdbarch);
	}
    }

  /* The SAVE instruction is similar to ENTRY, except that defined by the
     MIPS16e ASE of the MIPS Architecture.  Unlike with ENTRY though, the
     size of the frame is specified as an immediate field of instruction
     and an extended variation exists which lets additional registers and
     frame space to be specified.  The instruction always treats registers
     as 32-bit so its usefulness for 64-bit ABIs is questionable.  */
  if (save_inst != 0 && mips_abi_regsize (gdbarch) == 4)
    {
      static int args_table[16] = {
	0, 0, 0, 0, 1, 1, 1, 1,
	2, 2, 2, 0, 3, 3, 4, -1,
      };
      static int astatic_table[16] = {
	0, 1, 2, 3, 0, 1, 2, 3,
	0, 1, 2, 4, 0, 1, 0, -1,
      };
      int aregs = (save_inst >> 16) & 0xf;
      int xsregs = (save_inst >> 24) & 0x7;
      int args = args_table[aregs];
      int astatic = astatic_table[aregs];
      long frame_size;

      if (args < 0)
	{
	  warning (_("Invalid number of argument registers encoded in SAVE."));
	  args = 0;
	}
      if (astatic < 0)
	{
	  warning (_("Invalid number of static registers encoded in SAVE."));
	  astatic = 0;
	}

      /* For standard SAVE the frame size of 0 means 128.  */
      frame_size = ((save_inst >> 16) & 0xf0) | (save_inst & 0xf);
      if (frame_size == 0 && (save_inst >> 16) == 0)
	frame_size = 16;
      frame_size *= 8;
      frame_offset += frame_size;

      /* Now we can calculate what the SP must have been at the
	 start of the function prologue.  */
      sp += frame_offset;

      /* Check if A0-A3 were saved in the caller's argument save area.  */
      for (reg = MIPS_A0_REGNUM, offset = 0; reg < args + 4; reg++)
	{
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	  offset += mips_abi_regsize (gdbarch);
	}

      offset = -4;

      /* Check if the RA register was pushed on the stack.  */
      if (save_inst & 0x40)
	{
	  set_reg_offset (gdbarch, this_cache, MIPS_RA_REGNUM, sp + offset);
	  offset -= mips_abi_regsize (gdbarch);
	}

      /* Check if the S8 register was pushed on the stack.  */
      if (xsregs > 6)
	{
	  set_reg_offset (gdbarch, this_cache, 30, sp + offset);
	  offset -= mips_abi_regsize (gdbarch);
	  xsregs--;
	}
      /* Check if S2-S7 were pushed on the stack.  */
      for (reg = 18 + xsregs - 1; reg > 18 - 1; reg--)
	{
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	  offset -= mips_abi_regsize (gdbarch);
	}

      /* Check if the S1 register was pushed on the stack.  */
      if (save_inst & 0x10)
	{
	  set_reg_offset (gdbarch, this_cache, 17, sp + offset);
	  offset -= mips_abi_regsize (gdbarch);
	}
      /* Check if the S0 register was pushed on the stack.  */
      if (save_inst & 0x20)
	{
	  set_reg_offset (gdbarch, this_cache, 16, sp + offset);
	  offset -= mips_abi_regsize (gdbarch);
	}

      /* Check if A0-A3 were pushed on the stack.  */
      for (reg = MIPS_A0_REGNUM + 3; reg > MIPS_A0_REGNUM + 3 - astatic; reg--)
	{
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	  offset -= mips_abi_regsize (gdbarch);
	}
    }

  if (this_cache != NULL)
    {
      this_cache->base =
	(get_frame_register_signed (this_frame,
				    gdbarch_num_regs (gdbarch) + frame_reg)
	 + frame_offset - frame_adjust);
      /* FIXME: brobecker/2004-10-10: Just as in the mips32 case, we should
	 be able to get rid of the assignment below, evetually.  But it's
	 still needed for now.  */
      this_cache->saved_regs[gdbarch_num_regs (gdbarch)
			     + mips_regnum (gdbarch)->pc]
	= this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM];
    }

  /* Set end_prologue_addr to the address of the instruction immediately
     after the last one we scanned.  Unless the last one looked like a
     non-prologue instruction (and we looked ahead), in which case use
     its address instead.  */
  end_prologue_addr = (prev_non_prologue_insn || prev_delay_slot
		       ? prev_pc : cur_pc - prev_extend_bytes);

  return end_prologue_addr;
}

/* Heuristic unwinder for 16-bit MIPS instruction set (aka MIPS16).
   Procedures that use the 32-bit instruction set are handled by the
   mips_insn32 unwinder.  */

static struct mips_frame_cache *
mips_insn16_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct mips_frame_cache *cache;

  if ((*this_cache) != NULL)
    return (struct mips_frame_cache *) (*this_cache);
  cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
  (*this_cache) = cache;
  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

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

    find_pc_partial_function (pc, NULL, &start_addr, NULL);
    if (start_addr == 0)
      start_addr = heuristic_proc_start (gdbarch, pc);
    /* We can't analyze the prologue if we couldn't find the begining
       of the function.  */
    if (start_addr == 0)
      return cache;

    mips16_scan_prologue (gdbarch, start_addr, pc, this_frame,
			  (struct mips_frame_cache *) *this_cache);
  }
  
  /* gdbarch_sp_regnum contains the value and not the address.  */
  cache->saved_regs[gdbarch_num_regs (gdbarch)
		    + MIPS_SP_REGNUM].set_value (cache->base);

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

static void
mips_insn16_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
			   struct frame_id *this_id)
{
  struct mips_frame_cache *info = mips_insn16_frame_cache (this_frame,
							   this_cache);
  /* This marks the outermost frame.  */
  if (info->base == 0)
    return;
  (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
}

static struct value *
mips_insn16_frame_prev_register (const frame_info_ptr &this_frame,
				 void **this_cache, int regnum)
{
  struct mips_frame_cache *info = mips_insn16_frame_cache (this_frame,
							   this_cache);
  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}

static int
mips_insn16_frame_sniffer (const struct frame_unwind *self,
			   const frame_info_ptr &this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);
  if (mips_pc_is_mips16 (gdbarch, pc))
    return 1;
  return 0;
}

static const struct frame_unwind mips_insn16_frame_unwind =
{
  "mips insn16 prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  mips_insn16_frame_this_id,
  mips_insn16_frame_prev_register,
  NULL,
  mips_insn16_frame_sniffer
};

static CORE_ADDR
mips_insn16_frame_base_address (const frame_info_ptr &this_frame,
				void **this_cache)
{
  struct mips_frame_cache *info = mips_insn16_frame_cache (this_frame,
							   this_cache);
  return info->base;
}

static const struct frame_base mips_insn16_frame_base =
{
  &mips_insn16_frame_unwind,
  mips_insn16_frame_base_address,
  mips_insn16_frame_base_address,
  mips_insn16_frame_base_address
};

static const struct frame_base *
mips_insn16_frame_base_sniffer (const frame_info_ptr &this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);
  if (mips_pc_is_mips16 (gdbarch, pc))
    return &mips_insn16_frame_base;
  else
    return NULL;
}

/* Decode a 9-bit signed immediate argument of ADDIUSP -- -2 is mapped
   to -258, -1 -- to -257, 0 -- to 256, 1 -- to 257 and other values are
   interpreted directly, and then multiplied by 4.  */

static int
micromips_decode_imm9 (int imm)
{
  imm = (imm ^ 0x100) - 0x100;
  if (imm > -3 && imm < 2)
    imm ^= 0x100;
  return imm << 2;
}

/* Analyze the function prologue from START_PC to LIMIT_PC.  Return
   the address of the first instruction past the prologue.  */

static CORE_ADDR
micromips_scan_prologue (struct gdbarch *gdbarch,
			 CORE_ADDR start_pc, CORE_ADDR limit_pc,
			 const frame_info_ptr &this_frame,
			 struct mips_frame_cache *this_cache)
{
  CORE_ADDR end_prologue_addr;
  int prev_non_prologue_insn = 0;
  int frame_reg = MIPS_SP_REGNUM;
  int this_non_prologue_insn;
  int non_prologue_insns = 0;
  long frame_offset = 0;	/* Size of stack frame.  */
  long frame_adjust = 0;	/* Offset of FP from SP.  */
  int prev_delay_slot = 0;
  int in_delay_slot;
  CORE_ADDR prev_pc;
  CORE_ADDR cur_pc;
  ULONGEST insn;		/* current instruction */
  CORE_ADDR sp;
  long offset;
  long sp_adj;
  long v1_off = 0;		/* The assumption is LUI will replace it.  */
  int reglist;
  int breg;
  int dreg;
  int sreg;
  int treg;
  int loc;
  int op;
  int s;
  int i;

  /* Can be called when there's no process, and hence when there's no
     THIS_FRAME.  */
  if (this_frame != NULL)
    sp = get_frame_register_signed (this_frame,
				    gdbarch_num_regs (gdbarch)
				    + MIPS_SP_REGNUM);
  else
    sp = 0;

  if (limit_pc > start_pc + 200)
    limit_pc = start_pc + 200;
  prev_pc = start_pc;

  /* Permit at most one non-prologue non-control-transfer instruction
     in the middle which may have been reordered by the compiler for
     optimisation.  */
  for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += loc)
    {
      this_non_prologue_insn = 0;
      in_delay_slot = 0;
      sp_adj = 0;
      loc = 0;
      insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, cur_pc, NULL);
      loc += MIPS_INSN16_SIZE;
      switch (mips_insn_size (ISA_MICROMIPS, insn))
	{
	/* 32-bit instructions.  */
	case 2 * MIPS_INSN16_SIZE:
	  insn <<= 16;
	  insn |= mips_fetch_instruction (gdbarch,
					  ISA_MICROMIPS, cur_pc + loc, NULL);
	  loc += MIPS_INSN16_SIZE;
	  switch (micromips_op (insn >> 16))
	    {
	    /* Record $sp/$fp adjustment.  */
	    /* Discard (D)ADDU $gp,$jp used for PIC code.  */
	    case 0x0: /* POOL32A: bits 000000 */
	    case 0x16: /* POOL32S: bits 010110 */
	      op = b0s11_op (insn);
	      sreg = b0s5_reg (insn >> 16);
	      treg = b5s5_reg (insn >> 16);
	      dreg = b11s5_reg (insn);
	      if (op == 0x1d0
				/* SUBU: bits 000000 00111010000 */
				/* DSUBU: bits 010110 00111010000 */
		  && dreg == MIPS_SP_REGNUM && sreg == MIPS_SP_REGNUM
		  && treg == 3)
				/* (D)SUBU $sp, $v1 */
		    sp_adj = v1_off;
	      else if (op != 0x150
				/* ADDU: bits 000000 00101010000 */
				/* DADDU: bits 010110 00101010000 */
		       || dreg != 28 || sreg != 28 || treg != MIPS_T9_REGNUM)
		this_non_prologue_insn = 1;
	      break;

	    case 0x8: /* POOL32B: bits 001000 */
	      op = b12s4_op (insn);
	      breg = b0s5_reg (insn >> 16);
	      reglist = sreg = b5s5_reg (insn >> 16);
	      offset = (b0s12_imm (insn) ^ 0x800) - 0x800;
	      if ((op == 0x9 || op == 0xc)
				/* SWP: bits 001000 1001 */
				/* SDP: bits 001000 1100 */
		  && breg == MIPS_SP_REGNUM && sreg < MIPS_RA_REGNUM)
				/* S[DW]P reg,offset($sp) */
		{
		  s = 4 << ((b12s4_op (insn) & 0x4) == 0x4);
		  set_reg_offset (gdbarch, this_cache,
				  sreg, sp + offset);
		  set_reg_offset (gdbarch, this_cache,
				  sreg + 1, sp + offset + s);
		}
	      else if ((op == 0xd || op == 0xf)
				/* SWM: bits 001000 1101 */
				/* SDM: bits 001000 1111 */
		       && breg == MIPS_SP_REGNUM
				/* SWM reglist,offset($sp) */
		       && ((reglist >= 1 && reglist <= 9)
			   || (reglist >= 16 && reglist <= 25)))
		{
		  int sreglist = std::min(reglist & 0xf, 8);

		  s = 4 << ((b12s4_op (insn) & 0x2) == 0x2);
		  for (i = 0; i < sreglist; i++)
		    set_reg_offset (gdbarch, this_cache, 16 + i, sp + s * i);
		  if ((reglist & 0xf) > 8)
		    set_reg_offset (gdbarch, this_cache, 30, sp + s * i++);
		  if ((reglist & 0x10) == 0x10)
		    set_reg_offset (gdbarch, this_cache,
				    MIPS_RA_REGNUM, sp + s * i++);
		}
	      else
		this_non_prologue_insn = 1;
	      break;

	    /* Record $sp/$fp adjustment.  */
	    /* Discard (D)ADDIU $gp used for PIC code.  */
	    case 0xc: /* ADDIU: bits 001100 */
	    case 0x17: /* DADDIU: bits 010111 */
	      sreg = b0s5_reg (insn >> 16);
	      dreg = b5s5_reg (insn >> 16);
	      offset = (b0s16_imm (insn) ^ 0x8000) - 0x8000;
	      if (sreg == MIPS_SP_REGNUM && dreg == MIPS_SP_REGNUM)
				/* (D)ADDIU $sp, imm */
		sp_adj = offset;
	      else if (sreg == MIPS_SP_REGNUM && dreg == 30)
				/* (D)ADDIU $fp, $sp, imm */
		{
		  frame_adjust = offset;
		  frame_reg = 30;
		}
	      else if (sreg != 28 || dreg != 28)
				/* (D)ADDIU $gp, imm */
		this_non_prologue_insn = 1;
	      break;

	    /* LUI $v1 is used for larger $sp adjustments.  */
	    /* Discard LUI $gp used for PIC code.  */
	    case 0x10: /* POOL32I: bits 010000 */
	      if (b5s5_op (insn >> 16) == 0xd
				/* LUI: bits 010000 001101 */
		  && b0s5_reg (insn >> 16) == 3)
				/* LUI $v1, imm */
		v1_off = ((b0s16_imm (insn) << 16) ^ 0x80000000) - 0x80000000;
	      else if (b5s5_op (insn >> 16) != 0xd
				/* LUI: bits 010000 001101 */
		       || b0s5_reg (insn >> 16) != 28)
				/* LUI $gp, imm */
		this_non_prologue_insn = 1;
	      break;

	    /* ORI $v1 is used for larger $sp adjustments.  */
	    case 0x14: /* ORI: bits 010100 */
	      sreg = b0s5_reg (insn >> 16);
	      dreg = b5s5_reg (insn >> 16);
	      if (sreg == 3 && dreg == 3)
				/* ORI $v1, imm */
		v1_off |= b0s16_imm (insn);
	      else
		this_non_prologue_insn = 1;
	      break;

	    case 0x26: /* SWC1: bits 100110 */
	    case 0x2e: /* SDC1: bits 101110 */
	      breg = b0s5_reg (insn >> 16);
	      if (breg != MIPS_SP_REGNUM)
				/* S[DW]C1 reg,offset($sp) */
		this_non_prologue_insn = 1;
	      break;

	    case 0x36: /* SD: bits 110110 */
	    case 0x3e: /* SW: bits 111110 */
	      breg = b0s5_reg (insn >> 16);
	      sreg = b5s5_reg (insn >> 16);
	      offset = (b0s16_imm (insn) ^ 0x8000) - 0x8000;
	      if (breg == MIPS_SP_REGNUM)
				/* S[DW] reg,offset($sp) */
		set_reg_offset (gdbarch, this_cache, sreg, sp + offset);
	      else
		this_non_prologue_insn = 1;
	      break;

	    default:
	      /* The instruction in the delay slot can be a part
		 of the prologue, so move forward once more.  */
	      if (micromips_instruction_has_delay_slot (insn, 0))
		in_delay_slot = 1;
	      else
		this_non_prologue_insn = 1;
	      break;
	    }
	  insn >>= 16;
	  break;

	/* 16-bit instructions.  */
	case MIPS_INSN16_SIZE:
	  switch (micromips_op (insn))
	    {
	    case 0x3: /* MOVE: bits 000011 */
	      sreg = b0s5_reg (insn);
	      dreg = b5s5_reg (insn);
	      if (sreg == MIPS_SP_REGNUM && dreg == 30)
				/* MOVE  $fp, $sp */
		frame_reg = 30;
	      else if ((sreg & 0x1c) != 0x4)
				/* MOVE  reg, $a0-$a3 */
		this_non_prologue_insn = 1;
	      break;

	    case 0x11: /* POOL16C: bits 010001 */
	      if (b6s4_op (insn) == 0x5)
				/* SWM: bits 010001 0101 */
		{
		  offset = ((b0s4_imm (insn) << 2) ^ 0x20) - 0x20;
		  reglist = b4s2_regl (insn);
		  for (i = 0; i <= reglist; i++)
		    set_reg_offset (gdbarch, this_cache, 16 + i, sp + 4 * i);
		  set_reg_offset (gdbarch, this_cache,
				  MIPS_RA_REGNUM, sp + 4 * i++);
		}
	      else
		this_non_prologue_insn = 1;
	      break;

	    case 0x13: /* POOL16D: bits 010011 */
	      if ((insn & 0x1) == 0x1)
				/* ADDIUSP: bits 010011 1 */
		sp_adj = micromips_decode_imm9 (b1s9_imm (insn));
	      else if (b5s5_reg (insn) == MIPS_SP_REGNUM)
				/* ADDIUS5: bits 010011 0 */
				/* ADDIUS5 $sp, imm */
		sp_adj = (b1s4_imm (insn) ^ 8) - 8;
	      else
		this_non_prologue_insn = 1;
	      break;

	    case 0x32: /* SWSP: bits 110010 */
	      offset = b0s5_imm (insn) << 2;
	      sreg = b5s5_reg (insn);
	      set_reg_offset (gdbarch, this_cache, sreg, sp + offset);
	      break;

	    default:
	      /* The instruction in the delay slot can be a part
		 of the prologue, so move forward once more.  */
	      if (micromips_instruction_has_delay_slot (insn << 16, 0))
		in_delay_slot = 1;
	      else
		this_non_prologue_insn = 1;
	      break;
	    }
	  break;
	}
      if (sp_adj < 0)
	frame_offset -= sp_adj;

      non_prologue_insns += this_non_prologue_insn;

      /* A jump or branch, enough non-prologue insns seen or positive
	 stack adjustment?  If so, then we must have reached the end
	 of the prologue by now.  */
      if (prev_delay_slot || non_prologue_insns > 1 || sp_adj > 0
	  || micromips_instruction_is_compact_branch (insn))
	break;

      prev_non_prologue_insn = this_non_prologue_insn;
      prev_delay_slot = in_delay_slot;
      prev_pc = cur_pc;
    }

  if (this_cache != NULL)
    {
      this_cache->base =
	(get_frame_register_signed (this_frame,
				    gdbarch_num_regs (gdbarch) + frame_reg)
	 + frame_offset - frame_adjust);
      /* FIXME: brobecker/2004-10-10: Just as in the mips32 case, we should
	 be able to get rid of the assignment below, evetually. But it's
	 still needed for now.  */
      this_cache->saved_regs[gdbarch_num_regs (gdbarch)
			     + mips_regnum (gdbarch)->pc]
	= this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM];
    }

  /* Set end_prologue_addr to the address of the instruction immediately
     after the last one we scanned.  Unless the last one looked like a
     non-prologue instruction (and we looked ahead), in which case use
     its address instead.  */
  end_prologue_addr
    = prev_non_prologue_insn || prev_delay_slot ? prev_pc : cur_pc;

  return end_prologue_addr;
}

/* Heuristic unwinder for procedures using microMIPS instructions.
   Procedures that use the 32-bit instruction set are handled by the
   mips_insn32 unwinder.  Likewise MIPS16 and the mips_insn16 unwinder. */

static struct mips_frame_cache *
mips_micro_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct mips_frame_cache *cache;

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

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

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

    find_pc_partial_function (pc, NULL, &start_addr, NULL);
    if (start_addr == 0)
      start_addr = heuristic_proc_start (get_frame_arch (this_frame), pc);
    /* We can't analyze the prologue if we couldn't find the begining
       of the function.  */
    if (start_addr == 0)
      return cache;

    micromips_scan_prologue (gdbarch, start_addr, pc, this_frame,
			     (struct mips_frame_cache *) *this_cache);
  }

  /* gdbarch_sp_regnum contains the value and not the address.  */
  cache->saved_regs[gdbarch_num_regs (gdbarch)
		    + MIPS_SP_REGNUM].set_value (cache->base);

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

static void
mips_micro_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
			  struct frame_id *this_id)
{
  struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
							  this_cache);
  /* This marks the outermost frame.  */
  if (info->base == 0)
    return;
  (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
}

static struct value *
mips_micro_frame_prev_register (const frame_info_ptr &this_frame,
				void **this_cache, int regnum)
{
  struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
							  this_cache);
  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}

static int
mips_micro_frame_sniffer (const struct frame_unwind *self,
			  const frame_info_ptr &this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);

  if (mips_pc_is_micromips (gdbarch, pc))
    return 1;
  return 0;
}

static const struct frame_unwind mips_micro_frame_unwind =
{
  "mips micro prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  mips_micro_frame_this_id,
  mips_micro_frame_prev_register,
  NULL,
  mips_micro_frame_sniffer
};

static CORE_ADDR
mips_micro_frame_base_address (const frame_info_ptr &this_frame,
			       void **this_cache)
{
  struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
							  this_cache);
  return info->base;
}

static const struct frame_base mips_micro_frame_base =
{
  &mips_micro_frame_unwind,
  mips_micro_frame_base_address,
  mips_micro_frame_base_address,
  mips_micro_frame_base_address
};

static const struct frame_base *
mips_micro_frame_base_sniffer (const frame_info_ptr &this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);

  if (mips_pc_is_micromips (gdbarch, pc))
    return &mips_micro_frame_base;
  else
    return NULL;
}

/* Mark all the registers as unset in the saved_regs array
   of THIS_CACHE.  Do nothing if THIS_CACHE is null.  */

static void
reset_saved_regs (struct gdbarch *gdbarch, struct mips_frame_cache *this_cache)
{
  if (this_cache == NULL || this_cache->saved_regs == NULL)
    return;

  {
    const int num_regs = gdbarch_num_regs (gdbarch);
    int i;

    /* Reset the register values to their default state.  Register i's value
       is in register i.  */
    for (i = 0; i < num_regs; i++)
      this_cache->saved_regs[i].set_realreg (i);
  }
}

/* Analyze the function prologue from START_PC to LIMIT_PC.  Builds
   the associated FRAME_CACHE if not null.  
   Return the address of the first instruction past the prologue.  */

static CORE_ADDR
mips32_scan_prologue (struct gdbarch *gdbarch,
		      CORE_ADDR start_pc, CORE_ADDR limit_pc,
		      const frame_info_ptr &this_frame,
		      struct mips_frame_cache *this_cache)
{
  int prev_non_prologue_insn;
  int this_non_prologue_insn;
  int non_prologue_insns;
  CORE_ADDR frame_addr = 0; /* Value of $r30. Used by gcc for
			       frame-pointer.  */
  int prev_delay_slot;
  CORE_ADDR prev_pc;
  CORE_ADDR cur_pc;
  CORE_ADDR sp;
  long frame_offset;
  int  frame_reg = MIPS_SP_REGNUM;

  CORE_ADDR end_prologue_addr;
  int seen_sp_adjust = 0;
  int load_immediate_bytes = 0;
  int in_delay_slot;
  int regsize_is_64_bits = (mips_abi_regsize (gdbarch) == 8);

  /* Can be called when there's no process, and hence when there's no
     THIS_FRAME.  */
  if (this_frame != NULL)
    sp = get_frame_register_signed (this_frame,
				    gdbarch_num_regs (gdbarch)
				    + MIPS_SP_REGNUM);
  else
    sp = 0;

  if (limit_pc > start_pc + 200)
    limit_pc = start_pc + 200;

restart:
  prev_non_prologue_insn = 0;
  non_prologue_insns = 0;
  prev_delay_slot = 0;
  prev_pc = start_pc;

  /* Permit at most one non-prologue non-control-transfer instruction
     in the middle which may have been reordered by the compiler for
     optimisation.  */
  frame_offset = 0;
  for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN32_SIZE)
    {
      unsigned long inst, high_word;
      long offset;
      int reg;

      this_non_prologue_insn = 0;
      in_delay_slot = 0;

      /* Fetch the instruction.  */
      inst = (unsigned long) mips_fetch_instruction (gdbarch, ISA_MIPS,
						     cur_pc, NULL);

      /* Save some code by pre-extracting some useful fields.  */
      high_word = (inst >> 16) & 0xffff;
      offset = ((inst & 0xffff) ^ 0x8000) - 0x8000;
      reg = high_word & 0x1f;

      if (high_word == 0x27bd		/* addiu $sp,$sp,-i */
	  || high_word == 0x23bd	/* addi $sp,$sp,-i */
	  || high_word == 0x67bd)	/* daddiu $sp,$sp,-i */
	{
	  if (offset < 0)		/* Negative stack adjustment?  */
	    frame_offset -= offset;
	  else
	    /* Exit loop if a positive stack adjustment is found, which
	       usually means that the stack cleanup code in the function
	       epilogue is reached.  */
	    break;
	  seen_sp_adjust = 1;
	}
      else if (((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */
	       && !regsize_is_64_bits)
	{
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	}
      else if (((high_word & 0xFFE0) == 0xffa0)	/* sd reg,offset($sp) */
	       && regsize_is_64_bits)
	{
	  /* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra.  */
	  set_reg_offset (gdbarch, this_cache, reg, sp + offset);
	}
      else if (high_word == 0x27be)	/* addiu $30,$sp,size */
	{
	  /* Old gcc frame, r30 is virtual frame pointer.  */
	  if (offset != frame_offset)
	    frame_addr = sp + offset;
	  else if (this_frame && frame_reg == MIPS_SP_REGNUM)
	    {
	      unsigned alloca_adjust;

	      frame_reg = 30;
	      frame_addr = get_frame_register_signed
		(this_frame, gdbarch_num_regs (gdbarch) + 30);
	      frame_offset = 0;

	      alloca_adjust = (unsigned) (frame_addr - (sp + offset));
	      if (alloca_adjust > 0)
		{
		  /* FP > SP + frame_size.  This may be because of
		     an alloca or somethings similar.  Fix sp to
		     "pre-alloca" value, and try again.  */
		  sp += alloca_adjust;
		  /* Need to reset the status of all registers.  Otherwise,
		     we will hit a guard that prevents the new address
		     for each register to be recomputed during the second
		     pass.  */
		  reset_saved_regs (gdbarch, this_cache);
		  goto restart;
		}
	    }
	}
      /* move $30,$sp.  With different versions of gas this will be either
	 `addu $30,$sp,$zero' or `or $30,$sp,$zero' or `daddu 30,sp,$0'.
	 Accept any one of these.  */
      else if (inst == 0x03A0F021 || inst == 0x03a0f025 || inst == 0x03a0f02d)
	{
	  /* New gcc frame, virtual frame pointer is at r30 + frame_size.  */
	  if (this_frame && frame_reg == MIPS_SP_REGNUM)
	    {
	      unsigned alloca_adjust;

	      frame_reg = 30;
	      frame_addr = get_frame_register_signed
		(this_frame, gdbarch_num_regs (gdbarch) + 30);

	      alloca_adjust = (unsigned) (frame_addr - sp);
	      if (alloca_adjust > 0)
		{
		  /* FP > SP + frame_size.  This may be because of
		     an alloca or somethings similar.  Fix sp to
		     "pre-alloca" value, and try again.  */
		  sp = frame_addr;
		  /* Need to reset the status of all registers.  Otherwise,
		     we will hit a guard that prevents the new address
		     for each register to be recomputed during the second
		     pass.  */
		  reset_saved_regs (gdbarch, this_cache);
		  goto restart;
		}
	    }
	}
      else if ((high_word & 0xFFE0) == 0xafc0 	/* sw reg,offset($30) */
	       && !regsize_is_64_bits)
	{
	  set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset);
	}
      else if ((high_word & 0xFFE0) == 0xE7A0 /* swc1 freg,n($sp) */
	       || (high_word & 0xF3E0) == 0xA3C0 /* sx reg,n($s8) */
	       || (inst & 0xFF9F07FF) == 0x00800021 /* move reg,$a0-$a3 */
	       || high_word == 0x3c1c /* lui $gp,n */
	       || high_word == 0x279c /* addiu $gp,$gp,n */
	       || high_word == 0x679c /* daddiu $gp,$gp,n */
	       || inst == 0x0399e021 /* addu $gp,$gp,$t9 */
	       || inst == 0x033ce021 /* addu $gp,$t9,$gp */
	       || inst == 0x0399e02d /* daddu $gp,$gp,$t9 */
	       || inst == 0x033ce02d /* daddu $gp,$t9,$gp */
	      )
	{
	  /* These instructions are part of the prologue, but we don't
	     need to do anything special to handle them.  */
	}
      /* The instructions below load $at or $t0 with an immediate
	 value in preparation for a stack adjustment via
	 subu $sp,$sp,[$at,$t0].  These instructions could also
	 initialize a local variable, so we accept them only before
	 a stack adjustment instruction was seen.  */
      else if (!seen_sp_adjust
	       && !prev_delay_slot
	       && (high_word == 0x3c01 /* lui $at,n */
		   || high_word == 0x3c08 /* lui $t0,n */
		   || high_word == 0x3421 /* ori $at,$at,n */
		   || high_word == 0x3508 /* ori $t0,$t0,n */
		   || high_word == 0x3401 /* ori $at,$zero,n */
		   || high_word == 0x3408 /* ori $t0,$zero,n */
		  ))
	{
	  load_immediate_bytes += MIPS_INSN32_SIZE;		/* FIXME!  */
	}
      /* Check for branches and jumps.  The instruction in the delay
	 slot can be a part of the prologue, so move forward once more.  */
      else if (mips32_instruction_has_delay_slot (gdbarch, inst))
	{
	  in_delay_slot = 1;
	}
      /* This instruction is not an instruction typically found
	 in a prologue, so we must have reached the end of the
	 prologue.  */
      else
	{
	  this_non_prologue_insn = 1;
	}

      non_prologue_insns += this_non_prologue_insn;

      /* A jump or branch, or enough non-prologue insns seen?  If so,
	 then we must have reached the end of the prologue by now.  */
      if (prev_delay_slot || non_prologue_insns > 1)
	break;

      prev_non_prologue_insn = this_non_prologue_insn;
      prev_delay_slot = in_delay_slot;
      prev_pc = cur_pc;
    }

  if (this_cache != NULL)
    {
      this_cache->base = 
	(get_frame_register_signed (this_frame,
				    gdbarch_num_regs (gdbarch) + frame_reg)
	 + frame_offset);
      /* FIXME: brobecker/2004-09-15: We should be able to get rid of
	 this assignment below, eventually.  But it's still needed
	 for now.  */
      this_cache->saved_regs[gdbarch_num_regs (gdbarch)
			     + mips_regnum (gdbarch)->pc]
	= this_cache->saved_regs[gdbarch_num_regs (gdbarch)
				 + MIPS_RA_REGNUM];
    }

  /* Set end_prologue_addr to the address of the instruction immediately
     after the last one we scanned.  Unless the last one looked like a
     non-prologue instruction (and we looked ahead), in which case use
     its address instead.  */
  end_prologue_addr
    = prev_non_prologue_insn || prev_delay_slot ? prev_pc : cur_pc;
     
  /* In a frameless function, we might have incorrectly
     skipped some load immediate instructions.  Undo the skipping
     if the load immediate was not followed by a stack adjustment.  */
  if (load_immediate_bytes && !seen_sp_adjust)
    end_prologue_addr -= load_immediate_bytes;

  return end_prologue_addr;
}

/* Heuristic unwinder for procedures using 32-bit instructions (covers
   both 32-bit and 64-bit MIPS ISAs).  Procedures using 16-bit
   instructions (a.k.a. MIPS16) are handled by the mips_insn16
   unwinder.  Likewise microMIPS and the mips_micro unwinder. */

static struct mips_frame_cache *
mips_insn32_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct mips_frame_cache *cache;

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

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

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

    find_pc_partial_function (pc, NULL, &start_addr, NULL);
    if (start_addr == 0)
      start_addr = heuristic_proc_start (gdbarch, pc);
    /* We can't analyze the prologue if we couldn't find the begining
       of the function.  */
    if (start_addr == 0)
      return cache;

    mips32_scan_prologue (gdbarch, start_addr, pc, this_frame,
			  (struct mips_frame_cache *) *this_cache);
  }
  
  /* gdbarch_sp_regnum contains the value and not the address.  */
  cache->saved_regs[gdbarch_num_regs (gdbarch)
		    + MIPS_SP_REGNUM].set_value (cache->base);

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

static void
mips_insn32_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
			   struct frame_id *this_id)
{
  struct mips_frame_cache *info = mips_insn32_frame_cache (this_frame,
							   this_cache);
  /* This marks the outermost frame.  */
  if (info->base == 0)
    return;
  (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
}

static struct value *
mips_insn32_frame_prev_register (const frame_info_ptr &this_frame,
				 void **this_cache, int regnum)
{
  struct mips_frame_cache *info = mips_insn32_frame_cache (this_frame,
							   this_cache);
  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}

static int
mips_insn32_frame_sniffer (const struct frame_unwind *self,
			   const frame_info_ptr &this_frame, void **this_cache)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  if (mips_pc_is_mips (pc))
    return 1;
  return 0;
}

static const struct frame_unwind mips_insn32_frame_unwind =
{
  "mips insn32 prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  mips_insn32_frame_this_id,
  mips_insn32_frame_prev_register,
  NULL,
  mips_insn32_frame_sniffer
};

static CORE_ADDR
mips_insn32_frame_base_address (const frame_info_ptr &this_frame,
				void **this_cache)
{
  struct mips_frame_cache *info = mips_insn32_frame_cache (this_frame,
							   this_cache);
  return info->base;
}

static const struct frame_base mips_insn32_frame_base =
{
  &mips_insn32_frame_unwind,
  mips_insn32_frame_base_address,
  mips_insn32_frame_base_address,
  mips_insn32_frame_base_address
};

static const struct frame_base *
mips_insn32_frame_base_sniffer (const frame_info_ptr &this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  if (mips_pc_is_mips (pc))
    return &mips_insn32_frame_base;
  else
    return NULL;
}

static struct trad_frame_cache *
mips_stub_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  CORE_ADDR pc;
  CORE_ADDR start_addr;
  CORE_ADDR stack_addr;
  struct trad_frame_cache *this_trad_cache;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  int num_regs = gdbarch_num_regs (gdbarch);

  if ((*this_cache) != NULL)
    return (struct trad_frame_cache *) (*this_cache);
  this_trad_cache = trad_frame_cache_zalloc (this_frame);
  (*this_cache) = this_trad_cache;

  /* The return address is in the link register.  */
  trad_frame_set_reg_realreg (this_trad_cache,
			      gdbarch_pc_regnum (gdbarch),
			      num_regs + MIPS_RA_REGNUM);

  /* Frame ID, since it's a frameless / stackless function, no stack
     space is allocated and SP on entry is the current SP.  */
  pc = get_frame_pc (this_frame);
  find_pc_partial_function (pc, NULL, &start_addr, NULL);
  stack_addr = get_frame_register_signed (this_frame,
					  num_regs + MIPS_SP_REGNUM);
  trad_frame_set_id (this_trad_cache, frame_id_build (stack_addr, start_addr));

  /* Assume that the frame's base is the same as the
     stack-pointer.  */
  trad_frame_set_this_base (this_trad_cache, stack_addr);

  return this_trad_cache;
}

static void
mips_stub_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
			 struct frame_id *this_id)
{
  struct trad_frame_cache *this_trad_cache
    = mips_stub_frame_cache (this_frame, this_cache);
  trad_frame_get_id (this_trad_cache, this_id);
}

static struct value *
mips_stub_frame_prev_register (const frame_info_ptr &this_frame,
			       void **this_cache, int regnum)
{
  struct trad_frame_cache *this_trad_cache
    = mips_stub_frame_cache (this_frame, this_cache);
  return trad_frame_get_register (this_trad_cache, this_frame, regnum);
}

static int
mips_stub_frame_sniffer (const struct frame_unwind *self,
			 const frame_info_ptr &this_frame, void **this_cache)
{
  gdb_byte dummy[4];
  CORE_ADDR pc = get_frame_address_in_block (this_frame);
  struct bound_minimal_symbol msym;

  /* Use the stub unwinder for unreadable code.  */
  if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
    return 1;

  if (in_plt_section (pc) || in_mips_stubs_section (pc))
    return 1;

  /* Calling a PIC function from a non-PIC function passes through a
     stub.  The stub for foo is named ".pic.foo".  */
  msym = lookup_minimal_symbol_by_pc (pc);
  if (msym.minsym != NULL
      && msym.minsym->linkage_name () != NULL
      && startswith (msym.minsym->linkage_name (), ".pic."))
    return 1;

  return 0;
}

static const struct frame_unwind mips_stub_frame_unwind =
{
  "mips stub",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  mips_stub_frame_this_id,
  mips_stub_frame_prev_register,
  NULL,
  mips_stub_frame_sniffer
};

static CORE_ADDR
mips_stub_frame_base_address (const frame_info_ptr &this_frame,
			      void **this_cache)
{
  struct trad_frame_cache *this_trad_cache
    = mips_stub_frame_cache (this_frame, this_cache);
  return trad_frame_get_this_base (this_trad_cache);
}

static const struct frame_base mips_stub_frame_base =
{
  &mips_stub_frame_unwind,
  mips_stub_frame_base_address,
  mips_stub_frame_base_address,
  mips_stub_frame_base_address
};

static const struct frame_base *
mips_stub_frame_base_sniffer (const frame_info_ptr &this_frame)
{
  if (mips_stub_frame_sniffer (&mips_stub_frame_unwind, this_frame, NULL))
    return &mips_stub_frame_base;
  else
    return NULL;
}

/* mips_addr_bits_remove - remove useless address bits  */

static CORE_ADDR
mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

  if (mips_mask_address_p (tdep) && (((ULONGEST) addr) >> 32 == 0xffffffffUL))
    /* This hack is a work-around for existing boards using PMON, the
       simulator, and any other 64-bit targets that doesn't have true
       64-bit addressing.  On these targets, the upper 32 bits of
       addresses are ignored by the hardware.  Thus, the PC or SP are
       likely to have been sign extended to all 1s by instruction
       sequences that load 32-bit addresses.  For example, a typical
       piece of code that loads an address is this:

       lui $r2, <upper 16 bits>
       ori $r2, <lower 16 bits>

       But the lui sign-extends the value such that the upper 32 bits
       may be all 1s.  The workaround is simply to mask off these
       bits.  In the future, gcc may be changed to support true 64-bit
       addressing, and this masking will have to be disabled.  */
    return addr &= 0xffffffffUL;
  else
    return addr;
}


/* Checks for an atomic sequence of instructions beginning with a LL/LLD
   instruction and ending with a SC/SCD instruction.  If such a sequence
   is found, attempt to step through it.  A breakpoint is placed at the end of 
   the sequence.  */

/* Instructions used during single-stepping of atomic sequences, standard
   ISA version.  */
#define LL_OPCODE 0x30
#define LLD_OPCODE 0x34
#define SC_OPCODE 0x38
#define SCD_OPCODE 0x3c

static std::vector<CORE_ADDR>
mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX};
  CORE_ADDR loc = pc;
  CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination.  */
  ULONGEST insn;
  int insn_count;
  int index;
  int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */  
  const int atomic_sequence_length = 16; /* Instruction sequence length.  */

  insn = mips_fetch_instruction (gdbarch, ISA_MIPS, loc, NULL);
  /* Assume all atomic sequences start with a ll/lld instruction.  */
  if (itype_op (insn) != LL_OPCODE && itype_op (insn) != LLD_OPCODE)
    return {};

  /* Assume that no atomic sequence is longer than "atomic_sequence_length" 
     instructions.  */
  for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
    {
      int is_branch = 0;
      loc += MIPS_INSN32_SIZE;
      insn = mips_fetch_instruction (gdbarch, ISA_MIPS, loc, NULL);

      /* Assume that there is at most one branch in the atomic
	 sequence.  If a branch is found, put a breakpoint in its
	 destination address.  */
      switch (itype_op (insn))
	{
	case 0: /* SPECIAL */
	  if (rtype_funct (insn) >> 1 == 4) /* JR, JALR */
	    return {}; /* fallback to the standard single-step code.  */
	  break;
	case 1: /* REGIMM */
	  is_branch = ((itype_rt (insn) & 0xc) == 0 /* B{LT,GE}Z* */
		       || ((itype_rt (insn) & 0x1e) == 0
			   && itype_rs (insn) == 0)); /* BPOSGE* */
	  break;
	case 2: /* J */
	case 3: /* JAL */
	  return {}; /* fallback to the standard single-step code.  */
	case 4: /* BEQ */
	case 5: /* BNE */
	case 6: /* BLEZ */
	case 7: /* BGTZ */
	case 20: /* BEQL */
	case 21: /* BNEL */
	case 22: /* BLEZL */
	case 23: /* BGTTL */
	  is_branch = 1;
	  break;
	case 17: /* COP1 */
	  is_branch = ((itype_rs (insn) == 9 || itype_rs (insn) == 10)
		       && (itype_rt (insn) & 0x2) == 0);
	  if (is_branch) /* BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T */
	    break;
	  [[fallthrough]];
	case 18: /* COP2 */
	case 19: /* COP3 */
	  is_branch = (itype_rs (insn) == 8); /* BCzF, BCzFL, BCzT, BCzTL */
	  break;
	}
      if (is_branch)
	{
	  branch_bp = loc + mips32_relative_offset (insn) + 4;
	  if (last_breakpoint >= 1)
	    return {}; /* More than one branch found, fallback to the
			  standard single-step code.  */
	  breaks[1] = branch_bp;
	  last_breakpoint++;
	}

      if (itype_op (insn) == SC_OPCODE || itype_op (insn) == SCD_OPCODE)
	break;
    }

  /* Assume that the atomic sequence ends with a sc/scd instruction.  */
  if (itype_op (insn) != SC_OPCODE && itype_op (insn) != SCD_OPCODE)
    return {};

  loc += MIPS_INSN32_SIZE;

  /* Insert a breakpoint right after the end of the atomic sequence.  */
  breaks[0] = loc;

  /* Check for duplicated breakpoints.  Check also for a breakpoint
     placed (branch instruction's destination) in the atomic sequence.  */
  if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
    last_breakpoint = 0;

  std::vector<CORE_ADDR> next_pcs;

  /* Effectively inserts the breakpoints.  */
  for (index = 0; index <= last_breakpoint; index++)
    next_pcs.push_back (breaks[index]);

  return next_pcs;
}

static std::vector<CORE_ADDR>
micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
				     CORE_ADDR pc)
{
  const int atomic_sequence_length = 16; /* Instruction sequence length.  */
  int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */
  CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX};
  CORE_ADDR branch_bp = 0; /* Breakpoint at branch instruction's
			      destination.  */
  CORE_ADDR loc = pc;
  int sc_found = 0;
  ULONGEST insn;
  int insn_count;
  int index;

  /* Assume all atomic sequences start with a ll/lld instruction.  */
  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
  if (micromips_op (insn) != 0x18)	/* POOL32C: bits 011000 */
    return {};
  loc += MIPS_INSN16_SIZE;
  insn <<= 16;
  insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
  if ((b12s4_op (insn) & 0xb) != 0x3)	/* LL, LLD: bits 011000 0x11 */
    return {};
  loc += MIPS_INSN16_SIZE;

  /* Assume all atomic sequences end with an sc/scd instruction.  Assume
     that no atomic sequence is longer than "atomic_sequence_length"
     instructions.  */
  for (insn_count = 0;
       !sc_found && insn_count < atomic_sequence_length;
       ++insn_count)
    {
      int is_branch = 0;

      insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
      loc += MIPS_INSN16_SIZE;

      /* Assume that there is at most one conditional branch in the
	 atomic sequence.  If a branch is found, put a breakpoint in
	 its destination address.  */
      switch (mips_insn_size (ISA_MICROMIPS, insn))
	{
	/* 32-bit instructions.  */
	case 2 * MIPS_INSN16_SIZE:
	  switch (micromips_op (insn))
	    {
	    case 0x10: /* POOL32I: bits 010000 */
	      if ((b5s5_op (insn) & 0x18) != 0x0
				/* BLTZ, BLTZAL, BGEZ, BGEZAL: 010000 000xx */
				/* BLEZ, BNEZC, BGTZ, BEQZC: 010000 001xx */
		  && (b5s5_op (insn) & 0x1d) != 0x11
				/* BLTZALS, BGEZALS: bits 010000 100x1 */
		  && ((b5s5_op (insn) & 0x1e) != 0x14
		      || (insn & 0x3) != 0x0)
				/* BC2F, BC2T: bits 010000 1010x xxx00 */
		  && (b5s5_op (insn) & 0x1e) != 0x1a
				/* BPOSGE64, BPOSGE32: bits 010000 1101x */
		  && ((b5s5_op (insn) & 0x1e) != 0x1c
		      || (insn & 0x3) != 0x0)
				/* BC1F, BC1T: bits 010000 1110x xxx00 */
		  && ((b5s5_op (insn) & 0x1c) != 0x1c
		      || (insn & 0x3) != 0x1))
				/* BC1ANY*: bits 010000 111xx xxx01 */
		break;
	      [[fallthrough]];

	    case 0x25: /* BEQ: bits 100101 */
	    case 0x2d: /* BNE: bits 101101 */
	      insn <<= 16;
	      insn |= mips_fetch_instruction (gdbarch,
					      ISA_MICROMIPS, loc, NULL);
	      branch_bp = (loc + MIPS_INSN16_SIZE
			   + micromips_relative_offset16 (insn));
	      is_branch = 1;
	      break;

	    case 0x00: /* POOL32A: bits 000000 */
	      insn <<= 16;
	      insn |= mips_fetch_instruction (gdbarch,
					      ISA_MICROMIPS, loc, NULL);
	      if (b0s6_op (insn) != 0x3c
				/* POOL32Axf: bits 000000 ... 111100 */
		  || (b6s10_ext (insn) & 0x2bf) != 0x3c)
				/* JALR, JALR.HB: 000000 000x111100 111100 */
				/* JALRS, JALRS.HB: 000000 010x111100 111100 */
		break;
	      [[fallthrough]];

	    case 0x1d: /* JALS: bits 011101 */
	    case 0x35: /* J: bits 110101 */
	    case 0x3d: /* JAL: bits 111101 */
	    case 0x3c: /* JALX: bits 111100 */
	      return {}; /* Fall back to the standard single-step code. */

	    case 0x18: /* POOL32C: bits 011000 */
	      if ((b12s4_op (insn) & 0xb) == 0xb)
				/* SC, SCD: bits 011000 1x11 */
		sc_found = 1;
	      break;
	    }
	  loc += MIPS_INSN16_SIZE;
	  break;

	/* 16-bit instructions.  */
	case MIPS_INSN16_SIZE:
	  switch (micromips_op (insn))
	    {
	    case 0x23: /* BEQZ16: bits 100011 */
	    case 0x2b: /* BNEZ16: bits 101011 */
	      branch_bp = loc + micromips_relative_offset7 (insn);
	      is_branch = 1;
	      break;

	    case 0x11: /* POOL16C: bits 010001 */
	      if ((b5s5_op (insn) & 0x1c) != 0xc
				/* JR16, JRC, JALR16, JALRS16: 010001 011xx */
		  && b5s5_op (insn) != 0x18)
				/* JRADDIUSP: bits 010001 11000 */
		break;
	      return {}; /* Fall back to the standard single-step code. */

	    case 0x33: /* B16: bits 110011 */
	      return {}; /* Fall back to the standard single-step code. */
	    }
	  break;
	}
      if (is_branch)
	{
	  if (last_breakpoint >= 1)
	    return {}; /* More than one branch found, fallback to the
			  standard single-step code.  */
	  breaks[1] = branch_bp;
	  last_breakpoint++;
	}
    }
  if (!sc_found)
    return {};

  /* Insert a breakpoint right after the end of the atomic sequence.  */
  breaks[0] = loc;

  /* Check for duplicated breakpoints.  Check also for a breakpoint
     placed (branch instruction's destination) in the atomic sequence */
  if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
    last_breakpoint = 0;

  std::vector<CORE_ADDR> next_pcs;

  /* Effectively inserts the breakpoints.  */
  for (index = 0; index <= last_breakpoint; index++)
    next_pcs.push_back (breaks[index]);

  return next_pcs;
}

static std::vector<CORE_ADDR>
deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  if (mips_pc_is_mips (pc))
    return mips_deal_with_atomic_sequence (gdbarch, pc);
  else if (mips_pc_is_micromips (gdbarch, pc))
    return micromips_deal_with_atomic_sequence (gdbarch, pc);
  else
    return {};
}

/* mips_software_single_step() is called just before we want to resume
   the inferior, if we want to single-step it but there is no hardware
   or kernel single-step support (MIPS on GNU/Linux for example).  We find
   the target of the coming instruction and breakpoint it.  */

std::vector<CORE_ADDR>
mips_software_single_step (struct regcache *regcache)
{
  struct gdbarch *gdbarch = regcache->arch ();
  CORE_ADDR pc, next_pc;

  pc = regcache_read_pc (regcache);
  std::vector<CORE_ADDR> next_pcs = deal_with_atomic_sequence (gdbarch, pc);

  if (!next_pcs.empty ())
    return next_pcs;

  next_pc = mips_next_pc (regcache, pc);

  return {next_pc};
}

/* Test whether the PC points to the return instruction at the
   end of a function.  */

static int
mips_about_to_return (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  ULONGEST insn;
  ULONGEST hint;

  /* This used to check for MIPS16, but this piece of code is never
     called for MIPS16 functions.  And likewise microMIPS ones.  */
  gdb_assert (mips_pc_is_mips (pc));

  insn = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
  hint = 0x7c0;
  return (insn & ~hint) == 0x3e00008;			/* jr(.hb) $ra */
}


/* This fencepost looks highly suspicious to me.  Removing it also
   seems suspicious as it could affect remote debugging across serial
   lines.  */

static CORE_ADDR
heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR start_pc;
  CORE_ADDR fence;
  int instlen;
  int seen_adjsp = 0;
  struct inferior *inf;

  pc = gdbarch_addr_bits_remove (gdbarch, pc);
  start_pc = pc;
  fence = start_pc - heuristic_fence_post;
  if (start_pc == 0)
    return 0;

  if (heuristic_fence_post == -1 || fence < VM_MIN_ADDRESS)
    fence = VM_MIN_ADDRESS;

  instlen = mips_pc_is_mips (pc) ? MIPS_INSN32_SIZE : MIPS_INSN16_SIZE;

  inf = current_inferior ();

  /* Search back for previous return.  */
  for (start_pc -= instlen;; start_pc -= instlen)
    if (start_pc < fence)
      {
	/* It's not clear to me why we reach this point when
	   stop_soon, but with this test, at least we
	   don't print out warnings for every child forked (eg, on
	   decstation).  22apr93 rich@cygnus.com.  */
	if (inf->control.stop_soon == NO_STOP_QUIETLY)
	  {
	    static int blurb_printed = 0;

	    warning (_("GDB can't find the start of the function at %s."),
		     paddress (gdbarch, pc));

	    if (!blurb_printed)
	      {
		/* This actually happens frequently in embedded
		   development, when you first connect to a board
		   and your stack pointer and pc are nowhere in
		   particular.  This message needs to give people
		   in that situation enough information to
		   determine that it's no big deal.  */
		gdb_printf ("\n\
    GDB is unable to find the start of the function at %s\n\
and thus can't determine the size of that function's stack frame.\n\
This means that GDB may be unable to access that stack frame, or\n\
the frames below it.\n\
    This problem is most likely caused by an invalid program counter or\n\
stack pointer.\n\
    However, if you think GDB should simply search farther back\n\
from %s for code which looks like the beginning of a\n\
function, you can increase the range of the search using the `set\n\
heuristic-fence-post' command.\n",
			    paddress (gdbarch, pc), paddress (gdbarch, pc));
		blurb_printed = 1;
	      }
	  }

	return 0;
      }
    else if (mips_pc_is_mips16 (gdbarch, start_pc))
      {
	unsigned short inst;

	/* On MIPS16, any one of the following is likely to be the
	   start of a function:
	   extend save
	   save
	   entry
	   addiu sp,-n
	   daddiu sp,-n
	   extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n'.  */
	inst = mips_fetch_instruction (gdbarch, ISA_MIPS16, start_pc, NULL);
	if ((inst & 0xff80) == 0x6480)		/* save */
	  {
	    if (start_pc - instlen >= fence)
	      {
		inst = mips_fetch_instruction (gdbarch, ISA_MIPS16,
					       start_pc - instlen, NULL);
		if ((inst & 0xf800) == 0xf000)	/* extend */
		  start_pc -= instlen;
	      }
	    break;
	  }
	else if (((inst & 0xf81f) == 0xe809
		  && (inst & 0x700) != 0x700)	/* entry */
		 || (inst & 0xff80) == 0x6380	/* addiu sp,-n */
		 || (inst & 0xff80) == 0xfb80	/* daddiu sp,-n */
		 || ((inst & 0xf810) == 0xf010 && seen_adjsp))	/* extend -n */
	  break;
	else if ((inst & 0xff00) == 0x6300	/* addiu sp */
		 || (inst & 0xff00) == 0xfb00)	/* daddiu sp */
	  seen_adjsp = 1;
	else
	  seen_adjsp = 0;
      }
    else if (mips_pc_is_micromips (gdbarch, start_pc))
      {
	ULONGEST insn;
	int stop = 0;
	long offset;
	int dreg;
	int sreg;

	/* On microMIPS, any one of the following is likely to be the
	   start of a function:
	   ADDIUSP -imm
	   (D)ADDIU $sp, -imm
	   LUI $gp, imm  */
	insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
	switch (micromips_op (insn))
	  {
	  case 0xc: /* ADDIU: bits 001100 */
	  case 0x17: /* DADDIU: bits 010111 */
	    sreg = b0s5_reg (insn);
	    dreg = b5s5_reg (insn);
	    insn <<= 16;
	    insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS,
					    pc + MIPS_INSN16_SIZE, NULL);
	    offset = (b0s16_imm (insn) ^ 0x8000) - 0x8000;
	    if (sreg == MIPS_SP_REGNUM && dreg == MIPS_SP_REGNUM
				/* (D)ADDIU $sp, imm */
		&& offset < 0)
	      stop = 1;
	    break;

	  case 0x10: /* POOL32I: bits 010000 */
	    if (b5s5_op (insn) == 0xd
				/* LUI: bits 010000 001101 */
		&& b0s5_reg (insn >> 16) == 28)
				/* LUI $gp, imm */
	      stop = 1;
	    break;

	  case 0x13: /* POOL16D: bits 010011 */
	    if ((insn & 0x1) == 0x1)
				/* ADDIUSP: bits 010011 1 */
	      {
		offset = micromips_decode_imm9 (b1s9_imm (insn));
		if (offset < 0)
				/* ADDIUSP -imm */
		  stop = 1;
	      }
	    else
				/* ADDIUS5: bits 010011 0 */
	      {
		dreg = b5s5_reg (insn);
		offset = (b1s4_imm (insn) ^ 8) - 8;
		if (dreg == MIPS_SP_REGNUM && offset < 0)
				/* ADDIUS5  $sp, -imm */
		  stop = 1;
	      }
	    break;
	  }
	if (stop)
	  break;
      }
    else if (mips_about_to_return (gdbarch, start_pc))
      {
	/* Skip return and its delay slot.  */
	start_pc += 2 * MIPS_INSN32_SIZE;
	break;
      }

  return start_pc;
}

struct mips_objfile_private
{
  bfd_size_type size;
  char *contents;
};

/* According to the current ABI, should the type be passed in a
   floating-point register (assuming that there is space)?  When there
   is no FPU, FP are not even considered as possible candidates for
   FP registers and, consequently this returns false - forces FP
   arguments into integer registers.  */

static int
fp_register_arg_p (struct gdbarch *gdbarch, enum type_code typecode,
		   struct type *arg_type)
{
  return ((typecode == TYPE_CODE_FLT
	   || (mips_eabi (gdbarch)
	       && (typecode == TYPE_CODE_STRUCT
		   || typecode == TYPE_CODE_UNION)
	       && arg_type->num_fields () == 1
	       && check_typedef (arg_type->field (0).type ())->code ()
	       == TYPE_CODE_FLT))
	  && mips_get_fpu_type (gdbarch) != MIPS_FPU_NONE);
}

/* On o32, argument passing in GPRs depends on the alignment of the type being
   passed.  Return 1 if this type must be aligned to a doubleword boundary.  */

static int
mips_type_needs_double_align (struct type *type)
{
  enum type_code typecode = type->code ();

  if (typecode == TYPE_CODE_FLT && type->length () == 8)
    return 1;
  else if (typecode == TYPE_CODE_STRUCT)
    {
      if (type->num_fields () < 1)
	return 0;
      return mips_type_needs_double_align (type->field (0).type ());
    }
  else if (typecode == TYPE_CODE_UNION)
    {
      int i, n;

      n = type->num_fields ();
      for (i = 0; i < n; i++)
	if (mips_type_needs_double_align (type->field (i).type ()))
	  return 1;
      return 0;
    }
  return 0;
}

/* Adjust the address downward (direction of stack growth) so that it
   is correctly aligned for a new stack frame.  */
static CORE_ADDR
mips_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return align_down (addr, 16);
}

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

static CORE_ADDR
mips_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
		      CORE_ADDR funaddr, struct value **args,
		      int nargs, struct type *value_type,
		      CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
		      struct regcache *regcache)
{
  static gdb_byte nop_insn[] = { 0, 0, 0, 0 };
  CORE_ADDR nop_addr;
  CORE_ADDR bp_slot;

  /* Reserve enough room on the stack for our breakpoint instruction.  */
  bp_slot = sp - sizeof (nop_insn);

  /* Return to microMIPS mode if calling microMIPS code to avoid
     triggering an address error exception on processors that only
     support microMIPS execution.  */
  *bp_addr = (mips_pc_is_micromips (gdbarch, funaddr)
	      ? make_compact_addr (bp_slot) : bp_slot);

  /* The breakpoint layer automatically adjusts the address of
     breakpoints inserted in a branch delay slot.  With enough
     bad luck, the 4 bytes located just before our breakpoint
     instruction could look like a branch instruction, and thus
     trigger the adjustement, and break the function call entirely.
     So, we reserve those 4 bytes and write a nop instruction
     to prevent that from happening.  */
  nop_addr = bp_slot - sizeof (nop_insn);
  write_memory (nop_addr, nop_insn, sizeof (nop_insn));
  sp = mips_frame_align (gdbarch, nop_addr);

  /* Inferior resumes at the function entry point.  */
  *real_pc = funaddr;

  return sp;
}

static CORE_ADDR
mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
			   struct regcache *regcache, CORE_ADDR bp_addr,
			   int nargs, struct value **args, CORE_ADDR sp,
			   function_call_return_method return_method,
			   CORE_ADDR struct_addr)
{
  int argreg;
  int float_argreg;
  int argnum;
  int arg_space = 0;
  int stack_offset = 0;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR func_addr = find_function_addr (function, NULL);
  int abi_regsize = mips_abi_regsize (gdbarch);

  /* For shared libraries, "t9" needs to point at the function
     address.  */
  regcache_cooked_write_signed (regcache, MIPS_T9_REGNUM, func_addr);

  /* Set the return address register to point to the entry point of
     the program, where a breakpoint lies in wait.  */
  regcache_cooked_write_signed (regcache, MIPS_RA_REGNUM, bp_addr);

  /* First ensure that the stack and structure return address (if any)
     are properly aligned.  The stack has to be at least 64-bit
     aligned even on 32-bit machines, because doubles must be 64-bit
     aligned.  For n32 and n64, stack frames need to be 128-bit
     aligned, so we round to this widest known alignment.  */

  sp = align_down (sp, 16);
  struct_addr = align_down (struct_addr, 16);

  /* Now make space on the stack for the args.  We allocate more
     than necessary for EABI, because the first few arguments are
     passed in registers, but that's OK.  */
  for (argnum = 0; argnum < nargs; argnum++)
    arg_space += align_up (args[argnum]->type ()->length (),
			   abi_regsize);
  sp -= align_up (arg_space, 16);

  if (mips_debug)
    gdb_printf (gdb_stdlog,
		"mips_eabi_push_dummy_call: sp=%s allocated %ld\n",
		paddress (gdbarch, sp),
		(long) align_up (arg_space, 16));

  /* Initialize the integer and float register pointers.  */
  argreg = MIPS_A0_REGNUM;
  float_argreg = mips_fpa0_regnum (gdbarch);

  /* The struct_return pointer occupies the first parameter-passing reg.  */
  if (return_method == return_method_struct)
    {
      if (mips_debug)
	gdb_printf (gdb_stdlog,
		    "mips_eabi_push_dummy_call: "
		    "struct_return reg=%d %s\n",
		    argreg, paddress (gdbarch, struct_addr));
      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
    }

  /* Now load as many as possible of the first arguments into
     registers, and push the rest onto the stack.  Loop thru args
     from first to last.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      const gdb_byte *val;
      /* This holds the address of structures that are passed by
	 reference.  */
      gdb_byte ref_valbuf[MAX_MIPS_ABI_REGSIZE];
      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (arg->type ());
      int len = arg_type->length ();
      enum type_code typecode = arg_type->code ();

      if (mips_debug)
	gdb_printf (gdb_stdlog,
		    "mips_eabi_push_dummy_call: %d len=%d type=%d",
		    argnum + 1, len, (int) typecode);

      /* The EABI passes structures that do not fit in a register by
	 reference.  */
      if (len > abi_regsize
	  && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
	{
	  gdb_assert (abi_regsize <= ARRAY_SIZE (ref_valbuf));
	  store_unsigned_integer (ref_valbuf, abi_regsize, byte_order,
				  arg->address ());
	  typecode = TYPE_CODE_PTR;
	  len = abi_regsize;
	  val = ref_valbuf;
	  if (mips_debug)
	    gdb_printf (gdb_stdlog, " push");
	}
      else
	val = arg->contents ().data ();

      /* 32-bit ABIs always start floating point arguments in an
	 even-numbered floating point register.  Round the FP register
	 up before the check to see if there are any FP registers
	 left.  Non MIPS_EABI targets also pass the FP in the integer
	 registers so also round up normal registers.  */
      if (abi_regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type))
	{
	  if ((float_argreg & 1))
	    float_argreg++;
	}

      /* Floating point arguments passed in registers have to be
	 treated specially.  On 32-bit architectures, doubles
	 are passed in register pairs; the even register gets
	 the low word, and the odd register gets the high word.
	 On non-EABI processors, the first two floating point arguments are
	 also copied to general registers, because MIPS16 functions
	 don't use float registers for arguments.  This duplication of
	 arguments in general registers can't hurt non-MIPS16 functions
	 because those registers are normally skipped.  */
      /* MIPS_EABI squeezes a struct that contains a single floating
	 point value into an FP register instead of pushing it onto the
	 stack.  */
      if (fp_register_arg_p (gdbarch, typecode, arg_type)
	  && float_argreg <= mips_last_fp_arg_regnum (gdbarch))
	{
	  /* EABI32 will pass doubles in consecutive registers, even on
	     64-bit cores.  At one time, we used to check the size of
	     `float_argreg' to determine whether or not to pass doubles
	     in consecutive registers, but this is not sufficient for
	     making the ABI determination.  */
	  if (len == 8 && mips_abi (gdbarch) == MIPS_ABI_EABI32)
	    {
	      int low_offset = gdbarch_byte_order (gdbarch)
			       == BFD_ENDIAN_BIG ? 4 : 0;
	      long regval;

	      /* Write the low word of the double to the even register(s).  */
	      regval = extract_signed_integer (val + low_offset,
					       4, byte_order);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			    float_argreg, phex (regval, 4));
	      regcache_cooked_write_signed (regcache, float_argreg++, regval);

	      /* Write the high word of the double to the odd register(s).  */
	      regval = extract_signed_integer (val + 4 - low_offset,
					       4, byte_order);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			    float_argreg, phex (regval, 4));
	      regcache_cooked_write_signed (regcache, float_argreg++, regval);
	    }
	  else
	    {
	      /* This is a floating point value that fits entirely
		 in a single register.  */
	      /* On 32 bit ABI's the float_argreg is further adjusted
		 above to ensure that it is even register aligned.  */
	      LONGEST regval = extract_signed_integer (val, len, byte_order);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			    float_argreg, phex (regval, len));
	      regcache_cooked_write_signed (regcache, float_argreg++, regval);
	    }
	}
      else
	{
	  /* Copy the argument to general registers or the stack in
	     register-sized pieces.  Large arguments are split between
	     registers and stack.  */
	  /* Note: structs whose size is not a multiple of abi_regsize
	     are treated specially: Irix cc passes
	     them in registers where gcc sometimes puts them on the
	     stack.  For maximum compatibility, we will put them in
	     both places.  */
	  int odd_sized_struct = (len > abi_regsize && len % abi_regsize != 0);

	  /* Note: Floating-point values that didn't fit into an FP
	     register are only written to memory.  */
	  while (len > 0)
	    {
	      /* Remember if the argument was written to the stack.  */
	      int stack_used_p = 0;
	      int partial_len = (len < abi_regsize ? len : abi_regsize);

	      if (mips_debug)
		gdb_printf (gdb_stdlog, " -- partial=%d",
			    partial_len);

	      /* Write this portion of the argument to the stack.  */
	      if (argreg > mips_last_arg_regnum (gdbarch)
		  || odd_sized_struct
		  || fp_register_arg_p (gdbarch, typecode, arg_type))
		{
		  /* Should shorter than int integer values be
		     promoted to int before being stored?  */
		  int longword_offset = 0;
		  CORE_ADDR addr;
		  stack_used_p = 1;
		  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
		    {
		      if (abi_regsize == 8
			  && (typecode == TYPE_CODE_INT
			      || typecode == TYPE_CODE_PTR
			      || typecode == TYPE_CODE_FLT) && len <= 4)
			longword_offset = abi_regsize - len;
		      else if ((typecode == TYPE_CODE_STRUCT
				|| typecode == TYPE_CODE_UNION)
			       && arg_type->length () < abi_regsize)
			longword_offset = abi_regsize - len;
		    }

		  if (mips_debug)
		    {
		      gdb_printf (gdb_stdlog, " - stack_offset=%s",
				  paddress (gdbarch, stack_offset));
		      gdb_printf (gdb_stdlog, " longword_offset=%s",
				  paddress (gdbarch, longword_offset));
		    }

		  addr = sp + stack_offset + longword_offset;

		  if (mips_debug)
		    {
		      int i;
		      gdb_printf (gdb_stdlog, " @%s ",
				  paddress (gdbarch, addr));
		      for (i = 0; i < partial_len; i++)
			{
			  gdb_printf (gdb_stdlog, "%02x",
				      val[i] & 0xff);
			}
		    }
		  write_memory (addr, val, partial_len);
		}

	      /* Note!!! This is NOT an else clause.  Odd sized
		 structs may go thru BOTH paths.  Floating point
		 arguments will not.  */
	      /* Write this portion of the argument to a general
		 purpose register.  */
	      if (argreg <= mips_last_arg_regnum (gdbarch)
		  && !fp_register_arg_p (gdbarch, typecode, arg_type))
		{
		  LONGEST regval =
		    extract_signed_integer (val, partial_len, byte_order);

		  if (mips_debug)
		    gdb_printf (gdb_stdlog, " - reg=%d val=%s",
				argreg,
				phex (regval, abi_regsize));
		  regcache_cooked_write_signed (regcache, argreg, regval);
		  argreg++;
		}

	      len -= partial_len;
	      val += partial_len;

	      /* Compute the offset into the stack at which we will
		 copy the next parameter.

		 In the new EABI (and the NABI32), the stack_offset
		 only needs to be adjusted when it has been used.  */

	      if (stack_used_p)
		stack_offset += align_up (partial_len, abi_regsize);
	    }
	}
      if (mips_debug)
	gdb_printf (gdb_stdlog, "\n");
    }

  regcache_cooked_write_signed (regcache, MIPS_SP_REGNUM, sp);

  /* Return adjusted stack pointer.  */
  return sp;
}

/* Determine the return value convention being used.  */

static enum return_value_convention
mips_eabi_return_value (struct gdbarch *gdbarch, struct value *function,
			struct type *type, struct regcache *regcache,
			gdb_byte *readbuf, const gdb_byte *writebuf)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
  int fp_return_type = 0;
  int offset, regnum, xfer;

  if (type->length () > 2 * mips_abi_regsize (gdbarch))
    return RETURN_VALUE_STRUCT_CONVENTION;

  /* Floating point type?  */
  if (tdep->mips_fpu_type != MIPS_FPU_NONE)
    {
      if (type->code () == TYPE_CODE_FLT)
	fp_return_type = 1;
      /* Structs with a single field of float type 
	 are returned in a floating point register.  */
      if ((type->code () == TYPE_CODE_STRUCT
	   || type->code () == TYPE_CODE_UNION)
	  && type->num_fields () == 1)
	{
	  struct type *fieldtype = type->field (0).type ();

	  if (check_typedef (fieldtype)->code () == TYPE_CODE_FLT)
	    fp_return_type = 1;
	}
    }

  if (fp_return_type)      
    {
      /* A floating-point value belongs in the least significant part
	 of FP0/FP1.  */
      if (mips_debug)
	gdb_printf (gdb_stderr, "Return float in $fp0\n");
      regnum = mips_regnum (gdbarch)->fp0;
    }
  else 
    {
      /* An integer value goes in V0/V1.  */
      if (mips_debug)
	gdb_printf (gdb_stderr, "Return scalar in $v0\n");
      regnum = MIPS_V0_REGNUM;
    }
  for (offset = 0;
       offset < type->length ();
       offset += mips_abi_regsize (gdbarch), regnum++)
    {
      xfer = mips_abi_regsize (gdbarch);
      if (offset + xfer > type->length ())
	xfer = type->length () - offset;
      mips_xfer_register (gdbarch, regcache,
			  gdbarch_num_regs (gdbarch) + regnum, xfer,
			  gdbarch_byte_order (gdbarch), readbuf, writebuf,
			  offset);
    }

  return RETURN_VALUE_REGISTER_CONVENTION;
}


/* N32/N64 ABI stuff.  */

/* Search for a naturally aligned double at OFFSET inside a struct
   ARG_TYPE.  The N32 / N64 ABIs pass these in floating point
   registers.  */

static int
mips_n32n64_fp_arg_chunk_p (struct gdbarch *gdbarch, struct type *arg_type,
			    int offset)
{
  int i;

  if (arg_type->code () != TYPE_CODE_STRUCT)
    return 0;

  if (mips_get_fpu_type (gdbarch) != MIPS_FPU_DOUBLE)
    return 0;

  if (arg_type->length () < offset + MIPS64_REGSIZE)
    return 0;

  for (i = 0; i < arg_type->num_fields (); i++)
    {
      int pos;
      struct type *field_type;

      /* We're only looking at normal fields.  */
      if (arg_type->field (i).is_static ()
	  || (arg_type->field (i).loc_bitpos () % 8) != 0)
	continue;

      /* If we have gone past the offset, there is no double to pass.  */
      pos = arg_type->field (i).loc_bitpos () / 8;
      if (pos > offset)
	return 0;

      field_type = check_typedef (arg_type->field (i).type ());

      /* If this field is entirely before the requested offset, go
	 on to the next one.  */
      if (pos + field_type->length () <= offset)
	continue;

      /* If this is our special aligned double, we can stop.  */
      if (field_type->code () == TYPE_CODE_FLT
	  && field_type->length () == MIPS64_REGSIZE)
	return 1;

      /* This field starts at or before the requested offset, and
	 overlaps it.  If it is a structure, recurse inwards.  */
      return mips_n32n64_fp_arg_chunk_p (gdbarch, field_type, offset - pos);
    }

  return 0;
}

static CORE_ADDR
mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
			     struct regcache *regcache, CORE_ADDR bp_addr,
			     int nargs, struct value **args, CORE_ADDR sp,
			     function_call_return_method return_method,
			     CORE_ADDR struct_addr)
{
  int argreg;
  int float_argreg;
  int argnum;
  int arg_space = 0;
  int stack_offset = 0;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR func_addr = find_function_addr (function, NULL);

  /* For shared libraries, "t9" needs to point at the function
     address.  */
  regcache_cooked_write_signed (regcache, MIPS_T9_REGNUM, func_addr);

  /* Set the return address register to point to the entry point of
     the program, where a breakpoint lies in wait.  */
  regcache_cooked_write_signed (regcache, MIPS_RA_REGNUM, bp_addr);

  /* First ensure that the stack and structure return address (if any)
     are properly aligned.  The stack has to be at least 64-bit
     aligned even on 32-bit machines, because doubles must be 64-bit
     aligned.  For n32 and n64, stack frames need to be 128-bit
     aligned, so we round to this widest known alignment.  */

  sp = align_down (sp, 16);
  struct_addr = align_down (struct_addr, 16);

  /* Now make space on the stack for the args.  */
  for (argnum = 0; argnum < nargs; argnum++)
    arg_space += align_up (args[argnum]->type ()->length (),
			   MIPS64_REGSIZE);
  sp -= align_up (arg_space, 16);

  if (mips_debug)
    gdb_printf (gdb_stdlog,
		"mips_n32n64_push_dummy_call: sp=%s allocated %ld\n",
		paddress (gdbarch, sp),
		(long) align_up (arg_space, 16));

  /* Initialize the integer and float register pointers.  */
  argreg = MIPS_A0_REGNUM;
  float_argreg = mips_fpa0_regnum (gdbarch);

  /* The struct_return pointer occupies the first parameter-passing reg.  */
  if (return_method == return_method_struct)
    {
      if (mips_debug)
	gdb_printf (gdb_stdlog,
		    "mips_n32n64_push_dummy_call: "
		    "struct_return reg=%d %s\n",
		    argreg, paddress (gdbarch, struct_addr));
      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
    }

  /* Now load as many as possible of the first arguments into
     registers, and push the rest onto the stack.  Loop thru args
     from first to last.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      const gdb_byte *val;
      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (arg->type ());
      int len = arg_type->length ();
      enum type_code typecode = arg_type->code ();

      if (mips_debug)
	gdb_printf (gdb_stdlog,
		    "mips_n32n64_push_dummy_call: %d len=%d type=%d",
		    argnum + 1, len, (int) typecode);

      val = arg->contents ().data ();

      /* A 128-bit long double value requires an even-odd pair of
	 floating-point registers.  */
      if (len == 16
	  && fp_register_arg_p (gdbarch, typecode, arg_type)
	  && (float_argreg & 1))
	{
	  float_argreg++;
	  argreg++;
	}

      if (fp_register_arg_p (gdbarch, typecode, arg_type)
	  && argreg <= mips_last_arg_regnum (gdbarch))
	{
	  /* This is a floating point value that fits entirely
	     in a single register or a pair of registers.  */
	  int reglen = (len <= MIPS64_REGSIZE ? len : MIPS64_REGSIZE);
	  LONGEST regval = extract_unsigned_integer (val, reglen, byte_order);
	  if (mips_debug)
	    gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			float_argreg, phex (regval, reglen));
	  regcache_cooked_write_unsigned (regcache, float_argreg, regval);

	  if (mips_debug)
	    gdb_printf (gdb_stdlog, " - reg=%d val=%s",
			argreg, phex (regval, reglen));
	  regcache_cooked_write_unsigned (regcache, argreg, regval);
	  float_argreg++;
	  argreg++;
	  if (len == 16)
	    {
	      regval = extract_unsigned_integer (val + reglen,
						 reglen, byte_order);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			    float_argreg, phex (regval, reglen));
	      regcache_cooked_write_unsigned (regcache, float_argreg, regval);

	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - reg=%d val=%s",
			    argreg, phex (regval, reglen));
	      regcache_cooked_write_unsigned (regcache, argreg, regval);
	      float_argreg++;
	      argreg++;
	    }
	}
      else
	{
	  /* Copy the argument to general registers or the stack in
	     register-sized pieces.  Large arguments are split between
	     registers and stack.  */
	  /* For N32/N64, structs, unions, or other composite types are
	     treated as a sequence of doublewords, and are passed in integer
	     or floating point registers as though they were simple scalar
	     parameters to the extent that they fit, with any excess on the
	     stack packed according to the normal memory layout of the
	     object.
	     The caller does not reserve space for the register arguments;
	     the callee is responsible for reserving it if required.  */
	  /* Note: Floating-point values that didn't fit into an FP
	     register are only written to memory.  */
	  while (len > 0)
	    {
	      /* Remember if the argument was written to the stack.  */
	      int stack_used_p = 0;
	      int partial_len = (len < MIPS64_REGSIZE ? len : MIPS64_REGSIZE);

	      if (mips_debug)
		gdb_printf (gdb_stdlog, " -- partial=%d",
			    partial_len);

	      if (fp_register_arg_p (gdbarch, typecode, arg_type))
		gdb_assert (argreg > mips_last_arg_regnum (gdbarch));

	      /* Write this portion of the argument to the stack.  */
	      if (argreg > mips_last_arg_regnum (gdbarch))
		{
		  /* Should shorter than int integer values be
		     promoted to int before being stored?  */
		  int longword_offset = 0;
		  CORE_ADDR addr;
		  stack_used_p = 1;
		  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
		    {
		      if ((typecode == TYPE_CODE_INT
			   || typecode == TYPE_CODE_PTR)
			  && len <= 4)
			longword_offset = MIPS64_REGSIZE - len;
		    }

		  if (mips_debug)
		    {
		      gdb_printf (gdb_stdlog, " - stack_offset=%s",
				  paddress (gdbarch, stack_offset));
		      gdb_printf (gdb_stdlog, " longword_offset=%s",
				  paddress (gdbarch, longword_offset));
		    }

		  addr = sp + stack_offset + longword_offset;

		  if (mips_debug)
		    {
		      int i;
		      gdb_printf (gdb_stdlog, " @%s ",
				  paddress (gdbarch, addr));
		      for (i = 0; i < partial_len; i++)
			{
			  gdb_printf (gdb_stdlog, "%02x",
				      val[i] & 0xff);
			}
		    }
		  write_memory (addr, val, partial_len);
		}

	      /* Note!!! This is NOT an else clause.  Odd sized
		 structs may go thru BOTH paths.  */
	      /* Write this portion of the argument to a general
		 purpose register.  */
	      if (argreg <= mips_last_arg_regnum (gdbarch))
		{
		  LONGEST regval;

		  /* Sign extend pointers, 32-bit integers and signed
		     16-bit and 8-bit integers; everything else is taken
		     as is.  */

		  if ((partial_len == 4
		       && (typecode == TYPE_CODE_PTR
			   || typecode == TYPE_CODE_INT))
		      || (partial_len < 4
			  && typecode == TYPE_CODE_INT
			  && !arg_type->is_unsigned ()))
		    regval = extract_signed_integer (val, partial_len,
						     byte_order);
		  else
		    regval = extract_unsigned_integer (val, partial_len,
						       byte_order);

		  /* A non-floating-point argument being passed in a
		     general register.  If a struct or union, and if
		     the remaining length is smaller than the register
		     size, we have to adjust the register value on
		     big endian targets.

		     It does not seem to be necessary to do the
		     same for integral types.  */

		  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
		      && partial_len < MIPS64_REGSIZE
		      && (typecode == TYPE_CODE_STRUCT
			  || typecode == TYPE_CODE_UNION))
		    regval <<= ((MIPS64_REGSIZE - partial_len)
				* TARGET_CHAR_BIT);

		  if (mips_debug)
		    gdb_printf (gdb_stdlog, " - reg=%d val=%s",
				argreg,
				phex (regval, MIPS64_REGSIZE));
		  regcache_cooked_write_unsigned (regcache, argreg, regval);

		  if (mips_n32n64_fp_arg_chunk_p (gdbarch, arg_type,
						  arg_type->length () - len))
		    {
		      if (mips_debug)
			gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
				    float_argreg,
				    phex (regval, MIPS64_REGSIZE));
		      regcache_cooked_write_unsigned (regcache, float_argreg,
						      regval);
		    }

		  float_argreg++;
		  argreg++;
		}

	      len -= partial_len;
	      val += partial_len;

	      /* Compute the offset into the stack at which we will
		 copy the next parameter.

		 In N32 (N64?), the stack_offset only needs to be
		 adjusted when it has been used.  */

	      if (stack_used_p)
		stack_offset += align_up (partial_len, MIPS64_REGSIZE);
	    }
	}
      if (mips_debug)
	gdb_printf (gdb_stdlog, "\n");
    }

  regcache_cooked_write_signed (regcache, MIPS_SP_REGNUM, sp);

  /* Return adjusted stack pointer.  */
  return sp;
}

static enum return_value_convention
mips_n32n64_return_value (struct gdbarch *gdbarch, struct value *function,
			  struct type *type, struct regcache *regcache,
			  gdb_byte *readbuf, const gdb_byte *writebuf)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

  /* From MIPSpro N32 ABI Handbook, Document Number: 007-2816-004

     Function results are returned in $2 (and $3 if needed), or $f0 (and $f2
     if needed), as appropriate for the type.  Composite results (struct,
     union, or array) are returned in $2/$f0 and $3/$f2 according to the
     following rules:

     * A struct with only one or two floating point fields is returned in $f0
     (and $f2 if necessary).  This is a generalization of the Fortran COMPLEX
     case.

     * Any other composite results of at most 128 bits are returned in
     $2 (first 64 bits) and $3 (remainder, if necessary).

     * Larger composite results are handled by converting the function to a
     procedure with an implicit first parameter, which is a pointer to an area
     reserved by the caller to receive the result.  [The o32-bit ABI requires
     that all composite results be handled by conversion to implicit first
     parameters.  The MIPS/SGI Fortran implementation has always made a
     specific exception to return COMPLEX results in the floating point
     registers.]

     From MIPSpro Assembly Language Programmer's Guide, Document Number:
     007-2418-004

	      Software
     Register Name(from
     Name     fgregdef.h) Use and Linkage
     -----------------------------------------------------------------
     $f0, $f2 fv0, fv1    Hold results of floating-point type function
			  ($f0) and complex type function ($f0 has the
			  real part, $f2 has the imaginary part.)  */

  if (type->length () > 2 * MIPS64_REGSIZE)
    return RETURN_VALUE_STRUCT_CONVENTION;
  else if ((type->code () == TYPE_CODE_COMPLEX
	    || (type->code () == TYPE_CODE_FLT && type->length () == 16))
	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
    {
      /* A complex value of up to 128 bits in width as well as a 128-bit
	 floating-point value goes in both $f0 and $f2.  A single complex
	 value is held in the lower halves only of the respective registers.
	 The two registers are used in the same as memory order, so the
	 bytes with the lower memory address are in $f0.  */
      if (mips_debug)
	gdb_printf (gdb_stderr, "Return float in $f0 and $f2\n");
      mips_xfer_register (gdbarch, regcache,
			  (gdbarch_num_regs (gdbarch)
			   + mips_regnum (gdbarch)->fp0),
			  type->length () / 2, gdbarch_byte_order (gdbarch),
			  readbuf, writebuf, 0);
      mips_xfer_register (gdbarch, regcache,
			  (gdbarch_num_regs (gdbarch)
			   + mips_regnum (gdbarch)->fp0 + 2),
			  type->length () / 2, gdbarch_byte_order (gdbarch),
			  readbuf ? readbuf + type->length () / 2 : readbuf,
			  (writebuf
			   ? writebuf + type->length () / 2 : writebuf), 0);
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
  else if (type->code () == TYPE_CODE_FLT
	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
    {
      /* A single or double floating-point value that fits in FP0.  */
      if (mips_debug)
	gdb_printf (gdb_stderr, "Return float in $fp0\n");
      mips_xfer_register (gdbarch, regcache,
			  (gdbarch_num_regs (gdbarch)
			   + mips_regnum (gdbarch)->fp0),
			  type->length (),
			  gdbarch_byte_order (gdbarch),
			  readbuf, writebuf, 0);
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
  else if (type->code () == TYPE_CODE_STRUCT
	   && type->num_fields () <= 2
	   && type->num_fields () >= 1
	   && ((type->num_fields () == 1
		&& (check_typedef (type->field (0).type ())->code ()
		    == TYPE_CODE_FLT))
	       || (type->num_fields () == 2
		   && (check_typedef (type->field (0).type ())->code ()
		       == TYPE_CODE_FLT)
		   && (check_typedef (type->field (1).type ())->code ()
		       == TYPE_CODE_FLT))))
    {
      /* A struct that contains one or two floats.  Each value is part
	 in the least significant part of their floating point
	 register (or GPR, for soft float).  */
      int regnum;
      int field;
      for (field = 0, regnum = (tdep->mips_fpu_type != MIPS_FPU_NONE
				? mips_regnum (gdbarch)->fp0
				: MIPS_V0_REGNUM);
	   field < type->num_fields (); field++, regnum += 2)
	{
	  int offset = type->field (field).loc_bitpos () / TARGET_CHAR_BIT;
	  if (mips_debug)
	    gdb_printf (gdb_stderr, "Return float struct+%d\n",
			offset);
	  if (type->field (field).type ()->length () == 16)
	    {
	      /* A 16-byte long double field goes in two consecutive
		 registers.  */
	      mips_xfer_register (gdbarch, regcache,
				  gdbarch_num_regs (gdbarch) + regnum,
				  8,
				  gdbarch_byte_order (gdbarch),
				  readbuf, writebuf, offset);
	      mips_xfer_register (gdbarch, regcache,
				  gdbarch_num_regs (gdbarch) + regnum + 1,
				  8,
				  gdbarch_byte_order (gdbarch),
				  readbuf, writebuf, offset + 8);
	    }
	  else
	    mips_xfer_register (gdbarch, regcache,
				gdbarch_num_regs (gdbarch) + regnum,
				type->field (field).type ()->length (),
				gdbarch_byte_order (gdbarch),
				readbuf, writebuf, offset);
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
  else if (type->code () == TYPE_CODE_STRUCT
	   || type->code () == TYPE_CODE_UNION
	   || type->code () == TYPE_CODE_ARRAY)
    {
      /* A composite type.  Extract the left justified value,
	 regardless of the byte order.  I.e. DO NOT USE
	 mips_xfer_lower.  */
      int offset;
      int regnum;
      for (offset = 0, regnum = MIPS_V0_REGNUM;
	   offset < type->length ();
	   offset += register_size (gdbarch, regnum), regnum++)
	{
	  int xfer = register_size (gdbarch, regnum);
	  if (offset + xfer > type->length ())
	    xfer = type->length () - offset;
	  if (mips_debug)
	    gdb_printf (gdb_stderr, "Return struct+%d:%d in $%d\n",
			offset, xfer, regnum);
	  mips_xfer_register (gdbarch, regcache,
			      gdbarch_num_regs (gdbarch) + regnum,
			      xfer, BFD_ENDIAN_UNKNOWN, readbuf, writebuf,
			      offset);
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
  else
    {
      /* A scalar extract each part but least-significant-byte
	 justified.  */
      int offset;
      int regnum;
      for (offset = 0, regnum = MIPS_V0_REGNUM;
	   offset < type->length ();
	   offset += register_size (gdbarch, regnum), regnum++)
	{
	  int xfer = register_size (gdbarch, regnum);
	  if (offset + xfer > type->length ())
	    xfer = type->length () - offset;
	  if (mips_debug)
	    gdb_printf (gdb_stderr, "Return scalar+%d:%d in $%d\n",
			offset, xfer, regnum);
	  mips_xfer_register (gdbarch, regcache,
			      gdbarch_num_regs (gdbarch) + regnum,
			      xfer, gdbarch_byte_order (gdbarch),
			      readbuf, writebuf, offset);
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}

/* Which registers to use for passing floating-point values between
   function calls, one of floating-point, general and both kinds of
   registers.  O32 and O64 use different register kinds for standard
   MIPS and MIPS16 code; to make the handling of cases where we may
   not know what kind of code is being used (e.g. no debug information)
   easier we sometimes use both kinds.  */

enum mips_fval_reg
{
  mips_fval_fpr,
  mips_fval_gpr,
  mips_fval_both
};

/* O32 ABI stuff.  */

static CORE_ADDR
mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
			  struct regcache *regcache, CORE_ADDR bp_addr,
			  int nargs, struct value **args, CORE_ADDR sp,
			  function_call_return_method return_method,
			  CORE_ADDR struct_addr)
{
  int argreg;
  int float_argreg;
  int argnum;
  int arg_space = 0;
  int stack_offset = 0;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR func_addr = find_function_addr (function, NULL);

  /* For shared libraries, "t9" needs to point at the function
     address.  */
  regcache_cooked_write_signed (regcache, MIPS_T9_REGNUM, func_addr);

  /* Set the return address register to point to the entry point of
     the program, where a breakpoint lies in wait.  */
  regcache_cooked_write_signed (regcache, MIPS_RA_REGNUM, bp_addr);

  /* First ensure that the stack and structure return address (if any)
     are properly aligned.  The stack has to be at least 64-bit
     aligned even on 32-bit machines, because doubles must be 64-bit
     aligned.  For n32 and n64, stack frames need to be 128-bit
     aligned, so we round to this widest known alignment.  */

  sp = align_down (sp, 16);
  struct_addr = align_down (struct_addr, 16);

  /* Now make space on the stack for the args.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      struct type *arg_type = check_typedef (args[argnum]->type ());

      /* Align to double-word if necessary.  */
      if (mips_type_needs_double_align (arg_type))
	arg_space = align_up (arg_space, MIPS32_REGSIZE * 2);
      /* Allocate space on the stack.  */
      arg_space += align_up (arg_type->length (), MIPS32_REGSIZE);
    }
  sp -= align_up (arg_space, 16);

  if (mips_debug)
    gdb_printf (gdb_stdlog,
		"mips_o32_push_dummy_call: sp=%s allocated %ld\n",
		paddress (gdbarch, sp),
		(long) align_up (arg_space, 16));

  /* Initialize the integer and float register pointers.  */
  argreg = MIPS_A0_REGNUM;
  float_argreg = mips_fpa0_regnum (gdbarch);

  /* The struct_return pointer occupies the first parameter-passing reg.  */
  if (return_method == return_method_struct)
    {
      if (mips_debug)
	gdb_printf (gdb_stdlog,
		    "mips_o32_push_dummy_call: "
		    "struct_return reg=%d %s\n",
		    argreg, paddress (gdbarch, struct_addr));
      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
      stack_offset += MIPS32_REGSIZE;
    }

  /* Now load as many as possible of the first arguments into
     registers, and push the rest onto the stack.  Loop thru args
     from first to last.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      const gdb_byte *val;
      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (arg->type ());
      int len = arg_type->length ();
      enum type_code typecode = arg_type->code ();

      if (mips_debug)
	gdb_printf (gdb_stdlog,
		    "mips_o32_push_dummy_call: %d len=%d type=%d",
		    argnum + 1, len, (int) typecode);

      val = arg->contents ().data ();

      /* 32-bit ABIs always start floating point arguments in an
	 even-numbered floating point register.  Round the FP register
	 up before the check to see if there are any FP registers
	 left.  O32 targets also pass the FP in the integer registers
	 so also round up normal registers.  */
      if (fp_register_arg_p (gdbarch, typecode, arg_type))
	{
	  if ((float_argreg & 1))
	    float_argreg++;
	}

      /* Floating point arguments passed in registers have to be
	 treated specially.  On 32-bit architectures, doubles are
	 passed in register pairs; the even FP register gets the
	 low word, and the odd FP register gets the high word.
	 On O32, the first two floating point arguments are also
	 copied to general registers, following their memory order,
	 because MIPS16 functions don't use float registers for
	 arguments.  This duplication of arguments in general
	 registers can't hurt non-MIPS16 functions, because those
	 registers are normally skipped.  */

      if (fp_register_arg_p (gdbarch, typecode, arg_type)
	  && float_argreg <= mips_last_fp_arg_regnum (gdbarch))
	{
	  if (register_size (gdbarch, float_argreg) < 8 && len == 8)
	    {
	      int freg_offset = gdbarch_byte_order (gdbarch)
				== BFD_ENDIAN_BIG ? 1 : 0;
	      unsigned long regval;

	      /* First word.  */
	      regval = extract_unsigned_integer (val, 4, byte_order);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			    float_argreg + freg_offset,
			    phex (regval, 4));
	      regcache_cooked_write_unsigned (regcache,
					      float_argreg++ + freg_offset,
					      regval);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - reg=%d val=%s",
			    argreg, phex (regval, 4));
	      regcache_cooked_write_unsigned (regcache, argreg++, regval);

	      /* Second word.  */
	      regval = extract_unsigned_integer (val + 4, 4, byte_order);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			    float_argreg - freg_offset,
			    phex (regval, 4));
	      regcache_cooked_write_unsigned (regcache,
					      float_argreg++ - freg_offset,
					      regval);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - reg=%d val=%s",
			    argreg, phex (regval, 4));
	      regcache_cooked_write_unsigned (regcache, argreg++, regval);
	    }
	  else
	    {
	      /* This is a floating point value that fits entirely
		 in a single register.  */
	      /* On 32 bit ABI's the float_argreg is further adjusted
		 above to ensure that it is even register aligned.  */
	      LONGEST regval = extract_unsigned_integer (val, len, byte_order);
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			    float_argreg, phex (regval, len));
	      regcache_cooked_write_unsigned (regcache,
					      float_argreg++, regval);
	      /* Although two FP registers are reserved for each
		 argument, only one corresponding integer register is
		 reserved.  */
	      if (mips_debug)
		gdb_printf (gdb_stdlog, " - reg=%d val=%s",
			    argreg, phex (regval, len));
	      regcache_cooked_write_unsigned (regcache, argreg++, regval);
	    }
	  /* Reserve space for the FP register.  */
	  stack_offset += align_up (len, MIPS32_REGSIZE);
	}
      else
	{
	  /* Copy the argument to general registers or the stack in
	     register-sized pieces.  Large arguments are split between
	     registers and stack.  */
	  /* Note: structs whose size is not a multiple of MIPS32_REGSIZE
	     are treated specially: Irix cc passes
	     them in registers where gcc sometimes puts them on the
	     stack.  For maximum compatibility, we will put them in
	     both places.  */
	  int odd_sized_struct = (len > MIPS32_REGSIZE
				  && len % MIPS32_REGSIZE != 0);
	  /* Structures should be aligned to eight bytes (even arg registers)
	     on MIPS_ABI_O32, if their first member has double precision.  */
	  if (mips_type_needs_double_align (arg_type))
	    {
	      if ((argreg & 1))
		{
		  argreg++;
		  stack_offset += MIPS32_REGSIZE;
		}
	    }
	  while (len > 0)
	    {
	      int partial_len = (len < MIPS32_REGSIZE ? len : MIPS32_REGSIZE);

	      if (mips_debug)
		gdb_printf (gdb_stdlog, " -- partial=%d",
			    partial_len);

	      /* Write this portion of the argument to the stack.  */
	      if (argreg > mips_last_arg_regnum (gdbarch)
		  || odd_sized_struct)
		{
		  /* Should shorter than int integer values be
		     promoted to int before being stored?  */
		  int longword_offset = 0;
		  CORE_ADDR addr;

		  if (mips_debug)
		    {
		      gdb_printf (gdb_stdlog, " - stack_offset=%s",
				  paddress (gdbarch, stack_offset));
		      gdb_printf (gdb_stdlog, " longword_offset=%s",
				  paddress (gdbarch, longword_offset));
		    }

		  addr = sp + stack_offset + longword_offset;

		  if (mips_debug)
		    {
		      int i;
		      gdb_printf (gdb_stdlog, " @%s ",
				  paddress (gdbarch, addr));
		      for (i = 0; i < partial_len; i++)
			{
			  gdb_printf (gdb_stdlog, "%02x",
				      val[i] & 0xff);
			}
		    }
		  write_memory (addr, val, partial_len);
		}

	      /* Note!!! This is NOT an else clause.  Odd sized
		 structs may go thru BOTH paths.  */
	      /* Write this portion of the argument to a general
		 purpose register.  */
	      if (argreg <= mips_last_arg_regnum (gdbarch))
		{
		  LONGEST regval = extract_signed_integer (val, partial_len,
							   byte_order);
		  /* Value may need to be sign extended, because
		     mips_isa_regsize() != mips_abi_regsize().  */

		  /* A non-floating-point argument being passed in a
		     general register.  If a struct or union, and if
		     the remaining length is smaller than the register
		     size, we have to adjust the register value on
		     big endian targets.

		     It does not seem to be necessary to do the
		     same for integral types.

		     Also don't do this adjustment on O64 binaries.

		     cagney/2001-07-23: gdb/179: Also, GCC, when
		     outputting LE O32 with sizeof (struct) <
		     mips_abi_regsize(), generates a left shift
		     as part of storing the argument in a register
		     (the left shift isn't generated when
		     sizeof (struct) >= mips_abi_regsize()).  Since
		     it is quite possible that this is GCC
		     contradicting the LE/O32 ABI, GDB has not been
		     adjusted to accommodate this.  Either someone
		     needs to demonstrate that the LE/O32 ABI
		     specifies such a left shift OR this new ABI gets
		     identified as such and GDB gets tweaked
		     accordingly.  */

		  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
		      && partial_len < MIPS32_REGSIZE
		      && (typecode == TYPE_CODE_STRUCT
			  || typecode == TYPE_CODE_UNION))
		    regval <<= ((MIPS32_REGSIZE - partial_len)
				* TARGET_CHAR_BIT);

		  if (mips_debug)
		    gdb_printf (gdb_stdlog, " - reg=%d val=%s",
				argreg,
				phex (regval, MIPS32_REGSIZE));
		  regcache_cooked_write_unsigned (regcache, argreg, regval);
		  argreg++;

		  /* Prevent subsequent floating point arguments from
		     being passed in floating point registers.  */
		  float_argreg = mips_last_fp_arg_regnum (gdbarch) + 1;
		}

	      len -= partial_len;
	      val += partial_len;

	      /* Compute the offset into the stack at which we will
		 copy the next parameter.

		 In older ABIs, the caller reserved space for
		 registers that contained arguments.  This was loosely
		 referred to as their "home".  Consequently, space is
		 always allocated.  */

	      stack_offset += align_up (partial_len, MIPS32_REGSIZE);
	    }
	}
      if (mips_debug)
	gdb_printf (gdb_stdlog, "\n");
    }

  regcache_cooked_write_signed (regcache, MIPS_SP_REGNUM, sp);

  /* Return adjusted stack pointer.  */
  return sp;
}

static enum return_value_convention
mips_o32_return_value (struct gdbarch *gdbarch, struct value *function,
		       struct type *type, struct regcache *regcache,
		       gdb_byte *readbuf, const gdb_byte *writebuf)
{
  CORE_ADDR func_addr = function ? find_function_addr (function, NULL) : 0;
  int mips16 = mips_pc_is_mips16 (gdbarch, func_addr);
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
  enum mips_fval_reg fval_reg;

  fval_reg = readbuf ? mips16 ? mips_fval_gpr : mips_fval_fpr : mips_fval_both;
  if (type->code () == TYPE_CODE_STRUCT
      || type->code () == TYPE_CODE_UNION
      || type->code () == TYPE_CODE_ARRAY)
    return RETURN_VALUE_STRUCT_CONVENTION;
  else if (type->code () == TYPE_CODE_FLT
	   && type->length () == 4 && tdep->mips_fpu_type != MIPS_FPU_NONE)
    {
      /* A single-precision floating-point value.  If reading in or copying,
	 then we get it from/put it to FP0 for standard MIPS code or GPR2
	 for MIPS16 code.  If writing out only, then we put it to both FP0
	 and GPR2.  We do not support reading in with no function known, if
	 this safety check ever triggers, then we'll have to try harder.  */
      gdb_assert (function || !readbuf);
      if (mips_debug)
	switch (fval_reg)
	  {
	  case mips_fval_fpr:
	    gdb_printf (gdb_stderr, "Return float in $fp0\n");
	    break;
	  case mips_fval_gpr:
	    gdb_printf (gdb_stderr, "Return float in $2\n");
	    break;
	  case mips_fval_both:
	    gdb_printf (gdb_stderr, "Return float in $fp0 and $2\n");
	    break;
	  }
      if (fval_reg != mips_fval_gpr)
	mips_xfer_register (gdbarch, regcache,
			    (gdbarch_num_regs (gdbarch)
			     + mips_regnum (gdbarch)->fp0),
			    type->length (),
			    gdbarch_byte_order (gdbarch),
			    readbuf, writebuf, 0);
      if (fval_reg != mips_fval_fpr)
	mips_xfer_register (gdbarch, regcache,
			    gdbarch_num_regs (gdbarch) + 2,
			    type->length (),
			    gdbarch_byte_order (gdbarch),
			    readbuf, writebuf, 0);
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
  else if (type->code () == TYPE_CODE_FLT
	   && type->length () == 8 && tdep->mips_fpu_type != MIPS_FPU_NONE)
    {
      /* A double-precision floating-point value.  If reading in or copying,
	 then we get it from/put it to FP1 and FP0 for standard MIPS code or
	 GPR2 and GPR3 for MIPS16 code.  If writing out only, then we put it
	 to both FP1/FP0 and GPR2/GPR3.  We do not support reading in with
	 no function known, if this safety check ever triggers, then we'll
	 have to try harder.  */
      gdb_assert (function || !readbuf);
      if (mips_debug)
	switch (fval_reg)
	  {
	  case mips_fval_fpr:
	    gdb_printf (gdb_stderr, "Return float in $fp1/$fp0\n");
	    break;
	  case mips_fval_gpr:
	    gdb_printf (gdb_stderr, "Return float in $2/$3\n");
	    break;
	  case mips_fval_both:
	    gdb_printf (gdb_stderr,
			"Return float in $fp1/$fp0 and $2/$3\n");
	    break;
	  }
      if (fval_reg != mips_fval_gpr)
	{
	  /* The most significant part goes in FP1, and the least significant
	     in FP0.  */
	  switch (gdbarch_byte_order (gdbarch))
	    {
	    case BFD_ENDIAN_LITTLE:
	      mips_xfer_register (gdbarch, regcache,
				  (gdbarch_num_regs (gdbarch)
				   + mips_regnum (gdbarch)->fp0 + 0),
				  4, gdbarch_byte_order (gdbarch),
				  readbuf, writebuf, 0);
	      mips_xfer_register (gdbarch, regcache,
				  (gdbarch_num_regs (gdbarch)
				   + mips_regnum (gdbarch)->fp0 + 1),
				  4, gdbarch_byte_order (gdbarch),
				  readbuf, writebuf, 4);
	      break;
	    case BFD_ENDIAN_BIG:
	      mips_xfer_register (gdbarch, regcache,
				  (gdbarch_num_regs (gdbarch)
				   + mips_regnum (gdbarch)->fp0 + 1),
				  4, gdbarch_byte_order (gdbarch),
				  readbuf, writebuf, 0);
	      mips_xfer_register (gdbarch, regcache,
				  (gdbarch_num_regs (gdbarch)
				   + mips_regnum (gdbarch)->fp0 + 0),
				  4, gdbarch_byte_order (gdbarch),
				  readbuf, writebuf, 4);
	      break;
	    default:
	      internal_error (_("bad switch"));
	    }
	}
      if (fval_reg != mips_fval_fpr)
	{
	  /* The two 32-bit parts are always placed in GPR2 and GPR3
	     following these registers' memory order.  */
	  mips_xfer_register (gdbarch, regcache,
			      gdbarch_num_regs (gdbarch) + 2,
			      4, gdbarch_byte_order (gdbarch),
			      readbuf, writebuf, 0);
	  mips_xfer_register (gdbarch, regcache,
			      gdbarch_num_regs (gdbarch) + 3,
			      4, gdbarch_byte_order (gdbarch),
			      readbuf, writebuf, 4);
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
#if 0
  else if (type->code () == TYPE_CODE_STRUCT
	   && type->num_fields () <= 2
	   && type->num_fields () >= 1
	   && ((type->num_fields () == 1
		&& (TYPE_CODE (type->field (0).type ())
		    == TYPE_CODE_FLT))
	       || (type->num_fields () == 2
		   && (TYPE_CODE (type->field (0).type ())
		       == TYPE_CODE_FLT)
		   && (TYPE_CODE (type->field (1).type ())
		       == TYPE_CODE_FLT)))
	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
    {
      /* A struct that contains one or two floats.  Each value is part
	 in the least significant part of their floating point
	 register..  */
      int regnum;
      int field;
      for (field = 0, regnum = mips_regnum (gdbarch)->fp0;
	   field < type->num_fields (); field++, regnum += 2)
	{
	  int offset = (type->fields ()[field].loc_bitpos () / TARGET_CHAR_BIT);
	  if (mips_debug)
	    gdb_printf (gdb_stderr, "Return float struct+%d\n",
			offset);
	  mips_xfer_register (gdbarch, regcache,
			      gdbarch_num_regs (gdbarch) + regnum,
			      TYPE_LENGTH (type->field (field).type ()),
			      gdbarch_byte_order (gdbarch),
			      readbuf, writebuf, offset);
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
#endif
#if 0
  else if (type->code () == TYPE_CODE_STRUCT
	   || type->code () == TYPE_CODE_UNION)
    {
      /* A structure or union.  Extract the left justified value,
	 regardless of the byte order.  I.e. DO NOT USE
	 mips_xfer_lower.  */
      int offset;
      int regnum;
      for (offset = 0, regnum = MIPS_V0_REGNUM;
	   offset < type->length ();
	   offset += register_size (gdbarch, regnum), regnum++)
	{
	  int xfer = register_size (gdbarch, regnum);
	  if (offset + xfer > type->length ())
	    xfer = type->length () - offset;
	  if (mips_debug)
	    gdb_printf (gdb_stderr, "Return struct+%d:%d in $%d\n",
			offset, xfer, regnum);
	  mips_xfer_register (gdbarch, regcache,
			      gdbarch_num_regs (gdbarch) + regnum, xfer,
			      BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
#endif
  else
    {
      /* A scalar extract each part but least-significant-byte
	 justified.  o32 thinks registers are 4 byte, regardless of
	 the ISA.  */
      int offset;
      int regnum;
      for (offset = 0, regnum = MIPS_V0_REGNUM;
	   offset < type->length ();
	   offset += MIPS32_REGSIZE, regnum++)
	{
	  int xfer = MIPS32_REGSIZE;
	  if (offset + xfer > type->length ())
	    xfer = type->length () - offset;
	  if (mips_debug)
	    gdb_printf (gdb_stderr, "Return scalar+%d:%d in $%d\n",
			offset, xfer, regnum);
	  mips_xfer_register (gdbarch, regcache,
			      gdbarch_num_regs (gdbarch) + regnum, xfer,
			      gdbarch_byte_order (gdbarch),
			      readbuf, writebuf, offset);
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}

/* O64 ABI.  This is a hacked up kind of 64-bit version of the o32
   ABI.  */

static CORE_ADDR
mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
			  struct regcache *regcache, CORE_ADDR bp_addr,
			  int nargs,
			  struct value **args, CORE_ADDR sp,
			  function_call_return_method return_method, CORE_ADDR struct_addr)
{
  int argreg;
  int float_argreg;
  int argnum;
  int arg_space = 0;
  int stack_offset = 0;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR func_addr = find_function_addr (function, NULL);

  /* For shared libraries, "t9" needs to point at the function
     address.  */
  regcache_cooked_write_signed (regcache, MIPS_T9_REGNUM, func_addr);

  /* Set the return address register to point to the entry point of
     the program, where a breakpoint lies in wait.  */
  regcache_cooked_write_signed (regcache, MIPS_RA_REGNUM, bp_addr);

  /* First ensure that the stack and structure return address (if any)
     are properly aligned.  The stack has to be at least 64-bit
     aligned even on 32-bit machines, because doubles must be 64-bit
     aligned.  For n32 and n64, stack frames need to be 128-bit
     aligned, so we round to this widest known alignment.  */

  sp = align_down (sp, 16);
  struct_addr = align_down (struct_addr, 16);

  /* Now make space on the stack for the args.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      struct type *arg_type = check_typedef (args[argnum]->type ());

      /* Allocate space on the stack.  */
      arg_space += align_up (arg_type->length (), MIPS64_REGSIZE);
    }
  sp -= align_up (arg_space, 16);

  if (mips_debug)
    gdb_printf (gdb_stdlog,
		"mips_o64_push_dummy_call: sp=%s allocated %ld\n",
		paddress (gdbarch, sp),
		(long) align_up (arg_space, 16));

  /* Initialize the integer and float register pointers.  */
  argreg = MIPS_A0_REGNUM;
  float_argreg = mips_fpa0_regnum (gdbarch);

  /* The struct_return pointer occupies the first parameter-passing reg.  */
  if (return_method == return_method_struct)
    {
      if (mips_debug)
	gdb_printf (gdb_stdlog,
		    "mips_o64_push_dummy_call: "
		    "struct_return reg=%d %s\n",
		    argreg, paddress (gdbarch, struct_addr));
      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
      stack_offset += MIPS64_REGSIZE;
    }

  /* Now load as many as possible of the first arguments into
     registers, and push the rest onto the stack.  Loop thru args
     from first to last.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      const gdb_byte *val;
      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (arg->type ());
      int len = arg_type->length ();
      enum type_code typecode = arg_type->code ();

      if (mips_debug)
	gdb_printf (gdb_stdlog,
		    "mips_o64_push_dummy_call: %d len=%d type=%d",
		    argnum + 1, len, (int) typecode);

      val = arg->contents ().data ();

      /* Floating point arguments passed in registers have to be
	 treated specially.  On 32-bit architectures, doubles are
	 passed in register pairs; the even FP register gets the
	 low word, and the odd FP register gets the high word.
	 On O64, the first two floating point arguments are also
	 copied to general registers, because MIPS16 functions
	 don't use float registers for arguments.  This duplication
	 of arguments in general registers can't hurt non-MIPS16
	 functions because those registers are normally skipped.  */

      if (fp_register_arg_p (gdbarch, typecode, arg_type)
	  && float_argreg <= mips_last_fp_arg_regnum (gdbarch))
	{
	  LONGEST regval = extract_unsigned_integer (val, len, byte_order);
	  if (mips_debug)
	    gdb_printf (gdb_stdlog, " - fpreg=%d val=%s",
			float_argreg, phex (regval, len));
	  regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
	  if (mips_debug)
	    gdb_printf (gdb_stdlog, " - reg=%d val=%s",
			argreg, phex (regval, len));
	  regcache_cooked_write_unsigned (regcache, argreg, regval);
	  argreg++;
	  /* Reserve space for the FP register.  */
	  stack_offset += align_up (len, MIPS64_REGSIZE);
	}
      else
	{
	  /* Copy the argument to general registers or the stack in
	     register-sized pieces.  Large arguments are split between
	     registers and stack.  */
	  /* Note: structs whose size is not a multiple of MIPS64_REGSIZE
	     are treated specially: Irix cc passes them in registers
	     where gcc sometimes puts them on the stack.  For maximum
	     compatibility, we will put them in both places.  */
	  int odd_sized_struct = (len > MIPS64_REGSIZE
				  && len % MIPS64_REGSIZE != 0);
	  while (len > 0)
	    {
	      int partial_len = (len < MIPS64_REGSIZE ? len : MIPS64_REGSIZE);

	      if (mips_debug)
		gdb_printf (gdb_stdlog, " -- partial=%d",
			    partial_len);

	      /* Write this portion of the argument to the stack.  */
	      if (argreg > mips_last_arg_regnum (gdbarch)
		  || odd_sized_struct)
		{
		  /* Should shorter than int integer values be
		     promoted to int before being stored?  */
		  int longword_offset = 0;
		  CORE_ADDR addr;
		  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
		    {
		      if ((typecode == TYPE_CODE_INT
			   || typecode == TYPE_CODE_PTR
			   || typecode == TYPE_CODE_FLT)
			  && len <= 4)
			longword_offset = MIPS64_REGSIZE - len;
		    }

		  if (mips_debug)
		    {
		      gdb_printf (gdb_stdlog, " - stack_offset=%s",
				  paddress (gdbarch, stack_offset));
		      gdb_printf (gdb_stdlog, " longword_offset=%s",
				  paddress (gdbarch, longword_offset));
		    }

		  addr = sp + stack_offset + longword_offset;

		  if (mips_debug)
		    {
		      int i;
		      gdb_printf (gdb_stdlog, " @%s ",
				  paddress (gdbarch, addr));
		      for (i = 0; i < partial_len; i++)
			{
			  gdb_printf (gdb_stdlog, "%02x",
				      val[i] & 0xff);
			}
		    }
		  write_memory (addr, val, partial_len);
		}

	      /* Note!!! This is NOT an else clause.  Odd sized
		 structs may go thru BOTH paths.  */
	      /* Write this portion of the argument to a general
		 purpose register.  */
	      if (argreg <= mips_last_arg_regnum (gdbarch))
		{
		  LONGEST regval = extract_signed_integer (val, partial_len,
							   byte_order);
		  /* Value may need to be sign extended, because
		     mips_isa_regsize() != mips_abi_regsize().  */

		  /* A non-floating-point argument being passed in a
		     general register.  If a struct or union, and if
		     the remaining length is smaller than the register
		     size, we have to adjust the register value on
		     big endian targets.

		     It does not seem to be necessary to do the
		     same for integral types.  */

		  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
		      && partial_len < MIPS64_REGSIZE
		      && (typecode == TYPE_CODE_STRUCT
			  || typecode == TYPE_CODE_UNION))
		    regval <<= ((MIPS64_REGSIZE - partial_len)
				* TARGET_CHAR_BIT);

		  if (mips_debug)
		    gdb_printf (gdb_stdlog, " - reg=%d val=%s",
				argreg,
				phex (regval, MIPS64_REGSIZE));
		  regcache_cooked_write_unsigned (regcache, argreg, regval);
		  argreg++;

		  /* Prevent subsequent floating point arguments from
		     being passed in floating point registers.  */
		  float_argreg = mips_last_fp_arg_regnum (gdbarch) + 1;
		}

	      len -= partial_len;
	      val += partial_len;

	      /* Compute the offset into the stack at which we will
		 copy the next parameter.

		 In older ABIs, the caller reserved space for
		 registers that contained arguments.  This was loosely
		 referred to as their "home".  Consequently, space is
		 always allocated.  */

	      stack_offset += align_up (partial_len, MIPS64_REGSIZE);
	    }
	}
      if (mips_debug)
	gdb_printf (gdb_stdlog, "\n");
    }

  regcache_cooked_write_signed (regcache, MIPS_SP_REGNUM, sp);

  /* Return adjusted stack pointer.  */
  return sp;
}

static enum return_value_convention
mips_o64_return_value (struct gdbarch *gdbarch, struct value *function,
		       struct type *type, struct regcache *regcache,
		       gdb_byte *readbuf, const gdb_byte *writebuf)
{
  CORE_ADDR func_addr = function ? find_function_addr (function, NULL) : 0;
  int mips16 = mips_pc_is_mips16 (gdbarch, func_addr);
  enum mips_fval_reg fval_reg;

  fval_reg = readbuf ? mips16 ? mips_fval_gpr : mips_fval_fpr : mips_fval_both;
  if (type->code () == TYPE_CODE_STRUCT
      || type->code () == TYPE_CODE_UNION
      || type->code () == TYPE_CODE_ARRAY)
    return RETURN_VALUE_STRUCT_CONVENTION;
  else if (fp_register_arg_p (gdbarch, type->code (), type))
    {
      /* A floating-point value.  If reading in or copying, then we get it
	 from/put it to FP0 for standard MIPS code or GPR2 for MIPS16 code.
	 If writing out only, then we put it to both FP0 and GPR2.  We do
	 not support reading in with no function known, if this safety
	 check ever triggers, then we'll have to try harder.  */
      gdb_assert (function || !readbuf);
      if (mips_debug)
	switch (fval_reg)
	  {
	  case mips_fval_fpr:
	    gdb_printf (gdb_stderr, "Return float in $fp0\n");
	    break;
	  case mips_fval_gpr:
	    gdb_printf (gdb_stderr, "Return float in $2\n");
	    break;
	  case mips_fval_both:
	    gdb_printf (gdb_stderr, "Return float in $fp0 and $2\n");
	    break;
	  }
      if (fval_reg != mips_fval_gpr)
	mips_xfer_register (gdbarch, regcache,
			    (gdbarch_num_regs (gdbarch)
			     + mips_regnum (gdbarch)->fp0),
			    type->length (),
			    gdbarch_byte_order (gdbarch),
			    readbuf, writebuf, 0);
      if (fval_reg != mips_fval_fpr)
	mips_xfer_register (gdbarch, regcache,
			    gdbarch_num_regs (gdbarch) + 2,
			    type->length (),
			    gdbarch_byte_order (gdbarch),
			    readbuf, writebuf, 0);
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
  else
    {
      /* A scalar extract each part but least-significant-byte
	 justified.  */
      int offset;
      int regnum;
      for (offset = 0, regnum = MIPS_V0_REGNUM;
	   offset < type->length ();
	   offset += MIPS64_REGSIZE, regnum++)
	{
	  int xfer = MIPS64_REGSIZE;
	  if (offset + xfer > type->length ())
	    xfer = type->length () - offset;
	  if (mips_debug)
	    gdb_printf (gdb_stderr, "Return scalar+%d:%d in $%d\n",
			offset, xfer, regnum);
	  mips_xfer_register (gdbarch, regcache,
			      gdbarch_num_regs (gdbarch) + regnum,
			      xfer, gdbarch_byte_order (gdbarch),
			      readbuf, writebuf, offset);
	}
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}

/* Floating point register management.

   Background: MIPS1 & 2 fp registers are 32 bits wide.  To support
   64bit operations, these early MIPS cpus treat fp register pairs
   (f0,f1) as a single register (d0).  Later MIPS cpu's have 64 bit fp
   registers and offer a compatibility mode that emulates the MIPS2 fp
   model.  When operating in MIPS2 fp compat mode, later cpu's split
   double precision floats into two 32-bit chunks and store them in
   consecutive fp regs.  To display 64-bit floats stored in this
   fashion, we have to combine 32 bits from f0 and 32 bits from f1.
   Throw in user-configurable endianness and you have a real mess.

   The way this works is:
     - If we are in 32-bit mode or on a 32-bit processor, then a 64-bit
       double-precision value will be split across two logical registers.
       The lower-numbered logical register will hold the low-order bits,
       regardless of the processor's endianness.
     - If we are on a 64-bit processor, and we are looking for a
       single-precision value, it will be in the low ordered bits
       of a 64-bit GPR (after mfc1, for example) or a 64-bit register
       save slot in memory.
     - If we are in 64-bit mode, everything is straightforward.

   Note that this code only deals with "live" registers at the top of the
   stack.  We will attempt to deal with saved registers later, when
   the raw/cooked register interface is in place.  (We need a general
   interface that can deal with dynamic saved register sizes -- fp
   regs could be 32 bits wide in one frame and 64 on the frame above
   and below).  */

/* Copy a 32-bit single-precision value from the current frame
   into rare_buffer.  */

static void
mips_read_fp_register_single (const frame_info_ptr &frame, int regno,
			      gdb_byte *rare_buffer)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  int raw_size = register_size (gdbarch, regno);
  gdb_byte *raw_buffer = (gdb_byte *) alloca (raw_size);

  if (!deprecated_frame_register_read (frame, regno, raw_buffer))
    error (_("can't read register %d (%s)"),
	   regno, gdbarch_register_name (gdbarch, regno));
  if (raw_size == 8)
    {
      /* We have a 64-bit value for this register.  Find the low-order
	 32 bits.  */
      int offset;

      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	offset = 4;
      else
	offset = 0;

      memcpy (rare_buffer, raw_buffer + offset, 4);
    }
  else
    {
      memcpy (rare_buffer, raw_buffer, 4);
    }
}

/* Copy a 64-bit double-precision value from the current frame into
   rare_buffer.  This may include getting half of it from the next
   register.  */

static void
mips_read_fp_register_double (const frame_info_ptr &frame, int regno,
			      gdb_byte *rare_buffer)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  int raw_size = register_size (gdbarch, regno);

  if (raw_size == 8 && !mips2_fp_compat (frame))
    {
      /* We have a 64-bit value for this register, and we should use
	 all 64 bits.  */
      if (!deprecated_frame_register_read (frame, regno, rare_buffer))
	error (_("can't read register %d (%s)"),
	       regno, gdbarch_register_name (gdbarch, regno));
    }
  else
    {
      int rawnum = regno % gdbarch_num_regs (gdbarch);

      if ((rawnum - mips_regnum (gdbarch)->fp0) & 1)
	internal_error (_("mips_read_fp_register_double: bad access to "
			"odd-numbered FP register"));

      /* mips_read_fp_register_single will find the correct 32 bits from
	 each register.  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	{
	  mips_read_fp_register_single (frame, regno, rare_buffer + 4);
	  mips_read_fp_register_single (frame, regno + 1, rare_buffer);
	}
      else
	{
	  mips_read_fp_register_single (frame, regno, rare_buffer);
	  mips_read_fp_register_single (frame, regno + 1, rare_buffer + 4);
	}
    }
}

static void
mips_print_fp_register (struct ui_file *file, const frame_info_ptr &frame,
			int regnum)
{				/* Do values for FP (float) regs.  */
  struct gdbarch *gdbarch = get_frame_arch (frame);
  gdb_byte *raw_buffer;
  std::string flt_str, dbl_str;

  const struct type *flt_type = builtin_type (gdbarch)->builtin_float;
  const struct type *dbl_type = builtin_type (gdbarch)->builtin_double;

  raw_buffer
    = ((gdb_byte *)
       alloca (2 * register_size (gdbarch, mips_regnum (gdbarch)->fp0)));

  gdb_printf (file, "%s:", gdbarch_register_name (gdbarch, regnum));
  gdb_printf (file, "%*s",
	      4 - (int) strlen (gdbarch_register_name (gdbarch, regnum)),
	      "");

  if (register_size (gdbarch, regnum) == 4 || mips2_fp_compat (frame))
    {
      struct value_print_options opts;

      /* 4-byte registers: Print hex and floating.  Also print even
	 numbered registers as doubles.  */
      mips_read_fp_register_single (frame, regnum, raw_buffer);
      flt_str = target_float_to_string (raw_buffer, flt_type, "%-17.9g");

      get_formatted_print_options (&opts, 'x');
      print_scalar_formatted (raw_buffer,
			      builtin_type (gdbarch)->builtin_uint32,
			      &opts, 'w', file);

      gdb_printf (file, " flt: %s", flt_str.c_str ());

      if ((regnum - gdbarch_num_regs (gdbarch)) % 2 == 0)
	{
	  mips_read_fp_register_double (frame, regnum, raw_buffer);
	  dbl_str = target_float_to_string (raw_buffer, dbl_type, "%-24.17g");

	  gdb_printf (file, " dbl: %s", dbl_str.c_str ());
	}
    }
  else
    {
      struct value_print_options opts;

      /* Eight byte registers: print each one as hex, float and double.  */
      mips_read_fp_register_single (frame, regnum, raw_buffer);
      flt_str = target_float_to_string (raw_buffer, flt_type, "%-17.9g");

      mips_read_fp_register_double (frame, regnum, raw_buffer);
      dbl_str = target_float_to_string (raw_buffer, dbl_type, "%-24.17g");

      get_formatted_print_options (&opts, 'x');
      print_scalar_formatted (raw_buffer,
			      builtin_type (gdbarch)->builtin_uint64,
			      &opts, 'g', file);

      gdb_printf (file, " flt: %s", flt_str.c_str ());
      gdb_printf (file, " dbl: %s", dbl_str.c_str ());
    }
}

static void
mips_print_register (struct ui_file *file, const frame_info_ptr &frame,
		     int regnum)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct value_print_options opts;
  struct value *val;

  if (mips_float_register_p (gdbarch, regnum))
    {
      mips_print_fp_register (file, frame, regnum);
      return;
    }

  val = get_frame_register_value (frame, regnum);

  gdb_puts (gdbarch_register_name (gdbarch, regnum), file);

  /* The problem with printing numeric register names (r26, etc.) is that
     the user can't use them on input.  Probably the best solution is to
     fix it so that either the numeric or the funky (a2, etc.) names
     are accepted on input.  */
  if (regnum < MIPS_NUMREGS)
    gdb_printf (file, "(r%d): ", regnum);
  else
    gdb_printf (file, ": ");

  get_formatted_print_options (&opts, 'x');
  value_print_scalar_formatted (val, &opts, 0, file);
}

/* Print IEEE exception condition bits in FLAGS.  */

static void
print_fpu_flags (struct ui_file *file, int flags)
{
  if (flags & (1 << 0))
    gdb_puts (" inexact", file);
  if (flags & (1 << 1))
    gdb_puts (" uflow", file);
  if (flags & (1 << 2))
    gdb_puts (" oflow", file);
  if (flags & (1 << 3))
    gdb_puts (" div0", file);
  if (flags & (1 << 4))
    gdb_puts (" inval", file);
  if (flags & (1 << 5))
    gdb_puts (" unimp", file);
  gdb_putc ('\n', file);
}

/* Print interesting information about the floating point processor
   (if present) or emulator.  */

static void
mips_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
		      const frame_info_ptr &frame, const char *args)
{
  int fcsr = mips_regnum (gdbarch)->fp_control_status;
  enum mips_fpu_type type = mips_get_fpu_type (gdbarch);
  ULONGEST fcs = 0;
  int i;

  if (fcsr == -1 || !read_frame_register_unsigned (frame, fcsr, &fcs))
    type = MIPS_FPU_NONE;

  gdb_printf (file, "fpu type: %s\n",
	      type == MIPS_FPU_DOUBLE ? "double-precision"
	      : type == MIPS_FPU_SINGLE ? "single-precision"
	      : "none / unused");

  if (type == MIPS_FPU_NONE)
    return;

  gdb_printf (file, "reg size: %d bits\n",
	      register_size (gdbarch, mips_regnum (gdbarch)->fp0) * 8);

  gdb_puts ("cond    :", file);
  if (fcs & (1 << 23))
    gdb_puts (" 0", file);
  for (i = 1; i <= 7; i++)
    if (fcs & (1 << (24 + i)))
      gdb_printf (file, " %d", i);
  gdb_putc ('\n', file);

  gdb_puts ("cause   :", file);
  print_fpu_flags (file, (fcs >> 12) & 0x3f);
  fputs ("mask    :", stdout);
  print_fpu_flags (file, (fcs >> 7) & 0x1f);
  fputs ("flags   :", stdout);
  print_fpu_flags (file, (fcs >> 2) & 0x1f);

  gdb_puts ("rounding: ", file);
  switch (fcs & 3)
    {
    case 0: gdb_puts ("nearest\n", file); break;
    case 1: gdb_puts ("zero\n", file); break;
    case 2: gdb_puts ("+inf\n", file); break;
    case 3: gdb_puts ("-inf\n", file); break;
    }

  gdb_puts ("flush   :", file);
  if (fcs & (1 << 21))
    gdb_puts (" nearest", file);
  if (fcs & (1 << 22))
    gdb_puts (" override", file);
  if (fcs & (1 << 24))
    gdb_puts (" zero", file);
  if ((fcs & (0xb << 21)) == 0)
    gdb_puts (" no", file);
  gdb_putc ('\n', file);

  gdb_printf (file, "nan2008 : %s\n", fcs & (1 << 18) ? "yes" : "no");
  gdb_printf (file, "abs2008 : %s\n", fcs & (1 << 19) ? "yes" : "no");
  gdb_putc ('\n', file);

  default_print_float_info (gdbarch, file, frame, args);
}

/* Replacement for generic do_registers_info.
   Print regs in pretty columns.  */

static int
print_fp_register_row (struct ui_file *file, const frame_info_ptr &frame,
		       int regnum)
{
  gdb_printf (file, " ");
  mips_print_fp_register (file, frame, regnum);
  gdb_printf (file, "\n");
  return regnum + 1;
}


/* Print a row's worth of GP (int) registers, with name labels above.  */

static int
print_gp_register_row (struct ui_file *file, const frame_info_ptr &frame,
		       int start_regnum)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  /* Do values for GP (int) regs.  */
  const gdb_byte *raw_buffer;
  struct value *value;
  int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8);    /* display cols
							       per row.  */
  int col, byte;
  int regnum;

  /* For GP registers, we print a separate row of names above the vals.  */
  for (col = 0, regnum = start_regnum;
       col < ncols && regnum < gdbarch_num_cooked_regs (gdbarch);
       regnum++)
    {
      if (*gdbarch_register_name (gdbarch, regnum) == '\0')
	continue;		/* unused register */
      if (mips_float_register_p (gdbarch, regnum))
	break;			/* End the row: reached FP register.  */
      /* Large registers are handled separately.  */
      if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch))
	{
	  if (col > 0)
	    break;		/* End the row before this register.  */

	  /* Print this register on a row by itself.  */
	  mips_print_register (file, frame, regnum);
	  gdb_printf (file, "\n");
	  return regnum + 1;
	}
      if (col == 0)
	gdb_printf (file, "     ");
      gdb_printf (file,
		  mips_abi_regsize (gdbarch) == 8 ? "%17s" : "%9s",
		  gdbarch_register_name (gdbarch, regnum));
      col++;
    }

  if (col == 0)
    return regnum;

  /* Print the R0 to R31 names.  */
  if ((start_regnum % gdbarch_num_regs (gdbarch)) < MIPS_NUMREGS)
    gdb_printf (file, "\n R%-4d",
		start_regnum % gdbarch_num_regs (gdbarch));
  else
    gdb_printf (file, "\n      ");

  /* Now print the values in hex, 4 or 8 to the row.  */
  for (col = 0, regnum = start_regnum;
       col < ncols && regnum < gdbarch_num_cooked_regs (gdbarch);
       regnum++)
    {
      if (*gdbarch_register_name (gdbarch, regnum) == '\0')
	continue;		/* unused register */
      if (mips_float_register_p (gdbarch, regnum))
	break;			/* End row: reached FP register.  */
      if (register_size (gdbarch, regnum) > mips_abi_regsize (gdbarch))
	break;			/* End row: large register.  */

      /* OK: get the data in raw format.  */
      value = get_frame_register_value (frame, regnum);
      if (value->optimized_out ()
	  || !value->entirely_available ())
	{
	  gdb_printf (file, "%*s ",
		      (int) mips_abi_regsize (gdbarch) * 2,
		      (mips_abi_regsize (gdbarch) == 4 ? "<unavl>"
		       : "<unavailable>"));
	  col++;
	  continue;
	}
      raw_buffer = value->contents_all ().data ();
      /* pad small registers */
      for (byte = 0;
	   byte < (mips_abi_regsize (gdbarch)
		   - register_size (gdbarch, regnum)); byte++)
	gdb_printf (file, "  ");
      /* Now print the register value in hex, endian order.  */
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	for (byte =
	     register_size (gdbarch, regnum) - register_size (gdbarch, regnum);
	     byte < register_size (gdbarch, regnum); byte++)
	  gdb_printf (file, "%02x", raw_buffer[byte]);
      else
	for (byte = register_size (gdbarch, regnum) - 1;
	     byte >= 0; byte--)
	  gdb_printf (file, "%02x", raw_buffer[byte]);
      gdb_printf (file, " ");
      col++;
    }
  if (col > 0)			/* ie. if we actually printed anything...  */
    gdb_printf (file, "\n");

  return regnum;
}

/* MIPS_DO_REGISTERS_INFO(): called by "info register" command.  */

static void
mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
			   const frame_info_ptr &frame, int regnum, int all)
{
  if (regnum != -1)		/* Do one specified register.  */
    {
      gdb_assert (regnum >= gdbarch_num_regs (gdbarch));
      if (*(gdbarch_register_name (gdbarch, regnum)) == '\0')
	error (_("Not a valid register for the current processor type"));

      mips_print_register (file, frame, regnum);
      gdb_printf (file, "\n");
    }
  else
    /* Do all (or most) registers.  */
    {
      regnum = gdbarch_num_regs (gdbarch);
      while (regnum < gdbarch_num_cooked_regs (gdbarch))
	{
	  if (mips_float_register_p (gdbarch, regnum))
	    {
	      if (all)		/* True for "INFO ALL-REGISTERS" command.  */
		regnum = print_fp_register_row (file, frame, regnum);
	      else
		regnum += MIPS_NUMREGS;	/* Skip floating point regs.  */
	    }
	  else
	    regnum = print_gp_register_row (file, frame, regnum);
	}
    }
}

static int
mips_single_step_through_delay (struct gdbarch *gdbarch,
				const frame_info_ptr &frame)
{
  CORE_ADDR pc = get_frame_pc (frame);
  enum mips_isa isa;
  ULONGEST insn;
  int size;

  if ((mips_pc_is_mips (pc)
       && !mips32_insn_at_pc_has_delay_slot (gdbarch, pc))
      || (mips_pc_is_micromips (gdbarch, pc)
	  && !micromips_insn_at_pc_has_delay_slot (gdbarch, pc, 0))
      || (mips_pc_is_mips16 (gdbarch, pc)
	  && !mips16_insn_at_pc_has_delay_slot (gdbarch, pc, 0)))
    return 0;

  isa = mips_pc_isa (gdbarch, pc);
  /* _has_delay_slot above will have validated the read.  */
  insn = mips_fetch_instruction (gdbarch, isa, pc, NULL);
  size = mips_insn_size (isa, insn);

  const address_space *aspace = get_frame_address_space (frame);

  return breakpoint_here_p (aspace, pc + size) != no_breakpoint_here;
}

/* To skip prologues, I use this predicate.  Returns either PC itself
   if the code at PC does not look like a function prologue; otherwise
   returns an address that (if we're lucky) follows the prologue.  If
   LENIENT, then we must skip everything which is involved in setting
   up the frame (it's OK to skip more, just so long as we don't skip
   anything which might clobber the registers which are being saved.
   We must skip more in the case where part of the prologue is in the
   delay slot of a non-prologue instruction).  */

static CORE_ADDR
mips_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR limit_pc;
  CORE_ADDR func_addr;

  /* 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, NULL, &func_addr, NULL))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      if (post_prologue_pc != 0)
	return std::max (pc, post_prologue_pc);
    }

  /* Can't determine prologue from the symbol table, need to examine
     instructions.  */

  /* Find an upper limit on the function prologue using the debug
     information.  If the debug information could not be used to provide
     that bound, then use an arbitrary large number as the upper bound.  */
  limit_pc = skip_prologue_using_sal (gdbarch, pc);
  if (limit_pc == 0)
    limit_pc = pc + 100;          /* Magic.  */

  if (mips_pc_is_mips16 (gdbarch, pc))
    return mips16_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
  else if (mips_pc_is_micromips (gdbarch, pc))
    return micromips_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
  else
    return mips32_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
}

/* Implement the stack_frame_destroyed_p gdbarch method (32-bit version).
   This is a helper function for mips_stack_frame_destroyed_p.  */

static int
mips32_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr = 0, func_end = 0;

  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    {
      /* The MIPS epilogue is max. 12 bytes long.  */
      CORE_ADDR addr = func_end - 12;

      if (addr < func_addr + 4)
	addr = func_addr + 4;
      if (pc < addr)
	return 0;

      for (; pc < func_end; pc += MIPS_INSN32_SIZE)
	{
	  unsigned long high_word;
	  unsigned long inst;

	  inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
	  high_word = (inst >> 16) & 0xffff;

	  if (high_word != 0x27bd	/* addiu $sp,$sp,offset */
	      && high_word != 0x67bd	/* daddiu $sp,$sp,offset */
	      && inst != 0x03e00008	/* jr $ra */
	      && inst != 0x00000000)	/* nop */
	    return 0;
	}

      return 1;
    }

  return 0;
}

/* Implement the stack_frame_destroyed_p gdbarch method (microMIPS version).
   This is a helper function for mips_stack_frame_destroyed_p.  */

static int
micromips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr = 0;
  CORE_ADDR func_end = 0;
  CORE_ADDR addr;
  ULONGEST insn;
  long offset;
  int dreg;
  int sreg;
  int loc;

  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    return 0;

  /* The microMIPS epilogue is max. 12 bytes long.  */
  addr = func_end - 12;

  if (addr < func_addr + 2)
    addr = func_addr + 2;
  if (pc < addr)
    return 0;

  for (; pc < func_end; pc += loc)
    {
      loc = 0;
      insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
      loc += MIPS_INSN16_SIZE;
      switch (mips_insn_size (ISA_MICROMIPS, insn))
	{
	/* 32-bit instructions.  */
	case 2 * MIPS_INSN16_SIZE:
	  insn <<= 16;
	  insn |= mips_fetch_instruction (gdbarch,
					  ISA_MICROMIPS, pc + loc, NULL);
	  loc += MIPS_INSN16_SIZE;
	  switch (micromips_op (insn >> 16))
	    {
	    case 0xc: /* ADDIU: bits 001100 */
	    case 0x17: /* DADDIU: bits 010111 */
	      sreg = b0s5_reg (insn >> 16);
	      dreg = b5s5_reg (insn >> 16);
	      offset = (b0s16_imm (insn) ^ 0x8000) - 0x8000;
	      if (sreg == MIPS_SP_REGNUM && dreg == MIPS_SP_REGNUM
			    /* (D)ADDIU $sp, imm */
		  && offset >= 0)
		break;
	      return 0;

	    default:
	      return 0;
	    }
	  break;

	/* 16-bit instructions.  */
	case MIPS_INSN16_SIZE:
	  switch (micromips_op (insn))
	    {
	    case 0x3: /* MOVE: bits 000011 */
	      sreg = b0s5_reg (insn);
	      dreg = b5s5_reg (insn);
	      if (sreg == 0 && dreg == 0)
				/* MOVE $zero, $zero aka NOP */
		break;
	      return 0;

	    case 0x11: /* POOL16C: bits 010001 */
	      if (b5s5_op (insn) == 0x18
				/* JRADDIUSP: bits 010011 11000 */
		  || (b5s5_op (insn) == 0xd
				/* JRC: bits 010011 01101 */
		      && b0s5_reg (insn) == MIPS_RA_REGNUM))
				/* JRC $ra */
		break;
	      return 0;

	    case 0x13: /* POOL16D: bits 010011 */
	      offset = micromips_decode_imm9 (b1s9_imm (insn));
	      if ((insn & 0x1) == 0x1
				/* ADDIUSP: bits 010011 1 */
		  && offset > 0)
		break;
	      return 0;

	    default:
	      return 0;
	    }
	}
    }

  return 1;
}

/* Implement the stack_frame_destroyed_p gdbarch method (16-bit version).
   This is a helper function for mips_stack_frame_destroyed_p.  */

static int
mips16_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr = 0, func_end = 0;

  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    {
      /* The MIPS epilogue is max. 12 bytes long.  */
      CORE_ADDR addr = func_end - 12;

      if (addr < func_addr + 4)
	addr = func_addr + 4;
      if (pc < addr)
	return 0;

      for (; pc < func_end; pc += MIPS_INSN16_SIZE)
	{
	  unsigned short inst;

	  inst = mips_fetch_instruction (gdbarch, ISA_MIPS16, pc, NULL);

	  if ((inst & 0xf800) == 0xf000)	/* extend */
	    continue;

	  if (inst != 0x6300		/* addiu $sp,offset */
	      && inst != 0xfb00		/* daddiu $sp,$sp,offset */
	      && inst != 0xe820		/* jr $ra */
	      && inst != 0xe8a0		/* jrc $ra */
	      && inst != 0x6500)	/* nop */
	    return 0;
	}

      return 1;
    }

  return 0;
}

/* Implement the stack_frame_destroyed_p gdbarch method.

   The epilogue is defined here as the area at the end of a function,
   after an instruction which destroys the function's stack frame.  */

static int
mips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  if (mips_pc_is_mips16 (gdbarch, pc))
    return mips16_stack_frame_destroyed_p (gdbarch, pc);
  else if (mips_pc_is_micromips (gdbarch, pc))
    return micromips_stack_frame_destroyed_p (gdbarch, pc);
  else
    return mips32_stack_frame_destroyed_p (gdbarch, pc);
}

/* Commands to show/set the MIPS FPU type.  */

static void
show_mipsfpu_command (const char *args, int from_tty)
{
  const char *fpu;

  if (gdbarch_bfd_arch_info (current_inferior ()->arch ())->arch
      != bfd_arch_mips)
    {
      gdb_printf
	("The MIPS floating-point coprocessor is unknown "
	 "because the current architecture is not MIPS.\n");
      return;
    }

  switch (mips_get_fpu_type (current_inferior ()->arch  ()))
    {
    case MIPS_FPU_SINGLE:
      fpu = "single-precision";
      break;
    case MIPS_FPU_DOUBLE:
      fpu = "double-precision";
      break;
    case MIPS_FPU_NONE:
      fpu = "absent (none)";
      break;
    default:
      internal_error (_("bad switch"));
    }
  if (mips_fpu_type_auto)
    gdb_printf ("The MIPS floating-point coprocessor "
		"is set automatically (currently %s)\n",
		fpu);
  else
    gdb_printf
      ("The MIPS floating-point coprocessor is assumed to be %s\n", fpu);
}


static void
set_mipsfpu_single_command (const char *args, int from_tty)
{
  struct gdbarch_info info;
  mips_fpu_type = MIPS_FPU_SINGLE;
  mips_fpu_type_auto = 0;
  /* FIXME: cagney/2003-11-15: Should be setting a field in "info"
     instead of relying on globals.  Doing that would let generic code
     handle the search for this specific architecture.  */
  if (!gdbarch_update_p (info))
    internal_error (_("set mipsfpu failed"));
}

static void
set_mipsfpu_double_command (const char *args, int from_tty)
{
  struct gdbarch_info info;
  mips_fpu_type = MIPS_FPU_DOUBLE;
  mips_fpu_type_auto = 0;
  /* FIXME: cagney/2003-11-15: Should be setting a field in "info"
     instead of relying on globals.  Doing that would let generic code
     handle the search for this specific architecture.  */
  if (!gdbarch_update_p (info))
    internal_error (_("set mipsfpu failed"));
}

static void
set_mipsfpu_none_command (const char *args, int from_tty)
{
  struct gdbarch_info info;
  mips_fpu_type = MIPS_FPU_NONE;
  mips_fpu_type_auto = 0;
  /* FIXME: cagney/2003-11-15: Should be setting a field in "info"
     instead of relying on globals.  Doing that would let generic code
     handle the search for this specific architecture.  */
  if (!gdbarch_update_p (info))
    internal_error (_("set mipsfpu failed"));
}

static void
set_mipsfpu_auto_command (const char *args, int from_tty)
{
  mips_fpu_type_auto = 1;
}

/* Just like reinit_frame_cache, but with the right arguments to be
   callable as an sfunc.  */

static void
reinit_frame_cache_sfunc (const char *args, int from_tty,
			  struct cmd_list_element *c)
{
  reinit_frame_cache ();
}

static int
gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info)
{
  gdb_disassemble_info *di
    = static_cast<gdb_disassemble_info *> (info->application_data);
  struct gdbarch *gdbarch = di->arch ();

  /* FIXME: cagney/2003-06-26: Is this even necessary?  The
     disassembler needs to be able to locally determine the ISA, and
     not rely on GDB.  Otherwize the stand-alone 'objdump -d' will not
     work.  */
  if (mips_pc_is_mips16 (gdbarch, memaddr))
    info->mach = bfd_mach_mips16;
  else if (mips_pc_is_micromips (gdbarch, memaddr))
    info->mach = bfd_mach_mips_micromips;

  /* Round down the instruction address to the appropriate boundary.  */
  memaddr &= (info->mach == bfd_mach_mips16
	      || info->mach == bfd_mach_mips_micromips) ? ~1 : ~3;

  return default_print_insn (memaddr, info);
}

/* Implement the breakpoint_kind_from_pc gdbarch method.  */

static int
mips_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
  CORE_ADDR pc = *pcptr;

  if (mips_pc_is_mips16 (gdbarch, pc))
    {
      *pcptr = unmake_compact_addr (pc);
      return MIPS_BP_KIND_MIPS16;
    }
  else if (mips_pc_is_micromips (gdbarch, pc))
    {
      ULONGEST insn;
      int status;

      *pcptr = unmake_compact_addr (pc);
      insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
      if (status || (mips_insn_size (ISA_MICROMIPS, insn) == 2))
	return MIPS_BP_KIND_MICROMIPS16;
      else
	return MIPS_BP_KIND_MICROMIPS32;
    }
  else
    return MIPS_BP_KIND_MIPS32;
}

/* Implement the sw_breakpoint_from_kind gdbarch method.  */

static const gdb_byte *
mips_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);

  switch (kind)
    {
    case MIPS_BP_KIND_MIPS16:
      {
	static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
	static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };

	*size = 2;
	if (byte_order_for_code == BFD_ENDIAN_BIG)
	  return mips16_big_breakpoint;
	else
	  return mips16_little_breakpoint;
      }
    case MIPS_BP_KIND_MICROMIPS16:
      {
	static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 };
	static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 };

	*size = 2;

	if (byte_order_for_code == BFD_ENDIAN_BIG)
	  return micromips16_big_breakpoint;
	else
	  return micromips16_little_breakpoint;
      }
    case MIPS_BP_KIND_MICROMIPS32:
      {
	static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 };
	static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 };

	*size = 4;
	if (byte_order_for_code == BFD_ENDIAN_BIG)
	  return micromips32_big_breakpoint;
	else
	  return micromips32_little_breakpoint;
      }
    case MIPS_BP_KIND_MIPS32:
      {
	static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd };
	static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };

	*size = 4;
	if (byte_order_for_code == BFD_ENDIAN_BIG)
	  return big_breakpoint;
	else
	  return little_breakpoint;
      }
    default:
      gdb_assert_not_reached ("unexpected mips breakpoint kind");
    };
}

/* Return non-zero if the standard MIPS instruction INST has a branch
   delay slot (i.e. it is a jump or branch instruction).  This function
   is based on mips32_next_pc.  */

static int
mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, ULONGEST inst)
{
  int op;
  int rs;
  int rt;

  op = itype_op (inst);
  if ((inst & 0xe0000000) != 0)
    {
      rs = itype_rs (inst);
      rt = itype_rt (inst);
      return (is_octeon_bbit_op (op, gdbarch) 
	      || op >> 2 == 5	/* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx  */
	      || op == 29	/* JALX: bits 011101  */
	      || (op == 17
		  && (rs == 8
				/* BC1F, BC1FL, BC1T, BC1TL: 010001 01000  */
		      || (rs == 9 && (rt & 0x2) == 0)
				/* BC1ANY2F, BC1ANY2T: bits 010001 01001  */
		      || (rs == 10 && (rt & 0x2) == 0))));
				/* BC1ANY4F, BC1ANY4T: bits 010001 01010  */
    }
  else
    switch (op & 0x07)		/* extract bits 28,27,26  */
      {
      case 0:			/* SPECIAL  */
	op = rtype_funct (inst);
	return (op == 8		/* JR  */
		|| op == 9);	/* JALR  */
	break;			/* end SPECIAL  */
      case 1:			/* REGIMM  */
	rs = itype_rs (inst);
	rt = itype_rt (inst);	/* branch condition  */
	return ((rt & 0xc) == 0
				/* BLTZ, BLTZL, BGEZ, BGEZL: bits 000xx  */
				/* BLTZAL, BLTZALL, BGEZAL, BGEZALL: 100xx  */
		|| ((rt & 0x1e) == 0x1c && rs == 0));
				/* BPOSGE32, BPOSGE64: bits 1110x  */
	break;			/* end REGIMM  */
      default:			/* J, JAL, BEQ, BNE, BLEZ, BGTZ  */
	return 1;
	break;
      }
}

/* Return non-zero if a standard MIPS instruction at ADDR has a branch
   delay slot (i.e. it is a jump or branch instruction).  */

static int
mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  ULONGEST insn;
  int status;

  insn = mips_fetch_instruction (gdbarch, ISA_MIPS, addr, &status);
  if (status)
    return 0;

  return mips32_instruction_has_delay_slot (gdbarch, insn);
}

/* Return non-zero if the microMIPS instruction INSN, comprising the
   16-bit major opcode word in the high 16 bits and any second word
   in the low 16 bits, has a branch delay slot (i.e. it is a non-compact
   jump or branch instruction).  The instruction must be 32-bit if
   MUSTBE32 is set or can be any instruction otherwise.  */

static int
micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32)
{
  ULONGEST major = insn >> 16;

  switch (micromips_op (major))
    {
    /* 16-bit instructions.  */
    case 0x33:			/* B16: bits 110011 */
    case 0x2b:			/* BNEZ16: bits 101011 */
    case 0x23:			/* BEQZ16: bits 100011 */
      return !mustbe32;
    case 0x11:			/* POOL16C: bits 010001 */
      return (!mustbe32
	      && ((b5s5_op (major) == 0xc
				/* JR16: bits 010001 01100 */
		  || (b5s5_op (major) & 0x1e) == 0xe)));
				/* JALR16, JALRS16: bits 010001 0111x */
    /* 32-bit instructions.  */
    case 0x3d:			/* JAL: bits 111101 */
    case 0x3c:			/* JALX: bits 111100 */
    case 0x35:			/* J: bits 110101 */
    case 0x2d:			/* BNE: bits 101101 */
    case 0x25:			/* BEQ: bits 100101 */
    case 0x1d:			/* JALS: bits 011101 */
      return 1;
    case 0x10:			/* POOL32I: bits 010000 */
      return ((b5s5_op (major) & 0x1c) == 0x0
				/* BLTZ, BLTZAL, BGEZ, BGEZAL: 010000 000xx */
	      || (b5s5_op (major) & 0x1d) == 0x4
				/* BLEZ, BGTZ: bits 010000 001x0 */
	      || (b5s5_op (major) & 0x1d) == 0x11
				/* BLTZALS, BGEZALS: bits 010000 100x1 */
	      || ((b5s5_op (major) & 0x1e) == 0x14
		  && (major & 0x3) == 0x0)
				/* BC2F, BC2T: bits 010000 1010x xxx00 */
	      || (b5s5_op (major) & 0x1e) == 0x1a
				/* BPOSGE64, BPOSGE32: bits 010000 1101x */
	      || ((b5s5_op (major) & 0x1e) == 0x1c
		  && (major & 0x3) == 0x0)
				/* BC1F, BC1T: bits 010000 1110x xxx00 */
	      || ((b5s5_op (major) & 0x1c) == 0x1c
		  && (major & 0x3) == 0x1));
				/* BC1ANY*: bits 010000 111xx xxx01 */
    case 0x0:			/* POOL32A: bits 000000 */
      return (b0s6_op (insn) == 0x3c
				/* POOL32Axf: bits 000000 ... 111100 */
	      && (b6s10_ext (insn) & 0x2bf) == 0x3c);
				/* JALR, JALR.HB: 000000 000x111100 111100 */
				/* JALRS, JALRS.HB: 000000 010x111100 111100 */
    default:
      return 0;
    }
}

/* Return non-zero if a microMIPS instruction at ADDR has a branch delay
   slot (i.e. it is a non-compact jump instruction).  The instruction
   must be 32-bit if MUSTBE32 is set or can be any instruction otherwise.  */

static int
micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
				     CORE_ADDR addr, int mustbe32)
{
  ULONGEST insn;
  int status;
  int size;

  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
  if (status)
    return 0;
  size = mips_insn_size (ISA_MICROMIPS, insn);
  insn <<= 16;
  if (size == 2 * MIPS_INSN16_SIZE)
    {
      insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
      if (status)
	return 0;
    }

  return micromips_instruction_has_delay_slot (insn, mustbe32);
}

/* Return non-zero if the MIPS16 instruction INST, which must be
   a 32-bit instruction if MUSTBE32 is set or can be any instruction
   otherwise, has a branch delay slot (i.e. it is a non-compact jump
   instruction).  This function is based on mips16_next_pc.  */

static int
mips16_instruction_has_delay_slot (unsigned short inst, int mustbe32)
{
  if ((inst & 0xf89f) == 0xe800)	/* JR/JALR (16-bit instruction)  */
    return !mustbe32;
  return (inst & 0xf800) == 0x1800;	/* JAL/JALX (32-bit instruction)  */
}

/* Return non-zero if a MIPS16 instruction at ADDR has a branch delay
   slot (i.e. it is a non-compact jump instruction).  The instruction
   must be 32-bit if MUSTBE32 is set or can be any instruction otherwise.  */

static int
mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
				  CORE_ADDR addr, int mustbe32)
{
  unsigned short insn;
  int status;

  insn = mips_fetch_instruction (gdbarch, ISA_MIPS16, addr, &status);
  if (status)
    return 0;

  return mips16_instruction_has_delay_slot (insn, mustbe32);
}

/* Calculate the starting address of the MIPS memory segment BPADDR is in.
   This assumes KSSEG exists.  */

static CORE_ADDR
mips_segment_boundary (CORE_ADDR bpaddr)
{
  CORE_ADDR mask = CORE_ADDR_MAX;
  int segsize;

  if (sizeof (CORE_ADDR) == 8)
    /* Get the topmost two bits of bpaddr in a 32-bit safe manner (avoid
       a compiler warning produced where CORE_ADDR is a 32-bit type even
       though in that case this is dead code).  */
    switch (bpaddr >> ((sizeof (CORE_ADDR) << 3) - 2) & 3)
      {
      case 3:
	if (bpaddr == (bfd_signed_vma) (int32_t) bpaddr)
	  segsize = 29;			/* 32-bit compatibility segment  */
	else
	  segsize = 62;			/* xkseg  */
	break;
      case 2:				/* xkphys  */
	segsize = 59;
	break;
      default:				/* xksseg (1), xkuseg/kuseg (0)  */
	segsize = 62;
	break;
      }
  else if (bpaddr & 0x80000000)		/* kernel segment  */
    segsize = 29;
  else
    segsize = 31;			/* user segment  */
  mask <<= segsize;
  return bpaddr & mask;
}

/* Move the breakpoint at BPADDR out of any branch delay slot by shifting
   it backwards if necessary.  Return the address of the new location.  */

static CORE_ADDR
mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
{
  CORE_ADDR prev_addr;
  CORE_ADDR boundary;
  CORE_ADDR func_addr;

  /* If a breakpoint is set on the instruction in a branch delay slot,
     GDB gets confused.  When the breakpoint is hit, the PC isn't on
     the instruction in the branch delay slot, the PC will point to
     the branch instruction.  Since the PC doesn't match any known
     breakpoints, GDB reports a trap exception.

     There are two possible fixes for this problem.

     1) When the breakpoint gets hit, see if the BD bit is set in the
     Cause register (which indicates the last exception occurred in a
     branch delay slot).  If the BD bit is set, fix the PC to point to
     the instruction in the branch delay slot.

     2) When the user sets the breakpoint, don't allow him to set the
     breakpoint on the instruction in the branch delay slot.  Instead
     move the breakpoint to the branch instruction (which will have
     the same result).

     The problem with the first solution is that if the user then
     single-steps the processor, the branch instruction will get
     skipped (since GDB thinks the PC is on the instruction in the
     branch delay slot).

     So, we'll use the second solution.  To do this we need to know if
     the instruction we're trying to set the breakpoint on is in the
     branch delay slot.  */

  boundary = mips_segment_boundary (bpaddr);

  /* Make sure we don't scan back before the beginning of the current
     function, since we may fetch constant data or insns that look like
     a jump.  Of course we might do that anyway if the compiler has
     moved constants inline. :-(  */
  if (find_pc_partial_function (bpaddr, NULL, &func_addr, NULL)
      && func_addr > boundary && func_addr <= bpaddr)
    boundary = func_addr;

  if (mips_pc_is_mips (bpaddr))
    {
      if (bpaddr == boundary)
	return bpaddr;

      /* If the previous instruction has a branch delay slot, we have
	 to move the breakpoint to the branch instruction. */
      prev_addr = bpaddr - 4;
      if (mips32_insn_at_pc_has_delay_slot (gdbarch, prev_addr))
	bpaddr = prev_addr;
    }
  else
    {
      int (*insn_at_pc_has_delay_slot) (struct gdbarch *, CORE_ADDR, int);
      CORE_ADDR addr, jmpaddr;
      int i;

      boundary = unmake_compact_addr (boundary);

      /* The only MIPS16 instructions with delay slots are JAL, JALX,
	 JALR and JR.  An absolute JAL/JALX is always 4 bytes long,
	 so try for that first, then try the 2 byte JALR/JR.
	 The microMIPS ASE has a whole range of jumps and branches
	 with delay slots, some of which take 4 bytes and some take
	 2 bytes, so the idea is the same.
	 FIXME: We have to assume that bpaddr is not the second half
	 of an extended instruction.  */
      insn_at_pc_has_delay_slot = (mips_pc_is_micromips (gdbarch, bpaddr)
				   ? micromips_insn_at_pc_has_delay_slot
				   : mips16_insn_at_pc_has_delay_slot);

      jmpaddr = 0;
      addr = bpaddr;
      for (i = 1; i < 4; i++)
	{
	  if (unmake_compact_addr (addr) == boundary)
	    break;
	  addr -= MIPS_INSN16_SIZE;
	  if (i == 1 && insn_at_pc_has_delay_slot (gdbarch, addr, 0))
	    /* Looks like a JR/JALR at [target-1], but it could be
	       the second word of a previous JAL/JALX, so record it
	       and check back one more.  */
	    jmpaddr = addr;
	  else if (i > 1 && insn_at_pc_has_delay_slot (gdbarch, addr, 1))
	    {
	      if (i == 2)
		/* Looks like a JAL/JALX at [target-2], but it could also
		   be the second word of a previous JAL/JALX, record it,
		   and check back one more.  */
		jmpaddr = addr;
	      else
		/* Looks like a JAL/JALX at [target-3], so any previously
		   recorded JAL/JALX or JR/JALR must be wrong, because:

		   >-3: JAL
		    -2: JAL-ext (can't be JAL/JALX)
		    -1: bdslot (can't be JR/JALR)
		     0: target insn

		   Of course it could be another JAL-ext which looks
		   like a JAL, but in that case we'd have broken out
		   of this loop at [target-2]:

		    -4: JAL
		   >-3: JAL-ext
		    -2: bdslot (can't be jmp)
		    -1: JR/JALR
		     0: target insn  */
		jmpaddr = 0;
	    }
	  else
	    {
	      /* Not a jump instruction: if we're at [target-1] this
		 could be the second word of a JAL/JALX, so continue;
		 otherwise we're done.  */
	      if (i > 1)
		break;
	    }
	}

      if (jmpaddr)
	bpaddr = jmpaddr;
    }

  return bpaddr;
}

/* Return non-zero if SUFFIX is one of the numeric suffixes used for MIPS16
   call stubs, one of 1, 2, 5, 6, 9, 10, or, if ZERO is non-zero, also 0.  */

static int
mips_is_stub_suffix (const char *suffix, int zero)
{
  switch (suffix[0])
   {
   case '0':
     return zero && suffix[1] == '\0';
   case '1':
     return suffix[1] == '\0' || (suffix[1] == '0' && suffix[2] == '\0');
   case '2':
   case '5':
   case '6':
   case '9':
     return suffix[1] == '\0';
   default:
     return 0;
   }
}

/* Return non-zero if MODE is one of the mode infixes used for MIPS16
   call stubs, one of sf, df, sc, or dc.  */

static int
mips_is_stub_mode (const char *mode)
{
  return ((mode[0] == 's' || mode[0] == 'd')
	  && (mode[1] == 'f' || mode[1] == 'c'));
}

/* Code at PC is a compiler-generated stub.  Such a stub for a function
   bar might have a name like __fn_stub_bar, and might look like this:

      mfc1    $4, $f13
      mfc1    $5, $f12
      mfc1    $6, $f15
      mfc1    $7, $f14

   followed by (or interspersed with):

      j       bar

   or:

      lui     $25, %hi(bar)
      addiu   $25, $25, %lo(bar)
      jr      $25

   ($1 may be used in old code; for robustness we accept any register)
   or, in PIC code:

      lui     $28, %hi(_gp_disp)
      addiu   $28, $28, %lo(_gp_disp)
      addu    $28, $28, $25
      lw      $25, %got(bar)
      addiu   $25, $25, %lo(bar)
      jr      $25

   In the case of a __call_stub_bar stub, the sequence to set up
   arguments might look like this:

      mtc1    $4, $f13
      mtc1    $5, $f12
      mtc1    $6, $f15
      mtc1    $7, $f14

   followed by (or interspersed with) one of the jump sequences above.

   In the case of a __call_stub_fp_bar stub, JAL or JALR is used instead
   of J or JR, respectively, followed by:

      mfc1    $2, $f0
      mfc1    $3, $f1
      jr      $18

   We are at the beginning of the stub here, and scan down and extract
   the target address from the jump immediate instruction or, if a jump
   register instruction is used, from the register referred.  Return
   the value of PC calculated or 0 if inconclusive.

   The limit on the search is arbitrarily set to 20 instructions.  FIXME.  */

static CORE_ADDR
mips_get_mips16_fn_stub_pc (const frame_info_ptr &frame, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int addrreg = MIPS_ZERO_REGNUM;
  CORE_ADDR start_pc = pc;
  CORE_ADDR target_pc = 0;
  CORE_ADDR addr = 0;
  CORE_ADDR gp = 0;
  int status = 0;
  int i;

  for (i = 0;
       status == 0 && target_pc == 0 && i < 20;
       i++, pc += MIPS_INSN32_SIZE)
    {
      ULONGEST inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
      CORE_ADDR imm;
      int rt;
      int rs;
      int rd;

      switch (itype_op (inst))
	{
	case 0:		/* SPECIAL */
	  switch (rtype_funct (inst))
	    {
	    case 8:		/* JR */
	    case 9:		/* JALR */
	      rs = rtype_rs (inst);
	      if (rs == MIPS_GP_REGNUM)
		target_pc = gp;				/* Hmm...  */
	      else if (rs == addrreg)
		target_pc = addr;
	      break;

	    case 0x21:		/* ADDU */
	      rt = rtype_rt (inst);
	      rs = rtype_rs (inst);
	      rd = rtype_rd (inst);
	      if (rd == MIPS_GP_REGNUM
		  && ((rs == MIPS_GP_REGNUM && rt == MIPS_T9_REGNUM)
		      || (rs == MIPS_T9_REGNUM && rt == MIPS_GP_REGNUM)))
		gp += start_pc;
	      break;
	    }
	  break;

	case 2:		/* J */
	case 3:		/* JAL */
	  target_pc = jtype_target (inst) << 2;
	  target_pc += ((pc + 4) & ~(CORE_ADDR) 0x0fffffff);
	  break;

	case 9:		/* ADDIU */
	  rt = itype_rt (inst);
	  rs = itype_rs (inst);
	  if (rt == rs)
	    {
	      imm = (itype_immediate (inst) ^ 0x8000) - 0x8000;
	      if (rt == MIPS_GP_REGNUM)
		gp += imm;
	      else if (rt == addrreg)
		addr += imm;
	    }
	  break;

	case 0xf:	/* LUI */
	  rt = itype_rt (inst);
	  imm = ((itype_immediate (inst) ^ 0x8000) - 0x8000) << 16;
	  if (rt == MIPS_GP_REGNUM)
	    gp = imm;
	  else if (rt != MIPS_ZERO_REGNUM)
	    {
	      addrreg = rt;
	      addr = imm;
	    }
	  break;

	case 0x23:	/* LW */
	  rt = itype_rt (inst);
	  rs = itype_rs (inst);
	  imm = (itype_immediate (inst) ^ 0x8000) - 0x8000;
	  if (gp != 0 && rs == MIPS_GP_REGNUM)
	    {
	      gdb_byte buf[4];

	      memset (buf, 0, sizeof (buf));
	      status = target_read_memory (gp + imm, buf, sizeof (buf));
	      addrreg = rt;
	      addr = extract_signed_integer (buf, sizeof (buf), byte_order);
	    }
	  break;
	}
    }

  return target_pc;
}

/* If PC is in a MIPS16 call or return stub, return the address of the
   target PC, which is either the callee or the caller.  There are several
   cases which must be handled:

   * If the PC is in __mips16_ret_{d,s}{f,c}, this is a return stub
     and the target PC is in $31 ($ra).
   * If the PC is in __mips16_call_stub_{1..10}, this is a call stub
     and the target PC is in $2.
   * If the PC at the start of __mips16_call_stub_{s,d}{f,c}_{0..10},
     i.e. before the JALR instruction, this is effectively a call stub
     and the target PC is in $2.  Otherwise this is effectively
     a return stub and the target PC is in $18.
   * If the PC is at the start of __call_stub_fp_*, i.e. before the
     JAL or JALR instruction, this is effectively a call stub and the
     target PC is buried in the instruction stream.  Otherwise this
     is effectively a return stub and the target PC is in $18.
   * If the PC is in __call_stub_* or in __fn_stub_*, this is a call
     stub and the target PC is buried in the instruction stream.

   See the source code for the stubs in gcc/config/mips/mips16.S, or the
   stub builder in gcc/config/mips/mips.c (mips16_build_call_stub) for the
   gory details.  */

static CORE_ADDR
mips_skip_mips16_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  CORE_ADDR start_addr;
  const char *name;
  size_t prefixlen;

  /* Find the starting address and name of the function containing the PC.  */
  if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
    return 0;

  /* If the PC is in __mips16_ret_{d,s}{f,c}, this is a return stub
     and the target PC is in $31 ($ra).  */
  prefixlen = strlen (mips_str_mips16_ret_stub);
  if (strncmp (name, mips_str_mips16_ret_stub, prefixlen) == 0
      && mips_is_stub_mode (name + prefixlen)
      && name[prefixlen + 2] == '\0')
    return get_frame_register_signed
	     (frame, gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM);

  /* If the PC is in __mips16_call_stub_*, this is one of the call
     call/return stubs.  */
  prefixlen = strlen (mips_str_mips16_call_stub);
  if (strncmp (name, mips_str_mips16_call_stub, prefixlen) == 0)
    {
      /* If the PC is in __mips16_call_stub_{1..10}, this is a call stub
	 and the target PC is in $2.  */
      if (mips_is_stub_suffix (name + prefixlen, 0))
	return get_frame_register_signed
		 (frame, gdbarch_num_regs (gdbarch) + MIPS_V0_REGNUM);

      /* If the PC at the start of __mips16_call_stub_{s,d}{f,c}_{0..10},
	 i.e. before the JALR instruction, this is effectively a call stub
	 and the target PC is in $2.  Otherwise this is effectively
	 a return stub and the target PC is in $18.  */
      else if (mips_is_stub_mode (name + prefixlen)
	       && name[prefixlen + 2] == '_'
	       && mips_is_stub_suffix (name + prefixlen + 3, 0))
	{
	  if (pc == start_addr)
	    /* This is the 'call' part of a call stub.  The return
	       address is in $2.  */
	    return get_frame_register_signed
		     (frame, gdbarch_num_regs (gdbarch) + MIPS_V0_REGNUM);
	  else
	    /* This is the 'return' part of a call stub.  The return
	       address is in $18.  */
	    return get_frame_register_signed
		     (frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
	}
      else
	return 0;		/* Not a stub.  */
    }

  /* If the PC is in __call_stub_* or __fn_stub*, this is one of the
     compiler-generated call or call/return stubs.  */
  if (startswith (name, mips_str_fn_stub)
      || startswith (name, mips_str_call_stub))
    {
      if (pc == start_addr)
	/* This is the 'call' part of a call stub.  Call this helper
	   to scan through this code for interesting instructions
	   and determine the final PC.  */
	return mips_get_mips16_fn_stub_pc (frame, pc);
      else
	/* This is the 'return' part of a call stub.  The return address
	   is in $18.  */
	return get_frame_register_signed
		 (frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
    }

  return 0;			/* Not a stub.  */
}

/* Return non-zero if the PC is inside a return thunk (aka stub or trampoline).
   This implements the IN_SOLIB_RETURN_TRAMPOLINE macro.  */

static int
mips_in_return_stub (struct gdbarch *gdbarch, CORE_ADDR pc, const char *name)
{
  CORE_ADDR start_addr;
  size_t prefixlen;

  /* Find the starting address of the function containing the PC.  */
  if (find_pc_partial_function (pc, NULL, &start_addr, NULL) == 0)
    return 0;

  /* If the PC is in __mips16_call_stub_{s,d}{f,c}_{0..10} but not at
     the start, i.e. after the JALR instruction, this is effectively
     a return stub.  */
  prefixlen = strlen (mips_str_mips16_call_stub);
  if (pc != start_addr
      && strncmp (name, mips_str_mips16_call_stub, prefixlen) == 0
      && mips_is_stub_mode (name + prefixlen)
      && name[prefixlen + 2] == '_'
      && mips_is_stub_suffix (name + prefixlen + 3, 1))
    return 1;

  /* If the PC is in __call_stub_fp_* but not at the start, i.e. after
     the JAL or JALR instruction, this is effectively a return stub.  */
  prefixlen = strlen (mips_str_call_fp_stub);
  if (pc != start_addr
      && strncmp (name, mips_str_call_fp_stub, prefixlen) == 0)
    return 1;

  /* Consume the .pic. prefix of any PIC stub, this function must return
     true when the PC is in a PIC stub of a __mips16_ret_{d,s}{f,c} stub
     or the call stub path will trigger in handle_inferior_event causing
     it to go astray.  */
  prefixlen = strlen (mips_str_pic);
  if (strncmp (name, mips_str_pic, prefixlen) == 0)
    name += prefixlen;

  /* If the PC is in __mips16_ret_{d,s}{f,c}, this is a return stub.  */
  prefixlen = strlen (mips_str_mips16_ret_stub);
  if (strncmp (name, mips_str_mips16_ret_stub, prefixlen) == 0
      && mips_is_stub_mode (name + prefixlen)
      && name[prefixlen + 2] == '\0')
    return 1;

  return 0;			/* Not a stub.  */
}

/* If the current PC is the start of a non-PIC-to-PIC stub, return the
   PC of the stub target.  The stub just loads $t9 and jumps to it,
   so that $t9 has the correct value at function entry.  */

static CORE_ADDR
mips_skip_pic_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct bound_minimal_symbol msym;
  int i;
  gdb_byte stub_code[16];
  int32_t stub_words[4];

  /* The stub for foo is named ".pic.foo", and is either two
     instructions inserted before foo or a three instruction sequence
     which jumps to foo.  */
  msym = lookup_minimal_symbol_by_pc (pc);
  if (msym.minsym == NULL
      || msym.value_address () != pc
      || msym.minsym->linkage_name () == NULL
      || !startswith (msym.minsym->linkage_name (), ".pic."))
    return 0;

  /* A two-instruction header.  */
  if (msym.minsym->size () == 8)
    return pc + 8;

  /* A three-instruction (plus delay slot) trampoline.  */
  if (msym.minsym->size () == 16)
    {
      if (target_read_memory (pc, stub_code, 16) != 0)
	return 0;
      for (i = 0; i < 4; i++)
	stub_words[i] = extract_unsigned_integer (stub_code + i * 4,
						  4, byte_order);

      /* A stub contains these instructions:
	 lui	t9, %hi(target)
	 j	target
	  addiu	t9, t9, %lo(target)
	 nop

	 This works even for N64, since stubs are only generated with
	 -msym32.  */
      if ((stub_words[0] & 0xffff0000U) == 0x3c190000
	  && (stub_words[1] & 0xfc000000U) == 0x08000000
	  && (stub_words[2] & 0xffff0000U) == 0x27390000
	  && stub_words[3] == 0x00000000)
	return ((((stub_words[0] & 0x0000ffff) << 16)
		 + (stub_words[2] & 0x0000ffff)) ^ 0x8000) - 0x8000;
    }

  /* Not a recognized stub.  */
  return 0;
}

static CORE_ADDR
mips_skip_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc)
{
  CORE_ADDR requested_pc = pc;
  CORE_ADDR target_pc;
  CORE_ADDR new_pc;

  do
    {
      target_pc = pc;

      new_pc = mips_skip_mips16_trampoline_code (frame, pc);
      if (new_pc)
	pc = new_pc;

      new_pc = find_solib_trampoline_target (frame, pc);
      if (new_pc)
	pc = new_pc;

      new_pc = mips_skip_pic_trampoline_code (frame, pc);
      if (new_pc)
	pc = new_pc;
    }
  while (pc != target_pc);

  return pc != requested_pc ? pc : 0;
}

/* Convert a dbx stab register number (from `r' declaration) to a GDB
   [1 * gdbarch_num_regs .. 2 * gdbarch_num_regs) REGNUM.  */

static int
mips_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
{
  int regnum;
  if (num >= 0 && num < 32)
    regnum = num;
  else if (num >= 38 && num < 70)
    regnum = num + mips_regnum (gdbarch)->fp0 - 38;
  else if (num == 70)
    regnum = mips_regnum (gdbarch)->hi;
  else if (num == 71)
    regnum = mips_regnum (gdbarch)->lo;
  else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 72 && num < 78)
    regnum = num + mips_regnum (gdbarch)->dspacc - 72;
  else
    return -1;
  return gdbarch_num_regs (gdbarch) + regnum;
}


/* Convert a dwarf, dwarf2, or ecoff register number to a GDB [1 *
   gdbarch_num_regs .. 2 * gdbarch_num_regs) REGNUM.  */

static int
mips_dwarf_dwarf2_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int num)
{
  int regnum;
  if (num >= 0 && num < 32)
    regnum = num;
  else if (num >= 32 && num < 64)
    regnum = num + mips_regnum (gdbarch)->fp0 - 32;
  else if (num == 64)
    regnum = mips_regnum (gdbarch)->hi;
  else if (num == 65)
    regnum = mips_regnum (gdbarch)->lo;
  else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 66 && num < 72)
    regnum = num + mips_regnum (gdbarch)->dspacc - 66;
  else
    return -1;
  return gdbarch_num_regs (gdbarch) + regnum;
}

static int
mips_register_sim_regno (struct gdbarch *gdbarch, int regnum)
{
  /* Only makes sense to supply raw registers.  */
  gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch));
  /* FIXME: cagney/2002-05-13: Need to look at the pseudo register to
     decide if it is valid.  Should instead define a standard sim/gdb
     register numbering scheme.  */
  if (gdbarch_register_name (gdbarch,
			     gdbarch_num_regs (gdbarch) + regnum)[0] != '\0')
    return regnum;
  else
    return LEGACY_SIM_REGNO_IGNORE;
}


/* Convert an integer into an address.  Extracting the value signed
   guarantees a correctly sign extended address.  */

static CORE_ADDR
mips_integer_to_address (struct gdbarch *gdbarch,
			 struct type *type, const gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  return extract_signed_integer (buf, type->length (), byte_order);
}

/* Dummy virtual frame pointer method.  This is no more or less accurate
   than most other architectures; we just need to be explicit about it,
   because the pseudo-register gdbarch_sp_regnum will otherwise lead to
   an assertion failure.  */

static void
mips_virtual_frame_pointer (struct gdbarch *gdbarch, 
			    CORE_ADDR pc, int *reg, LONGEST *offset)
{
  *reg = MIPS_SP_REGNUM;
  *offset = 0;
}

static void
mips_find_abi_section (bfd *abfd, asection *sect, void *obj)
{
  enum mips_abi *abip = (enum mips_abi *) obj;
  const char *name = bfd_section_name (sect);

  if (*abip != MIPS_ABI_UNKNOWN)
    return;

  if (!startswith (name, ".mdebug."))
    return;

  if (strcmp (name, ".mdebug.abi32") == 0)
    *abip = MIPS_ABI_O32;
  else if (strcmp (name, ".mdebug.abiN32") == 0)
    *abip = MIPS_ABI_N32;
  else if (strcmp (name, ".mdebug.abi64") == 0)
    *abip = MIPS_ABI_N64;
  else if (strcmp (name, ".mdebug.abiO64") == 0)
    *abip = MIPS_ABI_O64;
  else if (strcmp (name, ".mdebug.eabi32") == 0)
    *abip = MIPS_ABI_EABI32;
  else if (strcmp (name, ".mdebug.eabi64") == 0)
    *abip = MIPS_ABI_EABI64;
  else
    warning (_("unsupported ABI %s."), name + 8);
}

static void
mips_find_long_section (bfd *abfd, asection *sect, void *obj)
{
  int *lbp = (int *) obj;
  const char *name = bfd_section_name (sect);

  if (startswith (name, ".gcc_compiled_long32"))
    *lbp = 32;
  else if (startswith (name, ".gcc_compiled_long64"))
    *lbp = 64;
  else if (startswith (name, ".gcc_compiled_long"))
    warning (_("unrecognized .gcc_compiled_longXX"));
}

static enum mips_abi
global_mips_abi (void)
{
  int i;

  for (i = 0; mips_abi_strings[i] != NULL; i++)
    if (mips_abi_strings[i] == mips_abi_string)
      return (enum mips_abi) i;

  internal_error (_("unknown ABI string"));
}

/* Return the default compressed instruction set, either of MIPS16
   or microMIPS, selected when none could have been determined from
   the ELF header of the binary being executed (or no binary has been
   selected.  */

static enum mips_isa
global_mips_compression (void)
{
  int i;

  for (i = 0; mips_compression_strings[i] != NULL; i++)
    if (mips_compression_strings[i] == mips_compression_string)
      return (enum mips_isa) i;

  internal_error (_("unknown compressed ISA string"));
}

static void
mips_register_g_packet_guesses (struct gdbarch *gdbarch)
{
  /* If the size matches the set of 32-bit or 64-bit integer registers,
     assume that's what we've got.  */
  register_remote_g_packet_guess (gdbarch, 38 * 4, mips_tdesc_gp32);
  register_remote_g_packet_guess (gdbarch, 38 * 8, mips_tdesc_gp64);

  /* If the size matches the full set of registers GDB traditionally
     knows about, including floating point, for either 32-bit or
     64-bit, assume that's what we've got.  */
  register_remote_g_packet_guess (gdbarch, 90 * 4, mips_tdesc_gp32);
  register_remote_g_packet_guess (gdbarch, 90 * 8, mips_tdesc_gp64);

  /* Otherwise we don't have a useful guess.  */
}

static struct value *
value_of_mips_user_reg (const frame_info_ptr &frame, const void *baton)
{
  const int *reg_p = (const int *) baton;
  return value_of_register (*reg_p, get_next_frame_sentinel_okay (frame));
}

static struct gdbarch *
mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  int elf_flags;
  enum mips_abi mips_abi, found_abi, wanted_abi;
  int i, num_regs;
  enum mips_fpu_type fpu_type;
  tdesc_arch_data_up tdesc_data;
  int elf_fpu_type = Val_GNU_MIPS_ABI_FP_ANY;
  const char * const *reg_names;
  struct mips_regnum mips_regnum, *regnum;
  enum mips_isa mips_isa;
  int dspacc;
  int dspctl;

  /* First of all, extract the elf_flags, if available.  */
  if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
    elf_flags = elf_elfheader (info.abfd)->e_flags;
  else if (arches != NULL)
    {
      mips_gdbarch_tdep *tdep
	= gdbarch_tdep<mips_gdbarch_tdep> (arches->gdbarch);
      elf_flags = tdep->elf_flags;
    }
  else
    elf_flags = 0;
  if (gdbarch_debug)
    gdb_printf (gdb_stdlog,
		"mips_gdbarch_init: elf_flags = 0x%08x\n", elf_flags);

  /* Check ELF_FLAGS to see if it specifies the ABI being used.  */
  switch ((elf_flags & EF_MIPS_ABI))
    {
    case EF_MIPS_ABI_O32:
      found_abi = MIPS_ABI_O32;
      break;
    case EF_MIPS_ABI_O64:
      found_abi = MIPS_ABI_O64;
      break;
    case EF_MIPS_ABI_EABI32:
      found_abi = MIPS_ABI_EABI32;
      break;
    case EF_MIPS_ABI_EABI64:
      found_abi = MIPS_ABI_EABI64;
      break;
    default:
      if ((elf_flags & EF_MIPS_ABI2))
	found_abi = MIPS_ABI_N32;
      else
	found_abi = MIPS_ABI_UNKNOWN;
      break;
    }

  /* GCC creates a pseudo-section whose name describes the ABI.  */
  if (found_abi == MIPS_ABI_UNKNOWN && info.abfd != NULL)
    bfd_map_over_sections (info.abfd, mips_find_abi_section, &found_abi);

  /* If we have no useful BFD information, use the ABI from the last
     MIPS architecture (if there is one).  */
  if (found_abi == MIPS_ABI_UNKNOWN && info.abfd == NULL && arches != NULL)
    {
      mips_gdbarch_tdep *tdep
	= gdbarch_tdep<mips_gdbarch_tdep> (arches->gdbarch);
      found_abi = tdep->found_abi;
    }

  /* Try the architecture for any hint of the correct ABI.  */
  if (found_abi == MIPS_ABI_UNKNOWN
      && info.bfd_arch_info != NULL
      && info.bfd_arch_info->arch == bfd_arch_mips)
    {
      switch (info.bfd_arch_info->mach)
	{
	case bfd_mach_mips3900:
	  found_abi = MIPS_ABI_EABI32;
	  break;
	case bfd_mach_mips4100:
	case bfd_mach_mips5000:
	  found_abi = MIPS_ABI_EABI64;
	  break;
	case bfd_mach_mips8000:
	case bfd_mach_mips10000:
	  /* On Irix, ELF64 executables use the N64 ABI.  The
	     pseudo-sections which describe the ABI aren't present
	     on IRIX.  (Even for executables created by gcc.)  */
	  if (info.abfd != NULL
	      && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour
	      && elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64)
	    found_abi = MIPS_ABI_N64;
	  else
	    found_abi = MIPS_ABI_N32;
	  break;
	}
    }

  /* Default 64-bit objects to N64 instead of O32.  */
  if (found_abi == MIPS_ABI_UNKNOWN
      && info.abfd != NULL
      && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour
      && elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64)
    found_abi = MIPS_ABI_N64;

  if (gdbarch_debug)
    gdb_printf (gdb_stdlog, "mips_gdbarch_init: found_abi = %d\n",
		found_abi);

  /* What has the user specified from the command line?  */
  wanted_abi = global_mips_abi ();
  if (gdbarch_debug)
    gdb_printf (gdb_stdlog, "mips_gdbarch_init: wanted_abi = %d\n",
		wanted_abi);

  /* Now that we have found what the ABI for this binary would be,
     check whether the user is overriding it.  */
  if (wanted_abi != MIPS_ABI_UNKNOWN)
    mips_abi = wanted_abi;
  else if (found_abi != MIPS_ABI_UNKNOWN)
    mips_abi = found_abi;
  else
    mips_abi = MIPS_ABI_O32;
  if (gdbarch_debug)
    gdb_printf (gdb_stdlog, "mips_gdbarch_init: mips_abi = %d\n",
		mips_abi);

  /* Make sure we don't use a 32-bit architecture with a 64-bit ABI.  */
  if (mips_abi != MIPS_ABI_EABI32
      && mips_abi != MIPS_ABI_O32
      && info.bfd_arch_info != NULL
      && info.bfd_arch_info->arch == bfd_arch_mips
      && info.bfd_arch_info->bits_per_word < 64)
    info.bfd_arch_info = bfd_lookup_arch (bfd_arch_mips, bfd_mach_mips4000);

  /* Determine the default compressed ISA.  */
  if ((elf_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0
      && (elf_flags & EF_MIPS_ARCH_ASE_M16) == 0)
    mips_isa = ISA_MICROMIPS;
  else if ((elf_flags & EF_MIPS_ARCH_ASE_M16) != 0
	   && (elf_flags & EF_MIPS_ARCH_ASE_MICROMIPS) == 0)
    mips_isa = ISA_MIPS16;
  else
    mips_isa = global_mips_compression ();
  mips_compression_string = mips_compression_strings[mips_isa];

  /* Also used when doing an architecture lookup.  */
  if (gdbarch_debug)
    gdb_printf (gdb_stdlog,
		"mips_gdbarch_init: "
		"mips64_transfers_32bit_regs_p = %d\n",
		mips64_transfers_32bit_regs_p);

  /* Determine the MIPS FPU type.  */
#ifdef HAVE_ELF
  if (info.abfd
      && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
    elf_fpu_type = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
					     Tag_GNU_MIPS_ABI_FP);
#endif /* HAVE_ELF */

  if (!mips_fpu_type_auto)
    fpu_type = mips_fpu_type;
  else if (elf_fpu_type != Val_GNU_MIPS_ABI_FP_ANY)
    {
      switch (elf_fpu_type)
	{
	case Val_GNU_MIPS_ABI_FP_DOUBLE:
	  fpu_type = MIPS_FPU_DOUBLE;
	  break;
	case Val_GNU_MIPS_ABI_FP_SINGLE:
	  fpu_type = MIPS_FPU_SINGLE;
	  break;
	case Val_GNU_MIPS_ABI_FP_SOFT:
	default:
	  /* Soft float or unknown.  */
	  fpu_type = MIPS_FPU_NONE;
	  break;
	}
    }
  else if (info.bfd_arch_info != NULL
	   && info.bfd_arch_info->arch == bfd_arch_mips)
    switch (info.bfd_arch_info->mach)
      {
      case bfd_mach_mips3900:
      case bfd_mach_mips4100:
      case bfd_mach_mips4111:
      case bfd_mach_mips4120:
	fpu_type = MIPS_FPU_NONE;
	break;
      case bfd_mach_mips4650:
	fpu_type = MIPS_FPU_SINGLE;
	break;
      default:
	fpu_type = MIPS_FPU_DOUBLE;
	break;
      }
  else if (arches != NULL)
    fpu_type = mips_get_fpu_type (arches->gdbarch);
  else
    fpu_type = MIPS_FPU_DOUBLE;
  if (gdbarch_debug)
    gdb_printf (gdb_stdlog,
		"mips_gdbarch_init: fpu_type = %d\n", fpu_type);

  /* Check for blatant incompatibilities.  */

  /* If we have only 32-bit registers, then we can't debug a 64-bit
     ABI.  */
  if (info.target_desc
      && tdesc_property (info.target_desc, PROPERTY_GP32) != NULL
      && mips_abi != MIPS_ABI_EABI32
      && mips_abi != MIPS_ABI_O32)
    return NULL;

  /* Fill in the OS dependent register numbers and names.  */
  if (info.osabi == GDB_OSABI_LINUX)
    {
      mips_regnum.fp0 = 38;
      mips_regnum.pc = 37;
      mips_regnum.cause = 36;
      mips_regnum.badvaddr = 35;
      mips_regnum.hi = 34;
      mips_regnum.lo = 33;
      mips_regnum.fp_control_status = 70;
      mips_regnum.fp_implementation_revision = 71;
      mips_regnum.dspacc = -1;
      mips_regnum.dspctl = -1;
      dspacc = 72;
      dspctl = 78;
      num_regs = 90;
      reg_names = mips_linux_reg_names;
    }
  else
    {
      mips_regnum.lo = MIPS_EMBED_LO_REGNUM;
      mips_regnum.hi = MIPS_EMBED_HI_REGNUM;
      mips_regnum.badvaddr = MIPS_EMBED_BADVADDR_REGNUM;
      mips_regnum.cause = MIPS_EMBED_CAUSE_REGNUM;
      mips_regnum.pc = MIPS_EMBED_PC_REGNUM;
      mips_regnum.fp0 = MIPS_EMBED_FP0_REGNUM;
      mips_regnum.fp_control_status = 70;
      mips_regnum.fp_implementation_revision = 71;
      mips_regnum.dspacc = dspacc = -1;
      mips_regnum.dspctl = dspctl = -1;
      num_regs = MIPS_LAST_EMBED_REGNUM + 1;
      if (info.bfd_arch_info != NULL
	  && info.bfd_arch_info->mach == bfd_mach_mips3900)
	reg_names = mips_tx39_reg_names;
      else
	reg_names = mips_generic_reg_names;
    }

  /* Check any target description for validity.  */
  if (tdesc_has_registers (info.target_desc))
    {
      static const char *const mips_gprs[] = {
	"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"
      };
      static const char *const mips_fprs[] = {
	"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
	"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
	"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
	"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
      };

      const struct tdesc_feature *feature;
      int valid_p;

      feature = tdesc_find_feature (info.target_desc,
				    "org.gnu.gdb.mips.cpu");
      if (feature == NULL)
	return NULL;

      tdesc_data = tdesc_data_alloc ();

      valid_p = 1;
      for (i = MIPS_ZERO_REGNUM; i <= MIPS_RA_REGNUM; i++)
	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
					    mips_gprs[i]);


      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					  mips_regnum.lo, "lo");
      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					  mips_regnum.hi, "hi");
      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					  mips_regnum.pc, "pc");

      if (!valid_p)
	return NULL;

      feature = tdesc_find_feature (info.target_desc,
				    "org.gnu.gdb.mips.cp0");
      if (feature == NULL)
	return NULL;

      valid_p = 1;
      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					  mips_regnum.badvaddr, "badvaddr");
      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					  MIPS_PS_REGNUM, "status");
      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					  mips_regnum.cause, "cause");

      if (!valid_p)
	return NULL;

      /* FIXME drow/2007-05-17: The FPU should be optional.  The MIPS
	 backend is not prepared for that, though.  */
      feature = tdesc_find_feature (info.target_desc,
				    "org.gnu.gdb.mips.fpu");
      if (feature == NULL)
	return NULL;

      valid_p = 1;
      for (i = 0; i < 32; i++)
	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					    i + mips_regnum.fp0, mips_fprs[i]);

      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
					  mips_regnum.fp_control_status,
					  "fcsr");
      valid_p
	&= tdesc_numbered_register (feature, tdesc_data.get (),
				    mips_regnum.fp_implementation_revision,
				    "fir");

      if (!valid_p)
	return NULL;

      num_regs = mips_regnum.fp_implementation_revision + 1;

      if (dspacc >= 0)
	{
	  feature = tdesc_find_feature (info.target_desc,
					"org.gnu.gdb.mips.dsp");
	  /* The DSP registers are optional; it's OK if they are absent.  */
	  if (feature != NULL)
	    {
	      i = 0;
	      valid_p = 1;
	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  dspacc + i++, "hi1");
	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  dspacc + i++, "lo1");
	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  dspacc + i++, "hi2");
	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  dspacc + i++, "lo2");
	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  dspacc + i++, "hi3");
	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  dspacc + i++, "lo3");

	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
						  dspctl, "dspctl");

	      if (!valid_p)
		return NULL;

	      mips_regnum.dspacc = dspacc;
	      mips_regnum.dspctl = dspctl;

	      num_regs = mips_regnum.dspctl + 1;
	    }
	}

      /* It would be nice to detect an attempt to use a 64-bit ABI
	 when only 32-bit registers are provided.  */
      reg_names = NULL;
    }

  /* Try to find a pre-existing architecture.  */
  for (arches = gdbarch_list_lookup_by_info (arches, &info);
       arches != NULL;
       arches = gdbarch_list_lookup_by_info (arches->next, &info))
    {
      mips_gdbarch_tdep *tdep
	= gdbarch_tdep<mips_gdbarch_tdep> (arches->gdbarch);

      /* MIPS needs to be pedantic about which ABI and the compressed
	 ISA variation the object is using.  */
      if (tdep->elf_flags != elf_flags)
	continue;
      if (tdep->mips_abi != mips_abi)
	continue;
      if (tdep->mips_isa != mips_isa)
	continue;
      /* Need to be pedantic about which register virtual size is
	 used.  */
      if (tdep->mips64_transfers_32bit_regs_p
	  != mips64_transfers_32bit_regs_p)
	continue;
      /* Be pedantic about which FPU is selected.  */
      if (mips_get_fpu_type (arches->gdbarch) != fpu_type)
	continue;

      return arches->gdbarch;
    }

  /* Need a new architecture.  Fill in a target specific vector.  */
  gdbarch *gdbarch
    = gdbarch_alloc (&info, gdbarch_tdep_up (new mips_gdbarch_tdep));
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);

  tdep->elf_flags = elf_flags;
  tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
  tdep->found_abi = found_abi;
  tdep->mips_abi = mips_abi;
  tdep->mips_isa = mips_isa;
  tdep->mips_fpu_type = fpu_type;
  tdep->register_size_valid_p = 0;
  tdep->register_size = 0;

  if (info.target_desc)
    {
      /* Some useful properties can be inferred from the target.  */
      if (tdesc_property (info.target_desc, PROPERTY_GP32) != NULL)
	{
	  tdep->register_size_valid_p = 1;
	  tdep->register_size = 4;
	}
      else if (tdesc_property (info.target_desc, PROPERTY_GP64) != NULL)
	{
	  tdep->register_size_valid_p = 1;
	  tdep->register_size = 8;
	}
    }

  /* Initially set everything according to the default ABI/ISA.  */
  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);
  set_gdbarch_register_reggroup_p (gdbarch, mips_register_reggroup_p);
  set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read);
  set_gdbarch_deprecated_pseudo_register_write (gdbarch,
						mips_pseudo_register_write);

  set_gdbarch_ax_pseudo_register_collect (gdbarch,
					  mips_ax_pseudo_register_collect);
  set_gdbarch_ax_pseudo_register_push_stack
      (gdbarch, mips_ax_pseudo_register_push_stack);

  set_gdbarch_elf_make_msymbol_special (gdbarch,
					mips_elf_make_msymbol_special);
  set_gdbarch_make_symbol_special (gdbarch, mips_make_symbol_special);
  set_gdbarch_adjust_dwarf2_addr (gdbarch, mips_adjust_dwarf2_addr);
  set_gdbarch_adjust_dwarf2_line (gdbarch, mips_adjust_dwarf2_line);

  regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct mips_regnum);
  *regnum = mips_regnum;
  set_gdbarch_fp0_regnum (gdbarch, regnum->fp0);
  set_gdbarch_num_regs (gdbarch, num_regs);
  set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
  set_gdbarch_register_name (gdbarch, mips_register_name);
  set_gdbarch_virtual_frame_pointer (gdbarch, mips_virtual_frame_pointer);
  tdep->mips_processor_reg_names = reg_names;
  tdep->regnum = regnum;

  switch (mips_abi)
    {
    case MIPS_ABI_O32:
      set_gdbarch_push_dummy_call (gdbarch, mips_o32_push_dummy_call);
      set_gdbarch_return_value (gdbarch, mips_o32_return_value);
      tdep->mips_last_arg_regnum = MIPS_A0_REGNUM + 4 - 1;
      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 4 - 1;
      tdep->default_mask_address_p = 0;
      set_gdbarch_long_bit (gdbarch, 32);
      set_gdbarch_ptr_bit (gdbarch, 32);
      set_gdbarch_long_long_bit (gdbarch, 64);
      break;
    case MIPS_ABI_O64:
      set_gdbarch_push_dummy_call (gdbarch, mips_o64_push_dummy_call);
      set_gdbarch_return_value (gdbarch, mips_o64_return_value);
      tdep->mips_last_arg_regnum = MIPS_A0_REGNUM + 4 - 1;
      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 4 - 1;
      tdep->default_mask_address_p = 0;
      set_gdbarch_long_bit (gdbarch, 32);
      set_gdbarch_ptr_bit (gdbarch, 32);
      set_gdbarch_long_long_bit (gdbarch, 64);
      break;
    case MIPS_ABI_EABI32:
      set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call);
      set_gdbarch_return_value (gdbarch, mips_eabi_return_value);
      tdep->mips_last_arg_regnum = MIPS_A0_REGNUM + 8 - 1;
      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
      tdep->default_mask_address_p = 0;
      set_gdbarch_long_bit (gdbarch, 32);
      set_gdbarch_ptr_bit (gdbarch, 32);
      set_gdbarch_long_long_bit (gdbarch, 64);
      break;
    case MIPS_ABI_EABI64:
      set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call);
      set_gdbarch_return_value (gdbarch, mips_eabi_return_value);
      tdep->mips_last_arg_regnum = MIPS_A0_REGNUM + 8 - 1;
      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
      tdep->default_mask_address_p = 0;
      set_gdbarch_long_bit (gdbarch, 64);
      set_gdbarch_ptr_bit (gdbarch, 64);
      set_gdbarch_long_long_bit (gdbarch, 64);
      break;
    case MIPS_ABI_N32:
      set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call);
      set_gdbarch_return_value (gdbarch, mips_n32n64_return_value);
      tdep->mips_last_arg_regnum = MIPS_A0_REGNUM + 8 - 1;
      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
      tdep->default_mask_address_p = 0;
      set_gdbarch_long_bit (gdbarch, 32);
      set_gdbarch_ptr_bit (gdbarch, 32);
      set_gdbarch_long_long_bit (gdbarch, 64);
      set_gdbarch_long_double_bit (gdbarch, 128);
      set_gdbarch_long_double_format (gdbarch, floatformats_ibm_long_double);
      break;
    case MIPS_ABI_N64:
      set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call);
      set_gdbarch_return_value (gdbarch, mips_n32n64_return_value);
      tdep->mips_last_arg_regnum = MIPS_A0_REGNUM + 8 - 1;
      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
      tdep->default_mask_address_p = 0;
      set_gdbarch_long_bit (gdbarch, 64);
      set_gdbarch_ptr_bit (gdbarch, 64);
      set_gdbarch_long_long_bit (gdbarch, 64);
      set_gdbarch_long_double_bit (gdbarch, 128);
      set_gdbarch_long_double_format (gdbarch, floatformats_ibm_long_double);
      break;
    default:
      internal_error (_("unknown ABI in switch"));
    }

  /* GCC creates a pseudo-section whose name specifies the size of
     longs, since -mlong32 or -mlong64 may be used independent of
     other options.  How those options affect pointer sizes is ABI and
     architecture dependent, so use them to override the default sizes
     set by the ABI.  This table shows the relationship between ABI,
     -mlongXX, and size of pointers:

     ABI		-mlongXX	ptr bits
     ---		--------	--------
     o32		32		32
     o32		64		32
     n32		32		32
     n32		64		64
     o64		32		32
     o64		64		64
     n64		32		32
     n64		64		64
     eabi32		32		32
     eabi32		64		32
     eabi64		32		32
     eabi64		64		64

    Note that for o32 and eabi32, pointers are always 32 bits
    regardless of any -mlongXX option.  For all others, pointers and
    longs are the same, as set by -mlongXX or set by defaults.  */

  if (info.abfd != NULL)
    {
      int long_bit = 0;

      bfd_map_over_sections (info.abfd, mips_find_long_section, &long_bit);
      if (long_bit)
	{
	  set_gdbarch_long_bit (gdbarch, long_bit);
	  switch (mips_abi)
	    {
	    case MIPS_ABI_O32:
	    case MIPS_ABI_EABI32:
	      break;
	    case MIPS_ABI_N32:
	    case MIPS_ABI_O64:
	    case MIPS_ABI_N64:
	    case MIPS_ABI_EABI64:
	      set_gdbarch_ptr_bit (gdbarch, long_bit);
	      break;
	    default:
	      internal_error (_("unknown ABI in switch"));
	    }
	}
    }

  /* FIXME: jlarmour/2000-04-07: There *is* a flag EF_MIPS_32BIT_MODE
     that could indicate -gp32 BUT gas/config/tc-mips.c contains the
     comment:

     ``We deliberately don't allow "-gp32" to set the MIPS_32BITMODE
     flag in object files because to do so would make it impossible to
     link with libraries compiled without "-gp32".  This is
     unnecessarily restrictive.

     We could solve this problem by adding "-gp32" multilibs to gcc,
     but to set this flag before gcc is built with such multilibs will
     break too many systems.''

     But even more unhelpfully, the default linker output target for
     mips64-elf is elf32-bigmips, and has EF_MIPS_32BIT_MODE set, even
     for 64-bit programs - you need to change the ABI to change this,
     and not all gcc targets support that currently.  Therefore using
     this flag to detect 32-bit mode would do the wrong thing given
     the current gcc - it would make GDB treat these 64-bit programs
     as 32-bit programs by default.  */

  set_gdbarch_read_pc (gdbarch, mips_read_pc);
  set_gdbarch_write_pc (gdbarch, mips_write_pc);

  /* Add/remove bits from an address.  The MIPS needs be careful to
     ensure that all 32 bit addresses are sign extended to 64 bits.  */
  set_gdbarch_addr_bits_remove (gdbarch, mips_addr_bits_remove);

  /* Unwind the frame.  */
  set_gdbarch_unwind_pc (gdbarch, mips_unwind_pc);
  set_gdbarch_unwind_sp (gdbarch, mips_unwind_sp);
  set_gdbarch_dummy_id (gdbarch, mips_dummy_id);

  /* Map debug register numbers onto internal register numbers.  */
  set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum);
  set_gdbarch_ecoff_reg_to_regnum (gdbarch,
				   mips_dwarf_dwarf2_ecoff_reg_to_regnum);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch,
				    mips_dwarf_dwarf2_ecoff_reg_to_regnum);
  set_gdbarch_register_sim_regno (gdbarch, mips_register_sim_regno);

  /* MIPS version of CALL_DUMMY.  */

  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
  set_gdbarch_push_dummy_code (gdbarch, mips_push_dummy_code);
  set_gdbarch_frame_align (gdbarch, mips_frame_align);

  set_gdbarch_print_float_info (gdbarch, mips_print_float_info);

  set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
  set_gdbarch_register_to_value (gdbarch, mips_register_to_value);
  set_gdbarch_value_to_register (gdbarch, mips_value_to_register);

  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_breakpoint_kind_from_pc (gdbarch, mips_breakpoint_kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, mips_sw_breakpoint_from_kind);
  set_gdbarch_adjust_breakpoint_address (gdbarch,
					 mips_adjust_breakpoint_address);

  set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);

  set_gdbarch_stack_frame_destroyed_p (gdbarch, mips_stack_frame_destroyed_p);

  set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
  set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
  set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address);

  set_gdbarch_register_type (gdbarch, mips_register_type);

  set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info);

  set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips);
  if (mips_abi == MIPS_ABI_N64)
    set_gdbarch_disassembler_options_implicit (gdbarch,
					       mips_disassembler_options_n64);
  else if (mips_abi == MIPS_ABI_N32)
    set_gdbarch_disassembler_options_implicit (gdbarch,
					       mips_disassembler_options_n32);
  else
    set_gdbarch_disassembler_options_implicit (gdbarch,
					       mips_disassembler_options_o32);
  set_gdbarch_disassembler_options (gdbarch, &mips_disassembler_options);
  set_gdbarch_valid_disassembler_options (gdbarch,
					  disassembler_options_mips ());

  /* FIXME: cagney/2003-08-29: The macros target_have_steppable_watchpoint,
     HAVE_NONSTEPPABLE_WATCHPOINT, and target_have_continuable_watchpoint
     need to all be folded into the target vector.  Since they are
     being used as guards for target_stopped_by_watchpoint, why not have
     target_stopped_by_watchpoint return the type of watchpoint that the code
     is sitting on?  */
  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);

  set_gdbarch_skip_trampoline_code (gdbarch, mips_skip_trampoline_code);

  /* NOTE drow/2012-04-25: We overload the core solib trampoline code
     to support MIPS16.  This is a bad thing.  Make sure not to do it
     if we have an OS ABI that actually supports shared libraries, since
     shared library support is more important.  If we have an OS someday
     that supports both shared libraries and MIPS16, we'll have to find
     a better place for these.
     macro/2012-04-25: But that applies to return trampolines only and
     currently no MIPS OS ABI uses shared libraries that have them.  */
  set_gdbarch_in_solib_return_trampoline (gdbarch, mips_in_return_stub);

  set_gdbarch_single_step_through_delay (gdbarch,
					 mips_single_step_through_delay);

  /* Virtual tables.  */
  set_gdbarch_vbit_in_delta (gdbarch, 1);

  mips_register_g_packet_guesses (gdbarch);

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

  /* The hook may have adjusted num_regs, fetch the final value and
     set pc_regnum and sp_regnum now that it has been fixed.  */
  num_regs = gdbarch_num_regs (gdbarch);
  set_gdbarch_pc_regnum (gdbarch, regnum->pc + num_regs);
  set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);

  /* Unwind the frame.  */
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &mips_stub_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &mips_insn16_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &mips_micro_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &mips_insn32_frame_unwind);
  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
  frame_base_append_sniffer (gdbarch, mips_stub_frame_base_sniffer);
  frame_base_append_sniffer (gdbarch, mips_insn16_frame_base_sniffer);
  frame_base_append_sniffer (gdbarch, mips_micro_frame_base_sniffer);
  frame_base_append_sniffer (gdbarch, mips_insn32_frame_base_sniffer);

  if (tdesc_data != nullptr)
    {
      set_tdesc_pseudo_register_type (gdbarch, mips_pseudo_register_type);
      tdesc_use_registers (gdbarch, info.target_desc, std::move (tdesc_data));

      /* Override the normal target description methods to handle our
	 dual real and pseudo registers.  */
      set_gdbarch_register_name (gdbarch, mips_register_name);
      set_gdbarch_register_reggroup_p (gdbarch,
				       mips_tdesc_register_reggroup_p);

      num_regs = gdbarch_num_regs (gdbarch);
      set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
      set_gdbarch_pc_regnum (gdbarch, tdep->regnum->pc + num_regs);
      set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
    }

  /* Add ABI-specific aliases for the registers.  */
  if (mips_abi == MIPS_ABI_N32 || mips_abi == MIPS_ABI_N64)
    for (i = 0; i < ARRAY_SIZE (mips_n32_n64_aliases); i++)
      user_reg_add (gdbarch, mips_n32_n64_aliases[i].name,
		    value_of_mips_user_reg, &mips_n32_n64_aliases[i].regnum);
  else
    for (i = 0; i < ARRAY_SIZE (mips_o32_aliases); i++)
      user_reg_add (gdbarch, mips_o32_aliases[i].name,
		    value_of_mips_user_reg, &mips_o32_aliases[i].regnum);

  /* Add some other standard aliases.  */
  for (i = 0; i < ARRAY_SIZE (mips_register_aliases); i++)
    user_reg_add (gdbarch, mips_register_aliases[i].name,
		  value_of_mips_user_reg, &mips_register_aliases[i].regnum);

  for (i = 0; i < ARRAY_SIZE (mips_numeric_register_aliases); i++)
    user_reg_add (gdbarch, mips_numeric_register_aliases[i].name,
		  value_of_mips_user_reg, 
		  &mips_numeric_register_aliases[i].regnum);

  return gdbarch;
}

static void
mips_abi_update (const char *ignore_args,
		 int from_tty, struct cmd_list_element *c)
{
  struct gdbarch_info info;

  /* Force the architecture to update, and (if it's a MIPS architecture)
     mips_gdbarch_init will take care of the rest.  */
  gdbarch_update_p (info);
}

/* Print out which MIPS ABI is in use.  */

static void
show_mips_abi (struct ui_file *file,
	       int from_tty,
	       struct cmd_list_element *ignored_cmd,
	       const char *ignored_value)
{
  if (gdbarch_bfd_arch_info (current_inferior ()->arch  ())->arch
      != bfd_arch_mips)
    gdb_printf
      (file, 
       "The MIPS ABI is unknown because the current architecture "
       "is not MIPS.\n");
  else
    {
      enum mips_abi global_abi = global_mips_abi ();
      enum mips_abi actual_abi = mips_abi (current_inferior ()->arch ());
      const char *actual_abi_str = mips_abi_strings[actual_abi];

      if (global_abi == MIPS_ABI_UNKNOWN)
	gdb_printf
	  (file, 
	   "The MIPS ABI is set automatically (currently \"%s\").\n",
	   actual_abi_str);
      else if (global_abi == actual_abi)
	gdb_printf
	  (file,
	   "The MIPS ABI is assumed to be \"%s\" (due to user setting).\n",
	   actual_abi_str);
      else
	{
	  /* Probably shouldn't happen...  */
	  gdb_printf (file,
		      "The (auto detected) MIPS ABI \"%s\" is in use "
		      "even though the user setting was \"%s\".\n",
		      actual_abi_str, mips_abi_strings[global_abi]);
	}
    }
}

/* Print out which MIPS compressed ISA encoding is used.  */

static void
show_mips_compression (struct ui_file *file, int from_tty,
		       struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("The compressed ISA encoding used is %s.\n"),
	      value);
}

/* Return a textual name for MIPS FPU type FPU_TYPE.  */

static const char *
mips_fpu_type_str (enum mips_fpu_type fpu_type)
{
  switch (fpu_type)
    {
    case MIPS_FPU_NONE:
      return "none";
    case MIPS_FPU_SINGLE:
      return "single";
    case MIPS_FPU_DOUBLE:
      return "double";
    default:
      return "???";
    }
}

static void
mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
  if (tdep != NULL)
    {
      int ef_mips_arch;
      int ef_mips_32bitmode;
      /* Determine the ISA.  */
      switch (tdep->elf_flags & EF_MIPS_ARCH)
	{
	case EF_MIPS_ARCH_1:
	  ef_mips_arch = 1;
	  break;
	case EF_MIPS_ARCH_2:
	  ef_mips_arch = 2;
	  break;
	case EF_MIPS_ARCH_3:
	  ef_mips_arch = 3;
	  break;
	case EF_MIPS_ARCH_4:
	  ef_mips_arch = 4;
	  break;
	default:
	  ef_mips_arch = 0;
	  break;
	}
      /* Determine the size of a pointer.  */
      ef_mips_32bitmode = (tdep->elf_flags & EF_MIPS_32BITMODE);
      gdb_printf (file,
		  "mips_dump_tdep: tdep->elf_flags = 0x%x\n",
		  tdep->elf_flags);
      gdb_printf (file,
		  "mips_dump_tdep: ef_mips_32bitmode = %d\n",
		  ef_mips_32bitmode);
      gdb_printf (file,
		  "mips_dump_tdep: ef_mips_arch = %d\n",
		  ef_mips_arch);
      gdb_printf (file,
		  "mips_dump_tdep: tdep->mips_abi = %d (%s)\n",
		  tdep->mips_abi, mips_abi_strings[tdep->mips_abi]);
      gdb_printf (file,
		  "mips_dump_tdep: "
		  "mips_mask_address_p() %d (default %d)\n",
		  mips_mask_address_p (tdep),
		  tdep->default_mask_address_p);
    }
  gdb_printf (file,
	      "mips_dump_tdep: MIPS_DEFAULT_FPU_TYPE = %d (%s)\n",
	      MIPS_DEFAULT_FPU_TYPE,
	      mips_fpu_type_str (MIPS_DEFAULT_FPU_TYPE));
  gdb_printf (file, "mips_dump_tdep: MIPS_EABI = %d\n",
	      mips_eabi (gdbarch));
  gdb_printf (file,
	      "mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
	      mips_get_fpu_type (gdbarch),
	      mips_fpu_type_str (mips_get_fpu_type (gdbarch)));
}

void _initialize_mips_tdep ();
void
_initialize_mips_tdep ()
{
  static struct cmd_list_element *mipsfpulist = NULL;

  mips_abi_string = mips_abi_strings[MIPS_ABI_UNKNOWN];
  if (MIPS_ABI_LAST + 1
      != sizeof (mips_abi_strings) / sizeof (mips_abi_strings[0]))
    internal_error (_("mips_abi_strings out of sync"));

  gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep);

  /* Create feature sets with the appropriate properties.  The values
     are not important.  */
  mips_tdesc_gp32 = allocate_target_description ().release ();
  set_tdesc_property (mips_tdesc_gp32, PROPERTY_GP32, "");

  mips_tdesc_gp64 = allocate_target_description ().release ();
  set_tdesc_property (mips_tdesc_gp64, PROPERTY_GP64, "");

  /* Add root prefix command for all "set mips"/"show mips" commands.  */
  add_setshow_prefix_cmd ("mips", no_class,
			  _("Various MIPS specific commands."),
			  _("Various MIPS specific commands."),
			  &setmipscmdlist, &showmipscmdlist,
			  &setlist, &showlist);

  /* Allow the user to override the ABI.  */
  add_setshow_enum_cmd ("abi", class_obscure, mips_abi_strings,
			&mips_abi_string, _("\
Set the MIPS ABI used by this program."), _("\
Show the MIPS ABI used by this program."), _("\
This option can be set to one of:\n\
  auto  - the default ABI associated with the current binary\n\
  o32\n\
  o64\n\
  n32\n\
  n64\n\
  eabi32\n\
  eabi64"),
			mips_abi_update,
			show_mips_abi,
			&setmipscmdlist, &showmipscmdlist);

  /* Allow the user to set the ISA to assume for compressed code if ELF
     file flags don't tell or there is no program file selected.  This
     setting is updated whenever unambiguous ELF file flags are interpreted,
     and carried over to subsequent sessions.  */
  add_setshow_enum_cmd ("compression", class_obscure, mips_compression_strings,
			&mips_compression_string, _("\
Set the compressed ISA encoding used by MIPS code."), _("\
Show the compressed ISA encoding used by MIPS code."), _("\
Select the compressed ISA encoding used in functions that have no symbol\n\
information available.  The encoding can be set to either of:\n\
  mips16\n\
  micromips\n\
and is updated automatically from ELF file flags if available."),
			mips_abi_update,
			show_mips_compression,
			&setmipscmdlist, &showmipscmdlist);

  /* Let the user turn off floating point and set the fence post for
     heuristic_proc_start.  */

  add_basic_prefix_cmd ("mipsfpu", class_support,
			_("Set use of MIPS floating-point coprocessor."),
			&mipsfpulist, 0, &setlist);
  add_cmd ("single", class_support, set_mipsfpu_single_command,
	   _("Select single-precision MIPS floating-point coprocessor."),
	   &mipsfpulist);
  cmd_list_element *set_mipsfpu_double_cmd
    = add_cmd ("double", class_support, set_mipsfpu_double_command,
	       _("Select double-precision MIPS floating-point coprocessor."),
	       &mipsfpulist);
  add_alias_cmd ("on", set_mipsfpu_double_cmd, class_support, 1, &mipsfpulist);
  add_alias_cmd ("yes", set_mipsfpu_double_cmd, class_support, 1, &mipsfpulist);
  add_alias_cmd ("1", set_mipsfpu_double_cmd, class_support, 1, &mipsfpulist);

  cmd_list_element *set_mipsfpu_none_cmd
    = add_cmd ("none", class_support, set_mipsfpu_none_command,
	       _("Select no MIPS floating-point coprocessor."), &mipsfpulist);
  add_alias_cmd ("off", set_mipsfpu_none_cmd, class_support, 1, &mipsfpulist);
  add_alias_cmd ("no", set_mipsfpu_none_cmd, class_support, 1, &mipsfpulist);
  add_alias_cmd ("0", set_mipsfpu_none_cmd, class_support, 1, &mipsfpulist);
  add_cmd ("auto", class_support, set_mipsfpu_auto_command,
	   _("Select MIPS floating-point coprocessor automatically."),
	   &mipsfpulist);
  add_cmd ("mipsfpu", class_support, show_mipsfpu_command,
	   _("Show current use of MIPS floating-point coprocessor target."),
	   &showlist);

  /* We really would like to have both "0" and "unlimited" work, but
     command.c doesn't deal with that.  So make it a var_zinteger
     because the user can always use "999999" or some such for unlimited.  */
  add_setshow_zinteger_cmd ("heuristic-fence-post", class_support,
			    &heuristic_fence_post, _("\
Set the distance searched for the start of a function."), _("\
Show the distance searched for the start of a function."), _("\
If you are debugging a stripped executable, GDB needs to search through the\n\
program for the start of a function.  This command sets the distance of the\n\
search.  The only need to set it is when debugging a stripped executable."),
			    reinit_frame_cache_sfunc,
			    NULL, /* FIXME: i18n: The distance searched for
				     the start of a function is %s.  */
			    &setlist, &showlist);

  /* Allow the user to control whether the upper bits of 64-bit
     addresses should be zeroed.  */
  add_setshow_auto_boolean_cmd ("mask-address", no_class,
				&mask_address_var, _("\
Set zeroing of upper 32 bits of 64-bit addresses."), _("\
Show zeroing of upper 32 bits of 64-bit addresses."), _("\
Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to\n\
allow GDB to determine the correct value."),
				NULL, show_mask_address,
				&setmipscmdlist, &showmipscmdlist);

  /* Allow the user to control the size of 32 bit registers within the
     raw remote packet.  */
  add_setshow_boolean_cmd ("remote-mips64-transfers-32bit-regs", class_obscure,
			   &mips64_transfers_32bit_regs_p, _("\
Set compatibility with 64-bit MIPS target that transfers 32-bit quantities."),
			   _("\
Show compatibility with 64-bit MIPS target that transfers 32-bit quantities."),
			   _("\
Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
64 bits for others.  Use \"off\" to disable compatibility mode"),
			   set_mips64_transfers_32bit_regs,
			   NULL, /* FIXME: i18n: Compatibility with 64-bit
				    MIPS target that transfers 32-bit
				    quantities is %s.  */
			   &setlist, &showlist);

  /* Debug this files internals.  */
  add_setshow_zuinteger_cmd ("mips", class_maintenance,
			     &mips_debug, _("\
Set mips debugging."), _("\
Show mips debugging."), _("\
When non-zero, mips specific debugging is enabled."),
			     NULL,
			     NULL, /* FIXME: i18n: Mips debugging is
				      currently %s.  */
			     &setdebuglist, &showdebuglist);
}
