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_minmax.c] - Blame information for rev 407

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 minimum number
29
 *****************************************************************************/
30
 
31
#if DECIMAL_CALL_BY_REFERENCE
32
void
33
bid128_minnum (UINT128 * pres, UINT128 * px,
34
               UINT128 * py _EXC_FLAGS_PARAM) {
35
  UINT128 x = *px;
36
  UINT128 y = *py;
37
#else
38
UINT128
39
bid128_minnum (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
40
#endif
41
 
42
  UINT128 res;
43
  int exp_x, exp_y;
44
  int diff;
45
  UINT128 sig_x, sig_y;
46
  UINT192 sig_n_prime192;
47
  UINT256 sig_n_prime256;
48
  char x_is_zero = 0, y_is_zero = 0;
49
 
50
  BID_SWAP128 (x);
51
  BID_SWAP128 (y);
52
 
53
  // check for non-canonical x
54
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // x is NAN
55
    x.w[1] = x.w[1] & 0xfe003fffffffffffull;    // clear out G[6]-G[16]
56
    // check for non-canonical NaN payload
57
    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
58
        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
59
         (x.w[0] > 0x38c15b09ffffffffull))) {
60
      x.w[1] = x.w[1] & 0xffffc00000000000ull;
61
      x.w[0] = 0x0ull;
62
    }
63
  } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {     // x = inf
64
    x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
65
    x.w[0] = 0x0ull;
66
  } else {      // x is not special
67
    // check for non-canonical values - treated as zero
68
    if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // G0_G1=11
69
      // non-canonical
70
      x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
71
      x.w[0] = 0x0ull;
72
    } else {    // G0_G1 != 11
73
      if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
74
          ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
75
           && x.w[0] > 0x378d8e63ffffffffull)) {
76
        // x is non-canonical if coefficient is larger than 10^34 -1
77
        x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
78
        x.w[0] = 0x0ull;
79
      } else {  // canonical
80
        ;
81
      }
82
    }
83
  }
84
  // check for non-canonical y
85
  if ((y.w[1] & MASK_NAN) == MASK_NAN) {        // y is NAN
86
    y.w[1] = y.w[1] & 0xfe003fffffffffffull;    // clear out G[6]-G[16]
87
    // check for non-canonical NaN payload
88
    if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
89
        (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
90
         (y.w[0] > 0x38c15b09ffffffffull))) {
91
      y.w[1] = y.w[1] & 0xffffc00000000000ull;
92
      y.w[0] = 0x0ull;
93
    }
94
  } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {     // y = inf
95
    y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
96
    y.w[0] = 0x0ull;
97
  } else {      // y is not special
98
    // check for non-canonical values - treated as zero
99
    if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // G0_G1=11
100
      // non-canonical
101
      y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
102
      y.w[0] = 0x0ull;
103
    } else {    // G0_G1 != 11
104
      if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
105
          ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
106
           && y.w[0] > 0x378d8e63ffffffffull)) {
107
        // y is non-canonical if coefficient is larger than 10^34 -1
108
        y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
109
        y.w[0] = 0x0ull;
110
      } else {  // canonical
111
        ;
112
      }
113
    }
114
  }
115
 
116
  // NaN (CASE1)
117
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // x is NAN
118
    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {    // x is SNaN
119
      // if x is SNAN, then return quiet (x)
120
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
121
      x.w[1] = x.w[1] & 0xfdffffffffffffffull;  // quietize x
122
      res = x;
123
    } else {    // x is QNaN
124
      if ((y.w[1] & MASK_NAN) == MASK_NAN) {    // y is NAN
125
        if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {        // y is SNAN
126
          *pfpsf |= INVALID_EXCEPTION;  // set invalid flag
127
        }
128
        res = x;
129
      } else {
130
        res = y;
131
      }
132
    }
133
    BID_RETURN (res);
134
  } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
135
    if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
136
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
137
      y.w[1] = y.w[1] & 0xfdffffffffffffffull;  // quietize y
138
      res = y;
139
    } else {
140
      // will return x (which is not NaN)
141
      res = x;
142
    }
143
    BID_RETURN (res);
144
  }
145
  // SIMPLE (CASE2)
146
  // if all the bits are the same, these numbers are equal (not Greater).
147
  if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
148
    res = x;
149
    BID_RETURN (res);
150
  }
151
  // INFINITY (CASE3)
