[llvm] fb7f65b - [SPARC][IAS] Emit the correct ELF machine type (#96583)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 3 05:14:44 PDT 2024


Author: Koakuma
Date: 2024-07-03T19:14:39+07:00
New Revision: fb7f65ba468f462103599e762c86f49b420cd984

URL: https://github.com/llvm/llvm-project/commit/fb7f65ba468f462103599e762c86f49b420cd984
DIFF: https://github.com/llvm/llvm-project/commit/fb7f65ba468f462103599e762c86f49b420cd984.diff

LOG: [SPARC][IAS] Emit the correct ELF machine type (#96583)

Emit the correct machine type when writing out ELF objects.
This patch is modeled on GCC's behavior:
- `-m32` emits an object of type EM_SPARC;
- `-m32 -mcpu=v9` emits EM_SPARC32PLUS (however, see below); and
- `-m64` emits EM_SPARCV9.

Note that GCC does not guarantee emission of EM_SPARC32PLUS objects,
since GNU as doesn't support user control of emitted machine type.
It will always autodetect the type based on the instruction mix:
- If there's a V9 instruction inside, then emit EM_SPARC32PLUS; and
- Emit EM_SPARC otherwise.

For LLVM we choose deterministic behavior instead for simplicity.

Added: 
    llvm/test/MC/Sparc/elf-sparc-machine-type.s

Modified: 
    llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
    llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
    llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index 81c943ca47bf8..29282582b82bd 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -131,15 +131,16 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
 namespace {
   class SparcAsmBackend : public MCAsmBackend {
   protected:
-    const Target &TheTarget;
     bool Is64Bit;
+    bool HasV9;
 
   public:
-    SparcAsmBackend(const Target &T)
-        : MCAsmBackend(StringRef(T.getName()) == "sparcel"
+    SparcAsmBackend(const MCSubtargetInfo &STI)
+        : MCAsmBackend(STI.getTargetTriple().isLittleEndian()
                            ? llvm::endianness::little
                            : llvm::endianness::big),
-          TheTarget(T), Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {}
+          Is64Bit(STI.getTargetTriple().isArch64Bit()),
+          HasV9(STI.hasFeature(Sparc::FeatureV9)) {}
 
     unsigned getNumFixupKinds() const override {
       return Sparc::NumTargetFixupKinds;
@@ -330,8 +331,8 @@ namespace {
   class ELFSparcAsmBackend : public SparcAsmBackend {
     Triple::OSType OSType;
   public:
-    ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
-      SparcAsmBackend(T), OSType(OSType) { }
+    ELFSparcAsmBackend(const MCSubtargetInfo &STI, Triple::OSType OSType)
+        : SparcAsmBackend(STI), OSType(OSType) {}
 
     void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                     const MCValue &Target, MutableArrayRef<char> Data,
@@ -358,7 +359,7 @@ namespace {
     std::unique_ptr<MCObjectTargetWriter>
     createObjectTargetWriter() const override {
       uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
-      return createSparcELFObjectWriter(Is64Bit, OSABI);
+      return createSparcELFObjectWriter(Is64Bit, HasV9, OSABI);
     }
   };
 
@@ -368,5 +369,5 @@ MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
                                           const MCSubtargetInfo &STI,
                                           const MCRegisterInfo &MRI,
                                           const MCTargetOptions &Options) {
-  return new ELFSparcAsmBackend(T, STI.getTargetTriple().getOS());
+  return new ELFSparcAsmBackend(STI, STI.getTargetTriple().getOS());
 }

diff  --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index f17d3e997452d..bfd71af736231 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -21,10 +21,12 @@ using namespace llvm;
 namespace {
   class SparcELFObjectWriter : public MCELFObjectTargetWriter {
   public:
-    SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI)
-      : MCELFObjectTargetWriter(Is64Bit, OSABI,
-                                Is64Bit ?  ELF::EM_SPARCV9 : ELF::EM_SPARC,
-                                /*HasRelocationAddend*/ true) {}
+    SparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI)
+        : MCELFObjectTargetWriter(
+              Is64Bit, OSABI,
+              Is64Bit ? ELF::EM_SPARCV9
+                      : (HasV9 ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC),
+              /*HasRelocationAddend*/ true) {}
 
     ~SparcELFObjectWriter() override = default;
 
@@ -146,6 +148,6 @@ bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
 }
 
 std::unique_ptr<MCObjectTargetWriter>
-llvm::createSparcELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
-  return std::make_unique<SparcELFObjectWriter>(Is64Bit, OSABI);
+llvm::createSparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI) {
+  return std::make_unique<SparcELFObjectWriter>(Is64Bit, HasV9, OSABI);
 }

diff  --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
index a2a9f7474c3f9..63419663b722c 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
@@ -34,8 +34,8 @@ MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII,
 MCAsmBackend *createSparcAsmBackend(const Target &T, const MCSubtargetInfo &STI,
                                     const MCRegisterInfo &MRI,
                                     const MCTargetOptions &Options);
-std::unique_ptr<MCObjectTargetWriter> createSparcELFObjectWriter(bool Is64Bit,
-                                                                 uint8_t OSABI);
+std::unique_ptr<MCObjectTargetWriter>
+createSparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI);
 
 // Defines symbolic names for Sparc v9 ASI tag names.
 namespace SparcASITag {

diff  --git a/llvm/test/MC/Sparc/elf-sparc-machine-type.s b/llvm/test/MC/Sparc/elf-sparc-machine-type.s
new file mode 100644
index 0000000000000..630812394560c
--- /dev/null
+++ b/llvm/test/MC/Sparc/elf-sparc-machine-type.s
@@ -0,0 +1,12 @@
+## 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 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
+
+# SPARC:       Machine: EM_SPARC (0x2)
+# SPARC32PLUS: Machine: EM_SPARC32PLUS (0x12)
+# SPARCV9:     Machine: EM_SPARCV9 (0x2B)


        


More information about the llvm-commits mailing list