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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [libbid/] [bid64_noncomp.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
static const UINT64 mult_factor[16] = {
27
  1ull, 10ull, 100ull, 1000ull,
28
  10000ull, 100000ull, 1000000ull, 10000000ull,
29
  100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
30
  1000000000000ull, 10000000000000ull,
31
  100000000000000ull, 1000000000000000ull
32
};
33
 
34
/*****************************************************************************
35
 *    BID64 non-computational functions:
36
 *         - bid64_isSigned
37
 *         - bid64_isNormal
38
 *         - bid64_isSubnormal
39
 *         - bid64_isFinite
40
 *         - bid64_isZero
41
 *         - bid64_isInf
42
 *         - bid64_isSignaling
43
 *         - bid64_isCanonical
44
 *         - bid64_isNaN
45
 *         - bid64_copy
46
 *         - bid64_negate
47
 *         - bid64_abs
48
 *         - bid64_copySign
49
 *         - bid64_class
50
 *         - bid64_sameQuantum
51
 *         - bid64_totalOrder
52
 *         - bid64_totalOrderMag
53
 *         - bid64_radix
54
 ****************************************************************************/
55
 
56
#if DECIMAL_CALL_BY_REFERENCE
57
void
58
bid64_isSigned (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
59
  UINT64 x = *px;
60
#else
61
int
62
bid64_isSigned (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
63
#endif
64
  int res;
65
 
66
  res = ((x & MASK_SIGN) == MASK_SIGN);
67
  BID_RETURN (res);
68
}
69
 
70
// return 1 iff x is not zero, nor NaN nor subnormal nor infinity
71
#if DECIMAL_CALL_BY_REFERENCE
72
void
73
bid64_isNormal (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
74
  UINT64 x = *px;
75
#else
76
int
77
bid64_isNormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
78
#endif
79
  int res;
80
  UINT128 sig_x_prime;
81
  UINT64 sig_x;
82
  unsigned int exp_x;
83
 
84
  if ((x & MASK_INF) == MASK_INF) {     // x is either INF or NaN
85
    res = 0;
86
  } else {
87
    // decode number into exponent and significand
88
    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
89
      sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
90
      // check for zero or non-canonical
91
      if (sig_x > 9999999999999999ull || sig_x == 0) {
92
        res = 0; // zero or non-canonical
93
        BID_RETURN (res);
94
      }
95
      exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
96
    } else {
97
      sig_x = (x & MASK_BINARY_SIG1);
98
      if (sig_x == 0) {
99
        res = 0; // zero
100
        BID_RETURN (res);
101
      }
102
      exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
103
    }
104
    // if exponent is less than -383, the number may be subnormal
105
    // if (exp_x - 398 = -383) the number may be subnormal
106
    if (exp_x < 15) {
107
      __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
108
      if (sig_x_prime.w[1] == 0
109
          && sig_x_prime.w[0] < 1000000000000000ull) {
110
        res = 0; // subnormal
111
      } else {
112
        res = 1;        // normal
113
      }
114
    } else {
115
      res = 1;  // normal
116
    }
117
  }
118
  BID_RETURN (res);
119
}
120
 
121
// return 1 iff x is not zero, nor NaN nor normal nor infinity
122
#if DECIMAL_CALL_BY_REFERENCE
123
void
124
bid64_isSubnormal (int *pres,
125
                   UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
126
  UINT64 x = *px;
127
#else
128
int
129
bid64_isSubnormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
130
#endif
131
  int res;
132
  UINT128 sig_x_prime;
133
  UINT64 sig_x;
134
  unsigned int exp_x;
135
 
136
  if ((x & MASK_INF) == MASK_INF) {     // x is either INF or NaN
137
    res = 0;
138
  } else {
139
    // decode number into exponent and significand
140
    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
141
      sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
142
      // check for zero or non-canonical
143
      if (sig_x > 9999999999999999ull || sig_x == 0) {
144
        res = 0; // zero or non-canonical
145
        BID_RETURN (res);
146
      }
147
      exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
148
    } else {
149
      sig_x = (x & MASK_BINARY_SIG1);
150
      if (sig_x == 0) {
151
        res = 0; // zero
152
        BID_RETURN (res);
153
      }
154
      exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
155
    }
156
    // if exponent is less than -383, the number may be subnormal
157
    // if (exp_x - 398 = -383) the number may be subnormal
158
    if (exp_x < 15) {
159
      __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
160
      if (sig_x_prime.w[1] == 0
161
          && sig_x_prime.w[0] < 1000000000000000ull) {
162
        res = 1;        // subnormal
163
      } else {
164
        res = 0; // normal
165
      }
166
    } else {
167
      res = 0;   // normal
168
    }
169
  }
170
  BID_RETURN (res);
171
}
172
 
