void
mips_fill_fpregset (const struct regcache *regcache,
		    mips_elf_fpregset_t *fpregsetp, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  char *from, *to;

  if ((regno >= gdbarch_fp0_regnum (gdbarch))
      && (regno < gdbarch_fp0_regnum (gdbarch) + 32))
    {
      to = (char *) (*fpregsetp + regno - gdbarch_fp0_regnum (gdbarch));
      regcache_raw_collect (regcache, regno, to);
    }
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
    {
      to = (char *) (*fpregsetp + 32);
      regcache_raw_collect (regcache, regno, to);
    }
  else if (regno == -1)
    {
      int regi;

      for (regi = 0; regi < 32; regi++)
	mips_fill_fpregset (regcache, fpregsetp,
			    gdbarch_fp0_regnum (gdbarch) + regi);
      mips_fill_fpregset (regcache, fpregsetp,
			  mips_regnum (gdbarch)->fp_control_status);
    }
}
void
mips64_supply_fpregset (struct regcache *regcache,
			const mips64_elf_fpregset_t *fpregsetp)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int regi;

  /* See mips_linux_o32_sigframe_init for a description of the
     peculiar FP register layout.  */
  if (register_size (gdbarch, gdbarch_fp0_regnum (gdbarch)) == 4)
    for (regi = 0; regi < 32; regi++)
      {
	const gdb_byte *reg_ptr = (const gdb_byte *)(*fpregsetp + (regi & ~1));
	if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (regi & 1))
	  reg_ptr += 4;
	regcache_raw_supply (regcache,
			     gdbarch_fp0_regnum (gdbarch) + regi,
			     reg_ptr);
      }
  else
    for (regi = 0; regi < 32; regi++)
      regcache_raw_supply (regcache,
			   gdbarch_fp0_regnum (gdbarch) + regi,
			   (const char *)(*fpregsetp + regi));

  supply_32bit_reg (regcache, mips_regnum (gdbarch)->fp_control_status,
		    (const gdb_byte *)(*fpregsetp + 32));

  /* The ABI doesn't tell us how to supply FCRIR, and core dumps don't
     include it - but the result of PTRACE_GETFPREGS does.  The best we
     can do is to assume that its value is present.  */
  supply_32bit_reg (regcache,
		    mips_regnum (gdbarch)->fp_implementation_revision,
		    (const gdb_byte *)(*fpregsetp + 32) + 4);
}
static CORE_ADDR
alpha_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
{
  if (regno == gdbarch_pc_regnum (gdbarch))
    return PC;
  if (regno == ALPHA_UNIQUE_REGNUM)
    return ALPHA_UNIQUE_PTRACE_ADDR;
  if (regno < gdbarch_fp0_regnum (gdbarch))
    return GPR_BASE + regno;
  else
    return FPR_BASE + regno - gdbarch_fp0_regnum (gdbarch);
}
예제 #4
0
void
mipsnbsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int i;

  for (i = gdbarch_fp0_regnum (gdbarch);
       i <= mips_regnum (gdbarch)->fp_control_status;
       i++)
    if ((regno == i || regno == -1) 
	&& ! gdbarch_cannot_store_register (gdbarch, i))
      regcache_raw_collect (regcache, i,
			    fpregs + ((i - gdbarch_fp0_regnum (gdbarch))
			      * mips_isa_regsize (gdbarch)));
}
예제 #5
0
void
supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int regi;

  for (regi = gdbarch_fp0_regnum (gdbarch);
       regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
    regcache_raw_supply (regcache, regi,
			 FPREG_ADDR (fpregsetp,
				     regi - gdbarch_fp0_regnum (gdbarch)));
  regcache_raw_supply (regcache, M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
  regcache_raw_supply (regcache, M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
  regcache_raw_supply (regcache, M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
}
예제 #6
0
static void
sh_linux_sigtramp_cache (struct frame_info *this_frame,
			 struct trad_frame_cache *this_cache,
			 CORE_ADDR func, int regs_offset)
{
  int i;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR base = get_frame_register_unsigned (this_frame,
						gdbarch_sp_regnum (gdbarch));
  CORE_ADDR regs = base + regs_offset;

  for (i = 0; i < 18; i++)
    trad_frame_set_reg_addr (this_cache, i, regs + i * 4);

  trad_frame_set_reg_addr (this_cache, SR_REGNUM, regs + 18 * 4);
  trad_frame_set_reg_addr (this_cache, GBR_REGNUM, regs + 19 * 4);
  trad_frame_set_reg_addr (this_cache, MACH_REGNUM, regs + 20 * 4);
  trad_frame_set_reg_addr (this_cache, MACL_REGNUM, regs + 21 * 4);

  /* Restore FP state if we have an FPU.  */
  if (gdbarch_fp0_regnum (gdbarch) != -1)
    {
      CORE_ADDR fpregs = regs + 22 * 4;
      for (i = FR0_REGNUM; i <= FP_LAST_REGNUM; i++)
	trad_frame_set_reg_addr (this_cache, i, fpregs + i * 4);
      trad_frame_set_reg_addr (this_cache, FPSCR_REGNUM, fpregs + 32 * 4);
      trad_frame_set_reg_addr (this_cache, FPUL_REGNUM, fpregs + 33 * 4);
    }

  /* Save a frame ID.  */
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}
예제 #7
0
static void
ppc_linux_sigtramp_cache (struct frame_info *next_frame,
			  struct trad_frame_cache *this_cache,
			  CORE_ADDR func, LONGEST offset,
			  int bias)
{
  CORE_ADDR base;
  CORE_ADDR regs;
  CORE_ADDR gpregs;
  CORE_ADDR fpregs;
  int i;
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  base = frame_unwind_register_unsigned (next_frame,
					 gdbarch_sp_regnum (current_gdbarch));
  if (bias > 0 && frame_pc_unwind (next_frame) != func)
    /* See below, some signal trampolines increment the stack as their
       first instruction, need to compensate for that.  */
    base -= bias;

  /* Find the address of the register buffer pointer.  */
  regs = base + offset;
  /* Use that to find the address of the corresponding register
     buffers.  */
  gpregs = read_memory_unsigned_integer (regs, tdep->wordsize);
  fpregs = gpregs + 48 * tdep->wordsize;

  /* General purpose.  */
  for (i = 0; i < 32; i++)
    {
      int regnum = i + tdep->ppc_gp0_regnum;
      trad_frame_set_reg_addr (this_cache, regnum, gpregs + i * tdep->wordsize);
    }
  trad_frame_set_reg_addr (this_cache,
			   gdbarch_pc_regnum (current_gdbarch),
			   gpregs + 32 * tdep->wordsize);
  trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum,
			   gpregs + 35 * tdep->wordsize);
  trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum,
			   gpregs + 36 * tdep->wordsize);
  trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum,
			   gpregs + 37 * tdep->wordsize);
  trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum,
			   gpregs + 38 * tdep->wordsize);

  if (ppc_floating_point_unit_p (gdbarch))
    {
      /* Floating point registers.  */
      for (i = 0; i < 32; i++)
	{
	  int regnum = i + gdbarch_fp0_regnum (current_gdbarch);
	  trad_frame_set_reg_addr (this_cache, regnum,
				   fpregs + i * tdep->wordsize);
	}
      trad_frame_set_reg_addr (this_cache, tdep->ppc_fpscr_regnum,
                         fpregs + 32 * tdep->wordsize);
    }
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}
예제 #8
0
static void
alphabsd_fetch_inferior_registers (struct target_ops *ops,
				   struct regcache *regcache, int regno)
{
  if (regno == -1 || getregs_supplies (regno))
    {
      struct reg gregs;

      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
	perror_with_name (_("Couldn't get registers"));

      alphabsd_supply_reg (regcache, (char *) &gregs, regno);
      if (regno != -1)
	return;
    }

