cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fixed31_32.h (11322B)


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