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

Subversion Repositories openrisc

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

Go to most recent revision | 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
 *
28
 *    BID128 non-computational functions:
29
 *         - bid128_isSigned
30
 *         - bid128_isNormal
31
 *         - bid128_isSubnormal
32
 *         - bid128_isFinite
33
 *         - bid128_isZero
34
 *         - bid128_isInf
35
 *         - bid128_isSignaling
36
 *         - bid128_isCanonical
37
 *         - bid128_isNaN
38
 *         - bid128_copy
39
 *         - bid128_negate
40
 *         - bid128_abs
41
 *         - bid128_copySign
42
 *         - bid128_class
43
 *         - bid128_totalOrder
44
 *         - bid128_totalOrderMag
45
 *         - bid128_sameQuantum
46
 *         - bid128_radix
47
 ****************************************************************************/
48
 
49
#if DECIMAL_CALL_BY_REFERENCE
50
void
51
bid128_isSigned (int *pres,
52
                 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
53
  UINT128 x = *px;
54
#else
55
int
56
bid128_isSigned (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
57
#endif
58
  int res;
59
 
60
  res = ((x.w[HIGH_128W] & MASK_SIGN) == MASK_SIGN);
61
  BID_RETURN (res);
62
}
63
 
64
// return 1 iff x is not zero, nor NaN nor subnormal nor infinity
65
#if DECIMAL_CALL_BY_REFERENCE
66
void
67
bid128_isNormal (int *pres,
68
                 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
69
  UINT128 x = *px;
70
#else
71
int
72
bid128_isNormal (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
73
#endif
74
  int res;
75
  UINT64 x_exp, C1_hi, C1_lo;
76
  BID_UI64DOUBLE tmp1;
77
  int exp, q, x_nr_bits;
78
 
79
  BID_SWAP128 (x);
80
  // test for special values - infinity or NaN
81
  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
82
    // x is special
83
    res = 0;
84
    BID_RETURN (res);
85
  }
86
  // unpack x 
87
  x_exp = x.w[1] & MASK_EXP;    // biased and shifted left 49 bit positions
88
  C1_hi = x.w[1] & MASK_COEFF;
89
  C1_lo = x.w[0];
90
  // test for zero
91
  if (C1_hi == 0 && C1_lo == 0) {
92
    res = 0;
93
    BID_RETURN (res);
94
  }
95
  // test for non-canonical values of the argument x
96
  if ((((C1_hi > 0x0001ed09bead87c0ull)
97
        || ((C1_hi == 0x0001ed09bead87c0ull)
98
            && (C1_lo > 0x378d8e63ffffffffull)))
99
       && ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull))
100
      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
101
    res = 0;
102
    BID_RETURN (res);
103
  }
104
  // x is subnormal or normal
105
  // determine the number of digits q in the significand
106
  // q = nr. of decimal digits in x
107
  // determine first the nr. of bits in x
108
  if (C1_hi == 0) {
109
    if (C1_lo >= 0x0020000000000000ull) {       // x >= 2^53
110
      // split the 64-bit value in two 32-bit halves to avoid rounding errors
111
      if (C1_lo >= 0x0000000100000000ull) {     // x >= 2^32
112
        tmp1.d = (double) (C1_lo >> 32);        // exact conversion
113
        x_nr_bits =
114
          33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
115
      } else {  // x < 2^32
116
        tmp1.d = (double) (C1_lo);      // exact conversion
117
        x_nr_bits =
118
          1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
119
      }
120
    } else {    // if x < 2^53
121
      tmp1.d = (double) C1_lo;  // exact conversion
122
      x_nr_bits =
123
        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
124
    }
125
  } else {      // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi)
126
    tmp1.d = (double) C1_hi;    // exact conversion
127
    x_nr_bits =
128
      65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
129
  }
130
  q = nr_digits[x_nr_bits - 1].digits;
131
  if (q == 0) {
132
    q = nr_digits[x_nr_bits - 1].digits1;
133
    if (C1_hi > nr_digits[x_nr_bits - 1].threshold_hi ||
134
        (C1_hi == nr_digits[x_nr_bits - 1].threshold_hi &&
135
         C1_lo >= nr_digits[x_nr_bits - 1].threshold_lo))
136
      q++;
137
  }
138
  exp = (int) (x_exp >> 49) - 6176;
139
  // test for subnormal values of x
140
  if (exp + q <= -6143) {
141
    res = 0;
142
    BID_RETURN (res);
143
  } else {
144
    res = 1;
145
    BID_RETURN (res);
146
  }
147
}
148
 
149
// return 1 iff x is not zero, nor NaN nor normal nor infinity
150
#if DECIMAL_CALL_BY_REFERENCE
151
void
152
bid128_isSubnormal (int *pres,
153
                    UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
154
  UINT128 x = *px;
155
#else
156
int
157
bid128_isSubnormal (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
158
#endif
159
  int res;
160
  UINT64 x_exp, C1_hi, C1_lo;
161
  BID_UI64DOUBLE tmp1;
162
  int exp, q, x_nr_bits;
163
 
164
  BID_SWAP128 (x);
165
  // test for special values - infinity or NaN
166
  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
167
    // x is special
168
    res = 0;
169
    BID_RETURN (res);
170
  }
171
  // unpack x 
172
  x_exp = x.w[1] & MASK_EXP;    // biased and shifted left 49 bit positions
173
  C1_hi = x.w[1] & MASK_COEFF;
174
  C1_lo = x.w[0];
175
  // test for zero
176
  if (C1_hi == 0 && C1_lo == 0) {
177
    res = 0;
178
    BID_RETURN (res);
179
  }
180
  // test for non-canonical values of the argument x
181
  if ((((C1_hi > 0x0001ed09bead87c0ull)
182
        || ((C1_hi == 0x0001ed09bead87c0ull)
183
            && (C1_lo > 0x378d8e63ffffffffull)))
184
       && ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull))
185
      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
186
    res = 0;
187
    BID_RETURN (res);
188
  }