  if (regno == -1
      || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
    {
      struct fpreg fpregs;

      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't get floating point status"));

      alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
    }
}
예제 #9
0
static void
mips64_fbsd_sigframe_init (const struct tramp_frame *self,
			   struct frame_info *this_frame,
			   struct trad_frame_cache *cache,
			   CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR sp, ucontext_addr, addr;
  int regnum;
  gdb_byte buf[4];

  /* We find the appropriate instance of `ucontext_t' at a
     fixed offset in the signal frame.  */
  sp = get_frame_register_signed (this_frame,
				  MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch));
  ucontext_addr = sp + N64_SIGFRAME_UCONTEXT_OFFSET;

  /* PC.  */
  regnum = mips_regnum (gdbarch)->pc;
  trad_frame_set_reg_addr (cache,
			   regnum + gdbarch_num_regs (gdbarch),
			   ucontext_addr + N64_UCONTEXT_PC);

  /* GPRs.  */
  for (regnum = MIPS_ZERO_REGNUM, addr = ucontext_addr + N64_UCONTEXT_REGS;
       regnum <= MIPS_RA_REGNUM; regnum++, addr += N64_UCONTEXT_REG_SIZE)
    trad_frame_set_reg_addr (cache,
			     regnum + gdbarch_num_regs (gdbarch),
			     addr);