173
//iff x is zero, subnormal or normal (not infinity or NaN)
174
#if DECIMAL_CALL_BY_REFERENCE
175
void
176
bid64_isFinite (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
177
  UINT64 x = *px;
178
#else
179
int
180
bid64_isFinite (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
181
#endif
182
  int res;
183
 
184
  res = ((x & MASK_INF) != MASK_INF);
185
  BID_RETURN (res);
186
}
187
 
188
#if DECIMAL_CALL_BY_REFERENCE
189
void
190
bid64_isZero (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
191
  UINT64 x = *px;
192
#else
193
int
194
bid64_isZero (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
195
#endif
196
  int res;
197
 
198
  // if infinity or nan, return 0
199
  if ((x & MASK_INF) == MASK_INF) {
200
    res = 0;
201
  } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
202
    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1]
203
    // => sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
204
    // if(sig_x > 9999999999999999ull) {return 1;}
205
    res =
206
      (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
207
       9999999999999999ull);
208
  } else {
209
    res = ((x & MASK_BINARY_SIG1) == 0);
210
  }
211
  BID_RETURN (res);
212
}
213
 
214
#if DECIMAL_CALL_BY_REFERENCE
215
void
216
bid64_isInf (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
217
  UINT64 x = *px;
218
#else
219
int
220
bid64_isInf (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
221
#endif
222
  int res;
223
 
224
  res = ((x & MASK_INF) == MASK_INF) && ((x & MASK_NAN) != MASK_NAN);
225
  BID_RETURN (res);
226
}
227
 
228
#if DECIMAL_CALL_BY_REFERENCE
229
void
230
bid64_isSignaling (int *pres,
231
                   UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
232
  UINT64 x = *px;
233
#else
234
int
235
bid64_isSignaling (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
236
#endif
237
  int res;
238
 
239
  res = ((x & MASK_SNAN) == MASK_SNAN);
240
  BID_RETURN (res);
241
}
242
 
243
#if DECIMAL_CALL_BY_REFERENCE
244
void
245
bid64_isCanonical (int *pres,
246
                   UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
247
  UINT64 x = *px;
248
#else
249
int
250
bid64_isCanonical (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
251
#endif
252
  int res;
253
 
254
  if ((x & MASK_NAN) == MASK_NAN) {     // NaN
255
    if (x & 0x01fc000000000000ull) {
256
      res = 0;
257
    } else if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {      // payload
258
      res = 0;
259
    } else {
260
      res = 1;
261
    }
262
  } else if ((x & MASK_INF) == MASK_INF) {
263
    if (x & 0x03ffffffffffffffull) {
264
      res = 0;
265
    } else {
266
      res = 1;
267
    }
268
  } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {  // 54-bit coeff.
269
    res =
270
      (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) <=
271
       9999999999999999ull);
272
  } else {      // 53-bit coeff.
273
    res = 1;
274
  }
275
  BID_RETURN (res);
276
}
277
 
278
#if DECIMAL_CALL_BY_REFERENCE
279
void
280
bid64_isNaN (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
281
  UINT64 x = *px;
282
#else
283
int
284
bid64_isNaN (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
285
#endif
286
  int res;
287
 
288
  res = ((x & MASK_NAN) == MASK_NAN);
289
  BID_RETURN (res);
290
}
291
 
292
// copies a floating-point operand x to destination y, with no change
293
#if DECIMAL_CALL_BY_REFERENCE
294
void
295
bid64_copy (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
296
  UINT64 x = *px;
297
#else
298
UINT64
299
bid64_copy (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
300
#endif
301
  UINT64 res;
302
 
303
  res = x;
304
  BID_RETURN (res);
305
}
306
 
307
// copies a floating-point operand x to destination y, reversing the sign
308
#if DECIMAL_CALL_BY_REFERENCE
309
void
310
bid64_negate (UINT64 * pres,
311
              UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
312
  UINT64 x = *px;
313
#else
314
UINT64
315
bid64_negate (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
316
#endif
317
  UINT64 res;
318
 
319
  res = x ^ MASK_SIGN;
320
  BID_RETURN (res);
321
}
322
 
323
// copies a floating-point operand x to destination y, changing the sign to positive
324
#if DECIMAL_CALL_BY_REFERENCE
325
void
326
bid64_abs (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
327
  UINT64 x = *px;
328
#else
329
UINT64
330
bid64_abs (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
331
#endif
332
  UINT64 res;
333
 
334
  res = x & ~MASK_SIGN;
335
  BID_RETURN (res);
336
}
337
 
338
// copies operand x to destination in the same format as x, but 
339
// with the sign of y
340
#if DECIMAL_CALL_BY_REFERENCE
341
void
342
bid64_copySign (UINT64 * pres, UINT64 * px,
343
                UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
344
  UINT64 x = *px;
345
  UINT64 y = *py;
346
#else
347
UINT64
348
bid64_copySign (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
349
#endif
350
  UINT64 res;
351
 
352
  res = (x & ~MASK_SIGN) | (y & MASK_SIGN);
353
  BID_RETURN (res);
354
}
355
 
356
#if DECIMAL_CALL_BY_REFERENCE
357
void
358
bid64_class (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
359
  UINT64 x = *px;
360
#else
361
int
362
bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
363
#endif
364
  int res;
365
  UINT128 sig_x_prime;
366
  UINT64 sig_x;
367
  int exp_x;
368
 
369
  if ((x & MASK_NAN) == MASK_NAN) {
370
    // is the NaN signaling?
371
    if ((x & MASK_SNAN) == MASK_SNAN) {
372
      res = signalingNaN;
373
      BID_RETURN (res);
374
    }
375
    // if NaN and not signaling, must be quietNaN
376
    res = quietNaN;
377
    BID_RETURN (res);
378
  } else if ((x & MASK_INF) == MASK_INF) {
379
    // is the Infinity negative?
380
    if ((x & MASK_SIGN) == MASK_SIGN) {
381
      res = negativeInfinity;
382
    } else {
383
      // otherwise, must be positive infinity
384
      res = positiveInfinity;
385
    }
386
    BID_RETURN (res);
387
  } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
388
    // decode number into exponent and significand
389
    sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
390
    // check for zero or non-canonical
391
    if (sig_x > 9999999999999999ull || sig_x == 0) {
392
      if ((x & MASK_SIGN) == MASK_SIGN) {
393
        res = negativeZero;
394
      } else {
395
        res = positiveZero;
396
      }
397
      BID_RETURN (res);
398
    }
399
    exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
400
  } else {
401
    sig_x = (x & MASK_BINARY_SIG1);
402
    if (sig_x == 0) {
403
      res =
404
        ((x & MASK_SIGN) == MASK_SIGN) ? negativeZero : positiveZero;
405
      BID_RETURN (res);
406
    }
407
    exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
408
  }
409
  // if exponent is less than -383, number may be subnormal
410
  //  if (exp_x - 398 < -383)
411
  if (exp_x < 15) {     // sig_x *10^exp_x
412
    __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
413
    if (sig_x_prime.w[1] == 0
414
        && (sig_x_prime.w[0] < 1000000000000000ull)) {
415
      res =
416
        ((x & MASK_SIGN) ==
417
         MASK_SIGN) ? negativeSubnormal : positiveSubnormal;
418
      BID_RETURN (res);
419
    }
420
  }
421
  // otherwise, normal number, determine the sign
422
  res =
423
    ((x & MASK_SIGN) == MASK_SIGN) ? negativeNormal : positiveNormal;
424
  BID_RETURN (res);
425
}
426
 
427
// true if the exponents of x and y are the same, false otherwise.
428
// The special cases of sameQuantum (NaN, NaN) and sameQuantum (Inf, Inf) are 
429
// true.
430
// If exactly one operand is infinite or exactly one operand is NaN, then false
431
#if DECIMAL_CALL_BY_REFERENCE
432
void
433
bid64_sameQuantum (int *pres, UINT64 * px,
434
                   UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
435
  UINT64 x = *px;
436
  UINT64 y = *py;
437
#else
438
int
439
bid64_sameQuantum (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
440
#endif
441
  int res;
442
  unsigned int exp_x, exp_y;
443
 
444
  // if both operands are NaN, return true; if just one is NaN, return false
445
  if ((x & MASK_NAN) == MASK_NAN || ((y & MASK_NAN) == MASK_NAN)) {
446
    res = ((x & MASK_NAN) == MASK_NAN && (y & MASK_NAN) == MASK_NAN);
447
    BID_RETURN (res);
448
  }
449
  // if both operands are INF, return true; if just one is INF, return false
450
  if ((x & MASK_INF) == MASK_INF || (y & MASK_INF) == MASK_INF) {
451
    res = ((x & MASK_INF) == MASK_INF && (y & MASK_INF) == MASK_INF);
452
    BID_RETURN (res);
453
  }
454
  // decode exponents for both numbers, and return true if they match
455
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
456
    exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
457
  } else {
458
    exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
459
  }
460
  if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
461
    exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
462
  } else {
463
    exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
464
  }
465
  res = (exp_x == exp_y);
466
  BID_RETURN (res);
467
}
468
 
469
#if DECIMAL_CALL_BY_REFERENCE
470
void
471
bid64_totalOrder (int *pres, UINT64 * px,
472
                  UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
473
  UINT64 x = *px;
474
  UINT64 y = *py;
475
#else
476
int
477
bid64_totalOrder (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
478
#endif
479
  int res;
480
  int exp_x, exp_y;
481
  UINT64 sig_x, sig_y, pyld_y, pyld_x;
482
  UINT128 sig_n_prime;
483
  char x_is_zero = 0, y_is_zero = 0;
484
 
485
  // NaN (CASE1)
486
  // if x and y are unordered numerically because either operand is NaN
487
  //    (1) totalOrder(-NaN, number) is true
488
  //    (2) totalOrder(number, +NaN) is true
489
  //    (3) if x and y are both NaN:
490
  //           i) negative sign bit < positive sign bit
491
  //           ii) signaling < quiet for +NaN, reverse for -NaN
492
  //           iii) lesser payload < greater payload for +NaN (reverse for -NaN)
493
  //           iv) else if bitwise identical (in canonical form), return 1
494
  if ((x & MASK_NAN) == MASK_NAN) {
495
    // if x is -NaN
496
    if ((x & MASK_SIGN) == MASK_SIGN) {
497
      // return true, unless y is -NaN also
498
      if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) != MASK_SIGN) {
499
        res = 1;        // y is a number, return 1
500
        BID_RETURN (res);
501
      } else {  // if y and x are both -NaN
502
        // if x and y are both -sNaN or both -qNaN, we have to compare payloads
503
        // this xnor statement evaluates to true if both are sNaN or qNaN
504
        if (!
505
            (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
506
                                               MASK_SNAN))) {
507
          // it comes down to the payload.  we want to return true if x has a
508
          // larger payload, or if the payloads are equal (canonical forms
509
          // are bitwise identical)
510
          pyld_y = y & 0x0003ffffffffffffull;
511
          pyld_x = x & 0x0003ffffffffffffull;
512
          if (pyld_y > 999999999999999ull || pyld_y == 0) {
513
            // if y is zero, x must be less than or numerically equal
514
            // y's payload is 0
515
            res = 1;
516
            BID_RETURN (res);
517
          }
518
          // if x is zero and y isn't, x has the smaller payload
519
          // definitely (since we know y isn't 0 at this point)
520
          if (pyld_x > 999999999999999ull || pyld_x == 0) {
521
            // x's payload is 0
522
            res = 0;
523
            BID_RETURN (res);
524
          }
525
          res = (pyld_x >= pyld_y);
526
          BID_RETURN (res);
527
        } else {
528
          // either x = -sNaN and y = -qNaN or x = -qNaN and y = -sNaN
529
          res = (y & MASK_SNAN) == MASK_SNAN;   // totalOrder(-qNaN, -sNaN) == 1
530
          BID_RETURN (res);
531
        }
532
      }
533
    } else {    // x is +NaN
534
      // return false, unless y is +NaN also
535
      if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) == MASK_SIGN) {
536
        res = 0; // y is a number, return 1
537
        BID_RETURN (res);
538
      } else {
539
        // x and y are both +NaN; 
540
        // must investigate payload if both quiet or both signaling
541
        // this xnor statement will be true if both x and y are +qNaN or +sNaN
542
        if (!
543
            (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
544
                                               MASK_SNAN))) {
545
          // it comes down to the payload.  we want to return true if x has a
546
          // smaller payload, or if the payloads are equal (canonical forms
547
          // are bitwise identical)
548
          pyld_y = y & 0x0003ffffffffffffull;
549
          pyld_x = x & 0x0003ffffffffffffull;
550
          // if x is zero and y isn't, x has the smaller 
551
          // payload definitely (since we know y isn't 0 at this point)
552
          if (pyld_x > 999999999999999ull || pyld_x == 0) {
553
            res = 1;
554
            BID_RETURN (res);
555
          }
556
          if (pyld_y > 999999999999999ull || pyld_y == 0) {
557
            // if y is zero, x must be less than or numerically equal
558
            res = 0;
559
            BID_RETURN (res);
560
          }
561
          res = (pyld_x <= pyld_y);
562
          BID_RETURN (res);
563
        } else {
564
          // return true if y is +qNaN and x is +sNaN 
565
          // (we know they're different bc of xor if_stmt above)
566
          res = ((x & MASK_SNAN) == MASK_SNAN);
567
          BID_RETURN (res);
568
        }
569
      }
570
    }
571
  } else if ((y & MASK_NAN) == MASK_NAN) {
572
    // x is certainly not NAN in this case.
573
    // return true if y is positive
574
    res = ((y & MASK_SIGN) != MASK_SIGN);
575
    BID_RETURN (res);
576
  }
577
  // SIMPLE (CASE2)
578
  // if all the bits are the same, these numbers are equal.
579
  if (x == y) {
580
    res = 1;
581
    BID_RETURN (res);
582
  }
583
  // OPPOSITE SIGNS (CASE 3)
584
  // if signs are opposite, return 1 if x is negative 
585
  // (if x<y, totalOrder is true)
586
  if (((x & MASK_SIGN) == MASK_SIGN) ^ ((y & MASK_SIGN) == MASK_SIGN)) {
587
    res = (x & MASK_SIGN) == MASK_SIGN;
588
    BID_RETURN (res);
589
  }
590
  // INFINITY (CASE4)
591
  if ((x & MASK_INF) == MASK_INF) {
592
    // if x==neg_inf, return (y == neg_inf)?1:0;
593
    if ((x & MASK_SIGN) == MASK_SIGN) {
594
      res = 1;
595
      BID_RETURN (res);
596
    } else {
597
      // x is positive infinity, only return1 if y 
598
      // is positive infinity as well
599
      // (we know y has same sign as x)
600
      res = ((y & MASK_INF) == MASK_INF);
601
      BID_RETURN (res);
602
    }
603
  } else if ((y & MASK_INF) == MASK_INF) {
604
    // x is finite, so:
605
    //    if y is +inf, x<y
606
    //    if y is -inf, x>y
607
    res = ((y & MASK_SIGN) != MASK_SIGN);
608
    BID_RETURN (res);
609
  }
610
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
611
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
612
    exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
613
    sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
614
    if (sig_x > 9999999999999999ull || sig_x == 0) {
615
      x_is_zero = 1;
616
    }
617
  } else {
618
    exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
619
    sig_x = (x & MASK_BINARY_SIG1);
620
    if (sig_x == 0) {
621
      x_is_zero = 1;
622
    }
623
  }
