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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [libgcc/] [config/] [libbid/] [bid128_next.c] - Blame information for rev 298

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

Line No. Rev Author Line
1 272 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
#define BID_128RES
25
#include "bid_internal.h"
26
 
27
/*****************************************************************************
28
 *  BID128 nextup
29
 ****************************************************************************/
30
 
31
#if DECIMAL_CALL_BY_REFERENCE
32
void
33
bid128_nextup (UINT128 * pres,
34
               UINT128 *
35
               px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
36
  UINT128 x = *px;
37
#else
38
UINT128
39
bid128_nextup (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
40
               _EXC_INFO_PARAM) {
41
#endif
42
 
43
  UINT128 res;
44
  UINT64 x_sign;
45
  UINT64 x_exp;
46
  int exp;
47
  BID_UI64DOUBLE tmp1;
48
  int x_nr_bits;
49
  int q1, ind;
50
  UINT128 C1;                   // C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
51
 
52
  BID_SWAP128 (x);
53
  // unpack the argument
54
  x_sign = x.w[1] & MASK_SIGN;  // 0 for positive, MASK_SIGN for negative
55
  C1.w[1] = x.w[1] & MASK_COEFF;
56
  C1.w[0] = x.w[0];
57
 
58
  // check for NaN or Infinity
59
  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
60
    // x is special
61
    if ((x.w[1] & MASK_NAN) == MASK_NAN) {      // x is NAN
62
      // if x = NaN, then res = Q (x)
63
      // check first for non-canonical NaN payload
64
      if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
65
          (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
66
           && (x.w[0] > 0x38c15b09ffffffffull))) {
67
        x.w[1] = x.w[1] & 0xffffc00000000000ull;
68
        x.w[0] = 0x0ull;
69
      }
70
      if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {  // x is SNAN
71
        // set invalid flag
72
        *pfpsf |= INVALID_EXCEPTION;
73
        // return quiet (x)
74
        res.w[1] = x.w[1] & 0xfc003fffffffffffull;      // clear out also G[6]-G[16]
75
        res.w[0] = x.w[0];
76
      } else {  // x is QNaN
77
        // return x
78
        res.w[1] = x.w[1] & 0xfc003fffffffffffull;      // clear out G[6]-G[16]
79
        res.w[0] = x.w[0];
80
      }
81
    } else {    // x is not NaN, so it must be infinity
82
      if (!x_sign) {    // x is +inf
83
        res.w[1] = 0x7800000000000000ull;       // +inf
84
        res.w[0] = 0x0000000000000000ull;
85
      } else {  // x is -inf
86
        res.w[1] = 0xdfffed09bead87c0ull;       // -MAXFP = -999...99 * 10^emax
87
        res.w[0] = 0x378d8e63ffffffffull;
88
      }
89
    }
90
    BID_RETURN (res);
91
  }
92
  // check for non-canonical values (treated as zero)
93
  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {      // G0_G1=11
94
    // non-canonical
95
    x_exp = (x.w[1] << 2) & MASK_EXP;   // biased and shifted left 49 bits
96
    C1.w[1] = 0; // significand high
97
    C1.w[0] = 0;  // significand low
98
  } else {      // G0_G1 != 11
99
    x_exp = x.w[1] & MASK_EXP;  // biased and shifted left 49 bits
100
    if (C1.w[1] > 0x0001ed09bead87c0ull ||
101
        (C1.w[1] == 0x0001ed09bead87c0ull
102
         && C1.w[0] > 0x378d8e63ffffffffull)) {
103
      // x is non-canonical if coefficient is larger than 10^34 -1
104
      C1.w[1] = 0;
105
      C1.w[0] = 0;
106
    } else {    // canonical
107
      ;
108
    }
109
  }
110
 
111
  if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
112
    // x is +/-0
113
    res.w[1] = 0x0000000000000000ull;   // +1 * 10^emin
114
    res.w[0] = 0x0000000000000001ull;
