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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [dfp.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* Decimal floating point support.
2
   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 3, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
#include "config.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tm.h"
25
#include "tree.h"
26
#include "tm_p.h"
27
#include "dfp.h"
28
 
29
/* The order of the following headers is important for making sure
30
   decNumber structure is large enough to hold decimal128 digits.  */
31
 
32
#include "decimal128.h"
33
#include "decimal128Local.h"
34
#include "decimal64.h"
35
#include "decimal32.h"
36
#include "decNumber.h"
37
 
38
#ifndef WORDS_BIGENDIAN
39
#define WORDS_BIGENDIAN 0
40
#endif
41
 
42
/* Initialize R (a real with the decimal flag set) from DN.  Can
43
   utilize status passed in via CONTEXT, if a previous operation had
44
   interesting status.  */
45
 
46
static void
47
decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context)
48
{
49
  memset (r, 0, sizeof (REAL_VALUE_TYPE));
50
 
51
  r->cl = rvc_normal;
52
  if (decNumberIsNaN (dn))
53
    r->cl = rvc_nan;
54
  if (decNumberIsInfinite (dn))
55
    r->cl = rvc_inf;
56
  if (context->status & DEC_Overflow)
57
    r->cl = rvc_inf;
58
  if (decNumberIsNegative (dn))
59
    r->sign = 1;
60
  r->decimal = 1;
61
 
62
  if (r->cl != rvc_normal)
63
    return;
64
 
65
  decContextDefault (context, DEC_INIT_DECIMAL128);
66
  context->traps = 0;
67
 
68
  decimal128FromNumber ((decimal128 *) r->sig, dn, context);
69
}
70
 
71
/* Create decimal encoded R from string S.  */
72
 
73
void
74
decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
75
{
76
  decNumber dn;
77
  decContext set;
78
  decContextDefault (&set, DEC_INIT_DECIMAL128);
79
  set.traps = 0;
80
 
81
  decNumberFromString (&dn, s, &set);
82
 
83
  /* It would be more efficient to store directly in decNumber format,
84
     but that is impractical from current data structure size.
85
     Encoding as a decimal128 is much more compact.  */
86
  decimal_from_decnumber (r, &dn, &set);
87
}
88
 
89
/* Initialize a decNumber from a REAL_VALUE_TYPE.  */
90
 
91
static void
92
decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
93
{
94
  decContext set;
95
  decContextDefault (&set, DEC_INIT_DECIMAL128);
96
  set.traps = 0;
97
 
98
  switch (r->cl)
99
    {
100
    case rvc_zero:
101
      decNumberZero (dn);
102
      break;
103
    case rvc_inf:
104
      decNumberFromString (dn, "Infinity", &set);
105
      break;
106
    case rvc_nan:
107
      if (r->signalling)
108
        decNumberFromString (dn, "snan", &set);
109
      else
110
        decNumberFromString (dn, "nan", &set);
111
      break;
112
    case rvc_normal:
113
      if (!r->decimal)
114
        {
115
          /* dconst{1,2,m1,half} are used in various places in
116
             the middle-end and optimizers, allow them here
117
             as an exception by converting them to decimal.  */
118
          if (memcmp (r, &dconst1, sizeof (*r)) == 0)
119
            {
120
              decNumberFromString (dn, "1", &set);
121
              break;
122
            }
123
          if (memcmp (r, &dconst2, sizeof (*r)) == 0)
124
            {
125
              decNumberFromString (dn, "2", &set);
126
              break;
127
            }
128
          if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
129
            {
130
              decNumberFromString (dn, "-1", &set);
131
              break;
132
            }
133
          if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
134
            {
135
              decNumberFromString (dn, "0.5", &set);
136
              break;
137
            }
138
          gcc_unreachable ();
139
        }
140
      decimal128ToNumber ((const decimal128 *) r->sig, dn);
141
      break;
142
    default:
143
      gcc_unreachable ();
144
    }
145
 
146
  /* Fix up sign bit.  */
147
  if (r->sign != decNumberIsNegative (dn))
148
    dn->bits ^= DECNEG;
149
}
150
 