  regnum = MIPS_PS_REGNUM;
  trad_frame_set_reg_addr (cache,
			   regnum + gdbarch_num_regs (gdbarch),
			   ucontext_addr + N64_UCONTEXT_SR);

  /* HI and LO.  */
  regnum = mips_regnum (gdbarch)->lo;
  trad_frame_set_reg_addr (cache,
			   regnum + gdbarch_num_regs (gdbarch),
			   ucontext_addr + N64_UCONTEXT_LO);
  regnum = mips_regnum (gdbarch)->hi;
  trad_frame_set_reg_addr (cache,
			   regnum + gdbarch_num_regs (gdbarch),
			   ucontext_addr + N64_UCONTEXT_HI);

  if (target_read_memory (ucontext_addr + N64_UCONTEXT_FPUSED, buf, 4) == 0
      && extract_unsigned_integer (buf, 4, byte_order) != 0)
    {
      for (regnum = 0, addr = ucontext_addr + N64_UCONTEXT_FPREGS;
	   regnum < 32; regnum++, addr += N64_UCONTEXT_REG_SIZE)
	trad_frame_set_reg_addr (cache,
				 regnum + gdbarch_fp0_regnum (gdbarch),
				 addr);
      trad_frame_set_reg_addr (cache, mips_regnum (gdbarch)->fp_control_status,
			       addr);
    }

