OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [gdb/] [i387-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* Intel 387 floating point stuff.
2
   Copyright (C) 1988, 89, 91, 98, 99, 2000 Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
6
   This program 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 2 of the License, or
9
   (at your option) any later version.
10
 
11
   This program 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.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
20
 
21
#include "defs.h"
22
#include "frame.h"
23
#include "inferior.h"
24
#include "language.h"
25
#include "value.h"
26
#include "gdbcore.h"
27
#include "floatformat.h"
28
 
29
 
30
/* FIXME: Eliminate the next two functions when we have the time to
31
   change all the callers.  */
32
 
33
void i387_to_double PARAMS ((char *from, char *to));
34
void double_to_i387 PARAMS ((char *from, char *to));
35
 
36
void
37
i387_to_double (from, to)
38
     char *from;
39
     char *to;
40
{
41
  floatformat_to_double (&floatformat_i387_ext, from, (double *) to);
42
}
43
 
44
void
45
double_to_i387 (from, to)
46
     char *from;
47
     char *to;
48
{
49
  floatformat_from_double (&floatformat_i387_ext, (double *) from, to);
50
}
51
 
52
 
53
/* FIXME: The functions on this page are used by the old `info float'
54
   implementations that a few of the i386 targets provide.  These
55
   functions should be removed if all of these have been converted to
56
   use the generic implementation based on the new register file
57
   layout.  */
58
 
59
static void print_387_control_bits PARAMS ((unsigned int control));
60
static void print_387_status_bits PARAMS ((unsigned int status));
61
 
62
static void
63
print_387_control_bits (control)
64
     unsigned int control;
65
{
66
  switch ((control >> 8) & 3)
67
    {
68
    case 0:
69
      puts_unfiltered (" 24 bit; ");
70
      break;
71
    case 1:
72
      puts_unfiltered (" (bad); ");
73
      break;
74
    case 2:
75
      puts_unfiltered (" 53 bit; ");
76
      break;
77
    case 3:
78
      puts_unfiltered (" 64 bit; ");
79
      break;
80
    }
81
  switch ((control >> 10) & 3)
82
    {
83
    case 0:
84
      puts_unfiltered ("NEAR; ");
85
      break;
86
    case 1:
87
      puts_unfiltered ("DOWN; ");
88
      break;
89
    case 2:
90
      puts_unfiltered ("UP; ");
91
      break;
92
    case 3:
93
      puts_unfiltered ("CHOP; ");
94
      break;
95
    }
96
  if (control & 0x3f)
97
    {
98
      puts_unfiltered ("mask");
99
      if (control & 0x0001)
100
        puts_unfiltered (" INVAL");
101
      if (control & 0x0002)
102
        puts_unfiltered (" DENOR");
103
      if (control & 0x0004)
104
        puts_unfiltered (" DIVZ");
105
      if (control & 0x0008)
106
        puts_unfiltered (" OVERF");
107
      if (control & 0x0010)
108
        puts_unfiltered (" UNDER");
109
      if (control & 0x0020)
110
        puts_unfiltered (" LOS");
111
      puts_unfiltered (";");
112
    }
113
 
114
  if (control & 0xe080)
115
    warning ("\nreserved bits on: %s",
116
             local_hex_string (control & 0xe080));
117
}
118
 
119
void
120
print_387_control_word (control)
121
     unsigned int control;
122
{
123
  printf_filtered ("control %s:", local_hex_string(control & 0xffff));
124
  print_387_control_bits (control);
125
  puts_unfiltered ("\n");
126
}
127
 
128
static void
129
print_387_status_bits (status)
130
     unsigned int status;
131
{
132
  printf_unfiltered (" flags %d%d%d%d; ",
133
                     (status & 0x4000) != 0,
134
                     (status & 0x0400) != 0,
135
                     (status & 0x0200) != 0,
136
                     (status & 0x0100) != 0);
137
  printf_unfiltered ("top %d; ", (status >> 11) & 7);
138
  if (status & 0xff)
139
    {
140
      puts_unfiltered ("excep");
141
      if (status & 0x0001) puts_unfiltered (" INVAL");
142
      if (status & 0x0002) puts_unfiltered (" DENOR");
143
      if (status & 0x0004) puts_unfiltered (" DIVZ");
144
      if (status & 0x0008) puts_unfiltered (" OVERF");
145
      if (status & 0x0010) puts_unfiltered (" UNDER");
146
      if (status & 0x0020) puts_unfiltered (" LOS");
147
      if (status & 0x0040) puts_unfiltered (" STACK");
148
    }
149
}
150
 
151
void
152
print_387_status_word (status)
153
     unsigned int status;
154
{
155
  printf_filtered ("status %s:", local_hex_string (status & 0xffff));
156
  print_387_status_bits (status);
157
  puts_unfiltered ("\n");
158
}
159
 
160
 
161
/* Implement the `info float' layout based on the register definitions
162
   in `tm-i386.h'.  */
163
 
164
/* Print the floating point number specified by RAW.  */
165
static void
166
print_i387_value (char *raw)
167
{
168
  DOUBLEST value;
169
 
170
  /* Avoid call to floatformat_to_doublest if possible to preserve as
171
     much information as possible.  */
172
 
173
#ifdef HAVE_LONG_DOUBLE
174
  if (sizeof (value) == sizeof (long double)
175
      && HOST_LONG_DOUBLE_FORMAT == &floatformat_i387_ext)
176
    {
177
      /* Copy straight over, but take care of the padding.  */
178
      memcpy (&value, raw, FPU_REG_RAW_SIZE);
179
      memset (&value + FPU_REG_RAW_SIZE, 0, sizeof (value) - FPU_REG_RAW_SIZE);
180
    }
181
  else
182
#endif
183
    floatformat_to_doublest (&floatformat_i387_ext, raw, &value);
184
 
185
  /* We try to print 19 digits.  The last digit may or may not contain
186
     garbage, but we'd better print one too many.  We need enough room
187
     to print the value, 1 position for the sign, 1 for the decimal
188
     point, 19 for the digits and 6 for the exponent adds up to 27.  */
189
#ifdef PRINTF_HAS_LONG_DOUBLE
190
  printf_filtered (" %-+27.19Lg", (long double) value);
191
#else
192
  printf_filtered (" %-+27.19g", (double) value);
193
#endif
194
}
195
 
196
/* Print the classification for the register contents RAW.  */
197
static void
198
print_i387_ext (unsigned char *raw)
199
{
200
  int sign;
201
  int integer;
202
  unsigned int exponent;
203
  unsigned long fraction[2];
204
 
205
  sign = raw[9] & 0x80;
206
  integer = raw[7] & 0x80;
207
  exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
208
  fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
209
  fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
210
                 | (raw[5] << 8) | raw[4]);
211
 
212
  if (exponent == 0x7fff && integer)
213
    {
214
      if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
215
        /* Infinity.  */
216
        printf_filtered (" %cInf", (sign ? '-' : '+'));
217
      else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
218
        /* Real Indefinite (QNaN).  */
219
        puts_unfiltered (" Real Indefinite (QNaN)");
220
      else if (fraction[1] & 0x40000000)
221
        /* QNaN.  */
222
        puts_filtered (" QNaN");
223
      else
224
        /* SNaN.  */
225
        puts_filtered (" SNaN");
226
    }
227
  else if (exponent < 0x7fff && exponent > 0x0000 && integer)
228
    /* Normal.  */
229
    print_i387_value (raw);
230
  else if (exponent == 0x0000)
231
    {
232
      /* Denormal or zero.  */
233
      print_i387_value (raw);
234
 
235
      if (integer)
236
        /* Pseudo-denormal.  */
237
        puts_filtered (" Pseudo-denormal");
238
      else if (fraction[0] || fraction[1])
239
        /* Denormal.  */
240
        puts_filtered (" Denormal");
241
    }
242
  else
243
    /* Unsupported.  */
244
    puts_filtered (" Unsupported");
245
}
246
 
