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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [libbid/] [bid64_next.c] - Blame information for rev 734

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* Copyright (C) 2007, 2009  Free Software Foundation, Inc.
2
 
3
This file is part of GCC.
4
 
5
GCC is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free
7
Software Foundation; either version 3, or (at your option) any later
8
version.
9
 
10
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11
WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
for more details.
14
 
15
Under Section 7 of GPL version 3, you are granted additional
16
permissions described in the GCC Runtime Library Exception, version
17
3.1, as published by the Free Software Foundation.
18
 
19
You should have received a copy of the GNU General Public License and
20
a copy of the GCC Runtime Library Exception along with this program;
21
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22
<http://www.gnu.org/licenses/>.  */
23
 
24
#include "bid_internal.h"
25
 
26
/*****************************************************************************
27
 *  BID64 nextup
28
 ****************************************************************************/
29
 
30
#if DECIMAL_CALL_BY_REFERENCE
31
void
32
bid64_nextup (UINT64 * pres,
33
              UINT64 *
34
              px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
35
  UINT64 x = *px;
36
#else
37
UINT64
38
bid64_nextup (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
39
              _EXC_INFO_PARAM) {
40
#endif
41
 
42
  UINT64 res;
43
  UINT64 x_sign;
44
  UINT64 x_exp;
45
  BID_UI64DOUBLE tmp1;
46
  int x_nr_bits;
47
  int q1, ind;
48
  UINT64 C1;                    // C1 represents x_signif (UINT64)
49
 
50
  // check for NaNs and infinities
51
  if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN
52
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
53
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
54
    else
55
      x = x & 0xfe03ffffffffffffull;    // clear G6-G12
56
    if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
57
      // set invalid flag
58
      *pfpsf |= INVALID_EXCEPTION;
59
      // return quiet (SNaN)
60
      res = x & 0xfdffffffffffffffull;
61
    } else {    // QNaN
62
      res = x;
63
    }
64
    BID_RETURN (res);
65
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
66
    if (!(x & 0x8000000000000000ull)) { // x is +inf
67
      res = 0x7800000000000000ull;
68
    } else {    // x is -inf
69
      res = 0xf7fb86f26fc0ffffull;      // -MAXFP = -999...99 * 10^emax
70
    }
71
    BID_RETURN (res);
72
  }
73
  // unpack the argument
74
  x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
75
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
76
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
77
    x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;  // biased
78
    C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
79
    if (C1 > 9999999999999999ull) {     // non-canonical
80
      x_exp = 0;
81
      C1 = 0;
82
    }
83
  } else {
84
    x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;  // biased
85
    C1 = x & MASK_BINARY_SIG1;
86
  }
87
 
88
  // check for zeros (possibly from non-canonical values)
