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

Subversion Repositories openrisc

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

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
 *  BID64 minimum function - returns greater of two numbers
28
 *****************************************************************************/
29
 
30
static const UINT64 mult_factor[16] = {
31
  1ull, 10ull, 100ull, 1000ull,
32
  10000ull, 100000ull, 1000000ull, 10000000ull,
33
  100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
34
  1000000000000ull, 10000000000000ull,
35
  100000000000000ull, 1000000000000000ull
36
};
37
 
38
#if DECIMAL_CALL_BY_REFERENCE
39
void
40
bid64_minnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
41
  UINT64 x = *px;
42
  UINT64 y = *py;
43
#else
44
UINT64
45
bid64_minnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
46
#endif
47
 
48
  UINT64 res;
49
  int exp_x, exp_y;
50
  UINT64 sig_x, sig_y;
51
  UINT128 sig_n_prime;
52
  char x_is_zero = 0, y_is_zero = 0;
53
 
54
  // check for non-canonical x
55
  if ((x & MASK_NAN) == MASK_NAN) {     // x is NaN
56
    x = x & 0xfe03ffffffffffffull;      // clear G6-G12
57
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
58
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
59
    }
60
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
61
    x = x & (MASK_SIGN | MASK_INF);
62
  } else {      // x is not special
63
    // check for non-canonical values - treated as zero
64
    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
65
      // if the steering bits are 11, then the exponent is G[0:w+1]
66
      if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
67
          9999999999999999ull) {
68
        // non-canonical
69
        x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
70
      } // else canonical
71
    }   // else canonical 
72
  }
73
 
74
  // check for non-canonical y
75
  if ((y & MASK_NAN) == MASK_NAN) {     // y is NaN
76
    y = y & 0xfe03ffffffffffffull;      // clear G6-G12
77
    if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
78
      y = y & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
79
    }
80
  } else if ((y & MASK_INF) == MASK_INF) {      // check for Infinity
81
    y = y & (MASK_SIGN | MASK_INF);
82
  } else {      // y is not special
83
    // check for non-canonical values - treated as zero
84
    if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
85
      // if the steering bits are 11, then the exponent is G[0:w+1]
86
      if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
87
          9999999999999999ull) {
88
        // non-canonical
89
        y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
90
      } // else canonical
91
    }   // else canonical
92
  }
93
 
94
  // NaN (CASE1)
95
  if ((x & MASK_NAN) == MASK_NAN) {     // x is NAN
96
    if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
97
      // if x is SNAN, then return quiet (x)
98
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
99
      x = x & 0xfdffffffffffffffull;    // quietize x
100
      res = x;
101
    } else {    // x is QNaN
102
      if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
103
        if ((y & MASK_SNAN) == MASK_SNAN) {     // y is SNAN
104
          *pfpsf |= INVALID_EXCEPTION;  // set invalid flag
105
        }
106
        res = x;
107
      } else {
108
        res = y;
109
      }
110
    }
111
    BID_RETURN (res);
112
  } else if ((y & MASK_NAN) == MASK_NAN) {      // y is NaN, but x is not
113
    if ((y & MASK_SNAN) == MASK_SNAN) {
114
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
115
      y = y & 0xfdffffffffffffffull;    // quietize y
116
      res = y;
117
    } else {
118
      // will return x (which is not NaN)
119
      res = x;
120
    }
121
    BID_RETURN (res);
122
  }
123
  // SIMPLE (CASE2)
124
  // if all the bits are the same, these numbers are equal, return either number
125
  if (x == y) {
126
    res = x;
127
    BID_RETURN (res);
128
  }
129
  // INFINITY (CASE3)
130
  if ((x & MASK_INF) == MASK_INF) {
131
    // if x is neg infinity, there is no way it is greater than y, return x
132
    if (((x & MASK_SIGN) == MASK_SIGN)) {
133
      res = x;
134
      BID_RETURN (res);
135
    }
136
    // x is pos infinity, return y
137
    else {
138
      res = y;
139
      BID_RETURN (res);
140
    }
141
  } else if ((y & MASK_INF) == MASK_INF) {
142
    // x is finite, so if y is positive infinity, then x is less, return y
143
    //                 if y is negative infinity, then x is greater, return x
144
    res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
145
    BID_RETURN (res);
146
  }
