| Index: src/IceTargetLowering.cpp
|
| diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp
|
| index aefad00f989bd6857e55bcf72d831fbada8f7d2d..4bb035a80294140b41964f6b08c7cdc00d39ffbd 100644
|
| --- a/src/IceTargetLowering.cpp
|
| +++ b/src/IceTargetLowering.cpp
|
| @@ -20,6 +20,7 @@
|
| #include "assembler_mips32.h"
|
| #include "IceCfg.h" // setError()
|
| #include "IceCfgNode.h"
|
| +#include "IceGlobalInits.h"
|
| #include "IceOperand.h"
|
| #include "IceRegAlloc.h"
|
| #include "IceTargetLowering.h"
|
| @@ -445,6 +446,89 @@ TargetDataLowering::createLowering(GlobalContext *Ctx) {
|
|
|
| TargetDataLowering::~TargetDataLowering() {}
|
|
|
| +void TargetDataLowering::emitGlobal(const VariableDeclaration &Var) {
|
| + if (!ALLOW_DUMP)
|
| + return;
|
| +
|
| + // If external and not initialized, this must be a cross test.
|
| + // Don't generate a declaration for such cases.
|
| + bool IsExternal = Var.isExternal() || Ctx->getFlags().getDisableInternal();
|
| + if (IsExternal && !Var.hasInitializer())
|
| + return;
|
| +
|
| + Ostream &Str = Ctx->getStrEmit();
|
| + const VariableDeclaration::InitializerListType &Initializers =
|
| + Var.getInitializers();
|
| + bool HasNonzeroInitializer = Var.hasNonzeroInitializer();
|
| + bool IsConstant = Var.getIsConstant();
|
| + uint32_t Align = Var.getAlignment();
|
| + SizeT Size = Var.getNumBytes();
|
| + IceString MangledName = Var.mangleName(Ctx);
|
| + IceString SectionSuffix = "";
|
| + if (Ctx->getFlags().getDataSections())
|
| + SectionSuffix = "." + MangledName;
|
| +
|
| + Str << "\t.type\t" << MangledName << ",%object\n";
|
| +
|
| + if (IsConstant)
|
| + Str << "\t.section\t.rodata" << SectionSuffix << ",\"a\",%progbits\n";
|
| + else if (HasNonzeroInitializer)
|
| + Str << "\t.section\t.data" << SectionSuffix << ",\"aw\",%progbits\n";
|
| + else
|
| + Str << "\t.section\t.bss" << SectionSuffix << ",\"aw\",%nobits\n";
|
| +
|
| + if (IsExternal)
|
| + Str << "\t.globl\t" << MangledName << "\n";
|
| +
|
| + if (Align > 1) {
|
| + assert(llvm::isPowerOf2_32(Align));
|
| + // Use the .p2align directive, since the .align N directive can either
|
| + // interpret N as bytes, or power of 2 bytes, depending on the target.
|
| + Str << "\t.p2align\t" << llvm::Log2_32(Align) << "\n";
|
| + }
|
| +
|
| + Str << MangledName << ":\n";
|
| +
|
| + if (HasNonzeroInitializer) {
|
| + for (VariableDeclaration::Initializer *Init : Initializers) {
|
| + switch (Init->getKind()) {
|
| + case VariableDeclaration::Initializer::DataInitializerKind: {
|
| + const auto Data = llvm::cast<VariableDeclaration::DataInitializer>(Init)
|
| + ->getContents();
|
| + for (SizeT i = 0; i < Init->getNumBytes(); ++i) {
|
| + Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
|
| + }
|
| + break;
|
| + }
|
| + case VariableDeclaration::Initializer::ZeroInitializerKind:
|
| + Str << "\t.zero\t" << Init->getNumBytes() << "\n";
|
| + break;
|
| + case VariableDeclaration::Initializer::RelocInitializerKind: {
|
| + const auto Reloc =
|
| + llvm::cast<VariableDeclaration::RelocInitializer>(Init);
|
| + Str << "\t" << getEmit32Directive() << "\t";
|
| + Str << Reloc->getDeclaration()->mangleName(Ctx);
|
| + if (RelocOffsetT Offset = Reloc->getOffset()) {
|
| + if (Offset >= 0 || (Offset == INT32_MIN))
|
| + Str << " + " << Offset;
|
| + else
|
| + Str << " - " << -Offset;
|
| + }
|
| + Str << "\n";
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + } else
|
| + // NOTE: for non-constant zero initializers, this is BSS (no bits),
|
| + // so an ELF writer would not write to the file, and only track
|
| + // virtual offsets, but the .s writer still needs this .zero and
|
| + // cannot simply use the .size to advance offsets.
|
| + Str << "\t.zero\t" << Size << "\n";
|
| +
|
| + Str << "\t.size\t" << MangledName << ", " << Size << "\n";
|
| +}
|
| +
|
| std::unique_ptr<TargetHeaderLowering>
|
| TargetHeaderLowering::createLowering(GlobalContext *Ctx) {
|
| TargetArch Target = Ctx->getFlags().getTargetArch();
|
|
|