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