147
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
148
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
149
    exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
150
    sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
151
  } else {
152
    exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
153
    sig_x = (x & MASK_BINARY_SIG1);
154
  }
155
 
156
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
157
  if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
158
    exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
159
    sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
160
  } else {
161
    exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
162
    sig_y = (y & MASK_BINARY_SIG1);
163
  }
164
 
165
  // ZERO (CASE4)
166
  // some properties:
167
  //    (+ZERO == -ZERO) => therefore 
168
  //        ignore the sign, and neither number is greater
169
  //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => 
170
  //        ignore the exponent field
171
  //    (Any non-canonical # is considered 0)
172
  if (sig_x == 0) {
173
    x_is_zero = 1;
174
  }
175
  if (sig_y == 0) {
176
    y_is_zero = 1;
177
  }
178
 
179
  if (x_is_zero && y_is_zero) {
180
    // if both numbers are zero, neither is greater => return either
181
    res = y;
182
    BID_RETURN (res);
183
  } else if (x_is_zero) {
184
    // is x is zero, it is greater if Y is negative
185
    res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
186
    BID_RETURN (res);
187
  } else if (y_is_zero) {
188
    // is y is zero, X is greater if it is positive
189
    res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;;
190
    BID_RETURN (res);
191
  }
192
  // OPPOSITE SIGN (CASE5)
193
  // now, if the sign bits differ, x is greater if y is negative
194
  if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
195
    res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
196
    BID_RETURN (res);
197
  }
198
  // REDUNDANT REPRESENTATIONS (CASE6)
199
 
200
  // if both components are either bigger or smaller, 
201
  // it is clear what needs to be done
202
  if (sig_x > sig_y && exp_x >= exp_y) {
203
    res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;
204
    BID_RETURN (res);
205
  }
206
  if (sig_x < sig_y && exp_x <= exp_y) {
207
    res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
208
    BID_RETURN (res);
209
  }
210
  // if exp_x is 15 greater than exp_y, no need for compensation
211
  if (exp_x - exp_y > 15) {
212
    res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;       // difference cannot be >10^15
213
    BID_RETURN (res);
214
  }
215
  // if exp_x is 15 less than exp_y, no need for compensation
216
  if (exp_y - exp_x > 15) {
217
    res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
218
    BID_RETURN (res);
219
  }
220
  // if |exp_x - exp_y| < 15, it comes down to the compensated significand
221
  if (exp_x > exp_y) {  // to simplify the loop below,
222
 
223
    // otherwise adjust the x significand upwards
224
    __mul_64x64_to_128MACH (sig_n_prime, sig_x,
225
                            mult_factor[exp_x - exp_y]);
226
    // if postitive, return whichever significand is larger 
227
    // (converse if negative)
228
    if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
229
      res = y;
230
      BID_RETURN (res);
231
    }
232
 
233
    res = (((sig_n_prime.w[1] > 0)
234
            || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
235
                                            MASK_SIGN)) ? y : x;
236
    BID_RETURN (res);
237
  }
238
  // adjust the y significand upwards
239
  __mul_64x64_to_128MACH (sig_n_prime, sig_y,
240
                          mult_factor[exp_y - exp_x]);
241
 
242
  // if postitive, return whichever significand is larger (converse if negative)
243
  if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
244
    res = y;
245
    BID_RETURN (res);
246
  }
247
  res = (((sig_n_prime.w[1] == 0)
248
          && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
249
                                            MASK_SIGN)) ? y : x;
250
  BID_RETURN (res);
251
}
252
 
253
/*****************************************************************************
254
 *  BID64 minimum magnitude function - returns greater of two numbers
255
 *****************************************************************************/
256
 