189
  // x is subnormal or normal
190
  // determine the number of digits q in the significand
191
  // q = nr. of decimal digits in x
192
  // determine first the nr. of bits in x
193
  if (C1_hi == 0) {
194
    if (C1_lo >= 0x0020000000000000ull) {       // x >= 2^53
195
      // split the 64-bit value in two 32-bit halves to avoid rounding errors
196
      if (C1_lo >= 0x0000000100000000ull) {     // x >= 2^32
197
        tmp1.d = (double) (C1_lo >> 32);        // exact conversion
198
        x_nr_bits =
199
          33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
200
      } else {  // x < 2^32
201
        tmp1.d = (double) (C1_lo);      // exact conversion
202
        x_nr_bits =
203
          1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
204
      }
205
    } else {    // if x < 2^53
206
      tmp1.d = (double) C1_lo;  // exact conversion
207
      x_nr_bits =
208
        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
209
    }
210
  } else {      // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi)
211
    tmp1.d = (double) C1_hi;    // exact conversion
212
    x_nr_bits =
213
      65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
214
  }
215
  q = nr_digits[x_nr_bits - 1].digits;
216
  if (q == 0) {
217
    q = nr_digits[x_nr_bits - 1].digits1;
218
    if (C1_hi > nr_digits[x_nr_bits - 1].threshold_hi ||
219
        (C1_hi == nr_digits[x_nr_bits - 1].threshold_hi &&
220
         C1_lo >= nr_digits[x_nr_bits - 1].threshold_lo))
221
      q++;
222
  }
223
  exp = (int) (x_exp >> 49) - 6176;
224
  // test for subnormal values of x
225
  if (exp + q <= -6143) {
226
    res = 1;
227
  } else {
228
    res = 0;
229
  }
230
  BID_RETURN (res);
231
}
232
 
