Chromium Code Reviews| Index: src/IceTargetLoweringARM32.cpp |
| diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp |
| index 8a0ebec9a50fb3d5f2ef3ec17bd27a09fe9d0d8a..15e68d175203d516fead9f3493cf774ca3f3fd36 100644 |
| --- a/src/IceTargetLoweringARM32.cpp |
| +++ b/src/IceTargetLoweringARM32.cpp |
| @@ -29,6 +29,8 @@ |
| #include "IceUtils.h" |
| #include "llvm/Support/MathExtras.h" |
| +#include <algorithm> |
| + |
| namespace Ice { |
| namespace { |
| @@ -3148,16 +3150,125 @@ void TargetDataARM32::lowerGlobals(const VariableDeclarationList &Vars, |
| } |
| } |
| +namespace { |
| +template <typename T> struct ConstantPoolEmitterTraits; |
| + |
| +static_assert(sizeof(unsigned long long) == 8, |
|
Jim Stichnoth
2015/09/18 13:59:34
Can you use uint64_t instead of unsigned long long
John
2015/09/18 14:20:25
Sometimes you might run into problems with uint64_
|
| + "unsigned long long is supposed to be 8 bytes wide."); |
| + |
| +// TODO(jpp): implement the following when implementing constant randomization: |
| +// * template <> struct ConstantPoolEmitterTraits<uint8_t> |
| +// * template <> struct ConstantPoolEmitterTraits<uint16_t> |
| +// * template <> struct ConstantPoolEmitterTraits<uint32_t> |
| +template <> struct ConstantPoolEmitterTraits<float> { |
| + using ConstantType = ConstantFloat; |
| + static constexpr Type IceType = IceType_f32; |
| + // AsmTag and TypeName can't be constexpr because llvm::StringRef is unhappy |
| + // about them being constexpr. |
| + static const char AsmTag[]; |
| + static const char TypeName[]; |
| + static unsigned long long bitcastToUint64(float Value) { |
| + static_assert(sizeof(Value) == sizeof(uint32_t), |
| + "Float should be 4 bytes."); |
| + uint32_t IntValue = *reinterpret_cast<uint32_t *>(&Value); |
| + return static_cast<unsigned long long>(IntValue); |
| + } |
| +}; |
| +const char ConstantPoolEmitterTraits<float>::AsmTag[] = ".long"; |
| +const char ConstantPoolEmitterTraits<float>::TypeName[] = "f32"; |
| + |
| +template <> struct ConstantPoolEmitterTraits<double> { |
| + using ConstantType = ConstantDouble; |
| + static constexpr Type IceType = IceType_f64; |
| + static const char AsmTag[]; |
| + static const char TypeName[]; |
| + static unsigned long long bitcastToUint64(double Value) { |
| + static_assert(sizeof(double) == sizeof(unsigned long long), |
| + "Double should be 8 bytes."); |
| + return *reinterpret_cast<unsigned long long *>(&Value); |
| + } |
| +}; |
| +const char ConstantPoolEmitterTraits<double>::AsmTag[] = ".quad"; |
| +const char ConstantPoolEmitterTraits<double>::TypeName[] = "f64"; |
| + |
| +template <typename T> |
| +void emitConstant( |
| + Ostream &Str, |
| + const typename ConstantPoolEmitterTraits<T>::ConstantType *Const) { |
| + using Traits = ConstantPoolEmitterTraits<T>; |
| + Const->emitPoolLabel(Str); |
| + Str << ":\n\t" << Traits::AsmTag << "\t0x"; |
| + T Value = Const->getValue(); |
| + Str.write_hex(Traits::bitcastToUint64(Value)); |
| + Str << "\t@" << Traits::TypeName << " " << Value << "\n"; |
|
Jim Stichnoth
2015/09/18 13:59:34
Optional: It would be cool if, as an end-of-line c
John
2015/09/18 14:20:25
I am already printing the actual FP value (e.g., 1
Jim Stichnoth
2015/09/18 15:39:59
Oh, whoops, sorry.
(sometimes I do prefer printf s
John
2015/09/18 15:42:28
I always prefer printf format string -- they are m
|
| +} |
| + |
| +template <typename T> void emitConstantPool(GlobalContext *Ctx) { |
| + if (!BuildDefs::dump()) { |
| + return; |
| + } |
| + |
| + using Traits = ConstantPoolEmitterTraits<T>; |
| + SizeT Align = |
| + std::max(static_cast<size_t>(4), typeAlignInBytes(Traits::IceType)); |
|
Jim Stichnoth
2015/09/18 13:59:34
First, I don't like magic constants like "4" sprin
John
2015/09/18 14:20:25
1) I avoid magic constants, too. However, this is
Jim Stichnoth
2015/09/18 15:39:59
I see, thanks.
|
| + assert((Align % 4) == 0 && "Constants should be aligned"); |
| + Ostream &Str = Ctx->getStrEmit(); |
| + ConstantList Pool = Ctx->getConstantPool(Traits::IceType); |
| + |
| + Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",%progbits," << Align |
| + << "\n" |
| + << "\t.align\t" << Align << "\n"; |
| + |
| + if (Ctx->getFlags().shouldReorderPooledConstants()) { |
| + // TODO(jpp): add constant pooling. |
| + UnimplementedError(Ctx->getFlags()); |
| + } |
| + |
| + for (Constant *C : Pool) { |
| + if (!C->getShouldBePooled()) { |
| + continue; |
| + } |
| + |
| + emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C)); |
| + } |
| +} |
| +} // end of anonymous namespace |
| + |
| void TargetDataARM32::lowerConstants() { |
| if (Ctx->getFlags().getDisableTranslation()) |
| return; |
| - UnimplementedError(Ctx->getFlags()); |
| + switch (Ctx->getFlags().getOutFileType()) { |
| + case FT_Elf: |
| + UnimplementedError(Ctx->getFlags()); |
| + break; |
| + case FT_Asm: { |
| + OstreamLocker L(Ctx); |
| + emitConstantPool<float>(Ctx); |
| + emitConstantPool<double>(Ctx); |
| + break; |
| + } |
| + case FT_Iasm: { |
| + UnimplementedError(Ctx->getFlags()); |
| + break; |
| + } |
| + } |
| } |
| void TargetDataARM32::lowerJumpTables() { |
| if (Ctx->getFlags().getDisableTranslation()) |
| return; |
| - UnimplementedError(Ctx->getFlags()); |
| + switch (Ctx->getFlags().getOutFileType()) { |
| + case FT_Elf: |
| + UnimplementedError(Ctx->getFlags()); |
| + break; |
| + case FT_Asm: |
| + // Already emitted from Cfg |
| + break; |
| + case FT_Iasm: { |
| + UnimplementedError(Ctx->getFlags()); |
| + break; |
| + } |
| + } |
| } |
| TargetHeaderARM32::TargetHeaderARM32(GlobalContext *Ctx) |