151
/* Encode a real into an IEEE 754 decimal32 type.  */
152
 
153
void
154
encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
155
                  long *buf, const REAL_VALUE_TYPE *r)
156
{
157
  decNumber dn;
158
  decimal32 d32;
159
  decContext set;
160
  int32_t image;
161
 
162
  decContextDefault (&set, DEC_INIT_DECIMAL128);
163
  set.traps = 0;
164
 
165
  decimal_to_decnumber (r, &dn);
166
  decimal32FromNumber (&d32, &dn, &set);
167
 
168
  memcpy (&image, d32.bytes, sizeof (int32_t));
169
  buf[0] = image;
170
}
171
 
172
/* Decode an IEEE 754 decimal32 type into a real.  */
173
 
174
void
175
decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
176
                  REAL_VALUE_TYPE *r, const long *buf)
177
{
178
  decNumber dn;
179
  decimal32 d32;
180
  decContext set;
181
  int32_t image;
182
 
183
  decContextDefault (&set, DEC_INIT_DECIMAL128);
184
  set.traps = 0;
185
 
186
  image = buf[0];
187
  memcpy (&d32.bytes, &image, sizeof (int32_t));
188
 
189
  decimal32ToNumber (&d32, &dn);
190
  decimal_from_decnumber (r, &dn, &set);
191
}
192
 
193
/* Encode a real into an IEEE 754 decimal64 type.  */
194
 
195
void
196
encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
197
                  long *buf, const REAL_VALUE_TYPE *r)
198
{
199
  decNumber dn;
200
  decimal64 d64;
201
  decContext set;
202
  int32_t image;
203
 
204
  decContextDefault (&set, DEC_INIT_DECIMAL128);
205
  set.traps = 0;
206
 
207
  decimal_to_decnumber (r, &dn);
208
  decimal64FromNumber (&d64, &dn, &set);
209
 
210
  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
211
    {
212
      memcpy (&image, &d64.bytes[0], sizeof (int32_t));
213
      buf[0] = image;
214
      memcpy (&image, &d64.bytes[4], sizeof (int32_t));
215
      buf[1] = image;
216
    }
217
  else
218
    {
219
      memcpy (&image, &d64.bytes[4], sizeof (int32_t));
220
      buf[0] = image;
221
      memcpy (&image, &d64.bytes[0], sizeof (int32_t));
222
      buf[1] = image;
223
    }
224
}
225
 
226
/* Decode an IEEE 754 decimal64 type into a real.  */
227
 
228
void
229
decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
230
                  REAL_VALUE_TYPE *r, const long *buf)
231
{
232
  decNumber dn;
233
  decimal64 d64;
234
  decContext set;
235
  int32_t image;
236
 
237
  decContextDefault (&set, DEC_INIT_DECIMAL128);
238
  set.traps = 0;
239
 
240
  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
241
    {
242
      image = buf[0];
243
      memcpy (&d64.bytes[0], &image, sizeof (int32_t));
244
      image = buf[1];
245
      memcpy (&d64.bytes[4], &image, sizeof (int32_t));
246
    }
247
  else
248
    {
249
      image = buf[1];
250
      memcpy (&d64.bytes[0], &image, sizeof (int32_t));
251
      image = buf[0];
252
      memcpy (&d64.bytes[4], &image, sizeof (int32_t));
253
    }
254
 
255
  decimal64ToNumber (&d64, &dn);
256
  decimal_from_decnumber (r, &dn, &set);
257
}
258
 
259
/* Encode a real into an IEEE 754 decimal128 type.  */
260
 
261
void
262
encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
263
                   long *buf, const REAL_VALUE_TYPE *r)
