2002-08-13 Andrew Cagney <cagney@redhat.com>
* i386-tdep.c (i386_register_name): Handle mmx registers. (mmx_regnum_p): New function. (i386_mmx_names): New array. (mmx_num_regs): New variable. (i386_pseudo_register_read): New function. (i386_pseudo_register_write): New function. (mmx_regnum_to_fp_regnum): New function. Code from Fernando Nasser. * regcache.c (regcache_raw_read_unsigned): New function. (regcache_raw_read_signed): New function. * regcache.h (regcache_raw_read_unsigned): Declare. (regcache_raw_read_signed): Declare.
This commit is contained in:
parent
a378f41926
commit
28fc674094
4 changed files with 123 additions and 0 deletions
|
@ -1,3 +1,18 @@
|
|||
2002-08-13 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* i386-tdep.c (i386_register_name): Handle mmx registers.
|
||||
(mmx_regnum_p): New function.
|
||||
(i386_mmx_names): New array.
|
||||
(mmx_num_regs): New variable.
|
||||
(i386_pseudo_register_read): New function.
|
||||
(i386_pseudo_register_write): New function.
|
||||
(mmx_regnum_to_fp_regnum): New function. Code from Fernando Nasser.
|
||||
|
||||
* regcache.c (regcache_raw_read_unsigned): New function.
|
||||
(regcache_raw_read_signed): New function.
|
||||
* regcache.h (regcache_raw_read_unsigned): Declare.
|
||||
(regcache_raw_read_signed): Declare.
|
||||
|
||||
2002-08-13 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* regcache.c (regcache_raw_read_as_address): Delete function.
|
||||
|
|
|
@ -56,6 +56,23 @@ static char *i386_register_names[] =
|
|||
"mxcsr"
|
||||
};
|
||||
|
||||
/* MMX registers. */
|
||||
|
||||
static char *i386_mmx_names[] =
|
||||
{
|
||||
"mm0", "mm1", "mm2", "mm3",
|
||||
"mm4", "mm5", "mm6", "mm7"
|
||||
};
|
||||
static const int mmx_num_regs = (sizeof (i386_mmx_names)
|
||||
/ sizeof (i386_mmx_names[0]));
|
||||
#define MM0_REGNUM (NUM_REGS)
|
||||
|
||||
static int
|
||||
mmx_regnum_p (int reg)
|
||||
{
|
||||
return (reg >= MM0_REGNUM && reg < MM0_REGNUM + mmx_num_regs);
|
||||
}
|
||||
|
||||
/* Return the name of register REG. */
|
||||
|
||||
const char *
|
||||
|
@ -63,6 +80,8 @@ i386_register_name (int reg)
|
|||
{
|
||||
if (reg < 0)
|
||||
return NULL;
|
||||
if (mmx_regnum_p (reg))
|
||||
return i386_mmx_names[reg - MM0_REGNUM];
|
||||
if (reg >= sizeof (i386_register_names) / sizeof (*i386_register_names))
|
||||
return NULL;
|
||||
|
||||
|
@ -1090,9 +1109,64 @@ i386_register_virtual_type (int regnum)
|
|||
if (IS_SSE_REGNUM (regnum))
|
||||
return builtin_type_vec128i;
|
||||
|
||||
if (mmx_regnum_p (regnum))
|
||||
return builtin_type_vec64i;
|
||||
|
||||
return builtin_type_int;
|
||||
}
|
||||
|
||||
/* Map a cooked register onto a raw register or memory. For the i386,
|
||||
the MMX registers need to be mapped onto floating point registers. */
|
||||
|
||||
static int
|
||||
mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
|
||||
{
|
||||
int mmxi;
|
||||
ULONGEST fstat;
|
||||
int tos;
|
||||
int fpi;
|
||||
mmxi = regnum - MM0_REGNUM;
|
||||
regcache_raw_read_unsigned (regcache, FSTAT_REGNUM, &fstat);
|
||||
tos = (fstat >> 11) & 0x7;
|
||||
fpi = (mmxi + tos) % 8;
|
||||
return (FP0_REGNUM + fpi);
|
||||
}
|
||||
|
||||
static void
|
||||
i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
int regnum, void *buf)
|
||||
{
|
||||
if (mmx_regnum_p (regnum))
|
||||
{
|
||||
char *mmx_buf = alloca (MAX_REGISTER_RAW_SIZE);
|
||||
int fpnum = mmx_regnum_to_fp_regnum (regcache, regnum);
|
||||
regcache_raw_read (regcache, fpnum, mmx_buf);
|
||||
/* Extract (always little endian). */
|
||||
memcpy (buf, mmx_buf, REGISTER_RAW_SIZE (regnum));
|
||||
}
|
||||
else
|
||||
regcache_raw_read (regcache, regnum, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
int regnum, const void *buf)
|
||||
{
|
||||
if (mmx_regnum_p (regnum))
|
||||
{
|
||||
char *mmx_buf = alloca (MAX_REGISTER_RAW_SIZE);
|
||||
int fpnum = mmx_regnum_to_fp_regnum (regcache, regnum);
|
||||
/* Read ... */
|
||||
regcache_raw_read (regcache, fpnum, mmx_buf);
|
||||
/* ... Modify ... (always little endian). */
|
||||
memcpy (mmx_buf, buf, REGISTER_RAW_SIZE (regnum));
|
||||
/* ... Write. */
|
||||
regcache_raw_write (regcache, fpnum, mmx_buf);
|
||||
}
|
||||
else
|
||||
regcache_raw_write (regcache, regnum, buf);
|
||||
}
|
||||
|
||||
/* Return true iff register REGNUM's virtual format is different from
|
||||
its raw format. Note that this definition assumes that the host
|
||||
supports IEEE 32-bit floats, since it doesn't say that SSE
|
||||
|
@ -1486,6 +1560,11 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
set_gdbarch_frame_num_args (gdbarch, i386_frame_num_args);
|
||||
set_gdbarch_pc_in_sigtramp (gdbarch, i386_pc_in_sigtramp);
|
||||
|
||||
/* Wire in the MMX registers. */
|
||||
set_gdbarch_num_pseudo_regs (gdbarch, mmx_num_regs);
|
||||
set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
|
||||
set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
|
||||
|
||||
/* Hook in ABI-specific overrides, if they have been registered. */
|
||||
gdbarch_init_osabi (info, gdbarch, osabi);
|
||||
|
||||
|
|
|
@ -660,6 +660,31 @@ regcache_raw_read (struct regcache *regcache, int regnum, void *buf)
|
|||
regcache->descr->sizeof_register[regnum]);
|
||||
}
|
||||
|
||||
void
|
||||
regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
|
||||
{
|
||||
char *buf;
|
||||
gdb_assert (regcache != NULL);
|
||||
gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
|
||||
buf = alloca (regcache->descr->sizeof_register[regnum]);
|
||||
regcache_raw_read (regcache, regnum, buf);
|
||||
(*val) = extract_signed_integer (buf,
|
||||
regcache->descr->sizeof_register[regnum]);
|
||||
}
|
||||
|
||||
void
|
||||
regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
|
||||
ULONGEST *val)
|
||||
{
|
||||
char *buf;
|
||||
gdb_assert (regcache != NULL);
|
||||
gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
|
||||
buf = alloca (regcache->descr->sizeof_register[regnum]);
|
||||
regcache_raw_read (regcache, regnum, buf);
|
||||
(*val) = extract_unsigned_integer (buf,
|
||||
regcache->descr->sizeof_register[regnum]);
|
||||
}
|
||||
|
||||
void
|
||||
read_register_gen (int regnum, char *buf)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,10 @@ struct regcache *regcache_xmalloc (struct gdbarch *gdbarch);
|
|||
void regcache_raw_read (struct regcache *regcache, int rawnum, void *buf);
|
||||
void regcache_raw_write (struct regcache *regcache, int rawnum,
|
||||
const void *buf);
|
||||
extern void regcache_raw_read_signed (struct regcache *regcache,
|
||||
int regnum, LONGEST *val);
|
||||
extern void regcache_raw_read_unsigned (struct regcache *regcache,
|
||||
int regnum, ULONGEST *val);
|
||||
int regcache_valid_p (struct regcache *regcache, int regnum);
|
||||
|
||||
/* Transfer a cooked register [0..NUM_REGS+NUM_PSEUDO_REGS). */
|
||||
|
|
Loading…
Reference in a new issue