diff options
Diffstat (limited to 'lib/gcc/arm-none-eabi/13.2.1/plugin/include/hwint.h')
-rw-r--r-- | lib/gcc/arm-none-eabi/13.2.1/plugin/include/hwint.h | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/lib/gcc/arm-none-eabi/13.2.1/plugin/include/hwint.h b/lib/gcc/arm-none-eabi/13.2.1/plugin/include/hwint.h new file mode 100644 index 0000000..427e9b9 --- /dev/null +++ b/lib/gcc/arm-none-eabi/13.2.1/plugin/include/hwint.h @@ -0,0 +1,378 @@ +/* HOST_WIDE_INT definitions for the GNU compiler. + Copyright (C) 1998-2023 Free Software Foundation, Inc. + + This file is part of GCC. + + Provide definitions for macros which depend on HOST_BITS_PER_INT + and HOST_BITS_PER_LONG. */ + +#ifndef GCC_HWINT_H +#define GCC_HWINT_H + +/* This describes the machine the compiler is hosted on. */ +#define HOST_BITS_PER_CHAR CHAR_BIT +#define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT) +#define HOST_BITS_PER_INT (CHAR_BIT * SIZEOF_INT) +#define HOST_BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG) +#define HOST_BITS_PER_PTR (CHAR_BIT * SIZEOF_VOID_P) + +/* The string that should be inserted into a printf style format to + indicate a "long" operand. */ +#ifndef HOST_LONG_FORMAT +#define HOST_LONG_FORMAT "l" +#endif + +/* The string that should be inserted into a printf style format to + indicate a "long long" operand. */ +#ifndef HOST_LONG_LONG_FORMAT +#define HOST_LONG_LONG_FORMAT "ll" +#endif + +/* If HAVE_LONG_LONG and SIZEOF_LONG_LONG aren't defined, but + GCC_VERSION >= 3000, assume this is the second or later stage of a + bootstrap, we do have long long, and it's 64 bits. (This is + required by C99; we do have some ports that violate that assumption + but they're all cross-compile-only.) Just in case, force a + constraint violation if that assumption is incorrect. */ +#if !defined HAVE_LONG_LONG +# if GCC_VERSION >= 3000 +# define HAVE_LONG_LONG 1 +# define SIZEOF_LONG_LONG 8 +extern char sizeof_long_long_must_be_8[sizeof (long long) == 8 ? 1 : -1]; +# endif +#endif + +#ifdef HAVE_LONG_LONG +# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG) +#endif + +/* Set HOST_WIDE_INT, this should be always 64 bits. + The underlying type is matched to that of int64_t and assumed + to be either long or long long. */ + +#define HOST_BITS_PER_WIDE_INT 64 +#if INT64_T_IS_LONG +# define HOST_WIDE_INT long +# define HOST_WIDE_INT_C(X) X ## L +#else +# if HOST_BITS_PER_LONGLONG == 64 +# define HOST_WIDE_INT long long +# define HOST_WIDE_INT_C(X) X ## LL +# else + #error "Unable to find a suitable type for HOST_WIDE_INT" +# endif +#endif + +#define HOST_WIDE_INT_UC(X) HOST_WIDE_INT_C (X ## U) +#define HOST_WIDE_INT_0 HOST_WIDE_INT_C (0) +#define HOST_WIDE_INT_0U HOST_WIDE_INT_UC (0) +#define HOST_WIDE_INT_1 HOST_WIDE_INT_C (1) +#define HOST_WIDE_INT_1U HOST_WIDE_INT_UC (1) +#define HOST_WIDE_INT_M1 HOST_WIDE_INT_C (-1) +#define HOST_WIDE_INT_M1U HOST_WIDE_INT_UC (-1) + +/* This is a magic identifier which allows GCC to figure out the type + of HOST_WIDE_INT for %wd specifier checks. You must issue this + typedef before using the __asm_fprintf__ format attribute. */ +typedef HOST_WIDE_INT __gcc_host_wide_int__; + +/* Provide C99 <inttypes.h> style format definitions for 64bits. */ +#ifndef HAVE_INTTYPES_H +#if INT64_T_IS_LONG +# define GCC_PRI64 HOST_LONG_FORMAT +#else +# define GCC_PRI64 HOST_LONG_LONG_FORMAT +#endif +#undef PRId64 +#define PRId64 GCC_PRI64 "d" +#undef PRIi64 +#define PRIi64 GCC_PRI64 "i" +#undef PRIo64 +#define PRIo64 GCC_PRI64 "o" +#undef PRIu64 +#define PRIu64 GCC_PRI64 "u" +#undef PRIx64 +#define PRIx64 GCC_PRI64 "x" +#undef PRIX64 +#define PRIX64 GCC_PRI64 "X" +#endif + +/* Various printf format strings for HOST_WIDE_INT. */ + +#if INT64_T_IS_LONG +# define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT +# define HOST_WIDE_INT_PRINT_C "L" +#else +# define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT +# define HOST_WIDE_INT_PRINT_C "LL" +#endif + +#define HOST_WIDE_INT_PRINT_DEC "%" PRId64 +#define HOST_WIDE_INT_PRINT_DEC_C "%" PRId64 HOST_WIDE_INT_PRINT_C +#define HOST_WIDE_INT_PRINT_UNSIGNED "%" PRIu64 +#define HOST_WIDE_INT_PRINT_HEX "%#" PRIx64 +#define HOST_WIDE_INT_PRINT_HEX_PURE "%" PRIx64 +#define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%" PRIx64 "%016" PRIx64 +#define HOST_WIDE_INT_PRINT_PADDED_HEX "%016" PRIx64 + +/* Define HOST_WIDEST_FAST_INT to the widest integer type supported + efficiently in hardware. (That is, the widest integer type that fits + in a hardware register.) Normally this is "long" but on some hosts it + should be "long long" or "__int64". This is no convenient way to + autodetect this, so such systems must set a flag in config.host; see there + for details. */ + +#ifdef USE_LONG_LONG_FOR_WIDEST_FAST_INT +# ifdef HAVE_LONG_LONG +# define HOST_WIDEST_FAST_INT long long +# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONGLONG +# else +# error "Your host said it wanted to use long long but that does not exist" +# endif +#else +# define HOST_WIDEST_FAST_INT long +# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG +#endif + +/* Inline functions operating on HOST_WIDE_INT. */ + +/* Return X with all but the lowest bit masked off. */ + +inline unsigned HOST_WIDE_INT +least_bit_hwi (unsigned HOST_WIDE_INT x) +{ + return (x & -x); +} + +/* True if X is zero or a power of two. */ + +inline bool +pow2_or_zerop (unsigned HOST_WIDE_INT x) +{ + return least_bit_hwi (x) == x; +} + +/* True if X is a power of two. */ + +inline bool +pow2p_hwi (unsigned HOST_WIDE_INT x) +{ + return x && pow2_or_zerop (x); +} + +#if GCC_VERSION < 3004 + +extern int clz_hwi (unsigned HOST_WIDE_INT x); +extern int ctz_hwi (unsigned HOST_WIDE_INT x); +extern int ffs_hwi (unsigned HOST_WIDE_INT x); + +/* Return the number of set bits in X. */ +extern int popcount_hwi (unsigned HOST_WIDE_INT x); + +/* Return log2, or -1 if not exact. */ +extern int exact_log2 (unsigned HOST_WIDE_INT); + +/* Return floor of log2, with -1 for zero. */ +extern int floor_log2 (unsigned HOST_WIDE_INT); + +/* Return the smallest n such that 2**n >= X. */ +extern int ceil_log2 (unsigned HOST_WIDE_INT); + +#else /* GCC_VERSION >= 3004 */ + +/* For convenience, define 0 -> word_size. */ +inline int +clz_hwi (unsigned HOST_WIDE_INT x) +{ + if (x == 0) + return HOST_BITS_PER_WIDE_INT; +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG + return __builtin_clzl (x); +# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG + return __builtin_clzll (x); +# else + return __builtin_clz (x); +# endif +} + +inline int +ctz_hwi (unsigned HOST_WIDE_INT x) +{ + if (x == 0) + return HOST_BITS_PER_WIDE_INT; +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG + return __builtin_ctzl (x); +# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG + return __builtin_ctzll (x); +# else + return __builtin_ctz (x); +# endif +} + +inline int +ffs_hwi (unsigned HOST_WIDE_INT x) +{ +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG + return __builtin_ffsl (x); +# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG + return __builtin_ffsll (x); +# else + return __builtin_ffs (x); +# endif +} + +inline int +popcount_hwi (unsigned HOST_WIDE_INT x) +{ +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG + return __builtin_popcountl (x); +# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG + return __builtin_popcountll (x); +# else + return __builtin_popcount (x); +# endif +} + +inline int +floor_log2 (unsigned HOST_WIDE_INT x) +{ + return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x); +} + +inline int +ceil_log2 (unsigned HOST_WIDE_INT x) +{ + return x == 0 ? 0 : floor_log2 (x - 1) + 1; +} + +inline int +exact_log2 (unsigned HOST_WIDE_INT x) +{ + return pow2p_hwi (x) ? ctz_hwi (x) : -1; +} + +#endif /* GCC_VERSION >= 3004 */ + +#define HOST_WIDE_INT_MIN (HOST_WIDE_INT) \ + (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1)) +#define HOST_WIDE_INT_MAX (~(HOST_WIDE_INT_MIN)) + +extern HOST_WIDE_INT abs_hwi (HOST_WIDE_INT); +extern unsigned HOST_WIDE_INT absu_hwi (HOST_WIDE_INT); +extern HOST_WIDE_INT gcd (HOST_WIDE_INT, HOST_WIDE_INT); +extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT); +extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT); +extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT); + +/* Like ctz_hwi, except 0 when x == 0. */ + +inline int +ctz_or_zero (unsigned HOST_WIDE_INT x) +{ + return ffs_hwi (x) - 1; +} + +/* Sign extend SRC starting from PREC. */ + +inline HOST_WIDE_INT +sext_hwi (HOST_WIDE_INT src, unsigned int prec) +{ + if (prec == HOST_BITS_PER_WIDE_INT) + return src; + else +#if defined (__GNUC__) + { + /* Take the faster path if the implementation-defined bits it's relying + on are implemented the way we expect them to be. Namely, conversion + from unsigned to signed preserves bit pattern, and right shift of + a signed value propagates the sign bit. + We have to convert from signed to unsigned and back, because when left + shifting signed values, any overflow is undefined behavior. */ + gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT); + int shift = HOST_BITS_PER_WIDE_INT - prec; + return ((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) src << shift)) >> shift; + } +#else + { + /* Fall back to the slower, well defined path otherwise. */ + gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT); + HOST_WIDE_INT sign_mask = HOST_WIDE_INT_1 << (prec - 1); + HOST_WIDE_INT value_mask = (HOST_WIDE_INT_1U << prec) - HOST_WIDE_INT_1U; + return (((src & value_mask) ^ sign_mask) - sign_mask); + } +#endif +} + +/* Zero extend SRC starting from PREC. */ +inline unsigned HOST_WIDE_INT +zext_hwi (unsigned HOST_WIDE_INT src, unsigned int prec) +{ + if (prec == HOST_BITS_PER_WIDE_INT) + return src; + else + { + gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT); + return src & ((HOST_WIDE_INT_1U << prec) - 1); + } +} + +/* Compute the absolute value of X. */ + +inline HOST_WIDE_INT +abs_hwi (HOST_WIDE_INT x) +{ + gcc_checking_assert (x != HOST_WIDE_INT_MIN); + return x >= 0 ? x : -x; +} + +/* Compute the absolute value of X as an unsigned type. */ + +inline unsigned HOST_WIDE_INT +absu_hwi (HOST_WIDE_INT x) +{ + return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x; +} + +/* Compute the sum of signed A and B and indicate in *OVERFLOW whether + that operation overflowed. */ + +inline HOST_WIDE_INT +add_hwi (HOST_WIDE_INT a, HOST_WIDE_INT b, bool *overflow) +{ +#if GCC_VERSION < 11000 + unsigned HOST_WIDE_INT result = a + (unsigned HOST_WIDE_INT)b; + if ((((result ^ a) & (result ^ b)) + >> (HOST_BITS_PER_WIDE_INT - 1)) & 1) + *overflow = true; + else + *overflow = false; + return result; +#else + HOST_WIDE_INT result; + *overflow = __builtin_add_overflow (a, b, &result); + return result; +#endif +} + +/* Compute the product of signed A and B and indicate in *OVERFLOW whether + that operation overflowed. */ + +inline HOST_WIDE_INT +mul_hwi (HOST_WIDE_INT a, HOST_WIDE_INT b, bool *overflow) +{ +#if GCC_VERSION < 11000 + unsigned HOST_WIDE_INT result = a * (unsigned HOST_WIDE_INT)b; + if ((a == -1 && b == HOST_WIDE_INT_MIN) + || (a != 0 && (HOST_WIDE_INT)result / a != b)) + *overflow = true; + else + *overflow = false; + return result; +#else + HOST_WIDE_INT result; + *overflow = __builtin_mul_overflow (a, b, &result); + return result; +#endif +} + +#endif /* ! GCC_HWINT_H */ |