152
  if ((x.w[1] & MASK_INF) == MASK_INF) {
153
    // if x is neg infinity, there is no way it is greater than y, return 0
154
    res = (((x.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
155
    BID_RETURN (res);
156
  } else if ((y.w[1] & MASK_INF) == MASK_INF) {
157
    // x is finite, so if y is positive infinity, then x is less, return 0
158
    //                 if y is negative infinity, then x is greater, return 1
159
    res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
160
    BID_RETURN (res);
161
  }
162
  // CONVERT X
163
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
164
  sig_x.w[0] = x.w[0];
165
  exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
166
 
167
  // CONVERT Y
168
  exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
169
  sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
170
  sig_y.w[0] = y.w[0];
171
 
172
  // ZERO (CASE4)
173
  // some properties:
174
  //    (+ZERO == -ZERO) => therefore ignore the sign
175
  //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => ignore the exponent 
176
  //    field
177
  //    (Any non-canonical # is considered 0)
178
  if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
179
    x_is_zero = 1;
180
  }
181
  if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
182
    y_is_zero = 1;
183
  }
184
 
185
  if (x_is_zero && y_is_zero) {
186
    // if both numbers are zero, neither is greater => return either number
187
    res = x;
188
    BID_RETURN (res);
189
  } else if (x_is_zero) {
190
    // is x is zero, it is greater if Y is negative
191
    res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
192
    BID_RETURN (res);
193
  } else if (y_is_zero) {
194
    // is y is zero, X is greater if it is positive
195
    res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
196
    BID_RETURN (res);
197
  }
198
  // OPPOSITE SIGN (CASE5)
199
  // now, if the sign bits differ, x is greater if y is negative
200
  if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
201
    res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
202
    BID_RETURN (res);
203
  }
204
  // REDUNDANT REPRESENTATIONS (CASE6)
205
  // if exponents are the same, then we have a simple comparison of 
206
  //    the significands
207
  if (exp_y == exp_x) {
208
    res = (((sig_x.w[1] > sig_y.w[1])
209
            || (sig_x.w[1] == sig_y.w[1]
210
                && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
211
                                                 MASK_SIGN)) ? y : x;
212
    BID_RETURN (res);
213
  }
214
  // if both components are either bigger or smaller, it is clear what 
215
  //    needs to be done
216
  if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
217
      && exp_x > exp_y) {
218
    res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
219
    BID_RETURN (res);
220
  }
221
  if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
222
      && exp_x < exp_y) {
223
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
224
    BID_RETURN (res);
225
  }
226
 
227
  diff = exp_x - exp_y;
228
 
229
  // if |exp_x - exp_y| < 33, it comes down to the compensated significand
230
  if (diff > 0) {        // to simplify the loop below,
231
    // if exp_x is 33 greater than exp_y, no need for compensation
232
    if (diff > 33) {
233
      // difference cannot be greater than 10^33
234
      res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
235
      BID_RETURN (res);
236
    }
237
    if (diff > 19) {    //128 by 128 bit multiply -> 256 bits
238
      __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
239
      // if postitive, return whichever significand is larger 
240
      // (converse if negative)
241
      res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
242
              || (sig_n_prime256.w[1] > sig_y.w[1])
243
              || (sig_n_prime256.w[1] == sig_y.w[1]
244
                  && sig_n_prime256.w[0] >
245
                  sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) ==
246
                                  MASK_SIGN)) ? y : x;
247
      BID_RETURN (res);
248
    }
249
    __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
250
    // if postitive, return whichever significand is larger 
251
    // (converse if negative)
252
    res =
253
      (((sig_n_prime192.w[2] > 0) || (sig_n_prime192.w[1] > sig_y.w[1])
254
        || (sig_n_prime192.w[1] == sig_y.w[1]
255
            && sig_n_prime192.w[0] >
256
            sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? y : x;
257
    BID_RETURN (res);
258
  }
259
  diff = exp_y - exp_x;
260
  // if exp_x is 33 less than exp_y, no need for compensation
261
  if (diff > 33) {
262
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
263
    BID_RETURN (res);
264
  }
265
  if (diff > 19) {      //128 by 128 bit multiply -> 256 bits
266
    // adjust the y significand upwards
267
    __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
268
    // if postitive, return whichever significand is larger 
269
    // (converse if negative)
270
    res =
271
      ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
272
        || (sig_n_prime256.w[1] > sig_x.w[1]
273
            || (sig_n_prime256.w[1] == sig_x.w[1]
274
                && sig_n_prime256.w[0] >
275
                sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
276
                                 MASK_SIGN)) ? x : y;
277
    BID_RETURN (res);
278
  }
279
  // adjust the y significand upwards
280
  __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
281
  // if postitive, return whichever significand is larger (converse if negative)
282
  res =
283
    ((sig_n_prime192.w[2] != 0
284
      || (sig_n_prime192.w[1] > sig_x.w[1]
285
          || (sig_n_prime192.w[1] == sig_x.w[1]
286
              && sig_n_prime192.w[0] > sig_x.w[0])))
287
     ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
288
  BID_RETURN (res);
289
}
290
 
291
/*****************************************************************************
292
 *  BID128 minimum magnitude function - returns greater of two numbers
293
 *****************************************************************************/
294
 
295
#if DECIMAL_CALL_BY_REFERENCE
296
void
297
bid128_minnum_mag (UINT128 * pres, UINT128 * px,
298
                   UINT128 * py _EXC_FLAGS_PARAM) {
299
  UINT128 x = *px;
300
  UINT128 y = *py;
301
#else
302
UINT128
303
bid128_minnum_mag (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
304
#endif
305
 
306
  UINT128 res;
307
  int exp_x, exp_y;
308
  int diff;
309
  UINT128 sig_x, sig_y;
310
  UINT192 sig_n_prime192;
311
  UINT256 sig_n_prime256;
312
 
313
  BID_SWAP128 (x);
314
  BID_SWAP128 (y);
315
 
316
  // check for non-canonical x
317
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // x is NAN
318
    x.w[1] = x.w[1] & 0xfe003fffffffffffull;    // clear out G[6]-G[16]
319
    // check for non-canonical NaN payload
320
    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
321
        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
322
         (x.w[0] > 0x38c15b09ffffffffull))) {
323
      x.w[1] = x.w[1] & 0xffffc00000000000ull;
324
      x.w[0] = 0x0ull;
325
    }
326
  } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {     // x = inf
327
    x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
328
    x.w[0] = 0x0ull;
329
  } else {      // x is not special
330
    // check for non-canonical values - treated as zero
331
    if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // G0_G1=11
332
      // non-canonical
333
      x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
334
      x.w[0] = 0x0ull;
335
    } else {    // G0_G1 != 11
336
      if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
337
          ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
338
           && x.w[0] > 0x378d8e63ffffffffull)) {
339
        // x is non-canonical if coefficient is larger than 10^34 -1
340
        x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
341
        x.w[0] = 0x0ull;
342
      } else {  // canonical
343
        ;
344
      }
