Subversion Repositories HelenOS

Rev

Rev 2071 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2005 Josef Cejka
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup softfloat  
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include<sftypes.h>
  36. #include<common.h>
  37.  
  38. /* Table for fast leading zeroes counting */
  39. char zeroTable[256] = {
  40.     8, 7, 7, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, \
  41.     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
  42.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
  43.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
  44.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  45.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  46.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  47.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  48.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  49.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  50.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  51.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  52.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  53.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  54.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  55.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  56. };
  57.  
  58.  
  59.  
  60. /** Take fraction shifted by 10 bits to left, round it, normalize it and detect exceptions
  61.  * @param cexp exponent with bias
  62.  * @param cfrac fraction shifted 10 places left with added hidden bit
  63.  * @param sign
  64.  * @return valied float64
  65.  */
  66. float64 finishFloat64(int32_t cexp, uint64_t cfrac, char sign)
  67. {
  68.     float64 result;
  69.  
  70.     result.parts.sign = sign;
  71.  
  72.     /* find first nonzero digit and shift result and detect possibly underflow */
  73.     while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1 ) )))) {
  74.         cexp--;
  75.         cfrac <<= 1;
  76.             /* TODO: fix underflow */
  77.     };
  78.    
  79.     if ((cexp < 0) || ( cexp == 0 && (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))))) {
  80.         /* FIXME: underflow */
  81.         result.parts.exp = 0;
  82.         if ((cexp + FLOAT64_FRACTION_SIZE + 1) < 0) { /* +1 is place for rounding */
  83.             result.parts.fraction = 0;
  84.             return result;
  85.         }
  86.        
  87.         while (cexp < 0) {
  88.             cexp++;
  89.             cfrac >>= 1;
  90.         }
  91.    
  92.         cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
  93.        
  94.         if (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))) {
  95.            
  96.             result.parts.fraction = ((cfrac >>(64 - FLOAT64_FRACTION_SIZE - 2) ) & (~FLOAT64_HIDDEN_BIT_MASK));
  97.             return result;
  98.         }  
  99.     } else {
  100.         cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
  101.     }
  102.    
  103.     ++cexp;
  104.  
  105.     if (cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1 ))) {
  106.         ++cexp;
  107.         cfrac >>= 1;
  108.     }  
  109.  
  110.     /* check overflow */
  111.     if (cexp >= FLOAT64_MAX_EXPONENT ) {
  112.         /* FIXME: overflow, return infinity */
  113.         result.parts.exp = FLOAT64_MAX_EXPONENT;
  114.         result.parts.fraction = 0;
  115.         return result;
  116.     }
  117.  
  118.     result.parts.exp = (uint32_t)cexp;
  119.    
  120.     result.parts.fraction = ((cfrac >>(64 - FLOAT64_FRACTION_SIZE - 2 ) ) & (~FLOAT64_HIDDEN_BIT_MASK));
  121.    
  122.     return result; 
  123. }
  124.  
  125. /** Counts leading zeroes in 64bit unsigned integer
  126.  * @param i
  127.  */
  128. int countZeroes64(uint64_t i)
  129. {
  130.     int j;
  131.     for (j =0; j < 64; j += 8) {
  132.         if ( i & (0xFFll << (56 - j))) {
  133.             return (j + countZeroes8(i >> (56 - j)));
  134.         }
  135.     }
  136.  
  137.     return 64;
  138. }
  139.  
  140. /** Counts leading zeroes in 32bit unsigned integer
  141.  * @param i
  142.  */
  143. int countZeroes32(uint32_t i)
  144. {
  145.     int j;
  146.     for (j =0; j < 32; j += 8) {
  147.         if ( i & (0xFF << (24 - j))) {
  148.             return (j + countZeroes8(i >> (24 - j)));
  149.         }
  150.     }
  151.  
  152.     return 32;
  153. }
  154.  
  155. /** Counts leading zeroes in byte
  156.  * @param i
  157.  */
  158. int countZeroes8(uint8_t i)
  159. {
  160.     return zeroTable[i];
  161. }
  162.  
  163. /** Round and normalize number expressed by exponent and fraction with first bit (equal to hidden bit) at 30. bit
  164.  * @param exp exponent
  165.  * @param fraction part with hidden bit shifted to 30. bit
  166.  */
  167. void roundFloat32(int32_t *exp, uint32_t *fraction)
  168. {
  169.     /* rounding - if first bit after fraction is set then round up */
  170.     (*fraction) += (0x1 << 6);
  171.    
  172.     if ((*fraction) & (FLOAT32_HIDDEN_BIT_MASK << 8)) {
  173.         /* rounding overflow */
  174.         ++(*exp);
  175.         (*fraction) >>= 1;
  176.     };
  177.    
  178.     if (((*exp) >= FLOAT32_MAX_EXPONENT ) || ((*exp) < 0)) {
  179.         /* overflow - set infinity as result */
  180.         (*exp) = FLOAT32_MAX_EXPONENT;
  181.         (*fraction) = 0;
  182.         return;
  183.     }
  184.  
  185.     return;
  186. }
  187.  
  188. /** Round and normalize number expressed by exponent and fraction with first bit (equal to hidden bit) at 62. bit
  189.  * @param exp exponent
  190.  * @param fraction part with hidden bit shifted to 62. bit
  191.  */
  192. void roundFloat64(int32_t *exp, uint64_t *fraction)
  193. {
  194.     /* rounding - if first bit after fraction is set then round up */
  195.     (*fraction) += (0x1 << 9);
  196.    
  197.     if ((*fraction) & (FLOAT64_HIDDEN_BIT_MASK << 11)) {
  198.         /* rounding overflow */
  199.         ++(*exp);
  200.         (*fraction) >>= 1;
  201.     };
  202.    
  203.     if (((*exp) >= FLOAT64_MAX_EXPONENT ) || ((*exp) < 0)) {
  204.         /* overflow - set infinity as result */
  205.         (*exp) = FLOAT64_MAX_EXPONENT;
  206.         (*fraction) = 0;
  207.         return;
  208.     }
  209.  
  210.     return;
  211. }
  212.  
  213. /** @}
  214.  */
  215.  
  216.