| Index: src/IceTargetLoweringX8632.cpp
|
| diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
|
| index 32246c4bef031382ea1e53fe8224c2cfab032ef3..8ee5ac9282b6d2348db77cd0b0cf1260b2656280 100644
|
| --- a/src/IceTargetLoweringX8632.cpp
|
| +++ b/src/IceTargetLoweringX8632.cpp
|
| @@ -562,6 +562,71 @@ void TargetX8632::addEpilog(CfgNode *Node) {
|
| }
|
| }
|
|
|
| +template <typename T> struct PoolTypeConverter {};
|
| +
|
| +template <> struct PoolTypeConverter<float> {
|
| + typedef float PrimitiveFpType;
|
| + typedef uint32_t PrimitiveIntType;
|
| + typedef ConstantFloat IceType;
|
| + static const Type Ty = IceType_f32;
|
| + static const char *TypeName;
|
| + static const char *AsmTag;
|
| + static const char *PrintfString;
|
| +};
|
| +const char *PoolTypeConverter<float>::TypeName = "float";
|
| +const char *PoolTypeConverter<float>::AsmTag = ".long";
|
| +const char *PoolTypeConverter<float>::PrintfString = "0x%x";
|
| +
|
| +template <> struct PoolTypeConverter<double> {
|
| + typedef double PrimitiveFpType;
|
| + typedef uint64_t PrimitiveIntType;
|
| + typedef ConstantDouble IceType;
|
| + static const Type Ty = IceType_f64;
|
| + static const char *TypeName;
|
| + static const char *AsmTag;
|
| + static const char *PrintfString;
|
| +};
|
| +const char *PoolTypeConverter<double>::TypeName = "double";
|
| +const char *PoolTypeConverter<double>::AsmTag = ".quad";
|
| +const char *PoolTypeConverter<double>::PrintfString = "0x%llx";
|
| +
|
| +template <typename T> void TargetX8632::emitConstantPool() const {
|
| + Ostream &Str = Ctx->getStrEmit();
|
| + Type Ty = T::Ty;
|
| + SizeT Align = typeAlignInBytes(Ty);
|
| + ConstantList Pool = Ctx->getConstantPool(Ty);
|
| +
|
| + Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
|
| + << "\n";
|
| + Str << "\t.align\t" << Align << "\n";
|
| + for (ConstantList::const_iterator I = Pool.begin(), E = Pool.end(); I != E;
|
| + ++I) {
|
| + typename T::IceType *Const = llvm::cast<typename T::IceType>(*I);
|
| + typename T::PrimitiveFpType Value = Const->getValue();
|
| + // Use memcpy() to copy bits from Value into RawValue in a way
|
| + // that avoids breaking strict-aliasing rules.
|
| + typename T::PrimitiveIntType RawValue;
|
| + memcpy(&RawValue, &Value, sizeof(Value));
|
| + char buf[30];
|
| + int CharsPrinted =
|
| + snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
|
| + assert(CharsPrinted >= 0 &&
|
| + (size_t)CharsPrinted < llvm::array_lengthof(buf));
|
| + (void)CharsPrinted; // avoid warnings if asserts are disabled
|
| + Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n";
|
| + Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
|
| + << Value << "\n";
|
| + }
|
| +}
|
| +
|
| +void TargetX8632::emitConstants() const {
|
| + emitConstantPool<PoolTypeConverter<float> >();
|
| + emitConstantPool<PoolTypeConverter<double> >();
|
| +
|
| + // No need to emit constants from the int pool since (for x86) they
|
| + // are embedded as immediates in the instructions.
|
| +}
|
| +
|
| void TargetX8632::split64(Variable *Var) {
|
| switch (Var->getType()) {
|
| default:
|
| @@ -1878,4 +1943,16 @@ void TargetX8632::postLower() {
|
| }
|
| }
|
|
|
| +template <> void ConstantFloat::emit(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + // It would be better to prefix with ".L$" instead of "L$", but
|
| + // llvm-mc doesn't parse "dword ptr [.L$foo]".
|
| + Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]";
|
| +}
|
| +
|
| +template <> void ConstantDouble::emit(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]";
|
| +}
|
| +
|
| } // end of namespace Ice
|
|
|