345
    }
346
  }
347
  // check for non-canonical y
348
  if ((y.w[1] & MASK_NAN) == MASK_NAN) {        // y is NAN
349
    y.w[1] = y.w[1] & 0xfe003fffffffffffull;    // clear out G[6]-G[16]
350
    // check for non-canonical NaN payload
351
    if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
352
        (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
353
         (y.w[0] > 0x38c15b09ffffffffull))) {
354
      y.w[1] = y.w[1] & 0xffffc00000000000ull;
355
      y.w[0] = 0x0ull;
356
    }
357
  } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {     // y = inf
358
    y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
359
    y.w[0] = 0x0ull;
360
  } else {      // y is not special
361
    // check for non-canonical values - treated as zero
362
    if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // G0_G1=11
363
      // non-canonical
364
      y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
365
      y.w[0] = 0x0ull;
366
    } else {    // G0_G1 != 11
367
      if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
368
          ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
369
           && y.w[0] > 0x378d8e63ffffffffull)) {
370
        // y is non-canonical if coefficient is larger than 10^34 -1
371
        y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
372
        y.w[0] = 0x0ull;
373
      } else {  // canonical
374
        ;
375
      }
376
    }
377
  }
378
 
379
  // NaN (CASE1)
380
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // x is NAN
381
    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {    // x is SNaN
382
      // if x is SNAN, then return quiet (x)
383
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
384
      x.w[1] = x.w[1] & 0xfdffffffffffffffull;  // quietize x
385
      res = x;
386
    } else {    // x is QNaN
387
      if ((y.w[1] & MASK_NAN) == MASK_NAN) {    // y is NAN
388
        if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {        // y is SNAN
389
          *pfpsf |= INVALID_EXCEPTION;  // set invalid flag
390
        }
391
        res = x;
392
      } else {
393
        res = y;
394
      }
395
    }
396
    BID_RETURN (res);
397
  } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
398
    if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
399
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
400
      y.w[1] = y.w[1] & 0xfdffffffffffffffull;  // quietize y
401
      res = y;
402
    } else {
403
      // will return x (which is not NaN)
404
      res = x;
405
    }
406
    BID_RETURN (res);
407
  }
408
  // SIMPLE (CASE2)
409
  // if all the bits are the same, these numbers are equal (not Greater).
410
  if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
411
    res = y;
412
    BID_RETURN (res);
413
  }
414
  // INFINITY (CASE3)
415
  if ((x.w[1] & MASK_INF) == MASK_INF) {
416
    // if x infinity, it has maximum magnitude.
417
    // Check if magnitudes are equal.  If x is negative, return it.
418
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN
419
           && (y.w[1] & MASK_INF) == MASK_INF) ? x : y;
420
    BID_RETURN (res);
421
  } else if ((y.w[1] & MASK_INF) == MASK_INF) {
422
    // x is finite, so if y is infinity, then x is less in magnitude
423
    res = x;
424
    BID_RETURN (res);
425
  }
426
  // CONVERT X
427
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
428
  sig_x.w[0] = x.w[0];
429
  exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
430
 
431
  // CONVERT Y
432
  exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
433
  sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
434
  sig_y.w[0] = y.w[0];
435
 
436
  // ZERO (CASE4)
437
  // some properties:
438
  //    (+ZERO == -ZERO) => therefore ignore the sign
439
  //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => 
440
  //        therefore ignore the exponent field
441
  //    (Any non-canonical # is considered 0)
442
  if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
443
    res = x;
444
    BID_RETURN (res);
445
  }
446
  if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
447
    res = y;
448
    BID_RETURN (res);
449
  }
450
  // REDUNDANT REPRESENTATIONS (CASE6)
451
  // check if exponents are the same and significands are the same
