OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [atof-vax.c] - Blame information for rev 241

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* atof_vax.c - turn a Flonum into a VAX floating point number
2
   Copyright 1987, 1992, 1993, 1995, 1997, 1999, 2000, 2005, 2007
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GAS, the GNU Assembler.
6
 
7
   GAS is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   GAS is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with GAS; see the file COPYING.  If not, write to the Free
19
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20
   02110-1301, USA.  */
21
 
22
#include "as.h"
23
 
24
/* Precision in LittleNums.  */
25
#define MAX_PRECISION   8
26
#define H_PRECISION     8
27
#define G_PRECISION     4
28
#define D_PRECISION     4
29
#define F_PRECISION     2
30
 
31
/* Length in LittleNums of guard bits.  */
32
#define GUARD           2
33
 
34
int flonum_gen2vax (int, FLONUM_TYPE *, LITTLENUM_TYPE *);
35
 
36
/* Number of chars in flonum type 'letter'.  */
37
 
38
static unsigned int
39
atof_vax_sizeof (int letter)
40
{
41
  int return_value;
42
 
43
  /* Permitting uppercase letters is probably a bad idea.
44
     Please use only lower-cased letters in case the upper-cased
45
     ones become unsupported!  */
46
  switch (letter)
47
    {
48
    case 'f':
49
    case 'F':
50
      return_value = 4;
51
      break;
52
 
53
    case 'd':
54
    case 'D':
55
    case 'g':
56
    case 'G':
57
      return_value = 8;
58
      break;
59
 
60
    case 'h':
61
    case 'H':
62
      return_value = 16;
63
      break;
64
 
65
    default:
66
      return_value = 0;
67
      break;
68
    }
69
 
70
  return return_value;
71
}
72
 
73
static const long mask[] =
74
{
75
  0x00000000,
76
  0x00000001,
77
  0x00000003,
78
  0x00000007,
79
  0x0000000f,
80
  0x0000001f,
81
  0x0000003f,
82
  0x0000007f,
83
  0x000000ff,
84
  0x000001ff,
85
  0x000003ff,
86
  0x000007ff,
87
  0x00000fff,
88
  0x00001fff,
89
  0x00003fff,
90
  0x00007fff,
91
  0x0000ffff,
92
  0x0001ffff,
93
  0x0003ffff,
94
  0x0007ffff,
95
  0x000fffff,
96
  0x001fffff,
97
  0x003fffff,
98
  0x007fffff,
99
  0x00ffffff,
100
  0x01ffffff,
101
  0x03ffffff,
102
  0x07ffffff,
103
  0x0fffffff,
104
  0x1fffffff,
105
  0x3fffffff,
106
  0x7fffffff,
107
  0xffffffff
108
};
109
 
110
 
111
/* Shared between flonum_gen2vax and next_bits.  */
112
static int bits_left_in_littlenum;
113
static LITTLENUM_TYPE *littlenum_pointer;
114
static LITTLENUM_TYPE *littlenum_end;
115
 
116
static int
117
next_bits (int number_of_bits)
118
{
119
  int return_value;
120
 
121
  if (littlenum_pointer < littlenum_end)
122
    return 0;
123
  if (number_of_bits >= bits_left_in_littlenum)
124
    {
125
      return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
126
      number_of_bits -= bits_left_in_littlenum;
127
      return_value <<= number_of_bits;
128
      bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
129
      littlenum_pointer--;
130
      if (littlenum_pointer >= littlenum_end)
131
        return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & mask[number_of_bits];
132
    }
133
  else
134
    {
135
      bits_left_in_littlenum -= number_of_bits;
136
      return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum);
137
    }
138
  return return_value;
139
}
140
 
141
static void
142
make_invalid_floating_point_number (LITTLENUM_TYPE *words)
143
{
144
  *words = 0x8000;              /* Floating Reserved Operand Code.  */
145
}
146
 
147
 
148
static int                      /* 0 means letter is OK.  */
149
what_kind_of_float (int letter,                 /* In: lowercase please. What kind of float?  */
150
                    int *precisionP,            /* Number of 16-bit words in the float.  */
151
                    long *exponent_bitsP)       /* Number of exponent bits.  */
152
{
153
  int retval;
154
 
155
  retval = 0;
156
  switch (letter)
157
    {
158
    case 'f':
159
      *precisionP = F_PRECISION;
160
      *exponent_bitsP = 8;
161
      break;
162
 
163
    case 'd':
164
      *precisionP = D_PRECISION;
165
      *exponent_bitsP = 8;
166
      break;
167
 
168
    case 'g':
169
      *precisionP = G_PRECISION;
170
      *exponent_bitsP = 11;
171
      break;
172
 
173
    case 'h':
174
      *precisionP = H_PRECISION;
175
      *exponent_bitsP = 15;
176
      break;
177
 
178
    default:
179
      retval = 69;
180
      break;
181
    }
182
  return retval;
183
}
184
 
