(root)/
gcc-13.2.0/
gcc/
hwint.h
       1  /* HOST_WIDE_INT definitions for the GNU compiler.
       2     Copyright (C) 1998-2023 Free Software Foundation, Inc.
       3  
       4     This file is part of GCC.
       5  
       6     Provide definitions for macros which depend on HOST_BITS_PER_INT
       7     and HOST_BITS_PER_LONG.  */
       8  
       9  #ifndef GCC_HWINT_H
      10  #define GCC_HWINT_H
      11  
      12  /* This describes the machine the compiler is hosted on.  */
      13  #define HOST_BITS_PER_CHAR  CHAR_BIT
      14  #define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT)
      15  #define HOST_BITS_PER_INT   (CHAR_BIT * SIZEOF_INT)
      16  #define HOST_BITS_PER_LONG  (CHAR_BIT * SIZEOF_LONG)
      17  #define HOST_BITS_PER_PTR   (CHAR_BIT * SIZEOF_VOID_P)
      18  
      19  /* The string that should be inserted into a printf style format to
      20     indicate a "long" operand.  */
      21  #ifndef HOST_LONG_FORMAT
      22  #define HOST_LONG_FORMAT "l"
      23  #endif
      24  
      25  /* The string that should be inserted into a printf style format to
      26     indicate a "long long" operand.  */
      27  #ifndef HOST_LONG_LONG_FORMAT
      28  #define HOST_LONG_LONG_FORMAT "ll"
      29  #endif
      30  
      31  /* If HAVE_LONG_LONG and SIZEOF_LONG_LONG aren't defined, but
      32     GCC_VERSION >= 3000, assume this is the second or later stage of a
      33     bootstrap, we do have long long, and it's 64 bits.  (This is
      34     required by C99; we do have some ports that violate that assumption
      35     but they're all cross-compile-only.)  Just in case, force a
      36     constraint violation if that assumption is incorrect.  */
      37  #if !defined HAVE_LONG_LONG
      38  # if GCC_VERSION >= 3000
      39  #  define HAVE_LONG_LONG 1
      40  #  define SIZEOF_LONG_LONG 8
      41  extern char sizeof_long_long_must_be_8[sizeof (long long) == 8 ? 1 : -1];
      42  # endif
      43  #endif
      44  
      45  #ifdef HAVE_LONG_LONG
      46  # define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG)
      47  #endif
      48  
      49  /* Set HOST_WIDE_INT, this should be always 64 bits.
      50     The underlying type is matched to that of int64_t and assumed
      51     to be either long or long long.  */
      52  
      53  #define HOST_BITS_PER_WIDE_INT 64
      54  #if INT64_T_IS_LONG   
      55  #   define HOST_WIDE_INT long
      56  #   define HOST_WIDE_INT_C(X) X ## L
      57  #else
      58  # if HOST_BITS_PER_LONGLONG == 64
      59  #   define HOST_WIDE_INT long long
      60  #   define HOST_WIDE_INT_C(X) X ## LL
      61  # else
      62     #error "Unable to find a suitable type for HOST_WIDE_INT"
      63  # endif
      64  #endif
      65  
      66  #define HOST_WIDE_INT_UC(X) HOST_WIDE_INT_C (X ## U)
      67  #define HOST_WIDE_INT_0 HOST_WIDE_INT_C (0)
      68  #define HOST_WIDE_INT_0U HOST_WIDE_INT_UC (0)
      69  #define HOST_WIDE_INT_1 HOST_WIDE_INT_C (1)
      70  #define HOST_WIDE_INT_1U HOST_WIDE_INT_UC (1)
      71  #define HOST_WIDE_INT_M1 HOST_WIDE_INT_C (-1)
      72  #define HOST_WIDE_INT_M1U HOST_WIDE_INT_UC (-1)
      73  
      74  /* This is a magic identifier which allows GCC to figure out the type
      75     of HOST_WIDE_INT for %wd specifier checks.  You must issue this
      76     typedef before using the __asm_fprintf__ format attribute.  */
      77  typedef HOST_WIDE_INT __gcc_host_wide_int__;
      78  
      79  /* Provide C99 <inttypes.h> style format definitions for 64bits.  */
      80  #ifndef HAVE_INTTYPES_H
      81  #if INT64_T_IS_LONG
      82  # define GCC_PRI64 HOST_LONG_FORMAT
      83  #else
      84  # define GCC_PRI64 HOST_LONG_LONG_FORMAT
      85  #endif
      86  #undef PRId64
      87  #define PRId64 GCC_PRI64 "d"
      88  #undef PRIi64
      89  #define PRIi64 GCC_PRI64 "i"
      90  #undef PRIo64
      91  #define PRIo64 GCC_PRI64 "o"
      92  #undef PRIu64
      93  #define PRIu64 GCC_PRI64 "u"
      94  #undef PRIx64
      95  #define PRIx64 GCC_PRI64 "x"
      96  #undef PRIX64
      97  #define PRIX64 GCC_PRI64 "X"
      98  #endif
      99  
     100  /* Various printf format strings for HOST_WIDE_INT.  */
     101  
     102  #if INT64_T_IS_LONG
     103  # define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT
     104  # define HOST_WIDE_INT_PRINT_C "L"
     105  #else
     106  # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
     107  # define HOST_WIDE_INT_PRINT_C "LL"
     108  #endif
     109  
     110  #define HOST_WIDE_INT_PRINT_DEC "%" PRId64
     111  #define HOST_WIDE_INT_PRINT_DEC_C "%" PRId64 HOST_WIDE_INT_PRINT_C
     112  #define HOST_WIDE_INT_PRINT_UNSIGNED "%" PRIu64
     113  #define HOST_WIDE_INT_PRINT_HEX "%#" PRIx64
     114  #define HOST_WIDE_INT_PRINT_HEX_PURE "%" PRIx64
     115  #define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%" PRIx64 "%016" PRIx64
     116  #define HOST_WIDE_INT_PRINT_PADDED_HEX "%016" PRIx64
     117  
     118  /* Define HOST_WIDEST_FAST_INT to the widest integer type supported
     119     efficiently in hardware.  (That is, the widest integer type that fits
     120     in a hardware register.)  Normally this is "long" but on some hosts it
     121     should be "long long" or "__int64".  This is no convenient way to
     122     autodetect this, so such systems must set a flag in config.host; see there
     123     for details.  */
     124  
     125  #ifdef USE_LONG_LONG_FOR_WIDEST_FAST_INT
     126  #  ifdef HAVE_LONG_LONG
     127  #    define HOST_WIDEST_FAST_INT long long
     128  #    define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONGLONG
     129  #  else
     130  #    error "Your host said it wanted to use long long but that does not exist"
     131  #  endif
     132  #else
     133  #  define HOST_WIDEST_FAST_INT long
     134  #  define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG
     135  #endif
     136  
     137  /* Inline functions operating on HOST_WIDE_INT.  */
     138  
     139  /* Return X with all but the lowest bit masked off.  */
     140  
     141  inline unsigned HOST_WIDE_INT
     142  least_bit_hwi (unsigned HOST_WIDE_INT x)
     143  {
     144    return (x & -x);
     145  }
     146  
     147  /* True if X is zero or a power of two.  */
     148  
     149  inline bool
     150  pow2_or_zerop (unsigned HOST_WIDE_INT x)
     151  {
     152    return least_bit_hwi (x) == x;
     153  }
     154  
     155  /* True if X is a power of two.  */
     156  
     157  inline bool
     158  pow2p_hwi (unsigned HOST_WIDE_INT x)
     159  {
     160    return x && pow2_or_zerop (x);
     161  }
     162  
     163  #if GCC_VERSION < 3004
     164  
     165  extern int clz_hwi (unsigned HOST_WIDE_INT x);
     166  extern int ctz_hwi (unsigned HOST_WIDE_INT x);
     167  extern int ffs_hwi (unsigned HOST_WIDE_INT x);
     168  
     169  /* Return the number of set bits in X.  */
     170  extern int popcount_hwi (unsigned HOST_WIDE_INT x);
     171  
     172  /* Return log2, or -1 if not exact.  */
     173  extern int exact_log2                  (unsigned HOST_WIDE_INT);
     174  
     175  /* Return floor of log2, with -1 for zero.  */
     176  extern int floor_log2                  (unsigned HOST_WIDE_INT);
     177  
     178  /* Return the smallest n such that 2**n >= X.  */
     179  extern int ceil_log2			(unsigned HOST_WIDE_INT);
     180  
     181  #else /* GCC_VERSION >= 3004 */
     182  
     183  /* For convenience, define 0 -> word_size.  */
     184  inline int
     185  clz_hwi (unsigned HOST_WIDE_INT x)
     186  {
     187    if (x == 0)
     188      return HOST_BITS_PER_WIDE_INT;
     189  # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
     190    return __builtin_clzl (x);
     191  # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
     192    return __builtin_clzll (x);
     193  # else
     194    return __builtin_clz (x);
     195  # endif
     196  }
     197  
     198  inline int
     199  ctz_hwi (unsigned HOST_WIDE_INT x)
     200  {
     201    if (x == 0)
     202      return HOST_BITS_PER_WIDE_INT;
     203  # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
     204    return __builtin_ctzl (x);
     205  # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
     206    return __builtin_ctzll (x);
     207  # else
     208    return __builtin_ctz (x);
     209  # endif
     210  }
     211  
     212  inline int
     213  ffs_hwi (unsigned HOST_WIDE_INT x)
     214  {
     215  # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
     216    return __builtin_ffsl (x);
     217  # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
     218    return __builtin_ffsll (x);
     219  # else
     220    return __builtin_ffs (x);
     221  # endif
     222  }
     223  
     224  inline int
     225  popcount_hwi (unsigned HOST_WIDE_INT x)
     226  {
     227  # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
     228    return __builtin_popcountl (x);
     229  # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
     230    return __builtin_popcountll (x);
     231  # else
     232    return __builtin_popcount (x);
     233  # endif
     234  }
     235  
     236  inline int
     237  floor_log2 (unsigned HOST_WIDE_INT x)
     238  {
     239    return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x);
     240  }
     241  
     242  inline int
     243  ceil_log2 (unsigned HOST_WIDE_INT x)
     244  {
     245    return x == 0 ? 0 : floor_log2 (x - 1) + 1;
     246  }
     247  
     248  inline int
     249  exact_log2 (unsigned HOST_WIDE_INT x)
     250  {
     251    return pow2p_hwi (x) ? ctz_hwi (x) : -1;
     252  }
     253  
     254  #endif /* GCC_VERSION >= 3004 */
     255  
     256  #define HOST_WIDE_INT_MIN (HOST_WIDE_INT) \
     257    (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1))
     258  #define HOST_WIDE_INT_MAX (~(HOST_WIDE_INT_MIN))
     259  
     260  extern HOST_WIDE_INT abs_hwi (HOST_WIDE_INT);
     261  extern unsigned HOST_WIDE_INT absu_hwi (HOST_WIDE_INT);
     262  extern HOST_WIDE_INT gcd (HOST_WIDE_INT, HOST_WIDE_INT);
     263  extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
     264  extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
     265  extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
     266  
     267  /* Like ctz_hwi, except 0 when x == 0.  */
     268  
     269  inline int
     270  ctz_or_zero (unsigned HOST_WIDE_INT x)
     271  {
     272    return ffs_hwi (x) - 1;
     273  }
     274  
     275  /* Sign extend SRC starting from PREC.  */
     276  
     277  inline HOST_WIDE_INT
     278  sext_hwi (HOST_WIDE_INT src, unsigned int prec)
     279  {
     280    if (prec == HOST_BITS_PER_WIDE_INT)
     281      return src;
     282    else
     283  #if defined (__GNUC__)
     284      {
     285        /* Take the faster path if the implementation-defined bits it's relying
     286  	 on are implemented the way we expect them to be.  Namely, conversion
     287  	 from unsigned to signed preserves bit pattern, and right shift of
     288  	 a signed value propagates the sign bit.
     289  	 We have to convert from signed to unsigned and back, because when left
     290  	 shifting signed values, any overflow is undefined behavior.  */
     291        gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT);
     292        int shift = HOST_BITS_PER_WIDE_INT - prec;
     293        return ((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) src << shift)) >> shift;
     294      }
     295  #else
     296      {
     297        /* Fall back to the slower, well defined path otherwise.  */
     298        gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT);
     299        HOST_WIDE_INT sign_mask = HOST_WIDE_INT_1 << (prec - 1);
     300        HOST_WIDE_INT value_mask = (HOST_WIDE_INT_1U << prec) - HOST_WIDE_INT_1U;
     301        return (((src & value_mask) ^ sign_mask) - sign_mask);
     302      }
     303  #endif
     304  }
     305  
     306  /* Zero extend SRC starting from PREC.  */
     307  inline unsigned HOST_WIDE_INT
     308  zext_hwi (unsigned HOST_WIDE_INT src, unsigned int prec)
     309  {
     310    if (prec == HOST_BITS_PER_WIDE_INT)
     311      return src;
     312    else
     313      {
     314        gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT);
     315        return src & ((HOST_WIDE_INT_1U << prec) - 1);
     316      }
     317  }
     318  
     319  /* Compute the absolute value of X.  */
     320  
     321  inline HOST_WIDE_INT
     322  abs_hwi (HOST_WIDE_INT x)
     323  {
     324    gcc_checking_assert (x != HOST_WIDE_INT_MIN);
     325    return x >= 0 ? x : -x;
     326  }
     327  
     328  /* Compute the absolute value of X as an unsigned type.  */
     329  
     330  inline unsigned HOST_WIDE_INT
     331  absu_hwi (HOST_WIDE_INT x)
     332  {
     333    return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x;
     334  }
     335  
     336  /* Compute the sum of signed A and B and indicate in *OVERFLOW whether
     337     that operation overflowed.  */
     338  
     339  inline HOST_WIDE_INT
     340  add_hwi (HOST_WIDE_INT a, HOST_WIDE_INT b, bool *overflow)
     341  {
     342  #if GCC_VERSION < 11000
     343    unsigned HOST_WIDE_INT result = a + (unsigned HOST_WIDE_INT)b;
     344    if ((((result ^ a) & (result ^ b))
     345         >> (HOST_BITS_PER_WIDE_INT - 1)) & 1)
     346      *overflow = true;
     347    else
     348      *overflow = false;
     349    return result;
     350  #else
     351    HOST_WIDE_INT result;
     352    *overflow = __builtin_add_overflow (a, b, &result);
     353    return result;
     354  #endif
     355  }
     356  
     357  /* Compute the product of signed A and B and indicate in *OVERFLOW whether
     358     that operation overflowed.  */
     359  
     360  inline HOST_WIDE_INT
     361  mul_hwi (HOST_WIDE_INT a, HOST_WIDE_INT b, bool *overflow)
     362  {
     363  #if GCC_VERSION < 11000
     364    unsigned HOST_WIDE_INT result = a * (unsigned HOST_WIDE_INT)b;
     365    if ((a == -1 && b == HOST_WIDE_INT_MIN)
     366        || (a != 0 && (HOST_WIDE_INT)result / a != b))
     367      *overflow = true;
     368    else
     369      *overflow = false;
     370    return result;
     371  #else
     372    HOST_WIDE_INT result;
     373    *overflow = __builtin_mul_overflow (a, b, &result);
     374    return result;
     375  #endif
     376  }
     377  
     378  #endif /* ! GCC_HWINT_H */