X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdouble-int.h;h=6d1555111d34b852160245f957079b71e5ec9278;hb=927a01eba66c97c810b74e48669832863c8b846d;hp=6ecfa48f7876a5e3a6d59a4bb137b8b8c4cb7dfd;hpb=faa56cf9fb2c67f8b284c4d9fcdc641a7728a4a9;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/double-int.h b/gcc/double-int.h index 6ecfa48f787..6d1555111d3 100644 --- a/gcc/double-int.h +++ b/gcc/double-int.h @@ -1,26 +1,30 @@ /* Operations with long integers. - Copyright (C) 2006 Free Software Foundation, Inc. - + Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc. + This file is part of GCC. - + GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any +Free Software Foundation; either version 3, or (at your option) any later version. - + GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #ifndef DOUBLE_INT_H #define DOUBLE_INT_H +#ifndef GENERATOR_FILE +#include +#endif +#include "coretypes.h" + /* A large integer is currently represented as a pair of HOST_WIDE_INTs. It therefore represents a number with precision of 2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the @@ -53,14 +57,10 @@ typedef struct HOST_WIDE_INT high; } double_int; -union tree_node; +#define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT) /* Constructors and conversions. */ -union tree_node *double_int_to_tree (union tree_node *, double_int); -bool double_int_fits_to_tree_p (union tree_node *, double_int); -double_int tree_to_double_int (union tree_node *); - /* Constructs double_int from integer CST. The bits over the precision of HOST_WIDE_INT are filled with the sign bit. */ @@ -68,7 +68,7 @@ static inline double_int shwi_to_double_int (HOST_WIDE_INT cst) { double_int r; - + r.low = (unsigned HOST_WIDE_INT) cst; r.high = cst < 0 ? -1 : 0; @@ -90,30 +90,56 @@ static inline double_int uhwi_to_double_int (unsigned HOST_WIDE_INT cst) { double_int r; - + r.low = cst; r.high = 0; return r; } +/* Returns value of CST as a signed number. CST must satisfy + double_int_fits_in_shwi_p. */ + +static inline HOST_WIDE_INT +double_int_to_shwi (double_int cst) +{ + return (HOST_WIDE_INT) cst.low; +} + +/* Returns value of CST as an unsigned number. CST must satisfy + double_int_fits_in_uhwi_p. */ + +static inline unsigned HOST_WIDE_INT +double_int_to_uhwi (double_int cst) +{ + return cst.low; +} + +bool double_int_fits_in_hwi_p (double_int, bool); +bool double_int_fits_in_shwi_p (double_int); + +/* Returns true if CST fits in unsigned HOST_WIDE_INT. */ + +static inline bool +double_int_fits_in_uhwi_p (double_int cst) +{ + return cst.high == 0; +} + /* The following operations perform arithmetics modulo 2^precision, so you do not need to call double_int_ext between them, even if you are representing numbers with precision less than 2 * HOST_BITS_PER_WIDE_INT bits. */ double_int double_int_mul (double_int, double_int); +double_int double_int_mul_with_sign (double_int, double_int, bool, int *); double_int double_int_add (double_int, double_int); +double_int double_int_sub (double_int, double_int); double_int double_int_neg (double_int); /* You must ensure that double_int_ext is called on the operands of the following operations, if the precision of the numbers is less than 2 * HOST_BITS_PER_WIDE_INT bits. */ -bool double_int_fits_in_hwi_p (double_int, bool); -bool double_int_fits_in_shwi_p (double_int); -bool double_int_fits_in_uhwi_p (double_int); -HOST_WIDE_INT double_int_to_shwi (double_int); -unsigned HOST_WIDE_INT double_int_to_uhwi (double_int); double_int double_int_div (double_int, double_int, bool, unsigned); double_int double_int_sdiv (double_int, double_int, unsigned); double_int double_int_udiv (double_int, double_int, unsigned); @@ -123,10 +149,90 @@ double_int double_int_umod (double_int, double_int, unsigned); double_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *); double_int double_int_sdivmod (double_int, double_int, unsigned, double_int *); double_int double_int_udivmod (double_int, double_int, unsigned, double_int *); -bool double_int_negative_p (double_int); + +double_int double_int_setbit (double_int, unsigned); +int double_int_ctz (double_int); + +/* Logical operations. */ + +/* Returns ~A. */ + +static inline double_int +double_int_not (double_int a) +{ + a.low = ~a.low; + a.high = ~a.high; + return a; +} + +/* Returns A | B. */ + +static inline double_int +double_int_ior (double_int a, double_int b) +{ + a.low |= b.low; + a.high |= b.high; + return a; +} + +/* Returns A & B. */ + +static inline double_int +double_int_and (double_int a, double_int b) +{ + a.low &= b.low; + a.high &= b.high; + return a; +} + +/* Returns A & ~B. */ + +static inline double_int +double_int_and_not (double_int a, double_int b) +{ + a.low &= ~b.low; + a.high &= ~b.high; + return a; +} + +/* Returns A ^ B. */ + +static inline double_int +double_int_xor (double_int a, double_int b) +{ + a.low ^= b.low; + a.high ^= b.high; + return a; +} + + +/* Shift operations. */ +double_int double_int_lshift (double_int, HOST_WIDE_INT, unsigned int, bool); +double_int double_int_rshift (double_int, HOST_WIDE_INT, unsigned int, bool); +double_int double_int_lrotate (double_int, HOST_WIDE_INT, unsigned int); +double_int double_int_rrotate (double_int, HOST_WIDE_INT, unsigned int); + +/* Returns true if CST is negative. Of course, CST is considered to + be signed. */ + +static inline bool +double_int_negative_p (double_int cst) +{ + return cst.high < 0; +} + int double_int_cmp (double_int, double_int, bool); int double_int_scmp (double_int, double_int); int double_int_ucmp (double_int, double_int); + +double_int double_int_max (double_int, double_int, bool); +double_int double_int_smax (double_int, double_int); +double_int double_int_umax (double_int, double_int); + +double_int double_int_min (double_int, double_int, bool); +double_int double_int_smin (double_int, double_int); +double_int double_int_umin (double_int, double_int); + void dump_double_int (FILE *, double_int, bool); /* Zero and sign extension of numbers in smaller precisions. */ @@ -134,6 +240,7 @@ void dump_double_int (FILE *, double_int, bool); double_int double_int_ext (double_int, unsigned, bool); double_int double_int_sext (double_int, unsigned); double_int double_int_zext (double_int, unsigned); +double_int double_int_mask (unsigned); #define ALL_ONES (~((unsigned HOST_WIDE_INT) 0)) @@ -173,4 +280,41 @@ double_int_equal_p (double_int cst1, double_int cst2) return cst1.low == cst2.low && cst1.high == cst2.high; } + +/* Legacy interface with decomposed high/low parts. */ + +extern int add_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT, + unsigned HOST_WIDE_INT, HOST_WIDE_INT, + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, + bool); +#define add_double(l1,h1,l2,h2,lv,hv) \ + add_double_with_sign (l1, h1, l2, h2, lv, hv, false) +extern int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT, + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *); +extern int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT, + unsigned HOST_WIDE_INT, HOST_WIDE_INT, + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, + bool); +#define mul_double(l1,h1,l2,h2,lv,hv) \ + mul_double_with_sign (l1, h1, l2, h2, lv, hv, false) +extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT, unsigned int, + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool); +extern void rshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT, unsigned int, + unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool); +extern int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT, + HOST_WIDE_INT, unsigned HOST_WIDE_INT, + HOST_WIDE_INT, unsigned HOST_WIDE_INT *, + HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, + HOST_WIDE_INT *); + + +#ifndef GENERATOR_FILE +/* Conversion to and from GMP integer representations. */ + +void mpz_set_double_int (mpz_t, double_int, bool); +double_int mpz_get_double_int (const_tree, mpz_t, bool); +#endif + #endif /* DOUBLE_INT_H */