summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qglobal.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2015-06-09 17:09:18 -0700
committerThiago Macieira <thiago.macieira@intel.com>2015-09-23 16:19:45 +0000
commit29bc68cf169b8cf87d306a1c72e12eb9b6fbfce7 (patch)
tree53b5602e4b8f373b7c7154865171e033d1b01598 /src/corelib/global/qglobal.h
parent0396c7a7d89b0813b997076a52c3f29fb3a0e919 (diff)
Add code to perform overflow-checking additions and multiplication
Most processors have carry flags which they set on addition overflow, so it's a good idea to access them whenever possible. Most of them also have widening multiply instructions that can be used to detect overflow of the non-widening version. Tested to compile on: Architecture Compiler x86 GCC 4.9, GCC 5*, Clang 3.6*, ICC 16 beta x86-64 GCC 4.9, GCC 5*, Clang 3.6*, ICC 16 beta x86-64 ILP32 GCC 4.9, GCC 5*, Clang 3.6* IA-64 LP64 GCC 4.8 ARMv7-A GCC 4.9, Clang 3.6* AArch64 Clang 3.6* MIPS GCC 4.9, Clang 3.6* MIPS64 GCC 4.9, Clang 3.6* PowerPC GCC 4.9, Clang 3.6* PowerPC 64 GCC 4.9, Clang 3.6* SPARC Clang 3.6* SPARCv9 Clang 3.6* [*] supports the intrinsics If the compiler does not offer a way to detect an overflow, we do it by hand. For unsigned additions, that's easy, since the C++ language specifies the behavior of the overflow. That's also the reason why this code is implemented only for unsigned integers. For the multiplication, if the compiler does not support widening multiplications, we do it with a division instead. This is necessary for GCC < 4.5 and compilers not compatible with GCC or MSVC. Change-Id: I049a653beeb5454c9539ffff13e637de0f1338c1 Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com> Reviewed-by: Alex Trotsenko <alex1973tr@gmail.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/global/qglobal.h')
-rw-r--r--src/corelib/global/qglobal.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index f8f306f614..6ee3e37ce6 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -448,6 +448,9 @@ template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qin
template <> struct QIntegerForSize<2> { typedef quint16 Unsigned; typedef qint16 Signed; };
template <> struct QIntegerForSize<4> { typedef quint32 Unsigned; typedef qint32 Signed; };
template <> struct QIntegerForSize<8> { typedef quint64 Unsigned; typedef qint64 Signed; };
+#if defined(Q_CC_GNU) && defined(__SIZEOF_INT128__)
+template <> struct QIntegerForSize<16> { __extension__ typedef unsigned __int128 Unsigned; __extension__ typedef __int128 Signed; };
+#endif
template <class T> struct QIntegerForSizeof: QIntegerForSize<sizeof(T)> { };
typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Signed qregisterint;
typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Unsigned qregisteruint;