/* Number of registers in `struct fpreg' from <machine/reg.h>. The
first 32 hold floating point registers. 33 holds the FSR. The
- 34th is a dummy for padding. */
+ 34th holds FIR on FreeBSD 12.0 and newer kernels. On older kernels
+ it was a zero-filled dummy for padding. */
#define MIPS_FBSD_NUM_FPREGS 34
-/* Supply a single register. If the source register size matches the
- size the regcache expects, this can use regcache_raw_supply(). If
- they are different, this copies the source register into a buffer
- that can be passed to regcache_raw_supply(). */
+/* Supply a single register. The register size might not match, so use
+ regcache->raw_supply_integer (). */
static void
mips_fbsd_supply_reg (struct regcache *regcache, int regnum, const void *addr,
size_t len)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
-
- if (register_size (gdbarch, regnum) == len)
- regcache_raw_supply (regcache, regnum, addr);
- else
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[MAX_REGISTER_SIZE];
- LONGEST val;
-
- val = extract_signed_integer ((const gdb_byte *) addr, len, byte_order);
- store_signed_integer (buf, register_size (gdbarch, regnum), byte_order,
- val);
- regcache_raw_supply (regcache, regnum, buf);
- }
+ regcache->raw_supply_integer (regnum, (const gdb_byte *) addr, len, true);
}
-/* Collect a single register. If the destination register size
- matches the size the regcache expects, this can use
- regcache_raw_supply(). If they are different, this fetches the
- register via regcache_raw_supply() into a buffer and then copies it
- into the final destination. */
+/* Collect a single register. The register size might not match, so use
+ regcache->raw_collect_integer (). */
static void
mips_fbsd_collect_reg (const struct regcache *regcache, int regnum, void *addr,
size_t len)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
-
- if (register_size (gdbarch, regnum) == len)
- regcache_raw_collect (regcache, regnum, addr);
- else
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[MAX_REGISTER_SIZE];
- LONGEST val;
-
- regcache_raw_collect (regcache, regnum, buf);
- val = extract_signed_integer (buf, register_size (gdbarch, regnum),
- byte_order);
- store_signed_integer ((gdb_byte *) addr, len, byte_order, val);
- }
+ regcache->raw_collect_integer (regnum, (gdb_byte *) addr, len, true);
}
/* Supply the floating-point registers stored in FPREGS to REGCACHE.
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
const gdb_byte *regs = (const gdb_byte *) fpregs;
- int i, fp0num, fsrnum;
+ int i, fp0num;
fp0num = mips_regnum (gdbarch)->fp0;
- fsrnum = mips_regnum (gdbarch)->fp_control_status;
- for (i = fp0num; i <= fsrnum; i++)
- if (regnum == i || regnum == -1)
- mips_fbsd_supply_reg (regcache, i,
- regs + (i - fp0num) * regsize, regsize);
+ for (i = 0; i <= 32; i++)
+ if (regnum == fp0num + i || regnum == -1)
+ mips_fbsd_supply_reg (regcache, fp0num + i,
+ regs + i * regsize, regsize);
+ if (regnum == mips_regnum (gdbarch)->fp_control_status || regnum == -1)
+ mips_fbsd_supply_reg (regcache, mips_regnum (gdbarch)->fp_control_status,
+ regs + 32 * regsize, regsize);
+ if ((regnum == mips_regnum (gdbarch)->fp_implementation_revision
+ || regnum == -1)
+ && extract_unsigned_integer (regs + 33 * regsize, regsize,
+ gdbarch_byte_order (gdbarch)) != 0)
+ mips_fbsd_supply_reg (regcache,
+ mips_regnum (gdbarch)->fp_implementation_revision,
+ regs + 33 * regsize, regsize);
}
/* Supply the general-purpose registers stored in GREGS to REGCACHE.
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
gdb_byte *regs = (gdb_byte *) fpregs;
- int i, fp0num, fsrnum;
+ int i, fp0num;
fp0num = mips_regnum (gdbarch)->fp0;
- fsrnum = mips_regnum (gdbarch)->fp_control_status;
- for (i = fp0num; i <= fsrnum; i++)
- if (regnum == i || regnum == -1)
- mips_fbsd_collect_reg (regcache, i,
- regs + (i - fp0num) * regsize, regsize);
+ for (i = 0; i < 32; i++)
+ if (regnum == fp0num + i || regnum == -1)
+ mips_fbsd_collect_reg (regcache, fp0num + i,
+ regs + i * regsize, regsize);
+ if (regnum == mips_regnum (gdbarch)->fp_control_status || regnum == -1)
+ mips_fbsd_collect_reg (regcache, mips_regnum (gdbarch)->fp_control_status,
+ regs + 32 * regsize, regsize);
+ if (regnum == mips_regnum (gdbarch)->fp_implementation_revision
+ || regnum == -1)
+ mips_fbsd_collect_reg (regcache,
+ mips_regnum (gdbarch)->fp_implementation_revision,
+ regs + 33 * regsize, regsize);
}
/* Collect the general-purpose registers from REGCACHE and store them
mips_fbsd_ilp32_fetch_link_map_offsets :
mips_fbsd_lp64_fetch_link_map_offsets));
}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_mips_fbsd_tdep (void);
void
_initialize_mips_fbsd_tdep (void)