[llvm] [SPARC][IAS] Add v8plus feature bit (PR #101367)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 31 10:15:09 PDT 2024


https://github.com/koachan created https://github.com/llvm/llvm-project/pull/101367

Implement handling for `v8plus` feature bit to allow the user to switch between V8 and V8+ mode with 32-bit code.
Currently this only sets the appropriate ELF machine type; codegen changes will be done in future patches.

This is done as a prerequisite for `-mv8plus` flag on clang (#98713).

>From ec0450f45e1bf3a78088cfd9eea1f665ee4ec6a7 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Wed, 31 Jul 2024 23:36:23 +0700
Subject: [PATCH] [SPARC] Add v8plus feature bit

Implement handling for `v8plus` feature bit to allow the user to switch
between V8 and V8+ mode with 32-bit code.

This is done as a prerequisite for `-mv8plus` flag on clang (#98713).
---
 .../Sparc/MCTargetDesc/SparcAsmBackend.cpp      |  4 +++-
 .../Sparc/MCTargetDesc/SparcELFObjectWriter.cpp | 17 ++++++++++++-----
 .../Sparc/MCTargetDesc/SparcMCTargetDesc.h      |  6 ++++--
 llvm/lib/Target/Sparc/Sparc.td                  |  3 +++
 llvm/test/MC/Sparc/elf-sparc-machine-type.s     |  9 +++++----
 5 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index 29282582b82bd..c2f9111375f41 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -132,6 +132,7 @@ namespace {
   class SparcAsmBackend : public MCAsmBackend {
   protected:
     bool Is64Bit;
+    bool IsV8Plus;
     bool HasV9;
 
   public:
@@ -140,6 +141,7 @@ namespace {
                            ? llvm::endianness::little
                            : llvm::endianness::big),
           Is64Bit(STI.getTargetTriple().isArch64Bit()),
+          IsV8Plus(STI.hasFeature(Sparc::FeatureV8Plus)),
           HasV9(STI.hasFeature(Sparc::FeatureV9)) {}
 
     unsigned getNumFixupKinds() const override {
@@ -359,7 +361,7 @@ namespace {
     std::unique_ptr<MCObjectTargetWriter>
     createObjectTargetWriter() const override {
       uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
-      return createSparcELFObjectWriter(Is64Bit, HasV9, OSABI);
+      return createSparcELFObjectWriter(Is64Bit, IsV8Plus, HasV9, OSABI);
     }
   };
 
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index bfd71af736231..87c914326fdbf 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -21,11 +21,16 @@ using namespace llvm;
 namespace {
   class SparcELFObjectWriter : public MCELFObjectTargetWriter {
   public:
-    SparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI)
+    SparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, bool HasV9, uint8_t OSABI)
         : MCELFObjectTargetWriter(
               Is64Bit, OSABI,
-              Is64Bit ? ELF::EM_SPARCV9
-                      : (HasV9 ? ELF::EM_SPARC32PLUS : ELF::EM_SPARC),
+              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),
               /*HasRelocationAddend*/ true) {}
 
     ~SparcELFObjectWriter() override = default;
@@ -148,6 +153,8 @@ bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCValue &,
 }
 
 std::unique_ptr<MCObjectTargetWriter>
-llvm::createSparcELFObjectWriter(bool Is64Bit, bool HasV9, uint8_t OSABI) {
-  return std::make_unique<SparcELFObjectWriter>(Is64Bit, HasV9, OSABI);
+llvm::createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, bool HasV9,
+                                 uint8_t OSABI) {
+  return std::make_unique<SparcELFObjectWriter>(Is64Bit, IsV8Plus, HasV9,
+                                                OSABI);
 }
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
index 63419663b722c..4d195c5130c48 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
@@ -34,8 +34,10 @@ 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, bool HasV9, uint8_t OSABI);
+std::unique_ptr<MCObjectTargetWriter> createSparcELFObjectWriter(bool Is64Bit,
+                                                                 bool IsV8Plus,
+                                                                 bool HasV9,
+                                                                 uint8_t OSABI);
 
 // Defines symbolic names for Sparc v9 ASI tag names.
 namespace SparcASITag {
diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td
index 65f372f4376b1..8b1122741b661 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 630812394560c..a4bd3607e350d 100644
--- a/llvm/test/MC/Sparc/elf-sparc-machine-type.s
+++ b/llvm/test/MC/Sparc/elf-sparc-machine-type.s
@@ -1,11 +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 sparc -mcpu=v9` or `-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         -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
 
 # SPARC:       Machine: EM_SPARC (0x2)
 # SPARC32PLUS: Machine: EM_SPARC32PLUS (0x12)



More information about the llvm-commits mailing list