185
/* Warning: this returns 16-bit LITTLENUMs, because that is
186
   what the VAX thinks in. It is up to the caller to figure
187
   out any alignment problems and to conspire for the bytes/word
188
   to be emitted in the right order. Bigendians beware!  */
189
 
190
static char *
191
atof_vax (char *str,                    /* Text to convert to binary.  */
192
          int what_kind,                /* 'd', 'f', 'g', 'h'  */
193
          LITTLENUM_TYPE *words)        /* Build the binary here.  */
194
{
195
  FLONUM_TYPE f;
196
  LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
197
  /* Extra bits for zeroed low-order bits.
198
     The 1st MAX_PRECISION are zeroed,
199
     the last contain flonum bits.  */
200
  char *return_value;
201
  int precision;                /* Number of 16-bit words in the format.  */
202
  long exponent_bits;
203
 
204
  return_value = str;
205
  f.low = bits + MAX_PRECISION;
206
  f.high = NULL;
207
  f.leader = NULL;
208
  f.exponent = 0;
209
  f.sign = '\0';
210
 
211
  if (what_kind_of_float (what_kind, &precision, &exponent_bits))
212
    {
213
      return_value = NULL;
214
      make_invalid_floating_point_number (words);
215
    }
216
 
217
  if (return_value)
218
    {
219
      memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
220
 
221
      /* Use more LittleNums than seems
222
         necessary: the highest flonum may have
223
         15 leading 0 bits, so could be useless.  */
224
      f.high = f.low + precision - 1 + GUARD;
225
 
226
      if (atof_generic (&return_value, ".", "eE", &f))
227
        {
228
          make_invalid_floating_point_number (words);
229
          return_value = NULL;
230
        }
231
      else if (flonum_gen2vax (what_kind, &f, words))
232
        return_value = NULL;
233
    }
234
 
235
  return return_value;
236
}
237
 
238
/* In: a flonum, a vax floating point format.
239
   Out: a vax floating-point bit pattern.  */
240
 
241
int
242
flonum_gen2vax (int format_letter,      /* One of 'd' 'f' 'g' 'h'.  */
243
                FLONUM_TYPE *f,
244
                LITTLENUM_TYPE *words)  /* Deliver answer here.  */
245
{
246
  LITTLENUM_TYPE *lp;
247
  int precision;
248
  long exponent_bits;
249
  int return_value;             /* 0 == OK.  */
250
 
251
  return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
252
 
253
  if (return_value != 0)
254
    make_invalid_floating_point_number (words);
255
 
256
  else
257
    {
258
      if (f->low > f->leader)
259
        /* 0.0e0 seen.  */
260
        memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
261
 
262
      else
263
        {
264
          long exponent_1;
265
          long exponent_2;
266
          long exponent_3;
267
          long exponent_4;
268
          int exponent_skippage;
269
          LITTLENUM_TYPE word1;
270
 
271
          /* JF: Deal with new Nan, +Inf and -Inf codes.  */
272
          if (f->sign != '-' && f->sign != '+')
273
            {
274
              make_invalid_floating_point_number (words);
275
              return return_value;
276
            }
277
 
278
          /* All vaxen floating_point formats (so far) have:
279
             Bit 15 is sign bit.
280
             Bits 14:n are excess-whatever exponent.
281
             Bits n-1:0 (if any) are most significant bits of fraction.
282
             Bits 15:0 of the next word are the next most significant bits.
283
             And so on for each other word.
284
 
285
             All this to be compatible with a KF11?? (Which is still faster
286
             than lots of vaxen I can think of, but it also has higher
287
             maintenance costs ... sigh).
288
 
289
             So we need: number of bits of exponent, number of bits of
290
             mantissa.  */
291
 
292
          bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
293
          littlenum_pointer = f->leader;
294
          littlenum_end = f->low;
295
          /* Seek (and forget) 1st significant bit.  */
296
          for (exponent_skippage = 0;
297
               !next_bits (1);
298
               exponent_skippage++);;
299
 
300
          exponent_1 = f->exponent + f->leader + 1 - f->low;
301
          /* Radix LITTLENUM_RADIX, point just higher than f->leader.  */
302
          exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
303
          /* Radix 2.  */
304
          exponent_3 = exponent_2 - exponent_skippage;
305
          /* Forget leading zeros, forget 1st bit.  */
306
          exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
307
          /* Offset exponent.  */
308
 
309
          if (exponent_4 & ~mask[exponent_bits])
310
            {
311
              /* Exponent overflow. Lose immediately.  */
312
              make_invalid_floating_point_number (words);
313
 
314
              /* We leave return_value alone: admit we read the
315
                 number, but return a floating exception
316
                 because we can't encode the number.  */
317
            }
318
          else
319
            {
320
              lp = words;
321
 
322
              /* Word 1. Sign, exponent and perhaps high bits.
323
                 Assume 2's complement integers.  */
324
              word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits))
325
                       | ((f->sign == '+') ? 0 : 0x8000)
326
                       | next_bits (15 - exponent_bits));
327
              *lp++ = word1;
328
 
329
              /* The rest of the words are just mantissa bits.  */
330
              for (; lp < words + precision; lp++)
331
                *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
332
 
333
              if (next_bits (1))
334
                {
335
                  /* Since the NEXT bit is a 1, round UP the mantissa.
336
                     The cunning design of these hidden-1 floats permits
337
                     us to let the mantissa overflow into the exponent, and
338
                     it 'does the right thing'. However, we lose if the
339
                     highest-order bit of the lowest-order word flips.
340
                     Is that clear?  */
341
                  unsigned long carry;
342
 
343
                  /*
344
                    #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
345
                    Please allow at least 1 more bit in carry than is in a LITTLENUM.
346
                    We need that extra bit to hold a carry during a LITTLENUM carry
347
                    propagation. Another extra bit (kept 0) will assure us that we
348
                    don't get a sticky sign bit after shifting right, and that
349
                    permits us to propagate the carry without any masking of bits.
350
                    #endif   */
351
                  for (carry = 1, lp--;
352
                       carry && (lp >= words);
353
                       lp--)
354
                    {
355
                      carry = *lp + carry;
356
                      *lp = carry;
357
                      carry >>= LITTLENUM_NUMBER_OF_BITS;
358
                    }
359
 
360
                  if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
361
                    {
362
                      make_invalid_floating_point_number (words);
363
                      /* We leave return_value alone: admit we read the
364
                         number, but return a floating exception
365
                         because we can't encode the number.  */
366
                    }
367
                }
368
            }
