LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/include - fixed31_32.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 60 1.7 %
Date: 2022-12-09 01:23:36 Functions: 0 6 0.0 %

          Line data    Source code
       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             : /*
      73             :  * @brief
      74             :  * Initialization routines
      75             :  */
      76             : 
      77             : /*
      78             :  * @brief
      79             :  * result = numerator / denominator
      80             :  */
      81             : struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator);
      82             : 
      83             : /*
      84             :  * @brief
      85             :  * result = arg
      86             :  */
      87             : static inline struct fixed31_32 dc_fixpt_from_int(int arg)
      88             : {
      89             :         struct fixed31_32 res;
      90             : 
      91           7 :         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             :  */
     105             : static inline struct fixed31_32 dc_fixpt_neg(struct fixed31_32 arg)
     106             : {
     107             :         struct fixed31_32 res;
     108             : 
     109           0 :         res.value = -arg.value;
     110             : 
     111             :         return res;
     112             : }
     113             : 
     114             : /*
     115             :  * @brief
     116             :  * result = abs(arg) := (arg >= 0) ? arg : -arg
     117             :  */
     118             : static inline struct fixed31_32 dc_fixpt_abs(struct fixed31_32 arg)
     119             : {
     120           0 :         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             :  */
     135             : static 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             :  */
     144             : static 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             :  */
     153             : static 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             :  */
     162             : static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, struct fixed31_32 arg2)
     163             : {
     164           0 :         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             :  */
     174             : static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1, struct fixed31_32 arg2)
     175             : {
     176           0 :         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             :  */
     188             : static 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           0 :         if (dc_fixpt_le(arg, min_value))
     194             :                 return min_value;
     195           0 :         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             :  */
     210           0 : static inline struct fixed31_32 dc_fixpt_shl(struct fixed31_32 arg, unsigned char shift)
     211             : {
     212           0 :         ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
     213             :                 ((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
     214             : 
     215           0 :         arg.value = arg.value << shift;
     216             : 
     217           0 :         return arg;
     218             : }
     219             : 
     220             : /*
     221             :  * @brief
     222             :  * result = arg >> shift
     223             :  */
     224             : static inline struct fixed31_32 dc_fixpt_shr(struct fixed31_32 arg, unsigned char shift)
     225             : {
     226           0 :         bool negative = arg.value < 0;
     227             : 
     228           0 :         if (negative)
     229           0 :                 arg.value = -arg.value;
     230           0 :         arg.value = arg.value >> shift;
     231           0 :         if (negative)
     232           0 :                 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             :  */
     245           0 : static inline struct fixed31_32 dc_fixpt_add(struct fixed31_32 arg1, struct fixed31_32 arg2)
     246             : {
     247             :         struct fixed31_32 res;
     248             : 
     249           0 :         ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
     250             :                 ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
     251             : 
     252           0 :         res.value = arg1.value + arg2.value;
     253             : 
     254           0 :         return res;
     255             : }
     256             : 
     257             : /*
     258             :  * @brief
     259             :  * result = arg1 + arg2
     260             :  */
     261             : static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1, int arg2)
     262             : {
     263           0 :         return dc_fixpt_add(arg1, dc_fixpt_from_int(arg2));
     264             : }
     265             : 
     266             : /*
     267             :  * @brief
     268             :  * result = arg1 - arg2
     269             :  */
     270           0 : static inline struct fixed31_32 dc_fixpt_sub(struct fixed31_32 arg1, struct fixed31_32 arg2)
     271             : {
     272             :         struct fixed31_32 res;
     273             : 
     274           0 :         ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
     275             :                 ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
     276             : 
     277           0 :         res.value = arg1.value - arg2.value;
     278             : 
     279           0 :         return res;
     280             : }
     281             : 
     282             : /*
     283             :  * @brief
     284             :  * result = arg1 - arg2
     285             :  */
     286             : static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, int arg2)
     287             : {
     288           0 :         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             :  */
     301             : struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2);
     302             : 
     303             : 
     304             : /*
     305             :  * @brief
     306             :  * result = arg1 * arg2
     307             :  */
     308             : static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1, int arg2)
     309             : {
     310           0 :         return dc_fixpt_mul(arg1, dc_fixpt_from_int(arg2));
     311             : }
     312             : 
     313             : /*
     314             :  * @brief
     315             :  * result = square(arg) := arg * arg
     316             :  */
     317             : struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg);
     318             : 
     319             : /*
     320             :  * @brief
     321             :  * result = arg1 / arg2
     322             :  */
     323             : static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1, long long arg2)
     324             : {
     325           0 :         return dc_fixpt_from_fraction(arg1.value, dc_fixpt_from_int((int)arg2).value);
     326             : }
     327             : 
     328             : /*
     329             :  * @brief
     330             :  * result = arg1 / arg2
     331             :  */
     332             : static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, struct fixed31_32 arg2)
     333             : {
     334           0 :         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             :  */
     349             : struct 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             :  */
     364             : struct 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             :  */
     374             : struct 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             :  */
     386             : struct 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             :  */
     400             : struct 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             :  */
     412             : struct 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             :  */
     426           0 : static inline struct fixed31_32 dc_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2)
     427             : {
     428           0 :         if (arg1.value == 0)
     429           0 :                 return arg2.value == 0 ? dc_fixpt_one : dc_fixpt_zero;
     430             : 
     431           0 :         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             :  */
     446             : static inline int dc_fixpt_floor(struct fixed31_32 arg)
     447             : {
     448           0 :         unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
     449             : 
     450           0 :         if (arg.value >= 0)
     451           0 :                 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
     452             :         else
     453           0 :                 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
     454             : }
     455             : 
     456             : /*
     457             :  * @brief
     458             :  * result = round(arg) := integer nearest to arg
     459             :  */
     460           0 : static inline int dc_fixpt_round(struct fixed31_32 arg)
     461             : {
     462           0 :         unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
     463             : 
     464           0 :         const long long summand = dc_fixpt_half.value;
     465             : 
     466           0 :         ASSERT(LLONG_MAX - (long long)arg_value >= summand);
     467             : 
     468           0 :         arg_value += summand;
     469             : 
     470           0 :         if (arg.value >= 0)
     471           0 :                 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
     472             :         else
     473           0 :                 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             :  */
     480           0 : static inline int dc_fixpt_ceil(struct fixed31_32 arg)
     481             : {
     482           0 :         unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
     483             : 
     484           0 :         const long long summand = dc_fixpt_one.value -
     485             :                 dc_fixpt_epsilon.value;
     486             : 
     487           0 :         ASSERT(LLONG_MAX - (long long)arg_value >= summand);
     488             : 
     489           0 :         arg_value += summand;
     490             : 
     491           0 :         if (arg.value >= 0)
     492           0 :                 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
     493             :         else
     494           0 :                 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             : 
     503             : unsigned int dc_fixpt_u4d19(struct fixed31_32 arg);
     504             : 
     505             : unsigned int dc_fixpt_u3d19(struct fixed31_32 arg);
     506             : 
     507             : unsigned int dc_fixpt_u2d19(struct fixed31_32 arg);
     508             : 
     509             : unsigned int dc_fixpt_u0d19(struct fixed31_32 arg);
     510             : 
     511             : unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg);
     512             : 
     513             : unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg);
     514             : 
     515             : int dc_fixpt_s4d19(struct fixed31_32 arg);
     516             : 
     517             : static inline struct fixed31_32 dc_fixpt_truncate(struct fixed31_32 arg, unsigned int frac_bits)
     518             : {
     519           0 :         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           0 :         if (negative)
     527           0 :                 arg.value = -arg.value;
     528           0 :         arg.value &= (~0LL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
     529           0 :         if (negative)
     530           0 :                 arg.value = -arg.value;
     531             :         return arg;
     532             : }
     533             : 
     534             : #endif

Generated by: LCOV version 1.14