89
  if (C1 == 0x0ull) {
90
    // x is 0
91
    res = 0x0000000000000001ull;        // MINFP = 1 * 10^emin
92
  } else {      // x is not special and is not zero
93
    if (x == 0x77fb86f26fc0ffffull) {
94
      // x = +MAXFP = 999...99 * 10^emax
95
      res = 0x7800000000000000ull;      // +inf
96
    } else if (x == 0x8000000000000001ull) {
97
      // x = -MINFP = 1...99 * 10^emin
98
      res = 0x8000000000000000ull;      // -0
99
    } else {    // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
100
      // can add/subtract 1 ulp to the significand
101
 
102
      // Note: we could check here if x >= 10^16 to speed up the case q1 =16 
103
      // q1 = nr. of decimal digits in x (1 <= q1 <= 54)
104
      //  determine first the nr. of bits in x
105
      if (C1 >= MASK_BINARY_OR2) {      // x >= 2^53
106
        // split the 64-bit value in two 32-bit halves to avoid rounding errors
107
        if (C1 >= 0x0000000100000000ull) {      // x >= 2^32
108
          tmp1.d = (double) (C1 >> 32); // exact conversion
109
          x_nr_bits =
110
            33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
111
        } else {        // x < 2^32
112
          tmp1.d = (double) C1; // exact conversion
113
          x_nr_bits =
114
            1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
115
        }
116
      } else {  // if x < 2^53
117
        tmp1.d = (double) C1;   // exact conversion
118
        x_nr_bits =
119
          1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
120
      }
121
      q1 = nr_digits[x_nr_bits - 1].digits;
122
      if (q1 == 0) {
123
        q1 = nr_digits[x_nr_bits - 1].digits1;
124
        if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
125
          q1++;
126
      }
127
      // if q1 < P16 then pad the significand with zeros
128
      if (q1 < P16) {
129
        if (x_exp > (UINT64) (P16 - q1)) {
130
          ind = P16 - q1;       // 1 <= ind <= P16 - 1
131
          // pad with P16 - q1 zeros, until exponent = emin
132
          // C1 = C1 * 10^ind
133
          C1 = C1 * ten2k64[ind];
134
          x_exp = x_exp - ind;
135
        } else {        // pad with zeros until the exponent reaches emin
136
          ind = x_exp;
137
          C1 = C1 * ten2k64[ind];
138
          x_exp = EXP_MIN;
139
        }
140
      }
141
      if (!x_sign) {    // x > 0
142
        // add 1 ulp (add 1 to the significand)
143
        C1++;
144
        if (C1 == 0x002386f26fc10000ull) {      // if  C1 = 10^16
145
          C1 = 0x00038d7ea4c68000ull;   // C1 = 10^15
146
          x_exp++;
147
        }
148
        // Ok, because MAXFP = 999...99 * 10^emax was caught already
149
      } else {  // x < 0
150
        // subtract 1 ulp (subtract 1 from the significand)
151
        C1--;
152
        if (C1 == 0x00038d7ea4c67fffull && x_exp != 0) { // if  C1 = 10^15 - 1
153
          C1 = 0x002386f26fc0ffffull;   // C1 = 10^16 - 1
154
          x_exp--;
155
        }
156
      }
157
      // assemble the result
158
      // if significand has 54 bits
159
      if (C1 & MASK_BINARY_OR2) {
160
        res =
161
          x_sign | (x_exp << 51) | MASK_STEERING_BITS | (C1 &
162
                                                         MASK_BINARY_SIG2);
163
      } else {  // significand fits in 53 bits
164
        res = x_sign | (x_exp << 53) | C1;
165
      }
166
    }   // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
167
  }     // end x is not special and is not zero
168
  BID_RETURN (res);
169
}
170
 
171
/*****************************************************************************
172
 *  BID64 nextdown
173
 ****************************************************************************/
174
 
175
#if DECIMAL_CALL_BY_REFERENCE
176
void
177
bid64_nextdown (UINT64 * pres,
178
                UINT64 *
179
                px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
180
  UINT64 x = *px;
181
#else
182
UINT64
183
bid64_nextdown (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
184
                _EXC_INFO_PARAM) {
185
#endif
186
 
187
  UINT64 res;
188
  UINT64 x_sign;
189
  UINT64 x_exp;
190
  BID_UI64DOUBLE tmp1;
191
  int x_nr_bits;
192
  int q1, ind;
193
  UINT64 C1;                    // C1 represents x_signif (UINT64)
194
 
195
  // check for NaNs and infinities
196
  if ((x & MASK_NAN) == MASK_NAN) {     // check for NaN 
197
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
198
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits 
199
    else
200
      x = x & 0xfe03ffffffffffffull;    // clear G6-G12 
201
    if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN 
202
      // set invalid flag
203
      *pfpsf |= INVALID_EXCEPTION;
204
      // return quiet (SNaN)
205
      res = x & 0xfdffffffffffffffull;
206
    } else {    // QNaN 
207
      res = x;
208
    }
209
    BID_RETURN (res);
210
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
211
    if (x & 0x8000000000000000ull) {    // x is -inf
212
      res = 0xf800000000000000ull;
213
    } else {    // x is +inf
214
      res = 0x77fb86f26fc0ffffull;      // +MAXFP = +999...99 * 10^emax
215
    }
216
    BID_RETURN (res);
217
  }
218
  // unpack the argument
219
  x_sign = x & MASK_SIGN;       // 0 for positive, MASK_SIGN for negative
220
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
221
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
222
    x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;  // biased
223
    C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
224
    if (C1 > 9999999999999999ull) {     // non-canonical
225
      x_exp = 0;
226
      C1 = 0;
227
    }
228
  } else {
229
    x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;  // biased
230
    C1 = x & MASK_BINARY_SIG1;
231
  }
