diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 456cffff6b4a7c2..fb39bb4b10b3770 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -697,6 +697,19 @@ enum { #include "ELFRelocs/SystemZ.def" }; +// SPARC Specific e_flags +enum : unsigned { + EF_SPARC_EXT_MASK = 0xffff00, + EF_SPARC_32PLUS = 0x000100, + EF_SPARC_SUN_US1 = 0x000200, + EF_SPARC_HAL_R1 = 0x000400, + EF_SPARC_SUN_US3 = 0x000800, + EF_SPARCV9_MM = 0x3, + EF_SPARCV9_TSO = 0x0, + EF_SPARCV9_PSO = 0x1, + EF_SPARCV9_RMO = 0x2, +}; + // ELF Relocation type for Sparc. enum { #include "ELFRelocs/Sparc.def" diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp index c2f9111375f412f..66826fadddd2e3d 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -133,7 +133,6 @@ namespace { protected: bool Is64Bit; bool IsV8Plus; - bool HasV9; public: SparcAsmBackend(const MCSubtargetInfo &STI) @@ -141,8 +140,7 @@ namespace { ? llvm::endianness::little : llvm::endianness::big), Is64Bit(STI.getTargetTriple().isArch64Bit()), - IsV8Plus(STI.hasFeature(Sparc::FeatureV8Plus)), - HasV9(STI.hasFeature(Sparc::FeatureV9)) {} + IsV8Plus(STI.hasFeature(Sparc::FeatureV8Plus)) {} unsigned getNumFixupKinds() const override { return Sparc::NumTargetFixupKinds; @@ -361,7 +359,7 @@ namespace { std::unique_ptr createObjectTargetWriter() const override { uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType); - return createSparcELFObjectWriter(Is64Bit, IsV8Plus, HasV9, OSABI); + return createSparcELFObjectWriter(Is64Bit, IsV8Plus, OSABI); } }; diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp index 87c914326fdbf15..601199d7170a73c 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -21,16 +21,11 @@ using namespace llvm; namespace { class SparcELFObjectWriter : public MCELFObjectTargetWriter { public: - SparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, bool HasV9, uint8_t OSABI) + SparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI) : MCELFObjectTargetWriter( Is64Bit, OSABI, - Is64Bit - ? ELF::EM_SPARCV9 - // Note that we still need to emit an EM_SPARC32PLUS object - // even when V8+ isn't explicitly requested, if we're - // targeting a V9-capable CPU. This matches GAS behavior upon - // encountering any V9 instructions in its input. - : ((IsV8Plus || HasV9) ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC), + Is64Bit ? ELF::EM_SPARCV9 + : (IsV8Plus ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC), /*HasRelocationAddend*/ true) {} ~SparcELFObjectWriter() override = default; @@ -153,8 +148,6 @@ bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &, } std::unique_ptr -llvm::createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, bool HasV9, - uint8_t OSABI) { - return std::make_unique(Is64Bit, IsV8Plus, HasV9, - OSABI); +llvm::createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI) { + return std::make_unique(Is64Bit, IsV8Plus, OSABI); } diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp index ad6ca0911adb98e..8561e95f24f38b0 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp @@ -86,7 +86,7 @@ createSparcMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { static MCTargetStreamer * createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { - return new SparcTargetELFStreamer(S); + return new SparcTargetELFStreamer(S, STI); } static MCTargetStreamer *createTargetAsmStreamer(MCStreamer &S, diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h index 4d195c5130c48fc..a7b0538d683b667 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h @@ -34,10 +34,8 @@ MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII, MCAsmBackend *createSparcAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options); -std::unique_ptr createSparcELFObjectWriter(bool Is64Bit, - bool IsV8Plus, - bool HasV9, - uint8_t OSABI); +std::unique_ptr +createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI); // Defines symbolic names for Sparc v9 ASI tag names. namespace SparcASITag { diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp index d2dcf200aef043a..747bdad510e41d3 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp @@ -12,11 +12,24 @@ #include "SparcTargetStreamer.h" #include "SparcInstPrinter.h" +#include "SparcMCTargetDesc.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCRegister.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/FormattedStream.h" using namespace llvm; +static unsigned getEFlagsForFeatureSet(const MCSubtargetInfo &STI) { + unsigned EFlags = 0; + + if (STI.hasFeature(Sparc::FeatureV8Plus)) + EFlags |= ELF::EF_SPARC_32PLUS; + + return EFlags; +} + // pin vtable to this file SparcTargetStreamer::SparcTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} @@ -38,8 +51,16 @@ void SparcTargetAsmStreamer::emitSparcRegisterScratch(unsigned reg) { << ", #scratch\n"; } -SparcTargetELFStreamer::SparcTargetELFStreamer(MCStreamer &S) - : SparcTargetStreamer(S) {} +SparcTargetELFStreamer::SparcTargetELFStreamer(MCStreamer &S, + const MCSubtargetInfo &STI) + : SparcTargetStreamer(S) { + MCAssembler &MCA = getStreamer().getAssembler(); + unsigned EFlags = MCA.getELFHeaderEFlags(); + + EFlags |= getEFlagsForFeatureSet(STI); + + MCA.setELFHeaderEFlags(EFlags); +} MCELFStreamer &SparcTargetELFStreamer::getStreamer() { return static_cast(Streamer); diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.h index ef28afa06bffb5a..bd9954ffb687bba 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.h +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.h @@ -40,7 +40,7 @@ class SparcTargetAsmStreamer : public SparcTargetStreamer { // This part is for ELF object output class SparcTargetELFStreamer : public SparcTargetStreamer { public: - SparcTargetELFStreamer(MCStreamer &S); + SparcTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); MCELFStreamer &getStreamer(); void emitSparcRegisterIgnore(unsigned reg) override {} void emitSparcRegisterScratch(unsigned reg) override {} diff --git a/llvm/test/MC/Sparc/elf-sparc-machine-type.s b/llvm/test/MC/Sparc/elf-sparc-machine-type.s index a4bd3607e350db4..85edec5dbaea5d0 100644 --- a/llvm/test/MC/Sparc/elf-sparc-machine-type.s +++ b/llvm/test/MC/Sparc/elf-sparc-machine-type.s @@ -1,10 +1,9 @@ ## Emit correct machine type depending on triple and cpu options. ## - `-triple sparc` emits an object of type EM_SPARC; -## - `-triple sparc -mcpu=v9` or `-triple sparc -mattr=+v8plus` emits EM_SPARC32PLUS; and +## - `-triple sparc -mattr=+v8plus` emits EM_SPARC32PLUS; and ## - `-triple sparcv9` emits EM_SPARCV9. # RUN: llvm-mc -filetype=obj -triple sparc %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARC %s -# RUN: llvm-mc -filetype=obj -triple sparc -mcpu=v9 %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARC32PLUS %s # RUN: llvm-mc -filetype=obj -triple sparc -mattr=+v8plus %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARC32PLUS %s # RUN: llvm-mc -filetype=obj -triple sparcv9 %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARCV9 %s