[llvm] [SPARC][IAS] Add v8plus feature bit (PR #101367)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 1 05:07:37 PDT 2024
https://github.com/koachan updated https://github.com/llvm/llvm-project/pull/101367
>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 1/2] [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)
>From c1068d5c819cd7f384249b6a5de4e140af1951bc Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Thu, 1 Aug 2024 19:07:13 +0700
Subject: [PATCH 2/2] Only emit EM_SPARC32PLUS objects on explicit request
---
llvm/include/llvm/BinaryFormat/ELF.h | 13 ++++++++++
.../Sparc/MCTargetDesc/SparcAsmBackend.cpp | 6 ++---
.../MCTargetDesc/SparcELFObjectWriter.cpp | 17 ++++---------
.../Sparc/MCTargetDesc/SparcMCTargetDesc.cpp | 2 +-
.../Sparc/MCTargetDesc/SparcMCTargetDesc.h | 6 ++---
.../MCTargetDesc/SparcTargetStreamer.cpp | 25 +++++++++++++++++--
.../Sparc/MCTargetDesc/SparcTargetStreamer.h | 2 +-
llvm/test/MC/Sparc/elf-sparc-machine-type.s | 3 +--
8 files changed, 48 insertions(+), 26 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 456cffff6b4a7..fb39bb4b10b37 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 c2f9111375f41..66826fadddd2e 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<MCObjectTargetWriter>
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 87c914326fdbf..601199d7170a7 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<MCObjectTargetWriter>
-llvm::createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, bool HasV9,
- uint8_t OSABI) {
- return std::make_unique<SparcELFObjectWriter>(Is64Bit, IsV8Plus, HasV9,
- OSABI);
+llvm::createSparcELFObjectWriter(bool Is64Bit, bool IsV8Plus, uint8_t OSABI) {
+ return std::make_unique<SparcELFObjectWriter>(Is64Bit, IsV8Plus, OSABI);
}
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
index ad6ca0911adb9..8561e95f24f38 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 4d195c5130c48..a7b0538d683b6 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<MCObjectTargetWriter> createSparcELFObjectWriter(bool Is64Bit,
- bool IsV8Plus,
- bool HasV9,
- uint8_t OSABI);
+std::unique_ptr<MCObjectTargetWriter>
+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 d2dcf200aef04..747bdad510e41 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<MCELFStreamer &>(Streamer);
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcTargetStreamer.h
index ef28afa06bffb..bd9954ffb687b 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 a4bd3607e350d..85edec5dbaea5 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
More information about the llvm-commits
mailing list