Home | History | Annotate | Download | only in vixl
      1 // Copyright 2015, 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 "vixl/utils.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 uint32_t float_sign(float val) {
     61   uint32_t rawbits = float_to_rawbits(val);
     62   return unsigned_bitextract_32(31, 31, rawbits);
     63 }
     64 
     65 
     66 uint32_t float_exp(float val) {
     67   uint32_t rawbits = float_to_rawbits(val);
     68   return unsigned_bitextract_32(30, 23, rawbits);
     69 }
     70 
     71 
     72 uint32_t float_mantissa(float val) {
     73   uint32_t rawbits = float_to_rawbits(val);
     74   return unsigned_bitextract_32(22, 0, rawbits);
     75 }
     76 
     77 
     78 uint32_t double_sign(double val) {
     79   uint64_t rawbits = double_to_rawbits(val);
     80   return static_cast<uint32_t>(unsigned_bitextract_64(63, 63, rawbits));
     81 }
     82 
     83 
     84 uint32_t double_exp(double val) {
     85   uint64_t rawbits = double_to_rawbits(val);
     86   return static_cast<uint32_t>(unsigned_bitextract_64(62, 52, rawbits));
     87 }
     88 
     89 
     90 uint64_t double_mantissa(double val) {
     91   uint64_t rawbits = double_to_rawbits(val);
     92   return unsigned_bitextract_64(51, 0, rawbits);
     93 }
     94 
     95 
     96 float float_pack(uint32_t sign, uint32_t exp, uint32_t mantissa) {
     97   uint64_t bits = (sign << 31) | (exp << 23) | mantissa;
     98   return rawbits_to_float(bits);
     99 }
    100 
    101 
    102 double double_pack(uint64_t sign, uint64_t exp, uint64_t mantissa) {
    103   uint64_t bits = (sign << 63) | (exp << 52) | mantissa;
    104   return rawbits_to_double(bits);
    105 }
    106 
    107 
    108 int float16classify(float16 value) {
    109   uint16_t exponent_max = (1 << 5) - 1;
    110   uint16_t exponent_mask = exponent_max << 10;
    111   uint16_t mantissa_mask = (1 << 10) - 1;
    112 
    113   uint16_t exponent = (value & exponent_mask) >> 10;
    114   uint16_t mantissa = value & mantissa_mask;
    115   if (exponent == 0) {
    116     if (mantissa == 0) {
    117       return FP_ZERO;
    118     }
    119     return FP_SUBNORMAL;
    120   } else if (exponent == exponent_max) {
    121     if (mantissa == 0) {
    122       return FP_INFINITE;
    123     }
    124     return FP_NAN;
    125   }
    126   return FP_NORMAL;
    127 }
    128 
    129 
    130 unsigned CountClearHalfWords(uint64_t imm, unsigned reg_size) {
    131   VIXL_ASSERT((reg_size % 8) == 0);
    132   int count = 0;
    133   for (unsigned i = 0; i < (reg_size / 16); i++) {
    134     if ((imm & 0xffff) == 0) {
    135       count++;
    136     }
    137     imm >>= 16;
    138   }
    139   return count;
    140 }
    141 
    142 }  // namespace vixl
    143