264
{
265
  decNumber dn;
266
  decContext set;
267
  decimal128 d128;
268
  int32_t image;
269
 
270
  decContextDefault (&set, DEC_INIT_DECIMAL128);
271
  set.traps = 0;
272
 
273
  decimal_to_decnumber (r, &dn);
274
  decimal128FromNumber (&d128, &dn, &set);
275
 
276
  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
277
    {
278
      memcpy (&image, &d128.bytes[0], sizeof (int32_t));
279
      buf[0] = image;
280
      memcpy (&image, &d128.bytes[4], sizeof (int32_t));
281
      buf[1] = image;
282
      memcpy (&image, &d128.bytes[8], sizeof (int32_t));
283
      buf[2] = image;
284
      memcpy (&image, &d128.bytes[12], sizeof (int32_t));
285
      buf[3] = image;
286
    }
287
  else
288
    {
289
      memcpy (&image, &d128.bytes[12], sizeof (int32_t));
290
      buf[0] = image;
291
      memcpy (&image, &d128.bytes[8], sizeof (int32_t));
292
      buf[1] = image;
293
      memcpy (&image, &d128.bytes[4], sizeof (int32_t));
294
      buf[2] = image;
295
      memcpy (&image, &d128.bytes[0], sizeof (int32_t));
296
      buf[3] = image;
297
    }
298
}
299
 
300
/* Decode an IEEE 754 decimal128 type into a real.  */
301
 
302
void
303
decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
304
                   REAL_VALUE_TYPE *r, const long *buf)
305
{
306
  decNumber dn;
307
  decimal128 d128;
308
  decContext set;
309
  int32_t image;
310
 
311
  decContextDefault (&set, DEC_INIT_DECIMAL128);
312
  set.traps = 0;
313
 
314
  if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
315
    {
316
      image = buf[0];
317
      memcpy (&d128.bytes[0],  &image, sizeof (int32_t));
318
      image = buf[1];
319
      memcpy (&d128.bytes[4],  &image, sizeof (int32_t));
320
      image = buf[2];
321
      memcpy (&d128.bytes[8],  &image, sizeof (int32_t));
322
      image = buf[3];
323
      memcpy (&d128.bytes[12], &image, sizeof (int32_t));
324
    }
325
  else
326
    {
327
      image = buf[3];
328
      memcpy (&d128.bytes[0],  &image, sizeof (int32_t));
329
      image = buf[2];
330
      memcpy (&d128.bytes[4],  &image, sizeof (int32_t));
331
      image = buf[1];
332
      memcpy (&d128.bytes[8],  &image, sizeof (int32_t));
333
      image = buf[0];
334
      memcpy (&d128.bytes[12], &image, sizeof (int32_t));
335
    }
336
 
337
  decimal128ToNumber (&d128, &dn);
338
  decimal_from_decnumber (r, &dn, &set);
339
}
340
 
341
/* Helper function to convert from a binary real internal
342
   representation.  */
343
 
344
static void
345
decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
346
                   enum machine_mode mode)
347
{
348
  char string[256];
349
  const decimal128 *const d128 = (const decimal128 *) from->sig;
350
 
351
  decimal128ToString (d128, string);
352
  real_from_string3 (to, string, mode);
353
}
354
 
355
 
356
/* Helper function to convert from a binary real internal
357
   representation.  */
358
 
359
static void
360
decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
361
{
362
  char string[256];
363
 
364
  /* We convert to string, then to decNumber then to decimal128.  */
365
  real_to_decimal (string, from, sizeof (string), 0, 1);
366
  decimal_real_from_string (to, string);
367
}
368
 
369
/* Helper function to real.c:do_compare() to handle decimal internal
370
   representation including when one of the operands is still in the
371
   binary internal representation.  */
372
 
373
int
374
decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
375
                    int nan_result)