624
 
625
  // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
626
  if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
627
    exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
628
    sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
629
    if (sig_y > 9999999999999999ull || sig_y == 0) {
630
      y_is_zero = 1;
631
    }
632
  } else {
633
    exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
634
    sig_y = (y & MASK_BINARY_SIG1);
635
    if (sig_y == 0) {
636
      y_is_zero = 1;
637
    }
638
  }
639
 
640
  // ZERO (CASE 5)
641
  // if x and y represent the same entities, and 
642
  // both are negative , return true iff exp_x <= exp_y
643
  if (x_is_zero && y_is_zero) {
644
    if (!((x & MASK_SIGN) == MASK_SIGN) ^
645
        ((y & MASK_SIGN) == MASK_SIGN)) {
646
      // if signs are the same:
647
      // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
648
      // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
649
      if (exp_x == exp_y) {
650
        res = 1;
651
        BID_RETURN (res);
652
      }
653
      res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
654
      BID_RETURN (res);
655
    } else {
656
      // signs are different.
657
      // totalOrder(-0, +0) is true
658
      // totalOrder(+0, -0) is false
659
      res = ((x & MASK_SIGN) == MASK_SIGN);
660
      BID_RETURN (res);
661
    }
662
  }
663
  // if x is zero and y isn't, clearly x has the smaller payload.
664
  if (x_is_zero) {
665
    res = ((y & MASK_SIGN) != MASK_SIGN);
666
    BID_RETURN (res);
667
  }
668
  // if y is zero, and x isn't, clearly y has the smaller payload.
669
  if (y_is_zero) {
670
    res = ((x & MASK_SIGN) == MASK_SIGN);
671
    BID_RETURN (res);
672
  }
673
  // REDUNDANT REPRESENTATIONS (CASE6)
674
  // if both components are either bigger or smaller, 
675
  // it is clear what needs to be done
676
  if (sig_x > sig_y && exp_x >= exp_y) {
677
    res = ((x & MASK_SIGN) == MASK_SIGN);
678
    BID_RETURN (res);
679
  }
680
  if (sig_x < sig_y && exp_x <= exp_y) {
681
    res = ((x & MASK_SIGN) != MASK_SIGN);
682
    BID_RETURN (res);
683
  }
684
  // if exp_x is 15 greater than exp_y, it is 
685
  // definitely larger, so no need for compensation
686
  if (exp_x - exp_y > 15) {
687
    // difference cannot be greater than 10^15
688
    res = ((x & MASK_SIGN) == MASK_SIGN);
689
    BID_RETURN (res);
690
  }
691
  // if exp_x is 15 less than exp_y, it is 
692
  // definitely smaller, no need for compensation
693
  if (exp_y - exp_x > 15) {
694
    res = ((x & MASK_SIGN) != MASK_SIGN);
695
    BID_RETURN (res);
696
  }
697
  // if |exp_x - exp_y| < 15, it comes down 
698
  // to the compensated significand
699
  if (exp_x > exp_y) {
700
    // otherwise adjust the x significand upwards
701
    __mul_64x64_to_128MACH (sig_n_prime, sig_x,
702
                            mult_factor[exp_x - exp_y]);
703
    // if x and y represent the same entities, 
704
    // and both are negative, return true iff exp_x <= exp_y
705
    if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
706
      // case cannot occure, because all bits must 
707
      // be the same - would have been caught if (x==y)
708
      res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
709
      BID_RETURN (res);
710
    }
711
    // if positive, return 1 if adjusted x is smaller than y
712
    res = ((sig_n_prime.w[1] == 0)
713
           && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) ==
714
                                           MASK_SIGN);
715
    BID_RETURN (res);
716
  }
717
  // adjust the y significand upwards
718
  __mul_64x64_to_128MACH (sig_n_prime, sig_y,
719
                          mult_factor[exp_y - exp_x]);
720
 
721
  // if x and y represent the same entities, 
722
  // and both are negative, return true iff exp_x <= exp_y