257
#if DECIMAL_CALL_BY_REFERENCE
258
void
259
bid64_minnum_mag (UINT64 * pres, UINT64 * px,
260
                  UINT64 * py _EXC_FLAGS_PARAM) {
261
  UINT64 x = *px;
262
  UINT64 y = *py;
263
#else
264
UINT64
265
bid64_minnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
266
#endif
267
 
268
  UINT64 res;
269
  int exp_x, exp_y;
270
  UINT64 sig_x, sig_y;
271
  UINT128 sig_n_prime;
272
 
273
  // check for non-canonical x
274
  if ((x & MASK_NAN) == MASK_NAN) {     // x is NaN
275
    x = x & 0xfe03ffffffffffffull;      // clear G6-G12
276
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
277
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
278
    }
279
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
280
    x = x & (MASK_SIGN | MASK_INF);
281
  } else {      // x is not special
282
    // check for non-canonical values - treated as zero
283
    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
284
      // if the steering bits are 11, then the exponent is G[0:w+1]
285
      if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
286
          9999999999999999ull) {
287
        // non-canonical
288
        x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
289
      } // else canonical
290
    }   // else canonical 
291
  }
292
 
293
  // check for non-canonical y
294
  if ((y & MASK_NAN) == MASK_NAN) {     // y is NaN
295
    y = y & 0xfe03ffffffffffffull;      // clear G6-G12
296
    if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
297
      y = y & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
298
    }
299
  } else if ((y & MASK_INF) == MASK_INF) {      // check for Infinity
300
    y = y & (MASK_SIGN | MASK_INF);
301
  } else {      // y is not special
302
    // check for non-canonical values - treated as zero
303
    if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
304
      // if the steering bits are 11, then the exponent is G[0:w+1]
305
      if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
306
          9999999999999999ull) {
307
        // non-canonical
308
        y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
309
      } // else canonical
310
    }   // else canonical
311
  }
312
 
313
  // NaN (CASE1)
314
  if ((x & MASK_NAN) == MASK_NAN) {     // x is NAN
315
    if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
316
      // if x is SNAN, then return quiet (x)
317
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
318
      x = x & 0xfdffffffffffffffull;    // quietize x
319
      res = x;
320
    } else {    // x is QNaN
321
      if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
322
        if ((y & MASK_SNAN) == MASK_SNAN) {     // y is SNAN
323
          *pfpsf |= INVALID_EXCEPTION;  // set invalid flag
324
        }
325
        res = x;
326
      } else {
327
        res = y;
328
      }
329
    }
330
    BID_RETURN (res);
331
  } else if ((y & MASK_NAN) == MASK_NAN) {      // y is NaN, but x is not
332
    if ((y & MASK_SNAN) == MASK_SNAN) {
333
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
334
      y = y & 0xfdffffffffffffffull;    // quietize y
335
      res = y;
336
    } else {
337
      // will return x (which is not NaN)
338
      res = x;
339
    }
340
    BID_RETURN (res);
341
  }
342
  // SIMPLE (CASE2)
343
  // if all the bits are the same, these numbers are equal, return either number
344
  if (x == y) {
345
    res = x;
346
    BID_RETURN (res);
347
  }
348
  // INFINITY (CASE3)
349
  if ((x & MASK_INF) == MASK_INF) {
350
    // x is infinity, its magnitude is greater than or equal to y
351
    // return x only if y is infinity and x is negative
352
    res = ((x & MASK_SIGN) == MASK_SIGN
353
           && (y & MASK_INF) == MASK_INF) ? x : y;
354
    BID_RETURN (res);
355
  } else if ((y & MASK_INF) == MASK_INF) {
356
    // y is infinity, then it must be greater in magnitude, return x
357
    res = x;
358
    BID_RETURN (res);
359
  }
360
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
361
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
362
    exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
363
    sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
364
  } else {
365
    exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
366
    sig_x = (x & MASK_BINARY_SIG1);
367
  }
368
 
369
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
370
  if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
371
    exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
372
    sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
373
  } else {
374
    exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
375
    sig_y = (y & MASK_BINARY_SIG1);
376
  }
377
 
378
  // ZERO (CASE4)
379
  // some properties:
380
  //    (+ZERO == -ZERO) => therefore 
381
  //        ignore the sign, and neither number is greater
382
  //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => 
383
  //        ignore the exponent field
384
  //    (Any non-canonical # is considered 0)
385
  if (sig_x == 0) {
386
    res = x;    // x_is_zero, its magnitude must be smaller than y
387
    BID_RETURN (res);
388
  }
389
  if (sig_y == 0) {
390
    res = y;    // y_is_zero, its magnitude must be smaller than x
391
    BID_RETURN (res);
392
  }
393
  // REDUNDANT REPRESENTATIONS (CASE6)
