Chromium Code Reviews| Index: src/IceTargetLoweringX8632.cpp |
| diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp |
| index 32246c4bef031382ea1e53fe8224c2cfab032ef3..9c01363704a52bab6660d30d6b587280e5db8637 100644 |
| --- a/src/IceTargetLoweringX8632.cpp |
| +++ b/src/IceTargetLoweringX8632.cpp |
| @@ -562,6 +562,70 @@ 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(); |
| + SizeT Align; |
| + Type Ty; |
| + ConstantList Pool; |
| + |
| + Ty = T::Ty; |
| + Pool = Ctx->getConstantPool(Ty); |
| + Align = typeAlignInBytes(Ty); |
|
JF
2014/05/23 16:35:03
Do these in the initialization above.
Jim Stichnoth
2014/05/23 20:37:35
Done.
|
| + 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]; |
| + snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); |
|
JF
2014/05/23 16:35:03
Check that the return is in [0, size-1].
Jim Stichnoth
2014/05/23 20:37:35
Done.
|
| + 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 +1942,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 |