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