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