/* 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 "extract-store-integer.h"
#include "frame.h"
#include "inferior.h"
#include "symtab.h"
#include "value.h"
#include "cli/cli-cmds.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 std::string 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 (const asymbol * sym,
			       struct minimal_symbol *msym)
{
  const elf_symbol_type *elfsym = (const 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;

      compact_block_start = block->start () | 1;
      bound_minimal_symbol 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
   compatibility 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 compatibility 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 through 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 (current_inferior (), 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 transferred 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))
    {
      gdb::array_view<gdb_byte> first_half = gdb::make_array_view (to, 4);
      gdb::array_view<gdb_byte> second_half = gdb::make_array_view (to + 4, 4);

      get_frame_register (frame, regnum + 0, second_half);
      get_frame_register (frame, regnum + 1, first_half);

      if (!get_frame_register_bytes (next_frame, regnum + 0, 0, second_half,
				     optimizedp, unavailablep))
	return 0;

      if (!get_frame_register_bytes (next_frame, regnum + 1, 0, first_half,
				     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 transferring 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)
{
  /* 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.  */
  bound_minimal_symbol 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)
{
  /* 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.  */

  bound_minimal_symbol 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)
{
  /* 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.  */

  bound_minimal_symbol 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)
{
  /* 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.  */

  bound_minimal_symbol 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 beginning
       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_legacy mips_insn16_frame_unwind (
  "mips insn16 prologue",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  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 beginning
       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_legacy mips_micro_frame_unwind (
  "mips micro prologue",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  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 beginning
       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_legacy mips_insn32_frame_unwind (
  "mips insn32 prologue",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  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);

  /* 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".  */
  bound_minimal_symbol 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_legacy mips_stub_frame_unwind (
  "mips stub",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  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 adjustment, 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 through 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 through 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 through 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 through 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 through 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 through 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 through 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 through 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::array_view<gdb_byte> rare_buffer)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  int raw_size = register_size (gdbarch, regno);
  gdb::byte_vector raw_buffer (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.data (), raw_buffer.data () + offset, 4);
    }
  else
    {
      memcpy (rare_buffer.data (), raw_buffer.data (), 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::array_view<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.slice (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.slice (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);
  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;

  gdb::byte_vector raw_buffer (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.data (), flt_type,
					"%-17.9g");

      get_formatted_print_options (&opts, 'x');
      print_scalar_formatted (raw_buffer.data (),
			      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.data (), 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.data (), flt_type,
					"%-17.9g");

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

      get_formatted_print_options (&opts, 'x');
      print_scalar_formatted (raw_buffer.data (),
			      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 (current_inferior (), 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 (current_inferior (), 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 (current_inferior (), 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);
  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.  */
  bound_minimal_symbol 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 (current_inferior (), 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);
}
