Bruce Evans:

The enclosed diffs implement printing of the floating point state for
the version of gdb-3.5 in 386BSD-0.0.  I don't have gdb for 386BSD-0.1
but I've been told that it is also missing this feature.

The changes are small.  Code to read the FP state from the kernel was
#ifdef'ed out, but it essentially works.  Code to change the FP regs
is still #ifdef'ed out.  It is close to working too.  Printing of the
FP regs was broken because hard reg numbers were confused with stack
offsets.

4. The emulator does not handle FP errors right, and it does not
   communicate the emulated FP state to the rest of the kernel, so
   "info float" shows garbage.
This commit is contained in:
Nate Williams 1993-07-01 00:17:55 +00:00
parent beb7ebb072
commit 315615555c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=81

View File

@ -1748,12 +1748,18 @@ print_387_status (status, ep)
top = (ep->status >> 11) & 7;
printf ("regno tag msb lsb value\n");
printf (" regno tag msb lsb value\n");
for (fpreg = 7; fpreg >= 0; fpreg--)
{
int st_regno;
double val;
printf ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
/* The physical regno `fpreg' is only relevant as an index into the
* tag word. Logical `%st' numbers are required for indexing `p->regs.
*/
st_regno = (fpreg + 8 - top) & 0x7;
printf ("%%st(%d) %s ", st_regno, fpreg == top ? "=>" : " ");
switch ((ep->tag >> (fpreg * 2)) & 3)
{
@ -1763,11 +1769,12 @@ print_387_status (status, ep)
case 3: printf ("empty "); break;
}
for (i = 9; i >= 0; i--)
printf ("%02x", ep->regs[fpreg][i]);
printf ("%02x", ep->regs[st_regno][i]);
i387_to_double (ep->regs[fpreg], (char *)&val);
i387_to_double (ep->regs[st_regno], (char *)&val);
printf (" %g\n", val);
}
#if 0 /* reserved fields are always 0xffff on 486's */
if (ep->r0)
printf ("warning: reserved0 is 0x%x\n", ep->r0);
if (ep->r1)
@ -1776,8 +1783,14 @@ print_387_status (status, ep)
printf ("warning: reserved2 is 0x%x\n", ep->r2);
if (ep->r3)
printf ("warning: reserved3 is 0x%x\n", ep->r3);
#endif
}
#ifdef __386BSD__
#define fpstate save87
#define U_FPSTATE(u) u.u_pcb.pcb_savefpu
#endif
#ifndef U_FPSTATE
#define U_FPSTATE(u) u.u_fpstate
#endif
@ -1786,7 +1799,6 @@ i386_float_info ()
{
struct user u; /* just for address computations */
int i;
#ifndef __386BSD__
/* fpstate defined in <sys/user.h> */
struct fpstate *fpstatep;
char buf[sizeof (struct fpstate) + 2 * sizeof (int)];
@ -1797,6 +1809,7 @@ i386_float_info ()
extern int corechan;
int skip;
#ifndef __386BSD__ /* XXX - look at pcb flags */
uaddr = (char *)&u.u_fpvalid - (char *)&u;
if (have_inferior_p())
{
@ -1804,7 +1817,7 @@ i386_float_info ()
unsigned int mask;
rounded_addr = uaddr & -sizeof (int);
data = ptrace (3, inferior_pid, rounded_addr, 0);
data = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0);
mask = 0xff << ((uaddr - rounded_addr) * 8);
fpvalid = ((data & mask) != 0);
@ -1823,6 +1836,7 @@ i386_float_info ()
printf ("no floating point status saved\n");
return;
}
#endif /* not __386BSD__ */
uaddr = (char *)&U_FPSTATE(u) - (char *)&u;
if (have_inferior_p ())
@ -1837,7 +1851,7 @@ i386_float_info ()
ip = (int *)buf;
for (i = 0; i < rounded_size; i++)
{
*ip++ = ptrace (3, inferior_pid, rounded_addr, 0);
*ip++ = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0);
rounded_addr += sizeof (int);
}
}
@ -1850,6 +1864,9 @@ i386_float_info ()
skip = 0;
}
#ifdef __386BSD__
print_387_status (0, (struct env387 *)buf);
#else
fpstatep = (struct fpstate *)(buf + skip);
print_387_status (fpstatep->status, (struct env387 *)fpstatep->state);
#endif