452
  if (exp_y == exp_x && sig_x.w[1] == sig_y.w[1]
453
      && sig_x.w[0] == sig_y.w[0]) {
454
    if (x.w[1] & 0x8000000000000000ull) {       // x is negative
455
      res = x;
456
      BID_RETURN (res);
457
    } else {
458
      res = y;
459
      BID_RETURN (res);
460
    }
461
  } else if (((sig_x.w[1] > sig_y.w[1] || (sig_x.w[1] == sig_y.w[1]
462
                                           && sig_x.w[0] > sig_y.w[0]))
463
              && exp_x == exp_y)
464
             || ((sig_x.w[1] > sig_y.w[1]
465
                  || (sig_x.w[1] == sig_y.w[1]
466
                      && sig_x.w[0] >= sig_y.w[0]))
467
                 && exp_x > exp_y)) {
468
    // if both components are either bigger or smaller, it is clear what 
469
    // needs to be done; also if the magnitudes are equal
470
    res = y;
471
    BID_RETURN (res);
472
  } else if (((sig_y.w[1] > sig_x.w[1] || (sig_y.w[1] == sig_x.w[1]
473
                                           && sig_y.w[0] > sig_x.w[0]))
474
              && exp_y == exp_x)
475
             || ((sig_y.w[1] > sig_x.w[1]
476
                  || (sig_y.w[1] == sig_x.w[1]
477
                      && sig_y.w[0] >= sig_x.w[0]))
478
                 && exp_y > exp_x)) {
479
    res = x;
480
    BID_RETURN (res);
481
  } else {
482
    ;   // continue
483
  }
484
  diff = exp_x - exp_y;
485
  // if |exp_x - exp_y| < 33, it comes down to the compensated significand
486
  if (diff > 0) {        // to simplify the loop below,
487
    // if exp_x is 33 greater than exp_y, no need for compensation
488
    if (diff > 33) {
489
      res = y;  // difference cannot be greater than 10^33
490
      BID_RETURN (res);
491
    }
492
    if (diff > 19) {    //128 by 128 bit multiply -> 256 bits
493
      __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
494
      // if positive, return whichever significand is larger 
495
      // (converse if negative)
496
      if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
497
          && sig_n_prime256.w[1] == sig_y.w[1]
498
          && (sig_n_prime256.w[0] == sig_y.w[0])) {
499
        res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;      // if equal
500
        BID_RETURN (res);
501
      }
502
      res = (((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
503
             || (sig_n_prime256.w[1] > sig_y.w[1])
504
             || (sig_n_prime256.w[1] == sig_y.w[1]
505
                 && sig_n_prime256.w[0] > sig_y.w[0])) ? y : x;
506
      BID_RETURN (res);
507
    }
508
    __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
509
    // if positive, return whichever significand is larger 
510
    // (converse if negative)
511
    if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
512
        && (sig_n_prime192.w[0] == sig_y.w[0])) {
513
      // if = in magnitude, return +, (if possible)
514
      res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
515
      BID_RETURN (res);
516
    }
517
    res = ((sig_n_prime192.w[2] > 0)
518
           || (sig_n_prime192.w[1] > sig_y.w[1])
519
           || (sig_n_prime192.w[1] == sig_y.w[1]
520
               && sig_n_prime192.w[0] > sig_y.w[0])) ? y : x;
521
    BID_RETURN (res);
522
  }
523
  diff = exp_y - exp_x;
524
  // if exp_x is 33 less than exp_y, no need for compensation
525
  if (diff > 33) {
526
    res = x;
527
    BID_RETURN (res);
528
  }
529
  if (diff > 19) {      //128 by 128 bit multiply -> 256 bits
530
    // adjust the y significand upwards
531
    __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
532
    // if positive, return whichever significand is larger 
533
    // (converse if negative)
534
    if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
535
        && sig_n_prime256.w[1] == sig_x.w[1]
536
        && (sig_n_prime256.w[0] == sig_x.w[0])) {
537
      // if = in magnitude, return +, (if possible)
538
      res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
539
      BID_RETURN (res);
540
    }
541
    res = (sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
542
           && (sig_n_prime256.w[1] < sig_x.w[1]
543
               || (sig_n_prime256.w[1] == sig_x.w[1]
544
                   && sig_n_prime256.w[0] < sig_x.w[0]))) ? y : x;
545
    BID_RETURN (res);
546
  }
547
  // adjust the y significand upwards
548
  __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
549
  // if positive, return whichever significand is larger (converse if negative)
550
  if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
551
      && (sig_n_prime192.w[0] == sig_x.w[0])) {
552
    // if = in magnitude, return +, if possible)
553
    res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
554
    BID_RETURN (res);
555
  }
556
  res = (sig_n_prime192.w[2] == 0
557
         && (sig_n_prime192.w[1] < sig_x.w[1]
558
             || (sig_n_prime192.w[1] == sig_x.w[1]
559
                 && sig_n_prime192.w[0] < sig_x.w[0]))) ? y : x;
560
  BID_RETURN (res);
561
}
562
 
563
/*****************************************************************************
564
 *  BID128 maximum function - returns greater of two numbers
565
 *****************************************************************************/
566
 
