1234567891011121314151617181920212223242526272829303132333435363738394041 |
- // SPDX-License-Identifier: GPL-3.0-or-later
- // Copyright © 2019 Ariadne Devos
- #ifndef _sHT_LOGIC_ARITHMETIC
- #define _sHT_LOGIC_ARITHMETIC
- #include <sHT/logic/failbit.h>
- /** The variable really is in ℕ (for proofs), but
- the range supported by the computer is limited.
- The actual value the code sees may wrap-around,
- so that must always be checked -- with the following
- functions. */
- #define sHT_overflowing
- /** Calculate a * b + c, tracking overflow
- (a, b, c : T, ret : T *, T ⊂ ℕ, M ∈ { uintN_t | N })
- Requires:
- - good(M, *m) <-> { a, b, c } ⊂ \bounds(T)
- - (read ^ write) (*ret)
- - (read ^ write ^ set) (*mask)
- Invariant:
- - failvalue(M, *m)
- Ensures:
- - good(M, *m) := good(M, old *m) ^ (a * b + c ∈ \bounds(T))
- - ret = a * b + c */
- #define sHT_muladd_overflow(T, M, ret, a, b, c, m) \
- do { \
- /* Computation is correct, failure is always maintained,
- a, b and c are non-negative so failure is set on overflow. */ \
- sHT_fail_if(M, (m), __builtin_mul_overflow((a), (b), (ret))); \
- sHT_fail_if(M, (m), __builtin_add_overflow(*(ret), (c), (ret))); \
- } while (0)
- #endif
|