| Index: src/IceTargetLoweringARM32.cpp
|
| diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
|
| index 0fe62e44a919a7c1c67f0f8c59fe4709c1174f2f..5c8bfd9ae7f5187e5aab358059791169326f4dcd 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 {
|
| @@ -3112,16 +3114,125 @@ void TargetDataARM32::lowerGlobals(const VariableDeclarationList &Vars,
|
| }
|
| }
|
|
|
| +namespace {
|
| +template <typename T> struct ConstantPoolEmitterTraits;
|
| +
|
| +static_assert(sizeof(uint64_t) == 8,
|
| + "uint64_t 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 uint64_t 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<uint64_t>(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 uint64_t bitcastToUint64(double Value) {
|
| + static_assert(sizeof(double) == sizeof(uint64_t),
|
| + "Double should be 8 bytes.");
|
| + return *reinterpret_cast<uint64_t *>(&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";
|
| +}
|
| +
|
| +template <typename T> void emitConstantPool(GlobalContext *Ctx) {
|
| + if (!BuildDefs::dump()) {
|
| + return;
|
| + }
|
| +
|
| + using Traits = ConstantPoolEmitterTraits<T>;
|
| + static constexpr size_t MinimumAlignment = 4;
|
| + SizeT Align = std::max(MinimumAlignment, typeAlignInBytes(Traits::IceType));
|
| + 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)
|
|
|