/src/openvswitch/lib/sat-math.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2008, 2012, 2019 Nicira, Inc. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at: |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #ifndef SAT_MATH_H |
18 | | #define SAT_MATH_H 1 |
19 | | |
20 | | #include <limits.h> |
21 | | #include "openvswitch/util.h" |
22 | | |
23 | | #ifndef __has_builtin |
24 | | #define __has_builtin(x) 0 |
25 | | #endif |
26 | | |
27 | | /* Returns x + y, clamping out-of-range results into the range of the return |
28 | | * type. */ |
29 | | static inline unsigned int |
30 | | sat_add(unsigned int x, unsigned int y) |
31 | 0 | { |
32 | 0 | return x + y >= x ? x + y : UINT_MAX; |
33 | 0 | } Unexecuted instantiation: vlog.c:sat_add Unexecuted instantiation: token-bucket.c:sat_add |
34 | | static inline long long int |
35 | | llsat_add__(long long int x, long long int y) |
36 | 0 | { |
37 | 0 | return (x >= 0 && y >= 0 && x > LLONG_MAX - y ? LLONG_MAX |
38 | 0 | : x < 0 && y < 0 && x < LLONG_MIN - y ? LLONG_MIN |
39 | 0 | : x + y); |
40 | 0 | } Unexecuted instantiation: vlog.c:llsat_add__ Unexecuted instantiation: token-bucket.c:llsat_add__ |
41 | | static inline long long int |
42 | | llsat_add(long long int x, long long int y) |
43 | 0 | { |
44 | 0 | #if (__GNUC__ >= 5 || __has_builtin(__builtin_saddll_overflow)) && !__CHECKER__ |
45 | 0 | long long int sum; |
46 | 0 | return (!__builtin_saddll_overflow(x, y, &sum) ? sum |
47 | 0 | : x > 0 ? LLONG_MAX : LLONG_MIN); |
48 | 0 | #else |
49 | 0 | return llsat_add__(x, y); |
50 | 0 | #endif |
51 | 0 | } Unexecuted instantiation: vlog.c:llsat_add Unexecuted instantiation: token-bucket.c:llsat_add |
52 | | |
53 | | /* Returns x - y, clamping out-of-range results into the range of the return |
54 | | * type. */ |
55 | | static inline unsigned int |
56 | | sat_sub(unsigned int x, unsigned int y) |
57 | 0 | { |
58 | 0 | return x >= y ? x - y : 0; |
59 | 0 | } Unexecuted instantiation: vlog.c:sat_sub Unexecuted instantiation: token-bucket.c:sat_sub |
60 | | static inline long long int |
61 | | llsat_sub__(long long int x, long long int y) |
62 | 0 | { |
63 | 0 | return (x >= 0 && y < 0 && x > LLONG_MAX + y ? LLONG_MAX |
64 | 0 | : x < 0 && y >= 0 && x < LLONG_MIN + y ? LLONG_MIN |
65 | 0 | : x - y); |
66 | 0 | } Unexecuted instantiation: vlog.c:llsat_sub__ Unexecuted instantiation: token-bucket.c:llsat_sub__ |
67 | | static inline long long int |
68 | | llsat_sub(long long int x, long long int y) |
69 | 0 | { |
70 | 0 | #if (__GNUC__ >= 5 || __has_builtin(__builtin_ssubll_overflow)) && !__CHECKER__ |
71 | 0 | long long int difference; |
72 | 0 | return (!__builtin_ssubll_overflow(x, y, &difference) ? difference |
73 | 0 | : x >= 0 ? LLONG_MAX : LLONG_MIN); |
74 | 0 | #else |
75 | 0 | return llsat_sub__(x, y); |
76 | 0 | #endif |
77 | 0 | } Unexecuted instantiation: vlog.c:llsat_sub Unexecuted instantiation: token-bucket.c:llsat_sub |
78 | | |
79 | | /* Returns x * y, clamping out-of-range results into the range of the return |
80 | | * type. */ |
81 | | static inline unsigned int |
82 | | sat_mul(unsigned int x, unsigned int y) |
83 | 0 | { |
84 | 0 | return OVS_SAT_MUL(x, y); |
85 | 0 | } Unexecuted instantiation: vlog.c:sat_mul Unexecuted instantiation: token-bucket.c:sat_mul |
86 | | static inline long long int |
87 | | llsat_mul__(long long int x, long long int y) |
88 | 0 | { |
89 | 0 | return ( x > 0 && y > 0 && x > LLONG_MAX / y ? LLONG_MAX |
90 | 0 | : x < 0 && y > 0 && x < LLONG_MIN / y ? LLONG_MIN |
91 | 0 | : x > 0 && y < 0 && y < LLONG_MIN / x ? LLONG_MIN |
92 | 0 | /* Special case because -LLONG_MIN / -1 overflows: */ |
93 | 0 | : x == LLONG_MIN && y == -1 ? LLONG_MAX |
94 | 0 | : x < 0 && y < 0 && x < LLONG_MAX / y ? LLONG_MAX |
95 | 0 | : x * y); |
96 | 0 | } Unexecuted instantiation: vlog.c:llsat_mul__ Unexecuted instantiation: token-bucket.c:llsat_mul__ |
97 | | static inline long long int |
98 | | llsat_mul(long long int x, long long int y) |
99 | 0 | { |
100 | 0 | #if (__GNUC__ >= 5 || __has_builtin(__builtin_smulll_overflow)) && !__CHECKER__ |
101 | 0 | long long int product; |
102 | 0 | return (!__builtin_smulll_overflow(x, y, &product) ? product |
103 | 0 | : (x > 0) == (y > 0) ? LLONG_MAX : LLONG_MIN); |
104 | 0 | #else |
105 | 0 | return llsat_mul__(x, y); |
106 | 0 | #endif |
107 | 0 | } Unexecuted instantiation: vlog.c:llsat_mul Unexecuted instantiation: token-bucket.c:llsat_mul |
108 | | |
109 | | #endif /* sat-math.h */ |