diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-11-30 19:13:17 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-11-30 19:30:24 -0800 |
commit | be03022b89d4f4cd59a2122b7286412721bf48c4 (patch) | |
tree | 5d47ae703ed7768bef1f6affeb05598aeb9ae18e /lib/Target/CppBackend/CPPBackend.cpp | |
parent | 66e6efea2604be022382921783e32329b6412df8 (diff) |
convert float and double constants even more carefully
Diffstat (limited to 'lib/Target/CppBackend/CPPBackend.cpp')
-rw-r--r-- | lib/Target/CppBackend/CPPBackend.cpp | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index ccde537055..ad03cd0adf 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -1448,17 +1448,44 @@ static inline std::string ftostr_precise(double V) { return B; } +static int hexToInt(char x) { + if (x <= '9') { + assert(x >= '0'); + return x - '0'; + } else { + assert('A' <= x && x <= 'F'); + return x - 'A' + 10; + } +} + +static inline std::string ftostr_exact(const ConstantFP *CFP) { + std::string temp; + raw_string_ostream stream(temp); + stream << *CFP; // bitcast on APF produces odd results, so do it this horrible way + const char *raw = temp.c_str(); + if (CFP->getType()->isFloatTy()) { + raw += 6; // skip "float " + } else { + raw += 7; // skip "double " + } + if (raw[1] != 'x') return raw; // number has already been printed out + raw += 2; // skip "0x" + union dbl { double d; float f[2]; int i[2]; unsigned char b[sizeof(double)]; } dbl; + for (unsigned i = 0; i < 8; i++) { + dbl.b[7-i] = (hexToInt(raw[2*i]) << 4) | + hexToInt(raw[2*i+1]); + } + char buffer[100]; + sprintf(buffer, "%30.30f", dbl.d); + return buffer; +} + std::string CppWriter::getConstant(const Constant* CV, Signedness sign) { if (isa<PointerType>(CV->getType())) { return getPtrAsStr(CV); } else { if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { - std::string S; - if (CFP->getType()->isFloatTy()) { - S = ftostr_precise(CFP->getValueAPF().convertToFloat()); - } else { - S = ftostr_precise(CFP->getValueAPF().convertToDouble()); - } + std::string S = ftostr_exact(CFP); S = '+' + S; //if (S.find('.') == S.npos) { TODO: do this when necessary, but it is necessary even for 0.0001 return S; |