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 #define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
30 #ifndef LLONG_MIN
31 #define LLONG_MIN (1LL<<63)
32 #endif
33 #ifndef LLONG_MAX
34 #define LLONG_MAX (-1LL>>1)
35 #endif
36 
37 /*
38  * @brief
39  * Arithmetic operations on real numbers
40  * represented as fixed-point numbers.
41  * There are: 1 bit for sign,
42  * 31 bit for integer part,
43  * 32 bits for fractional part.
44  *
45  * @note
46  * Currently, overflows and underflows are asserted;
47  * no special result returned.
48  */
49 
50 struct fixed31_32 {
51 	long long value;
52 };
53 
54 
55 /*
56  * @brief
57  * Useful constants
58  */
59 
60 static const struct fixed31_32 dc_fixpt_zero = { 0 };
61 static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
62 static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL };
63 static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL };
64 
65 static const struct fixed31_32 dc_fixpt_pi = { 13493037705LL };
66 static const struct fixed31_32 dc_fixpt_two_pi = { 26986075409LL };
67 static const struct fixed31_32 dc_fixpt_e = { 11674931555LL };
68 static const struct fixed31_32 dc_fixpt_ln2 = { 2977044471LL };
69 static const struct fixed31_32 dc_fixpt_ln2_div_2 = { 1488522236LL };
70 
71 /*
72  * @brief
73  * Initialization routines
74  */
75 
76 /*
77  * @brief
78  * result = numerator / denominator
79  */
80 struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator);
81 
82 /*
83  * @brief
84  * result = arg
85  */
86 static inline struct fixed31_32 dc_fixpt_from_int(int arg)
87 {
88 	struct fixed31_32 res;
89 
90 	res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
91 
92 	return res;
93 }
94 
95 /*
96  * @brief
97  * Unary operators
98  */
99 
100 /*
101  * @brief
102  * result = -arg
103  */
104 static inline struct fixed31_32 dc_fixpt_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 dc_fixpt_abs(struct fixed31_32 arg)
118 {
119 	if (arg.value < 0)
120 		return dc_fixpt_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 dc_fixpt_lt(struct fixed31_32 arg1, struct fixed31_32 arg2)
135 {
136 	return arg1.value < arg2.value;
137 }
138 
139 /*
140  * @brief
141  * result = arg1 <= arg2
142  */
143 static inline bool dc_fixpt_le(struct fixed31_32 arg1, struct fixed31_32 arg2)
144 {
145 	return arg1.value <= arg2.value;
146 }
147 
148 /*
149  * @brief
150  * result = arg1 == arg2
151  */
152 static inline bool dc_fixpt_eq(struct fixed31_32 arg1, struct fixed31_32 arg2)
153 {
154 	return arg1.value == arg2.value;
155 }
156 
157 /*
158  * @brief
159  * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
160  */
161 static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, struct fixed31_32 arg2)
162 {
163 	if (arg1.value <= arg2.value)
164 		return arg1;
165 	else
166 		return arg2;
167 }
168 
169 /*
170  * @brief
171  * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
172  */
173 static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1, struct fixed31_32 arg2)
174 {
175 	if (arg1.value <= arg2.value)
176 		return arg2;
177 	else
178 		return arg1;
179 }
180 
181 /*
182  * @brief
183  *          | min_value, when arg <= min_value
184  * result = | arg, when min_value < arg < max_value
185  *          | max_value, when arg >= max_value
186  */
187 static inline struct fixed31_32 dc_fixpt_clamp(
188 	struct fixed31_32 arg,
189 	struct fixed31_32 min_value,
190 	struct fixed31_32 max_value)
191 {
192 	if (dc_fixpt_le(arg, min_value))
193 		return min_value;
194 	else if (dc_fixpt_le(max_value, arg))
195 		return max_value;
196 	else
197 		return arg;
198 }
199 
200 /*
201  * @brief
202  * Binary shift operators
203  */
204 
205 /*
206  * @brief
207  * result = arg << shift
208  */
209 static inline struct fixed31_32 dc_fixpt_shl(struct fixed31_32 arg, unsigned char shift)
210 {
211 	ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
212 		((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
213 
214 	arg.value = arg.value << shift;
215 
216 	return arg;
217 }
218 
219 /*
220  * @brief
221  * result = arg >> shift
222  */
223 static inline struct fixed31_32 dc_fixpt_shr(struct fixed31_32 arg, unsigned char shift)
224 {
225 	bool negative = arg.value < 0;
226 
227 	if (negative)
228 		arg.value = -arg.value;
229 	arg.value = arg.value >> shift;
230 	if (negative)
231 		arg.value = -arg.value;
232 	return arg;
233 }
234 
235 /*
236  * @brief
237  * Binary additive operators
238  */
239 
240 /*
241  * @brief
242  * result = arg1 + arg2
243  */
244 static inline struct fixed31_32 dc_fixpt_add(struct fixed31_32 arg1, struct fixed31_32 arg2)
245 {
246 	struct fixed31_32 res;
247 
248 	ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
249 		((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
250 
251 	res.value = arg1.value + arg2.value;
252 
253 	return res;
254 }
255 
256 /*
257  * @brief
258  * result = arg1 + arg2
259  */
260 static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1, int arg2)
261 {
262 	return dc_fixpt_add(arg1, dc_fixpt_from_int(arg2));
263 }
264 
265 /*
266  * @brief
267  * result = arg1 - arg2
268  */
269 static inline struct fixed31_32 dc_fixpt_sub(struct fixed31_32 arg1, struct fixed31_32 arg2)
270 {
271 	struct fixed31_32 res;
272 
273 	ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
274 		((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
275 
276 	res.value = arg1.value - arg2.value;
277 
278 	return res;
279 }
280 
281 /*
282  * @brief
283  * result = arg1 - arg2
284  */
285 static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, int arg2)
286 {
287 	return dc_fixpt_sub(arg1, dc_fixpt_from_int(arg2));
288 }
289 
290 
291 /*
292  * @brief
293  * Binary multiplicative operators
294  */
295 
296 /*
297  * @brief
298  * result = arg1 * arg2
299  */
300 struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2);
301 
302 
303 /*
304  * @brief
305  * result = arg1 * arg2
306  */
307 static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1, int arg2)
308 {
309 	return dc_fixpt_mul(arg1, dc_fixpt_from_int(arg2));
310 }
311 
312 /*
313  * @brief
314  * result = square(arg) := arg * arg
315  */
316 struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg);
317 
318 /*
319  * @brief
320  * result = arg1 / arg2
321  */
322 static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1, long long arg2)
323 {
324 	return dc_fixpt_from_fraction(arg1.value, dc_fixpt_from_int(arg2).value);
325 }
326 
327 /*
328  * @brief
329  * result = arg1 / arg2
330  */
331 static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, struct fixed31_32 arg2)
332 {
333 	return dc_fixpt_from_fraction(arg1.value, arg2.value);
334 }
335 
336 /*
337  * @brief
338  * Reciprocal function
339  */
340 
341 /*
342  * @brief
343  * result = reciprocal(arg) := 1 / arg
344  *
345  * @note
346  * No special actions taken in case argument is zero.
347  */
348 struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg);
349 
350 /*
351  * @brief
352  * Trigonometric functions
353  */
354 
355 /*
356  * @brief
357  * result = sinc(arg) := sin(arg) / arg
358  *
359  * @note
360  * Argument specified in radians,
361  * internally it's normalized to [-2pi...2pi] range.
362  */
363 struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg);
364 
365 /*
366  * @brief
367  * result = sin(arg)
368  *
369  * @note
370  * Argument specified in radians,
371  * internally it's normalized to [-2pi...2pi] range.
372  */
373 struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg);
374 
375 /*
376  * @brief
377  * result = cos(arg)
378  *
379  * @note
380  * Argument specified in radians
381  * and should be in [-2pi...2pi] range -
382  * passing arguments outside that range
383  * will cause incorrect result!
384  */
385 struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg);
386 
387 /*
388  * @brief
389  * Transcendent functions
390  */
391 
392 /*
393  * @brief
394  * result = exp(arg)
395  *
396  * @note
397  * Currently, function is verified for abs(arg) <= 1.
398  */
399 struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg);
400 
401 /*
402  * @brief
403  * result = log(arg)
404  *
405  * @note
406  * Currently, abs(arg) should be less than 1.
407  * No normalization is done.
408  * Currently, no special actions taken
409  * in case of invalid argument(s). Take care!
410  */
411 struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg);
412 
413 /*
414  * @brief
415  * Power function
416  */
417 
418 /*
419  * @brief
420  * result = pow(arg1, arg2)
421  *
422  * @note
423  * Currently, abs(arg1) should be less than 1. Take care!
424  */
425 static inline struct fixed31_32 dc_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2)
426 {
427 	return dc_fixpt_exp(
428 		dc_fixpt_mul(
429 			dc_fixpt_log(arg1),
430 			arg2));
431 }
432 
433 /*
434  * @brief
435  * Rounding functions
436  */
437 
438 /*
439  * @brief
440  * result = floor(arg) := greatest integer lower than or equal to arg
441  */
442 static inline int dc_fixpt_floor(struct fixed31_32 arg)
443 {
444 	unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
445 
446 	if (arg.value >= 0)
447 		return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
448 	else
449 		return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
450 }
451 
452 /*
453  * @brief
454  * result = round(arg) := integer nearest to arg
455  */
456 static inline int dc_fixpt_round(struct fixed31_32 arg)
457 {
458 	unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
459 
460 	const long long summand = dc_fixpt_half.value;
461 
462 	ASSERT(LLONG_MAX - (long long)arg_value >= summand);
463 
464 	arg_value += summand;
465 
466 	if (arg.value >= 0)
467 		return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
468 	else
469 		return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
470 }
471 
472 /*
473  * @brief
474  * result = ceil(arg) := lowest integer greater than or equal to arg
475  */
476 static inline int dc_fixpt_ceil(struct fixed31_32 arg)
477 {
478 	unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
479 
480 	const long long summand = dc_fixpt_one.value -
481 		dc_fixpt_epsilon.value;
482 
483 	ASSERT(LLONG_MAX - (long long)arg_value >= summand);
484 
485 	arg_value += summand;
486 
487 	if (arg.value >= 0)
488 		return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
489 	else
490 		return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
491 }
492 
493 /* the following two function are used in scaler hw programming to convert fixed
494  * point value to format 2 bits from integer part and 19 bits from fractional
495  * part. The same applies for u0d19, 0 bits from integer part and 19 bits from
496  * fractional
497  */
498 
499 unsigned int dc_fixpt_u3d19(struct fixed31_32 arg);
500 
501 unsigned int dc_fixpt_u2d19(struct fixed31_32 arg);
502 
503 unsigned int dc_fixpt_u0d19(struct fixed31_32 arg);
504 
505 unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg);
506 
507 unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg);
508 
509 int dc_fixpt_s4d19(struct fixed31_32 arg);
510 
511 static inline struct fixed31_32 dc_fixpt_truncate(struct fixed31_32 arg, unsigned int frac_bits)
512 {
513 	bool negative = arg.value < 0;
514 
515 	if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
516 		ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
517 		return arg;
518 	}
519 
520 	if (negative)
521 		arg.value = -arg.value;
522 	arg.value &= (~0LL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
523 	if (negative)
524 		arg.value = -arg.value;
525 	return arg;
526 }
527 
528 #endif
529