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) |