723
  if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
724
    // Cannot occur, because all bits must be the same. 
725
    // Case would have been caught if (x==y)
726
    res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
727
    BID_RETURN (res);
728
  }
729
  // values are not equal, for positive numbers return 1 
730
  // if x is less than y.  0 otherwise
731
  res = ((sig_n_prime.w[1] > 0)
732
         || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
733
                                           MASK_SIGN);
734
  BID_RETURN (res);
735
}
736
 
737
// totalOrderMag is TotalOrder(abs(x), abs(y))
738
#if DECIMAL_CALL_BY_REFERENCE
739
void
740
bid64_totalOrderMag (int *pres, UINT64 * px,
741
                     UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
742
  UINT64 x = *px;
743
  UINT64 y = *py;
744
#else
745
int
746
bid64_totalOrderMag (UINT64 x,
747
                     UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
748
#endif
749
  int res;
750
  int exp_x, exp_y;
751
  UINT64 sig_x, sig_y, pyld_y, pyld_x;
752
  UINT128 sig_n_prime;
753
  char x_is_zero = 0, y_is_zero = 0;
754
 
755
  // NaN (CASE 1)
756
  // if x and y are unordered numerically because either operand is NaN
757
  //    (1) totalOrder(number, +NaN) is true
758
  //    (2) if x and y are both NaN:
759
  //       i) signaling < quiet for +NaN
760
  //       ii) lesser payload < greater payload for +NaN
761
  //       iii) else if bitwise identical (in canonical form), return 1
762
  if ((x & MASK_NAN) == MASK_NAN) {
763
    // x is +NaN
764
 
765
    // return false, unless y is +NaN also
766
    if ((y & MASK_NAN) != MASK_NAN) {
767
      res = 0;   // y is a number, return 1
768
      BID_RETURN (res);
769
 
770
    } else {
771
 
772
      // x and y are both +NaN; 
773
      // must investigate payload if both quiet or both signaling
774
      // this xnor statement will be true if both x and y are +qNaN or +sNaN
775
      if (!
776
          (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
777
                                             MASK_SNAN))) {
778
        // it comes down to the payload.  we want to return true if x has a
779
        // smaller payload, or if the payloads are equal (canonical forms
780
        // are bitwise identical)
781
        pyld_y = y & 0x0003ffffffffffffull;
782
        pyld_x = x & 0x0003ffffffffffffull;
783
        // if x is zero and y isn't, x has the smaller 
784
        // payload definitely (since we know y isn't 0 at this point)
785
        if (pyld_x > 999999999999999ull || pyld_x == 0) {
786
          res = 1;
787
          BID_RETURN (res);
788
        }
789
 
790
        if (pyld_y > 999999999999999ull || pyld_y == 0) {
791
          // if y is zero, x must be less than or numerically equal
792
          res = 0;
793
          BID_RETURN (res);
794
        }
795
        res = (pyld_x <= pyld_y);
796
        BID_RETURN (res);
797
 
798
      } else {
799
        // return true if y is +qNaN and x is +sNaN 
800
        // (we know they're different bc of xor if_stmt above)
801
        res = ((x & MASK_SNAN) == MASK_SNAN);
802
        BID_RETURN (res);
803
      }
804
    }
805
 
806
  } else if ((y & MASK_NAN) == MASK_NAN) {
807
    // x is certainly not NAN in this case.
808
    // return true if y is positive
809
    res = 1;
810
    BID_RETURN (res);
811
  }
812
  // SIMPLE (CASE2)
813
  // if all the bits (except sign bit) are the same, 
814
  // these numbers are equal.
815
  if ((x & ~MASK_SIGN) == (y & ~MASK_SIGN)) {
816
    res = 1;
817
    BID_RETURN (res);
818
  }
819
  // INFINITY (CASE3)
820
  if ((x & MASK_INF) == MASK_INF) {
821
    // x is positive infinity, only return1 
822
    // if y is positive infinity as well
823
    res = ((y & MASK_INF) == MASK_INF);
824
    BID_RETURN (res);
825
  } else if ((y & MASK_INF) == MASK_INF) {
826
    // x is finite, so:
827
    //    if y is +inf, x<y
828
    res = 1;
829
    BID_RETURN (res);
830
  }
831
  // if steering bits are 11 (condition will be 0), 
832
  // then exponent is G[0:w+1] =>
833
  if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
834
    exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
835
    sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
836
    if (sig_x > 9999999999999999ull || sig_x == 0) {
837
      x_is_zero = 1;
838
    }
839
  } else {
840
    exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
841
    sig_x = (x & MASK_BINARY_SIG1);
842
    if (sig_x == 0) {
843
      x_is_zero = 1;
844
    }
845
  }