247
/* Print the status word STATUS.  */
248
static void
249
print_i387_status_word (unsigned int status)
250
{
251
  printf_filtered ("Status Word:         %s",
252
                   local_hex_string_custom (status, "04"));
253
  puts_filtered ("  ");
254
  printf_filtered (" %s", (status & 0x0001) ? "IE" : "  ");
255
  printf_filtered (" %s", (status & 0x0002) ? "DE" : "  ");
256
  printf_filtered (" %s", (status & 0x0004) ? "ZE" : "  ");
257
  printf_filtered (" %s", (status & 0x0008) ? "OE" : "  ");
258
  printf_filtered (" %s", (status & 0x0010) ? "UE" : "  ");
259
  printf_filtered (" %s", (status & 0x0020) ? "PE" : "  ");
260
  puts_filtered ("  ");
261
  printf_filtered (" %s", (status & 0x0080) ? "ES" : "  ");
262
  puts_filtered ("  ");
263
  printf_filtered (" %s", (status & 0x0080) ? "SF" : "  ");
264
  puts_filtered ("  ");
265
  printf_filtered (" %s", (status & 0x0100) ? "C0" : "  ");
266
  printf_filtered (" %s", (status & 0x0200) ? "C1" : "  ");
267
  printf_filtered (" %s", (status & 0x0400) ? "C2" : "  ");
268
  printf_filtered (" %s", (status & 0x4000) ? "C3" : "  ");
269
 
270
  puts_filtered ("\n");
271
 
272
  printf_filtered ("                       TOP: %d\n", ((status >> 11) & 7));
273
}
274
 