115
  } else {      // x is not special and is not zero
116
    if (x.w[1] == 0x5fffed09bead87c0ull
117
        && x.w[0] == 0x378d8e63ffffffffull) {
118
      // x = +MAXFP = 999...99 * 10^emax
119
      res.w[1] = 0x7800000000000000ull; // +inf
120
      res.w[0] = 0x0000000000000000ull;
121
    } else if (x.w[1] == 0x8000000000000000ull
122
               && x.w[0] == 0x0000000000000001ull) {
123
      // x = -MINFP = 1...99 * 10^emin
124
      res.w[1] = 0x8000000000000000ull; // -0
125
      res.w[0] = 0x0000000000000000ull;
126
    } else {    // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
127
      // can add/subtract 1 ulp to the significand
128
 
129
      // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
130
      // q1 = nr. of decimal digits in x
131
      // determine first the nr. of bits in x
132
      if (C1.w[1] == 0) {
133
        if (C1.w[0] >= 0x0020000000000000ull) {  // x >= 2^53
134
          // split the 64-bit value in two 32-bit halves to avoid rnd errors
135
          if (C1.w[0] >= 0x0000000100000000ull) {        // x >= 2^32
136
            tmp1.d = (double) (C1.w[0] >> 32);   // exact conversion
137
            x_nr_bits =
138
              33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
139
                    0x3ff);
140
          } else {      // x < 2^32
141
            tmp1.d = (double) (C1.w[0]); // exact conversion
142
            x_nr_bits =
143
              1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
144
                   0x3ff);
145
          }
146
        } else {        // if x < 2^53
147
          tmp1.d = (double) C1.w[0];     // exact conversion
148
          x_nr_bits =
149
            1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
150
        }
151
      } else {  // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
152
        tmp1.d = (double) C1.w[1];      // exact conversion
153
        x_nr_bits =
154
          65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
155
      }
156
      q1 = nr_digits[x_nr_bits - 1].digits;
157
      if (q1 == 0) {
158
        q1 = nr_digits[x_nr_bits - 1].digits1;
159
        if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
160
            || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
161
                && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
162
          q1++;
163
      }
164
      // if q1 < P34 then pad the significand with zeros
165
      if (q1 < P34) {
166
        exp = (x_exp >> 49) - 6176;
167
        if (exp + 6176 > P34 - q1) {
168
          ind = P34 - q1;       // 1 <= ind <= P34 - 1
169
          // pad with P34 - q1 zeros, until exponent = emin
170
          // C1 = C1 * 10^ind
171
          if (q1 <= 19) {       // 64-bit C1
172
            if (ind <= 19) {    // 64-bit 10^ind and 64-bit C1
173
              __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
174
            } else {    // 128-bit 10^ind and 64-bit C1
175
              __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
176
            }
177
          } else {      // C1 is (most likely) 128-bit
178
            if (ind <= 14) {    // 64-bit 10^ind and 128-bit C1 (most likely)
179
              __mul_128x64_to_128 (C1, ten2k64[ind], C1);
180
            } else if (ind <= 19) {     // 64-bit 10^ind and 64-bit C1 (q1 <= 19)
181
              __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
182
            } else {    // 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
183
              __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
184
            }
185
          }
186
          x_exp = x_exp - ((UINT64) ind << 49);
187
        } else {        // pad with zeros until the exponent reaches emin
188
          ind = exp + 6176;
189
          // C1 = C1 * 10^ind
190
          if (ind <= 19) {      // 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
191
            if (q1 <= 19) {     // 64-bit C1, 64-bit 10^ind 
192
              __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
193
            } else {    // 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
194
              __mul_128x64_to_128 (C1, ten2k64[ind], C1);
195
            }
196
          } else {      // if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
197
            // 64-bit C1, 128-bit 10^ind
198
            __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
199
          }
200
          x_exp = EXP_MIN;
201
        }
202
      }
203
      if (!x_sign) {    // x > 0
204
        // add 1 ulp (add 1 to the significand)
205
        C1.w[0]++;
206
        if (C1.w[0] == 0)
207
          C1.w[1]++;
208
        if (C1.w[1] == 0x0001ed09bead87c0ull && C1.w[0] == 0x378d8e6400000000ull) {      // if  C1 = 10^34
209
          C1.w[1] = 0x0000314dc6448d93ull;      // C1 = 10^33
210
          C1.w[0] = 0x38c15b0a00000000ull;
211
          x_exp = x_exp + EXP_P1;
212
        }
213
      } else {  // x < 0
214
        // subtract 1 ulp (subtract 1 from the significand)
215
        C1.w[0]--;
216
        if (C1.w[0] == 0xffffffffffffffffull)
217
          C1.w[1]--;
218
        if (x_exp != 0 && C1.w[1] == 0x0000314dc6448d93ull && C1.w[0] == 0x38c15b09ffffffffull) { // if  C1 = 10^33 - 1
219
          C1.w[1] = 0x0001ed09bead87c0ull;      // C1 = 10^34 - 1
220
          C1.w[0] = 0x378d8e63ffffffffull;
221
          x_exp = x_exp - EXP_P1;
222
        }
223
      }
