LCOV - code coverage report
Current view: top level - gcc - dfp.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.8 % 395 331
Test Date: 2026-02-28 14:20:25 Functions: 95.7 % 23 22
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.