233
#if DECIMAL_CALL_BY_REFERENCE
234
void
235
bid128_isFinite (int *pres,
236
                 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
237
  UINT128 x = *px;
238
#else
239
int
240
bid128_isFinite (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
241
#endif
242
  int res;
243
  res = ((x.w[HIGH_128W] & MASK_INF) != MASK_INF);
244
  BID_RETURN (res);
245
}
246
 
247
#if DECIMAL_CALL_BY_REFERENCE
248
void
249
bid128_isZero (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
250
  UINT128 x = *px;
251
#else
252
int
253
bid128_isZero (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
254
#endif
255
  int res;
256
  UINT128 sig_x;
257
 
258
  BID_SWAP128 (x);
259
  if ((x.w[1] & MASK_INF) == MASK_INF) {
260
    res = 0;
261
    BID_RETURN (res);
262
  }
263
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
264
  sig_x.w[0] = x.w[0];
265
  if ((sig_x.w[1] > 0x0001ed09bead87c0ull) ||   // significand is non-canonical
266
      ((sig_x.w[1] == 0x0001ed09bead87c0ull) && (sig_x.w[0] > 0x378d8e63ffffffffull)) || // significand is non-canonical
267
      ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull && (x.w[1] & MASK_INF) != MASK_INF) || // significand is non-canonical
268
      (sig_x.w[1] == 0 && sig_x.w[0] == 0)) {      // significand is 0
269
    res = 1;
270
    BID_RETURN (res);
271
  }
272
  res = 0;
273
  BID_RETURN (res);
274
}
275
 
276
#if DECIMAL_CALL_BY_REFERENCE
277
void
278
bid128_isInf (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
279
  UINT128 x = *px;
280
#else
281
int
282
bid128_isInf (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
283
#endif
284
  int res;
285
  res = ((x.w[HIGH_128W] & MASK_INF) == MASK_INF)
286
    && ((x.w[HIGH_128W] & MASK_NAN) != MASK_NAN);
287
  BID_RETURN (res);
288
}
289
 
290
#if DECIMAL_CALL_BY_REFERENCE
291
void
292
bid128_isSignaling (int *pres,
293
                    UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
294
  UINT128 x = *px;
295
#else
296
int
297
bid128_isSignaling (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
298
#endif
299
  int res;
300
 
301
  res = ((x.w[HIGH_128W] & MASK_SNAN) == MASK_SNAN);
302
  BID_RETURN (res);
303
}
304
 
305
// return 1 iff x is a canonical number ,infinity, or NaN.
306
#if DECIMAL_CALL_BY_REFERENCE
307
void
308
bid128_isCanonical (int *pres,
309
                    UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
310
  UINT128 x = *px;
311
#else
312
int
313
bid128_isCanonical (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
314
#endif
315
  int res;
316
  UINT128 sig_x;
317
 
318
  BID_SWAP128 (x);
319
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // NaN
320
    if (x.w[1] & 0x01ffc00000000000ull) {
321
      res = 0;
322
      BID_RETURN (res);
323
    }
324
    sig_x.w[1] = x.w[1] & 0x00003fffffffffffull;        // 46 bits
325
    sig_x.w[0] = x.w[0];  // 64 bits
326
    // payload must be < 10^33 = 0x0000314dc6448d93_38c15b0a00000000
327
    if (sig_x.w[1] < 0x0000314dc6448d93ull
328
        || (sig_x.w[1] == 0x0000314dc6448d93ull
329
            && sig_x.w[0] < 0x38c15b0a00000000ull)) {
330
      res = 1;
331
    } else {
332
      res = 0;
333
    }
334
    BID_RETURN (res);
335
  } else if ((x.w[1] & MASK_INF) == MASK_INF) { // infinity
336
    if ((x.w[1] & 0x03ffffffffffffffull) || x.w[0]) {
337
      res = 0;
338
    } else {
339
      res = 1;
340
    }
341
    BID_RETURN (res);
342
  }
343
  // not NaN or infinity; extract significand to ensure it is canonical
344
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
345
  sig_x.w[0] = x.w[0];
346
  // a canonical number has a coefficient < 10^34 
347
  //    (0x0001ed09_bead87c0_378d8e64_00000000)
348
  if ((sig_x.w[1] > 0x0001ed09bead87c0ull) ||   // significand is non-canonical
349
      ((sig_x.w[1] == 0x0001ed09bead87c0ull) && (sig_x.w[0] > 0x378d8e63ffffffffull)) || // significand is non-canonical
350
      ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
351
    res = 0;
352
  } else {
353
    res = 1;
354
  }
355
  BID_RETURN (res);
356
}
357
 
358
#if DECIMAL_CALL_BY_REFERENCE
359
void
360
bid128_isNaN (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
361
  UINT128 x = *px;
362
#else
363
int
364
bid128_isNaN (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
365
#endif
366
  int res;
367
 
368
  res = ((x.w[HIGH_128W] & MASK_NAN) == MASK_NAN);
369
  BID_RETURN (res);
370
}
371
 
372
// copies a floating-point operand x to destination y, with no change
373
#if DECIMAL_CALL_BY_REFERENCE
374
void
375
bid128_copy (UINT128 * pres,
376
             UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
377
  UINT128 x = *px;
378
#else
379
UINT128
380
bid128_copy (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
381
#endif
382
  UINT128 res;
383
 
384
  res = x;
385
  BID_RETURN (res);
386
}
387
 
388
// copies a floating-point operand x to destination y, reversing the sign
389
#if DECIMAL_CALL_BY_REFERENCE
390
void
391
bid128_negate (UINT128 * pres,
392
               UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
393
  UINT128 x = *px;
394
#else
395
UINT128
396
bid128_negate (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
397
#endif
398
  UINT128 res;
399
 
400
  x.w[HIGH_128W] ^= MASK_SIGN;
401
  res = x;
402
  BID_RETURN (res);
403
}
404
 
405
// copies a floating-point operand x to destination y, changing the sign to positive
406
#if DECIMAL_CALL_BY_REFERENCE
407
void
408
bid128_abs (UINT128 * pres,
409
            UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
410
  UINT128 x = *px;
411
#else
412
UINT128
413
bid128_abs (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
414
#endif
415
  UINT128 res;
416
 
417
  x.w[HIGH_128W] &= ~MASK_SIGN;
418
  res = x;
419
  BID_RETURN (res);
420
}
421
 
422
// copies operand x to destination in the same format as x, but with the sign of y
423
#if DECIMAL_CALL_BY_REFERENCE
424
void
425
bid128_copySign (UINT128 * pres, UINT128 * px,
426
                 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
427
  UINT128 x = *px;
428
  UINT128 y = *py;
429
#else
430
UINT128
431
bid128_copySign (UINT128 x, UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
432
#endif
433
  UINT128 res;
434
 
435
  x.w[HIGH_128W] =
436
    (x.w[HIGH_128W] & ~MASK_SIGN) | (y.w[HIGH_128W] & MASK_SIGN);
437
  res = x;
438
  BID_RETURN (res);
439
}
440
 
441
#if DECIMAL_CALL_BY_REFERENCE
442
void
443
bid128_class (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
444
  UINT128 x = *px;
445
#else
446
int
447
bid128_class (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
448
#endif
449
  int res;
450
  UINT256 sig_x_prime256;
451
  UINT192 sig_x_prime192;
452
  UINT128 sig_x;
453
  int exp_x;
454
 
455
  BID_SWAP128 (x);
456
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {
457
    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {
458
      res = signalingNaN;
459
    } else {
460
      res = quietNaN;
461
    }
462
    BID_RETURN (res);
463
  }
464
  if ((x.w[1] & MASK_INF) == MASK_INF) {
465
    if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
466
      res = negativeInfinity;
467
    } else {
468
      res = positiveInfinity;
469
    }
470
    BID_RETURN (res);
471
  }
472
  // decode number into exponent and significand
473
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
474
  sig_x.w[0] = x.w[0];
475
  // check for zero or non-canonical
476
  if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
477
      || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
478
          && (sig_x.w[0] > 0x378d8e63ffffffffull))
479
      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)
480
      || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
481
    if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
482
      res = negativeZero;
483
    } else {
484
      res = positiveZero;
485
    }
486
    BID_RETURN (res);
487
  }
488
  exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
489
  // if exponent is less than -6176, the number may be subnormal 
490
  // (less than the smallest normal value)
491
  //  the smallest normal value is 1 x 10^-6143 = 10^33 x 10^-6176
492
  //  if (exp_x - 6176 < -6143)
493
  if (exp_x < 33) {     // sig_x * 10^exp_x
494
    if (exp_x > 19) {
495
      __mul_128x128_to_256 (sig_x_prime256, sig_x,
496
                            ten2k128[exp_x - 20]);
497
      // 10^33 = 0x0000314dc6448d93_38c15b0a00000000
498
      if ((sig_x_prime256.w[3] == 0) && (sig_x_prime256.w[2] == 0)
499
          && ((sig_x_prime256.w[1] < 0x0000314dc6448d93ull)
500
              || ((sig_x_prime256.w[1] == 0x0000314dc6448d93ull)
501
                  && (sig_x_prime256.w[0] < 0x38c15b0a00000000ull)))) {
502
        res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? negativeSubnormal :
503
          positiveSubnormal;
504
        BID_RETURN (res);
505
      }
506
    } else {
507
      __mul_64x128_to_192 (sig_x_prime192, ten2k64[exp_x], sig_x);
508
      // 10^33 = 0x0000314dc6448d93_38c15b0a00000000
509
      if ((sig_x_prime192.w[2] == 0)
510
          && ((sig_x_prime192.w[1] < 0x0000314dc6448d93ull)
511
              || ((sig_x_prime192.w[1] == 0x0000314dc6448d93ull)
512
                  && (sig_x_prime192.w[0] < 0x38c15b0a00000000ull)))) {
513
        res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? negativeSubnormal :
514
          positiveSubnormal;
515
        BID_RETURN (res);
516
      }
517
    }
518
  }
519
  // otherwise, normal number, determine the sign
520
  res =
521
    ((x.w[1] & MASK_SIGN) ==
522
     MASK_SIGN) ? negativeNormal : positiveNormal;
523
  BID_RETURN (res);
524
}
525
 
526
// true if the exponents of x and y are the same, false otherwise.
527
// The special cases of sameQuantum(NaN, NaN) and sameQuantum(Inf, Inf) are true
528
// If exactly one operand is infinite or exactly one operand is NaN, then false
529
#if DECIMAL_CALL_BY_REFERENCE
530
void
531
bid128_sameQuantum (int *pres, UINT128 * px,
532
                    UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
533
  UINT128 x = *px;
534
  UINT128 y = *py;
535
#else
536
int
537
bid128_sameQuantum (UINT128 x,
538
                    UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
539
#endif
540
  int res;
541
  UINT64 x_exp, y_exp;
542
 
543
  BID_SWAP128 (x);
544
  BID_SWAP128 (y);
545
  // if both operands are NaN, return true
546
  if ((x.w[1] & MASK_NAN) == MASK_NAN
547
      || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
548
    res = ((x.w[1] & MASK_NAN) == MASK_NAN
549
           && (y.w[1] & MASK_NAN) == MASK_NAN);
550
    BID_RETURN (res);
551
  }
552
  // if both operands are INF, return true
553
  if ((x.w[1] & MASK_INF) == MASK_INF
554
      || (y.w[1] & MASK_INF) == MASK_INF) {
555
    res = ((x.w[1] & MASK_INF) == MASK_INF)
556
      && ((y.w[1] & MASK_INF) == MASK_INF);
557
    BID_RETURN (res);
558
  }
559
  // decode exponents for both numbers, and return true if they match
560
  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {      // G0_G1=11
561
    x_exp = (x.w[1] << 2) & MASK_EXP;   // biased and shifted left 49 bits
562
  } else {      // G0_G1 != 11
563
    x_exp = x.w[1] & MASK_EXP;  // biased and shifted left 49 bits
564
  }
565
  if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {      // G0_G1=11
566
    y_exp = (y.w[1] << 2) & MASK_EXP;   // biased and shifted left 49 bits
567
  } else {      // G0_G1 != 11
568
    y_exp = y.w[1] & MASK_EXP;  // biased and shifted left 49 bits
569
  }
570
  res = (x_exp == y_exp);
571
  BID_RETURN (res);
572
}
573
 
574
#if DECIMAL_CALL_BY_REFERENCE
575
void
576
bid128_totalOrder (int *pres, UINT128 * px,
577
                   UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
578
  UINT128 x = *px;
579
  UINT128 y = *py;
580
#else
581
int
582
bid128_totalOrder (UINT128 x,
583
                   UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
584
#endif
585
  int res;
586
  int exp_x, exp_y;
587
  UINT128 sig_x, sig_y, pyld_y, pyld_x;
588
  UINT192 sig_n_prime192;
589
  UINT256 sig_n_prime256;
590
  char x_is_zero = 0, y_is_zero = 0;
591
 
592
  BID_SWAP128 (x);
593
  BID_SWAP128 (y);
594
  // NaN (CASE 1)
595
  // if x and y are unordered numerically because either operand is NaN
596
  //    (1) totalOrder(-NaN, number) is true
597
  //    (2) totalOrder(number, +NaN) is true
598
  //    (3) if x and y are both NaN:
599
  //       i) negative sign bit < positive sign bit
600
  //       ii) signaling < quiet for +NaN, reverse for -NaN
601
  //       iii) lesser payload < greater payload for +NaN (reverse for -NaN)
602
  //       iv) else if bitwise identical (in canonical form), return 1
603
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {
604
    // if x is -NaN
605
    if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
606
      // return true, unless y is -NaN also
607
      if ((y.w[1] & MASK_NAN) != MASK_NAN
608
          || (y.w[1] & MASK_SIGN) != MASK_SIGN) {
609
        res = 1;        // y is a number, return 1
610
        BID_RETURN (res);
611
      } else {  // if y and x are both -NaN
612
        pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
613
        pyld_x.w[0] = x.w[0];
614
        pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
615
        pyld_y.w[0] = y.w[0];
616
        if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
617
            || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
618
                && (pyld_x.w[0] > 0x38c15b09ffffffffull))) {
619
          pyld_x.w[1] = 0;
620
          pyld_x.w[0] = 0;
621
        }
622
        if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
623
            || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
624
                && (pyld_y.w[0] > 0x38c15b09ffffffffull))) {
625
          pyld_y.w[1] = 0;
626
          pyld_y.w[0] = 0;
627
        }
628
        // if x and y are both -SNaN or both -QNaN, we have to compare payloads
629
        // this statement evaluates to true if both are SNaN or QNaN
630
        if (!
631
            (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^
632
             ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
633
          // it comes down to the payload.  we want to return true if x has a
634
          // larger payload, or if the payloads are equal (canonical forms
635
          // are bitwise identical)
636
          if ((pyld_x.w[1] > pyld_y.w[1]) ||
637
              ((pyld_x.w[1] == pyld_y.w[1])
638
               && (pyld_x.w[0] >= pyld_y.w[0])))
639
            res = 1;
640
          else
641
            res = 0;
642
          BID_RETURN (res);
643
        } else {
644
          // either x = -SNaN and y = -QNaN or x = -QNaN and y = -SNaN
645
          res = ((y.w[1] & MASK_SNAN) == MASK_SNAN);
646
          // totalOrder (-QNaN, -SNaN) == 1
647
          BID_RETURN (res);
648
        }
649
      }
650
    } else {    // x is +NaN
651
      // return false, unless y is +NaN also
652
      if ((y.w[1] & MASK_NAN) != MASK_NAN
653
          || (y.w[1] & MASK_SIGN) == MASK_SIGN) {
654
        res = 0; // y is a number, return 1
655
        BID_RETURN (res);
656
      } else {
657
        // x and y are both +NaN; 
658
        pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
659
        pyld_x.w[0] = x.w[0];
660
        pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
661
        pyld_y.w[0] = y.w[0];
662
        if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
663
            || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
664
                && (pyld_x.w[0] > 0x38c15b09ffffffffull))) {
665
          pyld_x.w[1] = 0;
666
          pyld_x.w[0] = 0;
667
        }
668
        if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
669
            || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
670
                && (pyld_y.w[0] > 0x38c15b09ffffffffull))) {
671
          pyld_y.w[1] = 0;
672
          pyld_y.w[0] = 0;
673
        }
674
        // if x and y are both +SNaN or both +QNaN, we have to compare payloads
675
        // this statement evaluates to true if both are SNaN or QNaN
676
        if (!
677
            (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^
678
             ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
679
          // it comes down to the payload.  we want to return true if x has a
680
          // smaller payload, or if the payloads are equal (canonical forms
681
          // are bitwise identical)
682
          if ((pyld_x.w[1] < pyld_y.w[1]) ||
683
              ((pyld_x.w[1] == pyld_y.w[1])
684
               && (pyld_x.w[0] <= pyld_y.w[0])))
685
            res = 1;
686
          else
687
            res = 0;
688
          BID_RETURN (res);
689
        } else {
690
          // either x = SNaN and y = QNaN or x = QNaN and y = SNaN
691
          res = ((x.w[1] & MASK_SNAN) == MASK_SNAN);
692
          // totalOrder (-QNaN, -SNaN) == 1
693
          BID_RETURN (res);
694
        }
695
      }
696
    }
697
  } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {
698
    // x is certainly not NAN in this case.
699
    // return true if y is positive
700
    res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
701
    BID_RETURN (res);
702
  }