567
#if DECIMAL_CALL_BY_REFERENCE
568
void
569
bid128_maxnum (UINT128 * pres, UINT128 * px,
570
               UINT128 * py _EXC_FLAGS_PARAM) {
571
  UINT128 x = *px;
572
  UINT128 y = *py;
573
#else
574
UINT128
575
bid128_maxnum (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
576
#endif
577
 
578
  UINT128 res;
579
  int exp_x, exp_y;
580
  int diff;
581
  UINT128 sig_x, sig_y;
582
  UINT192 sig_n_prime192;
583
  UINT256 sig_n_prime256;
584
  char x_is_zero = 0, y_is_zero = 0;
585
 
586
  BID_SWAP128 (x);
587
  BID_SWAP128 (y);
588
 
589
  // check for non-canonical x
590
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // x is NAN
591
    x.w[1] = x.w[1] & 0xfe003fffffffffffull;    // clear out G[6]-G[16]
592
    // check for non-canonical NaN payload
593
    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
594
        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
595
         (x.w[0] > 0x38c15b09ffffffffull))) {
596
      x.w[1] = x.w[1] & 0xffffc00000000000ull;
597
      x.w[0] = 0x0ull;
598
    }
599
  } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {     // x = inf
600
    x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
601
    x.w[0] = 0x0ull;
602
  } else {      // x is not special
603
    // check for non-canonical values - treated as zero
604
    if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // G0_G1=11
605
      // non-canonical
606
      x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
607
      x.w[0] = 0x0ull;
608
    } else {    // G0_G1 != 11
609
      if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
610
          ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
611
           && x.w[0] > 0x378d8e63ffffffffull)) {
612
        // x is non-canonical if coefficient is larger than 10^34 -1
613
        x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
614
        x.w[0] = 0x0ull;
615
      } else {  // canonical
616
        ;
617
      }
618
    }
619
  }
620
  // check for non-canonical y
621
  if ((y.w[1] & MASK_NAN) == MASK_NAN) {        // y is NAN
622
    y.w[1] = y.w[1] & 0xfe003fffffffffffull;    // clear out G[6]-G[16]
623
    // check for non-canonical NaN payload
624
    if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
625
        (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
626
         (y.w[0] > 0x38c15b09ffffffffull))) {
627
      y.w[1] = y.w[1] & 0xffffc00000000000ull;
628
      y.w[0] = 0x0ull;
629
    }
630
  } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {     // y = inf
631
    y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
632
    y.w[0] = 0x0ull;
633
  } else {      // y is not special
634
    // check for non-canonical values - treated as zero
635
    if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // G0_G1=11
636
      // non-canonical
637
      y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
638
      y.w[0] = 0x0ull;
639
    } else {    // G0_G1 != 11
640
      if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
641
          ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
642
           && y.w[0] > 0x378d8e63ffffffffull)) {
643
        // y is non-canonical if coefficient is larger than 10^34 -1
644
        y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
645
        y.w[0] = 0x0ull;
646
      } else {  // canonical
647
        ;
648
      }
649
    }
650
  }
651
 
652
  // NaN (CASE1)
653
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // x is NAN
654
    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {    // x is SNaN
655
      // if x is SNAN, then return quiet (x)
656
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
657
      x.w[1] = x.w[1] & 0xfdffffffffffffffull;  // quietize x
658
      res = x;
659
    } else {    // x is QNaN
660
      if ((y.w[1] & MASK_NAN) == MASK_NAN) {    // y is NAN
661
        if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {        // y is SNAN
662
          *pfpsf |= INVALID_EXCEPTION;  // set invalid flag
663
        }
664
        res = x;
665
      } else {
666
        res = y;
667
      }
668
    }
669
    BID_RETURN (res);
670
  } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
671
    if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
672
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
673
      y.w[1] = y.w[1] & 0xfdffffffffffffffull;  // quietize y
674
      res = y;
675
    } else {
676
      // will return x (which is not NaN)
677
      res = x;
678
    }
679
    BID_RETURN (res);
680
  }
681
  // SIMPLE (CASE2)
682
  // if all the bits are the same, these numbers are equal (not Greater).
683
  if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
684
    res = x;
685
    BID_RETURN (res);
686
  }
687
  // INFINITY (CASE3)
688
  if ((x.w[1] & MASK_INF) == MASK_INF) {
689
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
690
    BID_RETURN (res);
691
  } else if ((y.w[1] & MASK_INF) == MASK_INF) {
692
    // x is finite, so if y is positive infinity, then x is less, return 0
693
    //                 if y is negative infinity, then x is greater, return 1
694
    res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
695
    BID_RETURN (res);
696
  }
697
  // CONVERT X
698
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
699
  sig_x.w[0] = x.w[0];
700
  exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
701
 
702
  // CONVERT Y
703
  exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
704
  sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
705
  sig_y.w[0] = y.w[0];
706
 
707
  // ZERO (CASE4)
708
  // some properties:
709
  //    (+ZERO == -ZERO) => therefore ignore the sign
710
  //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => 
711
  //        therefore ignore the exponent field
712
  //    (Any non-canonical # is considered 0)
713
  if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
714
    x_is_zero = 1;