376
{
377
  decContext set;
378
  decNumber dn, dn2, dn3;
379
  REAL_VALUE_TYPE a1, b1;
380
 
381
  /* If either operand is non-decimal, create temporary versions.  */
382
  if (!a->decimal)
383
    {
384
      decimal_from_binary (&a1, a);
385
      a = &a1;
386
    }
387
  if (!b->decimal)
388
    {
389
      decimal_from_binary (&b1, b);
390
      b = &b1;
391
    }
392
 
393
  /* Convert into decNumber form for comparison operation.  */
394
  decContextDefault (&set, DEC_INIT_DECIMAL128);
395
  set.traps = 0;
396
  decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
397
  decimal128ToNumber ((const decimal128 *) b->sig, &dn3);
398
 
399
  /* Finally, do the comparison.  */
400
  decNumberCompare (&dn, &dn2, &dn3, &set);
401
 
402
  /* Return the comparison result.  */
403
  if (decNumberIsNaN (&dn))
404
    return nan_result;
405
  else if (decNumberIsZero (&dn))
406
    return 0;
407
  else if (decNumberIsNegative (&dn))
408
    return -1;
409
  else
410
    return 1;
411
}
412
 
413
/* Helper to round_for_format, handling decimal float types.  */
414
 
415
void
416
decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
417
{
418
  decNumber dn;
419
  decContext set;
420
 
421
  /* Real encoding occurs later.  */
422
  if (r->cl != rvc_normal)
423
    return;
424
 
425
  decContextDefault (&set, DEC_INIT_DECIMAL128);
426
  set.traps = 0;
427
  decimal128ToNumber ((decimal128 *) r->sig, &dn);
428
 
429
  if (fmt == &decimal_quad_format)
430
    {
431
      /* The internal format is already in this format.  */
432
      return;
433
    }
434
  else if (fmt == &decimal_single_format)
435
    {
436
      decimal32 d32;
437
      decContextDefault (&set, DEC_INIT_DECIMAL32);
438
      set.traps = 0;
439
 
440
      decimal32FromNumber (&d32, &dn, &set);
441
      decimal32ToNumber (&d32, &dn);
442
    }
443
  else if (fmt == &decimal_double_format)
444
    {
445
      decimal64 d64;
446
      decContextDefault (&set, DEC_INIT_DECIMAL64);
447
      set.traps = 0;
448
 
449
      decimal64FromNumber (&d64, &dn, &set);
450
      decimal64ToNumber (&d64, &dn);
451
    }
452
  else
453
    gcc_unreachable ();
454
 
455
  decimal_from_decnumber (r, &dn, &set);
456
}
457
 
458
/* Extend or truncate to a new mode.  Handles conversions between
459
   binary and decimal types.  */
460
 
461
void
462
decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode,
463
                      const REAL_VALUE_TYPE *a)
464
{
465
  const struct real_format *fmt = REAL_MODE_FORMAT (mode);
466
 
467
  if (a->decimal && fmt->b == 10)
468
    return;
469
  if (a->decimal)
470
      decimal_to_binary (r, a, mode);
471
  else
472
      decimal_from_binary (r, a);
473
}
474
 
475
/* Render R_ORIG as a decimal floating point constant.  Emit DIGITS
476
   significant digits in the result, bounded by BUF_SIZE.  If DIGITS
477
   is 0, choose the maximum for the representation.  If
478
   CROP_TRAILING_ZEROS, strip trailing zeros.  Currently, not honoring
479
   DIGITS or CROP_TRAILING_ZEROS.  */
480
 
481
void
482
decimal_real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig,
483
                         size_t buf_size,
484
                         size_t digits ATTRIBUTE_UNUSED,
485
                         int crop_trailing_zeros ATTRIBUTE_UNUSED)
486
{
487
  const decimal128 *const d128 = (const decimal128*) r_orig->sig;
488
 
489
  /* decimal128ToString requires space for at least 24 characters;
490
     Require two more for suffix.  */
491
  gcc_assert (buf_size >= 24);
492
  decimal128ToString (d128, str);
493
}
494
 
495
static bool
496
decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
497
                const REAL_VALUE_TYPE *op1, int subtract_p)