232
 
233
  // check for zeros (possibly from non-canonical values)
234
  if (C1 == 0x0ull) {
235
    // x is 0
236
    res = 0x8000000000000001ull;        // -MINFP = -1 * 10^emin
237
  } else {      // x is not special and is not zero
238
    if (x == 0xf7fb86f26fc0ffffull) {
239
      // x = -MAXFP = -999...99 * 10^emax
240
      res = 0xf800000000000000ull;      // -inf
241
    } else if (x == 0x0000000000000001ull) {
242
      // x = +MINFP = 1...99 * 10^emin
243
      res = 0x0000000000000000ull;      // -0
244
    } else {    // -MAXFP + 1ulp <= x <= -MINFP OR MINFP + 1 ulp <= x <= MAXFP
245
      // can add/subtract 1 ulp to the significand
246
 
247
      // Note: we could check here if x >= 10^16 to speed up the case q1 =16 
248
      // q1 = nr. of decimal digits in x (1 <= q1 <= 16)
249
      //  determine first the nr. of bits in x
250
      if (C1 >= 0x0020000000000000ull) {        // x >= 2^53
251
        // split the 64-bit value in two 32-bit halves to avoid 
252
        // rounding errors
253
        if (C1 >= 0x0000000100000000ull) {      // x >= 2^32
254
          tmp1.d = (double) (C1 >> 32); // exact conversion
255
          x_nr_bits =
256
            33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
257
        } else {        // x < 2^32
258
          tmp1.d = (double) C1; // exact conversion
259
          x_nr_bits =
260
            1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
261
        }
262
      } else {  // if x < 2^53
263
        tmp1.d = (double) C1;   // exact conversion
264
        x_nr_bits =
265
          1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
266
      }
267
      q1 = nr_digits[x_nr_bits - 1].digits;
268
      if (q1 == 0) {
269
        q1 = nr_digits[x_nr_bits - 1].digits1;
270
        if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
271
          q1++;
272
      }
273
      // if q1 < P16 then pad the significand with zeros
274
      if (q1 < P16) {
275
        if (x_exp > (UINT64) (P16 - q1)) {
276
          ind = P16 - q1;       // 1 <= ind <= P16 - 1
277
          // pad with P16 - q1 zeros, until exponent = emin
278
          // C1 = C1 * 10^ind
279
          C1 = C1 * ten2k64[ind];
280
          x_exp = x_exp - ind;
281
        } else {        // pad with zeros until the exponent reaches emin
282
          ind = x_exp;
283
          C1 = C1 * ten2k64[ind];
284
          x_exp = EXP_MIN;
285
        }
286
      }
287
      if (x_sign) {     // x < 0
288
        // add 1 ulp (add 1 to the significand)
289
        C1++;
290
        if (C1 == 0x002386f26fc10000ull) {      // if  C1 = 10^16
291
          C1 = 0x00038d7ea4c68000ull;   // C1 = 10^15
292
          x_exp++;
293
          // Ok, because -MAXFP = -999...99 * 10^emax was caught already
294
        }
295
      } else {  // x > 0
296
        // subtract 1 ulp (subtract 1 from the significand)
297
        C1--;
298
        if (C1 == 0x00038d7ea4c67fffull && x_exp != 0) { // if  C1 = 10^15 - 1
299
          C1 = 0x002386f26fc0ffffull;   // C1 = 10^16 - 1
300
          x_exp--;
301
        }
302
      }
303
      // assemble the result
304
      // if significand has 54 bits
305
      if (C1 & MASK_BINARY_OR2) {
306
        res =
307
          x_sign | (x_exp << 51) | MASK_STEERING_BITS | (C1 &
308
                                                         MASK_BINARY_SIG2);
309
      } else {  // significand fits in 53 bits
310
        res = x_sign | (x_exp << 53) | C1;
311
      }
312
    }   // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
313
  }     // end x is not special and is not zero