224
      // assemble the result
225
      res.w[1] = x_sign | x_exp | C1.w[1];
226
      res.w[0] = C1.w[0];
227
    }   // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
228
  }     // end x is not special and is not zero
229
  BID_RETURN (res);
230
}
231
 
232
/*****************************************************************************
233
 *  BID128 nextdown
234
 ****************************************************************************/
235
 
236
#if DECIMAL_CALL_BY_REFERENCE
237
void
238
bid128_nextdown (UINT128 * pres,
239
                 UINT128 *
240
                 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
241
  UINT128 x = *px;
242
#else
243
UINT128
244
bid128_nextdown (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
245
                 _EXC_INFO_PARAM) {
246
#endif
247
 
248
  UINT128 res;
249
  UINT64 x_sign;
250
  UINT64 x_exp;
251
  int exp;
252
  BID_UI64DOUBLE tmp1;
253
  int x_nr_bits;
254
  int q1, ind;
255
  UINT128 C1;                   // C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
256
 
257
  BID_SWAP128 (x);
258
  // unpack the argument
259
  x_sign = x.w[1] & MASK_SIGN;  // 0 for positive, MASK_SIGN for negative
260
  C1.w[1] = x.w[1] & MASK_COEFF;
261
  C1.w[0] = x.w[0];
262
 
263
  // check for NaN or Infinity
264
  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
265
    // x is special
266
    if ((x.w[1] & MASK_NAN) == MASK_NAN) {      // x is NAN
267
      // if x = NaN, then res = Q (x)
268
      // check first for non-canonical NaN payload
269
      if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
270
          (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
271
           && (x.w[0] > 0x38c15b09ffffffffull))) {
272
        x.w[1] = x.w[1] & 0xffffc00000000000ull;
273
        x.w[0] = 0x0ull;
274
      }
275
      if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {  // x is SNAN
276
        // set invalid flag
277
        *pfpsf |= INVALID_EXCEPTION;
278
        // return quiet (x)
279
        res.w[1] = x.w[1] & 0xfc003fffffffffffull;      // clear out also G[6]-G[16]
280
        res.w[0] = x.w[0];
281
      } else {  // x is QNaN
282
        // return x
283
        res.w[1] = x.w[1] & 0xfc003fffffffffffull;      // clear out G[6]-G[16]
284
        res.w[0] = x.w[0];
285
      }
286
    } else {    // x is not NaN, so it must be infinity
287
      if (!x_sign) {    // x is +inf
288
        res.w[1] = 0x5fffed09bead87c0ull;       // +MAXFP = +999...99 * 10^emax
289
        res.w[0] = 0x378d8e63ffffffffull;
290
      } else {  // x is -inf
291
        res.w[1] = 0xf800000000000000ull;       // -inf
292
        res.w[0] = 0x0000000000000000ull;
293
      }
294
    }
295
    BID_RETURN (res);
296
  }
297
  // check for non-canonical values (treated as zero)
298
  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {      // G0_G1=11
299
    // non-canonical
300
    x_exp = (x.w[1] << 2) & MASK_EXP;   // biased and shifted left 49 bits
301
    C1.w[1] = 0; // significand high
302
    C1.w[0] = 0;  // significand low
303
  } else {      // G0_G1 != 11
304
    x_exp = x.w[1] & MASK_EXP;  // biased and shifted left 49 bits
305
    if (C1.w[1] > 0x0001ed09bead87c0ull ||
306
        (C1.w[1] == 0x0001ed09bead87c0ull
307
         && C1.w[0] > 0x378d8e63ffffffffull)) {
308
      // x is non-canonical if coefficient is larger than 10^34 -1
309
      C1.w[1] = 0;
310
      C1.w[0] = 0;
311
    } else {    // canonical
312
      ;
313
    }
314
  }
315
 
316
  if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
317
    // x is +/-0
318
    res.w[1] = 0x8000000000000000ull;   // -1 * 10^emin
319
    res.w[0] = 0x0000000000000001ull;