394
  // if both components are either bigger or smaller, 
395
  // it is clear what needs to be done
396
  if (sig_x > sig_y && exp_x >= exp_y) {
397
    res = y;
398
    BID_RETURN (res);
399
  }
400
  if (sig_x < sig_y && exp_x <= exp_y) {
401
    res = x;
402
    BID_RETURN (res);
403
  }
404
  // if exp_x is 15 greater than exp_y, no need for compensation
405
  if (exp_x - exp_y > 15) {
406
    res = y;    // difference cannot be greater than 10^15
407
    BID_RETURN (res);
408
  }
409
  // if exp_x is 15 less than exp_y, no need for compensation
410
  if (exp_y - exp_x > 15) {
411
    res = x;
412
    BID_RETURN (res);
413
  }
414
  // if |exp_x - exp_y| < 15, it comes down to the compensated significand
415
  if (exp_x > exp_y) {  // to simplify the loop below,
416
    // otherwise adjust the x significand upwards
417
    __mul_64x64_to_128MACH (sig_n_prime, sig_x,
418
                            mult_factor[exp_x - exp_y]);
419
    // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y), this is 
420
    // the compensated signif.
421
    if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
422
      // two numbers are equal, return minNum(x,y)
423
      res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
424
      BID_RETURN (res);
425
    }
426
    // now, if compensated_x (sig_n_prime) is greater than y, return y,  
427
    // otherwise return x
428
    res = ((sig_n_prime.w[1] != 0) || sig_n_prime.w[0] > sig_y) ? y : x;
429
    BID_RETURN (res);
430
  }
431
  // exp_y must be greater than exp_x, thus adjust the y significand upwards
432
  __mul_64x64_to_128MACH (sig_n_prime, sig_y,
433
                          mult_factor[exp_y - exp_x]);
434
 
435
  if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
436
    res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
437
    // two numbers are equal, return either
438
    BID_RETURN (res);
439
  }
440
 
441
  res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? y : x;
442
  BID_RETURN (res);
443
}
444
 
445
/*****************************************************************************
446
 *  BID64 maximum function - returns greater of two numbers
447
 *****************************************************************************/
448
 
449
#if DECIMAL_CALL_BY_REFERENCE
450
void
451
bid64_maxnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
452
  UINT64 x = *px;
453
  UINT64 y = *py;
454
#else
455
UINT64
456
bid64_maxnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
457
#endif
458
 
459
  UINT64 res;
460
  int exp_x, exp_y;
461
  UINT64 sig_x, sig_y;
462
  UINT128 sig_n_prime;
463
  char x_is_zero = 0, y_is_zero = 0;
464
 
465
  // check for non-canonical x
466
  if ((x & MASK_NAN) == MASK_NAN) {     // x is NaN
467
    x = x & 0xfe03ffffffffffffull;      // clear G6-G12
468
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
469
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
470
    }
471
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
472
    x = x & (MASK_SIGN | MASK_INF);
473
  } else {      // x is not special
474
    // check for non-canonical values - treated as zero
475
    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
476
      // if the steering bits are 11, then the exponent is G[0:w+1]
477
      if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
478
          9999999999999999ull) {
479
        // non-canonical
480
        x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
481
      } // else canonical
482
    }   // else canonical 
483
  }
484
 
485
  // check for non-canonical y
486
  if ((y & MASK_NAN) == MASK_NAN) {     // y is NaN
487
    y = y & 0xfe03ffffffffffffull;      // clear G6-G12
488
    if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
489
      y = y & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
490
    }
491
  } else if ((y & MASK_INF) == MASK_INF) {      // check for Infinity
492
    y = y & (MASK_SIGN | MASK_INF);
493
  } else {      // y is not special
494
    // check for non-canonical values - treated as zero
495
    if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
496
      // if the steering bits are 11, then the exponent is G[0:w+1]
497
      if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
498
          9999999999999999ull) {
499
        // non-canonical
500
        y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
501
      } // else canonical
502
    }   // else canonical
503
  }
504
 
505
  // NaN (CASE1)
