Commit fb79284d by Jan Voung

Emit ARM build-attributes in the file scope (as header).

The ARM linker will check that .o files declare compatible build attributes (e.g., all claim hard-float calling convention, all claim VFP-vX ,etc.). Thus, in order to set up cross tests that link LLC generated code against and Subzero generated code, we need the build attributes to be compatible. Pick ARMv7, hard-float calling convention, and neon, etc. which we use for PNaCl LLVM. Will probably have to reorganize to keep in sync once the ELF writer also emits this. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076 R=kschimpf@google.com, stichnot@chromium.org Review URL: https://codereview.chromium.org/1171563002.
parent 8eefffad
......@@ -102,11 +102,7 @@ void Compiler::run(const Ice::ClFlagsExtra &ExtraFlags, GlobalContext &Ctx,
TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx);
if (Ctx.getFlags().getOutFileType() == FT_Elf) {
TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx);
Ctx.getObjectWriter()->writeInitialELFHeader();
}
Ctx.emitFileHeader();
Ctx.startWorkerThreads();
std::unique_ptr<Translator> Translator;
......
......@@ -400,6 +400,17 @@ void addAllIfNotNull(std::unique_ptr<VariableDeclarationList> src,
} // end of anonymous namespace
void GlobalContext::emitFileHeader() {
TimerMarker T1(Ice::TimerStack::TT_emit, this);
if (getFlags().getOutFileType() == FT_Elf) {
getObjectWriter()->writeInitialELFHeader();
} else {
if (!ALLOW_DUMP)
llvm::report_fatal_error("emitFileHeader for non-ELF");
TargetHeaderLowering::createLowering(this)->lower();
}
}
void GlobalContext::emitItems() {
const bool Threaded = !getFlags().isSequential();
// Pending is a vector containing the reassembled, ordered list of
......
......@@ -300,6 +300,9 @@ public:
// Notifies that no more work will be added to the work queue.
void optQueueNotifyEnd() { OptQ.notifyEnd(); }
// Emit file header for output file.
void emitFileHeader();
void emitQueueBlockingPush(EmitterWorkItem *Item);
EmitterWorkItem *emitQueueBlockingPop();
void emitQueueNotifyEnd() { EmitQ.notifyEnd(); }
......
......@@ -437,13 +437,25 @@ TargetDataLowering::createLowering(GlobalContext *Ctx) {
TargetArch Target = Ctx->getFlags().getTargetArch();
#define SUBZERO_TARGET(X) \
if (Target == Target_##X) \
return std::unique_ptr<TargetDataLowering>(TargetData##X::create(Ctx));
return TargetData##X::create(Ctx);
#include "llvm/Config/SZTargets.def"
llvm_unreachable("Unsupported target data lowering");
return nullptr;
llvm::report_fatal_error("Unsupported target data lowering");
}
TargetDataLowering::~TargetDataLowering() {}
std::unique_ptr<TargetHeaderLowering>
TargetHeaderLowering::createLowering(GlobalContext *Ctx) {
TargetArch Target = Ctx->getFlags().getTargetArch();
#define SUBZERO_TARGET(X) \
if (Target == Target_##X) \
return TargetHeader##X::create(Ctx);
#include "llvm/Config/SZTargets.def"
llvm::report_fatal_error("Unsupported target header lowering");
}
TargetHeaderLowering::~TargetHeaderLowering() {}
} // end of namespace Ice
......@@ -389,6 +389,26 @@ protected:
GlobalContext *Ctx;
};
// TargetHeaderLowering is used to "lower" the header of an output file.
// It writes out the target-specific header attributes. E.g., for ARM
// this writes out the build attributes (float ABI, etc.).
class TargetHeaderLowering {
TargetHeaderLowering() = delete;
TargetHeaderLowering(const TargetHeaderLowering &) = delete;
TargetHeaderLowering &operator=(const TargetHeaderLowering &) = delete;
public:
static std::unique_ptr<TargetHeaderLowering>
createLowering(GlobalContext *Ctx);
virtual ~TargetHeaderLowering();
virtual void lower() {}
protected:
explicit TargetHeaderLowering(GlobalContext *Ctx) : Ctx(Ctx) {}
GlobalContext *Ctx;
};
} // end of namespace Ice
#endif // SUBZERO_SRC_ICETARGETLOWERING_H
......@@ -2225,4 +2225,43 @@ void TargetDataARM32::lowerConstants() const {
UnimplementedError(Ctx->getFlags());
}
TargetHeaderARM32::TargetHeaderARM32(GlobalContext *Ctx)
: TargetHeaderLowering(Ctx) {}
void TargetHeaderARM32::lower() {
OstreamLocker L(Ctx);
Ostream &Str = Ctx->getStrEmit();
Str << ".syntax unified\n";
// Emit build attributes in format: .eabi_attribute TAG, VALUE.
// See Sec. 2 of "Addenda to, and Errata in the ABI for the ARM architecture"
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0045d/IHI0045D_ABI_addenda.pdf
//
// Tag_conformance should be be emitted first in a file-scope
// sub-subsection of the first public subsection of the attributes.
Str << ".eabi_attribute 67, \"2.09\" @ Tag_conformance\n";
// Chromebooks are at least A15, but do A9 for higher compat.
Str << ".cpu cortex-a9\n"
<< ".eabi_attribute 6, 10 @ Tag_CPU_arch: ARMv7\n"
<< ".eabi_attribute 7, 65 @ Tag_CPU_arch_profile: App profile\n";
Str << ".eabi_attribute 8, 1 @ Tag_ARM_ISA_use: Yes\n"
<< ".eabi_attribute 9, 2 @ Tag_THUMB_ISA_use: Thumb-2\n";
// TODO(jvoung): check other CPU features like HW div.
Str << ".fpu neon\n"
<< ".eabi_attribute 17, 1 @ Tag_ABI_PCS_GOT_use: permit directly\n"
<< ".eabi_attribute 20, 1 @ Tag_ABI_FP_denormal\n"
<< ".eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions\n"
<< ".eabi_attribute 23, 3 @ Tag_ABI_FP_number_model: IEEE 754\n"
<< ".eabi_attribute 34, 1 @ Tag_CPU_unaligned_access\n"
<< ".eabi_attribute 24, 1 @ Tag_ABI_align_needed: 8-byte\n"
<< ".eabi_attribute 25, 1 @ Tag_ABI_align_preserved: 8-byte\n"
<< ".eabi_attribute 28, 1 @ Tag_ABI_VFP_args\n"
<< ".eabi_attribute 36, 1 @ Tag_FP_HP_extension\n"
<< ".eabi_attribute 38, 1 @ Tag_ABI_FP_16bit_format\n"
<< ".eabi_attribute 42, 1 @ Tag_MPextension_use\n"
<< ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n";
// Technically R9 is used for TLS with Sandboxing, and we reserve it.
// However, for compatibility with current NaCl LLVM, don't claim that.
Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
}
} // end of namespace Ice
......@@ -308,8 +308,8 @@ class TargetDataARM32 : public TargetDataLowering {
TargetDataARM32 &operator=(const TargetDataARM32 &) = delete;
public:
static TargetDataLowering *create(GlobalContext *Ctx) {
return new TargetDataARM32(Ctx);
static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) {
return std::unique_ptr<TargetDataLowering>(new TargetDataARM32(Ctx));
}
void lowerGlobals(std::unique_ptr<VariableDeclarationList> Vars) const final;
......@@ -324,6 +324,25 @@ private:
template <typename T> static void emitConstantPool(GlobalContext *Ctx);
};
class TargetHeaderARM32 final : public TargetHeaderLowering {
TargetHeaderARM32() = delete;
TargetHeaderARM32(const TargetHeaderARM32 &) = delete;
TargetHeaderARM32 &operator=(const TargetHeaderARM32 &) = delete;
public:
static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) {
return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderARM32(Ctx));
}
void lower();
protected:
explicit TargetHeaderARM32(GlobalContext *Ctx);
private:
~TargetHeaderARM32() = default;
};
} // end of namespace Ice
#endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H
......@@ -702,4 +702,7 @@ void TargetDataMIPS32::lowerConstants() const {
llvm::report_fatal_error("Not yet implemented");
}
TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx)
: TargetHeaderLowering(Ctx) {}
} // end of namespace Ice
......@@ -56,18 +56,23 @@ public:
const char *getConstantPrefix() const final { return ""; }
void emit(const ConstantUndef *C) const final {
(void)C;
llvm::report_fatal_error("Not yet implemented");
}
void emit(const ConstantInteger32 *C) const final {
(void)C;
llvm::report_fatal_error("Not yet implemented");
}
void emit(const ConstantInteger64 *C) const final {
(void)C;
llvm::report_fatal_error("Not yet implemented");
}
void emit(const ConstantFloat *C) const final {
(void)C;
llvm::report_fatal_error("Not yet implemented");
}
void emit(const ConstantDouble *C) const final {
(void)C;
llvm::report_fatal_error("Not yet implemented");
}
......@@ -128,8 +133,8 @@ class TargetDataMIPS32 : public TargetDataLowering {
TargetDataMIPS32 &operator=(const TargetDataMIPS32 &) = delete;
public:
static TargetDataLowering *create(GlobalContext *Ctx) {
return new TargetDataMIPS32(Ctx);
static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) {
return std::unique_ptr<TargetDataLowering>(new TargetDataMIPS32(Ctx));
}
void lowerGlobals(std::unique_ptr<VariableDeclarationList> Vars) const final;
......@@ -144,6 +149,23 @@ private:
template <typename T> static void emitConstantPool(GlobalContext *Ctx);
};
class TargetHeaderMIPS32 final : public TargetHeaderLowering {
TargetHeaderMIPS32() = delete;
TargetHeaderMIPS32(const TargetHeaderMIPS32 &) = delete;
TargetHeaderMIPS32 &operator=(const TargetHeaderMIPS32 &) = delete;
public:
static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) {
return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderMIPS32(Ctx));
}
protected:
explicit TargetHeaderMIPS32(GlobalContext *Ctx);
private:
~TargetHeaderMIPS32() = default;
};
} // end of namespace Ice
#endif // SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
......@@ -5016,4 +5016,7 @@ void TargetDataX8632::lowerConstants() const {
}
}
TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx)
: TargetHeaderLowering(Ctx) {}
} // end of namespace Ice
......@@ -581,8 +581,8 @@ class TargetDataX8632 : public TargetDataLowering {
TargetDataX8632 &operator=(const TargetDataX8632 &) = delete;
public:
static TargetDataLowering *create(GlobalContext *Ctx) {
return new TargetDataX8632(Ctx);
static std::unique_ptr<TargetDataLowering> create(GlobalContext *Ctx) {
return std::unique_ptr<TargetDataLowering>(new TargetDataX8632(Ctx));
}
void lowerGlobals(std::unique_ptr<VariableDeclarationList> Vars) const final;
......@@ -597,6 +597,23 @@ private:
template <typename T> static void emitConstantPool(GlobalContext *Ctx);
};
class TargetHeaderX8632 final : public TargetHeaderLowering {
TargetHeaderX8632() = delete;
TargetHeaderX8632(const TargetHeaderX8632 &) = delete;
TargetHeaderX8632 &operator=(const TargetHeaderX8632 &) = delete;
public:
static std::unique_ptr<TargetHeaderLowering> create(GlobalContext *Ctx) {
return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderX8632(Ctx));
}
protected:
explicit TargetHeaderX8632(GlobalContext *Ctx);
private:
~TargetHeaderX8632() = default;
};
} // end of namespace Ice
#endif // SUBZERO_SRC_ICETARGETLOWERINGX8632_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment