1 /*
2  * Copyright 2012-15 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 __DAL_FIXED31_32_H__
27 #define __DAL_FIXED31_32_H__
28 
29 #include "os_types.h"
30 
31 #define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
32 
33 /*
34  * @brief
35  * Arithmetic operations on real numbers
36  * represented as fixed-point numbers.
37  * There are: 1 bit for sign,
38  * 31 bit for integer part,
39  * 32 bits for fractional part.
40  *
41  * @note
42  * Currently, overflows and underflows are asserted;
43  * no special result returned.
44  */
45 
46 struct fixed31_32 {
47 	int64_t value;
48 };
49 
50 /*
51  * @brief
52  * Useful constants
53  */
54 
55 static const struct fixed31_32 dal_fixed31_32_zero = { 0 };
56 static const struct fixed31_32 dal_fixed31_32_epsilon = { 1LL };
57 static const struct fixed31_32 dal_fixed31_32_half = { 0x80000000LL };
58 static const struct fixed31_32 dal_fixed31_32_one = { 0x100000000LL };
59 
60 static const struct fixed31_32 dal_fixed31_32_pi = { 13493037705LL };
61 static const struct fixed31_32 dal_fixed31_32_two_pi = { 26986075409LL };
62 static const struct fixed31_32 dal_fixed31_32_e = { 11674931555LL };
63 static const struct fixed31_32 dal_fixed31_32_ln2 = { 2977044471LL };
64 static const struct fixed31_32 dal_fixed31_32_ln2_div_2 = { 1488522236LL };
65 
66 /*
67  * @brief
68  * Initialization routines
69  */
70 
71 /*
72  * @brief
73  * result = numerator / denominator
74  */
75 struct fixed31_32 dal_fixed31_32_from_fraction(
76 	int64_t numerator,
77 	int64_t denominator);
78 
79 /*
80  * @brief
81  * result = arg
82  */
83 struct fixed31_32 dal_fixed31_32_from_int_nonconst(int64_t arg);
84 static inline struct fixed31_32 dal_fixed31_32_from_int(int64_t arg)
85 {
86 	if (__builtin_constant_p(arg)) {
87 		struct fixed31_32 res;
88 		BUILD_BUG_ON((LONG_MIN > arg) || (arg > LONG_MAX));
89 		res.value = arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
90 		return res;
91 	} else
92 		return dal_fixed31_32_from_int_nonconst(arg);
93 }
94 
95 /*
96  * @brief
97  * Unary operators
98  */
99 
100 /*
101  * @brief
102  * result = -arg
103  */
104 static inline struct fixed31_32 dal_fixed31_32_neg(struct fixed31_32 arg)
105 {
106 	struct fixed31_32 res;
107 
108 	res.value = -arg.value;
109 
110 	return res;
111 }
112 
113 /*
114  * @brief
115  * result = abs(arg) := (arg >= 0) ? arg : -arg
116  */
117 static inline struct fixed31_32 dal_fixed31_32_abs(struct fixed31_32 arg)
118 {
119 	if (arg.value < 0)
120 		return dal_fixed31_32_neg(arg);
121 	else
122 		return arg;
123 }
124 
125 /*
126  * @brief
127  * Binary relational operators
128  */
129 
130 /*
131  * @brief
132  * result = arg1 < arg2
133  */
134 static inline bool dal_fixed31_32_lt(struct fixed31_32 arg1,
135 				     struct fixed31_32 arg2)
136 {
137 	return arg1.value < arg2.value;
138 }
139 
140 /*
141  * @brief
142  * result = arg1 <= arg2
143  */
144 static inline bool dal_fixed31_32_le(struct fixed31_32 arg1,
145 				     struct fixed31_32 arg2)
146 {
147 	return arg1.value <= arg2.value;
148 }
149 
150 /*
151  * @brief
152  * result = arg1 == arg2
153  */
154 static inline bool dal_fixed31_32_eq(struct fixed31_32 arg1,
155 				     struct fixed31_32 arg2)
156 {
157 	return arg1.value == arg2.value;
158 }
159 
160 /*
161  * @brief
162  * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
163  */
164 static inline struct fixed31_32 dal_fixed31_32_min(struct fixed31_32 arg1,
165 						   struct fixed31_32 arg2)
166 {
167 	if (arg1.value <= arg2.value)
168 		return arg1;
169 	else
170 		return arg2;
171 }
172 
173 /*
174  * @brief
175  * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
176  */
177 static inline struct fixed31_32 dal_fixed31_32_max(struct fixed31_32 arg1,
178 						   struct fixed31_32 arg2)
179 {
180 	if (arg1.value <= arg2.value)
181 		return arg2;
182 	else
183 		return arg1;
184 }
185 
186 /*
187  * @brief
188  *          | min_value, when arg <= min_value
189  * result = | arg, when min_value < arg < max_value
190  *          | max_value, when arg >= max_value
191  */
192 static inline struct fixed31_32 dal_fixed31_32_clamp(
193 	struct fixed31_32 arg,
194 	struct fixed31_32 min_value,
195 	struct fixed31_32 max_value)
196 {
197 	if (dal_fixed31_32_le(arg, min_value))
198 		return min_value;
199 	else if (dal_fixed31_32_le(max_value, arg))
200 		return max_value;
201 	else
202 		return arg;
203 }
204 
205 /*
206  * @brief
207  * Binary shift operators
208  */
209 
210 /*
211  * @brief
212  * result = arg << shift
213  */
214 struct fixed31_32 dal_fixed31_32_shl(
215 	struct fixed31_32 arg,
216 	uint8_t shift);
217 
218 /*
219  * @brief
220  * result = arg >> shift
221  */
222 static inline struct fixed31_32 dal_fixed31_32_shr(
223 	struct fixed31_32 arg,
224 	uint8_t shift)
225 {
226 	struct fixed31_32 res;
227 	res.value = arg.value >> shift;
228 	return res;
229 }
230 
231 /*
232  * @brief
233  * Binary additive operators
234  */
235 
236 /*
237  * @brief
238  * result = arg1 + arg2
239  */
240 struct fixed31_32 dal_fixed31_32_add(
241 	struct fixed31_32 arg1,
242 	struct fixed31_32 arg2);
243 
244 /*
245  * @brief
246  * result = arg1 + arg2
247  */
248 static inline struct fixed31_32 dal_fixed31_32_add_int(struct fixed31_32 arg1,
249 						       int32_t arg2)
250 {
251 	return dal_fixed31_32_add(arg1,
252 				  dal_fixed31_32_from_int(arg2));
253 }
254 
255 /*
256  * @brief
257  * result = arg1 - arg2
258  */
259 struct fixed31_32 dal_fixed31_32_sub(
260 	struct fixed31_32 arg1,
261 	struct fixed31_32 arg2);
262 
263 /*
264  * @brief
265  * result = arg1 - arg2
266  */
267 static inline struct fixed31_32 dal_fixed31_32_sub_int(struct fixed31_32 arg1,
268 						       int32_t arg2)
269 {
270 	return dal_fixed31_32_sub(arg1,
271 				  dal_fixed31_32_from_int(arg2));
272 }
273 
274 
275 /*
276  * @brief
277  * Binary multiplicative operators
278  */
279 
280 /*
281  * @brief
282  * result = arg1 * arg2
283  */
284 struct fixed31_32 dal_fixed31_32_mul(
285 	struct fixed31_32 arg1,
286 	struct fixed31_32 arg2);
287 
288 
289 /*
290  * @brief
291  * result = arg1 * arg2
292  */
293 static inline struct fixed31_32 dal_fixed31_32_mul_int(struct fixed31_32 arg1,
294 						       int32_t arg2)
295 {
296 	return dal_fixed31_32_mul(arg1,
297 				  dal_fixed31_32_from_int(arg2));
298 }
299 
300 /*
301  * @brief
302  * result = square(arg) := arg * arg
303  */
304 struct fixed31_32 dal_fixed31_32_sqr(
305 	struct fixed31_32 arg);
306 
307 /*
308  * @brief
309  * result = arg1 / arg2
310  */
311 static inline struct fixed31_32 dal_fixed31_32_div_int(struct fixed31_32 arg1,
312 						       int64_t arg2)
313 {
314 	return dal_fixed31_32_from_fraction(arg1.value,
315 					    dal_fixed31_32_from_int(arg2).value);
316 }
317 
318 /*
319  * @brief
320  * result = arg1 / arg2
321  */
322 static inline struct fixed31_32 dal_fixed31_32_div(struct fixed31_32 arg1,
323 						   struct fixed31_32 arg2)
324 {
325 	return dal_fixed31_32_from_fraction(arg1.value,
326 					    arg2.value);
327 }
328 
329 /*
330  * @brief
331  * Reciprocal function
332  */
333 
334 /*
335  * @brief
336  * result = reciprocal(arg) := 1 / arg
337  *
338  * @note
339  * No special actions taken in case argument is zero.
340  */
341 struct fixed31_32 dal_fixed31_32_recip(
342 	struct fixed31_32 arg);
343 
344 /*
345  * @brief
346  * Trigonometric functions
347  */
348 
349 /*
350  * @brief
351  * result = sinc(arg) := sin(arg) / arg
352  *
353  * @note
354  * Argument specified in radians,
355  * internally it's normalized to [-2pi...2pi] range.
356  */
357 struct fixed31_32 dal_fixed31_32_sinc(
358 	struct fixed31_32 arg);
359 
360 /*
361  * @brief
362  * result = sin(arg)
363  *
364  * @note
365  * Argument specified in radians,
366  * internally it's normalized to [-2pi...2pi] range.
367  */
368 struct fixed31_32 dal_fixed31_32_sin(
369 	struct fixed31_32 arg);
370 
371 /*
372  * @brief
373  * result = cos(arg)
374  *
375  * @note
376  * Argument specified in radians
377  * and should be in [-2pi...2pi] range -
378  * passing arguments outside that range
379  * will cause incorrect result!
380  */
381 struct fixed31_32 dal_fixed31_32_cos(
382 	struct fixed31_32 arg);
383 
384 /*
385  * @brief
386  * Transcendent functions
387  */
388 
389 /*
390  * @brief
391  * result = exp(arg)
392  *
393  * @note
394  * Currently, function is verified for abs(arg) <= 1.
395  */
396 struct fixed31_32 dal_fixed31_32_exp(
397 	struct fixed31_32 arg);
398 
399 /*
400  * @brief
401  * result = log(arg)
402  *
403  * @note
404  * Currently, abs(arg) should be less than 1.
405  * No normalization is done.
406  * Currently, no special actions taken
407  * in case of invalid argument(s). Take care!
408  */
409 struct fixed31_32 dal_fixed31_32_log(
410 	struct fixed31_32 arg);
411 
412 /*
413  * @brief
414  * Power function
415  */
416 
417 /*
418  * @brief
419  * result = pow(arg1, arg2)
420  *
421  * @note
422  * Currently, abs(arg1) should be less than 1. Take care!
423  */
424 struct fixed31_32 dal_fixed31_32_pow(
425 	struct fixed31_32 arg1,
426 	struct fixed31_32 arg2);
427 
428 /*
429  * @brief
430  * Rounding functions
431  */
432 
433 /*
434  * @brief
435  * result = floor(arg) := greatest integer lower than or equal to arg
436  */
437 int32_t dal_fixed31_32_floor(
438 	struct fixed31_32 arg);
439 
440 /*
441  * @brief
442  * result = round(arg) := integer nearest to arg
443  */
444 int32_t dal_fixed31_32_round(
445 	struct fixed31_32 arg);
446 
447 /*
448  * @brief
449  * result = ceil(arg) := lowest integer greater than or equal to arg
450  */
451 int32_t dal_fixed31_32_ceil(
452 	struct fixed31_32 arg);
453 
454 /* the following two function are used in scaler hw programming to convert fixed
455  * point value to format 2 bits from integer part and 19 bits from fractional
456  * part. The same applies for u0d19, 0 bits from integer part and 19 bits from
457  * fractional
458  */
459 
460 uint32_t dal_fixed31_32_u2d19(
461 	struct fixed31_32 arg);
462 
463 uint32_t dal_fixed31_32_u0d19(
464 	struct fixed31_32 arg);
465 
466 
467 uint32_t dal_fixed31_32_clamp_u0d14(
468 	struct fixed31_32 arg);
469 
470 uint32_t dal_fixed31_32_clamp_u0d10(
471 	struct fixed31_32 arg);
472 
473 #endif
474