498
{
499
  decNumber dn;
500
  decContext set;
501
  decNumber dn2, dn3;
502
 
503
  decimal_to_decnumber (op0, &dn2);
504
  decimal_to_decnumber (op1, &dn3);
505
 
506
  decContextDefault (&set, DEC_INIT_DECIMAL128);
507
  set.traps = 0;
508
 
509
  if (subtract_p)
510
    decNumberSubtract (&dn, &dn2, &dn3, &set);
511
  else
512
    decNumberAdd (&dn, &dn2, &dn3, &set);
513
 
514
  decimal_from_decnumber (r, &dn, &set);
515
 
516
  /* Return true, if inexact.  */
517
  return (set.status & DEC_Inexact);
518
}
519
 
520
/* Compute R = OP0 * OP1.  */
521
 
522
static bool
523
decimal_do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
524
                     const REAL_VALUE_TYPE *op1)
525
{
526
  decContext set;
527
  decNumber dn, dn2, dn3;
528
 
529
  decimal_to_decnumber (op0, &dn2);
530
  decimal_to_decnumber (op1, &dn3);
531
 
532
  decContextDefault (&set, DEC_INIT_DECIMAL128);
533
  set.traps = 0;
534
 
535
  decNumberMultiply (&dn, &dn2, &dn3, &set);
536
  decimal_from_decnumber (r, &dn, &set);
537
 
538
  /* Return true, if inexact.  */
539
  return (set.status & DEC_Inexact);
540
}
541
 
542
/* Compute R = OP0 / OP1.  */
543
 
544
static bool
545
decimal_do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
546
                   const REAL_VALUE_TYPE *op1)
547
{
548
  decContext set;
549
  decNumber dn, dn2, dn3;
550
 
551
  decimal_to_decnumber (op0, &dn2);
552
  decimal_to_decnumber (op1, &dn3);
553
 
554
  decContextDefault (&set, DEC_INIT_DECIMAL128);
555
  set.traps = 0;
556
 
557
  decNumberDivide (&dn, &dn2, &dn3, &set);
558
  decimal_from_decnumber (r, &dn, &set);
559
 
560
  /* Return true, if inexact.  */
561
  return (set.status & DEC_Inexact);
562
}
563
 
564
/* Set R to A truncated to an integral value toward zero (decimal
565
   floating point).  */
566
 
567
void
568
decimal_do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
569
{
570
  decNumber dn, dn2;
571
  decContext set;
572
 
573
  decContextDefault (&set, DEC_INIT_DECIMAL128);
574
  set.traps = 0;
575
  set.round = DEC_ROUND_DOWN;
576
  decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
577
 
578
  decNumberToIntegralValue (&dn, &dn2, &set);
579
  decimal_from_decnumber (r, &dn, &set);
580
}
581
 
582
/* Render decimal float value R as an integer.  */
583
 
584
HOST_WIDE_INT
585
decimal_real_to_integer (const REAL_VALUE_TYPE *r)
586
{
587
  decContext set;
588
  decNumber dn, dn2, dn3;
589
  REAL_VALUE_TYPE to;
590
  char string[256];
591
 
592
  decContextDefault (&set, DEC_INIT_DECIMAL128);
593
  set.traps = 0;
594
  set.round = DEC_ROUND_DOWN;
595
  decimal128ToNumber ((const decimal128 *) r->sig, &dn);
596
 
597
  decNumberToIntegralValue (&dn2, &dn, &set);
598
  decNumberZero (&dn3);
599
  decNumberRescale (&dn, &dn2, &dn3, &set);
600
 
601
  /* Convert to REAL_VALUE_TYPE and call appropriate conversion
602
     function.  */
603
  decNumberToString (&dn, string);
604
  real_from_string (&to, string);
605
  return real_to_integer (&to);
606
}
607
 
608
/* Likewise, but to an integer pair, HI+LOW.  */
609
 
610
void
611
decimal_real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
612
                          const REAL_VALUE_TYPE *r)
