double-int.c revision 169689
1169689Skan/* Operations with long integers. 2169689Skan Copyright (C) 2006 Free Software Foundation, Inc. 3169689Skan 4169689SkanThis file is part of GCC. 5169689Skan 6169689SkanGCC is free software; you can redistribute it and/or modify it 7169689Skanunder the terms of the GNU General Public License as published by the 8169689SkanFree Software Foundation; either version 2, or (at your option) any 9169689Skanlater version. 10169689Skan 11169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT 12169689SkanANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13169689SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14169689Skanfor more details. 15169689Skan 16169689SkanYou should have received a copy of the GNU General Public License 17169689Skanalong with GCC; see the file COPYING. If not, write to the Free 18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 19169689Skan02110-1301, USA. */ 20169689Skan 21169689Skan#include "config.h" 22169689Skan#include "system.h" 23169689Skan#include "coretypes.h" 24169689Skan#include "tm.h" 25169689Skan#include "tree.h" 26169689Skan 27169689Skan/* Returns mask for PREC bits. */ 28169689Skan 29169689Skanstatic inline double_int 30169689Skandouble_int_mask (unsigned prec) 31169689Skan{ 32169689Skan unsigned HOST_WIDE_INT m; 33169689Skan double_int mask; 34169689Skan 35169689Skan if (prec > HOST_BITS_PER_WIDE_INT) 36169689Skan { 37169689Skan prec -= HOST_BITS_PER_WIDE_INT; 38169689Skan m = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1; 39169689Skan mask.high = (HOST_WIDE_INT) m; 40169689Skan mask.low = ALL_ONES; 41169689Skan } 42169689Skan else 43169689Skan { 44169689Skan mask.high = 0; 45169689Skan mask.low = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1; 46169689Skan } 47169689Skan 48169689Skan return mask; 49169689Skan} 50169689Skan 51169689Skan/* Clears the bits of CST over the precision PREC. If UNS is false, the bits 52169689Skan outside of the precision are set to the sign bit (i.e., the PREC-th one), 53169689Skan otherwise they are set to zero. 54169689Skan 55169689Skan This corresponds to returning the value represented by PREC lowermost bits 56169689Skan of CST, with the given signedness. */ 57169689Skan 58169689Skandouble_int 59169689Skandouble_int_ext (double_int cst, unsigned prec, bool uns) 60169689Skan{ 61169689Skan if (uns) 62169689Skan return double_int_zext (cst, prec); 63169689Skan else 64169689Skan return double_int_sext (cst, prec); 65169689Skan} 66169689Skan 67169689Skan/* The same as double_int_ext with UNS = true. */ 68169689Skan 69169689Skandouble_int 70169689Skandouble_int_zext (double_int cst, unsigned prec) 71169689Skan{ 72169689Skan double_int mask = double_int_mask (prec); 73169689Skan double_int r; 74169689Skan 75169689Skan r.low = cst.low & mask.low; 76169689Skan r.high = cst.high & mask.high; 77169689Skan 78169689Skan return r; 79169689Skan} 80169689Skan 81169689Skan/* The same as double_int_ext with UNS = false. */ 82169689Skan 83169689Skandouble_int 84169689Skandouble_int_sext (double_int cst, unsigned prec) 85169689Skan{ 86169689Skan double_int mask = double_int_mask (prec); 87169689Skan double_int r; 88169689Skan unsigned HOST_WIDE_INT snum; 89169689Skan 90169689Skan if (prec <= HOST_BITS_PER_WIDE_INT) 91169689Skan snum = cst.low; 92169689Skan else 93169689Skan { 94169689Skan prec -= HOST_BITS_PER_WIDE_INT; 95169689Skan snum = (unsigned HOST_WIDE_INT) cst.high; 96169689Skan } 97169689Skan if (((snum >> (prec - 1)) & 1) == 1) 98169689Skan { 99169689Skan r.low = cst.low | ~mask.low; 100169689Skan r.high = cst.high | ~mask.high; 101169689Skan } 102169689Skan else 103169689Skan { 104169689Skan r.low = cst.low & mask.low; 105169689Skan r.high = cst.high & mask.high; 106169689Skan } 107169689Skan 108169689Skan return r; 109169689Skan} 110169689Skan 111169689Skan/* Constructs long integer from tree CST. The extra bits over the precision of 112169689Skan the number are filled with sign bit if CST is signed, and with zeros if it 113169689Skan is unsigned. */ 114169689Skan 115169689Skandouble_int 116169689Skantree_to_double_int (tree cst) 117169689Skan{ 118169689Skan /* We do not need to call double_int_restrict here to ensure the semantics as 119169689Skan described, as this is the default one for trees. */ 120169689Skan return TREE_INT_CST (cst); 121169689Skan} 122169689Skan 123169689Skan/* Returns true if CST fits in unsigned HOST_WIDE_INT. */ 124169689Skan 125169689Skanbool 126169689Skandouble_int_fits_in_uhwi_p (double_int cst) 127169689Skan{ 128169689Skan return cst.high == 0; 129169689Skan} 130169689Skan 131169689Skan/* Returns true if CST fits in signed HOST_WIDE_INT. */ 132169689Skan 133169689Skanbool 134169689Skandouble_int_fits_in_shwi_p (double_int cst) 135169689Skan{ 136169689Skan if (cst.high == 0) 137169689Skan return (HOST_WIDE_INT) cst.low >= 0; 138169689Skan else if (cst.high == -1) 139169689Skan return (HOST_WIDE_INT) cst.low < 0; 140169689Skan else 141169689Skan return false; 142169689Skan} 143169689Skan 144169689Skan/* Returns true if CST fits in HOST_WIDE_INT if UNS is false, or in 145169689Skan unsigned HOST_WIDE_INT if UNS is true. */ 146169689Skan 147169689Skanbool 148169689Skandouble_int_fits_in_hwi_p (double_int cst, bool uns) 149169689Skan{ 150169689Skan if (uns) 151169689Skan return double_int_fits_in_uhwi_p (cst); 152169689Skan else 153169689Skan return double_int_fits_in_shwi_p (cst); 154169689Skan} 155169689Skan 156169689Skan/* Returns value of CST as a signed number. CST must satisfy 157169689Skan double_int_fits_in_shwi_p. */ 158169689Skan 159169689SkanHOST_WIDE_INT 160169689Skandouble_int_to_shwi (double_int cst) 161169689Skan{ 162169689Skan return (HOST_WIDE_INT) cst.low; 163169689Skan} 164169689Skan 165169689Skan/* Returns value of CST as an unsigned number. CST must satisfy 166169689Skan double_int_fits_in_uhwi_p. */ 167169689Skan 168169689Skanunsigned HOST_WIDE_INT 169169689Skandouble_int_to_uhwi (double_int cst) 170169689Skan{ 171169689Skan return cst.low; 172169689Skan} 173169689Skan 174169689Skan/* Returns A * B. */ 175169689Skan 176169689Skandouble_int 177169689Skandouble_int_mul (double_int a, double_int b) 178169689Skan{ 179169689Skan double_int ret; 180169689Skan mul_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high); 181169689Skan return ret; 182169689Skan} 183169689Skan 184169689Skan/* Returns A + B. */ 185169689Skan 186169689Skandouble_int 187169689Skandouble_int_add (double_int a, double_int b) 188169689Skan{ 189169689Skan double_int ret; 190169689Skan add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high); 191169689Skan return ret; 192169689Skan} 193169689Skan 194169689Skan/* Returns -A. */ 195169689Skan 196169689Skandouble_int 197169689Skandouble_int_neg (double_int a) 198169689Skan{ 199169689Skan double_int ret; 200169689Skan neg_double (a.low, a.high, &ret.low, &ret.high); 201169689Skan return ret; 202169689Skan} 203169689Skan 204169689Skan/* Returns A / B (computed as unsigned depending on UNS, and rounded as 205169689Skan specified by CODE). CODE is enum tree_code in fact, but double_int.h 206169689Skan must be included before tree.h. The remainder after the division is 207169689Skan stored to MOD. */ 208169689Skan 209169689Skandouble_int 210169689Skandouble_int_divmod (double_int a, double_int b, bool uns, unsigned code, 211169689Skan double_int *mod) 212169689Skan{ 213169689Skan double_int ret; 214169689Skan 215169689Skan div_and_round_double (code, uns, a.low, a.high, b.low, b.high, 216169689Skan &ret.low, &ret.high, &mod->low, &mod->high); 217169689Skan return ret; 218169689Skan} 219169689Skan 220169689Skan/* The same as double_int_divmod with UNS = false. */ 221169689Skan 222169689Skandouble_int 223169689Skandouble_int_sdivmod (double_int a, double_int b, unsigned code, double_int *mod) 224169689Skan{ 225169689Skan return double_int_divmod (a, b, false, code, mod); 226169689Skan} 227169689Skan 228169689Skan/* The same as double_int_divmod with UNS = true. */ 229169689Skan 230169689Skandouble_int 231169689Skandouble_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod) 232169689Skan{ 233169689Skan return double_int_divmod (a, b, true, code, mod); 234169689Skan} 235169689Skan 236169689Skan/* Returns A / B (computed as unsigned depending on UNS, and rounded as 237169689Skan specified by CODE). CODE is enum tree_code in fact, but double_int.h 238169689Skan must be included before tree.h. */ 239169689Skan 240169689Skandouble_int 241169689Skandouble_int_div (double_int a, double_int b, bool uns, unsigned code) 242169689Skan{ 243169689Skan double_int mod; 244169689Skan 245169689Skan return double_int_divmod (a, b, uns, code, &mod); 246169689Skan} 247169689Skan 248169689Skan/* The same as double_int_div with UNS = false. */ 249169689Skan 250169689Skandouble_int 251169689Skandouble_int_sdiv (double_int a, double_int b, unsigned code) 252169689Skan{ 253169689Skan return double_int_div (a, b, false, code); 254169689Skan} 255169689Skan 256169689Skan/* The same as double_int_div with UNS = true. */ 257169689Skan 258169689Skandouble_int 259169689Skandouble_int_udiv (double_int a, double_int b, unsigned code) 260169689Skan{ 261169689Skan return double_int_div (a, b, true, code); 262169689Skan} 263169689Skan 264169689Skan/* Returns A % B (computed as unsigned depending on UNS, and rounded as 265169689Skan specified by CODE). CODE is enum tree_code in fact, but double_int.h 266169689Skan must be included before tree.h. */ 267169689Skan 268169689Skandouble_int 269169689Skandouble_int_mod (double_int a, double_int b, bool uns, unsigned code) 270169689Skan{ 271169689Skan double_int mod; 272169689Skan 273169689Skan double_int_divmod (a, b, uns, code, &mod); 274169689Skan return mod; 275169689Skan} 276169689Skan 277169689Skan/* The same as double_int_mod with UNS = false. */ 278169689Skan 279169689Skandouble_int 280169689Skandouble_int_smod (double_int a, double_int b, unsigned code) 281169689Skan{ 282169689Skan return double_int_mod (a, b, false, code); 283169689Skan} 284169689Skan 285169689Skan/* The same as double_int_mod with UNS = true. */ 286169689Skan 287169689Skandouble_int 288169689Skandouble_int_umod (double_int a, double_int b, unsigned code) 289169689Skan{ 290169689Skan return double_int_mod (a, b, true, code); 291169689Skan} 292169689Skan 293169689Skan/* Constructs tree in type TYPE from with value given by CST. */ 294169689Skan 295169689Skantree 296169689Skandouble_int_to_tree (tree type, double_int cst) 297169689Skan{ 298169689Skan cst = double_int_ext (cst, TYPE_PRECISION (type), TYPE_UNSIGNED (type)); 299169689Skan 300169689Skan return build_int_cst_wide (type, cst.low, cst.high); 301169689Skan} 302169689Skan 303169689Skan/* Returns true if CST is negative. Of course, CST is considered to 304169689Skan be signed. */ 305169689Skan 306169689Skanbool 307169689Skandouble_int_negative_p (double_int cst) 308169689Skan{ 309169689Skan return cst.high < 0; 310169689Skan} 311169689Skan 312169689Skan/* Returns -1 if A < B, 0 if A == B and 1 if A > B. Signedness of the 313169689Skan comparison is given by UNS. */ 314169689Skan 315169689Skanint 316169689Skandouble_int_cmp (double_int a, double_int b, bool uns) 317169689Skan{ 318169689Skan if (uns) 319169689Skan return double_int_ucmp (a, b); 320169689Skan else 321169689Skan return double_int_scmp (a, b); 322169689Skan} 323169689Skan 324169689Skan/* Compares two unsigned values A and B. Returns -1 if A < B, 0 if A == B, 325169689Skan and 1 if A > B. */ 326169689Skan 327169689Skanint 328169689Skandouble_int_ucmp (double_int a, double_int b) 329169689Skan{ 330169689Skan if ((unsigned HOST_WIDE_INT) a.high < (unsigned HOST_WIDE_INT) b.high) 331169689Skan return -1; 332169689Skan if ((unsigned HOST_WIDE_INT) a.high > (unsigned HOST_WIDE_INT) b.high) 333169689Skan return 1; 334169689Skan if (a.low < b.low) 335169689Skan return -1; 336169689Skan if (a.low > b.low) 337169689Skan return 1; 338169689Skan 339169689Skan return 0; 340169689Skan} 341169689Skan 342169689Skan/* Compares two signed values A and B. Returns -1 if A < B, 0 if A == B, 343169689Skan and 1 if A > B. */ 344169689Skan 345169689Skanint 346169689Skandouble_int_scmp (double_int a, double_int b) 347169689Skan{ 348169689Skan if (a.high < b.high) 349169689Skan return -1; 350169689Skan if (a.high > b.high) 351169689Skan return 1; 352169689Skan if ((HOST_WIDE_INT) a.low < (HOST_WIDE_INT) b.low) 353169689Skan return -1; 354169689Skan if ((HOST_WIDE_INT) a.low > (HOST_WIDE_INT) b.low) 355169689Skan return 1; 356169689Skan 357169689Skan return 0; 358169689Skan} 359169689Skan 360169689Skan/* Splits last digit of *CST (taken as unsigned) in BASE and returns it. */ 361169689Skan 362169689Skanstatic unsigned 363169689Skandouble_int_split_digit (double_int *cst, unsigned base) 364169689Skan{ 365169689Skan unsigned HOST_WIDE_INT resl, reml; 366169689Skan HOST_WIDE_INT resh, remh; 367169689Skan 368169689Skan div_and_round_double (FLOOR_DIV_EXPR, true, cst->low, cst->high, base, 0, 369169689Skan &resl, &resh, &reml, &remh); 370169689Skan cst->high = resh; 371169689Skan cst->low = resl; 372169689Skan 373169689Skan return reml; 374169689Skan} 375169689Skan 376169689Skan/* Dumps CST to FILE. If UNS is true, CST is considered to be unsigned, 377169689Skan otherwise it is signed. */ 378169689Skan 379169689Skanvoid 380169689Skandump_double_int (FILE *file, double_int cst, bool uns) 381169689Skan{ 382169689Skan unsigned digits[100], n; 383169689Skan int i; 384169689Skan 385169689Skan if (double_int_zero_p (cst)) 386169689Skan { 387169689Skan fprintf (file, "0"); 388169689Skan return; 389169689Skan } 390169689Skan 391169689Skan if (!uns && double_int_negative_p (cst)) 392169689Skan { 393169689Skan fprintf (file, "-"); 394169689Skan cst = double_int_neg (cst); 395169689Skan } 396169689Skan 397169689Skan for (n = 0; !double_int_zero_p (cst); n++) 398169689Skan digits[n] = double_int_split_digit (&cst, 10); 399169689Skan for (i = n - 1; i >= 0; i--) 400169689Skan fprintf (file, "%u", digits[i]); 401169689Skan} 402