369
        }
370
    }
371
  return return_value;
372
}
373
 
374
/* JF this used to be in vax.c but this looks like a better place for it.  */
375
 
376
/* In:  input_line_pointer->the 1st character of a floating-point
377
                number.
378
        1 letter denoting the type of statement that wants a
379
                binary floating point number returned.
380
        Address of where to build floating point literal.
381
                Assumed to be 'big enough'.
382
        Address of where to return size of literal (in chars).
383
 
384
   Out: Input_line_pointer->of next char after floating number.
385
        Error message, or 0.
386
        Floating point literal.
387
        Number of chars we used for the literal.  */
388
 
389
#define MAXIMUM_NUMBER_OF_LITTLENUMS  8         /* For .hfloats.  */
390
 
391
char *
392
vax_md_atof (int what_statement_type,
393
             char *literalP,
394
             int *sizeP)
395
{
396
  LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS];
397
  char kind_of_float;
398
  unsigned int number_of_chars;
399
  LITTLENUM_TYPE *littlenumP;
400
 
401
  switch (what_statement_type)
402
    {
403
    case 'F':
404
    case 'f':
405
      kind_of_float = 'f';
406
      break;
407
 
408
    case 'D':
409
    case 'd':
410
      kind_of_float = 'd';
411
      break;
412
 
413
    case 'g':
414
      kind_of_float = 'g';
415
      break;
416
 
417
    case 'h':
418
      kind_of_float = 'h';
419
      break;
420
 
421
    default:
422
      kind_of_float = 0;
423
      break;
424
    };
425
 
426
  if (kind_of_float)
427
    {
428
      LITTLENUM_TYPE *limit;
429
 
430
      input_line_pointer = atof_vax (input_line_pointer,
431
                                     kind_of_float,
432
                                     words);
433
      /* The atof_vax() builds up 16-bit numbers.
434
         Since the assembler may not be running on
435
         a little-endian machine, be very careful about
436
         converting words to chars.  */
437
      number_of_chars = atof_vax_sizeof (kind_of_float);
438
      know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE));
439
      limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE));
440
      for (littlenumP = words; littlenumP < limit; littlenumP++)
441
        {
442
          md_number_to_chars (literalP, *littlenumP, sizeof (LITTLENUM_TYPE));
443
          literalP += sizeof (LITTLENUM_TYPE);
444
        };
445
    }
446
  else
447
    number_of_chars = 0;
448
 
449
  *sizeP = number_of_chars;
450
  return kind_of_float ? NULL : _("Unrecognized or unsupported floating point constant");
451
}

powered by: WebSVN 2.1.0

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