+#ifdef HAVE_PTRACE_GETREGS
+
+static void
+mips_collect_register (struct regcache *regcache,
+ int use_64bit, int regno, union mips_register *reg)
+{
+ union mips_register tmp_reg;
+
+ if (use_64bit)
+ {
+ collect_register (regcache, regno, &tmp_reg.reg64);
+ *reg = tmp_reg;
+ }
+ else
+ {
+ collect_register (regcache, regno, &tmp_reg.reg32);
+ reg->reg64 = tmp_reg.reg32;
+ }
+}
+
+static void
+mips_supply_register (struct regcache *regcache,
+ int use_64bit, int regno, const union mips_register *reg)
+{
+ int offset = 0;
+
+ /* For big-endian 32-bit targets, ignore the high four bytes of each
+ eight-byte slot. */
+ if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit)
+ offset = 4;
+
+ supply_register (regcache, regno, reg->buf + offset);
+}
+
+static void
+mips_collect_register_32bit (struct regcache *regcache,
+ int use_64bit, int regno, unsigned char *buf)
+{
+ union mips_register tmp_reg;
+ int reg32;
+
+ mips_collect_register (regcache, use_64bit, regno, &tmp_reg);
+ reg32 = tmp_reg.reg64;
+ memcpy (buf, ®32, 4);
+}
+
+static void
+mips_supply_register_32bit (struct regcache *regcache,
+ int use_64bit, int regno, const unsigned char *buf)
+{
+ union mips_register tmp_reg;
+ int reg32;
+
+ memcpy (®32, buf, 4);
+ tmp_reg.reg64 = reg32;
+ mips_supply_register (regcache, use_64bit, regno, &tmp_reg);
+}
+
+static void
+mips_fill_gregset (struct regcache *regcache, void *buf)
+{
+ union mips_register *regset = buf;
+ int i, use_64bit;
+
+ use_64bit = (register_size (0) == 8);
+
+ for (i = 1; i < 32; i++)
+ mips_collect_register (regcache, use_64bit, i, regset + i);
+
+ mips_collect_register (regcache, use_64bit,
+ find_regno ("lo"), regset + 32);
+ mips_collect_register (regcache, use_64bit,
+ find_regno ("hi"), regset + 33);
+ mips_collect_register (regcache, use_64bit,
+ find_regno ("pc"), regset + 34);
+ mips_collect_register (regcache, use_64bit,
+ find_regno ("badvaddr"), regset + 35);
+ mips_collect_register (regcache, use_64bit,
+ find_regno ("status"), regset + 36);
+ mips_collect_register (regcache, use_64bit,
+ find_regno ("cause"), regset + 37);
+
+ mips_collect_register (regcache, use_64bit,
+ find_regno ("restart"), regset + 0);
+}
+
+static void
+mips_store_gregset (struct regcache *regcache, const void *buf)
+{
+ const union mips_register *regset = buf;
+ int i, use_64bit;
+
+ use_64bit = (register_size (0) == 8);
+
+ for (i = 0; i < 32; i++)
+ mips_supply_register (regcache, use_64bit, i, regset + i);
+
+ mips_supply_register (regcache, use_64bit, find_regno ("lo"), regset + 32);
+ mips_supply_register (regcache, use_64bit, find_regno ("hi"), regset + 33);
+ mips_supply_register (regcache, use_64bit, find_regno ("pc"), regset + 34);
+ mips_supply_register (regcache, use_64bit,
+ find_regno ("badvaddr"), regset + 35);
+ mips_supply_register (regcache, use_64bit,
+ find_regno ("status"), regset + 36);
+ mips_supply_register (regcache, use_64bit,
+ find_regno ("cause"), regset + 37);
+
+ mips_supply_register (regcache, use_64bit,
+ find_regno ("restart"), regset + 0);
+}
+
+static void
+mips_fill_fpregset (struct regcache *regcache, void *buf)
+{
+ union mips_register *regset = buf;
+ int i, use_64bit, first_fp, big_endian;
+
+ use_64bit = (register_size (0) == 8);
+ first_fp = find_regno ("f0");
+ big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
+
+ /* See GDB for a discussion of this peculiar layout. */
+ for (i = 0; i < 32; i++)
+ if (use_64bit)
+ collect_register (regcache, first_fp + i, regset[i].buf);
+ else
+ collect_register (regcache, first_fp + i,
+ regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
+
+ mips_collect_register_32bit (regcache, use_64bit,
+ find_regno ("fcsr"), regset[32].buf);
+ mips_collect_register_32bit (regcache, use_64bit, find_regno ("fir"),
+ regset[32].buf + 4);
+}
+
+static void
+mips_store_fpregset (struct regcache *regcache, const void *buf)
+{
+ const union mips_register *regset = buf;
+ int i, use_64bit, first_fp, big_endian;
+
+ use_64bit = (register_size (0) == 8);
+ first_fp = find_regno ("f0");
+ big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
+
+ /* See GDB for a discussion of this peculiar layout. */
+ for (i = 0; i < 32; i++)
+ if (use_64bit)
+ supply_register (regcache, first_fp + i, regset[i].buf);
+ else
+ supply_register (regcache, first_fp + i,
+ regset[i & ~1].buf + 4 * (big_endian != (i & 1)));
+
+ mips_supply_register_32bit (regcache, use_64bit,
+ find_regno ("fcsr"), regset[32].buf);
+ mips_supply_register_32bit (regcache, use_64bit, find_regno ("fir"),
+ regset[32].buf + 4);
+}
+#endif /* HAVE_PTRACE_GETREGS */
+
+struct regset_info target_regsets[] = {
+#ifdef HAVE_PTRACE_GETREGS
+ { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
+ mips_fill_gregset, mips_store_gregset },
+ { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS,
+ mips_fill_fpregset, mips_store_fpregset },
+#endif /* HAVE_PTRACE_GETREGS */
+ { 0, 0, 0, -1, -1, NULL, NULL }
+};
+