3961 lines
144 KiB
C
Executable File
3961 lines
144 KiB
C
Executable File
/*
|
|
is parametrized: no
|
|
*/
|
|
|
|
/*
|
|
// Functions for safely checking for over- and underflow of arithmetic operations
|
|
|
|
guf_math_ckd_result guf_ckd_add_TYPE(TYPE a, TYPE b);
|
|
- if a + b doesn't over/underflow TYPE: return GUF_MATH_CKD_SUCCESS (falsy)
|
|
- if a + b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (truthy)
|
|
- if a + b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (truthy)
|
|
|
|
guf_math_ckd_result guf_ckd_sub_TYPE(TYPE a, TYPE b);
|
|
- if a - b doesn't over/underflow TYPE: return GUF_MATH_CKD_SUCCESS (falsy)
|
|
- if a - b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (truthy)
|
|
- if a - b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (truthy)
|
|
|
|
guf_math_ckd_result guf_ckd_mul_TYPE(TYPE a, TYPE b);
|
|
- if a * b doesn't over/underflow TYPE: return GUF_MATH_CKD_SUCCESS (falsy)
|
|
- if a * b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (truthy)
|
|
- if a * b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (truthy)
|
|
|
|
|
|
// Functions for safely computing arithmetic operations with saturating over- and underflow semantics
|
|
// (cf. https://doc.rust-lang.org/std/intrinsics/fn.saturating_add.html (last-retrieved 2025-05-10))
|
|
|
|
guf_math_ckd_result guf_saturating_add_TYPE(TYPE a, TYPE b, TYPE *result);
|
|
- if a + b does not over-/underflow TYPE: return GUF_MATH_CKD_SUCCESS (if result is not NULL, set result to a + b)
|
|
- if a + b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (if result is not NULL, set result to TYPE_MAX, i.e. use saturating overflow semantics).
|
|
- if a + b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (if result is not NULL, set result to TYPE_MIN, i.e. use saturating underflow semantics).
|
|
|
|
guf_math_ckd_result guf_saturating_sub_TYPE(TYPE a, TYPE b, TYPE *result);
|
|
- if a - b does not over-/underflow TYPE: return GUF_MATH_CKD_SUCCESS (if result is not NULL, set result to a - b)
|
|
- if a - b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (if result is not NULL, set result to TYPE_MAX, i.e. use saturating overflow semantics).
|
|
- if a - b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (if result is not NULL, set result to TYPE_MIN, i.e. use saturating underflow semantics).
|
|
|
|
guf_math_ckd_result guf_saturating_mul_TYPE(TYPE a, TYPE b, TYPE *result);
|
|
- if a * b does not over-/underflow TYPE: return GUF_MATH_CKD_SUCCESS (if result is not NULL, set result to a * b)
|
|
- if a * b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (if result is not NULL, set result to TYPE_MAX, i.e. use saturating overflow semantics).
|
|
- if a * b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (if result is not NULL, set result to TYPE_MIN, i.e. use saturating underflow semantics).
|
|
|
|
|
|
// Functions for safely computing arithmetic operations with wrapping over- and underflow semantics
|
|
// (cf. https://doc.rust-lang.org/std/intrinsics/fn.wrapping_add.html (last-retrieved 2025-05-10))
|
|
|
|
guf_math_ckd_result guf_wrapping_add_TYPE(TYPE a, TYPE b, TYPE *result);
|
|
- if a + b does not over-/underflow TYPE: return GUF_MATH_CKD_SUCCESS (if result is not NULL, set result to a + b)
|
|
- if a + b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (if result is not NULL, set result using two's complement wrap-around overflow semantics).
|
|
- if a + b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (if result is not NULL, set result using two's complement wrap-around underflow semantics).
|
|
|
|
guf_math_ckd_result guf_wrapping_sub_TYPE(TYPE a, TYPE b, TYPE *result);
|
|
- if a - b doesn't over-/underflow TYPE: return GUF_MATH_CKD_SUCCESS (if result is not NULL, set result to a - b)
|
|
- if a - b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (if result is not NULL, set result using two's complement wrap-around overflow semantics).
|
|
- if a - b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (if result is not NULL, set result using two's complement wrap-around underflow semantics).
|
|
|
|
guf_math_ckd_result guf_wrapping_mul_TYPE(TYPE a, TYPE b, TYPE *result);
|
|
// NOTE/TODO: guf_wrapping_mul_TYPE relies on implementation-defined unsigned-to-signed two's complement conversion on over/underflow
|
|
// cf. https://stackoverflow.com/questions/76900522/can-you-ensure-overflow-wrapping-behavior-for-signed-integer-arithmetic-in-c (last-retrieved 2025-05-13)
|
|
- if a * b doesn't over-/underflow TYPE: return GUF_MATH_CKD_SUCCESS (if result is not NULL, set result to a * b)
|
|
- if a * b overflows TYPE: return GUF_MATH_CKD_OVERFLOW_POS (if result is not NULL, set result using two's complement wrap-around overflow semantics).
|
|
- if a * b "underflows" TYPE: return GUF_MATH_CKD_OVERFLOW_NEG (if result is not NULL, set result using two's complement wrap-around underflow semantics).
|
|
|
|
|
|
cf. https://stackoverflow.com/questions/199333/how-do-i-detect-unsigned-integer-overflow (last-retrieved 2025-03-17)
|
|
cf. https://stackoverflow.com/questions/59307930/how-to-implement-wrapping-signed-int-addition-in-c (last-retrieved 2025-05-10)
|
|
cf. https://stackoverflow.com/questions/54318815/integer-overflow-w-multiplication-in-c (last-retrieved 2025-05-11)
|
|
cf. https://stackoverflow.com/questions/29808397/how-to-portably-find-out-minint-max-absint-min (last-retrieved 2025-05-11)
|
|
cf. https://stackoverflow.com/questions/27001604/32-bit-unsigned-multiply-on-64-bit-causing-undefined-behavior (last-retrieved 2025-05-15)
|
|
*/
|
|
|
|
|
|
#if defined(GUF_MATH_CKDINT_IMPL_STATIC)
|
|
#define GUF_MATH_CKDINT_KWRDS static inline
|
|
#else
|
|
#define GUF_MATH_CKDINT_KWRDS
|
|
#endif
|
|
|
|
#ifndef GUF_MATH_CKDINT_H
|
|
#define GUF_MATH_CKDINT_H
|
|
#include "guf_common.h"
|
|
|
|
typedef enum guf_math_ckd_result {GUF_MATH_CKD_SUCCESS = 0, GUF_MATH_CKD_OVERFLOW_POS, GUF_MATH_CKD_OVERFLOW_NEG} guf_math_ckd_result;
|
|
|
|
|
|
#if !defined(GUF_MATH_CKDINT_IMPL_STATIC) && !defined(GUF_MATH_CKDINT_IMPL)
|
|
// Signed integer arithmetic checks (generated with libguf/tools/ckdint-gen.py)
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_int(int a, int b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_int(int a, int b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_int(int a, int b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_long(long a, long b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_long(long a, long b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_long(long a, long b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_long_long(long long a, long long b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_long_long(long long a, long long b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_long_long(long long a, long long b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_ptrdiff_t(ptrdiff_t a, ptrdiff_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_ptrdiff_t(ptrdiff_t a, ptrdiff_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_ptrdiff_t(ptrdiff_t a, ptrdiff_t b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_i8(int_least8_t a, int_least8_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_i8(int_least8_t a, int_least8_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_i8(int_least8_t a, int_least8_t b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_i16(int_least16_t a, int_least16_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_i16(int_least16_t a, int_least16_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_i16(int_least16_t a, int_least16_t b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_i32(int_least32_t a, int_least32_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_i32(int_least32_t a, int_least32_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_i32(int_least32_t a, int_least32_t b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_i64(int_least64_t a, int_least64_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_i64(int_least64_t a, int_least64_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_i64(int_least64_t a, int_least64_t b);
|
|
|
|
#ifdef INT8_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_i8(int8_t a, int8_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_i8(int8_t a, int8_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_i8(int8_t a, int8_t b);
|
|
#endif
|
|
|
|
#ifdef INT16_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_i16(int16_t a, int16_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_i16(int16_t a, int16_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_i16(int16_t a, int16_t b);
|
|
#endif
|
|
|
|
#ifdef INT32_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_i32(int32_t a, int32_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_i32(int32_t a, int32_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_i32(int32_t a, int32_t b);
|
|
#endif
|
|
|
|
#ifdef INT64_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_i64(int64_t a, int64_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_i64(int64_t a, int64_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_i64(int64_t a, int64_t b);
|
|
#endif
|
|
|
|
|
|
// Unsigned integer arithmetic checks (generated with libguf/tools/ckdint-gen.py)
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_uchar(unsigned char a, unsigned char b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_uchar(unsigned char a, unsigned char b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_uchar(unsigned char a, unsigned char b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_unsigned(unsigned a, unsigned b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_unsigned(unsigned a, unsigned b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_unsigned(unsigned a, unsigned b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_ulong(unsigned long a, unsigned long b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_ulong(unsigned long a, unsigned long b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_ulong(unsigned long a, unsigned long b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_ulong_long(unsigned long long a, unsigned long long b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_ulong_long(unsigned long long a, unsigned long long b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_ulong_long(unsigned long long a, unsigned long long b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_size_t(size_t a, size_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_size_t(size_t a, size_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_size_t(size_t a, size_t b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_u8(uint_least8_t a, uint_least8_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_u8(uint_least8_t a, uint_least8_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_u8(uint_least8_t a, uint_least8_t b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_u16(uint_least16_t a, uint_least16_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_u16(uint_least16_t a, uint_least16_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_u16(uint_least16_t a, uint_least16_t b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_u32(uint_least32_t a, uint_least32_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_u32(uint_least32_t a, uint_least32_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_u32(uint_least32_t a, uint_least32_t b);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_u64(uint_least64_t a, uint_least64_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_u64(uint_least64_t a, uint_least64_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_u64(uint_least64_t a, uint_least64_t b);
|
|
|
|
#ifdef UINT8_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_u8(uint8_t a, uint8_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_u8(uint8_t a, uint8_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_u8(uint8_t a, uint8_t b);
|
|
#endif
|
|
|
|
#ifdef UINT16_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_u16(uint16_t a, uint16_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_u16(uint16_t a, uint16_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_u16(uint16_t a, uint16_t b);
|
|
#endif
|
|
|
|
#ifdef UINT32_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_u32(uint32_t a, uint32_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_u32(uint32_t a, uint32_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_u32(uint32_t a, uint32_t b);
|
|
#endif
|
|
|
|
#ifdef UINT64_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_u64(uint64_t a, uint64_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_u64(uint64_t a, uint64_t b);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_u64(uint64_t a, uint64_t b);
|
|
#endif
|
|
|
|
|
|
|
|
// Signed saturating/wrapping arithmetic (generated with libguf/tools/ckdint-gen.py)
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_int(int a, int b, int *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_int(int a, int b, int *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_int(int a, int b, int *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_int(int a, int b, int *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_int(int a, int b, int *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_int(int a, int b, int *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_long(long a, long b, long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_long(long a, long b, long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_long(long a, long b, long *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_long(long a, long b, long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_long(long a, long b, long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_long(long a, long b, long *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_long_long(long long a, long long b, long long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_long_long(long long a, long long b, long long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_long_long(long long a, long long b, long long *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_long_long(long long a, long long b, long long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_long_long(long long a, long long b, long long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_long_long(long long a, long long b, long long *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result);
|
|
|
|
#ifdef INT8_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_i8(int8_t a, int8_t b, int8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_i8(int8_t a, int8_t b, int8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_i8(int8_t a, int8_t b, int8_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_i8(int8_t a, int8_t b, int8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_i8(int8_t a, int8_t b, int8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_i8(int8_t a, int8_t b, int8_t *result);
|
|
#endif
|
|
|
|
#ifdef INT16_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_i16(int16_t a, int16_t b, int16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_i16(int16_t a, int16_t b, int16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_i16(int16_t a, int16_t b, int16_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_i16(int16_t a, int16_t b, int16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_i16(int16_t a, int16_t b, int16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_i16(int16_t a, int16_t b, int16_t *result);
|
|
#endif
|
|
|
|
#ifdef INT32_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_i32(int32_t a, int32_t b, int32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_i32(int32_t a, int32_t b, int32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_i32(int32_t a, int32_t b, int32_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_i32(int32_t a, int32_t b, int32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_i32(int32_t a, int32_t b, int32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_i32(int32_t a, int32_t b, int32_t *result);
|
|
#endif
|
|
|
|
#ifdef INT64_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_i64(int64_t a, int64_t b, int64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_i64(int64_t a, int64_t b, int64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_i64(int64_t a, int64_t b, int64_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_i64(int64_t a, int64_t b, int64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_i64(int64_t a, int64_t b, int64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_i64(int64_t a, int64_t b, int64_t *result);
|
|
#endif
|
|
|
|
|
|
// Unsigned saturating/wrapping arithmetic (generated with libguf/tools/ckdint-gen.py)
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_uchar(unsigned char a, unsigned char b, unsigned char *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_uchar(unsigned char a, unsigned char b, unsigned char *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_uchar(unsigned char a, unsigned char b, unsigned char *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_uchar(unsigned char a, unsigned char b, unsigned char *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_uchar(unsigned char a, unsigned char b, unsigned char *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_uchar(unsigned char a, unsigned char b, unsigned char *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_unsigned(unsigned a, unsigned b, unsigned *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_unsigned(unsigned a, unsigned b, unsigned *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_unsigned(unsigned a, unsigned b, unsigned *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_unsigned(unsigned a, unsigned b, unsigned *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_unsigned(unsigned a, unsigned b, unsigned *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_unsigned(unsigned a, unsigned b, unsigned *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_ulong(unsigned long a, unsigned long b, unsigned long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_ulong(unsigned long a, unsigned long b, unsigned long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_ulong(unsigned long a, unsigned long b, unsigned long *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_ulong(unsigned long a, unsigned long b, unsigned long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_ulong(unsigned long a, unsigned long b, unsigned long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_ulong(unsigned long a, unsigned long b, unsigned long *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_size_t(size_t a, size_t b, size_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_size_t(size_t a, size_t b, size_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_size_t(size_t a, size_t b, size_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_size_t(size_t a, size_t b, size_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_size_t(size_t a, size_t b, size_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_size_t(size_t a, size_t b, size_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result);
|
|
|
|
#ifdef UINT8_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_u8(uint8_t a, uint8_t b, uint8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_u8(uint8_t a, uint8_t b, uint8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_u8(uint8_t a, uint8_t b, uint8_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_u8(uint8_t a, uint8_t b, uint8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_u8(uint8_t a, uint8_t b, uint8_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_u8(uint8_t a, uint8_t b, uint8_t *result);
|
|
#endif
|
|
|
|
#ifdef UINT16_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_u16(uint16_t a, uint16_t b, uint16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_u16(uint16_t a, uint16_t b, uint16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_u16(uint16_t a, uint16_t b, uint16_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_u16(uint16_t a, uint16_t b, uint16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_u16(uint16_t a, uint16_t b, uint16_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_u16(uint16_t a, uint16_t b, uint16_t *result);
|
|
#endif
|
|
|
|
#ifdef UINT32_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_u32(uint32_t a, uint32_t b, uint32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_u32(uint32_t a, uint32_t b, uint32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_u32(uint32_t a, uint32_t b, uint32_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_u32(uint32_t a, uint32_t b, uint32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_u32(uint32_t a, uint32_t b, uint32_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_u32(uint32_t a, uint32_t b, uint32_t *result);
|
|
#endif
|
|
|
|
#ifdef UINT64_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_u64(uint64_t a, uint64_t b, uint64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_u64(uint64_t a, uint64_t b, uint64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_u64(uint64_t a, uint64_t b, uint64_t *result);
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_u64(uint64_t a, uint64_t b, uint64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_u64(uint64_t a, uint64_t b, uint64_t *result);
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_u64(uint64_t a, uint64_t b, uint64_t *result);
|
|
#endif
|
|
|
|
|
|
#endif
|
|
#if defined(GUF_MATH_CKDINT_IMPL) || defined(GUF_MATH_CKDINT_IMPL_STATIC)
|
|
#include "guf_assert.h"
|
|
// Signed integer arithmetic checks (generated with libguf/tools/ckdint-gen.py)
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_int(int a, int b)
|
|
{
|
|
if (b > 0 && a > INT_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < INT_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_int(int a, int b)
|
|
{
|
|
if (b < 0 && a > INT_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < INT_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_int(int a, int b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > INT_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < INT_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (INT_MIN != -INT_MAX && b == -1) { // Prevent potential (INT_MIN / b) overflow for b == -1
|
|
return a == INT_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < INT_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > INT_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_long(long a, long b)
|
|
{
|
|
if (b > 0 && a > LONG_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < LONG_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_long(long a, long b)
|
|
{
|
|
if (b < 0 && a > LONG_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < LONG_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_long(long a, long b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > LONG_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < LONG_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (LONG_MIN != -LONG_MAX && b == -1) { // Prevent potential (LONG_MIN / b) overflow for b == -1
|
|
return a == LONG_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < LONG_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > LONG_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_long_long(long long a, long long b)
|
|
{
|
|
if (b > 0 && a > LLONG_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < LLONG_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_long_long(long long a, long long b)
|
|
{
|
|
if (b < 0 && a > LLONG_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < LLONG_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_long_long(long long a, long long b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > LLONG_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < LLONG_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (LLONG_MIN != -LLONG_MAX && b == -1) { // Prevent potential (LLONG_MIN / b) overflow for b == -1
|
|
return a == LLONG_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < LLONG_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > LLONG_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_ptrdiff_t(ptrdiff_t a, ptrdiff_t b)
|
|
{
|
|
if (b > 0 && a > PTRDIFF_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < PTRDIFF_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_ptrdiff_t(ptrdiff_t a, ptrdiff_t b)
|
|
{
|
|
if (b < 0 && a > PTRDIFF_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < PTRDIFF_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_ptrdiff_t(ptrdiff_t a, ptrdiff_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > PTRDIFF_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < PTRDIFF_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (PTRDIFF_MIN != -PTRDIFF_MAX && b == -1) { // Prevent potential (PTRDIFF_MIN / b) overflow for b == -1
|
|
return a == PTRDIFF_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < PTRDIFF_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > PTRDIFF_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_i8(int_least8_t a, int_least8_t b)
|
|
{
|
|
if (b > 0 && a > GUF_INT8_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < GUF_INT8_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_i8(int_least8_t a, int_least8_t b)
|
|
{
|
|
if (b < 0 && a > GUF_INT8_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < GUF_INT8_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_i8(int_least8_t a, int_least8_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > GUF_INT8_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < GUF_INT8_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (GUF_INT8_MIN != -GUF_INT8_MAX && b == -1) { // Prevent potential (GUF_INT8_MIN / b) overflow for b == -1
|
|
return a == GUF_INT8_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < GUF_INT8_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > GUF_INT8_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_i16(int_least16_t a, int_least16_t b)
|
|
{
|
|
if (b > 0 && a > GUF_INT16_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < GUF_INT16_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_i16(int_least16_t a, int_least16_t b)
|
|
{
|
|
if (b < 0 && a > GUF_INT16_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < GUF_INT16_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_i16(int_least16_t a, int_least16_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > GUF_INT16_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < GUF_INT16_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (GUF_INT16_MIN != -GUF_INT16_MAX && b == -1) { // Prevent potential (GUF_INT16_MIN / b) overflow for b == -1
|
|
return a == GUF_INT16_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < GUF_INT16_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > GUF_INT16_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_i32(int_least32_t a, int_least32_t b)
|
|
{
|
|
if (b > 0 && a > GUF_INT32_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < GUF_INT32_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_i32(int_least32_t a, int_least32_t b)
|
|
{
|
|
if (b < 0 && a > GUF_INT32_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < GUF_INT32_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_i32(int_least32_t a, int_least32_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > GUF_INT32_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < GUF_INT32_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (GUF_INT32_MIN != -GUF_INT32_MAX && b == -1) { // Prevent potential (GUF_INT32_MIN / b) overflow for b == -1
|
|
return a == GUF_INT32_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < GUF_INT32_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > GUF_INT32_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_i64(int_least64_t a, int_least64_t b)
|
|
{
|
|
if (b > 0 && a > GUF_INT64_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < GUF_INT64_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_i64(int_least64_t a, int_least64_t b)
|
|
{
|
|
if (b < 0 && a > GUF_INT64_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < GUF_INT64_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_i64(int_least64_t a, int_least64_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > GUF_INT64_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < GUF_INT64_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (GUF_INT64_MIN != -GUF_INT64_MAX && b == -1) { // Prevent potential (GUF_INT64_MIN / b) overflow for b == -1
|
|
return a == GUF_INT64_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < GUF_INT64_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > GUF_INT64_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
#ifdef INT8_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_i8(int8_t a, int8_t b)
|
|
{
|
|
if (b > 0 && a > INT8_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < INT8_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_i8(int8_t a, int8_t b)
|
|
{
|
|
if (b < 0 && a > INT8_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < INT8_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_i8(int8_t a, int8_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > INT8_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < INT8_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (INT8_MIN != -INT8_MAX && b == -1) { // Prevent potential (INT8_MIN / b) overflow for b == -1
|
|
return a == INT8_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < INT8_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > INT8_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef INT16_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_i16(int16_t a, int16_t b)
|
|
{
|
|
if (b > 0 && a > INT16_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < INT16_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_i16(int16_t a, int16_t b)
|
|
{
|
|
if (b < 0 && a > INT16_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < INT16_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_i16(int16_t a, int16_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > INT16_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < INT16_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (INT16_MIN != -INT16_MAX && b == -1) { // Prevent potential (INT16_MIN / b) overflow for b == -1
|
|
return a == INT16_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < INT16_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > INT16_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef INT32_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_i32(int32_t a, int32_t b)
|
|
{
|
|
if (b > 0 && a > INT32_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < INT32_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_i32(int32_t a, int32_t b)
|
|
{
|
|
if (b < 0 && a > INT32_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < INT32_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_i32(int32_t a, int32_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > INT32_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < INT32_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (INT32_MIN != -INT32_MAX && b == -1) { // Prevent potential (INT32_MIN / b) overflow for b == -1
|
|
return a == INT32_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < INT32_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > INT32_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef INT64_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_i64(int64_t a, int64_t b)
|
|
{
|
|
if (b > 0 && a > INT64_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b < 0 && a < INT64_MIN - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_i64(int64_t a, int64_t b)
|
|
{
|
|
if (b < 0 && a > INT64_MAX + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (b > 0 && a < INT64_MIN + b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_i64(int64_t a, int64_t b)
|
|
{
|
|
if (b > 0) {
|
|
if (a > INT64_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a < INT64_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else if (b < 0) {
|
|
if (INT64_MIN != -INT64_MAX && b == -1) { // Prevent potential (INT64_MIN / b) overflow for b == -1
|
|
return a == INT64_MIN ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
} else if (a < INT64_MAX / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else if (a > INT64_MIN / b) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
// Unsigned integer arithmetic checks (generated with libguf/tools/ckdint-gen.py)
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_uchar(unsigned char a, unsigned char b)
|
|
{
|
|
if (b > 0 && a > UCHAR_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_uchar(unsigned char a, unsigned char b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_uchar(unsigned char a, unsigned char b)
|
|
{
|
|
const unsigned char c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_unsigned(unsigned a, unsigned b)
|
|
{
|
|
if (b > 0 && a > UINT_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_unsigned(unsigned a, unsigned b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_unsigned(unsigned a, unsigned b)
|
|
{
|
|
const unsigned c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_ulong(unsigned long a, unsigned long b)
|
|
{
|
|
if (b > 0 && a > ULONG_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_ulong(unsigned long a, unsigned long b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_ulong(unsigned long a, unsigned long b)
|
|
{
|
|
const unsigned long c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_ulong_long(unsigned long long a, unsigned long long b)
|
|
{
|
|
if (b > 0 && a > ULLONG_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_ulong_long(unsigned long long a, unsigned long long b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_ulong_long(unsigned long long a, unsigned long long b)
|
|
{
|
|
const unsigned long long c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_size_t(size_t a, size_t b)
|
|
{
|
|
if (b > 0 && a > SIZE_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_size_t(size_t a, size_t b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_size_t(size_t a, size_t b)
|
|
{
|
|
const size_t c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_u8(uint_least8_t a, uint_least8_t b)
|
|
{
|
|
a = GUF_UWRAP_8(a);
|
|
b = GUF_UWRAP_8(b);
|
|
if (b > 0 && a > GUF_UINT8_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_u8(uint_least8_t a, uint_least8_t b)
|
|
{
|
|
a = GUF_UWRAP_8(a);
|
|
b = GUF_UWRAP_8(b);
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_u8(uint_least8_t a, uint_least8_t b)
|
|
{
|
|
a = GUF_UWRAP_8(a);
|
|
b = GUF_UWRAP_8(b);
|
|
const uint_least8_t c = GUF_UWRAP_8( 1u * a * b );
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_u16(uint_least16_t a, uint_least16_t b)
|
|
{
|
|
a = GUF_UWRAP_16(a);
|
|
b = GUF_UWRAP_16(b);
|
|
if (b > 0 && a > GUF_UINT16_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_u16(uint_least16_t a, uint_least16_t b)
|
|
{
|
|
a = GUF_UWRAP_16(a);
|
|
b = GUF_UWRAP_16(b);
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_u16(uint_least16_t a, uint_least16_t b)
|
|
{
|
|
a = GUF_UWRAP_16(a);
|
|
b = GUF_UWRAP_16(b);
|
|
const uint_least16_t c = GUF_UWRAP_16( 1u * a * b );
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_u32(uint_least32_t a, uint_least32_t b)
|
|
{
|
|
a = GUF_UWRAP_32(a);
|
|
b = GUF_UWRAP_32(b);
|
|
if (b > 0 && a > GUF_UINT32_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_u32(uint_least32_t a, uint_least32_t b)
|
|
{
|
|
a = GUF_UWRAP_32(a);
|
|
b = GUF_UWRAP_32(b);
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_u32(uint_least32_t a, uint_least32_t b)
|
|
{
|
|
a = GUF_UWRAP_32(a);
|
|
b = GUF_UWRAP_32(b);
|
|
const uint_least32_t c = GUF_UWRAP_32( 1u * a * b );
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_least_u64(uint_least64_t a, uint_least64_t b)
|
|
{
|
|
a = GUF_UWRAP_64(a);
|
|
b = GUF_UWRAP_64(b);
|
|
if (b > 0 && a > GUF_UINT64_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_least_u64(uint_least64_t a, uint_least64_t b)
|
|
{
|
|
a = GUF_UWRAP_64(a);
|
|
b = GUF_UWRAP_64(b);
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_least_u64(uint_least64_t a, uint_least64_t b)
|
|
{
|
|
a = GUF_UWRAP_64(a);
|
|
b = GUF_UWRAP_64(b);
|
|
const uint_least64_t c = GUF_UWRAP_64( 1u * a * b );
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
#ifdef UINT8_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_u8(uint8_t a, uint8_t b)
|
|
{
|
|
if (b > 0 && a > UINT8_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_u8(uint8_t a, uint8_t b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_u8(uint8_t a, uint8_t b)
|
|
{
|
|
const uint8_t c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UINT16_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_u16(uint16_t a, uint16_t b)
|
|
{
|
|
if (b > 0 && a > UINT16_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_u16(uint16_t a, uint16_t b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_u16(uint16_t a, uint16_t b)
|
|
{
|
|
const uint16_t c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UINT32_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_u32(uint32_t a, uint32_t b)
|
|
{
|
|
if (b > 0 && a > UINT32_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_u32(uint32_t a, uint32_t b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_u32(uint32_t a, uint32_t b)
|
|
{
|
|
const uint32_t c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UINT64_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_u64(uint64_t a, uint64_t b)
|
|
{
|
|
if (b > 0 && a > UINT64_MAX - b) {
|
|
return GUF_MATH_CKD_OVERFLOW_POS;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_u64(uint64_t a, uint64_t b)
|
|
{
|
|
if (b > a) {
|
|
return GUF_MATH_CKD_OVERFLOW_NEG;
|
|
} else {
|
|
return GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_u64(uint64_t a, uint64_t b)
|
|
{
|
|
const uint64_t c = 1u * a * b;
|
|
return a != 0 && ((1u * c / a) != b) ? GUF_MATH_CKD_OVERFLOW_POS : GUF_MATH_CKD_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
// Signed saturating/wrapping arithmetic (generated with libguf/tools/ckdint-gen.py)
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_int(int a, int b, int *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_int(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_int(int a, int b, int *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_int(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_int(int a, int b, int *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_int(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_int(int a, int b, int *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_int(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int)( (a + (int)INT_MIN) + (b + (int)INT_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int)( (a - (int)INT_MIN) + (b - (int)INT_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_int(int a, int b, int *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_int(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int)( (a + (int)INT_MIN) - (b - (int)INT_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int)( (a - (int)INT_MIN) - (b + (int)INT_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_int(int a, int b, int *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_int(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
unsigned res = 1u * (unsigned)a * (unsigned)b;
|
|
if (res > INT_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const unsigned mod = (unsigned)INT_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int)INT_MIN + (int)res;
|
|
} else {
|
|
*result = (int)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_long(long a, long b, long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = LONG_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = LONG_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_long(long a, long b, long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = LONG_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = LONG_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_long(long a, long b, long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = LONG_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = LONG_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_long(long a, long b, long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (long)( (a + (long)LONG_MIN) + (b + (long)LONG_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (long)( (a - (long)LONG_MIN) + (b - (long)LONG_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_long(long a, long b, long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (long)( (a + (long)LONG_MIN) - (b - (long)LONG_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (long)( (a - (long)LONG_MIN) - (b + (long)LONG_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_long(long a, long b, long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
unsigned long res = 1u * (unsigned long)a * (unsigned long)b;
|
|
if (res > LONG_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const unsigned long mod = (unsigned long)LONG_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (long)LONG_MIN + (long)res;
|
|
} else {
|
|
*result = (long)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_long_long(long long a, long long b, long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_long_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = LLONG_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = LLONG_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_long_long(long long a, long long b, long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_long_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = LLONG_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = LLONG_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_long_long(long long a, long long b, long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_long_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = LLONG_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = LLONG_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_long_long(long long a, long long b, long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_long_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (long long)( (a + (long long)LLONG_MIN) + (b + (long long)LLONG_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (long long)( (a - (long long)LLONG_MIN) + (b - (long long)LLONG_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_long_long(long long a, long long b, long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_long_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (long long)( (a + (long long)LLONG_MIN) - (b - (long long)LLONG_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (long long)( (a - (long long)LLONG_MIN) - (b + (long long)LLONG_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_long_long(long long a, long long b, long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_long_long(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
unsigned long long res = 1u * (unsigned long long)a * (unsigned long long)b;
|
|
if (res > LLONG_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const unsigned long long mod = (unsigned long long)LLONG_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (long long)LLONG_MIN + (long long)res;
|
|
} else {
|
|
*result = (long long)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_ptrdiff_t(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = PTRDIFF_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = PTRDIFF_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_ptrdiff_t(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = PTRDIFF_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = PTRDIFF_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_ptrdiff_t(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = PTRDIFF_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = PTRDIFF_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_ptrdiff_t(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (ptrdiff_t)( (a + (ptrdiff_t)PTRDIFF_MIN) + (b + (ptrdiff_t)PTRDIFF_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (ptrdiff_t)( (a - (ptrdiff_t)PTRDIFF_MIN) + (b - (ptrdiff_t)PTRDIFF_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_ptrdiff_t(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (ptrdiff_t)( (a + (ptrdiff_t)PTRDIFF_MIN) - (b - (ptrdiff_t)PTRDIFF_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (ptrdiff_t)( (a - (ptrdiff_t)PTRDIFF_MIN) - (b + (ptrdiff_t)PTRDIFF_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_ptrdiff_t(ptrdiff_t a, ptrdiff_t b, ptrdiff_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_ptrdiff_t(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
size_t res = 1u * (size_t)a * (size_t)b;
|
|
if (res > PTRDIFF_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const size_t mod = (size_t)PTRDIFF_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (ptrdiff_t)PTRDIFF_MIN + (ptrdiff_t)res;
|
|
} else {
|
|
*result = (ptrdiff_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT8_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT8_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT8_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT8_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT8_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT8_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int_least8_t)( (a + (int_least8_t)GUF_INT8_MIN) + (b + (int_least8_t)GUF_INT8_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int_least8_t)( (a - (int_least8_t)GUF_INT8_MIN) + (b - (int_least8_t)GUF_INT8_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int_least8_t)( (a + (int_least8_t)GUF_INT8_MIN) - (b - (int_least8_t)GUF_INT8_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int_least8_t)( (a - (int_least8_t)GUF_INT8_MIN) - (b + (int_least8_t)GUF_INT8_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_i8(int_least8_t a, int_least8_t b, int_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
uint_least8_t res = 1u * (uint_least8_t)a * (uint_least8_t)b;
|
|
if (res > GUF_INT8_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const uint_least8_t mod = (uint_least8_t)GUF_INT8_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int_least8_t)GUF_INT8_MIN + (int_least8_t)res;
|
|
} else {
|
|
*result = (int_least8_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT16_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT16_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT16_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT16_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT16_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT16_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int_least16_t)( (a + (int_least16_t)GUF_INT16_MIN) + (b + (int_least16_t)GUF_INT16_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int_least16_t)( (a - (int_least16_t)GUF_INT16_MIN) + (b - (int_least16_t)GUF_INT16_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int_least16_t)( (a + (int_least16_t)GUF_INT16_MIN) - (b - (int_least16_t)GUF_INT16_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int_least16_t)( (a - (int_least16_t)GUF_INT16_MIN) - (b + (int_least16_t)GUF_INT16_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_i16(int_least16_t a, int_least16_t b, int_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
uint_least16_t res = 1u * (uint_least16_t)a * (uint_least16_t)b;
|
|
if (res > GUF_INT16_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const uint_least16_t mod = (uint_least16_t)GUF_INT16_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int_least16_t)GUF_INT16_MIN + (int_least16_t)res;
|
|
} else {
|
|
*result = (int_least16_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT32_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT32_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT32_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT32_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT32_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT32_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int_least32_t)( (a + (int_least32_t)GUF_INT32_MIN) + (b + (int_least32_t)GUF_INT32_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int_least32_t)( (a - (int_least32_t)GUF_INT32_MIN) + (b - (int_least32_t)GUF_INT32_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int_least32_t)( (a + (int_least32_t)GUF_INT32_MIN) - (b - (int_least32_t)GUF_INT32_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int_least32_t)( (a - (int_least32_t)GUF_INT32_MIN) - (b + (int_least32_t)GUF_INT32_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_i32(int_least32_t a, int_least32_t b, int_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
uint_least32_t res = 1u * (uint_least32_t)a * (uint_least32_t)b;
|
|
if (res > GUF_INT32_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const uint_least32_t mod = (uint_least32_t)GUF_INT32_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int_least32_t)GUF_INT32_MIN + (int_least32_t)res;
|
|
} else {
|
|
*result = (int_least32_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT64_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT64_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT64_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT64_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_INT64_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = GUF_INT64_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int_least64_t)( (a + (int_least64_t)GUF_INT64_MIN) + (b + (int_least64_t)GUF_INT64_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int_least64_t)( (a - (int_least64_t)GUF_INT64_MIN) + (b - (int_least64_t)GUF_INT64_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int_least64_t)( (a + (int_least64_t)GUF_INT64_MIN) - (b - (int_least64_t)GUF_INT64_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int_least64_t)( (a - (int_least64_t)GUF_INT64_MIN) - (b + (int_least64_t)GUF_INT64_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_i64(int_least64_t a, int_least64_t b, int_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
uint_least64_t res = 1u * (uint_least64_t)a * (uint_least64_t)b;
|
|
if (res > GUF_INT64_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const uint_least64_t mod = (uint_least64_t)GUF_INT64_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int_least64_t)GUF_INT64_MIN + (int_least64_t)res;
|
|
} else {
|
|
*result = (int_least64_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
#ifdef INT8_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_i8(int8_t a, int8_t b, int8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT8_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT8_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_i8(int8_t a, int8_t b, int8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT8_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT8_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_i8(int8_t a, int8_t b, int8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT8_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT8_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_i8(int8_t a, int8_t b, int8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int8_t)( (a + (int8_t)INT8_MIN) + (b + (int8_t)INT8_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int8_t)( (a - (int8_t)INT8_MIN) + (b - (int8_t)INT8_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_i8(int8_t a, int8_t b, int8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int8_t)( (a + (int8_t)INT8_MIN) - (b - (int8_t)INT8_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int8_t)( (a - (int8_t)INT8_MIN) - (b + (int8_t)INT8_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_i8(int8_t a, int8_t b, int8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_i8(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
uint8_t res = 1u * (uint8_t)a * (uint8_t)b;
|
|
if (res > INT8_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const uint8_t mod = (uint8_t)INT8_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int8_t)INT8_MIN + (int8_t)res;
|
|
} else {
|
|
*result = (int8_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
#endif
|
|
|
|
#ifdef INT16_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_i16(int16_t a, int16_t b, int16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT16_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT16_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_i16(int16_t a, int16_t b, int16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT16_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT16_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_i16(int16_t a, int16_t b, int16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT16_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT16_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_i16(int16_t a, int16_t b, int16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int16_t)( (a + (int16_t)INT16_MIN) + (b + (int16_t)INT16_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int16_t)( (a - (int16_t)INT16_MIN) + (b - (int16_t)INT16_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_i16(int16_t a, int16_t b, int16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int16_t)( (a + (int16_t)INT16_MIN) - (b - (int16_t)INT16_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int16_t)( (a - (int16_t)INT16_MIN) - (b + (int16_t)INT16_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_i16(int16_t a, int16_t b, int16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_i16(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
uint16_t res = 1u * (uint16_t)a * (uint16_t)b;
|
|
if (res > INT16_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const uint16_t mod = (uint16_t)INT16_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int16_t)INT16_MIN + (int16_t)res;
|
|
} else {
|
|
*result = (int16_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
#endif
|
|
|
|
#ifdef INT32_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_i32(int32_t a, int32_t b, int32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT32_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT32_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_i32(int32_t a, int32_t b, int32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT32_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT32_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_i32(int32_t a, int32_t b, int32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT32_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT32_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_i32(int32_t a, int32_t b, int32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int32_t)( (a + (int32_t)INT32_MIN) + (b + (int32_t)INT32_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int32_t)( (a - (int32_t)INT32_MIN) + (b - (int32_t)INT32_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_i32(int32_t a, int32_t b, int32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int32_t)( (a + (int32_t)INT32_MIN) - (b - (int32_t)INT32_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int32_t)( (a - (int32_t)INT32_MIN) - (b + (int32_t)INT32_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_i32(int32_t a, int32_t b, int32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_i32(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
uint32_t res = 1u * (uint32_t)a * (uint32_t)b;
|
|
if (res > INT32_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const uint32_t mod = (uint32_t)INT32_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int32_t)INT32_MIN + (int32_t)res;
|
|
} else {
|
|
*result = (int32_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
#endif
|
|
|
|
#ifdef INT64_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_i64(int64_t a, int64_t b, int64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT64_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT64_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_i64(int64_t a, int64_t b, int64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT64_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT64_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_i64(int64_t a, int64_t b, int64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = INT64_MAX;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = INT64_MIN;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_i64(int64_t a, int64_t b, int64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = (int64_t)( (a + (int64_t)INT64_MIN) + (b + (int64_t)INT64_MIN) );
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = (int64_t)( (a - (int64_t)INT64_MIN) + (b - (int64_t)INT64_MIN) );
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_i64(int64_t a, int64_t b, int64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
GUF_ASSERT(b < 0);
|
|
*result = (int64_t)( (a + (int64_t)INT64_MIN) - (b - (int64_t)INT64_MIN) ); // TODO: not sure
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
GUF_ASSERT(b > 0);
|
|
*result = (int64_t)( (a - (int64_t)INT64_MIN) - (b + (int64_t)INT64_MIN) ); // TODO: not sure
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_i64(int64_t a, int64_t b, int64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_i64(a, b);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
case GUF_MATH_CKD_OVERFLOW_NEG: {
|
|
uint64_t res = 1u * (uint64_t)a * (uint64_t)b;
|
|
if (res > INT64_MAX) { // This is the fix for implementation defined conversion from unsigned to signed.
|
|
const uint64_t mod = (uint64_t)INT64_MAX + 1u;
|
|
GUF_ASSERT(mod > 0);
|
|
res = 1u * res % mod;
|
|
*result = (int64_t)INT64_MIN + (int64_t)res;
|
|
} else {
|
|
*result = (int64_t)res;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
#endif
|
|
|
|
|
|
// Unsigned saturating/wrapping arithmetic (generated with libguf/tools/ckdint-gen.py)
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_uchar(unsigned char a, unsigned char b, unsigned char *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_uchar(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UCHAR_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_uchar(unsigned char a, unsigned char b, unsigned char *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_uchar(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_uchar(unsigned char a, unsigned char b, unsigned char *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_uchar(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UCHAR_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_uchar(unsigned char a, unsigned char b, unsigned char *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_uchar(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_uchar(unsigned char a, unsigned char b, unsigned char *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_uchar(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_uchar(unsigned char a, unsigned char b, unsigned char *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_uchar(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_unsigned(unsigned a, unsigned b, unsigned *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_unsigned(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_unsigned(unsigned a, unsigned b, unsigned *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_unsigned(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_unsigned(unsigned a, unsigned b, unsigned *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_unsigned(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_unsigned(unsigned a, unsigned b, unsigned *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_unsigned(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_unsigned(unsigned a, unsigned b, unsigned *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_unsigned(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_unsigned(unsigned a, unsigned b, unsigned *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_unsigned(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_ulong(unsigned long a, unsigned long b, unsigned long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_ulong(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = ULONG_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_ulong(unsigned long a, unsigned long b, unsigned long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_ulong(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_ulong(unsigned long a, unsigned long b, unsigned long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_ulong(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = ULONG_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_ulong(unsigned long a, unsigned long b, unsigned long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_ulong(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_ulong(unsigned long a, unsigned long b, unsigned long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_ulong(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_ulong(unsigned long a, unsigned long b, unsigned long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_ulong(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_ulong_long(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = ULLONG_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_ulong_long(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_ulong_long(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = ULLONG_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_ulong_long(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_ulong_long(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_ulong_long(unsigned long long a, unsigned long long b, unsigned long long *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_ulong_long(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_size_t(size_t a, size_t b, size_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_size_t(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = SIZE_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_size_t(size_t a, size_t b, size_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_size_t(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_size_t(size_t a, size_t b, size_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_size_t(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = SIZE_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_size_t(size_t a, size_t b, size_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_size_t(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_size_t(size_t a, size_t b, size_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_size_t(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_size_t(size_t a, size_t b, size_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_size_t(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_u8(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_UINT8_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_u8(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_u8(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_UINT8_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result)
|
|
{
|
|
a = GUF_UWRAP_8(a);
|
|
b = GUF_UWRAP_8(b);
|
|
const guf_math_ckd_result check = guf_ckd_add_least_u8(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_8( 1u * a + b );
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result)
|
|
{
|
|
a = GUF_UWRAP_8(a);
|
|
b = GUF_UWRAP_8(b);
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_u8(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_8( 1u * a - b );
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_u8(uint_least8_t a, uint_least8_t b, uint_least8_t *result)
|
|
{
|
|
a = GUF_UWRAP_8(a);
|
|
b = GUF_UWRAP_8(b);
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_u8(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_8( 1u * a * b );
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_u16(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_UINT16_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_u16(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_u16(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_UINT16_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result)
|
|
{
|
|
a = GUF_UWRAP_16(a);
|
|
b = GUF_UWRAP_16(b);
|
|
const guf_math_ckd_result check = guf_ckd_add_least_u16(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_16( 1u * a + b );
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result)
|
|
{
|
|
a = GUF_UWRAP_16(a);
|
|
b = GUF_UWRAP_16(b);
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_u16(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_16( 1u * a - b );
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_u16(uint_least16_t a, uint_least16_t b, uint_least16_t *result)
|
|
{
|
|
a = GUF_UWRAP_16(a);
|
|
b = GUF_UWRAP_16(b);
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_u16(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_16( 1u * a * b );
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_u32(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_UINT32_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_u32(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_u32(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_UINT32_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result)
|
|
{
|
|
a = GUF_UWRAP_32(a);
|
|
b = GUF_UWRAP_32(b);
|
|
const guf_math_ckd_result check = guf_ckd_add_least_u32(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_32( 1u * a + b );
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result)
|
|
{
|
|
a = GUF_UWRAP_32(a);
|
|
b = GUF_UWRAP_32(b);
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_u32(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_32( 1u * a - b );
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_u32(uint_least32_t a, uint_least32_t b, uint_least32_t *result)
|
|
{
|
|
a = GUF_UWRAP_32(a);
|
|
b = GUF_UWRAP_32(b);
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_u32(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_32( 1u * a * b );
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_least_u64(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_UINT64_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_u64(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_u64(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = GUF_UINT64_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result)
|
|
{
|
|
a = GUF_UWRAP_64(a);
|
|
b = GUF_UWRAP_64(b);
|
|
const guf_math_ckd_result check = guf_ckd_add_least_u64(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_64( 1u * a + b );
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result)
|
|
{
|
|
a = GUF_UWRAP_64(a);
|
|
b = GUF_UWRAP_64(b);
|
|
const guf_math_ckd_result check = guf_ckd_sub_least_u64(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_64( 1u * a - b );
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_least_u64(uint_least64_t a, uint_least64_t b, uint_least64_t *result)
|
|
{
|
|
a = GUF_UWRAP_64(a);
|
|
b = GUF_UWRAP_64(b);
|
|
const guf_math_ckd_result check = guf_ckd_mul_least_u64(a, b);
|
|
if (result) {
|
|
*result = GUF_UWRAP_64( 1u * a * b );
|
|
}
|
|
return check;
|
|
}
|
|
|
|
#ifdef UINT8_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_u8(uint8_t a, uint8_t b, uint8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_u8(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT8_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_u8(uint8_t a, uint8_t b, uint8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_u8(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_u8(uint8_t a, uint8_t b, uint8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_u8(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT8_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_u8(uint8_t a, uint8_t b, uint8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_u8(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_u8(uint8_t a, uint8_t b, uint8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_u8(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_u8(uint8_t a, uint8_t b, uint8_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_u8(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UINT16_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_u16(uint16_t a, uint16_t b, uint16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_u16(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT16_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_u16(uint16_t a, uint16_t b, uint16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_u16(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_u16(uint16_t a, uint16_t b, uint16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_u16(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT16_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_u16(uint16_t a, uint16_t b, uint16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_u16(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_u16(uint16_t a, uint16_t b, uint16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_u16(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_u16(uint16_t a, uint16_t b, uint16_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_u16(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UINT32_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_u32(uint32_t a, uint32_t b, uint32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_u32(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT32_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_u32(uint32_t a, uint32_t b, uint32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_u32(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_u32(uint32_t a, uint32_t b, uint32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_u32(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT32_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_u32(uint32_t a, uint32_t b, uint32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_u32(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_u32(uint32_t a, uint32_t b, uint32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_u32(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_u32(uint32_t a, uint32_t b, uint32_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_u32(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UINT64_MAX
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_u64(uint64_t a, uint64_t b, uint64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_u64(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a + b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT64_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_u64(uint64_t a, uint64_t b, uint64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_u64(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a - b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_NEG:
|
|
*result = 0;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_u64(uint64_t a, uint64_t b, uint64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_u64(a, b);
|
|
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW_POS);
|
|
if (result) {
|
|
switch (check) {
|
|
case GUF_MATH_CKD_SUCCESS:
|
|
*result = a * b;
|
|
break;
|
|
case GUF_MATH_CKD_OVERFLOW_POS:
|
|
*result = UINT64_MAX;
|
|
break;
|
|
default:
|
|
GUF_ASSERT(false);
|
|
}
|
|
}
|
|
return check;
|
|
}
|
|
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_u64(uint64_t a, uint64_t b, uint64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_add_u64(a, b);
|
|
if (result) {
|
|
*result = 1u * a + b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_u64(uint64_t a, uint64_t b, uint64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_sub_u64(a, b);
|
|
if (result) {
|
|
*result = 1u * a - b;
|
|
}
|
|
return check;
|
|
}
|
|
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_u64(uint64_t a, uint64_t b, uint64_t *result)
|
|
{
|
|
const guf_math_ckd_result check = guf_ckd_mul_u64(a, b);
|
|
if (result) {
|
|
*result = 1u * a * b;
|
|
}
|
|
return check;
|
|
}
|
|
#endif
|
|
|
|
|
|
#endif /* End impl */
|
|
|
|
#endif /* End header-guard */
|
|
|
|
#undef GUF_MATH_CKDINT_KWRDS
|
|
#undef GUF_MATH_CKDINT_IMPL
|
|
#undef GUF_MATH_CKDINT_IMPL_STATIC
|
|
|