1 | /* |
2 | * Copyright 2015 Advanced Micro Devices, Inc. |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
11 | * The above copyright notice and this permission notice shall be included in |
12 | * all copies or substantial portions of the Software. |
13 | * |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * |
22 | * Authors: AMD |
23 | * |
24 | */ |
25 | |
26 | #ifndef BW_FIXED_H_ |
27 | #define BW_FIXED_H_ |
28 | |
29 | #define BW_FIXED_BITS_PER_FRACTIONAL_PART 24 |
30 | |
31 | #define BW_FIXED_GET_INTEGER_PART(x) ((x) >> BW_FIXED_BITS_PER_FRACTIONAL_PART) |
32 | struct bw_fixed { |
33 | int64_t value; |
34 | }; |
35 | |
36 | #define BW_FIXED_MIN_I32 \ |
37 | (int64_t)(-(1LL << (63 - BW_FIXED_BITS_PER_FRACTIONAL_PART))) |
38 | |
39 | #define BW_FIXED_MAX_I32 \ |
40 | (int64_t)((1ULL << (63 - BW_FIXED_BITS_PER_FRACTIONAL_PART)) - 1) |
41 | |
42 | static inline struct bw_fixed bw_min2(const struct bw_fixed arg1, |
43 | const struct bw_fixed arg2) |
44 | { |
45 | return (arg1.value <= arg2.value) ? arg1 : arg2; |
46 | } |
47 | |
48 | static inline struct bw_fixed bw_max2(const struct bw_fixed arg1, |
49 | const struct bw_fixed arg2) |
50 | { |
51 | return (arg2.value <= arg1.value) ? arg1 : arg2; |
52 | } |
53 | |
54 | static inline struct bw_fixed bw_min3(struct bw_fixed v1, |
55 | struct bw_fixed v2, |
56 | struct bw_fixed v3) |
57 | { |
58 | return bw_min2(arg1: bw_min2(arg1: v1, arg2: v2), arg2: v3); |
59 | } |
60 | |
61 | static inline struct bw_fixed bw_max3(struct bw_fixed v1, |
62 | struct bw_fixed v2, |
63 | struct bw_fixed v3) |
64 | { |
65 | return bw_max2(arg1: bw_max2(arg1: v1, arg2: v2), arg2: v3); |
66 | } |
67 | |
68 | struct bw_fixed bw_int_to_fixed_nonconst(int64_t value); |
69 | static inline struct bw_fixed bw_int_to_fixed(int64_t value) |
70 | { |
71 | if (__builtin_constant_p(value)) { |
72 | struct bw_fixed res; |
73 | BUILD_BUG_ON(value > BW_FIXED_MAX_I32 || value < BW_FIXED_MIN_I32); |
74 | res.value = value << BW_FIXED_BITS_PER_FRACTIONAL_PART; |
75 | return res; |
76 | } else |
77 | return bw_int_to_fixed_nonconst(value); |
78 | } |
79 | |
80 | static inline int32_t bw_fixed_to_int(struct bw_fixed value) |
81 | { |
82 | return BW_FIXED_GET_INTEGER_PART(value.value); |
83 | } |
84 | |
85 | struct bw_fixed bw_frc_to_fixed(int64_t num, int64_t denum); |
86 | |
87 | static inline struct bw_fixed fixed31_32_to_bw_fixed(int64_t raw) |
88 | { |
89 | struct bw_fixed result = { 0 }; |
90 | |
91 | if (raw < 0) { |
92 | raw = -raw; |
93 | result.value = -(raw >> (32 - BW_FIXED_BITS_PER_FRACTIONAL_PART)); |
94 | } else { |
95 | result.value = raw >> (32 - BW_FIXED_BITS_PER_FRACTIONAL_PART); |
96 | } |
97 | |
98 | return result; |
99 | } |
100 | |
101 | static inline struct bw_fixed bw_add(const struct bw_fixed arg1, |
102 | const struct bw_fixed arg2) |
103 | { |
104 | struct bw_fixed res; |
105 | |
106 | res.value = arg1.value + arg2.value; |
107 | |
108 | return res; |
109 | } |
110 | |
111 | static inline struct bw_fixed bw_sub(const struct bw_fixed arg1, const struct bw_fixed arg2) |
112 | { |
113 | struct bw_fixed res; |
114 | |
115 | res.value = arg1.value - arg2.value; |
116 | |
117 | return res; |
118 | } |
119 | |
120 | struct bw_fixed bw_mul(const struct bw_fixed arg1, const struct bw_fixed arg2); |
121 | static inline struct bw_fixed bw_div(const struct bw_fixed arg1, const struct bw_fixed arg2) |
122 | { |
123 | return bw_frc_to_fixed(num: arg1.value, denum: arg2.value); |
124 | } |
125 | |
126 | static inline struct bw_fixed bw_mod(const struct bw_fixed arg1, const struct bw_fixed arg2) |
127 | { |
128 | struct bw_fixed res; |
129 | div64_u64_rem(dividend: arg1.value, divisor: arg2.value, remainder: (uint64_t *)&res.value); |
130 | return res; |
131 | } |
132 | |
133 | struct bw_fixed bw_floor2(const struct bw_fixed arg, const struct bw_fixed significance); |
134 | struct bw_fixed bw_ceil2(const struct bw_fixed arg, const struct bw_fixed significance); |
135 | |
136 | static inline bool bw_equ(const struct bw_fixed arg1, const struct bw_fixed arg2) |
137 | { |
138 | return arg1.value == arg2.value; |
139 | } |
140 | |
141 | static inline bool bw_neq(const struct bw_fixed arg1, const struct bw_fixed arg2) |
142 | { |
143 | return arg1.value != arg2.value; |
144 | } |
145 | |
146 | static inline bool bw_leq(const struct bw_fixed arg1, const struct bw_fixed arg2) |
147 | { |
148 | return arg1.value <= arg2.value; |
149 | } |
150 | |
151 | static inline bool bw_meq(const struct bw_fixed arg1, const struct bw_fixed arg2) |
152 | { |
153 | return arg1.value >= arg2.value; |
154 | } |
155 | |
156 | static inline bool bw_ltn(const struct bw_fixed arg1, const struct bw_fixed arg2) |
157 | { |
158 | return arg1.value < arg2.value; |
159 | } |
160 | |
161 | static inline bool bw_mtn(const struct bw_fixed arg1, const struct bw_fixed arg2) |
162 | { |
163 | return arg1.value > arg2.value; |
164 | } |
165 | |
166 | #endif //BW_FIXED_H_ |
167 | |