Home | History | Annotate | Download | only in src
      1 // Copyright 2013, ARM Limited
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #include "utils-vixl.h"
     28 #include <stdio.h>
     29 
     30 namespace vixl {
     31 
     32 uint32_t float_to_rawbits(float value) {
     33   uint32_t bits = 0;
     34   memcpy(&bits, &value, 4);
     35   return bits;
     36 }
     37 
     38 
     39 uint64_t double_to_rawbits(double value) {
     40   uint64_t bits = 0;
     41   memcpy(&bits, &value, 8);
     42   return bits;
     43 }
     44 
     45 
     46 float rawbits_to_float(uint32_t bits) {
     47   float value = 0.0;
     48   memcpy(&value, &bits, 4);
     49   return value;
     50 }
     51 
     52 
     53 double rawbits_to_double(uint64_t bits) {
     54   double value = 0.0;
     55   memcpy(&value, &bits, 8);
     56   return value;
     57 }
     58 
     59 
     60 int CountLeadingZeros(uint64_t value, int width) {
     61   VIXL_ASSERT((width == 32) || (width == 64));
     62   int count = 0;
     63   uint64_t bit_test = UINT64_C(1) << (width - 1);
     64   while ((count < width) && ((bit_test & value) == 0)) {
     65     count++;
     66     bit_test >>= 1;
     67   }
     68   return count;
     69 }
     70 
     71 
     72 int CountLeadingSignBits(int64_t value, int width) {
     73   VIXL_ASSERT((width == 32) || (width == 64));
     74   if (value >= 0) {
     75     return CountLeadingZeros(value, width) - 1;
     76   } else {
     77     return CountLeadingZeros(~value, width) - 1;
     78   }
     79 }
     80 
     81 
     82 int CountTrailingZeros(uint64_t value, int width) {
     83   VIXL_ASSERT((width == 32) || (width == 64));
     84   int count = 0;
     85   while ((count < width) && (((value >> count) & 1) == 0)) {
     86     count++;
     87   }
     88   return count;
     89 }
     90 
     91 
     92 int CountSetBits(uint64_t value, int width) {
     93   // TODO: Other widths could be added here, as the implementation already
     94   // supports them.
     95   VIXL_ASSERT((width == 32) || (width == 64));
     96 
     97   // Mask out unused bits to ensure that they are not counted.
     98   value &= (UINT64_C(0xffffffffffffffff) >> (64-width));
     99 
    100   // Add up the set bits.
    101   // The algorithm works by adding pairs of bit fields together iteratively,
    102   // where the size of each bit field doubles each time.
    103   // An example for an 8-bit value:
    104   // Bits:  h  g  f  e  d  c  b  a
    105   //         \ |   \ |   \ |   \ |
    106   // value = h+g   f+e   d+c   b+a
    107   //            \    |      \    |
    108   // value =   h+g+f+e     d+c+b+a
    109   //                  \          |
    110   // value =       h+g+f+e+d+c+b+a
    111   const uint64_t kMasks[] = {
    112     UINT64_C(0x5555555555555555),
    113     UINT64_C(0x3333333333333333),
    114     UINT64_C(0x0f0f0f0f0f0f0f0f),
    115     UINT64_C(0x00ff00ff00ff00ff),
    116     UINT64_C(0x0000ffff0000ffff),
    117     UINT64_C(0x00000000ffffffff),
    118   };
    119 
    120   for (unsigned i = 0; i < (sizeof(kMasks) / sizeof(kMasks[0])); i++) {
    121     int shift = 1 << i;
    122     value = ((value >> shift) & kMasks[i]) + (value & kMasks[i]);
    123   }
    124 
    125   return value;
    126 }
    127 }  // namespace vixl
    128