LCOV - code coverage report
Current view: top level - include/allegro5/inline - fmaths.inl (source / functions) Hit Total Coverage
Test: allegro_auto.info Lines: 1 15 6.7 %
Date: 2013-01-02 Functions: 0 15 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 257 1280 20.1 %

           Branch data     Line data    Source code
       1                 :            : /*         ______   ___    ___
       2                 :            :  *        /\  _  \ /\_ \  /\_ \
       3                 :            :  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
       4                 :            :  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
       5                 :            :  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
       6                 :            :  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
       7                 :            :  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
       8                 :            :  *                                           /\____/
       9                 :            :  *                                           \_/__/
      10                 :            :  *
      11                 :            :  *      Fixed point math inline functions (generic C).
      12                 :            :  *
      13                 :            :  *      By Shawn Hargreaves.
      14                 :            :  *
      15                 :            :  *      See readme.txt for copyright information.
      16                 :            :  */
      17                 :            : 
      18                 :            : 
      19                 :            : #ifndef __al_included_allegro5_inline_fmaths_inl
      20                 :            : #define __al_included_allegro5_inline_fmaths_inl
      21                 :            : 
      22                 :            : #include "allegro5/error.h"
      23                 :            : 
      24                 :            : #ifdef __cplusplus
      25                 :            :    extern "C" {
      26                 :            : #endif
      27                 :            : 
      28                 :            : 
      29                 :            : /* al_ftofix and al_fixtof are used in generic C versions of al_fixmul and al_fixdiv */
      30 [ -  + ][ -  + ]:     213242 : AL_INLINE(al_fixed, al_ftofix, (double x),
         [ +  - ][ -  + ]
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  + ]
         [ +  + ][ -  + ]
         [ -  + ][ +  + ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  + ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  + ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  + ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ -  + ]
         [ -  + ][ +  - ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      31                 :            : {
      32                 :            :    if (x > 32767.0) {
      33                 :            :       al_set_errno(ERANGE);
      34                 :            :       return 0x7FFFFFFF;
      35                 :            :    }
      36                 :            : 
      37                 :            :    if (x < -32767.0) {
      38                 :            :       al_set_errno(ERANGE);
      39                 :            :       return -0x7FFFFFFF;
      40                 :            :    }
      41                 :            : 
      42                 :            :    return (al_fixed)(x * 65536.0 + (x < 0 ? -0.5 : 0.5));
      43                 :            : })
      44                 :            : 
      45                 :            : 
      46                 :          0 : AL_INLINE(double, al_fixtof, (al_fixed x),
      47                 :            : {
      48                 :            :    return (double)x / 65536.0;
      49                 :            : })
      50                 :            : 
      51                 :            : 
      52                 :            : #ifdef ALLEGRO_NO_ASM
      53                 :            : 
      54                 :            : /* use generic C versions */
      55                 :            : 
      56 [ #  # ][ #  # ]:          0 : AL_INLINE(al_fixed, al_fixadd, (al_fixed x, al_fixed y),
                 [ #  # ]
      57                 :            : {
      58                 :            :    al_fixed result = x + y;
      59                 :            : 
      60                 :            :    if (result >= 0) {
      61                 :            :       if ((x < 0) && (y < 0)) {
      62                 :            :          al_set_errno(ERANGE);
      63                 :            :          return -0x7FFFFFFF;
      64                 :            :       }
      65                 :            :       else
      66                 :            :          return result;
      67                 :            :    }
      68                 :            :    else {
      69                 :            :       if ((x > 0) && (y > 0)) {
      70                 :            :          al_set_errno(ERANGE);
      71                 :            :          return 0x7FFFFFFF;
      72                 :            :       }
      73                 :            :       else
      74                 :            :          return result;
      75                 :            :    }
      76                 :            : })
      77                 :            : 
      78                 :            : 
      79 [ #  # ][ #  # ]:          0 : AL_INLINE(al_fixed, al_fixsub, (al_fixed x, al_fixed y),
                 [ #  # ]
      80                 :            : {
      81                 :            :    al_fixed result = x - y;
      82                 :            : 
      83                 :            :    if (result >= 0) {
      84                 :            :       if ((x < 0) && (y > 0)) {
      85                 :            :          al_set_errno(ERANGE);
      86                 :            :          return -0x7FFFFFFF;
      87                 :            :       }
      88                 :            :       else
      89                 :            :          return result;
      90                 :            :    }
      91                 :            :    else {
      92                 :            :       if ((x > 0) && (y < 0)) {
      93                 :            :          al_set_errno(ERANGE);
      94                 :            :          return 0x7FFFFFFF;
      95                 :            :       }
      96                 :            :       else
      97                 :            :          return result;
      98                 :            :    }
      99                 :            : })
     100                 :            : 
     101                 :            : 
     102                 :            : /* In benchmarks conducted circa May 2005 we found that, in the main:
     103                 :            :  * - IA32 machines performed faster with one implementation;
     104                 :            :  * - AMD64 and G4 machines performed faster with another implementation.
     105                 :            :  *
     106                 :            :  * Benchmarks were mainly done with differing versions of gcc.
     107                 :            :  * Results varied with other compilers, optimisation levels, etc.
     108                 :            :  * so this is not optimal, though a tenable compromise.
     109                 :            :  *
     110                 :            :  * Note that the following implementation are NOT what were benchmarked.
     111                 :            :  * We had forgotten to put in overflow detection in those versions.
     112                 :            :  * If you don't need overflow detection then previous versions in the
     113                 :            :  * CVS tree might be worth looking at.
     114                 :            :  *
     115                 :            :  * PS. Don't move the #ifs inside the AL_INLINE; BCC doesn't like it.
     116                 :            :  */
     117                 :            : #if (defined ALLEGRO_I386) || (!defined LONG_LONG)
     118                 :            :    AL_INLINE(al_fixed, al_fixmul, (al_fixed x, al_fixed y),
     119                 :            :    {
     120                 :            :       return al_ftofix(al_fixtof(x) * al_fixtof(y));
     121                 :            :    })
     122                 :            : #else
     123 [ #  # ][ #  # ]:          0 :    AL_INLINE(al_fixed, al_fixmul, (al_fixed x, al_fixed y),
     124                 :            :    {
     125                 :            :       LONG_LONG lx = x;
     126                 :            :       LONG_LONG ly = y;
     127                 :            :       LONG_LONG lres = (lx*ly);
     128                 :            : 
     129                 :            :       if (lres > 0x7FFFFFFF0000LL) {
     130                 :            :          al_set_errno(ERANGE);
     131                 :            :          return 0x7FFFFFFF;
     132                 :            :       }
     133                 :            :       else if (lres < -0x7FFFFFFF0000LL) {
     134                 :            :          al_set_errno(ERANGE);
     135                 :            :          return 0x80000000;
     136                 :            :       }
     137                 :            :       else {
     138                 :            :          int res = lres >> 16;
     139                 :            :          return res;
     140                 :            :       }
     141                 :            :    })
     142                 :            : #endif      /* al_fixmul() C implementations */
     143                 :            : 
     144                 :            : 
     145                 :            : #if (defined ALLEGRO_CFG_NO_FPU) && (defined LONG_LONG)
     146                 :            : AL_INLINE(al_fixed, al_fixdiv, (al_fixed x, al_fixed y),
     147                 :            : {
     148                 :            :    LONG_LONG lres = x;
     149                 :            :    if (y == 0) {
     150                 :            :       al_set_errno(ERANGE);
     151                 :            :       return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF;
     152                 :            :    }
     153                 :            :    lres <<= 16;
     154                 :            :    lres /= y;
     155                 :            :    if (lres > 0x7FFFFFFF) {
     156                 :            :       al_set_errno(ERANGE);
     157                 :            :       return 0x7FFFFFFF;
     158                 :            :    }
     159                 :            :    else if (lres < -0x7FFFFFFF) {
     160                 :            :       al_set_errno(ERANGE);
     161                 :            :       return 0x80000000;
     162                 :            :    }
     163                 :            :    else {
     164                 :            :       return (al_fixed)(lres);
     165                 :            :    }
     166                 :            : })
     167                 :            : #else
     168 [ #  # ][ #  # ]:          0 : AL_INLINE(al_fixed, al_fixdiv, (al_fixed x, al_fixed y),
         [ #  # ][ #  # ]
     169                 :            : {
     170                 :            :    if (y == 0) {
     171                 :            :       al_set_errno(ERANGE);
     172                 :            :       return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF;
     173                 :            :    }
     174                 :            :    else
     175                 :            :       return al_ftofix(al_fixtof(x) / al_fixtof(y));
     176                 :            : })
     177                 :            : #endif
     178                 :            : 
     179                 :            : 
     180         [ #  # ]:          0 : AL_INLINE(int, al_fixfloor, (al_fixed x),
     181                 :            : {
     182                 :            :    /* (x >> 16) is not portable */
     183                 :            :    if (x >= 0)
     184                 :            :       return (x >> 16);
     185                 :            :    else
     186                 :            :       return ~((~x) >> 16);
     187                 :            : })
     188                 :            : 
     189                 :            : 
     190         [ #  # ]:          0 : AL_INLINE(int, al_fixceil, (al_fixed x),
     191                 :            : {
     192                 :            :    if (x > 0x7FFF0000) {
     193                 :            :       al_set_errno(ERANGE);
     194                 :            :       return 0x7FFF;
     195                 :            :    }
     196                 :            : 
     197                 :            :    return al_fixfloor(x + 0xFFFF);
     198                 :            : })
     199                 :            : 
     200                 :            : #endif      /* C vs. inline asm */
     201                 :            : 
     202                 :            : 
     203                 :          0 : AL_INLINE(al_fixed, al_itofix, (int x),
     204                 :            : {
     205                 :            :    return x << 16;
     206                 :            : })
     207                 :            : 
     208                 :            : 
     209                 :          0 : AL_INLINE(int, al_fixtoi, (al_fixed x),
     210                 :            : {
     211                 :            :    return al_fixfloor(x) + ((x & 0x8000) >> 15);
     212                 :            : })
     213                 :            : 
     214                 :            : 
     215                 :          0 : AL_INLINE(al_fixed, al_fixcos, (al_fixed x),
     216                 :            : {
     217                 :            :    return _al_fix_cos_tbl[((x + 0x4000) >> 15) & 0x1FF];
     218                 :            : })
     219                 :            : 
     220                 :            : 
     221                 :          0 : AL_INLINE(al_fixed, al_fixsin, (al_fixed x),
     222                 :            : {
     223                 :            :    return _al_fix_cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF];
     224                 :            : })
     225                 :            : 
     226                 :            : 
     227                 :          0 : AL_INLINE(al_fixed, al_fixtan, (al_fixed x),
     228                 :            : {
     229                 :            :    return _al_fix_tan_tbl[((x + 0x4000) >> 15) & 0xFF];
     230                 :            : })
     231                 :            : 
     232                 :            : 
     233         [ #  # ]:          0 : AL_INLINE(al_fixed, al_fixacos, (al_fixed x),
     234                 :            : {
     235                 :            :    if ((x < -65536) || (x > 65536)) {
     236                 :            :       al_set_errno(EDOM);
     237                 :            :       return 0;
     238                 :            :    }
     239                 :            : 
     240                 :            :    return _al_fix_acos_tbl[(x+65536+127)>>8];
     241                 :            : })
     242                 :            : 
     243                 :            : 
     244         [ #  # ]:          0 : AL_INLINE(al_fixed, al_fixasin, (al_fixed x),
     245                 :            : {
     246                 :            :    if ((x < -65536) || (x > 65536)) {
     247                 :            :       al_set_errno(EDOM);
     248                 :            :       return 0;
     249                 :            :    }
     250                 :            : 
     251                 :            :    return 0x00400000 - _al_fix_acos_tbl[(x+65536+127)>>8];
     252                 :            : })
     253                 :            : 
     254                 :            : #ifdef __cplusplus
     255                 :            :    }
     256                 :            : #endif
     257                 :            : 
     258                 :            : #endif
     259                 :            : 
     260                 :            : 

Generated by: LCOV version 1.9