715
  }
716
  if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
717
    y_is_zero = 1;
718
  }
719
 
720
  if (x_is_zero && y_is_zero) {
721
    // if both numbers are zero, neither is greater => return either number
722
    res = x;
723
    BID_RETURN (res);
724
  } else if (x_is_zero) {
725
    // is x is zero, it is greater if Y is negative
726
    res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
727
    BID_RETURN (res);
728
  } else if (y_is_zero) {
729
    // is y is zero, X is greater if it is positive
730
    res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
731
    BID_RETURN (res);
732
  }
733
  // OPPOSITE SIGN (CASE5)
734
  // now, if the sign bits differ, x is greater if y is negative
735
  if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
736
    res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
737
    BID_RETURN (res);
738
  }
739
  // REDUNDANT REPRESENTATIONS (CASE6)
740
  // if exponents are the same, then we have a simple comparison of 
741
  // the significands
742
  if (exp_y == exp_x) {
743
    res = (((sig_x.w[1] > sig_y.w[1]) || (sig_x.w[1] == sig_y.w[1] &&
744
                                          sig_x.w[0] >= sig_y.w[0])) ^
745
           ((x.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
746
    BID_RETURN (res);
747
  }
748
  // if both components are either bigger or smaller, it is clear what 
749
  // needs to be done
750
  if ((sig_x.w[1] > sig_y.w[1]
751
       || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
752
      && exp_x >= exp_y) {
753
    res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
754
    BID_RETURN (res);
755
  }
756
  if ((sig_x.w[1] < sig_y.w[1]
757
       || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
758
      && exp_x <= exp_y) {
759
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
760
    BID_RETURN (res);
761
  }
762
  diff = exp_x - exp_y;
763
  // if |exp_x - exp_y| < 33, it comes down to the compensated significand
764
  if (diff > 0) {        // to simplify the loop below,
765
    // if exp_x is 33 greater than exp_y, no need for compensation
766
    if (diff > 33) {
767
      // difference cannot be greater than 10^33
768
      res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
769
      BID_RETURN (res);
770
    }
771
    if (diff > 19) {    //128 by 128 bit multiply -> 256 bits
772
      __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
773
      // if postitive, return whichever significand is larger 
774
      // (converse if negative)
775
      res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
776
              || (sig_n_prime256.w[1] > sig_y.w[1])
777
              || (sig_n_prime256.w[1] == sig_y.w[1]
778
                  && sig_n_prime256.w[0] >
779
                  sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) ==
780
                                  MASK_SIGN)) ? x : y;
781
      BID_RETURN (res);
782
    }
783
    __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
784
    // if postitive, return whichever significand is larger 
785
    // (converse if negative)
786
    res =
787
      (((sig_n_prime192.w[2] > 0) || (sig_n_prime192.w[1] > sig_y.w[1])
788
        || (sig_n_prime192.w[1] == sig_y.w[1]
789
            && sig_n_prime192.w[0] >
790
            sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
791
    BID_RETURN (res);
792
  }
793
  diff = exp_y - exp_x;
794
  // if exp_x is 33 less than exp_y, no need for compensation
795
  if (diff > 33) {
796
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
797
    BID_RETURN (res);
798
  }
799
  if (diff > 19) {      //128 by 128 bit multiply -> 256 bits
800
    // adjust the y significand upwards
801
    __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
802
    // if postitive, return whichever significand is larger 
803
    // (converse if negative)
804
    res =
805
      ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
806
        || (sig_n_prime256.w[1] > sig_x.w[1]
807
            || (sig_n_prime256.w[1] == sig_x.w[1]
808
                && sig_n_prime256.w[0] >
809
                sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) !=
810
                                 MASK_SIGN)) ? x : y;
811
    BID_RETURN (res);
812
  }
813
  // adjust the y significand upwards
814
  __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
815
  // if postitive, return whichever significand is larger (converse if negative)
816
  res =
817
    ((sig_n_prime192.w[2] != 0
818
      || (sig_n_prime192.w[1] > sig_x.w[1]
819
          || (sig_n_prime192.w[1] == sig_x.w[1]
820
              && sig_n_prime192.w[0] >
821
              sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) !=
822
                               MASK_SIGN)) ? x : y;
823
  BID_RETURN (res);
824
}
825
 
826
/*****************************************************************************
827
 *  BID128 maximum magnitude function - returns greater of two numbers
828
 *****************************************************************************/
829
 
830
#if DECIMAL_CALL_BY_REFERENCE
831
void
832
bid128_maxnum_mag (UINT128 * pres, UINT128 * px,
833
                   UINT128 * py _EXC_FLAGS_PARAM) {
834
  UINT128 x = *px;
835
  UINT128 y = *py;
836
#else
837
UINT128
838
bid128_maxnum_mag (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
839
#endif
840
 
841
  UINT128 res;
842
  int exp_x, exp_y;
843
  int diff;
844
  UINT128 sig_x, sig_y;
845
  UINT192 sig_n_prime192;
846
  UINT256 sig_n_prime256;
847
 
848
  BID_SWAP128 (x);
849
  BID_SWAP128 (y);
850
 
851
  // check for non-canonical x
852
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // x is NAN
853
    x.w[1] = x.w[1] & 0xfe003fffffffffffull;    // clear out G[6]-G[16]
854
    // check for non-canonical NaN payload
855
    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
856
        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
857
         (x.w[0] > 0x38c15b09ffffffffull))) {
858
      x.w[1] = x.w[1] & 0xffffc00000000000ull;
859
      x.w[0] = 0x0ull;
860
    }
861
  } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {     // x = inf
862
    x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
863
    x.w[0] = 0x0ull;
864
  } else {      // x is not special
865
    // check for non-canonical values - treated as zero
866
    if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // G0_G1=11
867
      // non-canonical
868
      x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
869
      x.w[0] = 0x0ull;
870
    } else {    // G0_G1 != 11
871
      if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
872
          ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
873
           && x.w[0] > 0x378d8e63ffffffffull)) {
874
        // x is non-canonical if coefficient is larger than 10^34 -1
875
        x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
876
        x.w[0] = 0x0ull;
877
      } else {  // canonical
878
        ;
879
      }
880
    }
881
  }
882
  // check for non-canonical y
883
  if ((y.w[1] & MASK_NAN) == MASK_NAN) {        // y is NAN
884
    y.w[1] = y.w[1] & 0xfe003fffffffffffull;    // clear out G[6]-G[16]
885
    // check for non-canonical NaN payload
886
    if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
887
        (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
888
         (y.w[0] > 0x38c15b09ffffffffull))) {
889
      y.w[1] = y.w[1] & 0xffffc00000000000ull;
890
      y.w[0] = 0x0ull;
891
    }
892
  } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {     // y = inf
893
    y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
894
    y.w[0] = 0x0ull;
895
  } else {      // y is not special
896
    // check for non-canonical values - treated as zero
897
    if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // G0_G1=11
898
      // non-canonical
899
      y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
900
      y.w[0] = 0x0ull;
901
    } else {    // G0_G1 != 11
902
      if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
903
          ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull &&
904
           y.w[0] > 0x378d8e63ffffffffull)) {
905
        // y is non-canonical if coefficient is larger than 10^34 -1
906
        y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
907
        y.w[0] = 0x0ull;
908
      } else {  // canonical
909
        ;
910
      }