506
  if ((x & MASK_NAN) == MASK_NAN) {     // x is NAN
507
    if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
508
      // if x is SNAN, then return quiet (x)
509
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
510
      x = x & 0xfdffffffffffffffull;    // quietize x
511
      res = x;
512
    } else {    // x is QNaN
513
      if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
514
        if ((y & MASK_SNAN) == MASK_SNAN) {     // y is SNAN
515
          *pfpsf |= INVALID_EXCEPTION;  // set invalid flag
516
        }
517
        res = x;
518
      } else {
519
        res = y;
520
      }
521
    }
522
    BID_RETURN (res);
523
  } else if ((y & MASK_NAN) == MASK_NAN) {      // y is NaN, but x is not
524
    if ((y & MASK_SNAN) == MASK_SNAN) {
525
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
526
      y = y & 0xfdffffffffffffffull;    // quietize y
527
      res = y;
528
    } else {
529
      // will return x (which is not NaN)
530
      res = x;
531
    }
532
    BID_RETURN (res);
533
  }
534
  // SIMPLE (CASE2)
535
  // if all the bits are the same, these numbers are equal (not Greater).
536
  if (x == y) {
537
    res = x;
538
    BID_RETURN (res);
539
  }
540
  // INFINITY (CASE3)
541
  if ((x & MASK_INF) == MASK_INF) {
542
    // if x is neg infinity, there is no way it is greater than y, return y
543
    // x is pos infinity, it is greater, unless y is positive infinity => 
544
    // return y!=pos_infinity
545
    if (((x & MASK_SIGN) == MASK_SIGN)) {
546
      res = y;
547
      BID_RETURN (res);
548
    } else {
549
      res = (((y & MASK_INF) != MASK_INF)
550
             || ((y & MASK_SIGN) == MASK_SIGN)) ? x : y;
551
      BID_RETURN (res);
552
    }
553
  } else if ((y & MASK_INF) == MASK_INF) {
554
    // x is finite, so if y is positive infinity, then x is less, return y
555
    //                 if y is negative infinity, then x is greater, return x
556
    res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
557
    BID_RETURN (res);
558
  }
559
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
560
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
561
    exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
562
    sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
563
  } else {
564
    exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
565
    sig_x = (x & MASK_BINARY_SIG1);
566
  }
567
 
568
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
569
  if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
570
    exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
571
    sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
572
  } else {
573
    exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
574
    sig_y = (y & MASK_BINARY_SIG1);
575
  }
576
 
577
  // ZERO (CASE4)
578
  // some properties:
579
  //    (+ZERO == -ZERO) => therefore 
580
  //        ignore the sign, and neither number is greater
581
  //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => 
582
  //        ignore the exponent field
583
  //    (Any non-canonical # is considered 0)
584
  if (sig_x == 0) {
585
    x_is_zero = 1;
586
  }
587
  if (sig_y == 0) {
588
    y_is_zero = 1;
589
  }
590
 
591
  if (x_is_zero && y_is_zero) {
592
    // if both numbers are zero, neither is greater => return NOTGREATERTHAN
593
    res = y;
594
    BID_RETURN (res);
595
  } else if (x_is_zero) {
596
    // is x is zero, it is greater if Y is negative
597
    res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
598
    BID_RETURN (res);
599
  } else if (y_is_zero) {
600
    // is y is zero, X is greater if it is positive
601
    res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;;
602
    BID_RETURN (res);
603
  }
604
  // OPPOSITE SIGN (CASE5)
605
  // now, if the sign bits differ, x is greater if y is negative
606
  if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
607
    res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
608
    BID_RETURN (res);
609
  }
610
  // REDUNDANT REPRESENTATIONS (CASE6)
611
 
612
  // if both components are either bigger or smaller, 
613
  //     it is clear what needs to be done
614
  if (sig_x > sig_y && exp_x >= exp_y) {
615
    res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;
616
    BID_RETURN (res);
617
  }
618
  if (sig_x < sig_y && exp_x <= exp_y) {
619
    res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
620
    BID_RETURN (res);
621
  }
622
  // if exp_x is 15 greater than exp_y, no need for compensation
623
  if (exp_x - exp_y > 15) {
624
    res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;
625
    // difference cannot be > 10^15
626
    BID_RETURN (res);
627
  }
628
  // if exp_x is 15 less than exp_y, no need for compensation
629
  if (exp_y - exp_x > 15) {
630
    res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
631
    BID_RETURN (res);
632
  }
