119304Speter/* Operations with long integers. 219304Speter Copyright (C) 2006 Free Software Foundation, Inc. 319304Speter 419304SpeterThis file is part of GCC. 519304Speter 619304SpeterGCC is free software; you can redistribute it and/or modify it 719304Speterunder the terms of the GNU General Public License as published by the 819304SpeterFree Software Foundation; either version 2, or (at your option) any 919304Speterlater version. 1019304Speter 1119304SpeterGCC is distributed in the hope that it will be useful, but WITHOUT 1219304SpeterANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1319304SpeterFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1419304Speterfor more details. 1519304Speter 1619304SpeterYou should have received a copy of the GNU General Public License 1719304Speteralong with GCC; see the file COPYING. If not, write to the Free 1819304SpeterSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 1919304Speter02110-1301, USA. */ 2019304Speter 2119304Speter#ifndef DOUBLE_INT_H 2219304Speter#define DOUBLE_INT_H 2319304Speter 2419304Speter/* A large integer is currently represented as a pair of HOST_WIDE_INTs. 2519304Speter It therefore represents a number with precision of 2619304Speter 2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the 2719304Speter internal representation will change, if numbers with greater precision 2819304Speter are needed, so the users should not rely on it). The representation does 2919304Speter not contain any information about signedness of the represented value, so 3019304Speter it can be used to represent both signed and unsigned numbers. For 3119304Speter operations where the results depend on signedness (division, comparisons), 3219304Speter it must be specified separately. For each such operation, there are three 3319304Speter versions of the function -- double_int_op, that takes an extra UNS argument 3419304Speter giving the signedness of the values, and double_int_sop and double_int_uop 3519304Speter that stand for its specializations for signed and unsigned values. 3619304Speter 3719304Speter You may also represent with numbers in smaller precision using double_int. 3819304Speter You however need to use double_int_ext (that fills in the bits of the 3919304Speter number over the prescribed precision with zeros or with the sign bit) before 4019304Speter operations that do not perform arithmetics modulo 2^precision (comparisons, 4119304Speter division), and possibly before storing the results, if you want to keep 4219304Speter them in some canonical form). In general, the signedness of double_int_ext 4319304Speter should match the signedness of the operation. 4419304Speter 4519304Speter ??? The components of double_int differ in signedness mostly for 4619304Speter historical reasons (they replace an older structure used to represent 4719304Speter numbers with precision higher than HOST_WIDE_INT). It might be less 4819304Speter confusing to have them both signed or both unsigned. */ 4919304Speter 5019304Spetertypedef struct 5119304Speter{ 5219304Speter unsigned HOST_WIDE_INT low; 5319304Speter HOST_WIDE_INT high; 5419304Speter} double_int; 5519304Speter 5619304Speterunion tree_node; 5719304Speter 5819304Speter/* Constructors and conversions. */ 5919304Speter 6019304Speterunion tree_node *double_int_to_tree (union tree_node *, double_int); 6119304Speterdouble_int tree_to_double_int (union tree_node *tree); 6219304Speter 6319304Speter/* Constructs double_int from integer CST. The bits over the precision of 6419304Speter HOST_WIDE_INT are filled with the sign bit. */ 6519304Speter 6619304Speterstatic inline double_int 6719304Spetershwi_to_double_int (HOST_WIDE_INT cst) 6819304Speter{ 6919304Speter double_int r; 7019304Speter 7119304Speter r.low = (unsigned HOST_WIDE_INT) cst; 7219304Speter r.high = cst < 0 ? -1 : 0; 7319304Speter 7419304Speter return r; 7519304Speter} 7619304Speter 7719304Speter/* Some useful constants. */ 7819304Speter 7919304Speter#define double_int_minus_one (shwi_to_double_int (-1)) 8019304Speter#define double_int_zero (shwi_to_double_int (0)) 8119304Speter#define double_int_one (shwi_to_double_int (1)) 8219304Speter#define double_int_two (shwi_to_double_int (2)) 8319304Speter#define double_int_ten (shwi_to_double_int (10)) 8419304Speter 8519304Speter/* Constructs double_int from unsigned integer CST. The bits over the 8619304Speter precision of HOST_WIDE_INT are filled with zeros. */ 8719304Speter 8819304Speterstatic inline double_int 8919304Speteruhwi_to_double_int (unsigned HOST_WIDE_INT cst) 9019304Speter{ 9119304Speter double_int r; 9219304Speter 9319304Speter r.low = cst; 9419304Speter r.high = 0; 9519304Speter 9619304Speter return r; 9719304Speter} 9819304Speter 9919304Speter/* The following operations perform arithmetics modulo 2^precision, 10019304Speter so you do not need to call double_int_ext between them, even if 10119304Speter you are representing numbers with precision less than 10219304Speter 2 * HOST_BITS_PER_WIDE_INT bits. */ 10319304Speter 10419304Speterdouble_int double_int_mul (double_int, double_int); 10519304Speterdouble_int double_int_add (double_int, double_int); 10619304Speterdouble_int double_int_neg (double_int); 10719304Speter 10819304Speter/* You must ensure that double_int_ext is called on the operands 10919304Speter of the following operations, if the precision of the numbers 11019304Speter is less than 2 * HOST_BITS_PER_WIDE_INT bits. */ 11119304Speterbool double_int_fits_in_hwi_p (double_int, bool); 11219304Speterbool double_int_fits_in_shwi_p (double_int); 11319304Speterbool double_int_fits_in_uhwi_p (double_int); 11419304SpeterHOST_WIDE_INT double_int_to_shwi (double_int); 11519304Speterunsigned HOST_WIDE_INT double_int_to_uhwi (double_int); 11619304Speterdouble_int double_int_div (double_int, double_int, bool, unsigned); 11719304Speterdouble_int double_int_sdiv (double_int, double_int, unsigned); 11819304Speterdouble_int double_int_udiv (double_int, double_int, unsigned); 11919304Speterdouble_int double_int_mod (double_int, double_int, bool, unsigned); 12019304Speterdouble_int double_int_smod (double_int, double_int, unsigned); 12119304Speterdouble_int double_int_umod (double_int, double_int, unsigned); 12219304Speterdouble_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *); 12319304Speterdouble_int double_int_sdivmod (double_int, double_int, unsigned, double_int *); 12419304Speterdouble_int double_int_udivmod (double_int, double_int, unsigned, double_int *); 12519304Speterbool double_int_negative_p (double_int); 12619304Speterint double_int_cmp (double_int, double_int, bool); 12719304Speterint double_int_scmp (double_int, double_int); 12819304Speterint double_int_ucmp (double_int, double_int); 12919304Spetervoid dump_double_int (FILE *, double_int, bool); 13019304Speter 13119304Speter/* Zero and sign extension of numbers in smaller precisions. */ 13219304Speter 13319304Speterdouble_int double_int_ext (double_int, unsigned, bool); 13419304Speterdouble_int double_int_sext (double_int, unsigned); 13519304Speterdouble_int double_int_zext (double_int, unsigned); 13619304Speter 13719304Speter#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0)) 13819304Speter 13919304Speter/* The operands of the following comparison functions must be processed 14019304Speter with double_int_ext, if their precision is less than 14119304Speter 2 * HOST_BITS_PER_WIDE_INT bits. */ 14219304Speter 14319304Speter/* Returns true if CST is zero. */ 14419304Speter 14519304Speterstatic inline bool 14619304Speterdouble_int_zero_p (double_int cst) 14719304Speter{ 14819304Speter return cst.low == 0 && cst.high == 0; 14919304Speter} 15019304Speter 15119304Speter/* Returns true if CST is one. */ 15219304Speter 15319304Speterstatic inline bool 15419304Speterdouble_int_one_p (double_int cst) 15519304Speter{ 15619304Speter return cst.low == 1 && cst.high == 0; 15719304Speter} 15819304Speter 15919304Speter/* Returns true if CST is minus one. */ 16019304Speter 16119304Speterstatic inline bool 16219304Speterdouble_int_minus_one_p (double_int cst) 16319304Speter{ 16419304Speter return (cst.low == ALL_ONES && cst.high == -1); 16519304Speter} 16619304Speter 16719304Speter/* Returns true if CST1 == CST2. */ 16819304Speter 16919304Speterstatic inline bool 17019304Speterdouble_int_equal_p (double_int cst1, double_int cst2) 17119304Speter{ 17219304Speter return cst1.low == cst2.low && cst1.high == cst2.high; 17319304Speter} 17419304Speter 17519304Speter#endif /* DOUBLE_INT_H */ 17619304Speter