703
  // SIMPLE (CASE 2)
704
  // if all the bits are the same, the numbers are equal.
705
  if ((x.w[1] == y.w[1]) && (x.w[0] == y.w[0])) {
706
    res = 1;
707
    BID_RETURN (res);
708
  }
709
  // OPPOSITE SIGNS (CASE 3)
710
  // if signs are opposite, return 1 if x is negative 
711
  // (if x < y, totalOrder is true)
712
  if (((x.w[1] & MASK_SIGN) == MASK_SIGN) ^ ((y.w[1] & MASK_SIGN) ==
713
                                             MASK_SIGN)) {
714
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
715
    BID_RETURN (res);
716
  }
717
  // INFINITY (CASE 4)
718
  if ((x.w[1] & MASK_INF) == MASK_INF) {
719
    // if x == neg_inf, return (y == neg_inf);
720
    if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
721
      res = 1;
722
      BID_RETURN (res);
723
    } else {
724
      // x is positive infinity, only return1 if y is positive infinity as well
725
      res = ((y.w[1] & MASK_INF) == MASK_INF);
726
      BID_RETURN (res);
727
      // && (y & MASK_SIGN) != MASK_SIGN); (we know y has same sign as x)
728
    }
729
  } else if ((y.w[1] & MASK_INF) == MASK_INF) {
730
    // x is finite, so:
731
    //    if y is +inf, x<y
732
    //    if y is -inf, x>y
733
    res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
734
    BID_RETURN (res);
735
  }
