From: Dan Gohman Date: Mon, 8 Sep 2008 16:40:13 +0000 (+0000) Subject: Add AsmPrinter support for i128 and larger static initializer data. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=82f94f1ad98fdcc90e44053437fa555d339a4449;p=oota-llvm.git Add AsmPrinter support for i128 and larger static initializer data. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55919 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 03a61d42cd1..6d3d133930e 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -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(CV->getType())->getBitWidth() >= 64) { if (const ConstantInt *CI = dyn_cast(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 index 00000000000..9f8ceddea6c --- /dev/null +++ b/test/CodeGen/Generic/i128-and-beyond.ll @@ -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