2 Copyright (C) 1988, 1989 Free Software Foundation, Inc.
4 This file is part of GDB.
6 GDB is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GDB is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GDB; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
28 #include <sys/types.h>
31 #include <sys/param.h>
35 #include <sys/ioctl.h>
43 /* this table must line up with REGISTER_NAMES in m-i386.h */
44 /* symbols like 'EAX' come from <sys/reg.h> */
53 /* blockend is the value of u.u_ar0, and points to the
54 * place where GS is stored
56 i386_register_u_addr (blockend
, regnum
)
59 /* this will be needed if fp registers are reinstated */
60 /* for now, you can look at them with 'info float'
61 * sys5 wont let you change them with ptrace anyway
63 if (regnum
>= FP0_REGNUM
&& regnum
<= FP7_REGNUM
)
67 ubase
= blockend
+ 4 * (SS
+ 1) - KSTKSZ
;
68 fpstate
= ubase
+ ((char *)&u
.u_fpstate
- (char *)&u
);
69 return (fpstate
+ 0x1c + 10 * (regnum
- FP0_REGNUM
));
73 return (blockend
+ 4 * regmap
[regnum
]);
77 /* This is broken for cross debugging. Possible solutions are:
79 1. Don't worry about whether the thing compiles for cross-debugging.
80 Go ahead and call them from i386-tdep.c.
81 1a. Same thing but use some macros in xm-i386.h so that gdb will
82 compile for cross-debugging but just give an error (or some such behavior)
83 when you attempt to convert floats.
85 2. Write a portable (in the sense of running on any machine; it would
86 always be for i387 floating-point formats) extended<->double converter
87 (which just deals with the values as arrays of char).
89 3. Assume the host machine has *some* IEEE chip. However, IEEE does
90 not standardize formats for extended floats (387 is 10 bytes, 68881 is
91 12 bytes), so this won't work. */
93 i387_to_double (from
, to
)
98 /* push extended mode on 387 stack, then pop in double mode
100 * first, set exception masks so no error is generated -
101 * number will be rounded to inf or 0, if necessary
103 asm ("pushl %eax"); /* grab a stack slot */
104 asm ("fstcw (%esp)"); /* get 387 control word */
105 asm ("movl (%esp),%eax"); /* save old value */
106 asm ("orl $0x3f,%eax"); /* mask all exceptions */
108 asm ("fldcw (%esp)"); /* load new value into 387 */
110 asm ("movl 8(%ebp),%eax");
111 asm ("fldt (%eax)"); /* push extended number on 387 stack */
113 asm ("movl 12(%ebp),%eax");
114 asm ("fstpl (%eax)"); /* pop double */
117 asm ("popl %eax"); /* flush modified control word */
118 asm ("fnclex"); /* clear exceptions */
119 asm ("fldcw (%esp)"); /* restore original control word */
120 asm ("popl %eax"); /* flush saved copy */
123 double_to_i387 (from
, to
)
127 /* push double mode on 387 stack, then pop in extended mode
128 * no errors are possible because every 64-bit pattern
129 * can be converted to an extended
131 asm ("movl 8(%ebp),%eax");
134 asm ("movl 12(%ebp),%eax");
135 asm ("fstpt (%eax)");
141 unsigned short control
;
143 unsigned short status
;
148 unsigned short code_seg
;
149 unsigned short opcode
;
150 unsigned long operand
;
151 unsigned short operand_seg
;
153 unsigned char regs
[8][10];
157 print_387_control_word (control
)
158 unsigned short control
;
160 printf ("control 0x%04x: ", control
);
161 printf ("compute to ");
162 switch ((control
>> 8) & 3)
164 case 0: printf ("24 bits; "); break;
165 case 1: printf ("(bad); "); break;
166 case 2: printf ("53 bits; "); break;
167 case 3: printf ("64 bits; "); break;
170 switch ((control
>> 10) & 3)
172 case 0: printf ("NEAREST; "); break;
173 case 1: printf ("DOWN; "); break;
174 case 2: printf ("UP; "); break;
175 case 3: printf ("CHOP; "); break;
180 if (control
& 0x0001) printf (" INVALID");
181 if (control
& 0x0002) printf (" DENORM");
182 if (control
& 0x0004) printf (" DIVZ");
183 if (control
& 0x0008) printf (" OVERF");
184 if (control
& 0x0010) printf (" UNDERF");
185 if (control
& 0x0020) printf (" LOS");
189 if (control
& 0xe080) printf ("warning: reserved bits on 0x%x\n",
194 print_387_status_word (status
)
195 unsigned short status
;
197 printf ("status 0x%04x: ", status
);
200 printf ("exceptions:");
201 if (status
& 0x0001) printf (" INVALID");
202 if (status
& 0x0002) printf (" DENORM");
203 if (status
& 0x0004) printf (" DIVZ");
204 if (status
& 0x0008) printf (" OVERF");
205 if (status
& 0x0010) printf (" UNDERF");
206 if (status
& 0x0020) printf (" LOS");
207 if (status
& 0x0040) printf (" FPSTACK");
210 printf ("flags: %d%d%d%d; ",
211 (status
& 0x4000) != 0,
212 (status
& 0x0400) != 0,
213 (status
& 0x0200) != 0,
214 (status
& 0x0100) != 0);
216 printf ("top %d\n", (status
>> 11) & 7);
220 print_387_status (status
, ep
)
221 unsigned short status
;
230 bothstatus
= ((status
!= 0) && (ep
->status
!= 0));
235 print_387_status_word (status
);
242 print_387_status_word (ep
->status
);
245 print_387_control_word (ep
->control
);
246 printf ("last exception: ");
247 printf ("opcode 0x%x; ", ep
->opcode
);
248 printf ("pc 0x%x:0x%x; ", ep
->code_seg
, ep
->eip
);
249 printf ("operand 0x%x:0x%x\n", ep
->operand_seg
, ep
->operand
);
251 top
= (ep
->status
>> 11) & 7;
253 printf ("regno tag msb lsb value\n");
254 for (fpreg
= 7; fpreg
>= 0; fpreg
--)
258 printf ("%s %d: ", fpreg
== top
? "=>" : " ", fpreg
);
260 switch ((ep
->tag
>> (fpreg
* 2)) & 3)
262 case 0: printf ("valid "); break;
263 case 1: printf ("zero "); break;
264 case 2: printf ("trap "); break;
265 case 3: printf ("empty "); break;
267 for (i
= 9; i
>= 0; i
--)
268 printf ("%02x", ep
->regs
[fpreg
][i
]);
270 i387_to_double (ep
->regs
[fpreg
], (char *)&val
);
271 printf (" %g\n", val
);
274 printf ("warning: reserved0 is 0x%x\n", ep
->r0
);
276 printf ("warning: reserved1 is 0x%x\n", ep
->r1
);
278 printf ("warning: reserved2 is 0x%x\n", ep
->r2
);
280 printf ("warning: reserved3 is 0x%x\n", ep
->r3
);
284 #define U_FPSTATE(u) u.u_fpstate
289 struct user u
; /* just for address computations */
291 /* fpstate defined in <sys/user.h> */
292 struct fpstate
*fpstatep
;
293 char buf
[sizeof (struct fpstate
) + 2 * sizeof (int)];
296 unsigned int rounded_addr
;
297 unsigned int rounded_size
;
301 uaddr
= (char *)&u
.u_fpvalid
- (char *)&u
;
302 if (have_inferior_p())
307 rounded_addr
= uaddr
& -sizeof (int);
308 data
= ptrace (3, inferior_pid
, rounded_addr
, 0);
309 mask
= 0xff << ((uaddr
- rounded_addr
) * 8);
311 fpvalid
= ((data
& mask
) != 0);
315 if (lseek (corechan
, uaddr
, 0) < 0)
316 perror ("seek on core file");
317 if (myread (corechan
, &fpvalid
, 1) < 0)
318 perror ("read on core file");
324 printf ("no floating point status saved\n");
328 uaddr
= (char *)&U_FPSTATE(u
) - (char *)&u
;
329 if (have_inferior_p ())
333 rounded_addr
= uaddr
& -sizeof (int);
334 rounded_size
= (((uaddr
+ sizeof (struct fpstate
)) - uaddr
) +
335 sizeof (int) - 1) / sizeof (int);
336 skip
= uaddr
- rounded_addr
;
339 for (i
= 0; i
< rounded_size
; i
++)
341 *ip
++ = ptrace (3, inferior_pid
, rounded_addr
, 0);
342 rounded_addr
+= sizeof (int);
347 if (lseek (corechan
, uaddr
, 0) < 0)
348 perror_with_name ("seek on core file");
349 if (myread (corechan
, buf
, sizeof (struct fpstate
)) < 0)
350 perror_with_name ("read from core file");
354 fpstatep
= (struct fpstate
*)(buf
+ skip
);
355 print_387_status (fpstatep
->status
, (struct env387
*)fpstatep
->state
);
This page took 0.041004 seconds and 4 git commands to generate.