736
  // CONVERT x
737
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
738
  sig_x.w[0] = x.w[0];
739
  exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
740
 
741
  // CHECK IF x IS CANONICAL
742
  // 9999999999999999999999999999999999 (decimal) = 
743
  //     1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
744
  // [0, 10^34) is the 754r supported canonical range.  
745
  // If the value exceeds that, it is interpreted as 0.
746
  if ((((sig_x.w[1] > 0x0001ed09bead87c0ull) ||
747
        ((sig_x.w[1] == 0x0001ed09bead87c0ull) &&
748
         (sig_x.w[0] > 0x378d8e63ffffffffull))) &&
749
       ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
750
      ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
751
      ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
752
    x_is_zero = 1;
753
    // check for the case where the exponent is shifted right by 2 bits!
754
    if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
755
      exp_x = (x.w[1] >> 47) & 0x000000000003fffull;
756
    }
757
  }
758
  // CONVERT y
759
  exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
760
  sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
761
  sig_y.w[0] = y.w[0];
762
 
763
  // CHECK IF y IS CANONICAL
764
  // 9999999999999999999999999999999999(decimal) = 
765
  //     1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
766
  // [0, 10^34) is the 754r supported canonical range.  
767
  // If the value exceeds that, it is interpreted as 0.
768
  if ((((sig_y.w[1] > 0x0001ed09bead87c0ull) ||
769
        ((sig_y.w[1] == 0x0001ed09bead87c0ull) &&
770
         (sig_y.w[0] > 0x378d8e63ffffffffull))) &&
771
       ((y.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
772
      ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
773
      ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
774
    y_is_zero = 1;
775
    // check for the case where the exponent is shifted right by 2 bits!
776
    if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
777
      exp_y = (y.w[1] >> 47) & 0x000000000003fffull;
778
    }
779
  }
780
  // ZERO (CASE 5)
781
  // if x and y represent the same entities, and both are negative 
782
  // return true iff exp_x <= exp_y
783
  if (x_is_zero && y_is_zero) {
784
    // we know that signs must be the same because we would have caught it 
785
    // in case3 if signs were different
786
    // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
787
    // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
788
    if (exp_x == exp_y) {
789
      res = 1;
790
      BID_RETURN (res);
791
    }
792
    res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
793
    BID_RETURN (res);
794
  }
795
  // if x is zero and y isn't, clearly x has the smaller payload
796
  if (x_is_zero) {
797
    res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
798
    BID_RETURN (res);
799
  }
800
  // if y is zero, and x isn't, clearly y has the smaller payload
801
  if (y_is_zero) {
802
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
803
    BID_RETURN (res);
804
  }
805
  // REDUNDANT REPRESENTATIONS (CASE 6)
806
  // if both components are either bigger or smaller
807
  if (((sig_x.w[1] > sig_y.w[1])
808
       || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
809
      && exp_x >= exp_y) {
810
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
811
    BID_RETURN (res);
812
  }
813
  if (((sig_x.w[1] < sig_y.w[1])
814
       || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
815
      && exp_x <= exp_y) {
816
    res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
817
    BID_RETURN (res);
818
  }
819
  // if |exp_x - exp_y| < 33, it comes down to the compensated significand
820
  if (exp_x > exp_y) {
821
    // if exp_x is 33 greater than exp_y, it is definitely larger, 
822
    // so no need for compensation
823
    if (exp_x - exp_y > 33) {
824
      res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
825
      BID_RETURN (res);
826
      // difference cannot be greater than 10^33
827
    }
828
    // otherwise adjust the x significand upwards
829
    if (exp_x - exp_y > 19) {
830
      __mul_128x128_to_256 (sig_n_prime256, sig_x,
831
                            ten2k128[exp_x - exp_y - 20]);
832
      // the compensated significands are equal (ie "x and y represent the same
833
      // entities") return 1 if (negative && expx > expy) || 
834
      // (positive && expx < expy)
835
      if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
836
          && (sig_n_prime256.w[1] == sig_y.w[1])
837
          && (sig_n_prime256.w[0] == sig_y.w[0])) {
838
        // the case exp_x == exp_y  cannot occur, because all bits must be 
839
        // the same - would have been caught if (x == y)
840
        res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
841
        BID_RETURN (res);
842
      }
843
      // if positive, return 1 if adjusted x is smaller than y
844
      res = (((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
845
              && ((sig_n_prime256.w[1] < sig_y.w[1])
846
                  || (sig_n_prime256.w[1] == sig_y.w[1]
847
                      && sig_n_prime256.w[0] <
848
                      sig_y.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
849
                                       MASK_SIGN));
850
      BID_RETURN (res);
851
    }
852
    __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_x - exp_y], sig_x);
853
    // if positive, return whichever significand is larger 
854
    // (converse if negative)
855
    if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
856
        && (sig_n_prime192.w[0] == sig_y.w[0])) {
857
      res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
858
      BID_RETURN (res);
859
    }
860
    res = (((sig_n_prime192.w[2] == 0)
861
            && ((sig_n_prime192.w[1] < sig_y.w[1])
862
                || (sig_n_prime192.w[1] == sig_y.w[1]
863
                    && sig_n_prime192.w[0] <
864
                    sig_y.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
865
                                     MASK_SIGN));
866
    BID_RETURN (res);
867
  }
868
  // if exp_x is 33 less than exp_y, it is definitely smaller, 
869
  // no need for compensation
870
  if (exp_y - exp_x > 33) {
871
    res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
872
    BID_RETURN (res);
873
  }
874
  if (exp_y - exp_x > 19) {
875
    // adjust the y significand upwards
876
    __mul_128x128_to_256 (sig_n_prime256, sig_y,
877
                          ten2k128[exp_y - exp_x - 20]);
878
    // if x and y represent the same entities and both are negative
879
    // return true iff exp_x <= exp_y
880
    if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
881
        && (sig_n_prime256.w[1] == sig_x.w[1])
882
        && (sig_n_prime256.w[0] == sig_x.w[0])) {
883
      res = (exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN);
884
      BID_RETURN (res);
885
    }
886
    // values are not equal, for positive numbers return 1 if x is less than y
887
    // and 0 otherwise
888
    res = (((sig_n_prime256.w[3] != 0) ||
889
            // if upper128 bits of compensated y are non-zero, y is bigger
890
            (sig_n_prime256.w[2] != 0) ||
891
            // if upper128 bits of compensated y are non-zero, y is bigger
892
            (sig_n_prime256.w[1] > sig_x.w[1]) ||
893
            // if compensated y is bigger, y is bigger
894
            (sig_n_prime256.w[1] == sig_x.w[1]
895
             && sig_n_prime256.w[0] >
896
             sig_x.w[0])) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
897
    BID_RETURN (res);
898
  }
899
  __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y);
900
  if ((sig_n_prime192.w[2] == 0) && (sig_n_prime192.w[1] == sig_x.w[1])
901
      && (sig_n_prime192.w[0] == sig_x.w[0])) {
902
    res = (exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN);
903
    BID_RETURN (res);
904
  }
905
  res = (((sig_n_prime192.w[2] != 0) ||
906
          // if upper128 bits of compensated y are non-zero, y is bigger
907
          (sig_n_prime192.w[1] > sig_x.w[1]) ||
908
          // if compensated y is bigger, y is bigger
909
          (sig_n_prime192.w[1] == sig_x.w[1]
910
           && sig_n_prime192.w[0] >
911
           sig_x.w[0])) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
912
  BID_RETURN (res);
913
}
914
 
915
#if DECIMAL_CALL_BY_REFERENCE
916
void
917
bid128_totalOrderMag (int *pres, UINT128 * px,
918
                      UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
919
  UINT128 x = *px;
920
  UINT128 y = *py;
921
#else
922
int
923
bid128_totalOrderMag (UINT128 x,
924
                      UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
925
#endif
926
  int res;
927
  int exp_x, exp_y;
928
  UINT128 sig_x, sig_y, pyld_y, pyld_x;
929
  UINT192 sig_n_prime192;
930
  UINT256 sig_n_prime256;
931
  char x_is_zero = 0, y_is_zero = 0;
932
 
933
  BID_SWAP128 (x);
934
  BID_SWAP128 (y);
935
  x.w[1] = x.w[1] & 0x7fffffffffffffffull;
936
  y.w[1] = y.w[1] & 0x7fffffffffffffffull;
937
 
938
  // NaN (CASE 1)
939
  // if x and y are unordered numerically because either operand is NaN
940
  //    (1) totalOrder(number, +NaN) is true
941
  //    (2) if x and y are both NaN:
942
  //       i) signaling < quiet for +NaN
943
  //       ii) lesser payload < greater payload for +NaN
944
  //       iii) else if bitwise identical (in canonical form), return 1
945
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {
946
    // x is +NaN
947
    // return false, unless y is +NaN also
948
    if ((y.w[1] & MASK_NAN) != MASK_NAN) {
949
      res = 0;   // y is a number, return 0
950
      BID_RETURN (res);
951
    } else {
952
      // x and y are both +NaN; 
953
      pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
954
      pyld_x.w[0] = x.w[0];
955
      pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
956
      pyld_y.w[0] = y.w[0];
957
      if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
958
          || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
959
              && (pyld_x.w[0] > 0x38c15b09ffffffffull))) {
960
        pyld_x.w[1] = 0;
961
        pyld_x.w[0] = 0;
962
      }
963
      if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
964
          || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
965
              && (pyld_y.w[0] > 0x38c15b09ffffffffull))) {
966
        pyld_y.w[1] = 0;
967
        pyld_y.w[0] = 0;
968
      }
969
      // if x and y are both +SNaN or both +QNaN, we have to compare payloads
970
      // this statement evaluates to true if both are SNaN or QNaN
971
      if (!
972
          (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^
973
           ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
974
        // it comes down to the payload.  we want to return true if x has a
975
        // smaller payload, or if the payloads are equal (canonical forms
976
        // are bitwise identical)
977
        if ((pyld_x.w[1] < pyld_y.w[1]) ||
978
            ((pyld_x.w[1] == pyld_y.w[1])
979
             && (pyld_x.w[0] <= pyld_y.w[0]))) {
980
          res = 1;
981
        } else {
982
          res = 0;
983
        }
984
        BID_RETURN (res);
985
      } else {
986
        // either x = SNaN and y = QNaN or x = QNaN and y = SNaN
987
        res = ((x.w[1] & MASK_SNAN) == MASK_SNAN);
988
        // totalOrder (-QNaN, -SNaN) == 1
989
        BID_RETURN (res);
990
      }
991
    }
992
  } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {
993
    // x is certainly not NAN in this case.
994
    // return true because y is positive
995
    res = 1;
996
    BID_RETURN (res);
997
  }
998
  // SIMPLE (CASE 2)
999
  // if all the bits are the same, the numbers are equal.
1000
  if ((x.w[1] == y.w[1]) && (x.w[0] == y.w[0])) {
1001
    res = 1;
1002
    BID_RETURN (res);
1003
  }
1004
  // INFINITY (CASE 3)
1005
  if ((x.w[1] & MASK_INF) == MASK_INF) {
1006
    // x is positive infinity, only return 1 if y is positive infinity as well
1007
    res = ((y.w[1] & MASK_INF) == MASK_INF);
1008
    BID_RETURN (res);
1009
    // (we know y has same sign as x)
1010
  } else if ((y.w[1] & MASK_INF) == MASK_INF) {
1011
    // x is finite, so:
1012
    //    since y is +inf, x<y
1013
    res = 1;
1014
    BID_RETURN (res);
1015
  } else {
1016
    ;   // continue
1017
  }
1018
 
1019
  // CONVERT x
1020
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1021
  sig_x.w[0] = x.w[0];
1022
  exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1023
 
1024
  // CHECK IF x IS CANONICAL
1025
  // 9999999999999999999999999999999999 (decimal) = 
1026
  //     1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1027
  // [0, 10^34) is the 754r supported canonical range.  
1028
  // If the value exceeds that, it is interpreted as 0.
1029
  if ((((sig_x.w[1] > 0x0001ed09bead87c0ull) ||
1030
        ((sig_x.w[1] == 0x0001ed09bead87c0ull) &&
1031
         (sig_x.w[0] > 0x378d8e63ffffffffull))) &&
1032
       ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
1033
      ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
1034
      ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1035
    x_is_zero = 1;
1036
    // check for the case where the exponent is shifted right by 2 bits!
1037
    if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
1038
      exp_x = (x.w[1] >> 47) & 0x000000000003fffull;
1039
    }
1040
  }
1041
  // CONVERT y
1042
  exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1043
  sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1044
  sig_y.w[0] = y.w[0];
1045
 
1046
  // CHECK IF y IS CANONICAL
1047
  // 9999999999999999999999999999999999(decimal) = 
1048
  //     1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1049
  // [0, 10^34) is the 754r supported canonical range.  
1050
  // If the value exceeds that, it is interpreted as 0.
1051
  if ((((sig_y.w[1] > 0x0001ed09bead87c0ull) ||
1052
        ((sig_y.w[1] == 0x0001ed09bead87c0ull) &&
1053
         (sig_y.w[0] > 0x378d8e63ffffffffull))) &&
1054
       ((y.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
1055
      ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
1056
      ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1057
    y_is_zero = 1;
1058
    // check for the case where the exponent is shifted right by 2 bits!
1059
    if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
1060
      exp_y = (y.w[1] >> 47) & 0x000000000003fffull;
1061
    }
1062
  }
1063
  // ZERO (CASE 4)
1064
  if (x_is_zero && y_is_zero) {
1065
    // we know that signs must be the same because we would have caught it 
1066
    // in case3 if signs were different
1067
    // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
1068
    if (exp_x == exp_y) {
1069
      res = 1;
1070
      BID_RETURN (res);
1071
    }
1072
    res = (exp_x <= exp_y);
1073
    BID_RETURN (res);
1074
  }
1075
  // if x is zero and y isn't, clearly x has the smaller payload
1076
  if (x_is_zero) {
1077
    res = 1;
1078
    BID_RETURN (res);
1079
  }
1080
  // if y is zero, and x isn't, clearly y has the smaller payload
1081
  if (y_is_zero) {
1082
    res = 0;
1083
    BID_RETURN (res);
1084
  }
1085
  // REDUNDANT REPRESENTATIONS (CASE 5)
1086
  // if both components are either bigger or smaller
1087
  if (((sig_x.w[1] > sig_y.w[1])
1088
       || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1089
      && exp_x >= exp_y) {
1090
    res = 0;
1091
    BID_RETURN (res);
1092
  }
1093
  if (((sig_x.w[1] < sig_y.w[1])
1094
       || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1095
      && exp_x <= exp_y) {
1096
    res = 1;
1097
    BID_RETURN (res);
1098
  }
1099
  // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1100
  if (exp_x > exp_y) {
1101
    // if exp_x is 33 greater than exp_y, it is definitely larger, 
1102
    // so no need for compensation
1103
    if (exp_x - exp_y > 33) {
1104
      res = 0;   // difference cannot be greater than 10^33
1105
      BID_RETURN (res);
1106
    }
1107
    // otherwise adjust the x significand upwards
1108
    if (exp_x - exp_y > 19) {
1109
      __mul_128x128_to_256 (sig_n_prime256, sig_x,
1110
                            ten2k128[exp_x - exp_y - 20]);
1111
      // the compensated significands are equal (ie "x and y represent the same
1112
      // entities") return 1 if (negative && expx > expy) || 
1113
      // (positive && expx < expy)
1114
      if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
1115
          && (sig_n_prime256.w[1] == sig_y.w[1])
1116
          && (sig_n_prime256.w[0] == sig_y.w[0])) {
1117
        // the case (exp_x == exp_y) cannot occur, because all bits must be 
1118
        // the same - would have been caught if (x == y)
1119
        res = (exp_x <= exp_y);
1120
        BID_RETURN (res);
1121
      }
1122
      // since positive, return 1 if adjusted x is smaller than y
1123
      res = ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
1124
             && ((sig_n_prime256.w[1] < sig_y.w[1])
1125
                 || (sig_n_prime256.w[1] == sig_y.w[1]
1126
                     && sig_n_prime256.w[0] < sig_y.w[0])));
1127
      BID_RETURN (res);
1128
    }
1129
    __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_x - exp_y], sig_x);
1130
    // if positive, return whichever significand is larger 
1131
    // (converse if negative)
1132
    if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
1133
        && (sig_n_prime192.w[0] == sig_y.w[0])) {
1134
      res = (exp_x <= exp_y);
1135
      BID_RETURN (res);
1136
    }
1137
    res = ((sig_n_prime192.w[2] == 0)
1138
           && ((sig_n_prime192.w[1] < sig_y.w[1])
1139
               || (sig_n_prime192.w[1] == sig_y.w[1]
1140
                   && sig_n_prime192.w[0] < sig_y.w[0])));
1141
    BID_RETURN (res);
1142
  }
1143
  // if exp_x is 33 less than exp_y, it is definitely smaller, 
1144
  // no need for compensation
1145
  if (exp_y - exp_x > 33) {
1146
    res = 1;
1147
    BID_RETURN (res);
1148
  }
1149
  if (exp_y - exp_x > 19) {
1150
    // adjust the y significand upwards
1151
    __mul_128x128_to_256 (sig_n_prime256, sig_y,
1152
                          ten2k128[exp_y - exp_x - 20]);
1153
    if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
1154
        && (sig_n_prime256.w[1] == sig_x.w[1])
1155
        && (sig_n_prime256.w[0] == sig_x.w[0])) {
1156
      res = (exp_x <= exp_y);
1157
      BID_RETURN (res);
1158
    }
1159
    // values are not equal, for positive numbers return 1 if x is less than y
1160
    // and 0 otherwise
1161
    res = ((sig_n_prime256.w[3] != 0) ||
1162
           // if upper128 bits of compensated y are non-zero, y is bigger
1163
           (sig_n_prime256.w[2] != 0) ||
1164
           // if upper128 bits of compensated y are non-zero, y is bigger
1165
           (sig_n_prime256.w[1] > sig_x.w[1]) ||
1166
           // if compensated y is bigger, y is bigger
1167
           (sig_n_prime256.w[1] == sig_x.w[1]
1168
            && sig_n_prime256.w[0] > sig_x.w[0]));
1169
    BID_RETURN (res);
1170
  }
1171
  __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y);
1172
  if ((sig_n_prime192.w[2] == 0) && (sig_n_prime192.w[1] == sig_x.w[1])
1173
      && (sig_n_prime192.w[0] == sig_x.w[0])) {
1174
    res = (exp_x <= exp_y);
1175
    BID_RETURN (res);
1176
  }
1177
  res = ((sig_n_prime192.w[2] != 0) ||
1178
         // if upper128 bits of compensated y are non-zero, y is bigger
1179
         (sig_n_prime192.w[1] > sig_x.w[1]) ||
1180
         // if compensated y is bigger, y is bigger
1181
         (sig_n_prime192.w[1] == sig_x.w[1]
1182
          && sig_n_prime192.w[0] > sig_x.w[0]));
1183
  BID_RETURN (res);
1184
}
1185
 
1186
#if DECIMAL_CALL_BY_REFERENCE
1187
void
1188
bid128_radix (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1189
  UINT128 x = *px;
1190
#else
1191
int
1192
bid128_radix (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
1193
#endif
1194
  int res;
1195
  if (x.w[LOW_128W])    // dummy test
1196
    res = 10;
1197
  else
1198
    res = 10;
1199
  BID_RETURN (res);
1200
}

powered by: WebSVN 2.1.0

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