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#ifndef DOUBLE_INT_H 22169689Skan#define DOUBLE_INT_H 23169689Skan 24169689Skan/* A large integer is currently represented as a pair of HOST_WIDE_INTs. 25169689Skan It therefore represents a number with precision of 26169689Skan 2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the 27169689Skan internal representation will change, if numbers with greater precision 28169689Skan are needed, so the users should not rely on it). The representation does 29169689Skan not contain any information about signedness of the represented value, so 30169689Skan it can be used to represent both signed and unsigned numbers. For 31169689Skan operations where the results depend on signedness (division, comparisons), 32169689Skan it must be specified separately. For each such operation, there are three 33169689Skan versions of the function -- double_int_op, that takes an extra UNS argument 34169689Skan giving the signedness of the values, and double_int_sop and double_int_uop 35169689Skan that stand for its specializations for signed and unsigned values. 36169689Skan 37169689Skan You may also represent with numbers in smaller precision using double_int. 38169689Skan You however need to use double_int_ext (that fills in the bits of the 39169689Skan number over the prescribed precision with zeros or with the sign bit) before 40169689Skan operations that do not perform arithmetics modulo 2^precision (comparisons, 41169689Skan division), and possibly before storing the results, if you want to keep 42169689Skan them in some canonical form). In general, the signedness of double_int_ext 43169689Skan should match the signedness of the operation. 44169689Skan 45169689Skan ??? The components of double_int differ in signedness mostly for 46169689Skan historical reasons (they replace an older structure used to represent 47169689Skan numbers with precision higher than HOST_WIDE_INT). It might be less 48169689Skan confusing to have them both signed or both unsigned. */ 49169689Skan 50169689Skantypedef struct 51169689Skan{ 52169689Skan unsigned HOST_WIDE_INT low; 53169689Skan HOST_WIDE_INT high; 54169689Skan} double_int; 55169689Skan 56169689Skanunion tree_node; 57169689Skan 58169689Skan/* Constructors and conversions. */ 59169689Skan 60169689Skanunion tree_node *double_int_to_tree (union tree_node *, double_int); 61169689Skandouble_int tree_to_double_int (union tree_node *tree); 62169689Skan 63169689Skan/* Constructs double_int from integer CST. The bits over the precision of 64169689Skan HOST_WIDE_INT are filled with the sign bit. */ 65169689Skan 66169689Skanstatic inline double_int 67169689Skanshwi_to_double_int (HOST_WIDE_INT cst) 68169689Skan{ 69169689Skan double_int r; 70169689Skan 71169689Skan r.low = (unsigned HOST_WIDE_INT) cst; 72169689Skan r.high = cst < 0 ? -1 : 0; 73169689Skan 74169689Skan return r; 75169689Skan} 76169689Skan 77169689Skan/* Some useful constants. */ 78169689Skan 79169689Skan#define double_int_minus_one (shwi_to_double_int (-1)) 80169689Skan#define double_int_zero (shwi_to_double_int (0)) 81169689Skan#define double_int_one (shwi_to_double_int (1)) 82169689Skan#define double_int_two (shwi_to_double_int (2)) 83169689Skan#define double_int_ten (shwi_to_double_int (10)) 84169689Skan 85169689Skan/* Constructs double_int from unsigned integer CST. The bits over the 86169689Skan precision of HOST_WIDE_INT are filled with zeros. */ 87169689Skan 88169689Skanstatic inline double_int 89169689Skanuhwi_to_double_int (unsigned HOST_WIDE_INT cst) 90169689Skan{ 91169689Skan double_int r; 92169689Skan 93169689Skan r.low = cst; 94169689Skan r.high = 0; 95169689Skan 96169689Skan return r; 97169689Skan} 98169689Skan 99169689Skan/* The following operations perform arithmetics modulo 2^precision, 100169689Skan so you do not need to call double_int_ext between them, even if 101169689Skan you are representing numbers with precision less than 102169689Skan 2 * HOST_BITS_PER_WIDE_INT bits. */ 103169689Skan 104169689Skandouble_int double_int_mul (double_int, double_int); 105169689Skandouble_int double_int_add (double_int, double_int); 106169689Skandouble_int double_int_neg (double_int); 107169689Skan 108169689Skan/* You must ensure that double_int_ext is called on the operands 109169689Skan of the following operations, if the precision of the numbers 110169689Skan is less than 2 * HOST_BITS_PER_WIDE_INT bits. */ 111169689Skanbool double_int_fits_in_hwi_p (double_int, bool); 112169689Skanbool double_int_fits_in_shwi_p (double_int); 113169689Skanbool double_int_fits_in_uhwi_p (double_int); 114169689SkanHOST_WIDE_INT double_int_to_shwi (double_int); 115169689Skanunsigned HOST_WIDE_INT double_int_to_uhwi (double_int); 116169689Skandouble_int double_int_div (double_int, double_int, bool, unsigned); 117169689Skandouble_int double_int_sdiv (double_int, double_int, unsigned); 118169689Skandouble_int double_int_udiv (double_int, double_int, unsigned); 119169689Skandouble_int double_int_mod (double_int, double_int, bool, unsigned); 120169689Skandouble_int double_int_smod (double_int, double_int, unsigned); 121169689Skandouble_int double_int_umod (double_int, double_int, unsigned); 122169689Skandouble_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *); 123169689Skandouble_int double_int_sdivmod (double_int, double_int, unsigned, double_int *); 124169689Skandouble_int double_int_udivmod (double_int, double_int, unsigned, double_int *); 125169689Skanbool double_int_negative_p (double_int); 126169689Skanint double_int_cmp (double_int, double_int, bool); 127169689Skanint double_int_scmp (double_int, double_int); 128169689Skanint double_int_ucmp (double_int, double_int); 129169689Skanvoid dump_double_int (FILE *, double_int, bool); 130169689Skan 131169689Skan/* Zero and sign extension of numbers in smaller precisions. */ 132169689Skan 133169689Skandouble_int double_int_ext (double_int, unsigned, bool); 134169689Skandouble_int double_int_sext (double_int, unsigned); 135169689Skandouble_int double_int_zext (double_int, unsigned); 136169689Skan 137169689Skan#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0)) 138169689Skan 139169689Skan/* The operands of the following comparison functions must be processed 140169689Skan with double_int_ext, if their precision is less than 141169689Skan 2 * HOST_BITS_PER_WIDE_INT bits. */ 142169689Skan 143169689Skan/* Returns true if CST is zero. */ 144169689Skan 145169689Skanstatic inline bool 146169689Skandouble_int_zero_p (double_int cst) 147169689Skan{ 148169689Skan return cst.low == 0 && cst.high == 0; 149169689Skan} 150169689Skan 151169689Skan/* Returns true if CST is one. */ 152169689Skan 153169689Skanstatic inline bool 154169689Skandouble_int_one_p (double_int cst) 155169689Skan{ 156169689Skan return cst.low == 1 && cst.high == 0; 157169689Skan} 158169689Skan 159169689Skan/* Returns true if CST is minus one. */ 160169689Skan 161169689Skanstatic inline bool 162169689Skandouble_int_minus_one_p (double_int cst) 163169689Skan{ 164169689Skan return (cst.low == ALL_ONES && cst.high == -1); 165169689Skan} 166169689Skan 167169689Skan/* Returns true if CST1 == CST2. */ 168169689Skan 169169689Skanstatic inline bool 170169689Skandouble_int_equal_p (double_int cst1, double_int cst2) 171169689Skan{ 172169689Skan return cst1.low == cst2.low && cst1.high == cst2.high; 173169689Skan} 174169689Skan 175169689Skan#endif /* DOUBLE_INT_H */ 176