320
  } else {      // x is not special and is not zero
321
    if (x.w[1] == 0xdfffed09bead87c0ull
322
        && x.w[0] == 0x378d8e63ffffffffull) {
323
      // x = -MAXFP = -999...99 * 10^emax
324
      res.w[1] = 0xf800000000000000ull; // -inf
325
      res.w[0] = 0x0000000000000000ull;
326
    } else if (x.w[1] == 0x0ull && x.w[0] == 0x0000000000000001ull) {    // +MINFP
327
      res.w[1] = 0x0000000000000000ull; // +0
328
      res.w[0] = 0x0000000000000000ull;
329
    } else {    // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
330
      // can add/subtract 1 ulp to the significand
331
 
332
      // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
333
      // q1 = nr. of decimal digits in x
334
      // determine first the nr. of bits in x
335
      if (C1.w[1] == 0) {
336
        if (C1.w[0] >= 0x0020000000000000ull) {  // x >= 2^53
337
          // split the 64-bit value in two 32-bit halves to avoid rnd errors
338
          if (C1.w[0] >= 0x0000000100000000ull) {        // x >= 2^32
339
            tmp1.d = (double) (C1.w[0] >> 32);   // exact conversion
340
            x_nr_bits =
341
              33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
342
                    0x3ff);
343
          } else {      // x < 2^32
344
            tmp1.d = (double) (C1.w[0]); // exact conversion
345
            x_nr_bits =
346
              1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
347
                   0x3ff);
348
          }
349
        } else {        // if x < 2^53
350
          tmp1.d = (double) C1.w[0];     // exact conversion
351
          x_nr_bits =
352
            1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
353
        }
354
      } else {  // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
355
        tmp1.d = (double) C1.w[1];      // exact conversion
356
        x_nr_bits =
357
          65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
358
      }
359
      q1 = nr_digits[x_nr_bits - 1].digits;
360
      if (q1 == 0) {
361
        q1 = nr_digits[x_nr_bits - 1].digits1;
362
        if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
363
            || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
364
                && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
365
          q1++;
366
      }
367
      // if q1 < P then pad the significand with zeros
368
      if (q1 < P34) {
369
        exp = (x_exp >> 49) - 6176;
370
        if (exp + 6176 > P34 - q1) {
371
          ind = P34 - q1;       // 1 <= ind <= P34 - 1
372
          // pad with P34 - q1 zeros, until exponent = emin
373
          // C1 = C1 * 10^ind
374
          if (q1 <= 19) {       // 64-bit C1
375
            if (ind <= 19) {    // 64-bit 10^ind and 64-bit C1
376
              __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
377
            } else {    // 128-bit 10^ind and 64-bit C1
378
              __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
379
            }
380
          } else {      // C1 is (most likely) 128-bit
381
            if (ind <= 14) {    // 64-bit 10^ind and 128-bit C1 (most likely)
382
              __mul_128x64_to_128 (C1, ten2k64[ind], C1);
383
            } else if (ind <= 19) {     // 64-bit 10^ind and 64-bit C1 (q1 <= 19)
384
              __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
385
            } else {    // 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
386
              __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
387
            }
388
          }
389
          x_exp = x_exp - ((UINT64) ind << 49);
390
        } else {        // pad with zeros until the exponent reaches emin
391
          ind = exp + 6176;
392
          // C1 = C1 * 10^ind
393
          if (ind <= 19) {      // 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
394
            if (q1 <= 19) {     // 64-bit C1, 64-bit 10^ind 
395
              __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
396
            } else {    // 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
397
              __mul_128x64_to_128 (C1, ten2k64[ind], C1);
398
            }
399
          } else {      // if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
400
            // 64-bit C1, 128-bit 10^ind
401
            __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
402
          }
403
          x_exp = EXP_MIN;
404
        }
405
      }
406
      if (x_sign) {     // x < 0
407
        // add 1 ulp (add 1 to the significand)
408
        C1.w[0]++;
409
        if (C1.w[0] == 0)
410
          C1.w[1]++;
411
        if (C1.w[1] == 0x0001ed09bead87c0ull && C1.w[0] == 0x378d8e6400000000ull) {      // if  C1 = 10^34
412
          C1.w[1] = 0x0000314dc6448d93ull;      // C1 = 10^33
413
          C1.w[0] = 0x38c15b0a00000000ull;
414
          x_exp = x_exp + EXP_P1;
415
        }
416
      } else {  // x > 0
417
        // subtract 1 ulp (subtract 1 from the significand)
418
        C1.w[0]--;
419
        if (C1.w[0] == 0xffffffffffffffffull)
420
          C1.w[1]--;
421
        if (x_exp != 0 && C1.w[1] == 0x0000314dc6448d93ull && C1.w[0] == 0x38c15b09ffffffffull) { // if  C1 = 10^33 - 1
422
          C1.w[1] = 0x0001ed09bead87c0ull;      // C1 = 10^34 - 1
423
          C1.w[0] = 0x378d8e63ffffffffull;
424
          x_exp = x_exp - EXP_P1;
425
        }
426
      }
