diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-23 14:19:52 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-23 14:19:52 +0000 |
commit | 9643cca39fb9fb3b49a8912926de98acf882283c (patch) | |
tree | 22cc59e4b240d84c3a5a60531119c4eca914a256 /lib/Support | |
parent | 1adacceba9c9ee0f16e54388e56c9a249b296f75 (diff) | |
download | FreeBSD-src-9643cca39fb9fb3b49a8912926de98acf882283c.zip FreeBSD-src-9643cca39fb9fb3b49a8912926de98acf882283c.tar.gz |
Update LLVM to r84949.
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/APFloat.cpp | 70 | ||||
-rw-r--r-- | lib/Support/StringExtras.cpp | 56 | ||||
-rw-r--r-- | lib/Support/StringMap.cpp | 19 | ||||
-rw-r--r-- | lib/Support/Triple.cpp | 3 | ||||
-rw-r--r-- | lib/Support/raw_ostream.cpp | 34 |
5 files changed, 109 insertions, 73 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index e431d27..7e42e2d 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); diff --git a/lib/Support/StringExtras.cpp b/lib/Support/StringExtras.cpp index 1618086..c72f121 100644 --- a/lib/Support/StringExtras.cpp +++ b/lib/Support/StringExtras.cpp @@ -56,59 +56,3 @@ void llvm::SplitString(const std::string &Source, S2 = getToken(S, Delimiters); } } - - - -/// UnescapeString - Modify the argument string, turning two character sequences -/// @verbatim -/// like '\\' 'n' into '\n'. This handles: \e \a \b \f \n \r \t \v \' \ and -/// \num (where num is a 1-3 byte octal value). -/// @endverbatim -void llvm::UnescapeString(std::string &Str) { - for (unsigned i = 0; i != Str.size(); ++i) { - if (Str[i] == '\\' && i != Str.size()-1) { - switch (Str[i+1]) { - default: continue; // Don't execute the code after the switch. - case 'a': Str[i] = '\a'; break; - case 'b': Str[i] = '\b'; break; - case 'e': Str[i] = 27; break; - case 'f': Str[i] = '\f'; break; - case 'n': Str[i] = '\n'; break; - case 'r': Str[i] = '\r'; break; - case 't': Str[i] = '\t'; break; - case 'v': Str[i] = '\v'; break; - case '"': Str[i] = '\"'; break; - case '\'': Str[i] = '\''; break; - case '\\': Str[i] = '\\'; break; - } - // Nuke the second character. - Str.erase(Str.begin()+i+1); - } - } -} - -/// EscapeString - Modify the argument string, turning '\\' and anything that -/// doesn't satisfy std::isprint into an escape sequence. -void llvm::EscapeString(std::string &Str) { - for (unsigned i = 0; i != Str.size(); ++i) { - if (Str[i] == '\\') { - ++i; - Str.insert(Str.begin()+i, '\\'); - } else if (Str[i] == '\t') { - Str[i++] = '\\'; - Str.insert(Str.begin()+i, 't'); - } else if (Str[i] == '"') { - Str.insert(Str.begin()+i++, '\\'); - } else if (Str[i] == '\n') { - Str[i++] = '\\'; - Str.insert(Str.begin()+i, 'n'); - } else if (!std::isprint(Str[i])) { - // Always expand to a 3-digit octal escape. - unsigned Char = Str[i]; - Str[i++] = '\\'; - Str.insert(Str.begin()+i++, '0'+((Char/64) & 7)); - Str.insert(Str.begin()+i++, '0'+((Char/8) & 7)); - Str.insert(Str.begin()+i , '0'+( Char & 7)); - } - } -} diff --git a/lib/Support/StringMap.cpp b/lib/Support/StringMap.cpp index 040308b..a729d3d 100644 --- a/lib/Support/StringMap.cpp +++ b/lib/Support/StringMap.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringExtras.h" #include <cassert> using namespace llvm; @@ -46,20 +47,6 @@ void StringMapImpl::init(unsigned InitSize) { } -/// HashString - Compute a hash code for the specified string. -/// -static unsigned HashString(const char *Start, const char *End) { - // Bernstein hash function. - unsigned int Result = 0; - // TODO: investigate whether a modified bernstein hash function performs - // better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx - // X*33+c -> X*33^c - while (Start != End) - Result = Result * 33 + *Start++; - Result = Result + (Result >> 5); - return Result; -} - /// LookupBucketFor - Look up the bucket that the specified string should end /// up in. If it already exists as a key in the map, the Item pointer for the /// specified bucket will be non-null. Otherwise, it will be null. In either @@ -71,7 +58,7 @@ unsigned StringMapImpl::LookupBucketFor(const StringRef &Name) { init(16); HTSize = NumBuckets; } - unsigned FullHashValue = HashString(Name.begin(), Name.end()); + unsigned FullHashValue = HashString(Name); unsigned BucketNo = FullHashValue & (HTSize-1); unsigned ProbeAmt = 1; @@ -126,7 +113,7 @@ unsigned StringMapImpl::LookupBucketFor(const StringRef &Name) { int StringMapImpl::FindKey(const StringRef &Key) const { unsigned HTSize = NumBuckets; if (HTSize == 0) return -1; // Really empty table? - unsigned FullHashValue = HashString(Key.begin(), Key.end()); + unsigned FullHashValue = HashString(Key); unsigned BucketNo = FullHashValue & (HTSize-1); unsigned ProbeAmt = 1; diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 6f805da..26a1a4e 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -96,6 +96,7 @@ const char *Triple::getOSTypeName(OSType Kind) { case OpenBSD: return "openbsd"; case Solaris: return "solaris"; case Win32: return "win32"; + case Haiku: return "haiku"; } return "<invalid>"; @@ -276,6 +277,8 @@ void Triple::Parse() const { OS = Solaris; else if (OSName.startswith("win32")) OS = Win32; + else if (OSName.startswith("haiku")) + OS = Haiku; else OS = UnknownOS; diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index 0a82cc1..31451cc 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -168,6 +168,40 @@ raw_ostream &raw_ostream::write_hex(unsigned long long N) { return write(CurPtr, EndPtr-CurPtr); } +raw_ostream &raw_ostream::write_escaped(StringRef Str) { + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + unsigned char c = Str[i]; + + switch (c) { + case '\\': + *this << '\\' << '\\'; + break; + case '\t': + *this << '\\' << 't'; + break; + case '\n': + *this << '\\' << 'n'; + break; + case '"': + *this << '\\' << '"'; + break; + default: + if (std::isprint(c)) { + *this << c; + break; + } + + // Always expand to a 3-character octal escape. + *this << '\\'; + *this << char('0' + ((c >> 6) & 7)); + *this << char('0' + ((c >> 3) & 7)); + *this << char('0' + ((c >> 0) & 7)); + } + } + + return *this; +} + raw_ostream &raw_ostream::operator<<(const void *P) { *this << '0' << 'x'; |