Support C99 hexadecimal floating-point literals in assembly
[oota-llvm.git] / lib / MC / MCInstPrinter.cpp
index 7efb3f0ef31348261a0f5631d8c30a46da191b0d..6a452c8d4a7f50fd5ae42f31ea3f8cc4c4733b33 100644 (file)
@@ -52,10 +52,55 @@ StringRef MCInstPrinter::markup(StringRef a, StringRef b) const {
     return b;
 }
 
-/// Utility function to print immediates in decimal or hex.
-format_object1<int64_t> MCInstPrinter::formatImm(const int64_t Value) const {
-  if (getPrintImmHex())
-    return format("0x%llx", Value);
-  else
-    return format("%lld", Value);
+// For asm-style hex (e.g. 0ffh) the first digit always has to be a number.
+static bool needsLeadingZero(uint64_t Value)
+{
+  while(Value)
+  {
+    uint64_t digit = (Value >> 60) & 0xf;
+    if (digit != 0)
+      return (digit >= 0xa);
+    Value <<= 4;
+  }
+  return false;
+}
+
+format_object1<int64_t> MCInstPrinter::formatDec(const int64_t Value) const {
+  return format("%" PRId64, Value);
+}
+
+format_object1<int64_t> MCInstPrinter::formatHex(const int64_t Value) const {
+  switch(PrintHexStyle) {
+  case HexStyle::C:
+    if (Value < 0)
+      return format("-0x%" PRIx64, -Value);
+    else
+      return format("0x%" PRIx64, Value);
+  case HexStyle::Asm:
+    if (Value < 0) {
+      if (needsLeadingZero((uint64_t)(-Value)))
+        return format("-0%" PRIx64 "h", -Value);
+      else
+        return format("-%" PRIx64 "h", -Value);
+    } else {
+      if (needsLeadingZero((uint64_t)(Value)))
+        return format("0%" PRIx64 "h", Value);
+      else
+        return format("%" PRIx64 "h", Value);
+    }
+  }
+  llvm_unreachable("unsupported print style");
+}
+
+format_object1<uint64_t> MCInstPrinter::formatHex(const uint64_t Value) const {
+  switch(PrintHexStyle) {
+  case HexStyle::C:
+     return format("0x%" PRIx64, Value);
+  case HexStyle::Asm:
+    if (needsLeadingZero(Value))
+      return format("0%" PRIx64 "h", Value);
+    else
+      return format("%" PRIx64 "h", Value);
+  }
+  llvm_unreachable("unsupported print style");
 }