314
  BID_RETURN (res);
315
}
316
 
317
/*****************************************************************************
318
 *  BID64 nextafter
319
 ****************************************************************************/
320
 
321
#if DECIMAL_CALL_BY_REFERENCE
322
void
323
bid64_nextafter (UINT64 * pres, UINT64 * px,
324
                 UINT64 *
325
                 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
326
  UINT64 x = *px;
327
  UINT64 y = *py;
328
#else
329
UINT64
330
bid64_nextafter (UINT64 x,
331
                 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
332
                 _EXC_INFO_PARAM) {
333
#endif
334
 
335
  UINT64 res;
336
  UINT64 tmp1, tmp2;
337
  FPSC tmp_fpsf = 0;             // dummy fpsf for calls to comparison functions
338
  int res1, res2;
339
 
340
  // check for NaNs or infinities
341
  if (((x & MASK_SPECIAL) == MASK_SPECIAL) ||
342
      ((y & MASK_SPECIAL) == MASK_SPECIAL)) {
343
    // x is NaN or infinity or y is NaN or infinity
344
 
345
    if ((x & MASK_NAN) == MASK_NAN) {   // x is NAN
346
      if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
347
        x = x & 0xfe00000000000000ull;  // clear G6-G12 and the payload bits
348
      else
349
        x = x & 0xfe03ffffffffffffull;  // clear G6-G12
350
      if ((x & MASK_SNAN) == MASK_SNAN) {       // x is SNAN
351
        // set invalid flag
352
        *pfpsf |= INVALID_EXCEPTION;
353
        // return quiet (x)
354
        res = x & 0xfdffffffffffffffull;
355
      } else {  // x is QNaN
356
        if ((y & MASK_SNAN) == MASK_SNAN) {     // y is SNAN
357
          // set invalid flag
358
          *pfpsf |= INVALID_EXCEPTION;
359
        }
360
        // return x
361
        res = x;
362
      }
363
      BID_RETURN (res);
364
    } else if ((y & MASK_NAN) == MASK_NAN) {    // y is NAN
365
      if ((y & 0x0003ffffffffffffull) > 999999999999999ull)
366
        y = y & 0xfe00000000000000ull;  // clear G6-G12 and the payload bits
367
      else
368
        y = y & 0xfe03ffffffffffffull;  // clear G6-G12
369
      if ((y & MASK_SNAN) == MASK_SNAN) {       // y is SNAN
370
        // set invalid flag
371
        *pfpsf |= INVALID_EXCEPTION;
372
        // return quiet (y)
373
        res = y & 0xfdffffffffffffffull;
374
      } else {  // y is QNaN
375
        // return y
376
        res = y;
377
      }
378
      BID_RETURN (res);
379
    } else {    // at least one is infinity
380
      if ((x & MASK_ANY_INF) == MASK_INF) {     // x = inf
381
        x = x & (MASK_SIGN | MASK_INF);
382
      }
383
      if ((y & MASK_ANY_INF) == MASK_INF) {     // y = inf
384
        y = y & (MASK_SIGN | MASK_INF);
385
      }
386
    }
387
  }
388
  // neither x nor y is NaN
389
 
390
  // if not infinity, check for non-canonical values x (treated as zero)
391
  if ((x & MASK_ANY_INF) != MASK_INF) { // x != inf
392
    // unpack x
393
    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
394
      // if the steering bits are 11 (condition will be 0), then
395
      // the exponent is G[0:w+1]
396
      if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
397
          9999999999999999ull) {
398
        // non-canonical
399
        x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
400
      }
401
    } else {    // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS) x is unch.
402
      ; // canonical
403
    }
404
  }
