diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b1ee580ec8..2dec108295 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2002-05-11 Mark Kettenis + + * 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 From Christian Limpach diff --git a/gdb/i387-nat.c b/gdb/i387-nat.c index 163dcfdfcd..7cb42baa99 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));