aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/CppBackend/CPPBackend.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-11-30 19:13:17 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-11-30 19:30:24 -0800
commitbe03022b89d4f4cd59a2122b7286412721bf48c4 (patch)
tree5d47ae703ed7768bef1f6affeb05598aeb9ae18e /lib/Target/CppBackend/CPPBackend.cpp
parent66e6efea2604be022382921783e32329b6412df8 (diff)
convert float and double constants even more carefully
Diffstat (limited to 'lib/Target/CppBackend/CPPBackend.cpp')
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp39
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;