Home | History | Annotate | Line # | Download | only in gcc
      1 /* Fixed-point arithmetic support.
      2    Copyright (C) 2006-2022 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 fixed_identical (const FIXED_VALUE_TYPE *a, const FIXED_VALUE_TYPE *b)
     31 {
     32   return (a->mode == b->mode
     33 	  && a->data.high == b->data.high
     34 	  && a->data.low == b->data.low);
     35 }
     36 
     37 /* Calculate a hash value.  */
     38 
     39 unsigned int
     40 fixed_hash (const FIXED_VALUE_TYPE *f)
     41 {
     42   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 check_real_for_fixed_mode (REAL_VALUE_TYPE *real_value, machine_mode mode)
     63 {
     64   REAL_VALUE_TYPE max_value, min_value, epsilon_value;
     65 
     66   real_2expN (&max_value, GET_MODE_IBIT (mode), VOIDmode);
     67   real_2expN (&epsilon_value, -GET_MODE_FBIT (mode), VOIDmode);
     68 
     69   if (SIGNED_FIXED_POINT_MODE_P (mode))
     70     min_value = real_value_negate (&max_value);
     71   else
     72     real_from_string (&min_value, "0.0");
     73 
     74   if (real_compare (LT_EXPR, real_value, &min_value))
     75     return FIXED_UNDERFLOW;
     76   if (real_compare (EQ_EXPR, real_value, &max_value))
     77     return FIXED_MAX_EPS;
     78   real_arithmetic (&max_value, MINUS_EXPR, &max_value, &epsilon_value);
     79   if (real_compare (GT_EXPR, real_value, &max_value))
     80     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 fixed_from_double_int (double_int payload, scalar_mode mode)
     90 {
     91   FIXED_VALUE_TYPE value;
     92 
     93   gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_DOUBLE_INT);
     94 
     95   if (SIGNED_SCALAR_FIXED_POINT_MODE_P (mode))
     96     value.data = payload.sext (1 + GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode));
     97   else if (UNSIGNED_SCALAR_FIXED_POINT_MODE_P (mode))
     98     value.data = payload.zext (GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode));
     99   else
    100     gcc_unreachable ();
    101 
    102   value.mode = mode;
    103 
    104   return value;
    105 }
    106 
    107 
    108 /* Initialize from a decimal or hexadecimal string.  */
    109 
    110 void
    111 fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, scalar_mode mode)
    112 {
    113   REAL_VALUE_TYPE real_value, fixed_value, base_value;
    114   unsigned int fbit;
    115   enum fixed_value_range_code temp;
    116   bool fail;
    117 
    118   f->mode = mode;
    119   fbit = GET_MODE_FBIT (mode);
    120 
    121   real_from_string (&real_value, str);
    122   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   if (temp == FIXED_UNDERFLOW
    125       || temp == FIXED_GT_MAX_EPS
    126       || (temp == FIXED_MAX_EPS && ALL_ACCUM_MODE_P (f->mode)))
    127     warning (OPT_Woverflow,
    128 	     "large fixed-point constant implicitly truncated to fixed-point type");
    129   real_2expN (&base_value, fbit, VOIDmode);
    130   real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
    131   wide_int w = real_to_integer (&fixed_value, &fail,
    132 				GET_MODE_PRECISION (mode));
    133   f->data.low = w.ulow ();
    134   f->data.high = w.elt (1);
    135 
    136   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       f->data.low = -1;
    140       f->data.high = -1;
    141       f->data = f->data.zext (GET_MODE_FBIT (f->mode)
    142 				+ GET_MODE_IBIT (f->mode));
    143     }
    144   else
    145     f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode)
    146 			      + GET_MODE_FBIT (f->mode)
    147 			      + GET_MODE_IBIT (f->mode),
    148 			      UNSIGNED_FIXED_POINT_MODE_P (f->mode));
    149 }
    150 
    151 /* Render F as a decimal floating point constant.  */
    152 
    153 void
    154 fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *f_orig,
    155 		  size_t buf_size)
    156 {
    157   REAL_VALUE_TYPE real_value, base_value, fixed_value;
    158 
    159   signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode) ? UNSIGNED : SIGNED;
    160   real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode), VOIDmode);
    161   real_from_integer (&real_value, VOIDmode,
    162 		     wide_int::from (f_orig->data,
    163 				     GET_MODE_PRECISION (f_orig->mode), sgn),
    164 		     sgn);
    165   real_arithmetic (&fixed_value, RDIV_EXPR, &real_value, &base_value);
    166   real_to_decimal (str, &fixed_value, buf_size, 0, 1);
    167 }
    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 fixed_saturate1 (machine_mode mode, double_int a, double_int *f,
    179 		 bool sat_p)
    180 {
    181   bool overflow_p = false;
    182   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode);
    183   int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);
    184 
    185   if (unsigned_p) /* Unsigned type.  */
    186     {
    187       double_int max;
    188       max.low = -1;
    189       max.high = -1;
    190       max = max.zext (i_f_bits);
    191       if (a.ugt (max))
    192 	{
    193 	  if (sat_p)
    194 	    *f = max;
    195 	  else
    196 	    overflow_p = true;
    197 	}
    198     }
    199   else /* Signed type.  */
    200     {
    201       double_int max, min;
    202       max.high = -1;
    203       max.low = -1;
    204       max = max.zext (i_f_bits);
    205       min.high = 0;
    206       min.low = 1;
    207       min = min.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
    208       min = min.sext (1 + i_f_bits);
    209       if (a.sgt (max))
    210 	{
    211 	  if (sat_p)
    212 	    *f = max;
    213 	  else
    214 	    overflow_p = true;
    215 	}
    216       else if (a.slt (min))
    217 	{
    218 	  if (sat_p)
    219 	    *f = min;
    220 	  else
    221 	    overflow_p = true;
    222 	}
    223     }
    224   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 fixed_saturate2 (machine_mode mode, double_int a_high, double_int a_low,
    237 		 double_int *f, bool sat_p)
    238 {
    239   bool overflow_p = false;
    240   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode);
    241   int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);
    242 
    243   if (unsigned_p) /* Unsigned type.  */
    244     {
    245       double_int max_r, max_s;
    246       max_r.high = 0;
    247       max_r.low = 0;
    248       max_s.high = -1;
    249       max_s.low = -1;
    250       max_s = max_s.zext (i_f_bits);
    251       if (a_high.ugt (max_r)
    252 	  || (a_high == max_r &&
    253 	      a_low.ugt (max_s)))
    254 	{
    255 	  if (sat_p)
    256 	    *f = max_s;
    257 	  else
    258 	    overflow_p = true;
    259 	}
    260     }
    261   else /* Signed type.  */
    262     {
    263       double_int max_r, max_s, min_r, min_s;
    264       max_r.high = 0;
    265       max_r.low = 0;
    266       max_s.high = -1;
    267       max_s.low = -1;
    268       max_s = max_s.zext (i_f_bits);
    269       min_r.high = -1;
    270       min_r.low = -1;
    271       min_s.high = 0;
    272       min_s.low = 1;
    273       min_s = min_s.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
    274       min_s = min_s.sext (1 + i_f_bits);
    275       if (a_high.sgt (max_r)
    276 	  || (a_high == max_r &&
    277 	      a_low.ugt (max_s)))
    278 	{
    279 	  if (sat_p)
    280 	    *f = max_s;
    281 	  else
    282 	    overflow_p = true;
    283 	}
    284       else if (a_high.slt (min_r)
    285 	       || (a_high == min_r &&
    286 		   a_low.ult (min_s)))
    287 	{
    288 	  if (sat_p)
    289 	    *f = min_s;
    290 	  else
    291 	    overflow_p = true;
    292 	}
    293     }
    294   return overflow_p;
    295 }
    296 
    297 /* Return the sign bit based on I_F_BITS.  */
    298 
    299 static inline int
    300 get_fixed_sign_bit (double_int a, int i_f_bits)
    301 {
    302   if (i_f_bits < HOST_BITS_PER_WIDE_INT)
    303     return (a.low >> i_f_bits) & 1;
    304   else
    305     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 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   bool overflow_p = false;
    317   bool unsigned_p;
    318   double_int temp;
    319   int i_f_bits;
    320 
    321   /* This was a conditional expression but it triggered a bug in
    322      Sun C 5.5.  */
    323   if (subtract_p)
    324     temp = -b->data;
    325   else
    326     temp = b->data;
    327 
    328   unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
    329   i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
    330   f->mode = a->mode;
    331   f->data = a->data + temp;
    332   if (unsigned_p) /* Unsigned type.  */
    333     {
    334       if (subtract_p) /* Unsigned subtraction.  */
    335 	{
    336 	  if (a->data.ult (b->data))
    337 	    {
    338 	      if (sat_p)
    339 		{
    340 		  f->data.high = 0;
    341 		  f->data.low = 0;
    342 		 }
    343 	      else
    344 		overflow_p = true;
    345 	    }
    346 	}
    347       else /* Unsigned addition.  */
    348 	{
    349 	  f->data = f->data.zext (i_f_bits);
    350 	  if (f->data.ult (a->data)
    351 	      || f->data.ult (b->data))
    352 	    {
    353 	      if (sat_p)
    354 		{
    355 		  f->data.high = -1;
    356 		  f->data.low = -1;
    357 		}
    358 	      else
    359 		overflow_p = true;
    360 	    }
    361 	}
    362     }
    363   else /* Signed type.  */
    364     {
    365       if ((!subtract_p
    366 	   && (get_fixed_sign_bit (a->data, i_f_bits)
    367 	       == get_fixed_sign_bit (b->data, i_f_bits))
    368 	   && (get_fixed_sign_bit (a->data, i_f_bits)
    369 	       != get_fixed_sign_bit (f->data, i_f_bits)))
    370 	  || (subtract_p
    371 	      && (get_fixed_sign_bit (a->data, i_f_bits)
    372 		  != get_fixed_sign_bit (b->data, i_f_bits))
    373 	      && (get_fixed_sign_bit (a->data, i_f_bits)
    374 		  != get_fixed_sign_bit (f->data, i_f_bits))))
    375 	{
    376 	  if (sat_p)
    377 	    {
    378 	      f->data.low = 1;
    379 	      f->data.high = 0;
    380 	      f->data = f->data.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
    381 	      if (get_fixed_sign_bit (a->data, i_f_bits) == 0)
    382 		{
    383 		  --f->data;
    384 		}
    385 	    }
    386 	  else
    387 	    overflow_p = true;
    388 	}
    389     }
    390   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
    391   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 do_fixed_multiply (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
    400 		   const FIXED_VALUE_TYPE *b, bool sat_p)
    401 {
    402   bool overflow_p = false;
    403   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
    404   int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
    405   f->mode = a->mode;
    406   if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT)
    407     {
    408       f->data = a->data * b->data;
    409       f->data = f->data.lshift (-GET_MODE_FBIT (f->mode),
    410 				HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
    411       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       double_int a_high, a_low, b_high, b_low;
    417       double_int high_high, high_low, low_high, low_low;
    418       double_int r, s, temp1, temp2;
    419       int carry = 0;
    420 
    421       /* Decompose a and b to four double_int.  */
    422       a_high.low = a->data.high;
    423       a_high.high = 0;
    424       a_low.low = a->data.low;
    425       a_low.high = 0;
    426       b_high.low = b->data.high;
    427       b_high.high = 0;
    428       b_low.low = b->data.low;
    429       b_low.high = 0;
    430 
    431       /* Perform four multiplications.  */
    432       low_low = a_low * b_low;
    433       low_high = a_low * b_high;
    434       high_low = a_high * b_low;
    435       high_high = a_high * b_high;
    436 
    437       /* Accumulate four results to {r, s}.  */
    438       temp1.high = high_low.low;
    439       temp1.low = 0;
    440       s = low_low + temp1;
    441       if (s.ult (low_low)
    442 	  || s.ult (temp1))
    443 	carry ++; /* Carry */
    444       temp1.high = s.high;
    445       temp1.low = s.low;
    446       temp2.high = low_high.low;
    447       temp2.low = 0;
    448       s = temp1 + temp2;
    449       if (s.ult (temp1)
    450 	  || s.ult (temp2))
    451 	carry ++; /* Carry */
    452 
    453       temp1.low = high_low.high;
    454       temp1.high = 0;
    455       r = high_high + temp1;
    456       temp1.low = low_high.high;
    457       temp1.high = 0;
    458       r += temp1;
    459       temp1.low = carry;
    460       temp1.high = 0;
    461       r += temp1;
    462 
    463       /* We need to subtract b from r, if a < 0.  */
    464       if (!unsigned_p && a->data.high < 0)
    465 	r -= b->data;
    466       /* We need to subtract a from r, if b < 0.  */
    467       if (!unsigned_p && b->data.high < 0)
    468 	r -= a->data;
    469 
    470       /* Shift right the result by FBIT.  */
    471       if (GET_MODE_FBIT (f->mode) == HOST_BITS_PER_DOUBLE_INT)
    472 	{
    473 	  s.low = r.low;
    474 	  s.high = r.high;
    475 	  if (unsigned_p)
    476 	    {
    477 	      r.low = 0;
    478 	      r.high = 0;
    479 	    }
    480 	  else
    481 	    {
    482 	      r.low = -1;
    483 	      r.high = -1;
    484 	    }
    485 	  f->data.low = s.low;
    486 	  f->data.high = s.high;
    487 	}
    488       else
    489 	{
    490 	  s = s.llshift ((-GET_MODE_FBIT (f->mode)), HOST_BITS_PER_DOUBLE_INT);
    491 	  f->data = r.llshift ((HOST_BITS_PER_DOUBLE_INT
    492 			  - GET_MODE_FBIT (f->mode)),
    493 			 HOST_BITS_PER_DOUBLE_INT);
    494 	  f->data.low = f->data.low | s.low;
    495 	  f->data.high = f->data.high | s.high;
    496 	  s.low = f->data.low;
    497 	  s.high = f->data.high;
    498 	  r = r.lshift (-GET_MODE_FBIT (f->mode),
    499 			HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
    500 	}
    501 
    502       overflow_p = fixed_saturate2 (f->mode, r, s, &f->data, sat_p);
    503     }
    504 
    505   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
    506   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 do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
    515 		 const FIXED_VALUE_TYPE *b, bool sat_p)
    516 {
    517   bool overflow_p = false;
    518   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
    519   int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
    520   f->mode = a->mode;
    521   if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT)
    522     {
    523       f->data = a->data.lshift (GET_MODE_FBIT (f->mode),
    524 				HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
    525       f->data = f->data.div (b->data, unsigned_p, TRUNC_DIV_EXPR);
    526       overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p);
    527     }
    528   else
    529     {
    530       double_int pos_a, pos_b, r, s;
    531       double_int quo_r, quo_s, mod, temp;
    532       int num_of_neg = 0;
    533       int i;
    534 
    535       /* If a < 0, negate a.  */
    536       if (!unsigned_p && a->data.high < 0)
    537 	{
    538 	  pos_a = -a->data;
    539 	  num_of_neg ++;
    540 	}
    541       else
    542 	pos_a = a->data;
    543 
    544       /* If b < 0, negate b.  */
    545       if (!unsigned_p && b->data.high < 0)
    546 	{
    547 	  pos_b = -b->data;
    548 	  num_of_neg ++;
    549 	}
    550       else
    551 	pos_b = b->data;
    552 
    553       /* Left shift pos_a to {r, s} by FBIT.  */
    554       if (GET_MODE_FBIT (f->mode) == HOST_BITS_PER_DOUBLE_INT)
    555 	{
    556 	  r = pos_a;
    557 	  s.high = 0;
    558 	  s.low = 0;
    559 	}
    560       else
    561  	{
    562 	  s = pos_a.llshift (GET_MODE_FBIT (f->mode), HOST_BITS_PER_DOUBLE_INT);
    563 	  r = pos_a.llshift (- (HOST_BITS_PER_DOUBLE_INT
    564 			    - 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       quo_r = r.divmod (pos_b, 1, TRUNC_DIV_EXPR, &mod);
    570       quo_s = double_int_zero;
    571 
    572       for (i = 0; i < HOST_BITS_PER_DOUBLE_INT; i++)
    573 	{
    574 	  /* Record the leftmost bit of mod.  */
    575 	  int leftmost_mod = (mod.high < 0);
    576 
    577 	  /* Shift left mod by 1 bit.  */
    578 	  mod = mod.lshift (1);
    579 
    580 	  /* Test the leftmost bit of s to add to mod.  */
    581 	  if (s.high < 0)
    582 	    mod.low += 1;
    583 
    584 	  /* Shift left quo_s by 1 bit.  */
    585 	  quo_s = quo_s.lshift (1);
    586 
    587 	  /* Try to calculate (mod - pos_b).  */
    588 	  temp = mod - pos_b;
    589 
    590 	  if (leftmost_mod == 1 || mod.ucmp (pos_b) != -1)
    591 	    {
    592 	      quo_s.low += 1;
    593 	      mod = temp;
    594 	    }
    595 
    596 	  /* Shift left s by 1 bit.  */
    597 	  s = s.lshift (1);
    598 
    599 	}
    600 
    601       if (num_of_neg == 1)
    602 	{
    603 	  quo_s = -quo_s;
    604 	  if (quo_s.high == 0 && quo_s.low == 0)
    605 	    quo_r = -quo_r;
    606 	  else
    607 	    {
    608 	      quo_r.low = ~quo_r.low;
    609 	      quo_r.high = ~quo_r.high;
    610 	    }
    611 	}
    612 
    613       f->data = quo_s;
    614       overflow_p = fixed_saturate2 (f->mode, quo_r, quo_s, &f->data, sat_p);
    615     }
    616 
    617   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
    618   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 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   bool overflow_p = false;
    630   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
    631   int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
    632   f->mode = a->mode;
    633 
    634   if (b->data.low == 0)
    635     {
    636       f->data = a->data;
    637       return overflow_p;
    638     }
    639 
    640   if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT || (!left_p))
    641     {
    642       f->data = a->data.lshift (left_p ? b->data.low : -b->data.low,
    643 				HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
    644       if (left_p) /* Only left shift saturates.  */
    645 	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       double_int temp_high, temp_low;
    650       if (b->data.low == HOST_BITS_PER_DOUBLE_INT)
    651 	{
    652 	  temp_high = a->data;
    653 	  temp_low.high = 0;
    654 	  temp_low.low = 0;
    655 	}
    656       else
    657 	{
    658 	  temp_low = a->data.lshift (b->data.low,
    659 				     HOST_BITS_PER_DOUBLE_INT, !unsigned_p);
    660 	  /* Logical shift right to temp_high.  */
    661 	  temp_high = a->data.llshift (b->data.low - HOST_BITS_PER_DOUBLE_INT,
    662 			 HOST_BITS_PER_DOUBLE_INT);
    663 	}
    664       if (!unsigned_p && a->data.high < 0) /* Signed-extend temp_high.  */
    665 	temp_high = temp_high.ext (b->data.low, unsigned_p);
    666       f->data = temp_low;
    667       overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, &f->data,
    668 				    sat_p);
    669     }
    670   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
    671   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 do_fixed_neg (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, bool sat_p)
    680 {
    681   bool overflow_p = false;
    682   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode);
    683   int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode);
    684   f->mode = a->mode;
    685   f->data = -a->data;
    686   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
    687 
    688   if (unsigned_p) /* Unsigned type.  */
    689     {
    690       if (f->data.low != 0 || f->data.high != 0)
    691 	{
    692 	  if (sat_p)
    693 	    {
    694 	      f->data.low = 0;
    695 	      f->data.high = 0;
    696 	    }
    697 	  else
    698 	    overflow_p = true;
    699 	}
    700     }
    701   else /* Signed type.  */
    702     {
    703       if (!(f->data.high == 0 && f->data.low == 0)
    704 	  && f->data.high == a->data.high && f->data.low == a->data.low )
    705 	{
    706 	  if (sat_p)
    707 	    {
    708 	      /* Saturate to the maximum by subtracting f->data by one.  */
    709 	      f->data.low = -1;
    710 	      f->data.high = -1;
    711 	      f->data = f->data.zext (i_f_bits);
    712 	    }
    713 	  else
    714 	    overflow_p = true;
    715 	}
    716     }
    717   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 fixed_arithmetic (FIXED_VALUE_TYPE *f, int icode, const FIXED_VALUE_TYPE *op0,
    727 		  const FIXED_VALUE_TYPE *op1, bool sat_p)
    728 {
    729   switch (icode)
    730     {
    731     case NEGATE_EXPR:
    732       return do_fixed_neg (f, op0, sat_p);
    733 
    734     case PLUS_EXPR:
    735       gcc_assert (op0->mode == op1->mode);
    736       return do_fixed_add (f, op0, op1, false, sat_p);
    737 
    738     case MINUS_EXPR:
    739       gcc_assert (op0->mode == op1->mode);
    740       return do_fixed_add (f, op0, op1, true, sat_p);
    741 
    742     case MULT_EXPR:
    743       gcc_assert (op0->mode == op1->mode);
    744       return do_fixed_multiply (f, op0, op1, sat_p);
    745 
    746     case TRUNC_DIV_EXPR:
    747       gcc_assert (op0->mode == op1->mode);
    748       return do_fixed_divide (f, op0, op1, sat_p);
    749 
    750     case LSHIFT_EXPR:
    751       return do_fixed_shift (f, op0, op1, true, sat_p);
    752 
    753     case RSHIFT_EXPR:
    754       return do_fixed_shift (f, op0, op1, false, sat_p);
    755 
    756     default:
    757       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 fixed_compare (int icode, const FIXED_VALUE_TYPE *op0,
    766 	       const FIXED_VALUE_TYPE *op1)
    767 {
    768   enum tree_code code = (enum tree_code) icode;
    769   gcc_assert (op0->mode == op1->mode);
    770 
    771   switch (code)
    772     {
    773     case NE_EXPR:
    774       return op0->data != op1->data;
    775 
    776     case EQ_EXPR:
    777       return op0->data == op1->data;
    778 
    779     case LT_EXPR:
    780       return op0->data.cmp (op1->data,
    781 			     UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) == -1;
    782 
    783     case LE_EXPR:
    784       return op0->data.cmp (op1->data,
    785 			     UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) != 1;
    786 
    787     case GT_EXPR:
    788       return op0->data.cmp (op1->data,
    789 			     UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) == 1;
    790 
    791     case GE_EXPR:
    792       return op0->data.cmp (op1->data,
    793 			     UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) != -1;
    794 
    795     default:
    796       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 fixed_convert (FIXED_VALUE_TYPE *f, scalar_mode mode,
    806                const FIXED_VALUE_TYPE *a, bool sat_p)
    807 {
    808   bool overflow_p = false;
    809   if (mode == a->mode)
    810     {
    811       *f = *a;
    812       return overflow_p;
    813     }
    814 
    815   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       double_int temp_high, temp_low;
    819       int amount = GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode);
    820       temp_low = a->data.lshift (amount,
    821 				 HOST_BITS_PER_DOUBLE_INT,
    822 				 SIGNED_FIXED_POINT_MODE_P (a->mode));
    823       /* Logical shift right to temp_high.  */
    824       temp_high = a->data.llshift (amount - HOST_BITS_PER_DOUBLE_INT,
    825 		     HOST_BITS_PER_DOUBLE_INT);
    826       if (SIGNED_FIXED_POINT_MODE_P (a->mode)
    827 	  && a->data.high < 0) /* Signed-extend temp_high.  */
    828 	temp_high = temp_high.sext (amount);
    829       f->mode = mode;
    830       f->data = temp_low;
    831       if (SIGNED_FIXED_POINT_MODE_P (a->mode) ==
    832 	  SIGNED_FIXED_POINT_MODE_P (f->mode))
    833 	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 	  if (SIGNED_FIXED_POINT_MODE_P (a->mode))
    840 	    {
    841 	      /* Signed -> Unsigned.  */
    842 	      if (a->data.high < 0)
    843 		{
    844 		  if (sat_p)
    845 		    {
    846 		      f->data.low = 0;  /* Set to zero.  */
    847 		      f->data.high = 0;  /* Set to zero.  */
    848 		    }
    849 		  else
    850 		    overflow_p = true;
    851 		}
    852 	      else
    853 		overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low,
    854 					      &f->data, sat_p);
    855 	    }
    856 	  else
    857 	    {
    858 	      /* Unsigned -> Signed.  */
    859 	      if (temp_high.high < 0)
    860 		{
    861 		  if (sat_p)
    862 		    {
    863 		      /* Set to maximum.  */
    864 		      f->data.low = -1;  /* Set to all ones.  */
    865 		      f->data.high = -1;  /* Set to all ones.  */
    866 		      f->data = f->data.zext (GET_MODE_FBIT (f->mode)
    867 						+ GET_MODE_IBIT (f->mode));
    868 						/* Clear the sign.  */
    869 		    }
    870 		  else
    871 		    overflow_p = true;
    872 		}
    873 	      else
    874 		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       double_int temp;
    883       temp = a->data.lshift (GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode),
    884 			     HOST_BITS_PER_DOUBLE_INT,
    885 			     SIGNED_FIXED_POINT_MODE_P (a->mode));
    886       f->mode = mode;
    887       f->data = temp;
    888       if (SIGNED_FIXED_POINT_MODE_P (a->mode) ==
    889 	  SIGNED_FIXED_POINT_MODE_P (f->mode))
    890 	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 	  if (SIGNED_FIXED_POINT_MODE_P (a->mode))
    896 	    {
    897 	      /* Signed -> Unsigned.  */
    898 	      if (a->data.high < 0)
    899 		{
    900 		  if (sat_p)
    901 		    {
    902 		      f->data.low = 0;  /* Set to zero.  */
    903 		      f->data.high = 0;  /* Set to zero.  */
    904 		    }
    905 		  else
    906 		    overflow_p = true;
    907 		}
    908 	      else
    909 		overflow_p = fixed_saturate1 (f->mode, f->data, &f->data,
    910 					      sat_p);
    911 	    }
    912 	  else
    913 	    {
    914 	      /* Unsigned -> Signed.  */
    915 	      if (temp.high < 0)
    916 		{
    917 		  if (sat_p)
    918 		    {
    919 		      /* Set to maximum.  */
    920 		      f->data.low = -1;  /* Set to all ones.  */
    921 		      f->data.high = -1;  /* Set to all ones.  */
    922 		      f->data = f->data.zext (GET_MODE_FBIT (f->mode)
    923 						+ GET_MODE_IBIT (f->mode));
    924 						/* Clear the sign.  */
    925 		    }
    926 		  else
    927 		    overflow_p = true;
    928 		}
    929 	      else
    930 		overflow_p = fixed_saturate1 (f->mode, f->data, &f->data,
    931 					      sat_p);
    932 	    }
    933 	}
    934     }
    935 
    936   f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode)
    937 			    + GET_MODE_FBIT (f->mode)
    938 			    + GET_MODE_IBIT (f->mode),
    939 			    UNSIGNED_FIXED_POINT_MODE_P (f->mode));
    940   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 fixed_convert_from_int (FIXED_VALUE_TYPE *f, scalar_mode mode,
    950 			double_int a, bool unsigned_p, bool sat_p)
    951 {
    952   bool overflow_p = false;
    953   /* Left shift a to temp_high, temp_low.  */
    954   double_int temp_high, temp_low;
    955   int amount = GET_MODE_FBIT (mode);
    956   if (amount == HOST_BITS_PER_DOUBLE_INT)
    957     {
    958        temp_high = a;
    959        temp_low.low = 0;
    960        temp_low.high = 0;
    961     }
    962   else
    963     {
    964       temp_low = a.llshift (amount, HOST_BITS_PER_DOUBLE_INT);
    965 
    966       /* Logical shift right to temp_high.  */
    967       temp_high = a.llshift (amount - HOST_BITS_PER_DOUBLE_INT,
    968 		     HOST_BITS_PER_DOUBLE_INT);
    969     }
    970   if (!unsigned_p && a.high < 0) /* Signed-extend temp_high.  */
    971     temp_high = temp_high.sext (amount);
    972 
    973   f->mode = mode;
    974   f->data = temp_low;
    975 
    976   if (unsigned_p == UNSIGNED_FIXED_POINT_MODE_P (f->mode))
    977     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       if (!unsigned_p)
    983 	{
    984 	  /* Signed -> Unsigned.  */
    985 	  if (a.high < 0)
    986 	    {
    987 	      if (sat_p)
    988 		{
    989 		  f->data.low = 0;  /* Set to zero.  */
    990 		  f->data.high = 0;  /* Set to zero.  */
    991 		}
    992 	      else
    993 		overflow_p = true;
    994 	    }
    995 	  else
    996 	    overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low,
    997 					  &f->data, sat_p);
    998 	}
    999       else
   1000 	{
   1001 	  /* Unsigned -> Signed.  */
   1002 	  if (temp_high.high < 0)
   1003 	    {
   1004 	      if (sat_p)
   1005 		{
   1006 		  /* Set to maximum.  */
   1007 		  f->data.low = -1;  /* Set to all ones.  */
   1008 		  f->data.high = -1;  /* Set to all ones.  */
   1009 		  f->data = f->data.zext (GET_MODE_FBIT (f->mode)
   1010 					    + GET_MODE_IBIT (f->mode));
   1011 					    /* Clear the sign.  */
   1012 		}
   1013 	      else
   1014 		overflow_p = true;
   1015 	    }
   1016 	  else
   1017 	    overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low,
   1018 					  &f->data, sat_p);
   1019 	}
   1020     }
   1021   f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode)
   1022 			    + GET_MODE_FBIT (f->mode)
   1023 			    + GET_MODE_IBIT (f->mode),
   1024 			    UNSIGNED_FIXED_POINT_MODE_P (f->mode));
   1025   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 fixed_convert_from_real (FIXED_VALUE_TYPE *f, scalar_mode mode,
   1034 			 const REAL_VALUE_TYPE *a, bool sat_p)
   1035 {
   1036   bool overflow_p = false;
   1037   REAL_VALUE_TYPE real_value, fixed_value, base_value;
   1038   bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode);
   1039   int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);
   1040   unsigned int fbit = GET_MODE_FBIT (mode);
   1041   enum fixed_value_range_code temp;
   1042   bool fail;
   1043 
   1044   real_value = *a;
   1045   f->mode = mode;
   1046   real_2expN (&base_value, fbit, VOIDmode);
   1047   real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
   1048 
   1049   wide_int w = real_to_integer (&fixed_value, &fail,
   1050 				GET_MODE_PRECISION (mode));
   1051   f->data.low = w.ulow ();
   1052   f->data.high = w.elt (1);
   1053   temp = check_real_for_fixed_mode (&real_value, mode);
   1054   if (temp == FIXED_UNDERFLOW) /* Minimum.  */
   1055     {
   1056       if (sat_p)
   1057 	{
   1058 	  if (unsigned_p)
   1059 	    {
   1060 	      f->data.low = 0;
   1061 	      f->data.high = 0;
   1062 	    }
   1063 	  else
   1064 	    {
   1065 	      f->data.low = 1;
   1066 	      f->data.high = 0;
   1067 	      f->data = f->data.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
   1068 	      f->data = f->data.sext (1 + i_f_bits);
   1069 	    }
   1070 	}
   1071       else
   1072 	overflow_p = true;
   1073     }
   1074   else if (temp == FIXED_GT_MAX_EPS || temp == FIXED_MAX_EPS) /* Maximum.  */
   1075     {
   1076       if (sat_p)
   1077 	{
   1078 	  f->data.low = -1;
   1079 	  f->data.high = -1;
   1080 	  f->data = f->data.zext (i_f_bits);
   1081 	}
   1082       else
   1083 	overflow_p = true;
   1084     }
   1085   f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p);
   1086   return overflow_p;
   1087 }
   1088 
   1089 /* Convert to a new real mode from a fixed-point.  */
   1090 
   1091 void
   1092 real_convert_from_fixed (REAL_VALUE_TYPE *r, scalar_mode mode,
   1093 			 const FIXED_VALUE_TYPE *f)
   1094 {
   1095   REAL_VALUE_TYPE base_value, fixed_value, real_value;
   1096 
   1097   signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f->mode) ? UNSIGNED : SIGNED;
   1098   real_2expN (&base_value, GET_MODE_FBIT (f->mode), VOIDmode);
   1099   real_from_integer (&fixed_value, VOIDmode,
   1100 		     wide_int::from (f->data, GET_MODE_PRECISION (f->mode),
   1101 				     sgn), sgn);
   1102   real_arithmetic (&real_value, RDIV_EXPR, &fixed_value, &base_value);
   1103   real_convert (r, mode, &real_value);
   1104 }
   1105 
   1106 /* Determine whether a fixed-point value F is negative.  */
   1107 
   1108 bool
   1109 fixed_isneg (const FIXED_VALUE_TYPE *f)
   1110 {
   1111   if (SIGNED_FIXED_POINT_MODE_P (f->mode))
   1112     {
   1113       int i_f_bits = GET_MODE_IBIT (f->mode) + GET_MODE_FBIT (f->mode);
   1114       int sign_bit = get_fixed_sign_bit (f->data, i_f_bits);
   1115       if (sign_bit == 1)
   1116 	return true;
   1117     }
   1118 
   1119   return false;
   1120 }
   1121