911
    }
912
  }
913
 
914
  // NaN (CASE1)
915
  if ((x.w[1] & MASK_NAN) == MASK_NAN) {        // x is NAN
916
    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {    // x is SNaN
917
      // if x is SNAN, then return quiet (x)
918
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
919
      x.w[1] = x.w[1] & 0xfdffffffffffffffull;  // quietize x
920
      res = x;
921
    } else {    // x is QNaN
922
      if ((y.w[1] & MASK_NAN) == MASK_NAN) {    // y is NAN
923
        if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {        // y is SNAN
924
          *pfpsf |= INVALID_EXCEPTION;  // set invalid flag
925
        }
926
        res = x;
927
      } else {
928
        res = y;
929
      }
930
    }
931
    BID_RETURN (res);
932
  } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
933
    if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
934
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
935
      y.w[1] = y.w[1] & 0xfdffffffffffffffull;  // quietize y
936
      res = y;
937
    } else {
938
      // will return x (which is not NaN)
939
      res = x;
940
    }
941
    BID_RETURN (res);
942
  }
943
  // SIMPLE (CASE2)
944
  // if all the bits are the same, these numbers are equal (not Greater).
945
  if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
946
    res = y;
947
    BID_RETURN (res);
948
  }
949
  // INFINITY (CASE3)
950
  if ((x.w[1] & MASK_INF) == MASK_INF) {
951
    // if x infinity, it has maximum magnitude
952
    res = ((x.w[1] & MASK_SIGN) == MASK_SIGN
953
           && (y.w[1] & MASK_INF) == MASK_INF) ? y : x;
954
    BID_RETURN (res);
955
  } else if ((y.w[1] & MASK_INF) == MASK_INF) {
956
    // x is finite, so if y is positive infinity, then x is less, return 0
957
    //                 if y is negative infinity, then x is greater, return 1
958
    res = y;
959
    BID_RETURN (res);
960
  }
961
  // CONVERT X
962
  sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
963
  sig_x.w[0] = x.w[0];
964
  exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
965
 
966
  // CONVERT Y
967
  exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
968
  sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
969
  sig_y.w[0] = y.w[0];
970
 
971
  // ZERO (CASE4)
972
  // some properties:
973
  //    (+ZERO == -ZERO) => therefore ignore the sign
974
  //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => 
975
  //         therefore ignore the exponent field
976
  //    (Any non-canonical # is considered 0)
977
  if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
978
    res = y;
979
    BID_RETURN (res);
980
  }
981
  if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
982
    res = x;
983
    BID_RETURN (res);
984
  }
985
  // REDUNDANT REPRESENTATIONS (CASE6)