846
 
847
  // if steering bits are 11 (condition will be 0), 
848
  // then exponent is G[0:w+1] =>
849
  if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
850
    exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
851
    sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
852
    if (sig_y > 9999999999999999ull || sig_y == 0) {
853
      y_is_zero = 1;
854
    }
855
  } else {
856
    exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
857
    sig_y = (y & MASK_BINARY_SIG1);
858
    if (sig_y == 0) {
859
      y_is_zero = 1;
860
    }
861
  }
862
 
863
  // ZERO (CASE 5)
864
  // if x and y represent the same entities, 
865
  // and both are negative , return true iff exp_x <= exp_y
866
  if (x_is_zero && y_is_zero) {
867
    // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
868
    res = (exp_x <= exp_y);
869
    BID_RETURN (res);
870
  }
871
  // if x is zero and y isn't, clearly x has the smaller payload.
872
  if (x_is_zero) {
873
    res = 1;
874
    BID_RETURN (res);
875
  }
876
  // if y is zero, and x isn't, clearly y has the smaller payload.
877
  if (y_is_zero) {
878
    res = 0;
879
    BID_RETURN (res);
880
  }
881
  // REDUNDANT REPRESENTATIONS (CASE6)
882
  // if both components are either bigger or smaller
883
  if (sig_x > sig_y && exp_x >= exp_y) {
884
    res = 0;
885
    BID_RETURN (res);
886
  }