  trad_frame_set_id (cache, frame_id_build (sp, func));
}
예제 #10
0
void
alpha_bsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
{
  if (regno == -1 || getregs_supplies (regno))
    {
      struct reg gregs;

      if (ptrace (PT_GETREGS, regcache->ptid ().pid (),
		  (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
	perror_with_name (_("Couldn't get registers"));

      alphabsd_supply_reg (regcache, (char *) &gregs, regno);
      if (regno != -1)
	return;
    }

  if (regno == -1
      || regno >= gdbarch_fp0_regnum (regcache->arch ()))
    {
      struct fpreg fpregs;

      if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't get floating point status"));

      alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
    }
}
예제 #11
0
static CORE_ADDR
mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
{
  CORE_ADDR regaddr;

  if (regno < 0 || regno >= gdbarch_num_regs (gdbarch))
    error (_("Bogon register number %d."), regno);

  if (regno > MIPS_ZERO_REGNUM && regno < MIPS_ZERO_REGNUM + 32)
    regaddr = regno;
  else if ((regno >= mips_regnum (gdbarch)->fp0)
	   && (regno < mips_regnum (gdbarch)->fp0 + 32))
    regaddr = MIPS64_FPR_BASE + (regno - gdbarch_fp0_regnum (gdbarch));
  else if (regno == mips_regnum (gdbarch)->pc)
    regaddr = MIPS64_PC;
  else if (regno == mips_regnum (gdbarch)->cause)
    regaddr = store? (CORE_ADDR) -1 : MIPS64_CAUSE;
  else if (regno == mips_regnum (gdbarch)->badvaddr)
    regaddr = store? (CORE_ADDR) -1 : MIPS64_BADVADDR;
  else if (regno == mips_regnum (gdbarch)->lo)
    regaddr = MIPS64_MMLO;
  else if (regno == mips_regnum (gdbarch)->hi)
    regaddr = MIPS64_MMHI;
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
    regaddr = MIPS64_FPC_CSR;
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
    regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR;
  else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
    regaddr = 0;
  else
    regaddr = (CORE_ADDR) -1;

  return regaddr;
}
예제 #12
0
파일: irix5-nat.c 프로젝트: nds32/binutils
void
supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
{
  int regi;
  static char zerobuf[32] = {0};
  char fsrbuf[8];
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

  /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs.  */

  for (regi = 0; regi < 32; regi++)
    regcache_raw_supply (regcache, gdbarch_fp0_regnum (gdbarch) + regi,
			 (const char *) &fpregsetp->__fp_r.__fp_regs[regi]);

  /* We can't supply the FSR register directly to the regcache,
     because there is a size issue: On one hand, fpregsetp->fp_csr
     is 32bits long, while the regcache expects a 64bits long value.
     So we use a buffer of the correct size and copy into it the register
     value at the proper location.  */
  memset (fsrbuf, 0, 4);
  memcpy (fsrbuf + 4, &fpregsetp->__fp_csr, 4);

  regcache_raw_supply (regcache,
		       mips_regnum (gdbarch)->fp_control_status, fsrbuf);

  /* FIXME: how can we supply FCRIR?  SGI doesn't tell us.  */
  regcache_raw_supply (regcache,
		       mips_regnum (gdbarch)->fp_implementation_revision,
		       zerobuf);
}
예제 #13
0
void
supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
{
  if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) == 0)
    return;

  i387_supply_fsave (regcache, -1, fpregsetp);
}
예제 #14
0
void
fill_fpregset (const struct regcache *regcache,
	       fpregset_t *fpregsetp, int regno)
{
  if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) == 0)
    return;

  i387_collect_fsave (regcache, regno, fpregsetp);
}
예제 #15
0
void
fill_fpregset (const struct regcache *regcache,
	       elf_fpregset_t *fpregsetp, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int i;

  /* Fill in the floating-point registers.  */
  for (i = gdbarch_fp0_regnum (gdbarch);
       i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
    if (regno == -1 || regno == i)
      regcache_raw_collect (regcache, i,
			    FPREG_ADDR (fpregsetp,
				        i - gdbarch_fp0_regnum (gdbarch)));

  /* Fill in the floating-point control registers.  */
  for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
    if (regno == -1 || regno == i)
      regcache_raw_collect (regcache, i,
			    &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
}
예제 #16
0
파일: m68k-tdep.c 프로젝트: ChrisG0x20/gdb
static struct type *
m68k_register_type (struct gdbarch *gdbarch, int regnum)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  if (tdep->fpregs_present)
    {
      if (regnum >= gdbarch_fp0_regnum (gdbarch)
	  && regnum <= gdbarch_fp0_regnum (gdbarch) + 7)
	{
	  if (tdep->flavour == m68k_coldfire_flavour)
	    return builtin_type (gdbarch)->builtin_double;
	  else
	    return m68881_ext_type (gdbarch);
	}

      if (regnum == M68K_FPI_REGNUM)
	return builtin_type (gdbarch)->builtin_func_ptr;

      if (regnum == M68K_FPC_REGNUM || regnum == M68K_FPS_REGNUM)
	return builtin_type (gdbarch)->builtin_int32;
    }
  else
    {
      if (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM)
	return builtin_type (gdbarch)->builtin_int0;
    }

  if (regnum == gdbarch_pc_regnum (gdbarch))
    return builtin_type (gdbarch)->builtin_func_ptr;

  if (regnum >= M68K_A0_REGNUM && regnum <= M68K_A0_REGNUM + 7)
    return builtin_type (gdbarch)->builtin_data_ptr;

  if (regnum == M68K_PS_REGNUM)
    return m68k_ps_type (gdbarch);

  return builtin_type (gdbarch)->builtin_int32;
}
void
mipsnbsd_supply_fpreg (struct regcache *regcache, const char *fpregs, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int i;

  for (i = gdbarch_fp0_regnum (gdbarch);
       i <= mips_regnum (gdbarch)->fp_implementation_revision;
       i++)
    {
      if (regno == i || regno == -1)
	{
	  if (gdbarch_cannot_fetch_register (gdbarch, i))
	    regcache_raw_supply (regcache, i, NULL);
	  else
            regcache_raw_supply (regcache, i,
				 fpregs 
				 + ((i - gdbarch_fp0_regnum (gdbarch))
				    * mips_isa_regsize (gdbarch)));
	}
    }
}
예제 #18
0
파일: irix5-nat.c 프로젝트: nds32/binutils
void
fill_fpregset (const struct regcache *regcache,
	       fpregset_t *fpregsetp, int regno)
{
  int regi;
  char *from, *to;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

  /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs.  */

  for (regi = gdbarch_fp0_regnum (gdbarch);
       regi < gdbarch_fp0_regnum (gdbarch) + 32; regi++)
    {
      if ((regno == -1) || (regno == regi))
	{
	  const int fp0_regnum = gdbarch_fp0_regnum (gdbarch);

	  to = (char *) &(fpregsetp->__fp_r.__fp_regs[regi - fp0_regnum]);
          regcache_raw_collect (regcache, regi, to);
	}
    }

  if (regno == -1
      || regno == mips_regnum (gdbarch)->fp_control_status)
    {
      char fsrbuf[8];

      /* We can't fill the FSR register directly from the regcache,
         because there is a size issue: On one hand, fpregsetp->fp_csr
         is 32bits long, while the regcache expects a 64bits long buffer.
         So we use a buffer of the correct size and copy the register
         value from that buffer.  */
      regcache_raw_collect (regcache,
			    mips_regnum (gdbarch)->fp_control_status, fsrbuf);

      memcpy (&fpregsetp->__fp_csr, fsrbuf + 4, 4);
    }
}
static int
i386nto_register_area (int regno, int regset, unsigned *off)
{
  int len;

  *off = 0;
  if (regset == NTO_REG_GENERAL)
    {
      if (regno == -1)
	return NUM_GPREGS * 4;

      *off = nto_reg_offset (regno);
      if (*off == -1)
	return 0;
      return 4;
    }
  else if (regset == NTO_REG_FLOAT)
    {
      unsigned off_adjust, regsize, regset_size;

      if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
	{
	  off_adjust = 32;
	  regsize = 16;
	  regset_size = 512;
	}
      else
	{
	  off_adjust = 28;
	  regsize = 10;
	  regset_size = 128;
	}

      if (regno == -1)
	return regset_size;

      *off = (regno - gdbarch_fp0_regnum (current_gdbarch))
	     * regsize + off_adjust;
      return 10;
      /* Why 10 instead of regsize?  GDB only stores 10 bytes per FP
         register so if we're sending a register back to the target,
         we only want pdebug to write 10 bytes so as not to clobber
         the reserved 6 bytes in the fxsave structure.  */
    }
  return -1;
}
예제 #20
0
static void
fetch_core_registers (struct regcache *regcache,
		      char *core_reg_sect,
		      unsigned core_reg_size,
		      int which,
		      CORE_ADDR reg_addr)
{
  gdb_gregset_t gregset;
  gdb_fpregset_t fpregset;
  gdb_gregset_t *gregset_p = &gregset;
  gdb_fpregset_t *fpregset_p = &fpregset;

  switch (which)
    {
    case 0:
      if (core_reg_size != sizeof (gregset))
	warning (_("Wrong size gregset in core file."));
      else
	{
	  memcpy (&gregset, core_reg_sect, sizeof (gregset));
	  supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
	}
      break;

    case 2:
      if (core_reg_size != sizeof (fpregset))
	warning (_("Wrong size fpregset in core file."));
      else
	{
	  memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
	  if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) >= 0)
	    supply_fpregset (regcache,
			     (const gdb_fpregset_t *) fpregset_p);
	}
      break;

    default:
      /* We've covered all the kinds of registers we know about here,
         so this must be something we wouldn't know what to do with
         anyway.  Just ignore it.  */
      break;
    }
}
예제 #21
0
static void
mipsnbsd_store_inferior_registers (struct target_ops *ops,
				   struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  if (regno == -1 || getregs_supplies (gdbarch, regno))
    {
      struct reg regs;

      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
	perror_with_name (_("Couldn't get registers"));

      mipsnbsd_fill_reg (regcache, (char *) &regs, regno);

      if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), 
		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
	perror_with_name (_("Couldn't write registers"));

      if (regno != -1)
	return;
    }

  if (regno == -1
      || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
    {
      struct fpreg fpregs; 

      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't get floating point status"));

      mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno);

      if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't write floating point status"));
    }
}
예제 #22
0
void
mips_supply_fpregset (struct regcache *regcache,
		      const mips_elf_fpregset_t *fpregsetp)
{
  int regi;
  char zerobuf[MAX_REGISTER_SIZE];

  memset (zerobuf, 0, MAX_REGISTER_SIZE);

  for (regi = 0; regi < 32; regi++)
    regcache_raw_supply (regcache,
			 gdbarch_fp0_regnum (current_gdbarch) + regi,
			 *fpregsetp + regi);

  regcache_raw_supply (regcache,
		       mips_regnum (current_gdbarch)->fp_control_status,
		       *fpregsetp + 32);

  /* FIXME: how can we supply FCRIR?  The ABI doesn't tell us.  */
  regcache_raw_supply (regcache,
		       mips_regnum (current_gdbarch)->fp_implementation_revision,
		       zerobuf);
}
void
mips64_fill_fpregset (const struct regcache *regcache,
		      mips64_elf_fpregset_t *fpregsetp, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte *to;

  if ((regno >= gdbarch_fp0_regnum (gdbarch))
      && (regno < gdbarch_fp0_regnum (gdbarch) + 32))
    {
      /* See mips_linux_o32_sigframe_init for a description of the
	 peculiar FP register layout.  */
      if (register_size (gdbarch, regno) == 4)
	{
	  int regi = regno - gdbarch_fp0_regnum (gdbarch);

	  to = (gdb_byte *) (*fpregsetp + (regi & ~1));
	  if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (regi & 1))
	    to += 4;
	  regcache_raw_collect (regcache, regno, to);
	}
      else
	{
	  to = (gdb_byte *) (*fpregsetp + regno - gdbarch_fp0_regnum (gdbarch));
	  regcache_raw_collect (regcache, regno, to);
	}
    }
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
    {
      gdb_byte buf[MAX_REGISTER_SIZE];
      LONGEST val;

      regcache_raw_collect (regcache, regno, buf);
      val = extract_signed_integer (buf, register_size (gdbarch, regno),
				    byte_order);
      to = (gdb_byte *) (*fpregsetp + 32);
      store_signed_integer (to, 4, byte_order, val);
    }
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
    {
      gdb_byte buf[MAX_REGISTER_SIZE];
      LONGEST val;

      regcache_raw_collect (regcache, regno, buf);
      val = extract_signed_integer (buf, register_size (gdbarch, regno),
				    byte_order);
      to = (gdb_byte *) (*fpregsetp + 32) + 4;
      store_signed_integer (to, 4, byte_order, val);
    }
  else if (regno == -1)
    {
      int regi;

      for (regi = 0; regi < 32; regi++)
	mips64_fill_fpregset (regcache, fpregsetp,
			      gdbarch_fp0_regnum (gdbarch) + regi);
      mips64_fill_fpregset (regcache, fpregsetp,
			    mips_regnum (gdbarch)->fp_control_status);
      mips64_fill_fpregset (regcache, fpregsetp,
			    (mips_regnum (gdbarch)
			      ->fp_implementation_revision));
    }
}