427
      // assemble the result
428
      res.w[1] = x_sign | x_exp | C1.w[1];
429
      res.w[0] = C1.w[0];
430
    }   // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
431
  }     // end x is not special and is not zero
432
  BID_RETURN (res);
433
}
434
 
435
/*****************************************************************************
436
 *  BID128 nextafter
437
 ****************************************************************************/
438
 
439
#if DECIMAL_CALL_BY_REFERENCE
440
void
441
bid128_nextafter (UINT128 * pres, UINT128 * px,
442
                  UINT128 *
443
                  py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
444
{
445
  UINT128 x = *px;
446
  UINT128 y = *py;
447
  UINT128 xnswp = *px;
448
  UINT128 ynswp = *py;
449
#else
450
UINT128
451
bid128_nextafter (UINT128 x,
452
                  UINT128 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
453
                  _EXC_INFO_PARAM) {
454
  UINT128 xnswp = x;
455
  UINT128 ynswp = y;
456
#endif
457
 
458
  UINT128 res;
459
  UINT128 tmp1, tmp2, tmp3;
460
  FPSC tmp_fpsf = 0;             // dummy fpsf for calls to comparison functions
461
  int res1, res2;
462
  UINT64 x_exp;
463
 
464
 
465
  BID_SWAP128 (x);
466
  BID_SWAP128 (y);
467
  // check for NaNs
468
  if (((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL)
469
      || ((y.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
470
    // x is special or y is special
471
    if ((x.w[1] & MASK_NAN) == MASK_NAN) {      // x is NAN
472
      // if x = NaN, then res = Q (x)
473
      // check first for non-canonical NaN payload
474
      if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
475
          (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
476
           && (x.w[0] > 0x38c15b09ffffffffull))) {
477
        x.w[1] = x.w[1] & 0xffffc00000000000ull;
478
        x.w[0] = 0x0ull;
479
      }
480
      if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {  // x is SNAN
481
        // set invalid flag
482
        *pfpsf |= INVALID_EXCEPTION;
483
        // return quiet (x)
484
        res.w[1] = x.w[1] & 0xfc003fffffffffffull;      // clear out also G[6]-G[16]
485
        res.w[0] = x.w[0];
486
      } else {  // x is QNaN
487
        // return x
488
        res.w[1] = x.w[1] & 0xfc003fffffffffffull;      // clear out G[6]-G[16]
489
        res.w[0] = x.w[0];
490
        if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {        // y is SNAN
491
          // set invalid flag
492
          *pfpsf |= INVALID_EXCEPTION;
493
        }
494
      }
495
      BID_RETURN (res)
496
    } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {       // y is NAN
497
      // if x = NaN, then res = Q (x)
498
      // check first for non-canonical NaN payload
499
      if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
500
          (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
501
           && (y.w[0] > 0x38c15b09ffffffffull))) {
502
        y.w[1] = y.w[1] & 0xffffc00000000000ull;
503
        y.w[0] = 0x0ull;
504
      }
505
      if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {  // y is SNAN
506
        // set invalid flag
507
        *pfpsf |= INVALID_EXCEPTION;
508
        // return quiet (x)
509
        res.w[1] = y.w[1] & 0xfc003fffffffffffull;      // clear out also G[6]-G[16]
510
        res.w[0] = y.w[0];
511
      } else {  // x is QNaN
512
        // return x
513
        res.w[1] = y.w[1] & 0xfc003fffffffffffull;      // clear out G[6]-G[16]
514
        res.w[0] = y.w[0];
515
      }
516
      BID_RETURN (res)
517
    } else {    // at least one is infinity
518
      if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {        // x = inf
519
        x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
520
        x.w[0] = 0x0ull;
521
      }
522
      if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {        // y = inf
523
        y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
524
        y.w[0] = 0x0ull;
525
      }
526
    }
527
  }
528
  // neither x nor y is NaN
529
 
530
  // if not infinity, check for non-canonical values x (treated as zero)
531
  if ((x.w[1] & MASK_ANY_INF) != MASK_INF) {    // x != inf
532
    if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {    // G0_G1=11
533
      // non-canonical
534
      x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
535
      x.w[1] = (x.w[1] & MASK_SIGN) | x_exp;
536
      x.w[0] = 0x0ull;
537
    } else {    // G0_G1 != 11
538
      x_exp = x.w[1] & MASK_EXP;        // biased and shifted left 49 bits
539
      if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
540
          ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
541
           && x.w[0] > 0x378d8e63ffffffffull)) {
542
        // x is non-canonical if coefficient is larger than 10^34 -1
543
        x.w[1] = (x.w[1] & MASK_SIGN) | x_exp;
544
        x.w[0] = 0x0ull;
545
      } else {  // canonical
546
        ;
547
      }
548
    }
549
  }
550
  // no need to check for non-canonical y
551
 
552
  // neither x nor y is NaN
553
  tmp_fpsf = *pfpsf;    // save fpsf
554
#if DECIMAL_CALL_BY_REFERENCE
555
  bid128_quiet_equal (&res1, &xnswp,
556
                      &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
557
                      _EXC_INFO_ARG);
558
  bid128_quiet_greater (&res2, &xnswp,
559
                        &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
560
                        _EXC_INFO_ARG);
561
#else
562
  res1 =
563
    bid128_quiet_equal (xnswp,
564
                        ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
565
                        _EXC_INFO_ARG);
566
  res2 =
567
    bid128_quiet_greater (xnswp,
568
                          ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
569
                          _EXC_INFO_ARG);
570
#endif
571
  *pfpsf = tmp_fpsf;    // restore fpsf
572
 
573
  if (res1) {   // x = y
574
    // return x with the sign of y
575
    res.w[1] =
576
      (x.w[1] & 0x7fffffffffffffffull) | (y.
577
                                          w[1] & 0x8000000000000000ull);
578
    res.w[0] = x.w[0];
579
  } else if (res2) {    // x > y
580
#if DECIMAL_CALL_BY_REFERENCE
581
    bid128_nextdown (&res,
582
                     &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
583
                     _EXC_INFO_ARG);
584
#else
585
    res =
586
      bid128_nextdown (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
587
                       _EXC_INFO_ARG);
588
#endif
589
    BID_SWAP128 (res);
590
  } else {      // x < y
591
#if DECIMAL_CALL_BY_REFERENCE
592
    bid128_nextup (&res,
593
                   &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
594
#else
595
    res =
596
      bid128_nextup (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
597
#endif
598
    BID_SWAP128 (res);
599
  }
600
  // if the operand x is finite but the result is infinite, signal 
601
  // overflow and inexact
602
  if (((x.w[1] & MASK_SPECIAL) != MASK_SPECIAL)
603
      && ((res.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
604
    // set the inexact flag
605
    *pfpsf |= INEXACT_EXCEPTION;
606
    // set the overflow flag
607
    *pfpsf |= OVERFLOW_EXCEPTION;
608
  }
609
  // if the result is in (-10^emin, 10^emin), and is different from the
610
  // operand x, signal underflow and inexact
611
  tmp1.w[HIGH_128W] = 0x0000314dc6448d93ull;
612
  tmp1.w[LOW_128W] = 0x38c15b0a00000000ull;     // +100...0[34] * 10^emin
613
  tmp2.w[HIGH_128W] = res.w[1] & 0x7fffffffffffffffull;
614
  tmp2.w[LOW_128W] = res.w[0];
615
  tmp3.w[HIGH_128W] = res.w[1];
616
  tmp3.w[LOW_128W] = res.w[0];
617
  tmp_fpsf = *pfpsf;    // save fpsf
618
#if DECIMAL_CALL_BY_REFERENCE
619
  bid128_quiet_greater (&res1, &tmp1,
620
                        &tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
621
                        _EXC_INFO_ARG);
622
  bid128_quiet_not_equal (&res2, &xnswp,
623
                          &tmp3 _EXC_FLAGS_ARG _EXC_MASKS_ARG
624
                          _EXC_INFO_ARG);
625
#else
626
  res1 =
627
    bid128_quiet_greater (tmp1,
628
                          tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
629
                          _EXC_INFO_ARG);
630
  res2 =
631
    bid128_quiet_not_equal (xnswp,
632
                            tmp3 _EXC_FLAGS_ARG _EXC_MASKS_ARG
633
                            _EXC_INFO_ARG);
634
#endif
635
  *pfpsf = tmp_fpsf;    // restore fpsf
636
  if (res1 && res2) {
637
    // set the inexact flag 
638
    *pfpsf |= INEXACT_EXCEPTION;
639
    // set the underflow flag 
640
    *pfpsf |= UNDERFLOW_EXCEPTION;
641
  }
642
  BID_RETURN (res);
643
}

powered by: WebSVN 2.1.0

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