275
/* Print the control word CONTROL.  */
276
static void
277
print_i387_control_word (unsigned int control)
278
{
279
  printf_filtered ("Control Word:        %s",
280
                   local_hex_string_custom (control, "04"));
281
  puts_filtered ("  ");
282
  printf_filtered (" %s", (control & 0x0001) ? "IM" : "  ");
283
  printf_filtered (" %s", (control & 0x0002) ? "DM" : "  ");
284
  printf_filtered (" %s", (control & 0x0004) ? "ZM" : "  ");
285
  printf_filtered (" %s", (control & 0x0008) ? "OM" : "  ");
286
  printf_filtered (" %s", (control & 0x0010) ? "UM" : "  ");
287
  printf_filtered (" %s", (control & 0x0020) ? "PM" : "  ");
288
 
289
  puts_filtered ("\n");
290
 
291
  puts_filtered ("                       PC: ");
292
  switch ((control >> 8) & 3)
293
    {
294
    case 0:
295
      puts_filtered ("Single Precision (24-bits)\n");
296
      break;
297
    case 1:
298
      puts_filtered ("Reserved\n");
299
      break;
300
    case 2:
301
      puts_filtered ("Double Precision (53-bits)\n");
302
      break;
303
    case 3:
304
      puts_filtered ("Extended Precision (64-bits)\n");
305
      break;
306
    }
307
 
308
  puts_filtered ("                       RC: ");
309
  switch ((control >> 10) & 3)
310
    {
311
    case 0:
312
      puts_filtered ("Round to nearest\n");
313
      break;
314
    case 1:
315
      puts_filtered ("Round down\n");
316
      break;
317
    case 2:
318
      puts_filtered ("Round up\n");
319
      break;
320
    case 3:
321
      puts_filtered ("Round toward zero\n");
322
      break;
323
    }
324
}
325
 
326
/* Print out the i387 floating poin state.  */
327
void
328
i387_float_info (void)
329
{
330
  unsigned int fctrl;
331
  unsigned int fstat;
332
  unsigned int ftag;
333
  unsigned int fiseg;
334
  unsigned int fioff;
335
  unsigned int foseg;
336
  unsigned int fooff;
337
  unsigned int fop;
338
  int fpreg;
339
  int top;
340
 
341
  fctrl = read_register (FCTRL_REGNUM);
342
  fstat = read_register (FSTAT_REGNUM);
343
  ftag  = read_register (FTAG_REGNUM);
344
  fiseg = read_register (FCS_REGNUM);
345
  fioff = read_register (FCOFF_REGNUM);
346
  foseg = read_register (FDS_REGNUM);
347
  fooff = read_register (FDOFF_REGNUM);
348
  fop   = read_register (FOP_REGNUM);
349
 
350
  top = ((fstat >> 11) & 7);
351
 
352
  for (fpreg = 7; fpreg >= 0; fpreg--)
353
    {
354
      unsigned char raw[FPU_REG_RAW_SIZE];
355
      int tag = (ftag >> (fpreg * 2)) & 3;
356
      int i;
357
 
358
      printf_filtered ("%sR%d: ", fpreg == top ? "=>" : "  ", fpreg);
359
 
360
      switch (tag)
361
        {
362
        case 0:
363
          puts_filtered ("Valid   ");
364
          break;
365
        case 1:
366
          puts_filtered ("Zero    ");
367
          break;
368
        case 2:
369
          puts_filtered ("Special ");
370
          break;
371
        case 3:
372
          puts_filtered ("Empty   ");
373
          break;
374
        }
375
 
376
      read_register_gen ((fpreg + 8 - top) % 8 + FP0_REGNUM, raw);
377
 
378
      puts_filtered ("0x");
379
      for (i = 9; i >= 0; i--)
380
        printf_filtered ("%02x", raw[i]);
381
 
382
      if (tag != 3)
383
        print_i387_ext (raw);
384
 
385
      puts_filtered ("\n");
386
    }
387
 
388
  puts_filtered ("\n");
389
 
390
  print_i387_status_word (fstat);
391
  print_i387_control_word (fctrl);
392
  printf_filtered ("Tag Word:            %s\n",
393
                   local_hex_string_custom (ftag, "04"));
394
  printf_filtered ("Instruction Pointer: %s:",
395
                   local_hex_string_custom (fiseg, "02"));
396
  printf_filtered ("%s\n", local_hex_string_custom (fioff, "08"));
397
  printf_filtered ("Operand Pointer:     %s:",
398
                   local_hex_string_custom (foseg, "02"));
399
  printf_filtered ("%s\n", local_hex_string_custom (fooff, "08"));
400
  printf_filtered ("Opcode:              %s\n",
401
                   local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04"));
402
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.