LCOV - code coverage report
Current view: top level - gcc - fixed-value.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 8.2 % 536 44
Test Date: 2024-12-21 13:15:12 Functions: 20.0 % 20 4
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Fixed-point arithmetic support.
       2                 :             :    Copyright (C) 2006-2024 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 "diagnostic-core.h"
      26                 :             : 
      27                 :             : /* Compare two fixed objects for bitwise identity.  */
      28                 :             : 
      29                 :             : bool
      30                 :      547746 : fixed_identical (const FIXED_VALUE_TYPE *a, const FIXED_VALUE_TYPE *b)
      31                 :             : {
      32                 :      547746 :   return (a->mode == b->mode
      33                 :      547746 :           && a->data.high == b->data.high
      34                 :     1095468 :           && a->data.low == b->data.low);
      35                 :             : }
      36                 :             : 
      37                 :             : /* Calculate a hash value.  */
      38                 :             : 
      39                 :             : unsigned int
      40                 :    11506082 : fixed_hash (const FIXED_VALUE_TYPE *f)
      41                 :             : {
      42                 :    11506082 :   return (unsigned int) (f->data.low ^ f->data.high);
      43                 :             : }
      44                 :             : 
      45                 :             : /* Define the enum code for the range of the fixed-point value.  */
      46                 :             : enum fixed_value_range_code {
      47                 :             :   FIXED_OK,             /* The value is within the range.  */
      48                 :             :   FIXED_UNDERFLOW,      /* The value is less than the minimum.  */
      49                 :             :   FIXED_GT_MAX_EPS,     /* The value is greater than the maximum, but not equal
      50                 :             :                            to the maximum plus the epsilon.  */
      51                 :             :   FIXED_MAX_EPS         /* The value equals the maximum plus the epsilon.  */
      52                 :             : };
      53                 :             : 
      54                 :             : /* Check REAL_VALUE against the range of the fixed-point mode.
      55                 :             :    Return FIXED_OK, if it is within the range.
      56                 :             :           FIXED_UNDERFLOW, if it is less than the minimum.
      57                 :             :           FIXED_GT_MAX_EPS, if it is greater than the maximum, but not equal to
      58                 :             :             the maximum plus the epsilon.
      59                 :             :           FIXED_MAX_EPS, if it is equal to the maximum plus the epsilon.  */
      60                 :             : 
      61                 :             : static enum fixed_value_range_code
      62                 :          54 : check_real_for_fixed_mode (REAL_VALUE_TYPE *real_value, machine_mode mode)
      63                 :             : {
      64                 :          54 :   REAL_VALUE_TYPE max_value, min_value, epsilon_value;
      65                 :             : 
      66                 :          54 :   real_2expN (&max_value, GET_MODE_IBIT (mode), VOIDmode);
      67                 :          54 :   real_2expN (&epsilon_value, -GET_MODE_FBIT (mode), VOIDmode);
      68                 :             : 
      69                 :          54 :   if (SIGNED_FIXED_POINT_MODE_P (mode))
      70                 :          54 :     min_value = real_value_negate (&max_value);
      71                 :             :   else
      72                 :           0 :     real_from_string (&min_value, "0.0");
      73                 :             : 
      74                 :          54 :   if (real_compare (LT_EXPR, real_value, &min_value))
      75                 :             :     return FIXED_UNDERFLOW;
      76                 :          54 :   if (real_compare (EQ_EXPR, real_value, &max_value))
      77                 :             :     return FIXED_MAX_EPS;
      78                 :          39 :   real_arithmetic (&max_value, MINUS_EXPR, &max_value, &epsilon_value);
      79                 :          39 :   if (real_compare (GT_EXPR, real_value, &max_value))
      80                 :           0 :     return FIXED_GT_MAX_EPS;
      81                 :             :   return FIXED_OK;
      82                 :             : }
      83                 :             : 
      84                 :             : 
      85                 :             : /* Construct a CONST_FIXED from a bit payload and machine mode MODE.
      86                 :             :    The bits in PAYLOAD are sign-extended/zero-extended according to MODE.  */
      87                 :             : 
      88                 :             : FIXED_VALUE_TYPE
      89                 :           0 : fixed_from_double_int (double_int payload, scalar_mode mode)
      90                 :             : {
      91                 :           0 :   FIXED_VALUE_TYPE value;
      92                 :             : 
      93                 :           0 :   gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_DOUBLE_INT);
      94                 :             : 
      95                 :           0 :   if (SIGNED_SCALAR_FIXED_POINT_MODE_P (mode))
      96                 :           0 :     value.data = payload.sext (1 + GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode));
      97                 :           0 :   else if (UNSIGNED_SCALAR_FIXED_POINT_MODE_P (mode))
      98                 :           0 :     value.data = payload.zext (GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode));
      99                 :             :   else
     100                 :           0 :     gcc_unreachable ();
     101                 :             : 
     102                 :           0 :   value.mode = mode;
     103                 :             : 
     104                 :           0 :   return value;
     105                 :             : }
     106                 :             : 
     107                 :             : 
     108                 :             : /* Initialize from a decimal or hexadecimal string.  */
     109                 :             : 
     110                 :             : void
     111                 :          54 : fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, scalar_mode mode)
     112                 :             : {
     113                 :          54 :   REAL_VALUE_TYPE real_value, fixed_value, base_value;
     114                 :          54 :   unsigned int fbit;
     115                 :          54 :   enum fixed_value_range_code temp;
     116                 :          54 :   bool fail;
     117                 :             : 
     118                 :          54 :   f->mode = mode;
     119                 :          54 :   fbit = GET_MODE_FBIT (mode);
     120                 :             : 
     121                 :          54 :   real_from_string (&real_value, str);
     122                 :          54 :   temp = check_real_for_fixed_mode (&real_value, f->mode);
     123                 :             :   /* We don't want to warn the case when the _Fract value is 1.0.  */
     124                 :          54 :   if (temp == FIXED_UNDERFLOW
     125                 :          54 :       || temp == FIXED_GT_MAX_EPS
     126                 :          54 :       || (temp == FIXED_MAX_EPS && ALL_ACCUM_MODE_P (f->mode)))
     127                 :           0 :     warning (OPT_Woverflow,
     128                 :             :              "large fixed-point constant implicitly truncated to fixed-point type");
     129                 :          54 :   real_2expN (&base_value, fbit, VOIDmode);
     130                 :          54 :   real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
     131                 :          54 :   wide_int w = real_to_integer (&fixed_value, &fail,
     132                 :          54 :                                 GET_MODE_PRECISION (mode));
     133                 :          54 :   f->data.low = w.ulow ();
     134                 :          54 :   f->data.high = w.elt (1);
     135                 :             : 
     136                 :          54 :   if (temp == FIXED_MAX_EPS && ALL_FRACT_MODE_P (f->mode))
     137                 :             :     {
     138                 :             :       /* From the spec, we need to evaluate 1 to the maximal value.  */
     139                 :          15 :       f->data.low = -1;
     140                 :          15 :       f->data.high = -1;
     141                 :          15 :       f->data = f->data.zext (GET_MODE_FBIT (f->mode)
     142                 :          15 :                                 + GET_MODE_IBIT (f->mode));
     143                 :             :     }
     144                 :             :   else
     145                 :          39 :     f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode)
     146                 :          39 :                               + GET_MODE_FBIT (f->mode)
     147                 :          39 :                               + GET_MODE_IBIT (f->mode),
     148                 :          39 :                               UNSIGNED_FIXED_POINT_MODE_P (f->mode));
     149                 :          54 : }
     150                 :             : 
     151                 :             : /* Render F as a decimal floating point constant.  */
     152                 :             : 
     153                 :             : void
     154                 :           0 : fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *f_orig,
     155                 :             :                   size_t buf_size)
     156                 :             : {
     157                 :           0 :   REAL_VALUE_TYPE real_value, base_value, fixed_value;
     158                 :             : 
     159                 :           0 :   signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode) ? UNSIGNED : SIGNED;
     160                 :           0 :   real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode), VOIDmode);
     161                 :           0 :   real_from_integer (&real_value, VOIDmode,
     162                 :           0 :                      wide_int::from (f_orig->data,
     163                 :           0 :                                      GET_MODE_PRECISION (f_orig->mode), sgn),
     164                 :             :                      sgn);
     165                 :           0 :   real_arithmetic (&fixed_value, RDIV_EXPR, &real_value, &base_value);
     166                 :           0 :   real_to_decimal (str, &fixed_value, buf_size, 0, 1);
     167                 :           0 : }
     168                 :             : 
     169                 :             : /* If SAT_P, saturate A to the maximum or the minimum, and save to *F based on
     170                 :             :    the machine mode MODE.
     171                 :             :    Do not modify *F otherwise.
     172                 :             :    This function assumes the width of double_int is greater than the width
     173                 :             :    of the fixed-point value (the sum of a possible sign bit, possible ibits,
     174                 :             :    and fbits).
     175                 :             :    Return true, if !SAT_P and overflow.  */
     176                 :             : 
     177                 :             : static bool
     178                 :           0 : fixed_saturate1 (machine_mode mode, double_int a, double_int *f,
     179                 :             :                  bool sat_p)
     180                 :             : {
     181                 :           0 :   bool overflow_p = false;
     182                 :           0 :   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode);
     183                 :           0 :   int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);
     184                 :             : 
     185                 :           0 :   if (unsigned_p) /* Unsigned type.  */
     186                 :             :     {
     187                 :           0 :       double_int max;
     188                 :           0 :       max.low = -1;
     189                 :           0 :       max.high = -1;
     190                 :           0 :       max = max.zext (i_f_bits);
     191                 :           0 :       if (a.ugt (max))
     192                 :             :         {
     193                 :           0 :           if (sat_p)
     194                 :           0 :             *f = max;
     195                 :             :           else
     196                 :             :             overflow_p = true;
     197                 :             :         }
     198                 :             :     }
     199                 :             :   else /* Signed type.  */
     200                 :             :     {
     201                 :           0 :       double_int max, min;
     202                 :           0 :       max.high = -1;
     203                 :           0 :       max.low = -1;
     204                 :           0 :       max = max.zext (i_f_bits);
     205                 :           0 :       min.high = 0;
     206                 :           0 :       min.low = 1;
     207                 :           0 :       min = min.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
     208                 :           0 :       min = min.sext (1 + i_f_bits);
     209                 :           0 :       if (a.sgt (max))
     210                 :             :         {
     211                 :           0 :           if (sat_p)
     212                 :           0 :             *f = max;
     213                 :             :           else
     214                 :             :             overflow_p = true;
     215                 :             :         }
     216                 :           0 :       else if (a.slt (min))
     217                 :             :         {
     218                 :           0 :           if (sat_p)
     219                 :           0 :             *f = min;
     220                 :             :           else
     221                 :             :             overflow_p = true;
     222                 :             :         }
     223                 :             :     }
     224                 :           0 :   return overflow_p;
     225                 :             : }
     226                 :             : 
     227                 :             : /* If SAT_P, saturate {A_HIGH, A_LOW} to the maximum or the minimum, and
     228                 :             :    save to *F based on the machine mode MODE.
     229                 :             :    Do not modify *F otherwise.
     230                 :             :    This function assumes the width of two double_int is greater than the width
     231                 :             :    of the fixed-point value (the sum of a possible sign bit, possible ibits,
     232                 :             :    and fbits).
     233                 :             :    Return true, if !SAT_P and overflow.  */
     234                 :             : 
     235                 :             : static bool
     236                 :           0 : fixed_saturate2 (machine_mode mode, double_int a_high, double_int a_low,
     237                 :             :                  double_int *f, bool sat_p)
     238                 :             : {
     239                 :           0 :   bool overflow_p = false;
     240                 :           0 :   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode);
     241                 :           0 :   int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);
     242                 :             : 
     243                 :           0 :   if (unsigned_p) /* Unsigned type.  */
     244                 :             :     {
     245                 :           0 :       double_int max_r, max_s;
     246                 :           0 :       max_r.high = 0;
     247                 :           0 :       max_r.low = 0;
     248                 :           0 :       max_s.high = -1;
     249                 :           0 :       max_s.low = -1;
     250                 :           0 :       max_s = max_s.zext (i_f_bits);
     251                 :           0 :       if (a_high.ugt (max_r)
     252                 :           0 :           || (a_high == max_r &&
     253                 :           0 :               a_low.ugt (max_s)))
     254                 :             :         {
     255                 :           0 :           if (sat_p)
     256                 :           0 :             *f = max_s;
     257                 :             :           else
     258                 :             :             overflow_p = true;
     259                 :             :         }
     260                 :             :     }
     261                 :             :   else /* Signed type.  */
     262                 :             :     {
     263                 :           0 :       double_int max_r, max_s, min_r, min_s;
     264                 :           0 :       max_r.high = 0;
     265                 :           0 :       max_r.low = 0;
     266                 :           0 :       max_s.high = -1;
     267                 :           0 :       max_s.low = -1;
     268                 :           0 :       max_s = max_s.zext (i_f_bits);
     269                 :           0 :       min_r.high = -1;
     270                 :           0 :       min_r.low = -1;
     271                 :           0 :       min_s.high = 0;
     272                 :           0 :       min_s.low = 1;
     273                 :           0 :       min_s = min_s.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
     274                 :           0 :       min_s = min_s.sext (1 + i_f_bits);
     275                 :           0 :       if (a_high.sgt (max_r)
     276                 :           0 :           || (a_high == max_r &&
     277                 :           0 :               a_low.ugt (max_s)))
     278                 :             :         {
     279                 :           0 :           if (sat_p)
     280                 :           0 :             *f = max_s;
     281                 :             :           else
     282                 :             :             overflow_p = true;
     283                 :             :         }
     284                 :           0 :       else if (a_high.slt (min_r)
     285                 :           0 :                || (a_high == min_r &&
     286                 :           0 :                    a_low.ult (min_s)))
     287                 :             :         {
     288                 :           0 :           if (sat_p)
     289                 :           0 :             *f = min_s;
     290                 :             :           else
     291                 :             :             overflow_p = true;
     292                 :             :         }
     293                 :             :     }
     294                 :           0 :   return overflow_p;
     295                 :             : }
     296                 :             : 
     297                 :             : /* Return the sign bit based on I_F_BITS.  */
     298                 :             : 
     299                 :             : static inline int
     300                 :           0 : get_fixed_sign_bit (double_int a, int i_f_bits)
     301                 :             : {
     302                 :           0 :   if (i_f_bits < HOST_BITS_PER_WIDE_INT)
     303                 :           0 :     return (a.low >> i_f_bits) & 1;
     304                 :             :   else
     305                 :           0 :     return (a.high >> (i_f_bits - HOST_BITS_PER_WIDE_INT)) & 1;
     306                 :             : }
     307                 :             : 
     308                 :             : /* Calculate F = A + (SUBTRACT_P ? -B : B).
     309                 :             :    If SAT_P, saturate the result to the max or the min.
     310                 :             :    Return true, if !SAT_P and overflow.  */
     311                 :             : 
     312                 :             : static bool
     313                 :           0 : do_fixed_add (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
     314                 :             :               const FIXED_VALUE_TYPE *b, bool subtract_p, bool sat_p)
     315                 :             : {
     316                 :           0 :   bool overflow_p = false;
     317                 :           0 :   bool unsigned_p;
     318                 :           0 :   double_int temp;
     319                 :           0 :   int i_f_bits;
     320                 :             : 
     321                 :             :   /* This was a conditional expression but it triggered a bug in
     322                 :             :      Sun C 5.5.  */
     323                 :           0 :   if (subtract_p)
     324                 :           0 :     temp = -b->data;
     325                 :             :   else
     326                 :           0 :     temp = b->data;
     327                 :             : 
     328                 :           0 :   unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
     329                 :           0 :   i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
     330                 :           0 :   f->mode = a->mode;
     331                 :           0 :   f->data = a->data + temp;
     332                 :           0 :   if (unsigned_p) /* Unsigned type.  */
     333                 :             :     {
     334                 :           0 :       if (subtract_p) /* Unsigned subtraction.  */
     335                 :             :         {
     336                 :           0 :           if (a->data.ult (b->data))
     337                 :             :             {
     338                 :           0 :               if (sat_p)
     339                 :             :                 {
     340                 :           0 :                   f->data.high = 0;
     341                 :           0 :                   f->data.low = 0;
     342                 :             :                  }
     343                 :             :               else
     344                 :             :                 overflow_p = true;
     345                 :             :             }
     346                 :             :         }
     347                 :             :       else /* Unsigned addition.  */
     348                 :             :         {
     349                 :           0 :           f->data = f->data.zext (i_f_bits);
     350                 :           0 :           if (f->data.ult (a->data)
     351                 :           0 :               || f->data.ult (b->data))
     352                 :             :             {
     353                 :           0 :               if (sat_p)
     354                 :             :                 {
     355                 :           0 :                   f->data.high = -1;
     356                 :           0 :                   f->data.low = -1;
     357                 :             :                 }
     358                 :             :               else
     359                 :             :                 overflow_p = true;
     360                 :             :             }
     361                 :             :         }
     362                 :             :     }
     363                 :             :   else /* Signed type.  */
     364                 :             :     {
     365                 :           0 :       if ((!subtract_p
     366                 :           0 :            && (get_fixed_sign_bit (a->data, i_f_bits)
     367                 :           0 :                == get_fixed_sign_bit (b->data, i_f_bits))
     368                 :           0 :            && (get_fixed_sign_bit (a->data, i_f_bits)
     369                 :           0 :                != get_fixed_sign_bit (f->data, i_f_bits)))
     370                 :           0 :           || (subtract_p
     371                 :           0 :               && (get_fixed_sign_bit (a->data, i_f_bits)
     372                 :           0 :                   != get_fixed_sign_bit (b->data, i_f_bits))
     373                 :           0 :               && (get_fixed_sign_bit (a->data, i_f_bits)
     374                 :           0 :                   != get_fixed_sign_bit (f->data, i_f_bits))))
     375                 :             :         {
     376                 :           0 :           if (sat_p)
     377                 :             :             {
     378                 :           0 :               f->data.low = 1;
     379                 :           0 :               f->data.high = 0;
     380                 :           0 :               f->data = f->data.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
     381                 :           0 :               if (get_fixed_sign_bit (a->data, i_f_bits) == 0)
     382                 :             :                 {
     383                 :           0 :                   --f->data;
     384                 :             :                 }
     385                 :             :             }
     386                 :             :           else
     387                 :             :             overflow_p = true;
     388                 :             :         }
     389                 :             :     }
     390                 :           0 :   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
     391                 :           0 :   return overflow_p;
     392                 :             : }
     393                 :             : 
     394                 :             : /* Calculate F = A * B.
     395                 :             :    If SAT_P, saturate the result to the max or the min.
     396                 :             :    Return true, if !SAT_P and overflow.  */
     397                 :             : 
     398                 :             : static bool
     399                 :           0 : do_fixed_multiply (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
     400                 :             :                    const FIXED_VALUE_TYPE *b, bool sat_p)
     401                 :             : {
     402                 :           0 :   bool overflow_p = false;
     403                 :           0 :   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
     404                 :           0 :   int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
     405                 :           0 :   f->mode = a->mode;
     406                 :           0 :   if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT)
     407                 :             :     {
     408                 :           0 :       f->data = a->data * b->data;
     409                 :           0 :       f->data = f->data.lshift (-GET_MODE_FBIT (f->mode),
     410                 :           0 :                                 HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
     411                 :           0 :       overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p);
     412                 :             :     }
     413                 :             :   else
     414                 :             :     {
     415                 :             :       /* The result of multiplication expands to two double_int.  */
     416                 :           0 :       double_int a_high, a_low, b_high, b_low;
     417                 :           0 :       double_int high_high, high_low, low_high, low_low;
     418                 :           0 :       double_int r, s, temp1, temp2;
     419                 :           0 :       int carry = 0;
     420                 :             : 
     421                 :             :       /* Decompose a and b to four double_int.  */
     422                 :           0 :       a_high.low = a->data.high;
     423                 :           0 :       a_high.high = 0;
     424                 :           0 :       a_low.low = a->data.low;
     425                 :           0 :       a_low.high = 0;
     426                 :           0 :       b_high.low = b->data.high;
     427                 :           0 :       b_high.high = 0;
     428                 :           0 :       b_low.low = b->data.low;
     429                 :           0 :       b_low.high = 0;
     430                 :             : 
     431                 :             :       /* Perform four multiplications.  */
     432                 :           0 :       low_low = a_low * b_low;
     433                 :           0 :       low_high = a_low * b_high;
     434                 :           0 :       high_low = a_high * b_low;
     435                 :           0 :       high_high = a_high * b_high;
     436                 :             : 
     437                 :             :       /* Accumulate four results to {r, s}.  */
     438                 :           0 :       temp1.high = high_low.low;
     439                 :           0 :       temp1.low = 0;
     440                 :           0 :       s = low_low + temp1;
     441                 :           0 :       if (s.ult (low_low)
     442                 :           0 :           || s.ult (temp1))
     443                 :             :         carry ++; /* Carry */
     444                 :           0 :       temp1.high = s.high;
     445                 :           0 :       temp1.low = s.low;
     446                 :           0 :       temp2.high = low_high.low;
     447                 :           0 :       temp2.low = 0;
     448                 :           0 :       s = temp1 + temp2;
     449                 :           0 :       if (s.ult (temp1)
     450                 :           0 :           || s.ult (temp2))
     451                 :           0 :         carry ++; /* Carry */
     452                 :             : 
     453                 :           0 :       temp1.low = high_low.high;
     454                 :           0 :       temp1.high = 0;
     455                 :           0 :       r = high_high + temp1;
     456                 :           0 :       temp1.low = low_high.high;
     457                 :           0 :       temp1.high = 0;
     458                 :           0 :       r += temp1;
     459                 :           0 :       temp1.low = carry;
     460                 :           0 :       temp1.high = 0;
     461                 :           0 :       r += temp1;
     462                 :             : 
     463                 :             :       /* We need to subtract b from r, if a < 0.  */
     464                 :           0 :       if (!unsigned_p && a->data.high < 0)
     465                 :           0 :         r -= b->data;
     466                 :             :       /* We need to subtract a from r, if b < 0.  */
     467                 :           0 :       if (!unsigned_p && b->data.high < 0)
     468                 :           0 :         r -= a->data;
     469                 :             : 
     470                 :             :       /* Shift right the result by FBIT.  */
     471                 :           0 :       if (GET_MODE_FBIT (f->mode) == HOST_BITS_PER_DOUBLE_INT)
     472                 :             :         {
     473                 :           0 :           s.low = r.low;
     474                 :           0 :           s.high = r.high;
     475                 :           0 :           if (unsigned_p)
     476                 :             :             {
     477                 :           0 :               r.low = 0;
     478                 :           0 :               r.high = 0;
     479                 :             :             }
     480                 :             :           else
     481                 :             :             {
     482                 :           0 :               r.low = -1;
     483                 :           0 :               r.high = -1;
     484                 :             :             }
     485                 :           0 :           f->data.low = s.low;
     486                 :           0 :           f->data.high = s.high;
     487                 :             :         }
     488                 :             :       else
     489                 :             :         {
     490                 :           0 :           s = s.llshift ((-GET_MODE_FBIT (f->mode)), HOST_BITS_PER_DOUBLE_INT);
     491                 :           0 :           f->data = r.llshift ((HOST_BITS_PER_DOUBLE_INT
     492                 :           0 :                           - GET_MODE_FBIT (f->mode)),
     493                 :             :                          HOST_BITS_PER_DOUBLE_INT);
     494                 :           0 :           f->data.low = f->data.low | s.low;
     495                 :           0 :           f->data.high = f->data.high | s.high;
     496                 :           0 :           s.low = f->data.low;
     497                 :           0 :           s.high = f->data.high;
     498                 :           0 :           r = r.lshift (-GET_MODE_FBIT (f->mode),
     499                 :           0 :                         HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
     500                 :             :         }
     501                 :             : 
     502                 :           0 :       overflow_p = fixed_saturate2 (f->mode, r, s, &f->data, sat_p);
     503                 :             :     }
     504                 :             : 
     505                 :           0 :   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
     506                 :           0 :   return overflow_p;
     507                 :             : }
     508                 :             : 
     509                 :             : /* Calculate F = A / B.
     510                 :             :    If SAT_P, saturate the result to the max or the min.
     511                 :             :    Return true, if !SAT_P and overflow.  */
     512                 :             : 
     513                 :             : static bool
     514                 :           0 : do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
     515                 :             :                  const FIXED_VALUE_TYPE *b, bool sat_p)
     516                 :             : {
     517                 :           0 :   bool overflow_p = false;
     518                 :           0 :   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
     519                 :           0 :   int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
     520                 :           0 :   f->mode = a->mode;
     521                 :           0 :   if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT)
     522                 :             :     {
     523                 :           0 :       f->data = a->data.lshift (GET_MODE_FBIT (f->mode),
     524                 :           0 :                                 HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
     525                 :           0 :       f->data = f->data.div (b->data, unsigned_p, TRUNC_DIV_EXPR);
     526                 :           0 :       overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p);
     527                 :             :     }
     528                 :             :   else
     529                 :             :     {
     530                 :           0 :       double_int pos_a, pos_b, r, s;
     531                 :           0 :       double_int quo_r, quo_s, mod, temp;
     532                 :           0 :       int num_of_neg = 0;
     533                 :           0 :       int i;
     534                 :             : 
     535                 :             :       /* If a < 0, negate a.  */
     536                 :           0 :       if (!unsigned_p && a->data.high < 0)
     537                 :             :         {
     538                 :           0 :           pos_a = -a->data;
     539                 :           0 :           num_of_neg ++;
     540                 :             :         }
     541                 :             :       else
     542                 :           0 :         pos_a = a->data;
     543                 :             : 
     544                 :             :       /* If b < 0, negate b.  */
     545                 :           0 :       if (!unsigned_p && b->data.high < 0)
     546                 :             :         {
     547                 :           0 :           pos_b = -b->data;
     548                 :           0 :           num_of_neg ++;
     549                 :             :         }
     550                 :             :       else
     551                 :           0 :         pos_b = b->data;
     552                 :             : 
     553                 :             :       /* Left shift pos_a to {r, s} by FBIT.  */
     554                 :           0 :       if (GET_MODE_FBIT (f->mode) == HOST_BITS_PER_DOUBLE_INT)
     555                 :             :         {
     556                 :           0 :           r = pos_a;
     557                 :           0 :           s.high = 0;
     558                 :           0 :           s.low = 0;
     559                 :             :         }
     560                 :             :       else
     561                 :             :         {
     562                 :           0 :           s = pos_a.llshift (GET_MODE_FBIT (f->mode), HOST_BITS_PER_DOUBLE_INT);
     563                 :           0 :           r = pos_a.llshift (- (HOST_BITS_PER_DOUBLE_INT
     564                 :           0 :                             - GET_MODE_FBIT (f->mode)),
     565                 :             :                          HOST_BITS_PER_DOUBLE_INT);
     566                 :             :         }
     567                 :             : 
     568                 :             :       /* Divide r by pos_b to quo_r.  The remainder is in mod.  */
     569                 :           0 :       quo_r = r.divmod (pos_b, 1, TRUNC_DIV_EXPR, &mod);
     570                 :           0 :       quo_s = double_int_zero;
     571                 :             : 
     572                 :           0 :       for (i = 0; i < HOST_BITS_PER_DOUBLE_INT; i++)
     573                 :             :         {
     574                 :             :           /* Record the leftmost bit of mod.  */
     575                 :           0 :           int leftmost_mod = (mod.high < 0);
     576                 :             : 
     577                 :             :           /* Shift left mod by 1 bit.  */
     578                 :           0 :           mod = mod.lshift (1);
     579                 :             : 
     580                 :             :           /* Test the leftmost bit of s to add to mod.  */
     581                 :           0 :           if (s.high < 0)
     582                 :           0 :             mod.low += 1;
     583                 :             : 
     584                 :             :           /* Shift left quo_s by 1 bit.  */
     585                 :           0 :           quo_s = quo_s.lshift (1);
     586                 :             : 
     587                 :             :           /* Try to calculate (mod - pos_b).  */
     588                 :           0 :           temp = mod - pos_b;
     589                 :             : 
     590                 :           0 :           if (leftmost_mod == 1 || mod.ucmp (pos_b) != -1)
     591                 :             :             {
     592                 :           0 :               quo_s.low += 1;
     593                 :           0 :               mod = temp;
     594                 :             :             }
     595                 :             : 
     596                 :             :           /* Shift left s by 1 bit.  */
     597                 :           0 :           s = s.lshift (1);
     598                 :             : 
     599                 :             :         }
     600                 :             : 
     601                 :           0 :       if (num_of_neg == 1)
     602                 :             :         {
     603                 :           0 :           quo_s = -quo_s;
     604                 :           0 :           if (quo_s.high == 0 && quo_s.low == 0)
     605                 :           0 :             quo_r = -quo_r;
     606                 :             :           else
     607                 :             :             {
     608                 :           0 :               quo_r.low = ~quo_r.low;
     609                 :           0 :               quo_r.high = ~quo_r.high;
     610                 :             :             }
     611                 :             :         }
     612                 :             : 
     613                 :           0 :       f->data = quo_s;
     614                 :           0 :       overflow_p = fixed_saturate2 (f->mode, quo_r, quo_s, &f->data, sat_p);
     615                 :             :     }
     616                 :             : 
     617                 :           0 :   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
     618                 :           0 :   return overflow_p;
     619                 :             : }
     620                 :             : 
     621                 :             : /* Calculate F = A << B if LEFT_P.  Otherwise, F = A >> B.
     622                 :             :    If SAT_P, saturate the result to the max or the min.
     623                 :             :    Return true, if !SAT_P and overflow.  */
     624                 :             : 
     625                 :             : static bool
     626                 :           0 : do_fixed_shift (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
     627                 :             :               const FIXED_VALUE_TYPE *b, bool left_p, bool sat_p)
     628                 :             : {
     629                 :           0 :   bool overflow_p = false;
     630                 :           0 :   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
     631                 :           0 :   int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
     632                 :           0 :   f->mode = a->mode;
     633                 :             : 
     634                 :           0 :   if (b->data.low == 0)
     635                 :             :     {
     636                 :           0 :       f->data = a->data;
     637                 :           0 :       return overflow_p;
     638                 :             :     }
     639                 :             : 
     640                 :           0 :   if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT || (!left_p))
     641                 :             :     {
     642                 :           0 :       f->data = a->data.lshift (left_p ? b->data.low : -b->data.low,
     643                 :           0 :                                 HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
     644                 :           0 :       if (left_p) /* Only left shift saturates.  */
     645                 :           0 :         overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p);
     646                 :             :     }
     647                 :             :   else /* We need two double_int to store the left-shift result.  */
     648                 :             :     {
     649                 :           0 :       double_int temp_high, temp_low;
     650                 :           0 :       if (b->data.low == HOST_BITS_PER_DOUBLE_INT)
     651                 :             :         {
     652                 :           0 :           temp_high = a->data;
     653                 :           0 :           temp_low.high = 0;
     654                 :           0 :           temp_low.low = 0;
     655                 :             :         }
     656                 :             :       else
     657                 :             :         {
     658                 :           0 :           temp_low = a->data.lshift (b->data.low,
     659                 :           0 :                                      HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
     660                 :             :           /* Logical shift right to temp_high.  */
     661                 :           0 :           temp_high = a->data.llshift (b->data.low - HOST_BITS_PER_DOUBLE_INT,
     662                 :             :                          HOST_BITS_PER_DOUBLE_INT);
     663                 :             :         }
     664                 :           0 :       if (!unsigned_p && a->data.high < 0) /* Signed-extend temp_high.  */
     665                 :           0 :         temp_high = temp_high.ext (b->data.low, unsigned_p);
     666                 :           0 :       f->data = temp_low;
     667                 :           0 :       overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, &f->data,
     668                 :             :                                     sat_p);
     669                 :             :     }
     670                 :           0 :   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
     671                 :           0 :   return overflow_p;
     672                 :             : }
     673                 :             : 
     674                 :             : /* Calculate F = -A.
     675                 :             :    If SAT_P, saturate the result to the max or the min.
     676                 :             :    Return true, if !SAT_P and overflow.  */
     677                 :             : 
     678                 :             : static bool
     679                 :           0 : do_fixed_neg (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, bool sat_p)
     680                 :             : {
     681                 :           0 :   bool overflow_p = false;
     682                 :           0 :   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
     683                 :           0 :   int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
     684                 :           0 :   f->mode = a->mode;
     685                 :           0 :   f->data = -a->data;
     686                 :           0 :   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
     687                 :             : 
     688                 :           0 :   if (unsigned_p) /* Unsigned type.  */
     689                 :             :     {
     690                 :           0 :       if (f->data.low != 0 || f->data.high != 0)
     691                 :             :         {
     692                 :           0 :           if (sat_p)
     693                 :             :             {
     694                 :           0 :               f->data.low = 0;
     695                 :           0 :               f->data.high = 0;
     696                 :             :             }
     697                 :             :           else
     698                 :             :             overflow_p = true;
     699                 :             :         }
     700                 :             :     }
     701                 :             :   else /* Signed type.  */
     702                 :             :     {
     703                 :           0 :       if (!(f->data.high == 0 && f->data.low == 0)
     704                 :           0 :           && f->data.high == a->data.high && f->data.low == a->data.low )
     705                 :             :         {
     706                 :           0 :           if (sat_p)
     707                 :             :             {
     708                 :             :               /* Saturate to the maximum by subtracting f->data by one.  */
     709                 :           0 :               f->data.low = -1;
     710                 :           0 :               f->data.high = -1;
     711                 :           0 :               f->data = f->data.zext (i_f_bits);
     712                 :             :             }
     713                 :             :           else
     714                 :             :             overflow_p = true;
     715                 :             :         }
     716                 :             :     }
     717                 :           0 :   return overflow_p;
     718                 :             : }
     719                 :             : 
     720                 :             : /* Perform the binary or unary operation described by CODE.
     721                 :             :    Note that OP0 and OP1 must have the same mode for binary operators.
     722                 :             :    For a unary operation, leave OP1 NULL.
     723                 :             :    Return true, if !SAT_P and overflow.  */
     724                 :             : 
     725                 :             : bool
     726                 :           0 : fixed_arithmetic (FIXED_VALUE_TYPE *f, int icode, const FIXED_VALUE_TYPE *op0,
     727                 :             :                   const FIXED_VALUE_TYPE *op1, bool sat_p)
     728                 :             : {
     729                 :           0 :   switch (icode)
     730                 :             :     {
     731                 :           0 :     case NEGATE_EXPR:
     732                 :           0 :       return do_fixed_neg (f, op0, sat_p);
     733                 :             : 
     734                 :           0 :     case PLUS_EXPR:
     735                 :           0 :       gcc_assert (op0->mode == op1->mode);
     736                 :           0 :       return do_fixed_add (f, op0, op1, false, sat_p);
     737                 :             : 
     738                 :           0 :     case MINUS_EXPR:
     739                 :           0 :       gcc_assert (op0->mode == op1->mode);
     740                 :           0 :       return do_fixed_add (f, op0, op1, true, sat_p);
     741                 :             : 
     742                 :           0 :     case MULT_EXPR:
     743                 :           0 :       gcc_assert (op0->mode == op1->mode);
     744                 :           0 :       return do_fixed_multiply (f, op0, op1, sat_p);
     745                 :             : 
     746                 :           0 :     case TRUNC_DIV_EXPR:
     747                 :           0 :       gcc_assert (op0->mode == op1->mode);
     748                 :           0 :       return do_fixed_divide (f, op0, op1, sat_p);
     749                 :             : 
     750                 :           0 :     case LSHIFT_EXPR:
     751                 :           0 :       return do_fixed_shift (f, op0, op1, true, sat_p);
     752                 :             : 
     753                 :           0 :     case RSHIFT_EXPR:
     754                 :           0 :       return do_fixed_shift (f, op0, op1, false, sat_p);
     755                 :             : 
     756                 :           0 :     default:
     757                 :           0 :       gcc_unreachable ();
     758                 :             :     }
     759                 :             : }
     760                 :             : 
     761                 :             : /* Compare fixed-point values by tree_code.
     762                 :             :    Note that OP0 and OP1 must have the same mode.  */
     763                 :             : 
     764                 :             : bool
     765                 :           0 : fixed_compare (int icode, const FIXED_VALUE_TYPE *op0,
     766                 :             :                const FIXED_VALUE_TYPE *op1)
     767                 :             : {
     768                 :           0 :   enum tree_code code = (enum tree_code) icode;
     769                 :           0 :   gcc_assert (op0->mode == op1->mode);
     770                 :             : 
     771                 :           0 :   switch (code)
     772                 :             :     {
     773                 :           0 :     case NE_EXPR:
     774                 :           0 :       return op0->data != op1->data;
     775                 :             : 
     776                 :           0 :     case EQ_EXPR:
     777                 :           0 :       return op0->data == op1->data;
     778                 :             : 
     779                 :           0 :     case LT_EXPR:
     780                 :           0 :       return op0->data.cmp (op1->data,
     781                 :           0 :                              UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) == -1;
     782                 :             : 
     783                 :           0 :     case LE_EXPR:
     784                 :           0 :       return op0->data.cmp (op1->data,
     785                 :           0 :                              UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) != 1;
     786                 :             : 
     787                 :           0 :     case GT_EXPR:
     788                 :           0 :       return op0->data.cmp (op1->data,
     789                 :           0 :                              UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) == 1;
     790                 :             : 
     791                 :           0 :     case GE_EXPR:
     792                 :           0 :       return op0->data.cmp (op1->data,
     793                 :           0 :                              UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) != -1;
     794                 :             : 
     795                 :           0 :     default:
     796                 :           0 :       gcc_unreachable ();
     797                 :             :     }
     798                 :             : }
     799                 :             : 
     800                 :             : /* Extend or truncate to a new mode.
     801                 :             :    If SAT_P, saturate the result to the max or the min.
     802                 :             :    Return true, if !SAT_P and overflow.  */
     803                 :             : 
     804                 :             : bool
     805                 :           0 : fixed_convert (FIXED_VALUE_TYPE *f, scalar_mode mode,
     806                 :             :                const FIXED_VALUE_TYPE *a, bool sat_p)
     807                 :             : {
     808                 :           0 :   bool overflow_p = false;
     809                 :           0 :   if (mode == a->mode)
     810                 :             :     {
     811                 :           0 :       *f = *a;
     812                 :           0 :       return overflow_p;
     813                 :             :     }
     814                 :             : 
     815                 :           0 :   if (GET_MODE_FBIT (mode) > GET_MODE_FBIT (a->mode))
     816                 :             :     {
     817                 :             :       /* Left shift a to temp_high, temp_low based on a->mode.  */
     818                 :           0 :       double_int temp_high, temp_low;
     819                 :           0 :       int amount = GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode);
     820                 :           0 :       temp_low = a->data.lshift (amount,
     821                 :             :                                  HOST_BITS_PER_DOUBLE_INT,
     822                 :           0 :                                  SIGNED_FIXED_POINT_MODE_P (a->mode));
     823                 :             :       /* Logical shift right to temp_high.  */
     824                 :           0 :       temp_high = a->data.llshift (amount - HOST_BITS_PER_DOUBLE_INT,
     825                 :             :                      HOST_BITS_PER_DOUBLE_INT);
     826                 :           0 :       if (SIGNED_FIXED_POINT_MODE_P (a->mode)
     827                 :           0 :           && a->data.high < 0) /* Signed-extend temp_high.  */
     828                 :           0 :         temp_high = temp_high.sext (amount);
     829                 :           0 :       f->mode = mode;
     830                 :           0 :       f->data = temp_low;
     831                 :           0 :       if (SIGNED_FIXED_POINT_MODE_P (a->mode) ==
     832                 :           0 :           SIGNED_FIXED_POINT_MODE_P (f->mode))
     833                 :           0 :         overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, &f->data,
     834                 :             :                                       sat_p);
     835                 :             :       else
     836                 :             :         {
     837                 :             :           /* Take care of the cases when converting between signed and
     838                 :             :              unsigned.  */
     839                 :           0 :           if (SIGNED_FIXED_POINT_MODE_P (a->mode))
     840                 :             :             {
     841                 :             :               /* Signed -> Unsigned.  */
     842                 :           0 :               if (a->data.high < 0)
     843                 :             :                 {
     844                 :           0 :                   if (sat_p)
     845                 :             :                     {
     846                 :           0 :                       f->data.low = 0;  /* Set to zero.  */
     847                 :           0 :                       f->data.high = 0;  /* Set to zero.  */
     848                 :             :                     }
     849                 :             :                   else
     850                 :             :                     overflow_p = true;
     851                 :             :                 }
     852                 :             :               else
     853                 :           0 :                 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low,
     854                 :             :                                               &f->data, sat_p);
     855                 :             :             }
     856                 :             :           else
     857                 :             :             {
     858                 :             :               /* Unsigned -> Signed.  */
     859                 :           0 :               if (temp_high.high < 0)
     860                 :             :                 {
     861                 :           0 :                   if (sat_p)
     862                 :             :                     {
     863                 :             :                       /* Set to maximum.  */
     864                 :           0 :                       f->data.low = -1;  /* Set to all ones.  */
     865                 :           0 :                       f->data.high = -1;  /* Set to all ones.  */
     866                 :           0 :                       f->data = f->data.zext (GET_MODE_FBIT (f->mode)
     867                 :           0 :                                                 + GET_MODE_IBIT (f->mode));
     868                 :             :                                                 /* Clear the sign.  */
     869                 :             :                     }
     870                 :             :                   else
     871                 :             :                     overflow_p = true;
     872                 :             :                 }
     873                 :             :               else
     874                 :           0 :                 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low,
     875                 :             :                                               &f->data, sat_p);
     876                 :             :             }
     877                 :             :         }
     878                 :             :     }
     879                 :             :   else
     880                 :             :     {
     881                 :             :       /* Right shift a to temp based on a->mode.  */
     882                 :           0 :       double_int temp;
     883                 :           0 :       temp = a->data.lshift (GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode),
     884                 :             :                              HOST_BITS_PER_DOUBLE_INT,
     885                 :           0 :                              SIGNED_FIXED_POINT_MODE_P (a->mode));
     886                 :           0 :       f->mode = mode;
     887                 :           0 :       f->data = temp;
     888                 :           0 :       if (SIGNED_FIXED_POINT_MODE_P (a->mode) ==
     889                 :           0 :           SIGNED_FIXED_POINT_MODE_P (f->mode))
     890                 :           0 :         overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p);
     891                 :             :       else
     892                 :             :         {
     893                 :             :           /* Take care of the cases when converting between signed and
     894                 :             :              unsigned.  */
     895                 :           0 :           if (SIGNED_FIXED_POINT_MODE_P (a->mode))
     896                 :             :             {
     897                 :             :               /* Signed -> Unsigned.  */
     898                 :           0 :               if (a->data.high < 0)
     899                 :             :                 {
     900                 :           0 :                   if (sat_p)
     901                 :             :                     {
     902                 :           0 :                       f->data.low = 0;  /* Set to zero.  */
     903                 :           0 :                       f->data.high = 0;  /* Set to zero.  */
     904                 :             :                     }
     905                 :             :                   else
     906                 :             :                     overflow_p = true;
     907                 :             :                 }
     908                 :             :               else
     909                 :           0 :                 overflow_p = fixed_saturate1 (f->mode, f->data, &f->data,
     910                 :             :                                               sat_p);
     911                 :             :             }
     912                 :             :           else
     913                 :             :             {
     914                 :             :               /* Unsigned -> Signed.  */
     915                 :           0 :               if (temp.high < 0)
     916                 :             :                 {
     917                 :           0 :                   if (sat_p)
     918                 :             :                     {
     919                 :             :                       /* Set to maximum.  */
     920                 :           0 :                       f->data.low = -1;  /* Set to all ones.  */
     921                 :           0 :                       f->data.high = -1;  /* Set to all ones.  */
     922                 :           0 :                       f->data = f->data.zext (GET_MODE_FBIT (f->mode)
     923                 :           0 :                                                 + GET_MODE_IBIT (f->mode));
     924                 :             :                                                 /* Clear the sign.  */
     925                 :             :                     }
     926                 :             :                   else
     927                 :             :                     overflow_p = true;
     928                 :             :                 }
     929                 :             :               else
     930                 :           0 :                 overflow_p = fixed_saturate1 (f->mode, f->data, &f->data,
     931                 :             :                                               sat_p);
     932                 :             :             }
     933                 :             :         }
     934                 :             :     }
     935                 :             : 
     936                 :           0 :   f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode)
     937                 :           0 :                             + GET_MODE_FBIT (f->mode)
     938                 :           0 :                             + GET_MODE_IBIT (f->mode),
     939                 :           0 :                             UNSIGNED_FIXED_POINT_MODE_P (f->mode));
     940                 :           0 :   return overflow_p;
     941                 :             : }
     942                 :             : 
     943                 :             : /* Convert to a new fixed-point mode from an integer.
     944                 :             :    If UNSIGNED_P, this integer is unsigned.
     945                 :             :    If SAT_P, saturate the result to the max or the min.
     946                 :             :    Return true, if !SAT_P and overflow.  */
     947                 :             : 
     948                 :             : bool
     949                 :           0 : fixed_convert_from_int (FIXED_VALUE_TYPE *f, scalar_mode mode,
     950                 :             :                         double_int a, bool unsigned_p, bool sat_p)
     951                 :             : {
     952                 :           0 :   bool overflow_p = false;
     953                 :             :   /* Left shift a to temp_high, temp_low.  */
     954                 :           0 :   double_int temp_high, temp_low;
     955                 :           0 :   int amount = GET_MODE_FBIT (mode);
     956                 :           0 :   if (amount == HOST_BITS_PER_DOUBLE_INT)
     957                 :             :     {
     958                 :           0 :        temp_high = a;
     959                 :           0 :        temp_low.low = 0;
     960                 :           0 :        temp_low.high = 0;
     961                 :             :     }
     962                 :             :   else
     963                 :             :     {
     964                 :           0 :       temp_low = a.llshift (amount, HOST_BITS_PER_DOUBLE_INT);
     965                 :             : 
     966                 :             :       /* Logical shift right to temp_high.  */
     967                 :           0 :       temp_high = a.llshift (amount - HOST_BITS_PER_DOUBLE_INT,
     968                 :             :                      HOST_BITS_PER_DOUBLE_INT);
     969                 :             :     }
     970                 :           0 :   if (!unsigned_p && a.high < 0) /* Signed-extend temp_high.  */
     971                 :           0 :     temp_high = temp_high.sext (amount);
     972                 :             : 
     973                 :           0 :   f->mode = mode;
     974                 :           0 :   f->data = temp_low;
     975                 :             : 
     976                 :           0 :   if (unsigned_p == UNSIGNED_FIXED_POINT_MODE_P (f->mode))
     977                 :           0 :     overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, &f->data,
     978                 :             :                                   sat_p);
     979                 :             :   else
     980                 :             :     {
     981                 :             :       /* Take care of the cases when converting between signed and unsigned.  */
     982                 :           0 :       if (!unsigned_p)
     983                 :             :         {
     984                 :             :           /* Signed -> Unsigned.  */
     985                 :           0 :           if (a.high < 0)
     986                 :             :             {
     987                 :           0 :               if (sat_p)
     988                 :             :                 {
     989                 :           0 :                   f->data.low = 0;  /* Set to zero.  */
     990                 :           0 :                   f->data.high = 0;  /* Set to zero.  */
     991                 :             :                 }
     992                 :             :               else
     993                 :             :                 overflow_p = true;
     994                 :             :             }
     995                 :             :           else
     996                 :           0 :             overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low,
     997                 :             :                                           &f->data, sat_p);
     998                 :             :         }
     999                 :             :       else
    1000                 :             :         {
    1001                 :             :           /* Unsigned -> Signed.  */
    1002                 :           0 :           if (temp_high.high < 0)
    1003                 :             :             {
    1004                 :           0 :               if (sat_p)
    1005                 :             :                 {
    1006                 :             :                   /* Set to maximum.  */
    1007                 :           0 :                   f->data.low = -1;  /* Set to all ones.  */
    1008                 :           0 :                   f->data.high = -1;  /* Set to all ones.  */
    1009                 :           0 :                   f->data = f->data.zext (GET_MODE_FBIT (f->mode)
    1010                 :           0 :                                             + GET_MODE_IBIT (f->mode));
    1011                 :             :                                             /* Clear the sign.  */
    1012                 :             :                 }
    1013                 :             :               else
    1014                 :             :                 overflow_p = true;
    1015                 :             :             }
    1016                 :             :           else
    1017                 :           0 :             overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low,
    1018                 :             :                                           &f->data, sat_p);
    1019                 :             :         }
    1020                 :             :     }
    1021                 :           0 :   f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode)
    1022                 :           0 :                             + GET_MODE_FBIT (f->mode)
    1023                 :           0 :                             + GET_MODE_IBIT (f->mode),
    1024                 :           0 :                             UNSIGNED_FIXED_POINT_MODE_P (f->mode));
    1025                 :           0 :   return overflow_p;
    1026                 :             : }
    1027                 :             : 
    1028                 :             : /* Convert to a new fixed-point mode from a real.
    1029                 :             :    If SAT_P, saturate the result to the max or the min.
    1030                 :             :    Return true, if !SAT_P and overflow.  */
    1031                 :             : 
    1032                 :             : bool
    1033                 :           0 : fixed_convert_from_real (FIXED_VALUE_TYPE *f, scalar_mode mode,
    1034                 :             :                          const REAL_VALUE_TYPE *a, bool sat_p)
    1035                 :             : {
    1036                 :           0 :   bool overflow_p = false;
    1037                 :           0 :   REAL_VALUE_TYPE real_value, fixed_value, base_value;
    1038                 :           0 :   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode);
    1039                 :           0 :   int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);
    1040                 :           0 :   unsigned int fbit = GET_MODE_FBIT (mode);
    1041                 :           0 :   enum fixed_value_range_code temp;
    1042                 :           0 :   bool fail;
    1043                 :             : 
    1044                 :           0 :   real_value = *a;
    1045                 :           0 :   f->mode = mode;
    1046                 :           0 :   real_2expN (&base_value, fbit, VOIDmode);
    1047                 :           0 :   real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
    1048                 :             : 
    1049                 :           0 :   wide_int w = real_to_integer (&fixed_value, &fail,
    1050                 :           0 :                                 GET_MODE_PRECISION (mode));
    1051                 :           0 :   f->data.low = w.ulow ();
    1052                 :           0 :   f->data.high = w.elt (1);
    1053                 :           0 :   temp = check_real_for_fixed_mode (&real_value, mode);
    1054                 :           0 :   if (temp == FIXED_UNDERFLOW) /* Minimum.  */
    1055                 :             :     {
    1056                 :           0 :       if (sat_p)
    1057                 :             :         {
    1058                 :           0 :           if (unsigned_p)
    1059                 :             :             {
    1060                 :           0 :               f->data.low = 0;
    1061                 :           0 :               f->data.high = 0;
    1062                 :             :             }
    1063                 :             :           else
    1064                 :             :             {
    1065                 :           0 :               f->data.low = 1;
    1066                 :           0 :               f->data.high = 0;
    1067                 :           0 :               f->data = f->data.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
    1068                 :           0 :               f->data = f->data.sext (1 + i_f_bits);
    1069                 :             :             }
    1070                 :             :         }
    1071                 :             :       else
    1072                 :             :         overflow_p = true;
    1073                 :             :     }
    1074                 :           0 :   else if (temp == FIXED_GT_MAX_EPS || temp == FIXED_MAX_EPS) /* Maximum.  */
    1075                 :             :     {
    1076                 :           0 :       if (sat_p)
    1077                 :             :         {
    1078                 :           0 :           f->data.low = -1;
    1079                 :           0 :           f->data.high = -1;
    1080                 :           0 :           f->data = f->data.zext (i_f_bits);
    1081                 :             :         }
    1082                 :             :       else
    1083                 :             :         overflow_p = true;
    1084                 :             :     }
    1085                 :           0 :   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
    1086                 :           0 :   return overflow_p;
    1087                 :           0 : }
    1088                 :             : 
    1089                 :             : /* Convert to a new real mode from a fixed-point.  */
    1090                 :             : 
    1091                 :             : void
    1092                 :           0 : real_convert_from_fixed (REAL_VALUE_TYPE *r, scalar_mode mode,
    1093                 :             :                          const FIXED_VALUE_TYPE *f)
    1094                 :             : {
    1095                 :           0 :   REAL_VALUE_TYPE base_value, fixed_value, real_value;
    1096                 :             : 
    1097                 :           0 :   signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f->mode) ? UNSIGNED : SIGNED;
    1098                 :           0 :   real_2expN (&base_value, GET_MODE_FBIT (f->mode), VOIDmode);
    1099                 :           0 :   real_from_integer (&fixed_value, VOIDmode,
    1100                 :           0 :                      wide_int::from (f->data, GET_MODE_PRECISION (f->mode),
    1101                 :             :                                      sgn), sgn);
    1102                 :           0 :   real_arithmetic (&real_value, RDIV_EXPR, &fixed_value, &base_value);
    1103                 :           0 :   real_convert (r, mode, &real_value);
    1104                 :           0 : }
    1105                 :             : 
    1106                 :             : /* Determine whether a fixed-point value F is negative.  */
    1107                 :             : 
    1108                 :             : bool
    1109                 :           0 : fixed_isneg (const FIXED_VALUE_TYPE *f)
    1110                 :             : {
    1111                 :           0 :   if (SIGNED_FIXED_POINT_MODE_P (f->mode))
    1112                 :             :     {
    1113                 :           0 :       int i_f_bits = GET_MODE_IBIT (f->mode) + GET_MODE_FBIT (f->mode);
    1114                 :           0 :       int sign_bit = get_fixed_sign_bit (f->data, i_f_bits);
    1115                 :           0 :       if (sign_bit == 1)
    1116                 :           0 :         return true;
    1117                 :             :     }
    1118                 :             : 
    1119                 :             :   return false;
    1120                 :             : }
        

Generated by: LCOV version 2.1-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.