405
  // no need to check for non-canonical y
406
 
407
  // neither x nor y is NaN
408
  tmp_fpsf = *pfpsf;    // save fpsf
409
#if DECIMAL_CALL_BY_REFERENCE
410
  bid64_quiet_equal (&res1, px,
411
                     py _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
412
  bid64_quiet_greater (&res2, px,
413
                       py _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
414
#else
415
  res1 =
416
    bid64_quiet_equal (x,
417
                       y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
418
  res2 =
419
    bid64_quiet_greater (x,
420
                         y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
421
#endif
422
  *pfpsf = tmp_fpsf;    // restore fpsf
423
  if (res1) {   // x = y
424
    // return x with the sign of y
425
    res = (y & 0x8000000000000000ull) | (x & 0x7fffffffffffffffull);
426
  } else if (res2) {    // x > y
427
#if DECIMAL_CALL_BY_REFERENCE
428
    bid64_nextdown (&res,
429
                    px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
430
#else
431
    res =
432
      bid64_nextdown (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
433
#endif
434
  } else {      // x < y
435
#if DECIMAL_CALL_BY_REFERENCE
436
    bid64_nextup (&res, px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
437
#else
438
    res = bid64_nextup (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
439
#endif
440
  }
441
  // if the operand x is finite but the result is infinite, signal
442
  // overflow and inexact
443
  if (((x & MASK_INF) != MASK_INF) && ((res & MASK_INF) == MASK_INF)) {
444
    // set the inexact flag
445
    *pfpsf |= INEXACT_EXCEPTION;
446
    // set the overflow flag
447
    *pfpsf |= OVERFLOW_EXCEPTION;
448
  }
449
  // if the result is in (-10^emin, 10^emin), and is different from the
450
  // operand x, signal underflow and inexact 
451
  tmp1 = 0x00038d7ea4c68000ull; // +100...0[16] * 10^emin
452
  tmp2 = res & 0x7fffffffffffffffull;
453
  tmp_fpsf = *pfpsf;    // save fpsf
454
#if DECIMAL_CALL_BY_REFERENCE
455
  bid64_quiet_greater (&res1, &tmp1,
456
                       &tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
457
                       _EXC_INFO_ARG);
458
  bid64_quiet_not_equal (&res2, &x,
459
                         &res _EXC_FLAGS_ARG _EXC_MASKS_ARG
460
                         _EXC_INFO_ARG);
461
#else
462
  res1 =
463
    bid64_quiet_greater (tmp1,
464
                         tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
465
                         _EXC_INFO_ARG);
466
  res2 =
467
    bid64_quiet_not_equal (x,
468
                           res _EXC_FLAGS_ARG _EXC_MASKS_ARG
469
                           _EXC_INFO_ARG);
470
#endif
471
  *pfpsf = tmp_fpsf;    // restore fpsf
472
  if (res1 && res2) {
473
    // if (bid64_quiet_greater (tmp1, tmp2, &tmp_fpsf) &&
474
    // bid64_quiet_not_equal (x, res, &tmp_fpsf)) {
475
    // set the inexact flag
476
    *pfpsf |= INEXACT_EXCEPTION;
477
    // set the underflow flag
478
    *pfpsf |= UNDERFLOW_EXCEPTION;
479
  }
480
  BID_RETURN (res);
481
}

powered by: WebSVN 2.1.0

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