summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/i387-nat.c78
2 files changed, 38 insertions, 47 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b1ee580ec8a..2dec1082953 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2002-05-11 Mark Kettenis <kettenis@gnu.org>
+
+ * i387-nat.c (i387_supply_register, i387_fill_fsave,
+ i387_supply_fxsave, i387_fill_fxsave): Rewrite in order to do the
+ right thing on architectures with different endianness and/or
+ integer sizes.
+
2002-05-10 Jason Thorpe <thorpej@wasabisystems.com>
From Christian Limpach <chris@Pin.LU>
diff --git a/gdb/i387-nat.c b/gdb/i387-nat.c
index 163dcfdfcdd..7cb42baa99b 100644
--- a/gdb/i387-nat.c
+++ b/gdb/i387-nat.c
@@ -1,5 +1,5 @@
/* Native-dependent code for the i387.
- Copyright 2000, 2001 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GDB.
@@ -71,15 +71,13 @@ i387_supply_register (int regnum, char *fsave)
if (regnum >= FPC_REGNUM
&& regnum != FIOFF_REGNUM && regnum != FOOFF_REGNUM)
{
- unsigned int val = *(unsigned short *) (FSAVE_ADDR (fsave, regnum));
+ unsigned char val[4];
+ memcpy (val, FSAVE_ADDR (fsave, regnum), 2);
+ val[2] = val[3] = 0;
if (regnum == FOP_REGNUM)
- {
- val &= ((1 << 11) - 1);
- supply_register (regnum, (char *) &val);
- }
- else
- supply_register (regnum, (char *) &val);
+ val[1] &= ((1 << 3) - 1);
+ supply_register (regnum, val);
}
else
supply_register (regnum, FSAVE_ADDR (fsave, regnum));
@@ -116,23 +114,18 @@ i387_fill_fsave (char *fsave, int regnum)
if (i >= FPC_REGNUM
&& i != FIOFF_REGNUM && i != FOOFF_REGNUM)
{
- char buf[4];
+ unsigned char buf[4];
regcache_collect (i, buf);
if (i == FOP_REGNUM)
{
- unsigned short oldval, newval;
-
- /* The opcode occupies only 11 bits. */
- oldval = (*(unsigned short *) (FSAVE_ADDR (fsave, i)));
- newval = *(unsigned short *) buf;
- newval &= ((1 << 11) - 1);
- newval |= oldval & ~((1 << 11) - 1);
- memcpy (FSAVE_ADDR (fsave, i), &newval, 2);
+ /* The opcode occupies only 11 bits. Make sure we
+ don't touch the other bits. */
+ buf[1] &= ((1 << 3) - 1);
+ buf[1] |= ((FSAVE_ADDR (fsave, i))[1] & ~((1 << 3) - 1));
}
- else
- memcpy (FSAVE_ADDR (fsave, i), buf, 2);
+ memcpy (FSAVE_ADDR (fsave, i), buf, 2);
}
else
regcache_collect (i, FSAVE_ADDR (fsave, i));
@@ -195,13 +188,12 @@ i387_supply_fxsave (char *fxsave)
if (i >= FPC_REGNUM && i < XMM0_REGNUM
&& i != FIOFF_REGNUM && i != FOOFF_REGNUM)
{
- unsigned long val = *(unsigned short *) (FXSAVE_ADDR (fxsave, i));
+ unsigned char val[4];
+ memcpy (val, FXSAVE_ADDR (fxsave, i), 2);
+ val[2] = val[3] = 0;
if (i == FOP_REGNUM)
- {
- val &= ((1 << 11) - 1);
- supply_register (i, (char *) &val);
- }
+ val[1] &= ((1 << 3) - 1);
else if (i== FTAG_REGNUM)
{
/* The fxsave area contains a simplified version of the
@@ -209,18 +201,16 @@ i387_supply_fxsave (char *fxsave)
data to recreate the traditional i387 tag word. */
unsigned long ftag = 0;
- unsigned long fstat;
int fpreg;
int top;
- fstat = *(unsigned short *) (FXSAVE_ADDR (fxsave, FSTAT_REGNUM));
- top = ((fstat >> 11) & 0x7);
+ top = (((FXSAVE_ADDR (fxsave, FSTAT_REGNUM))[1] >> 3) & 0x7);
for (fpreg = 7; fpreg >= 0; fpreg--)
{
int tag;
- if (val & (1 << fpreg))
+ if (val[0] & (1 << fpreg))
{
int regnum = (fpreg + 8 - top) % 8 + FP0_REGNUM;
tag = i387_tag (FXSAVE_ADDR (fxsave, regnum));
@@ -230,10 +220,10 @@ i387_supply_fxsave (char *fxsave)
ftag |= tag << (2 * fpreg);
}
- supply_register (i, (char *) &ftag);
+ val[0] = ftag & 0xff;
+ val[1] = (ftag >> 8) & 0xff;
}
- else
- supply_register (i, (char *) &val);
+ supply_register (i, val);
}
else
supply_register (i, FXSAVE_ADDR (fxsave, i));
@@ -258,43 +248,37 @@ i387_fill_fxsave (char *fxsave, int regnum)
if (i >= FPC_REGNUM && i < XMM0_REGNUM
&& i != FIOFF_REGNUM && i != FDOFF_REGNUM)
{
- char buf[4];
+ unsigned char buf[4];
regcache_collect (i, buf);
if (i == FOP_REGNUM)
{
- unsigned short oldval, newval;
-
- /* The opcode occupies only 11 bits. */
- oldval = (*(unsigned short *) (FXSAVE_ADDR (fxsave, i)));
- newval = *(unsigned short *) buf;
- newval &= ((1 << 11) - 1);
- newval |= oldval & ~((1 << 11) - 1);
- memcpy (FXSAVE_ADDR (fxsave, i), &newval, 2);
+ /* The opcode occupies only 11 bits. Make sure we
+ don't touch the other bits. */
+ buf[1] &= ((1 << 3) - 1);
+ buf[1] |= ((FXSAVE_ADDR (fxsave, i))[1] & ~((1 << 3) - 1));
}
else if (i == FTAG_REGNUM)
{
/* Converting back is much easier. */
- unsigned short val = 0;
unsigned short ftag;
int fpreg;
- ftag = *(unsigned short *) buf;
+ ftag = (buf[1] << 8) | buf[0];
+ buf[0] = 0;
+ buf[1] = 0;
for (fpreg = 7; fpreg >= 0; fpreg--)
{
int tag = (ftag >> (fpreg * 2)) & 3;
if (tag != 3)
- val |= (1 << fpreg);
+ buf[0] |= (1 << fpreg);
}
-
- memcpy (FXSAVE_ADDR (fxsave, i), &val, 2);
}
- else
- memcpy (FXSAVE_ADDR (fxsave, i), buf, 2);
+ memcpy (FXSAVE_ADDR (fxsave, i), buf, 2);
}
else
regcache_collect (i, FXSAVE_ADDR (fxsave, i));