diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:19:52 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:19:52 +0000 | 
| commit | 4a142eb28942073eb27a112b5ca1cca3f01beb9c (patch) | |
| tree | 22cc59e4b240d84c3a5a60531119c4eca914a256 /lib/Support/APFloat.cpp | |
| parent | 5cd822fa9bbb9622241e3bf4d7674ed49ccde5b9 (diff) | |
Notes
Diffstat (limited to 'lib/Support/APFloat.cpp')
| -rw-r--r-- | lib/Support/APFloat.cpp | 70 | 
1 files changed, 69 insertions, 1 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index e431d27902397..7e42e2dac10a7 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -48,6 +48,7 @@ namespace llvm {      unsigned int arithmeticOK;    }; +  const fltSemantics APFloat::IEEEhalf = { 15, -14, 11, true };    const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, true };    const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true };    const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true }; @@ -2812,6 +2813,35 @@ APFloat::convertFloatAPFloatToAPInt() const                      (mysignificand & 0x7fffff)));  } +APInt +APFloat::convertHalfAPFloatToAPInt() const +{ +  assert(semantics == (const llvm::fltSemantics*)&IEEEhalf); +  assert (partCount()==1); + +  uint32_t myexponent, mysignificand; + +  if (category==fcNormal) { +    myexponent = exponent+15; //bias +    mysignificand = (uint32_t)*significandParts(); +    if (myexponent == 1 && !(mysignificand & 0x400)) +      myexponent = 0;   // denormal +  } else if (category==fcZero) { +    myexponent = 0; +    mysignificand = 0; +  } else if (category==fcInfinity) { +    myexponent = 0x1f; +    mysignificand = 0; +  } else { +    assert(category == fcNaN && "Unknown category!"); +    myexponent = 0x1f; +    mysignificand = (uint32_t)*significandParts(); +  } + +  return APInt(16, (((sign&1) << 15) | ((myexponent&0x1f) << 10) | +                    (mysignificand & 0x3ff))); +} +  // This function creates an APInt that is just a bit map of the floating  // point constant as it would appear in memory.  It is not a conversion,  // and treating the result as a normal integer is unlikely to be useful. @@ -2819,6 +2849,9 @@ APFloat::convertFloatAPFloatToAPInt() const  APInt  APFloat::bitcastToAPInt() const  { +  if (semantics == (const llvm::fltSemantics*)&IEEEhalf) +    return convertHalfAPFloatToAPInt(); +    if (semantics == (const llvm::fltSemantics*)&IEEEsingle)      return convertFloatAPFloatToAPInt(); @@ -3051,6 +3084,39 @@ APFloat::initFromFloatAPInt(const APInt & api)    }  } +void +APFloat::initFromHalfAPInt(const APInt & api) +{ +  assert(api.getBitWidth()==16); +  uint32_t i = (uint32_t)*api.getRawData(); +  uint32_t myexponent = (i >> 10) & 0x1f; +  uint32_t mysignificand = i & 0x3ff; + +  initialize(&APFloat::IEEEhalf); +  assert(partCount()==1); + +  sign = i >> 15; +  if (myexponent==0 && mysignificand==0) { +    // exponent, significand meaningless +    category = fcZero; +  } else if (myexponent==0x1f && mysignificand==0) { +    // exponent, significand meaningless +    category = fcInfinity; +  } else if (myexponent==0x1f && mysignificand!=0) { +    // sign, exponent, significand meaningless +    category = fcNaN; +    *significandParts() = mysignificand; +  } else { +    category = fcNormal; +    exponent = myexponent - 15;  //bias +    *significandParts() = mysignificand; +    if (myexponent==0)    // denormal +      exponent = -14; +    else +      *significandParts() |= 0x400; // integer bit +  } +} +  /// Treat api as containing the bits of a floating point number.  Currently  /// we infer the floating point type from the size of the APInt.  The  /// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful @@ -3058,7 +3124,9 @@ APFloat::initFromFloatAPInt(const APInt & api)  void  APFloat::initFromAPInt(const APInt& api, bool isIEEE)  { -  if (api.getBitWidth() == 32) +  if (api.getBitWidth() == 16) +    return initFromHalfAPInt(api); +  else if (api.getBitWidth() == 32)      return initFromFloatAPInt(api);    else if (api.getBitWidth()==64)      return initFromDoubleAPInt(api);  | 
