17c2aad20Sopenharmony_ci/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
27c2aad20Sopenharmony_ci
37c2aad20Sopenharmony_ci#ifndef __LINUX_OVERFLOW_H
47c2aad20Sopenharmony_ci#define __LINUX_OVERFLOW_H
57c2aad20Sopenharmony_ci
67c2aad20Sopenharmony_ci#define is_signed_type(type)	(((type)(-1)) < (type)1)
77c2aad20Sopenharmony_ci#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
87c2aad20Sopenharmony_ci#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
97c2aad20Sopenharmony_ci#define type_min(T) ((T)((T)-type_max(T)-(T)1))
107c2aad20Sopenharmony_ci
117c2aad20Sopenharmony_ci#ifndef unlikely
127c2aad20Sopenharmony_ci#define unlikely(x)	__builtin_expect(!!(x), 0)
137c2aad20Sopenharmony_ci#endif
147c2aad20Sopenharmony_ci
157c2aad20Sopenharmony_ci#ifdef __GNUC__
167c2aad20Sopenharmony_ci#define GCC_VERSION (__GNUC__ * 10000           \
177c2aad20Sopenharmony_ci                     + __GNUC_MINOR__ * 100     \
187c2aad20Sopenharmony_ci                     + __GNUC_PATCHLEVEL__)
197c2aad20Sopenharmony_ci#if GCC_VERSION >= 50100
207c2aad20Sopenharmony_ci#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
217c2aad20Sopenharmony_ci#endif
227c2aad20Sopenharmony_ci#endif
237c2aad20Sopenharmony_ci
247c2aad20Sopenharmony_ci#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
257c2aad20Sopenharmony_ci
267c2aad20Sopenharmony_ci#define check_mul_overflow(a, b, d) ({		\
277c2aad20Sopenharmony_ci	typeof(a) __a = (a);			\
287c2aad20Sopenharmony_ci	typeof(b) __b = (b);			\
297c2aad20Sopenharmony_ci	typeof(d) __d = (d);			\
307c2aad20Sopenharmony_ci	(void) (&__a == &__b);			\
317c2aad20Sopenharmony_ci	(void) (&__a == __d);			\
327c2aad20Sopenharmony_ci	__builtin_mul_overflow(__a, __b, __d);	\
337c2aad20Sopenharmony_ci})
347c2aad20Sopenharmony_ci
357c2aad20Sopenharmony_ci#else
367c2aad20Sopenharmony_ci
377c2aad20Sopenharmony_ci/*
387c2aad20Sopenharmony_ci * If one of a or b is a compile-time constant, this avoids a division.
397c2aad20Sopenharmony_ci */
407c2aad20Sopenharmony_ci#define __unsigned_mul_overflow(a, b, d) ({		\
417c2aad20Sopenharmony_ci	typeof(a) __a = (a);				\
427c2aad20Sopenharmony_ci	typeof(b) __b = (b);				\
437c2aad20Sopenharmony_ci	typeof(d) __d = (d);				\
447c2aad20Sopenharmony_ci	(void) (&__a == &__b);				\
457c2aad20Sopenharmony_ci	(void) (&__a == __d);				\
467c2aad20Sopenharmony_ci	*__d = __a * __b;				\
477c2aad20Sopenharmony_ci	__builtin_constant_p(__b) ?			\
487c2aad20Sopenharmony_ci	  __b > 0 && __a > type_max(typeof(__a)) / __b : \
497c2aad20Sopenharmony_ci	  __a > 0 && __b > type_max(typeof(__b)) / __a;	 \
507c2aad20Sopenharmony_ci})
517c2aad20Sopenharmony_ci
527c2aad20Sopenharmony_ci/*
537c2aad20Sopenharmony_ci * Signed multiplication is rather hard. gcc always follows C99, so
547c2aad20Sopenharmony_ci * division is truncated towards 0. This means that we can write the
557c2aad20Sopenharmony_ci * overflow check like this:
567c2aad20Sopenharmony_ci *
577c2aad20Sopenharmony_ci * (a > 0 && (b > MAX/a || b < MIN/a)) ||
587c2aad20Sopenharmony_ci * (a < -1 && (b > MIN/a || b < MAX/a) ||
597c2aad20Sopenharmony_ci * (a == -1 && b == MIN)
607c2aad20Sopenharmony_ci *
617c2aad20Sopenharmony_ci * The redundant casts of -1 are to silence an annoying -Wtype-limits
627c2aad20Sopenharmony_ci * (included in -Wextra) warning: When the type is u8 or u16, the
637c2aad20Sopenharmony_ci * __b_c_e in check_mul_overflow obviously selects
647c2aad20Sopenharmony_ci * __unsigned_mul_overflow, but unfortunately gcc still parses this
657c2aad20Sopenharmony_ci * code and warns about the limited range of __b.
667c2aad20Sopenharmony_ci */
677c2aad20Sopenharmony_ci
687c2aad20Sopenharmony_ci#define __signed_mul_overflow(a, b, d) ({				\
697c2aad20Sopenharmony_ci	typeof(a) __a = (a);						\
707c2aad20Sopenharmony_ci	typeof(b) __b = (b);						\
717c2aad20Sopenharmony_ci	typeof(d) __d = (d);						\
727c2aad20Sopenharmony_ci	typeof(a) __tmax = type_max(typeof(a));				\
737c2aad20Sopenharmony_ci	typeof(a) __tmin = type_min(typeof(a));				\
747c2aad20Sopenharmony_ci	(void) (&__a == &__b);						\
757c2aad20Sopenharmony_ci	(void) (&__a == __d);						\
767c2aad20Sopenharmony_ci	*__d = (__u64)__a * (__u64)__b;					\
777c2aad20Sopenharmony_ci	(__b > 0   && (__a > __tmax/__b || __a < __tmin/__b)) ||	\
787c2aad20Sopenharmony_ci	(__b < (typeof(__b))-1  && (__a > __tmin/__b || __a < __tmax/__b)) || \
797c2aad20Sopenharmony_ci	(__b == (typeof(__b))-1 && __a == __tmin);			\
807c2aad20Sopenharmony_ci})
817c2aad20Sopenharmony_ci
827c2aad20Sopenharmony_ci#define check_mul_overflow(a, b, d)					\
837c2aad20Sopenharmony_ci	__builtin_choose_expr(is_signed_type(typeof(a)),		\
847c2aad20Sopenharmony_ci			__signed_mul_overflow(a, b, d),			\
857c2aad20Sopenharmony_ci			__unsigned_mul_overflow(a, b, d))
867c2aad20Sopenharmony_ci
877c2aad20Sopenharmony_ci
887c2aad20Sopenharmony_ci#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
897c2aad20Sopenharmony_ci
907c2aad20Sopenharmony_ci#endif
91