613
{
614
  decContext set;
615
  decNumber dn, dn2, dn3;
616
  REAL_VALUE_TYPE to;
617
  char string[256];
618
 
619
  decContextDefault (&set, DEC_INIT_DECIMAL128);
620
  set.traps = 0;
621
  set.round = DEC_ROUND_DOWN;
622
  decimal128ToNumber ((const decimal128 *) r->sig, &dn);
623
 
624
  decNumberToIntegralValue (&dn2, &dn, &set);
625
  decNumberZero (&dn3);
626
  decNumberRescale (&dn, &dn2, &dn3, &set);
627
 
628
  /* Convert to REAL_VALUE_TYPE and call appropriate conversion
629
     function.  */
630
  decNumberToString (&dn, string);
631
  real_from_string (&to, string);
632
  real_to_integer2 (plow, phigh, &to);
633
}
634
 
635
/* Perform the decimal floating point operation described by CODE.
636
   For a unary operation, OP1 will be NULL.  This function returns
637
   true if the result may be inexact due to loss of precision.  */
638
 
639
bool
640
decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
641
                         const REAL_VALUE_TYPE *op0,
642
                         const REAL_VALUE_TYPE *op1)
643
{
644
  REAL_VALUE_TYPE a, b;
645
 
646
  /* If either operand is non-decimal, create temporaries.  */
647
  if (!op0->decimal)
648
    {
649
      decimal_from_binary (&a, op0);
650
      op0 = &a;
651
    }
652
  if (op1 && !op1->decimal)
653
    {
654
      decimal_from_binary (&b, op1);
655
      op1 = &b;
656
    }
657
 
658
  switch (code)
659
    {
660
    case PLUS_EXPR:
661
      return decimal_do_add (r, op0, op1, 0);
662
 
663
    case MINUS_EXPR:
664
      return decimal_do_add (r, op0, op1, 1);
665
 
666
    case MULT_EXPR:
667
      return decimal_do_multiply (r, op0, op1);
668
 
669
    case RDIV_EXPR:
670
      return decimal_do_divide (r, op0, op1);
671
 
672
    case MIN_EXPR:
673
      if (op1->cl == rvc_nan)
674
        *r = *op1;
675
      else if (real_compare (UNLT_EXPR, op0, op1))
676
        *r = *op0;
677
      else
678
        *r = *op1;
679
      return false;
680
 
681
    case MAX_EXPR:
682
      if (op1->cl == rvc_nan)
683
        *r = *op1;
684
      else if (real_compare (LT_EXPR, op0, op1))
685
        *r = *op1;
686
      else
687
        *r = *op0;
688
      return false;
689
 
690
    case NEGATE_EXPR:
691
      {
692
        *r = *op0;
693
        /* Flip sign bit.  */
694
        decimal128FlipSign ((decimal128 *) r->sig);
695
        /* Keep sign field in sync.  */
696
        r->sign ^= 1;
697
      }
698
      return false;
699
 
700
    case ABS_EXPR:
701
      {
702
        *r = *op0;
703
        /* Clear sign bit.  */
704
        decimal128ClearSign ((decimal128 *) r->sig);
705
        /* Keep sign field in sync.  */
706
        r->sign = 0;
707
      }
708
      return false;
709
 
710
    case FIX_TRUNC_EXPR:
711
      decimal_do_fix_trunc (r, op0);
712
      return false;
713
 
714
    default:
715
      gcc_unreachable ();
716
    }
717
}
718
 
719
/* Fills R with the largest finite value representable in mode MODE.
720
   If SIGN is nonzero, R is set to the most negative finite value.  */
721
 
722
void
723
decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
724
{
725
  const char *max;
726
 
727
  switch (mode)
728
    {
729
    case SDmode:
730
      max = "9.999999E96";
731
      break;
732
    case DDmode:
733
      max = "9.999999999999999E384";
734
      break;
735
    case TDmode:
736
      max = "9.999999999999999999999999999999999E6144";
737
      break;
738
    default:
739
      gcc_unreachable ();
740
    }
741
 
742
  decimal_real_from_string (r, max);
743
  if (sign)
744
    decimal128SetSign ((decimal128 *) r->sig, 1);
745
}

powered by: WebSVN 2.1.0

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