diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 456cffff6b4a7c..fb39bb4b10b377 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 29282582b82bde..66826fadddd2e3 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -132,7 +132,7 @@ namespace { class SparcAsmBackend : public MCAsmBackend { protected: bool Is64Bit; - bool HasV9; + bool IsV8Plus; public: SparcAsmBackend(const MCSubtargetInfo &STI) @@ -140,7 +140,7 @@ namespace { ? llvm::endianness::little : llvm::endianness::big), Is64Bit(STI.getTargetTriple().isArch64Bit()), - HasV9(STI.hasFeature(Sparc::FeatureV9)) {} + IsV8Plus(STI.hasFeature(Sparc::FeatureV8Plus)) {} unsigned getNumFixupKinds() const override { return Sparc::NumTargetFixupKinds; @@ -359,7 +359,7 @@ namespace { std::unique_ptr createObjectTargetWriter() const override { uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType); - return createSparcELFObjectWriter(Is64Bit, 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 bfd71af736231a..601199d7170a73 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -21,11 +21,11 @@ using namespace llvm; namespace { class SparcELFObjectWriter : public MCELFObjectTargetWriter { public: - SparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI) + SparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI) : MCELFObjectTargetWriter( Is64Bit, OSABI, Is64Bit ? ELF::EM_SPARCV9 - : (HasV9 ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC), + : (IsV8Plus ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC), /*HasRelocationAddend*/ true) {} ~SparcELFObjectWriter() override = default; @@ -148,6 +148,6 @@ bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &, } std::unique_ptr -llvm::createSparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI) { - return std::make_unique(Is64Bit, 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 2f89bd6ad9c96d..72f9b3bcd96811 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 63419663b722c5..a7b0538d683b66 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h @@ -35,7 +35,7 @@ MCAsmBackend *createSparcAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options); std::unique_ptr -createSparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI); +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 d2dcf200aef043..3205d06b295ee5 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/MCELFObjectWriter.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) { + ELFObjectWriter &W = getStreamer().getWriter(); + unsigned EFlags = W.getELFHeaderEFlags(); + + EFlags |= getEFlagsForFeatureSet(STI); + + W.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 ef28afa06bffb5..bd9954ffb687bb 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/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td index 65f372f4376b13..8b1122741b6616 100644 --- a/llvm/lib/Target/Sparc/Sparc.td +++ b/llvm/lib/Target/Sparc/Sparc.td @@ -34,6 +34,9 @@ def FeatureNoFMULS def FeatureV9 : SubtargetFeature<"v9", "IsV9", "true", "Enable SPARC-V9 instructions">; +def FeatureV8Plus + : SubtargetFeature<"v8plus", "IsV8Plus", "true", + "Enable V8+ mode, allowing use of 64-bit V9 instructions in 32-bit code">; def FeatureV8Deprecated : SubtargetFeature<"deprecated-v8", "UseV8DeprecatedInsts", "true", "Enable deprecated V8 instructions in V9 mode">; diff --git a/llvm/test/MC/Sparc/elf-sparc-machine-type.s b/llvm/test/MC/Sparc/elf-sparc-machine-type.s index 630812394560ca..85edec5dbaea5d 100644 --- a/llvm/test/MC/Sparc/elf-sparc-machine-type.s +++ b/llvm/test/MC/Sparc/elf-sparc-machine-type.s @@ -1,11 +1,11 @@ ## Emit correct machine type depending on triple and cpu options. ## - `-triple sparc` emits an object of type EM_SPARC; -## - `-triple sparc -mcpu=v9` 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 sparcv9 %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARCV9 %s +# RUN: llvm-mc -filetype=obj -triple sparc %s -o - | llvm-readobj -h - | FileCheck --check-prefixes=SPARC %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 # SPARC: Machine: EM_SPARC (0x2) # SPARC32PLUS: Machine: EM_SPARC32PLUS (0x12)