mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 11:40:10 +01:00
mesa: add u_overflow.h
It defines a couple of helpers to deal with signed and unsigned integers overflow. If __builtin_add_overflow (and others) intrinics are available they're used, otherwise overflow checks are done manually. Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37331>
This commit is contained in:
parent
66aefea02b
commit
cfbf745a79
3 changed files with 90 additions and 0 deletions
|
|
@ -1019,6 +1019,13 @@ foreach b : ['bswap32', 'bswap64', 'clz', 'clzll', 'ctz', 'expect', 'ffs',
|
||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
# Check for GCC overflow intrinsics
|
||||||
|
foreach b : ['add_overflow', 'add_overflow_p', 'sub_overflow_p']
|
||||||
|
if cc.has_function('__builtin_' + b)
|
||||||
|
pre_args += '-DHAVE___BUILTIN_@0@'.format(b.to_upper())
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
# check for GCC __attribute__
|
# check for GCC __attribute__
|
||||||
_attributes = [
|
_attributes = [
|
||||||
'const', 'flatten', 'malloc', 'pure', 'unused', 'warn_unused_result',
|
'const', 'flatten', 'malloc', 'pure', 'unused', 'warn_unused_result',
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ files_mesa_util = files(
|
||||||
'u_cpu_detect.h',
|
'u_cpu_detect.h',
|
||||||
'u_printf.c',
|
'u_printf.c',
|
||||||
'u_printf.h',
|
'u_printf.h',
|
||||||
|
'u_overflow.h',
|
||||||
'u_tristate.h',
|
'u_tristate.h',
|
||||||
'u_worklist.c',
|
'u_worklist.c',
|
||||||
'u_worklist.h',
|
'u_worklist.h',
|
||||||
|
|
|
||||||
82
src/util/u_overflow.h
Normal file
82
src/util/u_overflow.h
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2025 Advanced Micro Devices, Inc.
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
#include "util/macros.h"
|
||||||
|
|
||||||
|
#ifndef U_OVERFLOW_H
|
||||||
|
#define U_OVERFLOW_H
|
||||||
|
|
||||||
|
#ifdef HAVE___BUILTIN_ADD_OVERFLOW
|
||||||
|
#define util_add_overflow(ty, a, b, c) __builtin_add_overflow(a, b, c)
|
||||||
|
#else
|
||||||
|
#define DEFINE_U_ADD_OVERFLOW_UINT(ty) \
|
||||||
|
static inline bool \
|
||||||
|
util_add_overflow_##ty(ty a, ty b, ty * res) { \
|
||||||
|
*res = a + b; \
|
||||||
|
return *res < a; \
|
||||||
|
}
|
||||||
|
#define DEFINE_U_ADD_OVERFLOW_SINT(ty) \
|
||||||
|
static inline bool \
|
||||||
|
util_add_overflow_##ty(ty a, ty b, ty * res) { \
|
||||||
|
if ((b > 0 && a > u_intN_max(sizeof(a) * 8) - b) || \
|
||||||
|
(b < 0 && a < u_intN_min(sizeof(a) * 8) - b)) \
|
||||||
|
return true; \
|
||||||
|
*res = a + b; \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_U_ADD_OVERFLOW_UINT(size_t)
|
||||||
|
DEFINE_U_ADD_OVERFLOW_UINT(uint64_t)
|
||||||
|
DEFINE_U_ADD_OVERFLOW_SINT(int64_t)
|
||||||
|
|
||||||
|
#define util_add_overflow(ty, a, b, c) util_add_overflow_##ty(a, b, c)
|
||||||
|
#endif /* HAVE___BUILTIN_ADD_OVERFLOW */
|
||||||
|
|
||||||
|
#ifdef HAVE___BUILTIN_ADD_OVERFLOW_P
|
||||||
|
#define util_add_check_overflow(ty, a, b) __builtin_add_overflow_p(a, b, (ty)0)
|
||||||
|
#else
|
||||||
|
#define DEFINE_U_ADD_CHECK_OVERFLOW_UINT(ty) \
|
||||||
|
static inline bool \
|
||||||
|
util_add_check_overflow_##ty(ty a, ty b) { \
|
||||||
|
ty c = a + b; \
|
||||||
|
return c < a; \
|
||||||
|
}
|
||||||
|
#define DEFINE_U_ADD_CHECK_OVERFLOW_SINT(ty) \
|
||||||
|
static inline bool \
|
||||||
|
util_add_check_overflow_##ty(ty a, ty b) { \
|
||||||
|
return (b > 0 && a > u_intN_max(sizeof(a) * 8) - b) || \
|
||||||
|
(b < 0 && a < u_intN_min(sizeof(a) * 8) - b); \
|
||||||
|
}
|
||||||
|
DEFINE_U_ADD_CHECK_OVERFLOW_UINT(uint8_t)
|
||||||
|
DEFINE_U_ADD_CHECK_OVERFLOW_UINT(uint16_t)
|
||||||
|
DEFINE_U_ADD_CHECK_OVERFLOW_UINT(uint32_t)
|
||||||
|
DEFINE_U_ADD_CHECK_OVERFLOW_UINT(uint64_t)
|
||||||
|
|
||||||
|
DEFINE_U_ADD_CHECK_OVERFLOW_SINT(int8_t)
|
||||||
|
DEFINE_U_ADD_CHECK_OVERFLOW_SINT(int16_t)
|
||||||
|
DEFINE_U_ADD_CHECK_OVERFLOW_SINT(int32_t)
|
||||||
|
DEFINE_U_ADD_CHECK_OVERFLOW_SINT(int64_t)
|
||||||
|
|
||||||
|
#define util_add_check_overflow(ty, a, b) util_add_check_overflow_##ty(a, b)
|
||||||
|
#endif /* HAVE___BUILTIN_ADD_OVERFLOW_P */
|
||||||
|
|
||||||
|
#ifdef HAVE___BUILTIN_SUB_OVERFLOW_P
|
||||||
|
#define util_sub_check_overflow(ty, a, b) __builtin_sub_overflow_p(a, b, (ty)0)
|
||||||
|
#else
|
||||||
|
#define DEFINE_U_SUB_CHECK_OVERFLOW_SINT(ty) \
|
||||||
|
static inline bool \
|
||||||
|
util_sub_check_overflow_##ty(ty a, ty b) { \
|
||||||
|
return (b < 0 && a > u_intN_max(sizeof(a) * 8) + b) || \
|
||||||
|
(b > 0 && a < u_intN_min(sizeof(a) * 8) + b); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_U_SUB_CHECK_OVERFLOW_SINT(int8_t)
|
||||||
|
DEFINE_U_SUB_CHECK_OVERFLOW_SINT(int16_t)
|
||||||
|
DEFINE_U_SUB_CHECK_OVERFLOW_SINT(int32_t)
|
||||||
|
DEFINE_U_SUB_CHECK_OVERFLOW_SINT(int64_t)
|
||||||
|
|
||||||
|
#define util_sub_check_overflow(ty, a, b) util_sub_check_overflow_##ty(a, b)
|
||||||
|
#endif /* HAVE___BUILTIN_SUB_OVERFLOW_P */
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Reference in a new issue