diff options
Diffstat (limited to 'gcc/hwint.h')
-rw-r--r-- | gcc/hwint.h | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/gcc/hwint.h b/gcc/hwint.h index 127b013..0e895f8 100644 --- a/gcc/hwint.h +++ b/gcc/hwint.h @@ -333,4 +333,46 @@ 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 */ |