986
  if (exp_y == exp_x && sig_x.w[1] == sig_y.w[1]
987
      && sig_x.w[0] == sig_y.w[0]) {
988
    // check if exponents are the same and significands are the same
989
    if (x.w[1] & 0x8000000000000000ull) {       // x is negative
990
      res = y;
991
      BID_RETURN (res);
992
    } else {
993
      res = x;
994
      BID_RETURN (res);
995
    }
996
  } else if (((sig_x.w[1] > sig_y.w[1] || (sig_x.w[1] == sig_y.w[1]
997
                                           && sig_x.w[0] > sig_y.w[0]))
998
              && exp_x == exp_y)
999
             || ((sig_x.w[1] > sig_y.w[1]
1000
                  || (sig_x.w[1] == sig_y.w[1]
1001
                      && sig_x.w[0] >= sig_y.w[0]))
1002
                 && exp_x > exp_y)) {
1003
    // if both components are either bigger or smaller, it is clear what 
1004
    // needs to be done; also if the magnitudes are equal
1005
    res = x;
1006
    BID_RETURN (res);
1007
  } else if (((sig_y.w[1] > sig_x.w[1] || (sig_y.w[1] == sig_x.w[1]
1008
                                           && sig_y.w[0] > sig_x.w[0]))
1009
              && exp_y == exp_x)
1010
             || ((sig_y.w[1] > sig_x.w[1]
1011
                  || (sig_y.w[1] == sig_x.w[1]
1012
                      && sig_y.w[0] >= sig_x.w[0]))
1013
                 && exp_y > exp_x)) {
1014
    res = y;
1015
    BID_RETURN (res);
1016
  } else {
1017
    ;   // continue
1018
  }
1019
  diff = exp_x - exp_y;
1020
  // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1021
  if (diff > 0) {        // to simplify the loop below,
1022
    // if exp_x is 33 greater than exp_y, no need for compensation
1023
    if (diff > 33) {
1024
      res = x;  // difference cannot be greater than 10^33
1025
      BID_RETURN (res);
1026
    }
1027
    if (diff > 19) {    //128 by 128 bit multiply -> 256 bits
1028
      __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
1029
      // if postitive, return whichever significand is larger 
1030
      // (converse if negative)
1031
      if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1032
          && sig_n_prime256.w[1] == sig_y.w[1]
1033
          && (sig_n_prime256.w[0] == sig_y.w[0])) {
1034
        res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;      // if equal
1035
        BID_RETURN (res);
1036
      }
1037
      res = (((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
1038
             || (sig_n_prime256.w[1] > sig_y.w[1])
1039
             || (sig_n_prime256.w[1] == sig_y.w[1]
1040
                 && sig_n_prime256.w[0] > sig_y.w[0])) ? x : y;
1041
      BID_RETURN (res);
1042
    }
1043
    __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
1044
    // if postitive, return whichever significand is larger (converse if negative)
1045
    if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
1046
        && (sig_n_prime192.w[0] == sig_y.w[0])) {
1047
      // if equal, return positive magnitude
1048
      res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1049
      BID_RETURN (res);
1050
    }
1051
    res = ((sig_n_prime192.w[2] > 0)
1052
           || (sig_n_prime192.w[1] > sig_y.w[1])
1053
           || (sig_n_prime192.w[1] == sig_y.w[1]
1054
               && sig_n_prime192.w[0] > sig_y.w[0])) ? x : y;
1055
    BID_RETURN (res);
1056
  }
1057
  diff = exp_y - exp_x;
1058
  // if exp_x is 33 less than exp_y, no need for compensation
1059
  if (diff > 33) {
1060
    res = y;
1061
    BID_RETURN (res);
1062
  }
1063
  if (diff > 19) {      //128 by 128 bit multiply -> 256 bits
1064
    // adjust the y significand upwards
1065
    __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
1066
    // if postitive, return whichever significand is larger 
1067
    // (converse if negative)
1068
    if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1069
        && sig_n_prime256.w[1] == sig_x.w[1]
1070
        && (sig_n_prime256.w[0] == sig_x.w[0])) {
1071
      // if equal, return positive (if possible)
1072
      res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1073
      BID_RETURN (res);
1074
    }
1075
    res = (sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
1076
           && (sig_n_prime256.w[1] < sig_x.w[1]
1077
               || (sig_n_prime256.w[1] == sig_x.w[1]
1078
                   && sig_n_prime256.w[0] < sig_x.w[0]))) ? x : y;
1079
    BID_RETURN (res);
1080
  }
1081
  // adjust the y significand upwards
1082
  __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
1083
  // if postitive, return whichever significand is larger (converse if negative)
1084
  if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1085
      && (sig_n_prime192.w[0] == sig_x.w[0])) {
1086
    // if equal, return positive (if possible)
1087
    res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1088
    BID_RETURN (res);
1089
  }
1090
  res = (sig_n_prime192.w[2] == 0
1091
         && (sig_n_prime192.w[1] < sig_x.w[1]
1092
             || (sig_n_prime192.w[1] == sig_x.w[1]
1093
                 && sig_n_prime192.w[0] < sig_x.w[0]))) ? x : y;
1094
  BID_RETURN (res);
1095
}

powered by: WebSVN 2.1.0

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