633
  // if |exp_x - exp_y| < 15, it comes down to the compensated significand
634
  if (exp_x > exp_y) {  // to simplify the loop below,
635
    // otherwise adjust the x significand upwards
636
    __mul_64x64_to_128MACH (sig_n_prime, sig_x,
637
                            mult_factor[exp_x - exp_y]);
638
    // if postitive, return whichever significand is larger 
639
    // (converse if negative)
640
    if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
641
      res = y;
642
      BID_RETURN (res);
643
    }
644
    res = (((sig_n_prime.w[1] > 0)
645
            || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
646
                                            MASK_SIGN)) ? x : y;
647
    BID_RETURN (res);
648
  }
649
  // adjust the y significand upwards
650
  __mul_64x64_to_128MACH (sig_n_prime, sig_y,
651
                          mult_factor[exp_y - exp_x]);
652
 
653
  // if postitive, return whichever significand is larger (converse if negative)
654
  if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
655
    res = y;
656
    BID_RETURN (res);
657
  }
658
  res = (((sig_n_prime.w[1] == 0)
659
          && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
660
                                            MASK_SIGN)) ? x : y;
661
  BID_RETURN (res);
662
}
663
 
664
/*****************************************************************************
665
 *  BID64 maximum magnitude function - returns greater of two numbers
666
 *****************************************************************************/
667
 
668
#if DECIMAL_CALL_BY_REFERENCE
669
void
670
bid64_maxnum_mag (UINT64 * pres, UINT64 * px,
671
                  UINT64 * py _EXC_FLAGS_PARAM) {
672
  UINT64 x = *px;
673
  UINT64 y = *py;
674
#else
675
UINT64
676
bid64_maxnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
677
#endif
678
 
679
  UINT64 res;
680
  int exp_x, exp_y;
681
  UINT64 sig_x, sig_y;
682
  UINT128 sig_n_prime;
683
 
684
  // check for non-canonical x
685
  if ((x & MASK_NAN) == MASK_NAN) {     // x is NaN
686
    x = x & 0xfe03ffffffffffffull;      // clear G6-G12
687
    if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
688
      x = x & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
689
    }
690
  } else if ((x & MASK_INF) == MASK_INF) {      // check for Infinity
691
    x = x & (MASK_SIGN | MASK_INF);
692
  } else {      // x is not special
693
    // check for non-canonical values - treated as zero
694
    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
695
      // if the steering bits are 11, then the exponent is G[0:w+1]
696
      if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
697
          9999999999999999ull) {
698
        // non-canonical
699
        x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
700
      } // else canonical
701
    }   // else canonical 
702
  }
703
 
704
  // check for non-canonical y
705
  if ((y & MASK_NAN) == MASK_NAN) {     // y is NaN
706
    y = y & 0xfe03ffffffffffffull;      // clear G6-G12
707
    if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
708
      y = y & 0xfe00000000000000ull;    // clear G6-G12 and the payload bits
709
    }
710
  } else if ((y & MASK_INF) == MASK_INF) {      // check for Infinity
711
    y = y & (MASK_SIGN | MASK_INF);
712
  } else {      // y is not special
713
    // check for non-canonical values - treated as zero
714
    if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
715
      // if the steering bits are 11, then the exponent is G[0:w+1]
716
      if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
717
          9999999999999999ull) {
718
        // non-canonical
719
        y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
720
      } // else canonical
721
    }   // else canonical
722
  }
723
 
724
  // NaN (CASE1)
725
  if ((x & MASK_NAN) == MASK_NAN) {     // x is NAN
726
    if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
727
      // if x is SNAN, then return quiet (x)
728
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
729
      x = x & 0xfdffffffffffffffull;    // quietize x
730
      res = x;
731
    } else {    // x is QNaN
732
      if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
733
        if ((y & MASK_SNAN) == MASK_SNAN) {     // y is SNAN
734
          *pfpsf |= INVALID_EXCEPTION;  // set invalid flag
735
        }
736
        res = x;
737
      } else {
738
        res = y;
739
      }
740
    }
741
    BID_RETURN (res);
