aboutsummaryrefslogtreecommitdiff
path: root/gcc/hwint.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/hwint.h')
-rw-r--r--gcc/hwint.h42
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 */