LCOV - code coverage report
Current view: directory - gfx/skia/src/core - Sk64.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 177 0 0.0 %
Date: 2012-06-02 Functions: 16 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2006 The Android Open Source Project
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #include "Sk64.h"
      11                 : #include "SkMath.h"
      12                 : 
      13                 : #define shift_left(hi, lo)          \
      14                 :     hi = (hi << 1) | (lo >> 31);    \
      15                 :     lo <<= 1
      16                 : 
      17                 : #define shift_left_bits(hi, lo, bits)           \
      18                 :     SkASSERT((unsigned)(bits) < 31);                \
      19                 :     hi = (hi << (bits)) | (lo >> (32 - (bits)));    \
      20                 :     lo <<= (bits)
      21                 : 
      22                 : //////////////////////////////////////////////////////////////////////
      23                 : 
      24               0 : int Sk64::getClzAbs() const
      25                 : {
      26               0 :     int32_t     hi = fHi;
      27               0 :     uint32_t    lo = fLo;
      28                 : 
      29                 :     // get abs
      30               0 :     if (hi < 0)
      31                 :     {
      32               0 :         hi = -hi - Sk32ToBool(lo);
      33               0 :         lo = 0 - lo;
      34                 :     }
      35               0 :     return hi ? SkCLZ(hi) : SkCLZ(lo) + 32;
      36                 : }
      37                 : 
      38               0 : void Sk64::shiftLeft(unsigned bits)
      39                 : {
      40               0 :     SkASSERT(bits <= 63);
      41               0 :     if (bits == 0)
      42               0 :         return;
      43                 : 
      44               0 :     if (bits >= 32)
      45                 :     {
      46               0 :         fHi = fLo << (bits - 32);
      47               0 :         fLo = 0;
      48                 :     }
      49                 :     else
      50                 :     {
      51               0 :         fHi = (fHi << bits) | (fLo >> (32 - bits));
      52               0 :         fLo <<= bits;
      53                 :     }
      54                 : }
      55                 : 
      56               0 : int32_t Sk64::getShiftRight(unsigned bits) const
      57                 : {
      58               0 :     SkASSERT(bits <= 63);
      59                 : 
      60               0 :     if (bits == 0)
      61               0 :         return fLo;
      62                 : 
      63               0 :     if (bits >= 32)
      64               0 :         return fHi >> (bits - 32);
      65                 :     else
      66                 :     {
      67                 : #ifdef SK_DEBUG
      68               0 :         int32_t tmp = fHi >> bits;
      69               0 :         SkASSERT(tmp == 0 || tmp == -1);
      70                 : #endif
      71               0 :         return (fHi << (32 - bits)) | (fLo >> bits);
      72                 :     }
      73                 : }
      74                 : 
      75               0 : void Sk64::shiftRight(unsigned bits)
      76                 : {
      77               0 :     SkASSERT(bits <= 63);
      78               0 :     if (bits == 0)
      79               0 :         return;
      80                 : 
      81               0 :     if (bits >= 32)
      82                 :     {
      83               0 :         fLo = fHi >> (bits - 32);
      84               0 :         fHi >>= 31;
      85                 :     }
      86                 :     else
      87                 :     {
      88               0 :         fLo = (fHi << (32 - bits)) | (fLo >> bits);
      89               0 :         fHi >>= bits;
      90                 :     }
      91                 : }
      92                 : 
      93               0 : void Sk64::roundRight(unsigned bits)
      94                 : {
      95               0 :     SkASSERT(bits <= 63);
      96               0 :     if (bits)
      97                 :     {
      98                 :         Sk64 one;
      99               0 :         one.set(1);
     100               0 :         one.shiftLeft(bits - 1);
     101               0 :         this->add(one);
     102               0 :         this->shiftRight(bits);
     103                 :     }
     104               0 : }
     105                 : 
     106               0 : int Sk64::shiftToMake32() const
     107                 : {
     108               0 :     int32_t     hi = fHi;
     109               0 :     uint32_t    lo = fLo;
     110                 : 
     111               0 :     if (hi < 0) // make it positive
     112                 :     {
     113               0 :         hi = -hi - Sk32ToBool(lo);
     114               0 :         lo = 0 - lo;
     115                 :     }
     116                 : 
     117               0 :     if (hi == 0)
     118               0 :         return lo >> 31;
     119                 :     else
     120               0 :         return 33 - SkCLZ(hi);
     121                 : }
     122                 : 
     123               0 : void Sk64::negate()
     124                 : {
     125               0 :     fHi = -fHi - Sk32ToBool(fLo);
     126               0 :     fLo = 0 - fLo;
     127               0 : }
     128                 : 
     129               0 : void Sk64::abs()
     130                 : {
     131               0 :     if (fHi < 0)
     132                 :     {
     133               0 :         fHi = -fHi - Sk32ToBool(fLo);
     134               0 :         fLo = 0 - fLo;
     135                 :     }
     136               0 : }
     137                 : 
     138                 : ////////////////////////////////////////////////////////////////
     139                 : 
     140                 : static inline int32_t round_right_16(int32_t hi, uint32_t lo)
     141                 : {
     142                 :     uint32_t sum = lo + (1 << 15);
     143                 :     hi += (sum < lo);
     144                 :     return (hi << 16) | (sum >> 16);
     145                 : }
     146                 : 
     147               0 : SkBool Sk64::isFixed() const
     148                 : {
     149               0 :     Sk64 tmp = *this;
     150               0 :     tmp.roundRight(16);
     151               0 :     return tmp.is32();
     152                 : }
     153                 : 
     154               0 : SkFract Sk64::getFract() const
     155                 : {
     156               0 :     Sk64 tmp = *this;
     157               0 :     tmp.roundRight(30);
     158               0 :     return tmp.get32();
     159                 : }
     160                 : 
     161               0 : void Sk64::sub(const Sk64& a)
     162                 : {
     163               0 :     fHi = fHi - a.fHi - (fLo < a.fLo);
     164               0 :     fLo = fLo - a.fLo;
     165               0 : }
     166                 : 
     167               0 : void Sk64::rsub(const Sk64& a)
     168                 : {
     169               0 :     fHi = a.fHi - fHi - (a.fLo < fLo);
     170               0 :     fLo = a.fLo - fLo;
     171               0 : }
     172                 : 
     173               0 : void Sk64::setMul(int32_t a, int32_t b)
     174                 : {
     175               0 :     int sa = a >> 31;
     176               0 :     int sb = b >> 31;
     177                 :     // now make them positive
     178               0 :     a = (a ^ sa) - sa;
     179               0 :     b = (b ^ sb) - sb;
     180                 : 
     181               0 :     uint32_t    ah = a >> 16;
     182               0 :     uint32_t    al = a & 0xFFFF;
     183               0 :     uint32_t bh = b >> 16;
     184               0 :     uint32_t bl = b & 0xFFFF;
     185                 : 
     186               0 :     uint32_t A = ah * bh;
     187               0 :     uint32_t B = ah * bl + al * bh;
     188               0 :     uint32_t C = al * bl;
     189                 : 
     190                 :     /*  [  A  ]
     191                 :            [  B  ]
     192                 :               [  C  ]
     193                 :     */
     194               0 :     fLo = C + (B << 16);
     195               0 :     fHi = A + (B >>16) + (fLo < C);
     196                 : 
     197               0 :     if (sa != sb)
     198               0 :         this->negate();
     199               0 : }
     200                 : 
     201               0 : void Sk64::div(int32_t denom, DivOptions option)
     202                 : {
     203               0 :     SkASSERT(denom);
     204                 : 
     205               0 :     int32_t     hi = fHi;
     206               0 :     uint32_t    lo = fLo;
     207               0 :     int         sign = denom ^ hi;
     208                 : 
     209               0 :     denom = SkAbs32(denom);
     210               0 :     if (hi < 0)
     211                 :     {
     212               0 :         hi = -hi - Sk32ToBool(lo);
     213               0 :         lo = 0 - lo;
     214                 :     }
     215                 : 
     216               0 :     if (option == kRound_DivOption) // add denom/2
     217                 :     {
     218               0 :         uint32_t newLo = lo + (denom >> 1);
     219               0 :         hi += (newLo < lo);
     220               0 :         lo = newLo;
     221                 :     }
     222                 : 
     223               0 :     if (hi == 0)    // fast-case
     224                 :     {
     225               0 :         if (lo < (uint32_t)denom)
     226               0 :             this->set(0, 0);
     227                 :         else
     228                 :         {
     229               0 :             this->set(0, lo / denom);
     230               0 :             if (sign < 0)
     231               0 :                 this->negate();
     232                 :         }
     233               0 :         return;
     234                 :     }
     235                 : 
     236                 :     int bits;
     237                 : 
     238                 :     {
     239               0 :         int dbits = SkCLZ(denom);
     240               0 :         int nbits = SkCLZ(hi);
     241                 : 
     242               0 :         bits = 32 + dbits - nbits;
     243               0 :         SkASSERT(bits <= 63);
     244               0 :         if (bits <= 0)
     245                 :         {
     246               0 :             this->set(0, 0);
     247               0 :             return;
     248                 :         }
     249               0 :         denom <<= (dbits - 1);
     250               0 :         shift_left_bits(hi, lo, nbits - 1);
     251                 :     }
     252                 : 
     253               0 :     int32_t     rhi = 0;
     254               0 :     uint32_t    rlo = 0;
     255                 : 
     256               0 :     do {
     257               0 :         shift_left(rhi, rlo);
     258                 : #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
     259                 :         if ((uint32_t)denom <= (uint32_t)hi)
     260                 :         {
     261                 :             hi -= denom;
     262                 :             rlo |= 1;
     263                 :         }
     264                 : #else
     265               0 :         int32_t diff = (denom - hi - 1) >> 31;
     266               0 :         hi -= denom & diff;
     267               0 :         rlo -= diff;
     268                 : #endif
     269               0 :         shift_left(hi, lo);
     270                 :     } while (--bits >= 0);
     271               0 :     SkASSERT(rhi >= 0);
     272                 : 
     273               0 :     fHi = rhi;
     274               0 :     fLo = rlo;
     275               0 :     if (sign < 0)
     276               0 :         this->negate();
     277                 : }
     278                 : 
     279                 : #define shift_left_2(a, b, c)   \
     280                 :     a = (a << 2) | (b >> 30);   \
     281                 :     b = (b << 2) | (c >> 30);   \
     282                 :     c <<= 2
     283                 : 
     284               0 : int32_t Sk64::getSqrt() const
     285                 : {
     286               0 :     SkASSERT(!this->isNeg());
     287                 : 
     288               0 :     uint32_t    hi = fHi;
     289               0 :     uint32_t lo = fLo;
     290               0 :     uint32_t    sqr = 0;
     291               0 :     uint32_t root = 0;
     292               0 :     int count = 31;
     293                 : 
     294               0 :     do {
     295               0 :         root <<= 1;
     296               0 :         shift_left_2(sqr, hi, lo);
     297                 : 
     298               0 :         uint32_t testDiv = (root << 1) + 1;
     299               0 :         if (sqr >= testDiv)
     300                 :         {
     301               0 :             sqr -= testDiv;
     302               0 :             root++;
     303                 :         }
     304                 :     } while (--count >= 0);
     305               0 :     SkASSERT((int32_t)root >= 0);
     306                 : 
     307               0 :     return root;
     308                 : }
     309                 : 
     310                 : #ifdef SkLONGLONG
     311                 :     SkLONGLONG Sk64::getLongLong() const
     312                 :     {
     313                 :         SkLONGLONG value = fHi;
     314                 :         value <<= 32;
     315                 :         return value | fLo;
     316                 :     }
     317                 : #endif
     318                 : 
     319               0 : SkFixed Sk64::getFixedDiv(const Sk64& denom) const
     320                 : {
     321               0 :     Sk64    N = *this;
     322               0 :     Sk64    D = denom;
     323               0 :     int32_t sign = SkExtractSign(N.fHi ^ D.fHi);
     324                 :     SkFixed result;
     325                 : 
     326               0 :     N.abs();
     327               0 :     D.abs();
     328                 : 
     329                 :     // need to knock D down to just 31 bits
     330                 :     // either by rounding it to the right, or shifting N to the left
     331                 :     // then we can just call 64/32 div
     332                 : 
     333               0 :     int nclz = N.fHi ? SkCLZ(N.fHi) : 32;
     334               0 :     int dclz = D.fHi ? SkCLZ(D.fHi) : (33 - (D.fLo >> 31));
     335                 : 
     336               0 :     int shiftN = nclz - 1;
     337               0 :     SkASSERT(shiftN >= 0);
     338               0 :     int shiftD = 33 - dclz;
     339               0 :     SkASSERT(shiftD >= 0);
     340                 : 
     341               0 :     if (shiftD + shiftN < 16)
     342               0 :         shiftD = 16 - shiftN;
     343                 :     else
     344               0 :         shiftN = 16 - shiftD;
     345                 : 
     346               0 :     D.roundRight(shiftD);
     347               0 :     if (D.isZero())
     348               0 :         result = SK_MaxS32;
     349                 :     else
     350                 :     {
     351               0 :         if (shiftN >= 0)
     352               0 :             N.shiftLeft(shiftN);
     353                 :         else
     354               0 :             N.roundRight(-shiftN);
     355               0 :         N.div(D.get32(), Sk64::kTrunc_DivOption);
     356               0 :         if (N.is32())
     357               0 :             result = N.get32();
     358                 :         else
     359               0 :             result = SK_MaxS32;
     360                 :     }
     361               0 :     return SkApplySign(result, sign);
     362                 : }
     363                 : 

Generated by: LCOV version 1.7