887
  if (sig_x < sig_y && exp_x <= exp_y) {
888
    res = 1;
889
    BID_RETURN (res);
890
  }
891
  // if exp_x is 15 greater than exp_y, it is definitely 
892
  // larger, so no need for compensation
893
  if (exp_x - exp_y > 15) {
894
    res = 0;     // difference cannot be greater than 10^15
895
    BID_RETURN (res);
896
  }
897
  // if exp_x is 15 less than exp_y, it is definitely 
898
  // smaller, no need for compensation
899
  if (exp_y - exp_x > 15) {
900
    res = 1;
901
    BID_RETURN (res);
902
  }
903
  // if |exp_x - exp_y| < 15, it comes down 
904
  // to the compensated significand
905
  if (exp_x > exp_y) {
906
 
907
    // otherwise adjust the x significand upwards
908
    __mul_64x64_to_128MACH (sig_n_prime, sig_x,
909
                            mult_factor[exp_x - exp_y]);
910
 
911
    // if x and y represent the same entities, 
912
    // and both are negative, return true iff exp_x <= exp_y
913
    if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
914
      // case cannot occur, because all bits 
915
      // must be the same - would have been caught if (x==y)
916
      res = (exp_x <= exp_y);
917
      BID_RETURN (res);
918
    }
919
    // if positive, return 1 if adjusted x is smaller than y
920
    res = ((sig_n_prime.w[1] == 0) && sig_n_prime.w[0] < sig_y);
921
    BID_RETURN (res);
922
  }
923
  // adjust the y significand upwards
924
  __mul_64x64_to_128MACH (sig_n_prime, sig_y,
925
                          mult_factor[exp_y - exp_x]);
926
 
927
  // if x and y represent the same entities, 
928
  // and both are negative, return true iff exp_x <= exp_y
929
  if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
930
    res = (exp_x <= exp_y);
931
    BID_RETURN (res);
932
  }
933
  // values are not equal, for positive numbers 
934
  // return 1 if x is less than y.  0 otherwise
935
  res = ((sig_n_prime.w[1] > 0) || (sig_x < sig_n_prime.w[0]));
936
  BID_RETURN (res);
937
 
938
}
939
 
940
#if DECIMAL_CALL_BY_REFERENCE
941
void
942
bid64_radix (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
943
  UINT64 x = *px;
944
#else
945
int
946
bid64_radix (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
947
#endif
948
  int res;
949
  if (x)        // dummy test
950
    res = 10;
951
  else
952
    res = 10;
953
  BID_RETURN (res);
954
}

powered by: WebSVN 2.1.0

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