Add AsmPrinter support for i128 and larger static initializer data.
authorDan Gohman <gohman@apple.com>
Mon, 8 Sep 2008 16:40:13 +0000 (16:40 +0000)
committerDan Gohman <gohman@apple.com>
Mon, 8 Sep 2008 16:40:13 +0000 (16:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55919 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/AsmPrinter.cpp
test/CodeGen/Generic/i128-and-beyond.ll [new file with mode: 0644]

index 03a61d42cd16d52d10ecbc8367f156b3b2b2481d..6d3d133930ebea90ec582798952c1e2c5ad10d3d 100644 (file)
@@ -1062,26 +1062,41 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
       }
       return;
     } else assert(0 && "Floating point constant type not handled");
-  } else if (CV->getType() == Type::Int64Ty) {
+  } else if (CV->getType()->isInteger() &&
+             cast<IntegerType>(CV->getType())->getBitWidth() >= 64) {
     if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
-      uint64_t Val = CI->getZExtValue();
-
-      if (TAI->getData64bitsDirective())
-        O << TAI->getData64bitsDirective() << Val << '\n';
-      else if (TD->isBigEndian()) {
-        O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
-          << '\t' << TAI->getCommentString()
-          << " Double-word most significant word " << Val << '\n';
-        O << TAI->getData32bitsDirective() << unsigned(Val)
-          << '\t' << TAI->getCommentString()
-          << " Double-word least significant word " << Val << '\n';
-      } else {
-        O << TAI->getData32bitsDirective() << unsigned(Val)
-          << '\t' << TAI->getCommentString()
-          << " Double-word least significant word " << Val << '\n';
-        O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
-          << '\t' << TAI->getCommentString()
-          << " Double-word most significant word " << Val << '\n';
+      unsigned BitWidth = CI->getBitWidth();
+      assert(isPowerOf2_32(BitWidth) &&
+             "Non-power-of-2-sized integers not handled!");
+
+      // We don't expect assemblers to support integer data directives
+      // for more than 64 bits, so we emit the data in at most 64-bit
+      // quantities at a time.
+      const uint64_t *RawData = CI->getValue().getRawData();
+      for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {
+        uint64_t Val;
+        if (TD->isBigEndian())
+          Val = RawData[e - i - 1];
+        else
+          Val = RawData[i];
+
+        if (TAI->getData64bitsDirective())
+          O << TAI->getData64bitsDirective() << Val << '\n';
+        else if (TD->isBigEndian()) {
+          O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+            << '\t' << TAI->getCommentString()
+            << " Double-word most significant word " << Val << '\n';
+          O << TAI->getData32bitsDirective() << unsigned(Val)
+            << '\t' << TAI->getCommentString()
+            << " Double-word least significant word " << Val << '\n';
+        } else {
+          O << TAI->getData32bitsDirective() << unsigned(Val)
+            << '\t' << TAI->getCommentString()
+            << " Double-word least significant word " << Val << '\n';
+          O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+            << '\t' << TAI->getCommentString()
+            << " Double-word most significant word " << Val << '\n';
+        }
       }
       return;
     }
@@ -1440,6 +1455,8 @@ void AsmPrinter::printDataDirective(const Type *type) {
       assert(TAI->getData64bitsDirective() &&
              "Target cannot handle 64-bit constant exprs!");
       O << TAI->getData64bitsDirective();
+    } else {
+      assert(0 && "Target cannot handle given data directive width!");
     }
     break;
   }
diff --git a/test/CodeGen/Generic/i128-and-beyond.ll b/test/CodeGen/Generic/i128-and-beyond.ll
new file mode 100644 (file)
index 0000000..9f8cedd
--- /dev/null
@@ -0,0 +1,9 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep 18446744073709551615 | count 14
+; RUN: llvm-as < %s | llc -march=ppc32 | grep 4294967295 | count 28
+
+; These static initializers are too big to hand off to assemblers
+; as monolithic blobs.
+
+@x = global i128 -1
+@y = global i256 -1
+@z = global i512 -1