742
  } else if ((y & MASK_NAN) == MASK_NAN) {      // y is NaN, but x is not
743
    if ((y & MASK_SNAN) == MASK_SNAN) {
744
      *pfpsf |= INVALID_EXCEPTION;      // set exception if SNaN
745
      y = y & 0xfdffffffffffffffull;    // quietize y
746
      res = y;
747
    } else {
748
      // will return x (which is not NaN)
749
      res = x;
750
    }
751
    BID_RETURN (res);
752
  }
753
  // SIMPLE (CASE2)
754
  // if all the bits are the same, these numbers are equal, return either number
755
  if (x == y) {
756
    res = x;
757
    BID_RETURN (res);
758
  }
759
  // INFINITY (CASE3)
760
  if ((x & MASK_INF) == MASK_INF) {
761
    // x is infinity, its magnitude is greater than or equal to y
762
    // return y as long as x isn't negative infinity
763
    res = ((x & MASK_SIGN) == MASK_SIGN
764
           && (y & MASK_INF) == MASK_INF) ? y : x;
765
    BID_RETURN (res);
766
  } else if ((y & MASK_INF) == MASK_INF) {
767
    // y is infinity, then it must be greater in magnitude
768
    res = y;
769
    BID_RETURN (res);
770
  }
771
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
772
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
773
    exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
774
    sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
775
  } else {
776
    exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
777
    sig_x = (x & MASK_BINARY_SIG1);
778
  }
779
 
780
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
781
  if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
782
    exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
783
    sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
784
  } else {
785
    exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
786
    sig_y = (y & MASK_BINARY_SIG1);
787
  }
788
 
789
  // ZERO (CASE4)
790
  // some properties:
791
  //    (+ZERO == -ZERO) => therefore 
792
  //        ignore the sign, and neither number is greater
793
  //    (ZERO x 10^A == ZERO x 10^B) for any valid A, B => 
794
  //        ignore the exponent field
795
  //    (Any non-canonical # is considered 0)
796
  if (sig_x == 0) {
797
    res = y;    // x_is_zero, its magnitude must be smaller than y
798
    BID_RETURN (res);
799
  }
800
  if (sig_y == 0) {
801
    res = x;    // y_is_zero, its magnitude must be smaller than x
802
    BID_RETURN (res);
803
  }
804
  // REDUNDANT REPRESENTATIONS (CASE6)
805
  // if both components are either bigger or smaller, 
806
  // it is clear what needs to be done
807
  if (sig_x > sig_y && exp_x >= exp_y) {
808
    res = x;
809
    BID_RETURN (res);
810
  }
811
  if (sig_x < sig_y && exp_x <= exp_y) {
812
    res = y;
813
    BID_RETURN (res);
814
  }
815
  // if exp_x is 15 greater than exp_y, no need for compensation
816
  if (exp_x - exp_y > 15) {
817
    res = x;    // difference cannot be greater than 10^15
818
    BID_RETURN (res);
819
  }
820
  // if exp_x is 15 less than exp_y, no need for compensation
821
  if (exp_y - exp_x > 15) {
822
    res = y;
823
    BID_RETURN (res);
824
  }
825
  // if |exp_x - exp_y| < 15, it comes down to the compensated significand
826
  if (exp_x > exp_y) {  // to simplify the loop below,
827
    // otherwise adjust the x significand upwards
828
    __mul_64x64_to_128MACH (sig_n_prime, sig_x,
829
                            mult_factor[exp_x - exp_y]);
830
    // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y), 
831
    // this is the compensated signif.
832
    if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
833
      // two numbers are equal, return maxNum(x,y)
834
      res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
835
      BID_RETURN (res);
836
    }
837
    // now, if compensated_x (sig_n_prime) is greater than y return y,  
838
    // otherwise return x
839
    res = ((sig_n_prime.w[1] != 0) || sig_n_prime.w[0] > sig_y) ? x : y;
840
    BID_RETURN (res);
841
  }
842
  // exp_y must be greater than exp_x, thus adjust the y significand upwards
843
  __mul_64x64_to_128MACH (sig_n_prime, sig_y,
844
                          mult_factor[exp_y - exp_x]);
845
 
846
  if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
847
    res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
848
    // two numbers are equal, return either
849
    BID_RETURN (res);
850
  }
851
 
852
  res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? x : y;
853
  BID_RETURN (res);
854
}

powered by: WebSVN 2.1.0

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