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